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