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