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