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