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