1 /* 2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.tools.javac.parser; 27 28 import java.util.*; 29 import java.util.function.Function; 30 import java.util.function.Predicate; 31 import java.util.stream.Collectors; 32 33 import com.sun.source.tree.MemberReferenceTree.ReferenceMode; 34 import com.sun.source.tree.ModuleTree.ModuleKind; 35 36 import com.sun.tools.javac.code.*; 37 import com.sun.tools.javac.code.Source.Feature; 38 import com.sun.tools.javac.parser.Tokens.*; 39 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; 40 import com.sun.tools.javac.resources.CompilerProperties; 41 import com.sun.tools.javac.resources.CompilerProperties.Errors; 42 import com.sun.tools.javac.tree.*; 43 import com.sun.tools.javac.tree.JCTree.*; 44 import com.sun.tools.javac.util.*; 45 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag; 46 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; 47 import com.sun.tools.javac.util.JCDiagnostic.Error; 48 import com.sun.tools.javac.util.List; 49 50 import static com.sun.tools.javac.parser.Tokens.TokenKind.*; 51 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT; 52 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE; 53 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH; 54 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ; 55 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT; 56 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT; 57 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT; 58 import static com.sun.tools.javac.tree.JCTree.Tag.*; 59 60 /** The parser maps a token sequence into an abstract syntax 61 * tree. It operates by recursive descent, with code derived 62 * systematically from an LL(1) grammar. For efficiency reasons, an 63 * operator precedence scheme is used for parsing binary operation 64 * expressions. 65 * 66 * <p><b>This is NOT part of any supported API. 67 * If you write code that depends on this, you do so at your own risk. 68 * This code and its internal interfaces are subject to change or 69 * deletion without notice.</b> 70 */ 71 public class JavacParser implements Parser { 72 73 /** The number of precedence levels of infix operators. 74 */ 75 private static final int infixPrecedenceLevels = 10; 76 77 /** Is the parser instantiated to parse a module-info file ? 78 */ 79 private final boolean parseModuleInfo; 80 81 /** The scanner used for lexical analysis. 82 */ 83 protected Lexer S; 84 85 /** The factory to be used for abstract syntax tree construction. 86 */ 87 protected TreeMaker F; 88 89 /** The log to be used for error diagnostics. 90 */ 91 private Log log; 92 93 /** The Source language setting. */ 94 private Source source; 95 96 /** The name table. */ 97 private Names names; 98 99 /** End position mappings container */ 100 protected final AbstractEndPosTable endPosTable; 101 102 // Because of javac's limited lookahead, some contexts are ambiguous in 103 // the presence of type annotations even though they are not ambiguous 104 // in the absence of type annotations. Consider this code: 105 // void m(String [] m) { } 106 // void m(String ... m) { } 107 // After parsing "String", javac calls bracketsOpt which immediately 108 // returns if the next character is not '['. Similarly, javac can see 109 // if the next token is ... and in that case parse an ellipsis. But in 110 // the presence of type annotations: 111 // void m(String @A [] m) { } 112 // void m(String @A ... m) { } 113 // no finite lookahead is enough to determine whether to read array 114 // levels or an ellipsis. Furthermore, if you call bracketsOpt, then 115 // bracketsOpt first reads all the leading annotations and only then 116 // discovers that it needs to fail. bracketsOpt needs a way to push 117 // back the extra annotations that it read. (But, bracketsOpt should 118 // not *always* be allowed to push back extra annotations that it finds 119 // -- in most contexts, any such extra annotation is an error. 120 // 121 // The following two variables permit type annotations that have 122 // already been read to be stored for later use. Alternate 123 // implementations are possible but would cause much larger changes to 124 // the parser. 125 126 /** Type annotations that have already been read but have not yet been used. **/ 127 private List<JCAnnotation> typeAnnotationsPushedBack = List.nil(); 128 129 /** 130 * If the parser notices extra annotations, then it either immediately 131 * issues an error (if this variable is false) or places the extra 132 * annotations in variable typeAnnotationsPushedBack (if this variable 133 * is true). 134 */ 135 private boolean permitTypeAnnotationsPushBack = false; 136 137 interface ErrorRecoveryAction { 138 JCTree doRecover(JavacParser parser); 139 } 140 141 enum BasicErrorRecoveryAction implements ErrorRecoveryAction { 142 BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }}, 143 CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }} 144 } 145 146 /** Construct a parser from a given scanner, tree factory and log. 147 */ 148 protected JavacParser(ParserFactory fac, 149 Lexer S, 150 boolean keepDocComments, 151 boolean keepLineMap, 152 boolean keepEndPositions) { 153 this(fac, S, keepDocComments, keepLineMap, keepEndPositions, false); 154 155 } 156 /** Construct a parser from a given scanner, tree factory and log. 157 */ 158 protected JavacParser(ParserFactory fac, 159 Lexer S, 160 boolean keepDocComments, 161 boolean keepLineMap, 162 boolean keepEndPositions, 163 boolean parseModuleInfo) { 164 this.S = S; 165 nextToken(); // prime the pump 166 this.F = fac.F; 167 this.log = fac.log; 168 this.names = fac.names; 169 this.source = fac.source; 170 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); 171 this.keepDocComments = keepDocComments; 172 this.parseModuleInfo = parseModuleInfo; 173 docComments = newDocCommentTable(keepDocComments, fac); 174 this.keepLineMap = keepLineMap; 175 this.errorTree = F.Erroneous(); 176 endPosTable = newEndPosTable(keepEndPositions); 177 } 178 179 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) { 180 return keepEndPositions 181 ? new SimpleEndPosTable(this) 182 : new EmptyEndPosTable(this); 183 } 184 185 protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) { 186 return keepDocComments ? new LazyDocCommentTable(fac) : null; 187 } 188 189 /** Switch: should we fold strings? 190 */ 191 boolean allowStringFolding; 192 193 /** Switch: should we keep docComments? 194 */ 195 boolean keepDocComments; 196 197 /** Switch: should we keep line table? 198 */ 199 boolean keepLineMap; 200 201 /** Switch: is "this" allowed as an identifier? 202 * This is needed to parse receiver types. 203 */ 204 boolean allowThisIdent; 205 206 /** The type of the method receiver, as specified by a first "this" parameter. 207 */ 208 JCVariableDecl receiverParam; 209 210 /** When terms are parsed, the mode determines which is expected: 211 * mode = EXPR : an expression 212 * mode = TYPE : a type 213 * mode = NOPARAMS : no parameters allowed for type 214 * mode = TYPEARG : type argument 215 */ 216 protected static final int EXPR = 0x1; 217 protected static final int TYPE = 0x2; 218 protected static final int NOPARAMS = 0x4; 219 protected static final int TYPEARG = 0x8; 220 protected static final int DIAMOND = 0x10; 221 222 /** The current mode. 223 */ 224 protected int mode = 0; 225 226 /** The mode of the term that was parsed last. 227 */ 228 protected int lastmode = 0; 229 230 /* ---------- token management -------------- */ 231 232 protected Token token; 233 234 public Token token() { 235 return token; 236 } 237 238 public void nextToken() { 239 S.nextToken(); 240 token = S.token(); 241 } 242 243 protected boolean peekToken(Filter<TokenKind> tk) { 244 return peekToken(0, tk); 245 } 246 247 protected boolean peekToken(int lookahead, Filter<TokenKind> tk) { 248 return tk.accepts(S.token(lookahead + 1).kind); 249 } 250 251 protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) { 252 return peekToken(0, tk1, tk2); 253 } 254 255 protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) { 256 return tk1.accepts(S.token(lookahead + 1).kind) && 257 tk2.accepts(S.token(lookahead + 2).kind); 258 } 259 260 protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) { 261 return peekToken(0, tk1, tk2, tk3); 262 } 263 264 protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) { 265 return tk1.accepts(S.token(lookahead + 1).kind) && 266 tk2.accepts(S.token(lookahead + 2).kind) && 267 tk3.accepts(S.token(lookahead + 3).kind); 268 } 269 270 @SuppressWarnings("unchecked") 271 protected boolean peekToken(Filter<TokenKind>... kinds) { 272 return peekToken(0, kinds); 273 } 274 275 @SuppressWarnings("unchecked") 276 protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) { 277 for (; lookahead < kinds.length ; lookahead++) { 278 if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) { 279 return false; 280 } 281 } 282 return true; 283 } 284 285 /* ---------- error recovery -------------- */ 286 287 private JCErroneous errorTree; 288 289 /** Skip forward until a suitable stop token is found. 290 */ 291 protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 292 while (true) { 293 switch (token.kind) { 294 case SEMI: 295 nextToken(); 296 return; 297 case PUBLIC: 298 case FINAL: 299 case ABSTRACT: 300 case MONKEYS_AT: 301 case EOF: 302 case CLASS: 303 case INTERFACE: 304 case ENUM: 305 return; 306 case IMPORT: 307 if (stopAtImport) 308 return; 309 break; 310 case LBRACE: 311 case RBRACE: 312 case PRIVATE: 313 case PROTECTED: 314 case STATIC: 315 case TRANSIENT: 316 case NATIVE: 317 case VOLATILE: 318 case SYNCHRONIZED: 319 case STRICTFP: 320 case LT: 321 case BYTE: 322 case SHORT: 323 case CHAR: 324 case INT: 325 case LONG: 326 case FLOAT: 327 case DOUBLE: 328 case BOOLEAN: 329 case VOID: 330 if (stopAtMemberDecl) 331 return; 332 break; 333 case UNDERSCORE: 334 case IDENTIFIER: 335 if (stopAtIdentifier) 336 return; 337 break; 338 case CASE: 339 case DEFAULT: 340 case IF: 341 case FOR: 342 case WHILE: 343 case DO: 344 case TRY: 345 case SWITCH: 346 case RETURN: 347 case THROW: 348 case BREAK: 349 case CONTINUE: 350 case ELSE: 351 case FINALLY: 352 case CATCH: 353 case THIS: 354 case SUPER: 355 case NEW: 356 if (stopAtStatement) 357 return; 358 break; 359 case ASSERT: 360 if (stopAtStatement) 361 return; 362 break; 363 } 364 nextToken(); 365 } 366 } 367 368 protected JCErroneous syntaxError(int pos, String key, TokenKind... args) { 369 return syntaxError(pos, List.nil(), key, args); 370 } 371 372 protected JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) { 373 setErrorEndPos(pos); 374 JCErroneous err = F.at(pos).Erroneous(errs); 375 reportSyntaxError(err, key, (Object[])args); 376 if (errs != null) { 377 JCTree last = errs.last(); 378 if (last != null) 379 storeEnd(last, pos); 380 } 381 return toP(err); 382 } 383 384 private static final int RECOVERY_THRESHOLD = 50; 385 private int errorPos = Position.NOPOS; 386 private int count = 0; 387 388 /** 389 * Report a syntax using the given the position parameter and arguments, 390 * unless one was already reported at the same position. 391 */ 392 protected void reportSyntaxError(int pos, String key, Object... args) { 393 JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos); 394 reportSyntaxError(diag, key, args); 395 } 396 397 /** 398 * Report a syntax error using the given DiagnosticPosition object and 399 * arguments, unless one was already reported at the same position. 400 */ 401 protected void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) { 402 int pos = diagPos.getPreferredPosition(); 403 if (pos > S.errPos() || pos == Position.NOPOS) { 404 if (token.kind == EOF) { 405 error(diagPos, "premature.eof"); 406 } else { 407 error(diagPos, key, args); 408 } 409 } 410 S.errPos(pos); 411 if (token.pos == errorPos) { 412 //check for a possible infinite loop in parsing: 413 Assert.check(count++ < RECOVERY_THRESHOLD); 414 } else { 415 count = 0; 416 errorPos = token.pos; 417 } 418 } 419 420 421 /** Generate a syntax error at current position unless one was already 422 * reported at the same position. 423 */ 424 protected JCErroneous syntaxError(String key) { 425 return syntaxError(token.pos, key); 426 } 427 428 /** Generate a syntax error at current position unless one was 429 * already reported at the same position. 430 */ 431 protected JCErroneous syntaxError(String key, TokenKind arg) { 432 return syntaxError(token.pos, key, arg); 433 } 434 435 /** If next input token matches given token, skip it, otherwise report 436 * an error. 437 */ 438 public void accept(TokenKind tk) { 439 if (token.kind == tk) { 440 nextToken(); 441 } else { 442 setErrorEndPos(token.pos); 443 reportSyntaxError(S.prevToken().endPos, "expected", tk); 444 } 445 } 446 447 /** Report an illegal start of expression/type error at given position. 448 */ 449 JCExpression illegal(int pos) { 450 setErrorEndPos(pos); 451 if ((mode & EXPR) != 0) 452 return syntaxError(pos, "illegal.start.of.expr"); 453 else 454 return syntaxError(pos, "illegal.start.of.type"); 455 456 } 457 458 /** Report an illegal start of expression/type error at current position. 459 */ 460 JCExpression illegal() { 461 return illegal(token.pos); 462 } 463 464 /** Diagnose a modifier flag from the set, if any. */ 465 protected void checkNoMods(long mods) { 466 if (mods != 0) { 467 long lowestMod = mods & -mods; 468 error(token.pos, "mod.not.allowed.here", 469 Flags.asFlagSet(lowestMod)); 470 } 471 } 472 473 /* ---------- doc comments --------- */ 474 475 /** A table to store all documentation comments 476 * indexed by the tree nodes they refer to. 477 * defined only if option flag keepDocComment is set. 478 */ 479 private final DocCommentTable docComments; 480 481 /** Make an entry into docComments hashtable, 482 * provided flag keepDocComments is set and given doc comment is non-null. 483 * @param tree The tree to be used as index in the hashtable 484 * @param dc The doc comment to associate with the tree, or null. 485 */ 486 protected void attach(JCTree tree, Comment dc) { 487 if (keepDocComments && dc != null) { 488 // System.out.println("doc comment = ");System.out.println(dc);//DEBUG 489 docComments.putComment(tree, dc); 490 } 491 } 492 493 /* -------- source positions ------- */ 494 495 protected void setErrorEndPos(int errPos) { 496 endPosTable.setErrorEndPos(errPos); 497 } 498 499 protected void storeEnd(JCTree tree, int endpos) { 500 endPosTable.storeEnd(tree, endpos); 501 } 502 503 protected <T extends JCTree> T to(T t) { 504 return endPosTable.to(t); 505 } 506 507 protected <T extends JCTree> T toP(T t) { 508 return endPosTable.toP(t); 509 } 510 511 /** Get the start position for a tree node. The start position is 512 * defined to be the position of the first character of the first 513 * token of the node's source text. 514 * @param tree The tree node 515 */ 516 public int getStartPos(JCTree tree) { 517 return TreeInfo.getStartPos(tree); 518 } 519 520 /** 521 * Get the end position for a tree node. The end position is 522 * defined to be the position of the last character of the last 523 * token of the node's source text. Returns Position.NOPOS if end 524 * positions are not generated or the position is otherwise not 525 * found. 526 * @param tree The tree node 527 */ 528 public int getEndPos(JCTree tree) { 529 return endPosTable.getEndPos(tree); 530 } 531 532 533 534 /* ---------- parsing -------------- */ 535 536 /** 537 * Ident = IDENTIFIER 538 */ 539 public Name ident() { 540 return ident(false); 541 } 542 543 protected Name ident(boolean advanceOnErrors) { 544 if (token.kind == IDENTIFIER) { 545 Name name = token.name(); 546 nextToken(); 547 return name; 548 } else if (token.kind == ASSERT) { 549 error(token.pos, "assert.as.identifier"); 550 nextToken(); 551 return names.error; 552 } else if (token.kind == ENUM) { 553 error(token.pos, "enum.as.identifier"); 554 nextToken(); 555 return names.error; 556 } else if (token.kind == THIS) { 557 if (allowThisIdent) { 558 // Make sure we're using a supported source version. 559 checkSourceLevel(Feature.TYPE_ANNOTATIONS); 560 Name name = token.name(); 561 nextToken(); 562 return name; 563 } else { 564 error(token.pos, "this.as.identifier"); 565 nextToken(); 566 return names.error; 567 } 568 } else if (token.kind == UNDERSCORE) { 569 if (Feature.UNDERSCORE_IDENTIFIER.allowedInSource(source)) { 570 warning(token.pos, "underscore.as.identifier"); 571 } else { 572 error(token.pos, "underscore.as.identifier"); 573 } 574 Name name = token.name(); 575 nextToken(); 576 return name; 577 } else { 578 accept(IDENTIFIER); 579 if (advanceOnErrors) { 580 nextToken(); 581 } 582 return names.error; 583 } 584 } 585 586 /** 587 * Qualident = Ident { DOT [Annotations] Ident } 588 */ 589 public JCExpression qualident(boolean allowAnnos) { 590 JCExpression t = toP(F.at(token.pos).Ident(ident())); 591 while (token.kind == DOT) { 592 int pos = token.pos; 593 nextToken(); 594 List<JCAnnotation> tyannos = null; 595 if (allowAnnos) { 596 tyannos = typeAnnotationsOpt(); 597 } 598 t = toP(F.at(pos).Select(t, ident())); 599 if (tyannos != null && tyannos.nonEmpty()) { 600 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); 601 } 602 } 603 return t; 604 } 605 606 JCExpression literal(Name prefix) { 607 return literal(prefix, token.pos); 608 } 609 610 /** 611 * Literal = 612 * INTLITERAL 613 * | LONGLITERAL 614 * | FLOATLITERAL 615 * | DOUBLELITERAL 616 * | CHARLITERAL 617 * | STRINGLITERAL 618 * | TRUE 619 * | FALSE 620 * | NULL 621 */ 622 JCExpression literal(Name prefix, int pos) { 623 JCExpression t = errorTree; 624 switch (token.kind) { 625 case INTLITERAL: 626 try { 627 t = F.at(pos).Literal( 628 TypeTag.INT, 629 Convert.string2int(strval(prefix), token.radix())); 630 } catch (NumberFormatException ex) { 631 error(token.pos, "int.number.too.large", strval(prefix)); 632 } 633 break; 634 case LONGLITERAL: 635 try { 636 t = F.at(pos).Literal( 637 TypeTag.LONG, 638 Long.valueOf(Convert.string2long(strval(prefix), token.radix()))); 639 } catch (NumberFormatException ex) { 640 error(token.pos, "int.number.too.large", strval(prefix)); 641 } 642 break; 643 case FLOATLITERAL: { 644 String proper = token.radix() == 16 ? 645 ("0x"+ token.stringVal()) : 646 token.stringVal(); 647 Float n; 648 try { 649 n = Float.valueOf(proper); 650 } catch (NumberFormatException ex) { 651 // error already reported in scanner 652 n = Float.NaN; 653 } 654 if (n.floatValue() == 0.0f && !isZero(proper)) 655 error(token.pos, "fp.number.too.small"); 656 else if (n.floatValue() == Float.POSITIVE_INFINITY) 657 error(token.pos, "fp.number.too.large"); 658 else 659 t = F.at(pos).Literal(TypeTag.FLOAT, n); 660 break; 661 } 662 case DOUBLELITERAL: { 663 String proper = token.radix() == 16 ? 664 ("0x"+ token.stringVal()) : 665 token.stringVal(); 666 Double n; 667 try { 668 n = Double.valueOf(proper); 669 } catch (NumberFormatException ex) { 670 // error already reported in scanner 671 n = Double.NaN; 672 } 673 if (n.doubleValue() == 0.0d && !isZero(proper)) 674 error(token.pos, "fp.number.too.small"); 675 else if (n.doubleValue() == Double.POSITIVE_INFINITY) 676 error(token.pos, "fp.number.too.large"); 677 else 678 t = F.at(pos).Literal(TypeTag.DOUBLE, n); 679 break; 680 } 681 case CHARLITERAL: 682 t = F.at(pos).Literal( 683 TypeTag.CHAR, 684 token.stringVal().charAt(0) + 0); 685 break; 686 case STRINGLITERAL: 687 t = F.at(pos).Literal( 688 TypeTag.CLASS, 689 token.stringVal()); 690 break; 691 case TRUE: case FALSE: 692 t = F.at(pos).Literal( 693 TypeTag.BOOLEAN, 694 (token.kind == TRUE ? 1 : 0)); 695 break; 696 case NULL: 697 t = F.at(pos).Literal( 698 TypeTag.BOT, 699 null); 700 break; 701 default: 702 Assert.error(); 703 } 704 if (t == errorTree) 705 t = F.at(pos).Erroneous(); 706 storeEnd(t, token.endPos); 707 nextToken(); 708 return t; 709 } 710 //where 711 boolean isZero(String s) { 712 char[] cs = s.toCharArray(); 713 int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10); 714 int i = ((base==16) ? 2 : 0); 715 while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++; 716 return !(i < cs.length && (Character.digit(cs[i], base) > 0)); 717 } 718 719 String strval(Name prefix) { 720 String s = token.stringVal(); 721 return prefix.isEmpty() ? s : prefix + s; 722 } 723 724 /** terms can be either expressions or types. 725 */ 726 public JCExpression parseExpression() { 727 return term(EXPR); 728 } 729 730 /** 731 * parses (optional) type annotations followed by a type. If the 732 * annotations are present before the type and are not consumed during array 733 * parsing, this method returns a {@link JCAnnotatedType} consisting of 734 * these annotations and the underlying type. Otherwise, it returns the 735 * underlying type. 736 * 737 * <p> 738 * 739 * Note that this method sets {@code mode} to {@code TYPE} first, before 740 * parsing annotations. 741 */ 742 public JCExpression parseType() { 743 return parseType(false); 744 } 745 746 public JCExpression parseType(boolean allowVar) { 747 List<JCAnnotation> annotations = typeAnnotationsOpt(); 748 return parseType(allowVar, annotations); 749 } 750 751 public JCExpression parseType(boolean allowVar, List<JCAnnotation> annotations) { 752 JCExpression result = unannotatedType(allowVar); 753 754 if (annotations.nonEmpty()) { 755 result = insertAnnotationsToMostInner(result, annotations, false); 756 } 757 758 return result; 759 } 760 761 public JCExpression unannotatedType(boolean allowVar) { 762 JCExpression result = term(TYPE); 763 764 if (isRestrictedLocalVarTypeName(result) && !allowVar) { 765 syntaxError(result.pos, "var.not.allowed.here"); 766 } 767 768 return result; 769 } 770 771 772 773 protected JCExpression term(int newmode) { 774 int prevmode = mode; 775 mode = newmode; 776 JCExpression t = term(); 777 lastmode = mode; 778 mode = prevmode; 779 return t; 780 } 781 782 /** 783 * {@literal 784 * Expression = Expression1 [ExpressionRest] 785 * ExpressionRest = [AssignmentOperator Expression1] 786 * AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | 787 * "&=" | "|=" | "^=" | 788 * "%=" | "<<=" | ">>=" | ">>>=" 789 * Type = Type1 790 * TypeNoParams = TypeNoParams1 791 * StatementExpression = Expression 792 * ConstantExpression = Expression 793 * } 794 */ 795 JCExpression term() { 796 JCExpression t = term1(); 797 if ((mode & EXPR) != 0 && 798 token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0) 799 return termRest(t); 800 else 801 return t; 802 } 803 804 JCExpression termRest(JCExpression t) { 805 switch (token.kind) { 806 case EQ: { 807 int pos = token.pos; 808 nextToken(); 809 mode = EXPR; 810 JCExpression t1 = term(); 811 return toP(F.at(pos).Assign(t, t1)); 812 } 813 case PLUSEQ: 814 case SUBEQ: 815 case STAREQ: 816 case SLASHEQ: 817 case PERCENTEQ: 818 case AMPEQ: 819 case BAREQ: 820 case CARETEQ: 821 case LTLTEQ: 822 case GTGTEQ: 823 case GTGTGTEQ: 824 int pos = token.pos; 825 TokenKind tk = token.kind; 826 nextToken(); 827 mode = EXPR; 828 JCExpression t1 = term(); 829 return F.at(pos).Assignop(optag(tk), t, t1); 830 default: 831 return t; 832 } 833 } 834 835 /** Expression1 = Expression2 [Expression1Rest] 836 * Type1 = Type2 837 * TypeNoParams1 = TypeNoParams2 838 */ 839 JCExpression term1() { 840 JCExpression t = term2(); 841 if ((mode & EXPR) != 0 && token.kind == QUES) { 842 mode = EXPR; 843 return term1Rest(t); 844 } else { 845 return t; 846 } 847 } 848 849 /** Expression1Rest = ["?" Expression ":" Expression1] 850 */ 851 JCExpression term1Rest(JCExpression t) { 852 if (token.kind == QUES) { 853 int pos = token.pos; 854 nextToken(); 855 JCExpression t1 = term(); 856 accept(COLON); 857 JCExpression t2 = term1(); 858 return F.at(pos).Conditional(t, t1, t2); 859 } else { 860 return t; 861 } 862 } 863 864 /** Expression2 = Expression3 [Expression2Rest] 865 * Type2 = Type3 866 * TypeNoParams2 = TypeNoParams3 867 */ 868 JCExpression term2() { 869 JCExpression t = term3(); 870 if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) { 871 mode = EXPR; 872 return term2Rest(t, TreeInfo.orPrec); 873 } else { 874 return t; 875 } 876 } 877 878 /* Expression2Rest = {infixop Expression3} 879 * | Expression3 instanceof Type 880 * infixop = "||" 881 * | "&&" 882 * | "|" 883 * | "^" 884 * | "&" 885 * | "==" | "!=" 886 * | "<" | ">" | "<=" | ">=" 887 * | "<<" | ">>" | ">>>" 888 * | "+" | "-" 889 * | "*" | "/" | "%" 890 */ 891 JCExpression term2Rest(JCExpression t, int minprec) { 892 JCExpression[] odStack = newOdStack(); 893 Token[] opStack = newOpStack(); 894 895 // optimization, was odStack = new Tree[...]; opStack = new Tree[...]; 896 int top = 0; 897 odStack[0] = t; 898 int startPos = token.pos; 899 Token topOp = Tokens.DUMMY; 900 while (prec(token.kind) >= minprec) { 901 opStack[top] = topOp; 902 top++; 903 topOp = token; 904 nextToken(); 905 odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); 906 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { 907 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], 908 odStack[top]); 909 top--; 910 topOp = opStack[top]; 911 } 912 } 913 Assert.check(top == 0); 914 t = odStack[0]; 915 916 if (t.hasTag(JCTree.Tag.PLUS)) { 917 t = foldStrings(t); 918 } 919 920 odStackSupply.add(odStack); 921 opStackSupply.add(opStack); 922 return t; 923 } 924 //where 925 /** Construct a binary or type test node. 926 */ 927 private JCExpression makeOp(int pos, 928 TokenKind topOp, 929 JCExpression od1, 930 JCExpression od2) 931 { 932 if (topOp == INSTANCEOF) { 933 return F.at(pos).TypeTest(od1, od2); 934 } else { 935 return F.at(pos).Binary(optag(topOp), od1, od2); 936 } 937 } 938 /** If tree is a concatenation of string literals, replace it 939 * by a single literal representing the concatenated string. 940 */ 941 protected JCExpression foldStrings(JCExpression tree) { 942 if (!allowStringFolding) 943 return tree; 944 ListBuffer<JCExpression> opStack = new ListBuffer<>(); 945 ListBuffer<JCLiteral> litBuf = new ListBuffer<>(); 946 boolean needsFolding = false; 947 JCExpression curr = tree; 948 while (true) { 949 if (curr.hasTag(JCTree.Tag.PLUS)) { 950 JCBinary op = (JCBinary)curr; 951 needsFolding |= foldIfNeeded(op.rhs, litBuf, opStack, false); 952 curr = op.lhs; 953 } else { 954 needsFolding |= foldIfNeeded(curr, litBuf, opStack, true); 955 break; //last one! 956 } 957 } 958 if (needsFolding) { 959 List<JCExpression> ops = opStack.toList(); 960 JCExpression res = ops.head; 961 for (JCExpression op : ops.tail) { 962 res = F.at(op.getStartPosition()).Binary(optag(TokenKind.PLUS), res, op); 963 storeEnd(res, getEndPos(op)); 964 } 965 return res; 966 } else { 967 return tree; 968 } 969 } 970 971 private boolean foldIfNeeded(JCExpression tree, ListBuffer<JCLiteral> litBuf, 972 ListBuffer<JCExpression> opStack, boolean last) { 973 JCLiteral str = stringLiteral(tree); 974 if (str != null) { 975 litBuf.prepend(str); 976 return last && merge(litBuf, opStack); 977 } else { 978 boolean res = merge(litBuf, opStack); 979 litBuf.clear(); 980 opStack.prepend(tree); 981 return res; 982 } 983 } 984 985 boolean merge(ListBuffer<JCLiteral> litBuf, ListBuffer<JCExpression> opStack) { 986 if (litBuf.isEmpty()) { 987 return false; 988 } else if (litBuf.size() == 1) { 989 opStack.prepend(litBuf.first()); 990 return false; 991 } else { 992 JCExpression t = F.at(litBuf.first().getStartPosition()).Literal(TypeTag.CLASS, 993 litBuf.stream().map(lit -> (String)lit.getValue()).collect(Collectors.joining())); 994 storeEnd(t, litBuf.last().getEndPosition(endPosTable)); 995 opStack.prepend(t); 996 return true; 997 } 998 } 999 1000 private JCLiteral stringLiteral(JCTree tree) { 1001 if (tree.hasTag(LITERAL)) { 1002 JCLiteral lit = (JCLiteral)tree; 1003 if (lit.typetag == TypeTag.CLASS) { 1004 return lit; 1005 } 1006 } 1007 return null; 1008 } 1009 1010 1011 /** optimization: To save allocating a new operand/operator stack 1012 * for every binary operation, we use supplys. 1013 */ 1014 ArrayList<JCExpression[]> odStackSupply = new ArrayList<>(); 1015 ArrayList<Token[]> opStackSupply = new ArrayList<>(); 1016 1017 private JCExpression[] newOdStack() { 1018 if (odStackSupply.isEmpty()) 1019 return new JCExpression[infixPrecedenceLevels + 1]; 1020 return odStackSupply.remove(odStackSupply.size() - 1); 1021 } 1022 1023 private Token[] newOpStack() { 1024 if (opStackSupply.isEmpty()) 1025 return new Token[infixPrecedenceLevels + 1]; 1026 return opStackSupply.remove(opStackSupply.size() - 1); 1027 } 1028 1029 /** 1030 * Expression3 = PrefixOp Expression3 1031 * | "(" Expr | TypeNoParams ")" Expression3 1032 * | Primary {Selector} {PostfixOp} 1033 * 1034 * {@literal 1035 * Primary = "(" Expression ")" 1036 * | Literal 1037 * | [TypeArguments] THIS [Arguments] 1038 * | [TypeArguments] SUPER SuperSuffix 1039 * | NEW [TypeArguments] Creator 1040 * | "(" Arguments ")" "->" ( Expression | Block ) 1041 * | Ident "->" ( Expression | Block ) 1042 * | [Annotations] Ident { "." [Annotations] Ident } 1043 * | Expression3 MemberReferenceSuffix 1044 * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 1045 * | Arguments 1046 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 1047 * ] 1048 * | BasicType BracketsOpt "." CLASS 1049 * } 1050 * 1051 * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" 1052 * PostfixOp = "++" | "--" 1053 * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt 1054 * | BasicType 1055 * TypeNoParams3 = Ident { "." Ident } BracketsOpt 1056 * Selector = "." [TypeArguments] Ident [Arguments] 1057 * | "." THIS 1058 * | "." [TypeArguments] SUPER SuperSuffix 1059 * | "." NEW [TypeArguments] InnerCreator 1060 * | "[" Expression "]" 1061 * TypeSelector = "." Ident [TypeArguments] 1062 * SuperSuffix = Arguments | "." Ident [Arguments] 1063 */ 1064 protected JCExpression term3() { 1065 int pos = token.pos; 1066 JCExpression t; 1067 List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); 1068 switch (token.kind) { 1069 case QUES: 1070 if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { 1071 mode = TYPE; 1072 return typeArgument(); 1073 } else 1074 return illegal(); 1075 case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: 1076 if (typeArgs == null && (mode & EXPR) != 0) { 1077 TokenKind tk = token.kind; 1078 nextToken(); 1079 mode = EXPR; 1080 if (tk == SUB && 1081 (token.kind == INTLITERAL || token.kind == LONGLITERAL) && 1082 token.radix() == 10) { 1083 mode = EXPR; 1084 t = literal(names.hyphen, pos); 1085 } else { 1086 t = term3(); 1087 return F.at(pos).Unary(unoptag(tk), t); 1088 } 1089 } else return illegal(); 1090 break; 1091 case LPAREN: 1092 if (typeArgs == null && (mode & EXPR) != 0) { 1093 ParensResult pres = analyzeParens(); 1094 switch (pres) { 1095 case CAST: 1096 accept(LPAREN); 1097 mode = TYPE; 1098 int pos1 = pos; 1099 List<JCExpression> targets = List.of(t = parseType()); 1100 while (token.kind == AMP) { 1101 checkSourceLevel(Feature.INTERSECTION_TYPES_IN_CAST); 1102 accept(AMP); 1103 targets = targets.prepend(parseType()); 1104 } 1105 if (targets.length() > 1) { 1106 t = toP(F.at(pos1).TypeIntersection(targets.reverse())); 1107 } 1108 accept(RPAREN); 1109 mode = EXPR; 1110 JCExpression t1 = term3(); 1111 return F.at(pos).TypeCast(t, t1); 1112 case IMPLICIT_LAMBDA: 1113 case EXPLICIT_LAMBDA: 1114 t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos); 1115 break; 1116 default: //PARENS 1117 accept(LPAREN); 1118 mode = EXPR; 1119 t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec))); 1120 accept(RPAREN); 1121 t = toP(F.at(pos).Parens(t)); 1122 break; 1123 } 1124 } else { 1125 return illegal(); 1126 } 1127 break; 1128 case THIS: 1129 if ((mode & EXPR) != 0) { 1130 mode = EXPR; 1131 t = to(F.at(pos).Ident(names._this)); 1132 nextToken(); 1133 if (typeArgs == null) 1134 t = argumentsOpt(null, t); 1135 else 1136 t = arguments(typeArgs, t); 1137 typeArgs = null; 1138 } else return illegal(); 1139 break; 1140 case SUPER: 1141 if ((mode & EXPR) != 0) { 1142 mode = EXPR; 1143 t = to(F.at(pos).Ident(names._super)); 1144 t = superSuffix(typeArgs, t); 1145 typeArgs = null; 1146 } else return illegal(); 1147 break; 1148 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: 1149 case CHARLITERAL: case STRINGLITERAL: 1150 case TRUE: case FALSE: case NULL: 1151 if (typeArgs == null && (mode & EXPR) != 0) { 1152 mode = EXPR; 1153 t = literal(names.empty); 1154 } else return illegal(); 1155 break; 1156 case NEW: 1157 if (typeArgs != null) return illegal(); 1158 if ((mode & EXPR) != 0) { 1159 mode = EXPR; 1160 nextToken(); 1161 if (token.kind == LT) typeArgs = typeArguments(false); 1162 t = creator(pos, typeArgs); 1163 typeArgs = null; 1164 } else return illegal(); 1165 break; 1166 case MONKEYS_AT: 1167 // Only annotated cast types and method references are valid 1168 List<JCAnnotation> typeAnnos = typeAnnotationsOpt(); 1169 if (typeAnnos.isEmpty()) { 1170 // else there would be no '@' 1171 throw new AssertionError("Expected type annotations, but found none!"); 1172 } 1173 1174 JCExpression expr = term3(); 1175 1176 if ((mode & TYPE) == 0) { 1177 // Type annotations on class literals no longer legal 1178 switch (expr.getTag()) { 1179 case REFERENCE: { 1180 JCMemberReference mref = (JCMemberReference) expr; 1181 mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr)); 1182 t = mref; 1183 break; 1184 } 1185 case SELECT: { 1186 JCFieldAccess sel = (JCFieldAccess) expr; 1187 1188 if (sel.name != names._class) { 1189 return illegal(); 1190 } else { 1191 log.error(token.pos, Errors.NoAnnotationsOnDotClass); 1192 return expr; 1193 } 1194 } 1195 default: 1196 return illegal(typeAnnos.head.pos); 1197 } 1198 1199 } else { 1200 // Type annotations targeting a cast 1201 t = insertAnnotationsToMostInner(expr, typeAnnos, false); 1202 } 1203 break; 1204 case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM: 1205 if (typeArgs != null) return illegal(); 1206 if ((mode & EXPR) != 0 && peekToken(ARROW)) { 1207 t = lambdaExpressionOrStatement(false, false, pos); 1208 } else { 1209 t = toP(F.at(token.pos).Ident(ident())); 1210 loop: while (true) { 1211 pos = token.pos; 1212 final List<JCAnnotation> annos = typeAnnotationsOpt(); 1213 1214 // need to report an error later if LBRACKET is for array 1215 // index access rather than array creation level 1216 if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS) 1217 return illegal(annos.head.pos); 1218 1219 switch (token.kind) { 1220 case LBRACKET: 1221 nextToken(); 1222 if (token.kind == RBRACKET) { 1223 nextToken(); 1224 t = bracketsOpt(t); 1225 t = toP(F.at(pos).TypeArray(t)); 1226 if (annos.nonEmpty()) { 1227 t = toP(F.at(pos).AnnotatedType(annos, t)); 1228 } 1229 t = bracketsSuffix(t); 1230 } else { 1231 if ((mode & EXPR) != 0) { 1232 mode = EXPR; 1233 JCExpression t1 = term(); 1234 if (!annos.isEmpty()) t = illegal(annos.head.pos); 1235 t = to(F.at(pos).Indexed(t, t1)); 1236 } 1237 accept(RBRACKET); 1238 } 1239 break loop; 1240 case LPAREN: 1241 if ((mode & EXPR) != 0) { 1242 mode = EXPR; 1243 t = arguments(typeArgs, t); 1244 if (!annos.isEmpty()) t = illegal(annos.head.pos); 1245 typeArgs = null; 1246 } 1247 break loop; 1248 case DOT: 1249 nextToken(); 1250 if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) { 1251 return illegal(); 1252 } 1253 int oldmode = mode; 1254 mode &= ~NOPARAMS; 1255 typeArgs = typeArgumentsOpt(EXPR); 1256 mode = oldmode; 1257 if ((mode & EXPR) != 0) { 1258 switch (token.kind) { 1259 case CLASS: 1260 if (typeArgs != null) return illegal(); 1261 mode = EXPR; 1262 t = to(F.at(pos).Select(t, names._class)); 1263 nextToken(); 1264 break loop; 1265 case THIS: 1266 if (typeArgs != null) return illegal(); 1267 mode = EXPR; 1268 t = to(F.at(pos).Select(t, names._this)); 1269 nextToken(); 1270 break loop; 1271 case SUPER: 1272 mode = EXPR; 1273 t = to(F.at(pos).Select(t, names._super)); 1274 t = superSuffix(typeArgs, t); 1275 typeArgs = null; 1276 break loop; 1277 case NEW: 1278 if (typeArgs != null) return illegal(); 1279 mode = EXPR; 1280 int pos1 = token.pos; 1281 nextToken(); 1282 if (token.kind == LT) typeArgs = typeArguments(false); 1283 t = innerCreator(pos1, typeArgs, t); 1284 typeArgs = null; 1285 break loop; 1286 } 1287 } 1288 1289 List<JCAnnotation> tyannos = null; 1290 if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { 1291 tyannos = typeAnnotationsOpt(); 1292 } 1293 // typeArgs saved for next loop iteration. 1294 t = toP(F.at(pos).Select(t, ident())); 1295 if (tyannos != null && tyannos.nonEmpty()) { 1296 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); 1297 } 1298 break; 1299 case ELLIPSIS: 1300 if (this.permitTypeAnnotationsPushBack) { 1301 this.typeAnnotationsPushedBack = annos; 1302 } else if (annos.nonEmpty()) { 1303 // Don't return here -- error recovery attempt 1304 illegal(annos.head.pos); 1305 } 1306 break loop; 1307 case LT: 1308 if ((mode & TYPE) == 0 && isUnboundMemberRef()) { 1309 //this is an unbound method reference whose qualifier 1310 //is a generic type i.e. A<S>::m 1311 int pos1 = token.pos; 1312 accept(LT); 1313 ListBuffer<JCExpression> args = new ListBuffer<>(); 1314 args.append(typeArgument()); 1315 while (token.kind == COMMA) { 1316 nextToken(); 1317 args.append(typeArgument()); 1318 } 1319 accept(GT); 1320 t = toP(F.at(pos1).TypeApply(t, args.toList())); 1321 while (token.kind == DOT) { 1322 nextToken(); 1323 mode = TYPE; 1324 t = toP(F.at(token.pos).Select(t, ident())); 1325 t = typeArgumentsOpt(t); 1326 } 1327 t = bracketsOpt(t); 1328 if (token.kind != COLCOL) { 1329 //method reference expected here 1330 t = illegal(); 1331 } 1332 mode = EXPR; 1333 return term3Rest(t, typeArgs); 1334 } 1335 break loop; 1336 default: 1337 break loop; 1338 } 1339 } 1340 } 1341 if (typeArgs != null) illegal(); 1342 t = typeArgumentsOpt(t); 1343 break; 1344 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1345 case DOUBLE: case BOOLEAN: 1346 if (typeArgs != null) illegal(); 1347 t = bracketsSuffix(bracketsOpt(basicType())); 1348 break; 1349 case VOID: 1350 if (typeArgs != null) illegal(); 1351 if ((mode & EXPR) != 0) { 1352 nextToken(); 1353 if (token.kind == DOT) { 1354 JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID)); 1355 t = bracketsSuffix(ti); 1356 } else { 1357 return illegal(pos); 1358 } 1359 } else { 1360 // Support the corner case of myMethodHandle.<void>invoke() by passing 1361 // a void type (like other primitive types) to the next phase. 1362 // The error will be reported in Attr.attribTypes or Attr.visitApply. 1363 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID)); 1364 nextToken(); 1365 return ti; 1366 //return illegal(); 1367 } 1368 break; 1369 default: 1370 return illegal(); 1371 } 1372 return term3Rest(t, typeArgs); 1373 } 1374 1375 JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) { 1376 if (typeArgs != null) illegal(); 1377 while (true) { 1378 int pos1 = token.pos; 1379 final List<JCAnnotation> annos = typeAnnotationsOpt(); 1380 1381 if (token.kind == LBRACKET) { 1382 nextToken(); 1383 if ((mode & TYPE) != 0) { 1384 int oldmode = mode; 1385 mode = TYPE; 1386 if (token.kind == RBRACKET) { 1387 nextToken(); 1388 t = bracketsOpt(t); 1389 t = toP(F.at(pos1).TypeArray(t)); 1390 if (token.kind == COLCOL) { 1391 mode = EXPR; 1392 continue; 1393 } 1394 if (annos.nonEmpty()) { 1395 t = toP(F.at(pos1).AnnotatedType(annos, t)); 1396 } 1397 return t; 1398 } 1399 mode = oldmode; 1400 } 1401 if ((mode & EXPR) != 0) { 1402 mode = EXPR; 1403 JCExpression t1 = term(); 1404 t = to(F.at(pos1).Indexed(t, t1)); 1405 } 1406 accept(RBRACKET); 1407 } else if (token.kind == DOT) { 1408 nextToken(); 1409 typeArgs = typeArgumentsOpt(EXPR); 1410 if (token.kind == SUPER && (mode & EXPR) != 0) { 1411 mode = EXPR; 1412 t = to(F.at(pos1).Select(t, names._super)); 1413 nextToken(); 1414 t = arguments(typeArgs, t); 1415 typeArgs = null; 1416 } else if (token.kind == NEW && (mode & EXPR) != 0) { 1417 if (typeArgs != null) return illegal(); 1418 mode = EXPR; 1419 int pos2 = token.pos; 1420 nextToken(); 1421 if (token.kind == LT) typeArgs = typeArguments(false); 1422 t = innerCreator(pos2, typeArgs, t); 1423 typeArgs = null; 1424 } else { 1425 List<JCAnnotation> tyannos = null; 1426 if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) { 1427 // is the mode check needed? 1428 tyannos = typeAnnotationsOpt(); 1429 } 1430 t = toP(F.at(pos1).Select(t, ident(true))); 1431 if (tyannos != null && tyannos.nonEmpty()) { 1432 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); 1433 } 1434 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 1435 typeArgs = null; 1436 } 1437 } else if ((mode & EXPR) != 0 && token.kind == COLCOL) { 1438 mode = EXPR; 1439 if (typeArgs != null) return illegal(); 1440 accept(COLCOL); 1441 t = memberReferenceSuffix(pos1, t); 1442 } else { 1443 if (!annos.isEmpty()) { 1444 if (permitTypeAnnotationsPushBack) 1445 typeAnnotationsPushedBack = annos; 1446 else 1447 return illegal(annos.head.pos); 1448 } 1449 break; 1450 } 1451 } 1452 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) { 1453 mode = EXPR; 1454 t = to(F.at(token.pos).Unary( 1455 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t)); 1456 nextToken(); 1457 } 1458 return toP(t); 1459 } 1460 1461 /** 1462 * If we see an identifier followed by a '<' it could be an unbound 1463 * method reference or a binary expression. To disambiguate, look for a 1464 * matching '>' and see if the subsequent terminal is either '.' or '::'. 1465 */ 1466 @SuppressWarnings("fallthrough") 1467 boolean isUnboundMemberRef() { 1468 int pos = 0, depth = 0; 1469 outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) { 1470 switch (t.kind) { 1471 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER: 1472 case DOT: case RBRACKET: case LBRACKET: case COMMA: 1473 case BYTE: case SHORT: case INT: case LONG: case FLOAT: 1474 case DOUBLE: case BOOLEAN: case CHAR: 1475 case MONKEYS_AT: 1476 break; 1477 1478 case LPAREN: 1479 // skip annotation values 1480 int nesting = 0; 1481 for (; ; pos++) { 1482 TokenKind tk2 = S.token(pos).kind; 1483 switch (tk2) { 1484 case EOF: 1485 return false; 1486 case LPAREN: 1487 nesting++; 1488 break; 1489 case RPAREN: 1490 nesting--; 1491 if (nesting == 0) { 1492 continue outer; 1493 } 1494 break; 1495 } 1496 } 1497 1498 case LT: 1499 depth++; break; 1500 case GTGTGT: 1501 depth--; 1502 case GTGT: 1503 depth--; 1504 case GT: 1505 depth--; 1506 if (depth == 0) { 1507 TokenKind nextKind = S.token(pos + 1).kind; 1508 return 1509 nextKind == TokenKind.DOT || 1510 nextKind == TokenKind.LBRACKET || 1511 nextKind == TokenKind.COLCOL; 1512 } 1513 break; 1514 default: 1515 return false; 1516 } 1517 } 1518 } 1519 1520 /** 1521 * If we see an identifier followed by a '<' it could be an unbound 1522 * method reference or a binary expression. To disambiguate, look for a 1523 * matching '>' and see if the subsequent terminal is either '.' or '::'. 1524 */ 1525 @SuppressWarnings("fallthrough") 1526 ParensResult analyzeParens() { 1527 int depth = 0; 1528 boolean type = false; 1529 outer: for (int lookahead = 0 ; ; lookahead++) { 1530 TokenKind tk = S.token(lookahead).kind; 1531 switch (tk) { 1532 case COMMA: 1533 type = true; 1534 case EXTENDS: case SUPER: case DOT: case AMP: 1535 //skip 1536 break; 1537 case QUES: 1538 if (peekToken(lookahead, EXTENDS) || 1539 peekToken(lookahead, SUPER)) { 1540 //wildcards 1541 type = true; 1542 } 1543 break; 1544 case BYTE: case SHORT: case INT: case LONG: case FLOAT: 1545 case DOUBLE: case BOOLEAN: case CHAR: case VOID: 1546 if (peekToken(lookahead, RPAREN)) { 1547 //Type, ')' -> cast 1548 return ParensResult.CAST; 1549 } else if (peekToken(lookahead, LAX_IDENTIFIER)) { 1550 //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda 1551 return ParensResult.EXPLICIT_LAMBDA; 1552 } 1553 break; 1554 case LPAREN: 1555 if (lookahead != 0) { 1556 // '(' in a non-starting position -> parens 1557 return ParensResult.PARENS; 1558 } else if (peekToken(lookahead, RPAREN)) { 1559 // '(', ')' -> explicit lambda 1560 return ParensResult.EXPLICIT_LAMBDA; 1561 } 1562 break; 1563 case RPAREN: 1564 // if we have seen something that looks like a type, 1565 // then it's a cast expression 1566 if (type) return ParensResult.CAST; 1567 // otherwise, disambiguate cast vs. parenthesized expression 1568 // based on subsequent token. 1569 switch (S.token(lookahead + 1).kind) { 1570 /*case PLUSPLUS: case SUBSUB: */ 1571 case BANG: case TILDE: 1572 case LPAREN: case THIS: case SUPER: 1573 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 1574 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 1575 case TRUE: case FALSE: case NULL: 1576 case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE: 1577 case BYTE: case SHORT: case CHAR: case INT: 1578 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 1579 return ParensResult.CAST; 1580 default: 1581 return ParensResult.PARENS; 1582 } 1583 case UNDERSCORE: 1584 case ASSERT: 1585 case ENUM: 1586 case IDENTIFIER: 1587 if (peekToken(lookahead, LAX_IDENTIFIER)) { 1588 // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda 1589 return ParensResult.EXPLICIT_LAMBDA; 1590 } else if (peekToken(lookahead, RPAREN, ARROW)) { 1591 // Identifier, ')' '->' -> implicit lambda 1592 return ParensResult.IMPLICIT_LAMBDA; 1593 } 1594 type = false; 1595 break; 1596 case FINAL: 1597 case ELLIPSIS: 1598 //those can only appear in explicit lambdas 1599 return ParensResult.EXPLICIT_LAMBDA; 1600 case MONKEYS_AT: 1601 type = true; 1602 lookahead += 1; //skip '@' 1603 while (peekToken(lookahead, DOT)) { 1604 lookahead += 2; 1605 } 1606 if (peekToken(lookahead, LPAREN)) { 1607 lookahead++; 1608 //skip annotation values 1609 int nesting = 0; 1610 for (; ; lookahead++) { 1611 TokenKind tk2 = S.token(lookahead).kind; 1612 switch (tk2) { 1613 case EOF: 1614 return ParensResult.PARENS; 1615 case LPAREN: 1616 nesting++; 1617 break; 1618 case RPAREN: 1619 nesting--; 1620 if (nesting == 0) { 1621 continue outer; 1622 } 1623 break; 1624 } 1625 } 1626 } 1627 break; 1628 case LBRACKET: 1629 if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) { 1630 // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda 1631 return ParensResult.EXPLICIT_LAMBDA; 1632 } else if (peekToken(lookahead, RBRACKET, RPAREN) || 1633 peekToken(lookahead, RBRACKET, AMP)) { 1634 // '[', ']', ')' -> cast 1635 // '[', ']', '&' -> cast (intersection type) 1636 return ParensResult.CAST; 1637 } else if (peekToken(lookahead, RBRACKET)) { 1638 //consume the ']' and skip 1639 type = true; 1640 lookahead++; 1641 break; 1642 } else { 1643 return ParensResult.PARENS; 1644 } 1645 case LT: 1646 depth++; break; 1647 case GTGTGT: 1648 depth--; 1649 case GTGT: 1650 depth--; 1651 case GT: 1652 depth--; 1653 if (depth == 0) { 1654 if (peekToken(lookahead, RPAREN) || 1655 peekToken(lookahead, AMP)) { 1656 // '>', ')' -> cast 1657 // '>', '&' -> cast 1658 return ParensResult.CAST; 1659 } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) || 1660 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) || 1661 peekToken(lookahead, ELLIPSIS)) { 1662 // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda 1663 // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda 1664 // '>', '...' -> explicit lambda 1665 return ParensResult.EXPLICIT_LAMBDA; 1666 } 1667 //it looks a type, but could still be (i) a cast to generic type, 1668 //(ii) an unbound method reference or (iii) an explicit lambda 1669 type = true; 1670 break; 1671 } else if (depth < 0) { 1672 //unbalanced '<', '>' - not a generic type 1673 return ParensResult.PARENS; 1674 } 1675 break; 1676 default: 1677 //this includes EOF 1678 return ParensResult.PARENS; 1679 } 1680 } 1681 } 1682 1683 /** Accepts all identifier-like tokens */ 1684 protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM; 1685 1686 enum ParensResult { 1687 CAST, 1688 EXPLICIT_LAMBDA, 1689 IMPLICIT_LAMBDA, 1690 PARENS 1691 } 1692 1693 JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) { 1694 List<JCVariableDecl> params = explicitParams ? 1695 formalParameters(true) : 1696 implicitParameters(hasParens); 1697 1698 return lambdaExpressionOrStatementRest(params, pos); 1699 } 1700 1701 JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) { 1702 checkSourceLevel(Feature.LAMBDA); 1703 accept(ARROW); 1704 1705 return token.kind == LBRACE ? 1706 lambdaStatement(args, pos, token.pos) : 1707 lambdaExpression(args, pos); 1708 } 1709 1710 JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) { 1711 JCBlock block = block(pos2, 0); 1712 return toP(F.at(pos).Lambda(args, block)); 1713 } 1714 1715 JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) { 1716 JCTree expr = parseExpression(); 1717 return toP(F.at(pos).Lambda(args, expr)); 1718 } 1719 1720 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 1721 */ 1722 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 1723 nextToken(); 1724 if (token.kind == LPAREN || typeArgs != null) { 1725 t = arguments(typeArgs, t); 1726 } else if (token.kind == COLCOL) { 1727 if (typeArgs != null) return illegal(); 1728 t = memberReferenceSuffix(t); 1729 } else { 1730 int pos = token.pos; 1731 accept(DOT); 1732 typeArgs = (token.kind == LT) ? typeArguments(false) : null; 1733 t = toP(F.at(pos).Select(t, ident())); 1734 t = argumentsOpt(typeArgs, t); 1735 } 1736 return t; 1737 } 1738 1739 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 1740 */ 1741 JCPrimitiveTypeTree basicType() { 1742 JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind))); 1743 nextToken(); 1744 return t; 1745 } 1746 1747 /** ArgumentsOpt = [ Arguments ] 1748 */ 1749 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 1750 if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) { 1751 mode = EXPR; 1752 return arguments(typeArgs, t); 1753 } else { 1754 return t; 1755 } 1756 } 1757 1758 /** Arguments = "(" [Expression { COMMA Expression }] ")" 1759 */ 1760 List<JCExpression> arguments() { 1761 ListBuffer<JCExpression> args = new ListBuffer<>(); 1762 if (token.kind == LPAREN) { 1763 nextToken(); 1764 if (token.kind != RPAREN) { 1765 args.append(parseExpression()); 1766 while (token.kind == COMMA) { 1767 nextToken(); 1768 args.append(parseExpression()); 1769 } 1770 } 1771 accept(RPAREN); 1772 } else { 1773 syntaxError(token.pos, "expected", LPAREN); 1774 } 1775 return args.toList(); 1776 } 1777 1778 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 1779 int pos = token.pos; 1780 List<JCExpression> args = arguments(); 1781 return toP(F.at(pos).Apply(typeArgs, t, args)); 1782 } 1783 1784 /** TypeArgumentsOpt = [ TypeArguments ] 1785 */ 1786 JCExpression typeArgumentsOpt(JCExpression t) { 1787 if (token.kind == LT && 1788 (mode & TYPE) != 0 && 1789 (mode & NOPARAMS) == 0) { 1790 mode = TYPE; 1791 return typeArguments(t, false); 1792 } else { 1793 return t; 1794 } 1795 } 1796 List<JCExpression> typeArgumentsOpt() { 1797 return typeArgumentsOpt(TYPE); 1798 } 1799 1800 List<JCExpression> typeArgumentsOpt(int useMode) { 1801 if (token.kind == LT) { 1802 if ((mode & useMode) == 0 || 1803 (mode & NOPARAMS) != 0) { 1804 illegal(); 1805 } 1806 mode = useMode; 1807 return typeArguments(false); 1808 } 1809 return null; 1810 } 1811 1812 /** 1813 * {@literal 1814 * TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 1815 * } 1816 */ 1817 List<JCExpression> typeArguments(boolean diamondAllowed) { 1818 if (token.kind == LT) { 1819 nextToken(); 1820 if (token.kind == GT && diamondAllowed) { 1821 checkSourceLevel(Feature.DIAMOND); 1822 mode |= DIAMOND; 1823 nextToken(); 1824 return List.nil(); 1825 } else { 1826 ListBuffer<JCExpression> args = new ListBuffer<>(); 1827 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1828 while (token.kind == COMMA) { 1829 nextToken(); 1830 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1831 } 1832 switch (token.kind) { 1833 1834 case GTGTGTEQ: case GTGTEQ: case GTEQ: 1835 case GTGTGT: case GTGT: 1836 token = S.split(); 1837 break; 1838 case GT: 1839 nextToken(); 1840 break; 1841 default: 1842 args.append(syntaxError(token.pos, "expected", GT)); 1843 break; 1844 } 1845 return args.toList(); 1846 } 1847 } else { 1848 return List.of(syntaxError(token.pos, "expected", LT)); 1849 } 1850 } 1851 1852 /** 1853 * {@literal 1854 * TypeArgument = Type 1855 * | [Annotations] "?" 1856 * | [Annotations] "?" EXTENDS Type {"&" Type} 1857 * | [Annotations] "?" SUPER Type 1858 * } 1859 */ 1860 JCExpression typeArgument() { 1861 List<JCAnnotation> annotations = typeAnnotationsOpt(); 1862 if (token.kind != QUES) return parseType(false, annotations); 1863 int pos = token.pos; 1864 nextToken(); 1865 JCExpression result; 1866 if (token.kind == EXTENDS) { 1867 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS)); 1868 nextToken(); 1869 JCExpression bound = parseType(); 1870 result = F.at(pos).Wildcard(t, bound); 1871 } else if (token.kind == SUPER) { 1872 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); 1873 nextToken(); 1874 JCExpression bound = parseType(); 1875 result = F.at(pos).Wildcard(t, bound); 1876 } else if (LAX_IDENTIFIER.accepts(token.kind)) { 1877 //error recovery 1878 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1879 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1880 JCIdent id = toP(F.at(token.pos).Ident(ident())); 1881 JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1882 reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER); 1883 result = err; 1884 } else { 1885 TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND)); 1886 result = toP(F.at(pos).Wildcard(t, null)); 1887 } 1888 if (!annotations.isEmpty()) { 1889 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result)); 1890 } 1891 return result; 1892 } 1893 1894 JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) { 1895 int pos = token.pos; 1896 List<JCExpression> args = typeArguments(diamondAllowed); 1897 return toP(F.at(pos).TypeApply(t, args)); 1898 } 1899 1900 /** 1901 * BracketsOpt = { [Annotations] "[" "]" }* 1902 * 1903 * <p> 1904 * 1905 * <code>annotations</code> is the list of annotations targeting 1906 * the expression <code>t</code>. 1907 */ 1908 private JCExpression bracketsOpt(JCExpression t, 1909 List<JCAnnotation> annotations) { 1910 List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); 1911 1912 if (token.kind == LBRACKET) { 1913 int pos = token.pos; 1914 nextToken(); 1915 t = bracketsOptCont(t, pos, nextLevelAnnotations); 1916 } else if (!nextLevelAnnotations.isEmpty()) { 1917 if (permitTypeAnnotationsPushBack) { 1918 this.typeAnnotationsPushedBack = nextLevelAnnotations; 1919 } else { 1920 return illegal(nextLevelAnnotations.head.pos); 1921 } 1922 } 1923 1924 if (!annotations.isEmpty()) { 1925 t = toP(F.at(token.pos).AnnotatedType(annotations, t)); 1926 } 1927 return t; 1928 } 1929 1930 /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ] 1931 */ 1932 private JCExpression bracketsOpt(JCExpression t) { 1933 return bracketsOpt(t, List.nil()); 1934 } 1935 1936 private JCExpression bracketsOptCont(JCExpression t, int pos, 1937 List<JCAnnotation> annotations) { 1938 accept(RBRACKET); 1939 t = bracketsOpt(t); 1940 t = toP(F.at(pos).TypeArray(t)); 1941 if (annotations.nonEmpty()) { 1942 t = toP(F.at(pos).AnnotatedType(annotations, t)); 1943 } 1944 return t; 1945 } 1946 1947 /** BracketsSuffixExpr = "." CLASS 1948 * BracketsSuffixType = 1949 */ 1950 JCExpression bracketsSuffix(JCExpression t) { 1951 if ((mode & EXPR) != 0 && token.kind == DOT) { 1952 mode = EXPR; 1953 int pos = token.pos; 1954 nextToken(); 1955 accept(CLASS); 1956 if (token.pos == endPosTable.errorEndPos) { 1957 // error recovery 1958 Name name; 1959 if (LAX_IDENTIFIER.accepts(token.kind)) { 1960 name = token.name(); 1961 nextToken(); 1962 } else { 1963 name = names.error; 1964 } 1965 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name)))); 1966 } else { 1967 Tag tag = t.getTag(); 1968 // Type annotations are illegal on class literals. Annotated non array class literals 1969 // are complained about directly in term3(), Here check for type annotations on dimensions 1970 // taking care to handle some interior dimension(s) being annotated. 1971 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE) 1972 syntaxError("no.annotations.on.dot.class"); 1973 t = toP(F.at(pos).Select(t, names._class)); 1974 } 1975 } else if ((mode & TYPE) != 0) { 1976 if (token.kind != COLCOL) { 1977 mode = TYPE; 1978 } 1979 } else if (token.kind != COLCOL) { 1980 syntaxError(token.pos, "dot.class.expected"); 1981 } 1982 return t; 1983 } 1984 1985 /** 1986 * MemberReferenceSuffix = "::" [TypeArguments] Ident 1987 * | "::" [TypeArguments] "new" 1988 */ 1989 JCExpression memberReferenceSuffix(JCExpression t) { 1990 int pos1 = token.pos; 1991 accept(COLCOL); 1992 return memberReferenceSuffix(pos1, t); 1993 } 1994 1995 JCExpression memberReferenceSuffix(int pos1, JCExpression t) { 1996 checkSourceLevel(Feature.METHOD_REFERENCES); 1997 mode = EXPR; 1998 List<JCExpression> typeArgs = null; 1999 if (token.kind == LT) { 2000 typeArgs = typeArguments(false); 2001 } 2002 Name refName; 2003 ReferenceMode refMode; 2004 if (token.kind == NEW) { 2005 refMode = ReferenceMode.NEW; 2006 refName = names.init; 2007 nextToken(); 2008 } else { 2009 refMode = ReferenceMode.INVOKE; 2010 refName = ident(); 2011 } 2012 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs)); 2013 } 2014 2015 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 2016 */ 2017 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 2018 List<JCAnnotation> newAnnotations = typeAnnotationsOpt(); 2019 2020 switch (token.kind) { 2021 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 2022 case DOUBLE: case BOOLEAN: 2023 if (typeArgs == null) { 2024 if (newAnnotations.isEmpty()) { 2025 return arrayCreatorRest(newpos, basicType()); 2026 } else { 2027 return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType()))); 2028 } 2029 } 2030 break; 2031 default: 2032 } 2033 JCExpression t = qualident(true); 2034 2035 int oldmode = mode; 2036 mode = TYPE; 2037 boolean diamondFound = false; 2038 int lastTypeargsPos = -1; 2039 if (token.kind == LT) { 2040 lastTypeargsPos = token.pos; 2041 t = typeArguments(t, true); 2042 diamondFound = (mode & DIAMOND) != 0; 2043 } 2044 while (token.kind == DOT) { 2045 if (diamondFound) { 2046 //cannot select after a diamond 2047 illegal(); 2048 } 2049 int pos = token.pos; 2050 nextToken(); 2051 List<JCAnnotation> tyannos = typeAnnotationsOpt(); 2052 t = toP(F.at(pos).Select(t, ident())); 2053 2054 if (tyannos != null && tyannos.nonEmpty()) { 2055 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t)); 2056 } 2057 2058 if (token.kind == LT) { 2059 lastTypeargsPos = token.pos; 2060 t = typeArguments(t, true); 2061 diamondFound = (mode & DIAMOND) != 0; 2062 } 2063 } 2064 mode = oldmode; 2065 if (token.kind == LBRACKET || token.kind == MONKEYS_AT) { 2066 // handle type annotations for non primitive arrays 2067 if (newAnnotations.nonEmpty()) { 2068 t = insertAnnotationsToMostInner(t, newAnnotations, false); 2069 } 2070 2071 JCExpression e = arrayCreatorRest(newpos, t); 2072 if (diamondFound) { 2073 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond"); 2074 return toP(F.at(newpos).Erroneous(List.of(e))); 2075 } 2076 else if (typeArgs != null) { 2077 int pos = newpos; 2078 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 2079 // note: this should always happen but we should 2080 // not rely on this as the parser is continuously 2081 // modified to improve error recovery. 2082 pos = typeArgs.head.pos; 2083 } 2084 setErrorEndPos(S.prevToken().endPos); 2085 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e)); 2086 reportSyntaxError(err, "cannot.create.array.with.type.arguments"); 2087 return toP(err); 2088 } 2089 return e; 2090 } else if (token.kind == LPAREN) { 2091 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); 2092 if (newClass.def != null) { 2093 assert newClass.def.mods.annotations.isEmpty(); 2094 if (newAnnotations.nonEmpty()) { 2095 // Add type and declaration annotations to the new class; 2096 // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass) 2097 // will later remove all type annotations and only leave the 2098 // declaration annotations. 2099 newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos); 2100 newClass.def.mods.annotations = newAnnotations; 2101 } 2102 } else { 2103 // handle type annotations for instantiations 2104 if (newAnnotations.nonEmpty()) { 2105 t = insertAnnotationsToMostInner(t, newAnnotations, false); 2106 newClass.clazz = t; 2107 } 2108 } 2109 return newClass; 2110 } else { 2111 setErrorEndPos(token.pos); 2112 reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET); 2113 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null)); 2114 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 2115 } 2116 } 2117 2118 /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest 2119 */ 2120 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 2121 List<JCAnnotation> newAnnotations = typeAnnotationsOpt(); 2122 2123 JCExpression t = toP(F.at(token.pos).Ident(ident())); 2124 2125 if (newAnnotations.nonEmpty()) { 2126 t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t)); 2127 } 2128 2129 if (token.kind == LT) { 2130 int oldmode = mode; 2131 t = typeArguments(t, true); 2132 mode = oldmode; 2133 } 2134 return classCreatorRest(newpos, encl, typeArgs, t); 2135 } 2136 2137 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer 2138 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt ) 2139 */ 2140 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 2141 List<JCAnnotation> annos = typeAnnotationsOpt(); 2142 2143 accept(LBRACKET); 2144 if (token.kind == RBRACKET) { 2145 accept(RBRACKET); 2146 elemtype = bracketsOpt(elemtype, annos); 2147 if (token.kind == LBRACE) { 2148 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype); 2149 if (annos.nonEmpty()) { 2150 // when an array initializer is present then 2151 // the parsed annotations should target the 2152 // new array tree 2153 // bracketsOpt inserts the annotation in 2154 // elemtype, and it needs to be corrected 2155 // 2156 JCAnnotatedType annotated = (JCAnnotatedType)elemtype; 2157 assert annotated.annotations == annos; 2158 na.annotations = annotated.annotations; 2159 na.elemtype = annotated.underlyingType; 2160 } 2161 return na; 2162 } else { 2163 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.nil(), null)); 2164 return syntaxError(token.pos, List.of(t), "array.dimension.missing"); 2165 } 2166 } else { 2167 ListBuffer<JCExpression> dims = new ListBuffer<>(); 2168 2169 // maintain array dimension type annotations 2170 ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>(); 2171 dimAnnotations.append(annos); 2172 2173 dims.append(parseExpression()); 2174 accept(RBRACKET); 2175 while (token.kind == LBRACKET 2176 || token.kind == MONKEYS_AT) { 2177 List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt(); 2178 int pos = token.pos; 2179 nextToken(); 2180 if (token.kind == RBRACKET) { 2181 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 2182 } else { 2183 if (token.kind == RBRACKET) { // no dimension 2184 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 2185 } else { 2186 dimAnnotations.append(maybeDimAnnos); 2187 dims.append(parseExpression()); 2188 accept(RBRACKET); 2189 } 2190 } 2191 } 2192 2193 List<JCExpression> elems = null; 2194 int errpos = token.pos; 2195 2196 if (token.kind == LBRACE) { 2197 elems = arrayInitializerElements(newpos, elemtype); 2198 } 2199 2200 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems)); 2201 na.dimAnnotations = dimAnnotations.toList(); 2202 2203 if (elems != null) { 2204 return syntaxError(errpos, List.of(na), "illegal.array.creation.both.dimension.and.initialization"); 2205 } 2206 2207 return na; 2208 } 2209 } 2210 2211 /** ClassCreatorRest = Arguments [ClassBody] 2212 */ 2213 JCNewClass classCreatorRest(int newpos, 2214 JCExpression encl, 2215 List<JCExpression> typeArgs, 2216 JCExpression t) 2217 { 2218 List<JCExpression> args = arguments(); 2219 JCClassDecl body = null; 2220 if (token.kind == LBRACE) { 2221 int pos = token.pos; 2222 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 2223 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 2224 body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 2225 } 2226 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); 2227 } 2228 2229 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}" 2230 */ 2231 JCExpression arrayInitializer(int newpos, JCExpression t) { 2232 List<JCExpression> elems = arrayInitializerElements(newpos, t); 2233 return toP(F.at(newpos).NewArray(t, List.nil(), elems)); 2234 } 2235 2236 List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) { 2237 accept(LBRACE); 2238 ListBuffer<JCExpression> elems = new ListBuffer<>(); 2239 if (token.kind == COMMA) { 2240 nextToken(); 2241 } else if (token.kind != RBRACE) { 2242 elems.append(variableInitializer()); 2243 while (token.kind == COMMA) { 2244 nextToken(); 2245 if (token.kind == RBRACE) break; 2246 elems.append(variableInitializer()); 2247 } 2248 } 2249 accept(RBRACE); 2250 return elems.toList(); 2251 } 2252 2253 /** VariableInitializer = ArrayInitializer | Expression 2254 */ 2255 public JCExpression variableInitializer() { 2256 return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression(); 2257 } 2258 2259 /** ParExpression = "(" Expression ")" 2260 */ 2261 JCExpression parExpression() { 2262 int pos = token.pos; 2263 accept(LPAREN); 2264 JCExpression t = parseExpression(); 2265 accept(RPAREN); 2266 return toP(F.at(pos).Parens(t)); 2267 } 2268 2269 /** Block = "{" BlockStatements "}" 2270 */ 2271 JCBlock block(int pos, long flags) { 2272 accept(LBRACE); 2273 List<JCStatement> stats = blockStatements(); 2274 JCBlock t = F.at(pos).Block(flags, stats); 2275 while (token.kind == CASE || token.kind == DEFAULT) { 2276 syntaxError("orphaned", token.kind); 2277 switchBlockStatementGroups(); 2278 } 2279 // the Block node has a field "endpos" for first char of last token, which is 2280 // usually but not necessarily the last char of the last token. 2281 t.endpos = token.pos; 2282 accept(RBRACE); 2283 return toP(t); 2284 } 2285 2286 public JCBlock block() { 2287 return block(token.pos, 0); 2288 } 2289 2290 /** BlockStatements = { BlockStatement } 2291 * BlockStatement = LocalVariableDeclarationStatement 2292 * | ClassOrInterfaceOrEnumDeclaration 2293 * | [Ident ":"] Statement 2294 * LocalVariableDeclarationStatement 2295 * = { FINAL | '@' Annotation } Type VariableDeclarators ";" 2296 */ 2297 @SuppressWarnings("fallthrough") 2298 List<JCStatement> blockStatements() { 2299 //todo: skip to anchor on error(?) 2300 int lastErrPos = -1; 2301 ListBuffer<JCStatement> stats = new ListBuffer<>(); 2302 while (true) { 2303 List<JCStatement> stat = blockStatement(); 2304 if (stat.isEmpty()) { 2305 return stats.toList(); 2306 } else { 2307 // error recovery 2308 if (token.pos == lastErrPos) 2309 return stats.toList(); 2310 if (token.pos <= endPosTable.errorEndPos) { 2311 skip(false, true, true, true); 2312 lastErrPos = token.pos; 2313 } 2314 stats.addAll(stat); 2315 } 2316 } 2317 } 2318 2319 /* 2320 * Parse a Statement (JLS 14.5). As an enhancement to improve error recovery, 2321 * this method will also recognize variable and class declarations (which are 2322 * not legal for a Statement) by delegating the parsing to BlockStatement (JLS 14.2). 2323 * If any illegal declarations are found, they will be wrapped in an erroneous tree, 2324 * and an error will be produced by this method. 2325 */ 2326 JCStatement parseStatementAsBlock() { 2327 int pos = token.pos; 2328 List<JCStatement> stats = blockStatement(); 2329 if (stats.isEmpty()) { 2330 JCErroneous e = syntaxError(pos, "illegal.start.of.stmt"); 2331 return toP(F.at(pos).Exec(e)); 2332 } else { 2333 JCStatement first = stats.head; 2334 String error = null; 2335 switch (first.getTag()) { 2336 case CLASSDEF: 2337 error = "class.not.allowed"; 2338 break; 2339 case VARDEF: 2340 error = "variable.not.allowed"; 2341 break; 2342 } 2343 if (error != null) { 2344 error(first, error); 2345 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats)); 2346 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist))); 2347 } 2348 return first; 2349 } 2350 } 2351 2352 /**This method parses a statement appearing inside a block. 2353 */ 2354 List<JCStatement> blockStatement() { 2355 //todo: skip to anchor on error(?) 2356 int pos = token.pos; 2357 switch (token.kind) { 2358 case RBRACE: case CASE: case DEFAULT: case EOF: 2359 return List.nil(); 2360 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 2361 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 2362 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 2363 case ASSERT: 2364 return List.of(parseSimpleStatement()); 2365 case MONKEYS_AT: 2366 case FINAL: { 2367 Comment dc = token.comment(CommentStyle.JAVADOC); 2368 JCModifiers mods = modifiersOpt(); 2369 if (token.kind == INTERFACE || 2370 token.kind == CLASS || 2371 token.kind == ENUM) { 2372 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); 2373 } else { 2374 JCExpression t = parseType(true); 2375 return localVariableDeclarations(mods, t); 2376 } 2377 } 2378 case ABSTRACT: case STRICTFP: { 2379 Comment dc = token.comment(CommentStyle.JAVADOC); 2380 JCModifiers mods = modifiersOpt(); 2381 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); 2382 } 2383 case INTERFACE: 2384 case CLASS: 2385 Comment dc = token.comment(CommentStyle.JAVADOC); 2386 return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); 2387 case ENUM: 2388 error(token.pos, "local.enum"); 2389 dc = token.comment(CommentStyle.JAVADOC); 2390 return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); 2391 default: 2392 Token prevToken = token; 2393 JCExpression t = term(EXPR | TYPE); 2394 if (token.kind == COLON && t.hasTag(IDENT)) { 2395 nextToken(); 2396 JCStatement stat = parseStatementAsBlock(); 2397 return List.of(F.at(pos).Labelled(prevToken.name(), stat)); 2398 } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { 2399 pos = token.pos; 2400 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 2401 F.at(pos); 2402 return localVariableDeclarations(mods, t); 2403 } else { 2404 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 2405 t = checkExprStat(t); 2406 accept(SEMI); 2407 JCExpressionStatement expr = toP(F.at(pos).Exec(t)); 2408 return List.of(expr); 2409 } 2410 } 2411 } 2412 //where 2413 private List<JCStatement> localVariableDeclarations(JCModifiers mods, JCExpression type) { 2414 ListBuffer<JCStatement> stats = 2415 variableDeclarators(mods, type, new ListBuffer<>(), true); 2416 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 2417 accept(SEMI); 2418 storeEnd(stats.last(), S.prevToken().endPos); 2419 return stats.toList(); 2420 } 2421 2422 /** Statement = 2423 * Block 2424 * | IF ParExpression Statement [ELSE Statement] 2425 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement 2426 * | FOR "(" FormalParameter : Expression ")" Statement 2427 * | WHILE ParExpression Statement 2428 * | DO Statement WHILE ParExpression ";" 2429 * | TRY Block ( Catches | [Catches] FinallyPart ) 2430 * | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart] 2431 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" 2432 * | SYNCHRONIZED ParExpression Block 2433 * | RETURN [Expression] ";" 2434 * | THROW Expression ";" 2435 * | BREAK [Ident] ";" 2436 * | CONTINUE [Ident] ";" 2437 * | ASSERT Expression [ ":" Expression ] ";" 2438 * | ";" 2439 */ 2440 public JCStatement parseSimpleStatement() { 2441 int pos = token.pos; 2442 switch (token.kind) { 2443 case LBRACE: 2444 return block(); 2445 case IF: { 2446 nextToken(); 2447 JCExpression cond = parExpression(); 2448 JCStatement thenpart = parseStatementAsBlock(); 2449 JCStatement elsepart = null; 2450 if (token.kind == ELSE) { 2451 nextToken(); 2452 elsepart = parseStatementAsBlock(); 2453 } 2454 return F.at(pos).If(cond, thenpart, elsepart); 2455 } 2456 case FOR: { 2457 nextToken(); 2458 accept(LPAREN); 2459 List<JCStatement> inits = token.kind == SEMI ? List.nil() : forInit(); 2460 if (inits.length() == 1 && 2461 inits.head.hasTag(VARDEF) && 2462 ((JCVariableDecl) inits.head).init == null && 2463 token.kind == COLON) { 2464 JCVariableDecl var = (JCVariableDecl)inits.head; 2465 accept(COLON); 2466 JCExpression expr = parseExpression(); 2467 accept(RPAREN); 2468 JCStatement body = parseStatementAsBlock(); 2469 return F.at(pos).ForeachLoop(var, expr, body); 2470 } else { 2471 accept(SEMI); 2472 JCExpression cond = token.kind == SEMI ? null : parseExpression(); 2473 accept(SEMI); 2474 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.nil() : forUpdate(); 2475 accept(RPAREN); 2476 JCStatement body = parseStatementAsBlock(); 2477 return F.at(pos).ForLoop(inits, cond, steps, body); 2478 } 2479 } 2480 case WHILE: { 2481 nextToken(); 2482 JCExpression cond = parExpression(); 2483 JCStatement body = parseStatementAsBlock(); 2484 return F.at(pos).WhileLoop(cond, body); 2485 } 2486 case DO: { 2487 nextToken(); 2488 JCStatement body = parseStatementAsBlock(); 2489 accept(WHILE); 2490 JCExpression cond = parExpression(); 2491 accept(SEMI); 2492 JCDoWhileLoop t = toP(F.at(pos).DoLoop(body, cond)); 2493 return t; 2494 } 2495 case TRY: { 2496 nextToken(); 2497 List<JCTree> resources = List.nil(); 2498 if (token.kind == LPAREN) { 2499 checkSourceLevel(Feature.TRY_WITH_RESOURCES); 2500 nextToken(); 2501 resources = resources(); 2502 accept(RPAREN); 2503 } 2504 JCBlock body = block(); 2505 ListBuffer<JCCatch> catchers = new ListBuffer<>(); 2506 JCBlock finalizer = null; 2507 if (token.kind == CATCH || token.kind == FINALLY) { 2508 while (token.kind == CATCH) catchers.append(catchClause()); 2509 if (token.kind == FINALLY) { 2510 nextToken(); 2511 finalizer = block(); 2512 } 2513 } else { 2514 if (resources.isEmpty()) { 2515 if (Feature.TRY_WITH_RESOURCES.allowedInSource(source)) { 2516 error(pos, "try.without.catch.finally.or.resource.decls"); 2517 } else { 2518 error(pos, "try.without.catch.or.finally"); 2519 } 2520 } 2521 } 2522 return F.at(pos).Try(resources, body, catchers.toList(), finalizer); 2523 } 2524 case SWITCH: { 2525 nextToken(); 2526 JCExpression selector = parExpression(); 2527 accept(LBRACE); 2528 List<JCCase> cases = switchBlockStatementGroups(); 2529 JCSwitch t = to(F.at(pos).Switch(selector, cases)); 2530 accept(RBRACE); 2531 return t; 2532 } 2533 case SYNCHRONIZED: { 2534 nextToken(); 2535 JCExpression lock = parExpression(); 2536 JCBlock body = block(); 2537 return F.at(pos).Synchronized(lock, body); 2538 } 2539 case RETURN: { 2540 nextToken(); 2541 JCExpression result = token.kind == SEMI ? null : parseExpression(); 2542 accept(SEMI); 2543 JCReturn t = toP(F.at(pos).Return(result)); 2544 return t; 2545 } 2546 case THROW: { 2547 nextToken(); 2548 JCExpression exc = parseExpression(); 2549 accept(SEMI); 2550 JCThrow t = toP(F.at(pos).Throw(exc)); 2551 return t; 2552 } 2553 case BREAK: { 2554 nextToken(); 2555 Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; 2556 accept(SEMI); 2557 JCBreak t = toP(F.at(pos).Break(label)); 2558 return t; 2559 } 2560 case CONTINUE: { 2561 nextToken(); 2562 Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null; 2563 accept(SEMI); 2564 JCContinue t = toP(F.at(pos).Continue(label)); 2565 return t; 2566 } 2567 case SEMI: 2568 nextToken(); 2569 return toP(F.at(pos).Skip()); 2570 case ELSE: 2571 int elsePos = token.pos; 2572 nextToken(); 2573 return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if"); 2574 case FINALLY: 2575 int finallyPos = token.pos; 2576 nextToken(); 2577 return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try"); 2578 case CATCH: 2579 return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try"); 2580 case ASSERT: { 2581 nextToken(); 2582 JCExpression assertion = parseExpression(); 2583 JCExpression message = null; 2584 if (token.kind == COLON) { 2585 nextToken(); 2586 message = parseExpression(); 2587 } 2588 accept(SEMI); 2589 JCAssert t = toP(F.at(pos).Assert(assertion, message)); 2590 return t; 2591 } 2592 default: 2593 Assert.error(); 2594 return null; 2595 } 2596 } 2597 2598 @Override 2599 public JCStatement parseStatement() { 2600 return parseStatementAsBlock(); 2601 } 2602 2603 private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) { 2604 int errPos = S.errPos(); 2605 JCTree stm = action.doRecover(this); 2606 S.errPos(errPos); 2607 return toP(F.Exec(syntaxError(startPos, List.of(stm), key))); 2608 } 2609 2610 /** CatchClause = CATCH "(" FormalParameter ")" Block 2611 * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below. 2612 */ 2613 protected JCCatch catchClause() { 2614 int pos = token.pos; 2615 accept(CATCH); 2616 accept(LPAREN); 2617 JCModifiers mods = optFinal(Flags.PARAMETER); 2618 List<JCExpression> catchTypes = catchTypes(); 2619 JCExpression paramType = catchTypes.size() > 1 ? 2620 toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) : 2621 catchTypes.head; 2622 JCVariableDecl formal = variableDeclaratorId(mods, paramType); 2623 accept(RPAREN); 2624 JCBlock body = block(); 2625 return F.at(pos).Catch(formal, body); 2626 } 2627 2628 List<JCExpression> catchTypes() { 2629 ListBuffer<JCExpression> catchTypes = new ListBuffer<>(); 2630 catchTypes.add(parseType()); 2631 while (token.kind == BAR) { 2632 checkSourceLevel(Feature.MULTICATCH); 2633 nextToken(); 2634 // Instead of qualident this is now parseType. 2635 // But would that allow too much, e.g. arrays or generics? 2636 catchTypes.add(parseType()); 2637 } 2638 return catchTypes.toList(); 2639 } 2640 2641 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 2642 * SwitchBlockStatementGroup = SwitchLabel BlockStatements 2643 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 2644 */ 2645 List<JCCase> switchBlockStatementGroups() { 2646 ListBuffer<JCCase> cases = new ListBuffer<>(); 2647 while (true) { 2648 int pos = token.pos; 2649 switch (token.kind) { 2650 case CASE: 2651 case DEFAULT: 2652 cases.append(switchBlockStatementGroup()); 2653 break; 2654 case RBRACE: case EOF: 2655 return cases.toList(); 2656 default: 2657 nextToken(); // to ensure progress 2658 syntaxError(pos, "expected3", 2659 CASE, DEFAULT, RBRACE); 2660 } 2661 } 2662 } 2663 2664 protected JCCase switchBlockStatementGroup() { 2665 int pos = token.pos; 2666 List<JCStatement> stats; 2667 JCCase c; 2668 switch (token.kind) { 2669 case CASE: 2670 nextToken(); 2671 JCExpression pat = parseExpression(); 2672 accept(COLON); 2673 stats = blockStatements(); 2674 c = F.at(pos).Case(pat, stats); 2675 if (stats.isEmpty()) 2676 storeEnd(c, S.prevToken().endPos); 2677 return c; 2678 case DEFAULT: 2679 nextToken(); 2680 accept(COLON); 2681 stats = blockStatements(); 2682 c = F.at(pos).Case(null, stats); 2683 if (stats.isEmpty()) 2684 storeEnd(c, S.prevToken().endPos); 2685 return c; 2686 } 2687 throw new AssertionError("should not reach here"); 2688 } 2689 2690 /** MoreStatementExpressions = { COMMA StatementExpression } 2691 */ 2692 <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos, 2693 JCExpression first, 2694 T stats) { 2695 // This Exec is a "StatementExpression"; it subsumes no terminating token 2696 stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 2697 while (token.kind == COMMA) { 2698 nextToken(); 2699 pos = token.pos; 2700 JCExpression t = parseExpression(); 2701 // This Exec is a "StatementExpression"; it subsumes no terminating token 2702 stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 2703 } 2704 return stats; 2705 } 2706 2707 /** ForInit = StatementExpression MoreStatementExpressions 2708 * | { FINAL | '@' Annotation } Type VariableDeclarators 2709 */ 2710 List<JCStatement> forInit() { 2711 ListBuffer<JCStatement> stats = new ListBuffer<>(); 2712 int pos = token.pos; 2713 if (token.kind == FINAL || token.kind == MONKEYS_AT) { 2714 return variableDeclarators(optFinal(0), parseType(true), stats, true).toList(); 2715 } else { 2716 JCExpression t = term(EXPR | TYPE); 2717 if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { 2718 return variableDeclarators(modifiersOpt(), t, stats, true).toList(); 2719 } else if ((lastmode & TYPE) != 0 && token.kind == COLON) { 2720 error(pos, "bad.initializer", "for-loop"); 2721 return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null)); 2722 } else { 2723 return moreStatementExpressions(pos, t, stats).toList(); 2724 } 2725 } 2726 } 2727 2728 /** ForUpdate = StatementExpression MoreStatementExpressions 2729 */ 2730 List<JCExpressionStatement> forUpdate() { 2731 return moreStatementExpressions(token.pos, 2732 parseExpression(), 2733 new ListBuffer<JCExpressionStatement>()).toList(); 2734 } 2735 2736 /** AnnotationsOpt = { '@' Annotation } 2737 * 2738 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION 2739 */ 2740 protected List<JCAnnotation> annotationsOpt(Tag kind) { 2741 if (token.kind != MONKEYS_AT) return List.nil(); // optimization 2742 ListBuffer<JCAnnotation> buf = new ListBuffer<>(); 2743 int prevmode = mode; 2744 while (token.kind == MONKEYS_AT) { 2745 int pos = token.pos; 2746 nextToken(); 2747 buf.append(annotation(pos, kind)); 2748 } 2749 lastmode = mode; 2750 mode = prevmode; 2751 List<JCAnnotation> annotations = buf.toList(); 2752 2753 return annotations; 2754 } 2755 2756 List<JCAnnotation> typeAnnotationsOpt() { 2757 List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION); 2758 return annotations; 2759 } 2760 2761 /** ModifiersOpt = { Modifier } 2762 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 2763 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 2764 * | "@" Annotation 2765 */ 2766 protected JCModifiers modifiersOpt() { 2767 return modifiersOpt(null); 2768 } 2769 protected JCModifiers modifiersOpt(JCModifiers partial) { 2770 long flags; 2771 ListBuffer<JCAnnotation> annotations = new ListBuffer<>(); 2772 int pos; 2773 if (partial == null) { 2774 flags = 0; 2775 pos = token.pos; 2776 } else { 2777 flags = partial.flags; 2778 annotations.appendList(partial.annotations); 2779 pos = partial.pos; 2780 } 2781 if (token.deprecatedFlag()) { 2782 flags |= Flags.DEPRECATED; 2783 } 2784 int lastPos; 2785 loop: 2786 while (true) { 2787 long flag; 2788 switch (token.kind) { 2789 case PRIVATE : flag = Flags.PRIVATE; break; 2790 case PROTECTED : flag = Flags.PROTECTED; break; 2791 case PUBLIC : flag = Flags.PUBLIC; break; 2792 case STATIC : flag = Flags.STATIC; break; 2793 case TRANSIENT : flag = Flags.TRANSIENT; break; 2794 case FINAL : flag = Flags.FINAL; break; 2795 case ABSTRACT : flag = Flags.ABSTRACT; break; 2796 case NATIVE : flag = Flags.NATIVE; break; 2797 case VOLATILE : flag = Flags.VOLATILE; break; 2798 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 2799 case STRICTFP : flag = Flags.STRICTFP; break; 2800 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 2801 case DEFAULT : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break; 2802 case ERROR : flag = 0; nextToken(); break; 2803 default: break loop; 2804 } 2805 if ((flags & flag) != 0) error(token.pos, "repeated.modifier"); 2806 lastPos = token.pos; 2807 nextToken(); 2808 if (flag == Flags.ANNOTATION) { 2809 if (token.kind != INTERFACE) { 2810 JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION); 2811 // if first modifier is an annotation, set pos to annotation's. 2812 if (flags == 0 && annotations.isEmpty()) 2813 pos = ann.pos; 2814 annotations.append(ann); 2815 flag = 0; 2816 } 2817 } 2818 flags |= flag; 2819 } 2820 switch (token.kind) { 2821 case ENUM: flags |= Flags.ENUM; break; 2822 case INTERFACE: flags |= Flags.INTERFACE; break; 2823 default: break; 2824 } 2825 2826 /* A modifiers tree with no modifier tokens or annotations 2827 * has no text position. */ 2828 if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty()) 2829 pos = Position.NOPOS; 2830 2831 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 2832 if (pos != Position.NOPOS) 2833 storeEnd(mods, S.prevToken().endPos); 2834 return mods; 2835 } 2836 2837 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 2838 * 2839 * @param pos position of "@" token 2840 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION 2841 */ 2842 JCAnnotation annotation(int pos, Tag kind) { 2843 // accept(AT); // AT consumed by caller 2844 if (kind == Tag.TYPE_ANNOTATION) { 2845 checkSourceLevel(Feature.TYPE_ANNOTATIONS); 2846 } 2847 JCTree ident = qualident(false); 2848 List<JCExpression> fieldValues = annotationFieldValuesOpt(); 2849 JCAnnotation ann; 2850 if (kind == Tag.ANNOTATION) { 2851 ann = F.at(pos).Annotation(ident, fieldValues); 2852 } else if (kind == Tag.TYPE_ANNOTATION) { 2853 ann = F.at(pos).TypeAnnotation(ident, fieldValues); 2854 } else { 2855 throw new AssertionError("Unhandled annotation kind: " + kind); 2856 } 2857 2858 storeEnd(ann, S.prevToken().endPos); 2859 return ann; 2860 } 2861 2862 List<JCExpression> annotationFieldValuesOpt() { 2863 return (token.kind == LPAREN) ? annotationFieldValues() : List.nil(); 2864 } 2865 2866 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 2867 List<JCExpression> annotationFieldValues() { 2868 accept(LPAREN); 2869 ListBuffer<JCExpression> buf = new ListBuffer<>(); 2870 if (token.kind != RPAREN) { 2871 buf.append(annotationFieldValue()); 2872 while (token.kind == COMMA) { 2873 nextToken(); 2874 buf.append(annotationFieldValue()); 2875 } 2876 } 2877 accept(RPAREN); 2878 return buf.toList(); 2879 } 2880 2881 /** AnnotationFieldValue = AnnotationValue 2882 * | Identifier "=" AnnotationValue 2883 */ 2884 JCExpression annotationFieldValue() { 2885 if (LAX_IDENTIFIER.accepts(token.kind)) { 2886 mode = EXPR; 2887 JCExpression t1 = term1(); 2888 if (t1.hasTag(IDENT) && token.kind == EQ) { 2889 int pos = token.pos; 2890 accept(EQ); 2891 JCExpression v = annotationValue(); 2892 return toP(F.at(pos).Assign(t1, v)); 2893 } else { 2894 return t1; 2895 } 2896 } 2897 return annotationValue(); 2898 } 2899 2900 /* AnnotationValue = ConditionalExpression 2901 * | Annotation 2902 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}" 2903 */ 2904 JCExpression annotationValue() { 2905 int pos; 2906 switch (token.kind) { 2907 case MONKEYS_AT: 2908 pos = token.pos; 2909 nextToken(); 2910 return annotation(pos, Tag.ANNOTATION); 2911 case LBRACE: 2912 pos = token.pos; 2913 accept(LBRACE); 2914 ListBuffer<JCExpression> buf = new ListBuffer<>(); 2915 if (token.kind == COMMA) { 2916 nextToken(); 2917 } else if (token.kind != RBRACE) { 2918 buf.append(annotationValue()); 2919 while (token.kind == COMMA) { 2920 nextToken(); 2921 if (token.kind == RBRACE) break; 2922 buf.append(annotationValue()); 2923 } 2924 } 2925 accept(RBRACE); 2926 return toP(F.at(pos).NewArray(null, List.nil(), buf.toList())); 2927 default: 2928 mode = EXPR; 2929 return term1(); 2930 } 2931 } 2932 2933 /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator } 2934 */ 2935 public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods, 2936 JCExpression type, 2937 T vdefs, 2938 boolean localDecl) 2939 { 2940 return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs, localDecl); 2941 } 2942 2943 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 2944 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator } 2945 * 2946 * @param reqInit Is an initializer always required? 2947 * @param dc The documentation comment for the variable declarations, or null. 2948 */ 2949 protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos, 2950 JCModifiers mods, 2951 JCExpression type, 2952 Name name, 2953 boolean reqInit, 2954 Comment dc, 2955 T vdefs, 2956 boolean localDecl) 2957 { 2958 JCTree elemType = TreeInfo.innermostType(type, true); // bracketsOpt needed? 2959 if (elemType.hasTag(IDENT)) { 2960 Name typeName = ((JCIdent)elemType).name; 2961 boolean typeNameVarCheck = isRestrictedLocalVarTypeName(typeName, elemType.pos); 2962 } 2963 2964 JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl); 2965 boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null; 2966 vdefs.append(head); 2967 while (token.kind == COMMA) { 2968 if (implicit) { 2969 reportSyntaxError(pos, "var.not.allowed.compound"); 2970 } 2971 // All but last of multiple declarators subsume a comma 2972 storeEnd((JCTree)vdefs.last(), token.endPos); 2973 nextToken(); 2974 vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl)); 2975 } 2976 return vdefs; 2977 } 2978 2979 /** VariableDeclarator = Ident VariableDeclaratorRest 2980 * ConstantDeclarator = Ident ConstantDeclaratorRest 2981 */ 2982 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) { 2983 return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl); 2984 } 2985 2986 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 2987 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer 2988 * 2989 * @param reqInit Is an initializer always required? 2990 * @param dc The documentation comment for the variable declarations, or null. 2991 */ 2992 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, 2993 boolean reqInit, Comment dc, boolean localDecl) { 2994 type = bracketsOpt(type); 2995 JCExpression init = null; 2996 if (token.kind == EQ) { 2997 nextToken(); 2998 init = variableInitializer(); 2999 } 3000 else if (reqInit) syntaxError(token.pos, "expected", EQ); 3001 JCTree elemType = TreeInfo.innermostType(type, true); 3002 int startPos = Position.NOPOS; 3003 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) { 3004 Name typeName = ((JCIdent)elemType).name; 3005 if (isRestrictedLocalVarTypeName(typeName, elemType.pos)) { 3006 if (type.hasTag(TYPEARRAY)) { 3007 //error - 'var' and arrays 3008 reportSyntaxError(pos, "var.not.allowed.array"); 3009 } else { 3010 startPos = TreeInfo.getStartPos(mods); 3011 if (startPos == Position.NOPOS) 3012 startPos = TreeInfo.getStartPos(type); 3013 //implicit type 3014 type = null; 3015 } 3016 } 3017 } 3018 JCVariableDecl result = 3019 toP(F.at(pos).VarDef(mods, name, type, init)); 3020 attach(result, dc); 3021 result.startPos = startPos; 3022 return result; 3023 } 3024 3025 boolean isRestrictedLocalVarTypeName(JCExpression e) { 3026 switch (e.getTag()) { 3027 case IDENT: 3028 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos); 3029 case TYPEARRAY: 3030 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype); 3031 default: 3032 return false; 3033 } 3034 } 3035 3036 boolean isRestrictedLocalVarTypeName(Name name, int pos) { 3037 if (name == names.var) { 3038 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) { 3039 return true; 3040 } else { 3041 warning(pos, "var.not.allowed", name); 3042 } 3043 } 3044 return false; 3045 } 3046 3047 /** VariableDeclaratorId = Ident BracketsOpt 3048 */ 3049 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 3050 return variableDeclaratorId(mods, type, false); 3051 } 3052 //where 3053 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) { 3054 int pos = token.pos; 3055 Name name; 3056 if (lambdaParameter && token.kind == UNDERSCORE) { 3057 log.error(pos, Errors.UnderscoreAsIdentifierInLambda); 3058 name = token.name(); 3059 nextToken(); 3060 } else { 3061 if (allowThisIdent && !lambdaParameter) { 3062 JCExpression pn = qualident(false); 3063 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) { 3064 name = ((JCIdent)pn).name; 3065 } else { 3066 if ((mods.flags & Flags.VARARGS) != 0) { 3067 log.error(token.pos, Errors.VarargsAndReceiver); 3068 } 3069 if (token.kind == LBRACKET) { 3070 log.error(token.pos, Errors.ArrayAndReceiver); 3071 } 3072 return toP(F.at(pos).ReceiverVarDef(mods, pn, type)); 3073 } 3074 } else { 3075 name = ident(); 3076 } 3077 } 3078 if ((mods.flags & Flags.VARARGS) != 0 && 3079 token.kind == LBRACKET) { 3080 log.error(token.pos, Errors.VarargsAndOldArraySyntax); 3081 } 3082 type = bracketsOpt(type); 3083 return toP(F.at(pos).VarDef(mods, name, type, null)); 3084 } 3085 3086 /** Resources = Resource { ";" Resources } 3087 */ 3088 List<JCTree> resources() { 3089 ListBuffer<JCTree> defs = new ListBuffer<>(); 3090 defs.append(resource()); 3091 while (token.kind == SEMI) { 3092 // All but last of multiple declarators must subsume a semicolon 3093 storeEnd(defs.last(), token.endPos); 3094 int semiColonPos = token.pos; 3095 nextToken(); 3096 if (token.kind == RPAREN) { // Optional trailing semicolon 3097 // after last resource 3098 break; 3099 } 3100 defs.append(resource()); 3101 } 3102 return defs.toList(); 3103 } 3104 3105 /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression 3106 * | Expression 3107 */ 3108 protected JCTree resource() { 3109 int startPos = token.pos; 3110 if (token.kind == FINAL || token.kind == MONKEYS_AT) { 3111 JCModifiers mods = optFinal(Flags.FINAL); 3112 JCExpression t = parseType(true); 3113 return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true); 3114 } 3115 JCExpression t = term(EXPR | TYPE); 3116 if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) { 3117 JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL)); 3118 return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true); 3119 } else { 3120 checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES); 3121 if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) { 3122 log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar); 3123 } 3124 3125 return t; 3126 } 3127 } 3128 3129 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 3130 */ 3131 public JCTree.JCCompilationUnit parseCompilationUnit() { 3132 Token firstToken = token; 3133 JCModifiers mods = null; 3134 boolean consumedToplevelDoc = false; 3135 boolean seenImport = false; 3136 boolean seenPackage = false; 3137 ListBuffer<JCTree> defs = new ListBuffer<>(); 3138 if (token.kind == MONKEYS_AT) 3139 mods = modifiersOpt(); 3140 3141 if (token.kind == PACKAGE) { 3142 int packagePos = token.pos; 3143 List<JCAnnotation> annotations = List.nil(); 3144 seenPackage = true; 3145 if (mods != null) { 3146 checkNoMods(mods.flags); 3147 annotations = mods.annotations; 3148 mods = null; 3149 } 3150 nextToken(); 3151 JCExpression pid = qualident(false); 3152 accept(SEMI); 3153 JCPackageDecl pd = toP(F.at(packagePos).PackageDecl(annotations, pid)); 3154 attach(pd, firstToken.comment(CommentStyle.JAVADOC)); 3155 consumedToplevelDoc = true; 3156 defs.append(pd); 3157 } 3158 3159 boolean checkForImports = true; 3160 boolean firstTypeDecl = true; 3161 while (token.kind != EOF) { 3162 if (token.pos <= endPosTable.errorEndPos) { 3163 // error recovery 3164 skip(checkForImports, false, false, false); 3165 if (token.kind == EOF) 3166 break; 3167 } 3168 if (checkForImports && mods == null && token.kind == IMPORT) { 3169 seenImport = true; 3170 defs.append(importDeclaration()); 3171 } else { 3172 Comment docComment = token.comment(CommentStyle.JAVADOC); 3173 if (firstTypeDecl && !seenImport && !seenPackage) { 3174 docComment = firstToken.comment(CommentStyle.JAVADOC); 3175 consumedToplevelDoc = true; 3176 } 3177 if (mods != null || token.kind != SEMI) 3178 mods = modifiersOpt(mods); 3179 if (firstTypeDecl && token.kind == IDENTIFIER) { 3180 ModuleKind kind = ModuleKind.STRONG; 3181 if (token.name() == names.open) { 3182 kind = ModuleKind.OPEN; 3183 nextToken(); 3184 } 3185 if (token.kind == IDENTIFIER && token.name() == names.module) { 3186 if (mods != null) { 3187 checkNoMods(mods.flags & ~Flags.DEPRECATED); 3188 } 3189 defs.append(moduleDecl(mods, kind, docComment)); 3190 consumedToplevelDoc = true; 3191 break; 3192 } else if (kind != ModuleKind.STRONG) { 3193 reportSyntaxError(token.pos, "expected.module"); 3194 } 3195 } 3196 JCTree def = typeDeclaration(mods, docComment); 3197 if (def instanceof JCExpressionStatement) 3198 def = ((JCExpressionStatement)def).expr; 3199 defs.append(def); 3200 if (def instanceof JCClassDecl) 3201 checkForImports = false; 3202 mods = null; 3203 firstTypeDecl = false; 3204 } 3205 } 3206 JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList()); 3207 if (!consumedToplevelDoc) 3208 attach(toplevel, firstToken.comment(CommentStyle.JAVADOC)); 3209 if (defs.isEmpty()) 3210 storeEnd(toplevel, S.prevToken().endPos); 3211 if (keepDocComments) 3212 toplevel.docComments = docComments; 3213 if (keepLineMap) 3214 toplevel.lineMap = S.getLineMap(); 3215 this.endPosTable.setParser(null); // remove reference to parser 3216 toplevel.endPositions = this.endPosTable; 3217 return toplevel; 3218 } 3219 3220 JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) { 3221 int pos = token.pos; 3222 checkSourceLevel(Feature.MODULES); 3223 3224 nextToken(); 3225 JCExpression name = qualident(false); 3226 List<JCDirective> directives = null; 3227 3228 accept(LBRACE); 3229 directives = moduleDirectiveList(); 3230 accept(RBRACE); 3231 accept(EOF); 3232 3233 JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives)); 3234 attach(result, dc); 3235 return result; 3236 } 3237 3238 List<JCDirective> moduleDirectiveList() { 3239 ListBuffer<JCDirective> defs = new ListBuffer<>(); 3240 while (token.kind == IDENTIFIER) { 3241 int pos = token.pos; 3242 if (token.name() == names.requires) { 3243 nextToken(); 3244 boolean isTransitive = false; 3245 boolean isStaticPhase = false; 3246 loop: 3247 while (true) { 3248 switch (token.kind) { 3249 case IDENTIFIER: 3250 if (token.name() == names.transitive && !isTransitive) { 3251 Token t1 = S.token(1); 3252 if (t1.kind == SEMI || t1.kind == DOT) { 3253 break loop; 3254 } 3255 isTransitive = true; 3256 break; 3257 } else { 3258 break loop; 3259 } 3260 case STATIC: 3261 if (isStaticPhase) { 3262 error(token.pos, "repeated.modifier"); 3263 } 3264 isStaticPhase = true; 3265 break; 3266 default: 3267 break loop; 3268 } 3269 nextToken(); 3270 } 3271 JCExpression moduleName = qualident(false); 3272 accept(SEMI); 3273 defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName))); 3274 } else if (token.name() == names.exports || token.name() == names.opens) { 3275 boolean exports = token.name() == names.exports; 3276 nextToken(); 3277 JCExpression pkgName = qualident(false); 3278 List<JCExpression> moduleNames = null; 3279 if (token.kind == IDENTIFIER && token.name() == names.to) { 3280 nextToken(); 3281 moduleNames = qualidentList(false); 3282 } 3283 accept(SEMI); 3284 JCDirective d; 3285 if (exports) { 3286 d = F.at(pos).Exports(pkgName, moduleNames); 3287 } else { 3288 d = F.at(pos).Opens(pkgName, moduleNames); 3289 } 3290 defs.append(toP(d)); 3291 } else if (token.name() == names.provides) { 3292 nextToken(); 3293 JCExpression serviceName = qualident(false); 3294 if (token.kind == IDENTIFIER && token.name() == names.with) { 3295 nextToken(); 3296 List<JCExpression> implNames = qualidentList(false); 3297 accept(SEMI); 3298 defs.append(toP(F.at(pos).Provides(serviceName, implNames))); 3299 } else { 3300 error(token.pos, "expected", "'" + names.with + "'"); 3301 skip(false, false, false, false); 3302 } 3303 } else if (token.name() == names.uses) { 3304 nextToken(); 3305 JCExpression service = qualident(false); 3306 accept(SEMI); 3307 defs.append(toP(F.at(pos).Uses(service))); 3308 } else { 3309 setErrorEndPos(pos); 3310 reportSyntaxError(pos, "invalid.module.directive"); 3311 break; 3312 } 3313 } 3314 return defs.toList(); 3315 } 3316 3317 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 3318 */ 3319 protected JCTree importDeclaration() { 3320 int pos = token.pos; 3321 nextToken(); 3322 boolean importStatic = false; 3323 if (token.kind == STATIC) { 3324 importStatic = true; 3325 nextToken(); 3326 } 3327 JCExpression pid = toP(F.at(token.pos).Ident(ident())); 3328 do { 3329 int pos1 = token.pos; 3330 accept(DOT); 3331 if (token.kind == STAR) { 3332 pid = to(F.at(pos1).Select(pid, names.asterisk)); 3333 nextToken(); 3334 break; 3335 } else { 3336 pid = toP(F.at(pos1).Select(pid, ident())); 3337 } 3338 } while (token.kind == DOT); 3339 accept(SEMI); 3340 return toP(F.at(pos).Import(pid, importStatic)); 3341 } 3342 3343 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 3344 * | ";" 3345 */ 3346 JCTree typeDeclaration(JCModifiers mods, Comment docComment) { 3347 int pos = token.pos; 3348 if (mods == null && token.kind == SEMI) { 3349 nextToken(); 3350 return toP(F.at(pos).Skip()); 3351 } else { 3352 return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment); 3353 } 3354 } 3355 3356 /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt 3357 * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) 3358 * @param mods Any modifiers starting the class or interface declaration 3359 * @param dc The documentation comment for the class, or null. 3360 */ 3361 protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) { 3362 if (token.kind == CLASS) { 3363 return classDeclaration(mods, dc); 3364 } else if (token.kind == INTERFACE) { 3365 return interfaceDeclaration(mods, dc); 3366 } else if (token.kind == ENUM) { 3367 return enumDeclaration(mods, dc); 3368 } else { 3369 int pos = token.pos; 3370 List<JCTree> errs; 3371 if (LAX_IDENTIFIER.accepts(token.kind)) { 3372 errs = List.of(mods, toP(F.at(pos).Ident(ident()))); 3373 setErrorEndPos(token.pos); 3374 } else { 3375 errs = List.of(mods); 3376 } 3377 final JCErroneous erroneousTree; 3378 if (parseModuleInfo) { 3379 erroneousTree = syntaxError(pos, errs, "expected.module.or.open"); 3380 } else { 3381 erroneousTree = syntaxError(pos, errs, "expected3", CLASS, INTERFACE, ENUM); 3382 } 3383 return toP(F.Exec(erroneousTree)); 3384 } 3385 } 3386 3387 /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type] 3388 * [IMPLEMENTS TypeList] ClassBody 3389 * @param mods The modifiers starting the class declaration 3390 * @param dc The documentation comment for the class, or null. 3391 */ 3392 protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) { 3393 int pos = token.pos; 3394 accept(CLASS); 3395 Name name = typeName(); 3396 3397 List<JCTypeParameter> typarams = typeParametersOpt(); 3398 3399 JCExpression extending = null; 3400 if (token.kind == EXTENDS) { 3401 nextToken(); 3402 extending = parseType(); 3403 } 3404 List<JCExpression> implementing = List.nil(); 3405 if (token.kind == IMPLEMENTS) { 3406 nextToken(); 3407 implementing = typeList(); 3408 } 3409 List<JCTree> defs = classOrInterfaceBody(name, false); 3410 JCClassDecl result = toP(F.at(pos).ClassDef( 3411 mods, name, typarams, extending, implementing, defs)); 3412 attach(result, dc); 3413 return result; 3414 } 3415 3416 Name typeName() { 3417 int pos = token.pos; 3418 Name name = ident(); 3419 if (isRestrictedLocalVarTypeName(name, pos)) { 3420 reportSyntaxError(pos, "var.not.allowed", name); 3421 } 3422 return name; 3423 } 3424 3425 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt 3426 * [EXTENDS TypeList] InterfaceBody 3427 * @param mods The modifiers starting the interface declaration 3428 * @param dc The documentation comment for the interface, or null. 3429 */ 3430 protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) { 3431 int pos = token.pos; 3432 accept(INTERFACE); 3433 3434 Name name = typeName(); 3435 3436 List<JCTypeParameter> typarams = typeParametersOpt(); 3437 3438 List<JCExpression> extending = List.nil(); 3439 if (token.kind == EXTENDS) { 3440 nextToken(); 3441 extending = typeList(); 3442 } 3443 List<JCTree> defs = classOrInterfaceBody(name, true); 3444 JCClassDecl result = toP(F.at(pos).ClassDef( 3445 mods, name, typarams, null, extending, defs)); 3446 attach(result, dc); 3447 return result; 3448 } 3449 3450 /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody 3451 * @param mods The modifiers starting the enum declaration 3452 * @param dc The documentation comment for the enum, or null. 3453 */ 3454 protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) { 3455 int pos = token.pos; 3456 accept(ENUM); 3457 3458 Name name = typeName(); 3459 3460 List<JCExpression> implementing = List.nil(); 3461 if (token.kind == IMPLEMENTS) { 3462 nextToken(); 3463 implementing = typeList(); 3464 } 3465 3466 List<JCTree> defs = enumBody(name); 3467 mods.flags |= Flags.ENUM; 3468 JCClassDecl result = toP(F.at(pos). 3469 ClassDef(mods, name, List.nil(), 3470 null, implementing, defs)); 3471 attach(result, dc); 3472 return result; 3473 } 3474 3475 /** EnumBody = "{" { EnumeratorDeclarationList } [","] 3476 * [ ";" {ClassBodyDeclaration} ] "}" 3477 */ 3478 List<JCTree> enumBody(Name enumName) { 3479 accept(LBRACE); 3480 ListBuffer<JCTree> defs = new ListBuffer<>(); 3481 if (token.kind == COMMA) { 3482 nextToken(); 3483 } else if (token.kind != RBRACE && token.kind != SEMI) { 3484 defs.append(enumeratorDeclaration(enumName)); 3485 while (token.kind == COMMA) { 3486 nextToken(); 3487 if (token.kind == RBRACE || token.kind == SEMI) break; 3488 defs.append(enumeratorDeclaration(enumName)); 3489 } 3490 if (token.kind != SEMI && token.kind != RBRACE) { 3491 defs.append(syntaxError(token.pos, "expected3", 3492 COMMA, RBRACE, SEMI)); 3493 nextToken(); 3494 } 3495 } 3496 if (token.kind == SEMI) { 3497 nextToken(); 3498 while (token.kind != RBRACE && token.kind != EOF) { 3499 defs.appendList(classOrInterfaceBodyDeclaration(enumName, 3500 false)); 3501 if (token.pos <= endPosTable.errorEndPos) { 3502 // error recovery 3503 skip(false, true, true, false); 3504 } 3505 } 3506 } 3507 accept(RBRACE); 3508 return defs.toList(); 3509 } 3510 3511 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 3512 */ 3513 JCTree enumeratorDeclaration(Name enumName) { 3514 Comment dc = token.comment(CommentStyle.JAVADOC); 3515 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 3516 if (token.deprecatedFlag()) { 3517 flags |= Flags.DEPRECATED; 3518 } 3519 int pos = token.pos; 3520 List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION); 3521 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 3522 List<JCExpression> typeArgs = typeArgumentsOpt(); 3523 int identPos = token.pos; 3524 Name name = ident(); 3525 int createPos = token.pos; 3526 List<JCExpression> args = (token.kind == LPAREN) 3527 ? arguments() : List.nil(); 3528 JCClassDecl body = null; 3529 if (token.kind == LBRACE) { 3530 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM); 3531 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 3532 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 3533 } 3534 if (args.isEmpty() && body == null) 3535 createPos = identPos; 3536 JCIdent ident = F.at(identPos).Ident(enumName); 3537 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 3538 if (createPos != identPos) 3539 storeEnd(create, S.prevToken().endPos); 3540 ident = F.at(identPos).Ident(enumName); 3541 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 3542 attach(result, dc); 3543 return result; 3544 } 3545 3546 /** TypeList = Type {"," Type} 3547 */ 3548 List<JCExpression> typeList() { 3549 ListBuffer<JCExpression> ts = new ListBuffer<>(); 3550 ts.append(parseType()); 3551 while (token.kind == COMMA) { 3552 nextToken(); 3553 ts.append(parseType()); 3554 } 3555 return ts.toList(); 3556 } 3557 3558 /** ClassBody = "{" {ClassBodyDeclaration} "}" 3559 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 3560 */ 3561 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 3562 accept(LBRACE); 3563 if (token.pos <= endPosTable.errorEndPos) { 3564 // error recovery 3565 skip(false, true, false, false); 3566 if (token.kind == LBRACE) 3567 nextToken(); 3568 } 3569 ListBuffer<JCTree> defs = new ListBuffer<>(); 3570 while (token.kind != RBRACE && token.kind != EOF) { 3571 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 3572 if (token.pos <= endPosTable.errorEndPos) { 3573 // error recovery 3574 skip(false, true, true, false); 3575 } 3576 } 3577 accept(RBRACE); 3578 return defs.toList(); 3579 } 3580 3581 /** ClassBodyDeclaration = 3582 * ";" 3583 * | [STATIC] Block 3584 * | ModifiersOpt 3585 * ( Type Ident 3586 * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) 3587 * | VOID Ident VoidMethodDeclaratorRest 3588 * | TypeParameters [Annotations] 3589 * ( Type Ident MethodDeclaratorRest 3590 * | VOID Ident VoidMethodDeclaratorRest 3591 * ) 3592 * | Ident ConstructorDeclaratorRest 3593 * | TypeParameters Ident ConstructorDeclaratorRest 3594 * | ClassOrInterfaceOrEnumDeclaration 3595 * ) 3596 * InterfaceBodyDeclaration = 3597 * ";" 3598 * | ModifiersOpt 3599 * ( Type Ident 3600 * ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest ) 3601 * | VOID Ident MethodDeclaratorRest 3602 * | TypeParameters [Annotations] 3603 * ( Type Ident MethodDeclaratorRest 3604 * | VOID Ident VoidMethodDeclaratorRest 3605 * ) 3606 * | ClassOrInterfaceOrEnumDeclaration 3607 * ) 3608 * 3609 */ 3610 protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 3611 if (token.kind == SEMI) { 3612 nextToken(); 3613 return List.nil(); 3614 } else { 3615 Comment dc = token.comment(CommentStyle.JAVADOC); 3616 int pos = token.pos; 3617 JCModifiers mods = modifiersOpt(); 3618 if (token.kind == CLASS || 3619 token.kind == INTERFACE || 3620 token.kind == ENUM) { 3621 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc)); 3622 } else if (token.kind == LBRACE && 3623 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 3624 mods.annotations.isEmpty()) { 3625 if (isInterface) { 3626 error(token.pos, "initializer.not.allowed"); 3627 } 3628 return List.of(block(pos, mods.flags)); 3629 } else { 3630 pos = token.pos; 3631 List<JCTypeParameter> typarams = typeParametersOpt(); 3632 // if there are type parameters but no modifiers, save the start 3633 // position of the method in the modifiers. 3634 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) { 3635 mods.pos = pos; 3636 storeEnd(mods, pos); 3637 } 3638 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION); 3639 3640 if (annosAfterParams.nonEmpty()) { 3641 checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS); 3642 mods.annotations = mods.annotations.appendList(annosAfterParams); 3643 if (mods.pos == Position.NOPOS) 3644 mods.pos = mods.annotations.head.pos; 3645 } 3646 3647 Token tk = token; 3648 pos = token.pos; 3649 JCExpression type; 3650 boolean isVoid = token.kind == VOID; 3651 if (isVoid) { 3652 type = to(F.at(pos).TypeIdent(TypeTag.VOID)); 3653 nextToken(); 3654 } else { 3655 // method returns types are un-annotated types 3656 type = unannotatedType(false); 3657 } 3658 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) { 3659 if (isInterface || tk.name() != className) 3660 error(pos, "invalid.meth.decl.ret.type.req"); 3661 else if (annosAfterParams.nonEmpty()) 3662 illegal(annosAfterParams.head.pos); 3663 return List.of(methodDeclaratorRest( 3664 pos, mods, null, names.init, typarams, 3665 isInterface, true, dc)); 3666 } else { 3667 pos = token.pos; 3668 Name name = ident(); 3669 if (token.kind == LPAREN) { 3670 return List.of(methodDeclaratorRest( 3671 pos, mods, type, name, typarams, 3672 isInterface, isVoid, dc)); 3673 } else if (!isVoid && typarams.isEmpty()) { 3674 List<JCTree> defs = 3675 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 3676 new ListBuffer<JCTree>(), false).toList(); 3677 accept(SEMI); 3678 storeEnd(defs.last(), S.prevToken().endPos); 3679 return defs; 3680 } else { 3681 pos = token.pos; 3682 List<JCTree> err = isVoid 3683 ? List.of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 3684 List.nil(), List.nil(), null, null))) 3685 : null; 3686 return List.of(syntaxError(token.pos, err, "expected", LPAREN)); 3687 } 3688 } 3689 } 3690 } 3691 } 3692 3693 /** MethodDeclaratorRest = 3694 * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 3695 * VoidMethodDeclaratorRest = 3696 * FormalParameters [THROWS TypeList] ( MethodBody | ";") 3697 * ConstructorDeclaratorRest = 3698 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody 3699 */ 3700 protected JCTree methodDeclaratorRest(int pos, 3701 JCModifiers mods, 3702 JCExpression type, 3703 Name name, 3704 List<JCTypeParameter> typarams, 3705 boolean isInterface, boolean isVoid, 3706 Comment dc) { 3707 if (isInterface) { 3708 if ((mods.flags & Flags.STATIC) != 0) { 3709 checkSourceLevel(Feature.STATIC_INTERFACE_METHODS); 3710 } 3711 if ((mods.flags & Flags.PRIVATE) != 0) { 3712 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS); 3713 } 3714 } 3715 JCVariableDecl prevReceiverParam = this.receiverParam; 3716 try { 3717 this.receiverParam = null; 3718 // Parsing formalParameters sets the receiverParam, if present 3719 List<JCVariableDecl> params = formalParameters(); 3720 if (!isVoid) type = bracketsOpt(type); 3721 List<JCExpression> thrown = List.nil(); 3722 if (token.kind == THROWS) { 3723 nextToken(); 3724 thrown = qualidentList(true); 3725 } 3726 JCBlock body = null; 3727 JCExpression defaultValue; 3728 if (token.kind == LBRACE) { 3729 body = block(); 3730 defaultValue = null; 3731 } else { 3732 if (token.kind == DEFAULT) { 3733 accept(DEFAULT); 3734 defaultValue = annotationValue(); 3735 } else { 3736 defaultValue = null; 3737 } 3738 accept(SEMI); 3739 if (token.pos <= endPosTable.errorEndPos) { 3740 // error recovery 3741 skip(false, true, false, false); 3742 if (token.kind == LBRACE) { 3743 body = block(); 3744 } 3745 } 3746 } 3747 3748 JCMethodDecl result = 3749 toP(F.at(pos).MethodDef(mods, name, type, typarams, 3750 receiverParam, params, thrown, 3751 body, defaultValue)); 3752 attach(result, dc); 3753 return result; 3754 } finally { 3755 this.receiverParam = prevReceiverParam; 3756 } 3757 } 3758 3759 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident} 3760 */ 3761 List<JCExpression> qualidentList(boolean allowAnnos) { 3762 ListBuffer<JCExpression> ts = new ListBuffer<>(); 3763 3764 List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil(); 3765 JCExpression qi = qualident(allowAnnos); 3766 if (!typeAnnos.isEmpty()) { 3767 JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false); 3768 ts.append(at); 3769 } else { 3770 ts.append(qi); 3771 } 3772 while (token.kind == COMMA) { 3773 nextToken(); 3774 3775 typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil(); 3776 qi = qualident(allowAnnos); 3777 if (!typeAnnos.isEmpty()) { 3778 JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false); 3779 ts.append(at); 3780 } else { 3781 ts.append(qi); 3782 } 3783 } 3784 return ts.toList(); 3785 } 3786 3787 /** 3788 * {@literal 3789 * TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 3790 * } 3791 */ 3792 protected List<JCTypeParameter> typeParametersOpt() { 3793 if (token.kind == LT) { 3794 ListBuffer<JCTypeParameter> typarams = new ListBuffer<>(); 3795 nextToken(); 3796 typarams.append(typeParameter()); 3797 while (token.kind == COMMA) { 3798 nextToken(); 3799 typarams.append(typeParameter()); 3800 } 3801 accept(GT); 3802 return typarams.toList(); 3803 } else { 3804 return List.nil(); 3805 } 3806 } 3807 3808 /** 3809 * {@literal 3810 * TypeParameter = [Annotations] TypeVariable [TypeParameterBound] 3811 * TypeParameterBound = EXTENDS Type {"&" Type} 3812 * TypeVariable = Ident 3813 * } 3814 */ 3815 JCTypeParameter typeParameter() { 3816 int pos = token.pos; 3817 List<JCAnnotation> annos = typeAnnotationsOpt(); 3818 Name name = typeName(); 3819 ListBuffer<JCExpression> bounds = new ListBuffer<>(); 3820 if (token.kind == EXTENDS) { 3821 nextToken(); 3822 bounds.append(parseType()); 3823 while (token.kind == AMP) { 3824 nextToken(); 3825 bounds.append(parseType()); 3826 } 3827 } 3828 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos)); 3829 } 3830 3831 /** FormalParameters = "(" [ FormalParameterList ] ")" 3832 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 3833 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 3834 */ 3835 List<JCVariableDecl> formalParameters() { 3836 return formalParameters(false); 3837 } 3838 List<JCVariableDecl> formalParameters(boolean lambdaParameters) { 3839 ListBuffer<JCVariableDecl> params = new ListBuffer<>(); 3840 JCVariableDecl lastParam; 3841 accept(LPAREN); 3842 if (token.kind != RPAREN) { 3843 this.allowThisIdent = true; 3844 lastParam = formalParameter(lambdaParameters); 3845 if (lastParam.nameexpr != null) { 3846 this.receiverParam = lastParam; 3847 } else { 3848 params.append(lastParam); 3849 } 3850 this.allowThisIdent = false; 3851 while (token.kind == COMMA) { 3852 if ((lastParam.mods.flags & Flags.VARARGS) != 0) { 3853 error(lastParam, "varargs.must.be.last"); 3854 } 3855 nextToken(); 3856 params.append(lastParam = formalParameter(lambdaParameters)); 3857 } 3858 } 3859 if (token.kind == RPAREN) { 3860 nextToken(); 3861 } else { 3862 setErrorEndPos(token.pos); 3863 reportSyntaxError(S.prevToken().endPos, "expected3", COMMA, RPAREN, LBRACKET); 3864 } 3865 return params.toList(); 3866 } 3867 3868 List<JCVariableDecl> implicitParameters(boolean hasParens) { 3869 if (hasParens) { 3870 accept(LPAREN); 3871 } 3872 ListBuffer<JCVariableDecl> params = new ListBuffer<>(); 3873 if (token.kind != RPAREN && token.kind != ARROW) { 3874 params.append(implicitParameter()); 3875 while (token.kind == COMMA) { 3876 nextToken(); 3877 params.append(implicitParameter()); 3878 } 3879 } 3880 if (hasParens) { 3881 accept(RPAREN); 3882 } 3883 return params.toList(); 3884 } 3885 3886 JCModifiers optFinal(long flags) { 3887 JCModifiers mods = modifiersOpt(); 3888 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 3889 mods.flags |= flags; 3890 return mods; 3891 } 3892 3893 /** 3894 * Inserts the annotations (and possibly a new array level) 3895 * to the left-most type in an array or nested type. 3896 * 3897 * When parsing a type like {@code @B Outer.Inner @A []}, the 3898 * {@code @A} annotation should target the array itself, while 3899 * {@code @B} targets the nested type {@code Outer}. 3900 * 3901 * Currently the parser parses the annotation first, then 3902 * the array, and then inserts the annotation to the left-most 3903 * nested type. 3904 * 3905 * When {@code createNewLevel} is true, then a new array 3906 * level is inserted as the most inner type, and have the 3907 * annotations target it. This is useful in the case of 3908 * varargs, e.g. {@code String @A [] @B ...}, as the parser 3909 * first parses the type {@code String @A []} then inserts 3910 * a new array level with {@code @B} annotation. 3911 */ 3912 private JCExpression insertAnnotationsToMostInner( 3913 JCExpression type, List<JCAnnotation> annos, 3914 boolean createNewLevel) { 3915 int origEndPos = getEndPos(type); 3916 JCExpression mostInnerType = type; 3917 JCArrayTypeTree mostInnerArrayType = null; 3918 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) { 3919 mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType); 3920 mostInnerType = mostInnerArrayType.elemtype; 3921 } 3922 3923 if (createNewLevel) { 3924 mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType)); 3925 } 3926 3927 JCExpression mostInnerTypeToReturn = mostInnerType; 3928 if (annos.nonEmpty()) { 3929 JCExpression lastToModify = mostInnerType; 3930 3931 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) || 3932 TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { 3933 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) { 3934 lastToModify = mostInnerType; 3935 mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression(); 3936 } 3937 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) { 3938 lastToModify = mostInnerType; 3939 mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz; 3940 } 3941 } 3942 3943 mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType); 3944 3945 if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) { 3946 ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType; 3947 } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) { 3948 ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType; 3949 } else { 3950 // We never saw a SELECT or TYPEAPPLY, return the annotated type. 3951 mostInnerTypeToReturn = mostInnerType; 3952 } 3953 } 3954 3955 if (mostInnerArrayType == null) { 3956 return mostInnerTypeToReturn; 3957 } else { 3958 mostInnerArrayType.elemtype = mostInnerTypeToReturn; 3959 storeEnd(type, origEndPos); 3960 return type; 3961 } 3962 } 3963 3964 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 3965 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 3966 */ 3967 protected JCVariableDecl formalParameter() { 3968 return formalParameter(false); 3969 } 3970 protected JCVariableDecl formalParameter(boolean lambdaParameter) { 3971 JCModifiers mods = optFinal(Flags.PARAMETER); 3972 // need to distinguish between vararg annos and array annos 3973 // look at typeAnnotationsPushedBack comment 3974 this.permitTypeAnnotationsPushBack = true; 3975 JCExpression type = parseType(); 3976 this.permitTypeAnnotationsPushBack = false; 3977 3978 if (token.kind == ELLIPSIS) { 3979 List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack; 3980 typeAnnotationsPushedBack = List.nil(); 3981 mods.flags |= Flags.VARARGS; 3982 // insert var arg type annotations 3983 type = insertAnnotationsToMostInner(type, varargsAnnos, true); 3984 nextToken(); 3985 } else { 3986 // if not a var arg, then typeAnnotationsPushedBack should be null 3987 if (typeAnnotationsPushedBack.nonEmpty()) { 3988 reportSyntaxError(typeAnnotationsPushedBack.head.pos, 3989 "illegal.start.of.type"); 3990 } 3991 typeAnnotationsPushedBack = List.nil(); 3992 } 3993 return variableDeclaratorId(mods, type, lambdaParameter); 3994 } 3995 3996 protected JCVariableDecl implicitParameter() { 3997 JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER); 3998 return variableDeclaratorId(mods, null, true); 3999 } 4000 4001 /* ---------- auxiliary methods -------------- */ 4002 4003 void error(int pos, String key, Object ... args) { 4004 log.error(DiagnosticFlag.SYNTAX, pos, key, args); 4005 } 4006 4007 void error(DiagnosticPosition pos, String key, Object ... args) { 4008 log.error(DiagnosticFlag.SYNTAX, pos, key, args); 4009 } 4010 4011 void warning(int pos, String key, Object ... args) { 4012 log.warning(pos, key, args); 4013 } 4014 4015 /** Check that given tree is a legal expression statement. 4016 */ 4017 protected JCExpression checkExprStat(JCExpression t) { 4018 if (!TreeInfo.isExpressionStatement(t)) { 4019 JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t)); 4020 error(ret, "not.stmt"); 4021 return ret; 4022 } else { 4023 return t; 4024 } 4025 } 4026 4027 /** Return precedence of operator represented by token, 4028 * -1 if token is not a binary operator. @see TreeInfo.opPrec 4029 */ 4030 static int prec(TokenKind token) { 4031 JCTree.Tag oc = optag(token); 4032 return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1; 4033 } 4034 4035 /** 4036 * Return the lesser of two positions, making allowance for either one 4037 * being unset. 4038 */ 4039 static int earlier(int pos1, int pos2) { 4040 if (pos1 == Position.NOPOS) 4041 return pos2; 4042 if (pos2 == Position.NOPOS) 4043 return pos1; 4044 return (pos1 < pos2 ? pos1 : pos2); 4045 } 4046 4047 /** Return operation tag of binary operator represented by token, 4048 * No_TAG if token is not a binary operator. 4049 */ 4050 static JCTree.Tag optag(TokenKind token) { 4051 switch (token) { 4052 case BARBAR: 4053 return OR; 4054 case AMPAMP: 4055 return AND; 4056 case BAR: 4057 return BITOR; 4058 case BAREQ: 4059 return BITOR_ASG; 4060 case CARET: 4061 return BITXOR; 4062 case CARETEQ: 4063 return BITXOR_ASG; 4064 case AMP: 4065 return BITAND; 4066 case AMPEQ: 4067 return BITAND_ASG; 4068 case EQEQ: 4069 return JCTree.Tag.EQ; 4070 case BANGEQ: 4071 return NE; 4072 case LT: 4073 return JCTree.Tag.LT; 4074 case GT: 4075 return JCTree.Tag.GT; 4076 case LTEQ: 4077 return LE; 4078 case GTEQ: 4079 return GE; 4080 case LTLT: 4081 return SL; 4082 case LTLTEQ: 4083 return SL_ASG; 4084 case GTGT: 4085 return SR; 4086 case GTGTEQ: 4087 return SR_ASG; 4088 case GTGTGT: 4089 return USR; 4090 case GTGTGTEQ: 4091 return USR_ASG; 4092 case PLUS: 4093 return JCTree.Tag.PLUS; 4094 case PLUSEQ: 4095 return PLUS_ASG; 4096 case SUB: 4097 return MINUS; 4098 case SUBEQ: 4099 return MINUS_ASG; 4100 case STAR: 4101 return MUL; 4102 case STAREQ: 4103 return MUL_ASG; 4104 case SLASH: 4105 return DIV; 4106 case SLASHEQ: 4107 return DIV_ASG; 4108 case PERCENT: 4109 return MOD; 4110 case PERCENTEQ: 4111 return MOD_ASG; 4112 case INSTANCEOF: 4113 return TYPETEST; 4114 default: 4115 return NO_TAG; 4116 } 4117 } 4118 4119 /** Return operation tag of unary operator represented by token, 4120 * No_TAG if token is not a binary operator. 4121 */ 4122 static JCTree.Tag unoptag(TokenKind token) { 4123 switch (token) { 4124 case PLUS: 4125 return POS; 4126 case SUB: 4127 return NEG; 4128 case BANG: 4129 return NOT; 4130 case TILDE: 4131 return COMPL; 4132 case PLUSPLUS: 4133 return PREINC; 4134 case SUBSUB: 4135 return PREDEC; 4136 default: 4137 return NO_TAG; 4138 } 4139 } 4140 4141 /** Return type tag of basic type represented by token, 4142 * NONE if token is not a basic type identifier. 4143 */ 4144 static TypeTag typetag(TokenKind token) { 4145 switch (token) { 4146 case BYTE: 4147 return TypeTag.BYTE; 4148 case CHAR: 4149 return TypeTag.CHAR; 4150 case SHORT: 4151 return TypeTag.SHORT; 4152 case INT: 4153 return TypeTag.INT; 4154 case LONG: 4155 return TypeTag.LONG; 4156 case FLOAT: 4157 return TypeTag.FLOAT; 4158 case DOUBLE: 4159 return TypeTag.DOUBLE; 4160 case BOOLEAN: 4161 return TypeTag.BOOLEAN; 4162 default: 4163 return TypeTag.NONE; 4164 } 4165 } 4166 4167 void checkSourceLevel(Feature feature) { 4168 checkSourceLevel(token.pos, feature); 4169 } 4170 4171 protected void checkSourceLevel(int pos, Feature feature) { 4172 if (!feature.allowedInSource(source)) { 4173 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name)); 4174 } 4175 } 4176 4177 /* 4178 * a functional source tree and end position mappings 4179 */ 4180 protected static class SimpleEndPosTable extends AbstractEndPosTable { 4181 4182 private final IntHashTable endPosMap; 4183 4184 SimpleEndPosTable(JavacParser parser) { 4185 super(parser); 4186 endPosMap = new IntHashTable(); 4187 } 4188 4189 public void storeEnd(JCTree tree, int endpos) { 4190 endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos, 4191 endPosMap.lookup(tree)); 4192 } 4193 4194 protected <T extends JCTree> T to(T t) { 4195 storeEnd(t, parser.token.endPos); 4196 return t; 4197 } 4198 4199 protected <T extends JCTree> T toP(T t) { 4200 storeEnd(t, parser.S.prevToken().endPos); 4201 return t; 4202 } 4203 4204 public int getEndPos(JCTree tree) { 4205 int value = endPosMap.getFromIndex(endPosMap.lookup(tree)); 4206 // As long as Position.NOPOS==-1, this just returns value. 4207 return (value == -1) ? Position.NOPOS : value; 4208 } 4209 4210 public int replaceTree(JCTree oldTree, JCTree newTree) { 4211 int pos = endPosMap.remove(oldTree); 4212 if (pos != -1) { 4213 storeEnd(newTree, pos); 4214 return pos; 4215 } 4216 return Position.NOPOS; 4217 } 4218 } 4219 4220 /* 4221 * a default skeletal implementation without any mapping overhead. 4222 */ 4223 protected static class EmptyEndPosTable extends AbstractEndPosTable { 4224 4225 EmptyEndPosTable(JavacParser parser) { 4226 super(parser); 4227 } 4228 4229 public void storeEnd(JCTree tree, int endpos) { /* empty */ } 4230 4231 protected <T extends JCTree> T to(T t) { 4232 return t; 4233 } 4234 4235 protected <T extends JCTree> T toP(T t) { 4236 return t; 4237 } 4238 4239 public int getEndPos(JCTree tree) { 4240 return Position.NOPOS; 4241 } 4242 4243 public int replaceTree(JCTree oldTree, JCTree newTree) { 4244 return Position.NOPOS; 4245 } 4246 4247 } 4248 4249 protected static abstract class AbstractEndPosTable implements EndPosTable { 4250 /** 4251 * The current parser. 4252 */ 4253 protected JavacParser parser; 4254 4255 /** 4256 * Store the last error position. 4257 */ 4258 public int errorEndPos = Position.NOPOS; 4259 4260 public AbstractEndPosTable(JavacParser parser) { 4261 this.parser = parser; 4262 } 4263 4264 /** 4265 * Store current token's ending position for a tree, the value of which 4266 * will be the greater of last error position and the ending position of 4267 * the current token. 4268 * @param t The tree. 4269 */ 4270 protected abstract <T extends JCTree> T to(T t); 4271 4272 /** 4273 * Store current token's ending position for a tree, the value of which 4274 * will be the greater of last error position and the ending position of 4275 * the previous token. 4276 * @param t The tree. 4277 */ 4278 protected abstract <T extends JCTree> T toP(T t); 4279 4280 /** 4281 * Set the error position during the parsing phases, the value of which 4282 * will be set only if it is greater than the last stored error position. 4283 * @param errPos The error position 4284 */ 4285 public void setErrorEndPos(int errPos) { 4286 if (errPos > errorEndPos) { 4287 errorEndPos = errPos; 4288 } 4289 } 4290 4291 public void setParser(JavacParser parser) { 4292 this.parser = parser; 4293 } 4294 } 4295 }