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