1 /* 2 * Copyright 1999-2009 Sun Microsystems, Inc. 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. Sun designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 22 * CA 95054 USA or visit www.sun.com if you need additional information or 23 * have any questions. 24 */ 25 26 package com.sun.tools.javac.parser; 27 28 import java.util.*; 29 30 import com.sun.tools.javac.tree.*; 31 import com.sun.tools.javac.code.*; 32 import com.sun.tools.javac.util.*; 33 import com.sun.tools.javac.util.List; 34 import static com.sun.tools.javac.util.ListBuffer.lb; 35 36 import com.sun.tools.javac.tree.JCTree.*; 37 38 import static com.sun.tools.javac.parser.Token.*; 39 40 /** The parser maps a token sequence into an abstract syntax 41 * tree. It operates by recursive descent, with code derived 42 * systematically from an LL(1) grammar. For efficiency reasons, an 43 * operator precedence scheme is used for parsing binary operation 44 * expressions. 45 * 46 * <p><b>This is NOT part of any API supported by Sun Microsystems. If 47 * you write code that depends on this, you do so at your own risk. 48 * This code and its internal interfaces are subject to change or 49 * deletion without notice.</b> 50 */ 51 public class JavacParser implements Parser { 52 53 /** The number of precedence levels of infix operators. 54 */ 55 private static final int infixPrecedenceLevels = 10; 56 57 /** The scanner used for lexical analysis. 58 */ 59 private Lexer S; 60 61 /** The factory to be used for abstract syntax tree construction. 62 */ 63 protected TreeMaker F; 64 65 /** The log to be used for error diagnostics. 66 */ 67 private Log log; 68 69 /** The keyword table. */ 70 private Keywords keywords; 71 72 /** The Source language setting. */ 73 private Source source; 74 75 /** The name table. */ 76 private Names names; 77 78 // Because of javac's limited lookahead, some contexts are ambiguous in 79 // the presence of type annotations even though they are not ambiguous 80 // in the absence of type annotations. Consider this code: 81 // void m(String [] m) { } 82 // void m(String ... m) { } 83 // After parsing "String", javac calls bracketsOpt which immediately 84 // returns if the next character is not '['. Similarly, javac can see 85 // if the next token is ... and in that case parse an ellipsis. But in 86 // the presence of type annotations: 87 // void m(String @A [] m) { } 88 // void m(String @A ... m) { } 89 // no finite lookahead is enough to determine whether to read array 90 // levels or an ellipsis. Furthermore, if you call bracketsOpt, then 91 // bracketsOpt first reads all the leading annotations and only then 92 // discovers that it needs to fail. bracketsOpt needs a way to push 93 // back the extra annotations that it read. (But, bracketsOpt should 94 // not *always* be allowed to push back extra annotations that it finds 95 // -- in most contexts, any such extra annotation is an error. 96 // Another similar case occurs with arrays and receiver annotations: 97 // String b() @Array [] @Receiver { } 98 // String b() @Receiver { } 99 // 100 // The following two variables permit type annotations that have 101 // already been read to be stored for later use. Alternate 102 // implementations are possible but would cause much larger changes to 103 // the parser. 104 /** Type annotations that have already been read but have not yet been used. **/ 105 private List<JCTypeAnnotation> typeAnnotationsPushedBack = null; 106 /** 107 * If the parser notices extra annotations, then it either immediately 108 * issues an error (if this variable is false) or places the extra 109 * annotations in variable typeAnnotationsPushedBack (if this variable 110 * is true). 111 */ 112 private boolean permitTypeAnnotationsPushBack = false; 113 114 /** Construct a parser from a given scanner, tree factory and log. 115 */ 116 protected JavacParser(ParserFactory fac, 117 Lexer S, 118 boolean keepDocComments, 119 boolean keepLineMap) { 120 this.S = S; 121 S.nextToken(); // prime the pump 122 this.F = fac.F; 123 this.log = fac.log; 124 this.names = fac.names; 125 this.keywords = fac.keywords; 126 this.source = fac.source; 127 this.allowGenerics = source.allowGenerics(); 128 this.allowVarargs = source.allowVarargs(); 129 this.allowAsserts = source.allowAsserts(); 130 this.allowEnums = source.allowEnums(); 131 this.allowForeach = source.allowForeach(); 132 this.allowStaticImport = source.allowStaticImport(); 133 this.allowAnnotations = source.allowAnnotations(); 134 this.allowDiamond = source.allowDiamond(); 135 this.allowTypeAnnotations = source.allowTypeAnnotations(); 136 this.allowFunctionType = source.allowFunctionType(); 137 this.allowLambda = source.allowLambda(); 138 this.keepDocComments = keepDocComments; 139 if (keepDocComments) 140 docComments = new HashMap<JCTree,String>(); 141 this.keepLineMap = keepLineMap; 142 this.errorTree = F.Erroneous(); 143 this.debugJSR308 = fac.options.get("TA:parser") != null; 144 } 145 146 /** Switch: debug output for type-annotations operations 147 */ 148 boolean debugJSR308; 149 150 /** Switch: Should generics be recognized? 151 */ 152 boolean allowGenerics; 153 154 /** Switch: Should diamond operator be recognized? 155 */ 156 boolean allowDiamond; 157 158 /** Switch: Should varargs be recognized? 159 */ 160 boolean allowVarargs; 161 162 /** Switch: should we recognize assert statements, or just give a warning? 163 */ 164 boolean allowAsserts; 165 166 /** Switch: should we recognize enums, or just give a warning? 167 */ 168 boolean allowEnums; 169 170 /** Switch: should we recognize foreach? 171 */ 172 boolean allowForeach; 173 174 /** Switch: should we recognize static import? 175 */ 176 boolean allowStaticImport; 177 178 /** Switch: should we recognize annotations? 179 */ 180 boolean allowAnnotations; 181 182 /** Switch: should we recognize type annotations? 183 */ 184 boolean allowTypeAnnotations; 185 186 /** Switch: should we recognize function type? 187 */ 188 boolean allowFunctionType; 189 190 /** Switch: should we recognize lambda? 191 */ 192 boolean allowLambda; 193 194 /** Switch: should we keep docComments? 195 */ 196 boolean keepDocComments; 197 198 /** Switch: should we keep line table? 199 */ 200 boolean keepLineMap; 201 202 /** When terms are parsed, the mode determines which is expected: 203 * mode = EXPR : an expression 204 * mode = TYPE : a type 205 * mode = NOPARAMS : no parameters allowed for type 206 * mode = TYPEARG : type argument 207 */ 208 static final int EXPR = 1; 209 static final int TYPE = 2; 210 static final int NOPARAMS = 4; 211 static final int TYPEARG = 8; 212 static final int DIAMOND = 16; 213 214 /** The current mode. 215 */ 216 private int mode = 0; 217 218 /** The mode of the term that was parsed last. 219 */ 220 private int lastmode = 0; 221 222 /* ---------- error recovery -------------- */ 223 224 private JCErroneous errorTree; 225 226 /** Skip forward until a suitable stop token is found. 227 */ 228 private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 229 while (true) { 230 switch (S.token()) { 231 case SEMI: 232 S.nextToken(); 233 return; 234 case PUBLIC: 235 case FINAL: 236 case ABSTRACT: 237 case MONKEYS_AT: 238 case EOF: 239 case CLASS: 240 case INTERFACE: 241 case ENUM: 242 return; 243 case IMPORT: 244 if (stopAtImport) 245 return; 246 break; 247 case LBRACE: 248 case RBRACE: 249 case PRIVATE: 250 case PROTECTED: 251 case STATIC: 252 case TRANSIENT: 253 case NATIVE: 254 case VOLATILE: 255 case SYNCHRONIZED: 256 case STRICTFP: 257 case LT: 258 case BYTE: 259 case SHORT: 260 case CHAR: 261 case INT: 262 case LONG: 263 case FLOAT: 264 case DOUBLE: 265 case BOOLEAN: 266 case VOID: 267 if (stopAtMemberDecl) 268 return; 269 break; 270 case IDENTIFIER: 271 if (stopAtIdentifier) 272 return; 273 break; 274 case CASE: 275 case DEFAULT: 276 case IF: 277 case FOR: 278 case WHILE: 279 case DO: 280 case TRY: 281 case SWITCH: 282 case RETURN: 283 case THROW: 284 case BREAK: 285 case CONTINUE: 286 case ELSE: 287 case FINALLY: 288 case CATCH: 289 if (stopAtStatement) 290 return; 291 break; 292 } 293 S.nextToken(); 294 } 295 } 296 297 private JCErroneous syntaxError(int pos, String key, Token... args) { 298 return syntaxError(pos, null, key, args); 299 } 300 301 private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) { 302 setErrorEndPos(pos); 303 reportSyntaxError(pos, key, (Object[])args); 304 return toP(F.at(pos).Erroneous(errs)); 305 } 306 307 private int errorPos = Position.NOPOS; 308 /** 309 * Report a syntax error at given position using the given 310 * argument unless one was already reported at the same position. 311 */ 312 private void reportSyntaxError(int pos, String key, Object... args) { 313 if (pos > S.errPos() || pos == Position.NOPOS) { 314 if (S.token() == EOF) 315 log.error(pos, "premature.eof"); 316 else 317 log.error(pos, key, args); 318 } 319 S.errPos(pos); 320 if (S.pos() == errorPos) 321 S.nextToken(); // guarantee progress 322 errorPos = S.pos(); 323 } 324 325 326 /** Generate a syntax error at current position unless one was already 327 * reported at the same position. 328 */ 329 private JCErroneous syntaxError(String key) { 330 return syntaxError(S.pos(), key); 331 } 332 333 /** Generate a syntax error at current position unless one was 334 * already reported at the same position. 335 */ 336 private JCErroneous syntaxError(String key, Token arg) { 337 return syntaxError(S.pos(), key, arg); 338 } 339 340 /** If next input token matches given token, skip it, otherwise report 341 * an error. 342 */ 343 public void accept(Token token) { 344 if (S.token() == token) { 345 S.nextToken(); 346 } else { 347 setErrorEndPos(S.pos()); 348 reportSyntaxError(S.prevEndPos(), "expected", token); 349 } 350 } 351 352 /** Report an illegal start of expression/type error at given position. 353 */ 354 JCExpression illegal(int pos) { 355 setErrorEndPos(S.pos()); 356 if ((mode & EXPR) != 0) 357 return syntaxError(pos, "illegal.start.of.expr"); 358 else 359 return syntaxError(pos, "illegal.start.of.type"); 360 361 } 362 363 /** Report an illegal start of expression/type error at current position. 364 */ 365 JCExpression illegal() { 366 return illegal(S.pos()); 367 } 368 369 /** Diagnose a modifier flag from the set, if any. */ 370 void checkNoMods(long mods) { 371 if (mods != 0) { 372 long lowestMod = mods & -mods; 373 log.error(S.pos(), "mod.not.allowed.here", 374 Flags.asFlagSet(lowestMod)); 375 } 376 } 377 378 /* ---------- doc comments --------- */ 379 380 /** A hashtable to store all documentation comments 381 * indexed by the tree nodes they refer to. 382 * defined only if option flag keepDocComment is set. 383 */ 384 Map<JCTree, String> docComments; 385 386 /** Make an entry into docComments hashtable, 387 * provided flag keepDocComments is set and given doc comment is non-null. 388 * @param tree The tree to be used as index in the hashtable 389 * @param dc The doc comment to associate with the tree, or null. 390 */ 391 void attach(JCTree tree, String dc) { 392 if (keepDocComments && dc != null) { 393 // System.out.println("doc comment = ");System.out.println(dc);//DEBUG 394 docComments.put(tree, dc); 395 } 396 } 397 398 /* -------- source positions ------- */ 399 400 private int errorEndPos = -1; 401 402 private void setErrorEndPos(int errPos) { 403 if (errPos > errorEndPos) 404 errorEndPos = errPos; 405 } 406 407 protected int getErrorEndPos() { 408 return errorEndPos; 409 } 410 411 /** 412 * Store ending position for a tree. 413 * @param tree The tree. 414 * @param endpos The ending position to associate with the tree. 415 */ 416 protected void storeEnd(JCTree tree, int endpos) {} 417 418 /** 419 * Store ending position for a tree. The ending position should 420 * be the ending position of the current token. 421 * @param t The tree. 422 */ 423 protected <T extends JCTree> T to(T t) { return t; } 424 425 /** 426 * Store ending position for a tree. The ending position should 427 * be greater of the ending position of the previous token and errorEndPos. 428 * @param t The tree. 429 */ 430 protected <T extends JCTree> T toP(T t) { return t; } 431 432 /** Get the start position for a tree node. The start position is 433 * defined to be the position of the first character of the first 434 * token of the node's source text. 435 * @param tree The tree node 436 */ 437 public int getStartPos(JCTree tree) { 438 return TreeInfo.getStartPos(tree); 439 } 440 441 /** 442 * Get the end position for a tree node. The end position is 443 * defined to be the position of the last character of the last 444 * token of the node's source text. Returns Position.NOPOS if end 445 * positions are not generated or the position is otherwise not 446 * found. 447 * @param tree The tree node 448 */ 449 public int getEndPos(JCTree tree) { 450 return Position.NOPOS; 451 } 452 453 454 455 /* ---------- parsing -------------- */ 456 457 /** 458 * Ident = IDENTIFIER 459 */ 460 Name ident() { 461 if (S.token() == IDENTIFIER) { 462 Name name = S.name(); 463 S.nextToken(); 464 return name; 465 } else if (S.token() == ASSERT) { 466 if (allowAsserts) { 467 log.error(S.pos(), "assert.as.identifier"); 468 S.nextToken(); 469 return names.error; 470 } else { 471 log.warning(S.pos(), "assert.as.identifier"); 472 Name name = S.name(); 473 S.nextToken(); 474 return name; 475 } 476 } else if (S.token() == ENUM) { 477 if (allowEnums) { 478 log.error(S.pos(), "enum.as.identifier"); 479 S.nextToken(); 480 return names.error; 481 } else { 482 log.warning(S.pos(), "enum.as.identifier"); 483 Name name = S.name(); 484 S.nextToken(); 485 return name; 486 } 487 } else { 488 accept(IDENTIFIER); 489 return names.error; 490 } 491 } 492 493 /** 494 * Qualident = Ident { DOT Ident } 495 */ 496 public JCExpression qualident() { 497 JCExpression t = toP(F.at(S.pos()).Ident(ident())); 498 while (S.token() == DOT) { 499 int pos = S.pos(); 500 S.nextToken(); 501 t = toP(F.at(pos).Select(t, ident())); 502 } 503 return t; 504 } 505 506 /** 507 * Literal = 508 * INTLITERAL 509 * | LONGLITERAL 510 * | FLOATLITERAL 511 * | DOUBLELITERAL 512 * | CHARLITERAL 513 * | STRINGLITERAL 514 * | TRUE 515 * | FALSE 516 * | NULL 517 */ 518 JCExpression literal(Name prefix) { 519 int pos = S.pos(); 520 JCExpression t = errorTree; 521 switch (S.token()) { 522 case INTLITERAL: 523 try { 524 t = F.at(pos).Literal( 525 TypeTags.INT, 526 Convert.string2int(strval(prefix), S.radix())); 527 } catch (NumberFormatException ex) { 528 log.error(S.pos(), "int.number.too.large", strval(prefix)); 529 } 530 break; 531 case LONGLITERAL: 532 try { 533 t = F.at(pos).Literal( 534 TypeTags.LONG, 535 new Long(Convert.string2long(strval(prefix), S.radix()))); 536 } catch (NumberFormatException ex) { 537 log.error(S.pos(), "int.number.too.large", strval(prefix)); 538 } 539 break; 540 case FLOATLITERAL: { 541 String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 542 Float n; 543 try { 544 n = Float.valueOf(proper); 545 } catch (NumberFormatException ex) { 546 // error already repoted in scanner 547 n = Float.NaN; 548 } 549 if (n.floatValue() == 0.0f && !isZero(proper)) 550 log.error(S.pos(), "fp.number.too.small"); 551 else if (n.floatValue() == Float.POSITIVE_INFINITY) 552 log.error(S.pos(), "fp.number.too.large"); 553 else 554 t = F.at(pos).Literal(TypeTags.FLOAT, n); 555 break; 556 } 557 case DOUBLELITERAL: { 558 String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 559 Double n; 560 try { 561 n = Double.valueOf(proper); 562 } catch (NumberFormatException ex) { 563 // error already reported in scanner 564 n = Double.NaN; 565 } 566 if (n.doubleValue() == 0.0d && !isZero(proper)) 567 log.error(S.pos(), "fp.number.too.small"); 568 else if (n.doubleValue() == Double.POSITIVE_INFINITY) 569 log.error(S.pos(), "fp.number.too.large"); 570 else 571 t = F.at(pos).Literal(TypeTags.DOUBLE, n); 572 break; 573 } 574 case CHARLITERAL: 575 t = F.at(pos).Literal( 576 TypeTags.CHAR, 577 S.stringVal().charAt(0) + 0); 578 break; 579 case STRINGLITERAL: 580 t = F.at(pos).Literal( 581 TypeTags.CLASS, 582 S.stringVal()); 583 break; 584 case TRUE: case FALSE: 585 t = F.at(pos).Literal( 586 TypeTags.BOOLEAN, 587 (S.token() == TRUE ? 1 : 0)); 588 break; 589 case NULL: 590 t = F.at(pos).Literal( 591 TypeTags.BOT, 592 null); 593 break; 594 default: 595 assert false; 596 } 597 if (t == errorTree) 598 t = F.at(pos).Erroneous(); 599 storeEnd(t, S.endPos()); 600 S.nextToken(); 601 return t; 602 } 603 //where 604 boolean isZero(String s) { 605 char[] cs = s.toCharArray(); 606 int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10); 607 int i = ((base==16) ? 2 : 0); 608 while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++; 609 return !(i < cs.length && (Character.digit(cs[i], base) > 0)); 610 } 611 612 String strval(Name prefix) { 613 String s = S.stringVal(); 614 return prefix.isEmpty() ? s : prefix + s; 615 } 616 617 /** terms can be either expressions or types. 618 */ 619 public JCExpression parseExpression() { 620 return term(EXPR); 621 } 622 623 /** 624 * parses (optional) type annotations followed by a type. If the 625 * annotations are present before the type and are not consumed during array 626 * parsing, this method returns a {@link JCAnnotatedType} consisting of 627 * these annotations and the underlying type. Otherwise, it returns the 628 * underlying type. 629 * 630 * <p> 631 * 632 * Note that this method sets {@code mode} to {@code TYPE} first, before 633 * parsing annotations. 634 */ 635 public JCExpression parseType() { 636 List<JCTypeAnnotation> annotations = typeAnnotationsOpt(); 637 return parseType(annotations); 638 } 639 640 public JCExpression parseType(List<JCTypeAnnotation> annotations) { 641 JCExpression result = unannotatedType(); 642 643 if (!annotations.isEmpty()) 644 result = F.AnnotatedType(annotations, result); 645 646 return result; 647 } 648 649 public JCExpression unannotatedType() { 650 return term(TYPE); 651 } 652 653 JCExpression term(int newmode) { 654 int prevmode = mode; 655 mode = newmode; 656 JCExpression t = term(); 657 lastmode = mode; 658 mode = prevmode; 659 return t; 660 } 661 662 /** 663 * Expression = Expression1 [ExpressionRest] 664 * ExpressionRest = [AssignmentOperator Expression1] 665 * AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" | 666 * "&=" | "|=" | "^=" | 667 * "%=" | "<<=" | ">>=" | ">>>=" 668 * Type = Type1 669 * TypeNoParams = TypeNoParams1 670 * StatementExpression = Expression 671 * ConstantExpression = Expression 672 */ 673 JCExpression term() { 674 JCExpression t = term1(); 675 if ((mode & EXPR) != 0 && 676 S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0) 677 return termRest(t); 678 else 679 return t; 680 } 681 682 JCExpression termRest(JCExpression t) { 683 switch (S.token()) { 684 case EQ: { 685 int pos = S.pos(); 686 S.nextToken(); 687 mode = EXPR; 688 JCExpression t1 = term(); 689 return toP(F.at(pos).Assign(t, t1)); 690 } 691 case PLUSEQ: 692 case SUBEQ: 693 case STAREQ: 694 case SLASHEQ: 695 case PERCENTEQ: 696 case AMPEQ: 697 case BAREQ: 698 case CARETEQ: 699 case LTLTEQ: 700 case GTGTEQ: 701 case GTGTGTEQ: 702 int pos = S.pos(); 703 Token token = S.token(); 704 S.nextToken(); 705 mode = EXPR; 706 JCExpression t1 = term(); 707 return F.at(pos).Assignop(optag(token), t, t1); 708 default: 709 return t; 710 } 711 } 712 713 /** Expression1 = Expression2 [Expression1Rest] 714 * Type1 = Type2 715 * TypeNoParams1 = TypeNoParams2 716 */ 717 JCExpression term1() { 718 JCExpression t = term2(); 719 if ((mode & EXPR) != 0 && S.token() == QUES) { 720 mode = EXPR; 721 return term1Rest(t); 722 } else { 723 return t; 724 } 725 } 726 727 /** Expression1Rest = ["?" Expression ":" Expression1] 728 */ 729 JCExpression term1Rest(JCExpression t) { 730 if (S.token() == QUES) { 731 int pos = S.pos(); 732 S.nextToken(); 733 JCExpression t1 = term(); 734 accept(COLON); 735 JCExpression t2 = term1(); 736 return F.at(pos).Conditional(t, t1, t2); 737 } else { 738 return t; 739 } 740 } 741 742 /** Expression2 = Expression3 [Expression2Rest] 743 * Type2 = Type3 744 * TypeNoParams2 = TypeNoParams3 745 */ 746 JCExpression term2() { 747 JCExpression t = term3(); 748 if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) { 749 mode = EXPR; 750 return term2Rest(t, TreeInfo.orPrec); 751 } else { 752 return t; 753 } 754 } 755 756 /* Expression2Rest = {infixop Expression3} 757 * | Expression3 instanceof Type 758 * infixop = "||" 759 * | "&&" 760 * | "|" 761 * | "^" 762 * | "&" 763 * | "==" | "!=" 764 * | "<" | ">" | "<=" | ">=" 765 * | "<<" | ">>" | ">>>" 766 * | "+" | "-" 767 * | "*" | "/" | "%" 768 */ 769 JCExpression term2Rest(JCExpression t, int minprec) { 770 List<JCExpression[]> savedOd = odStackSupply.elems; 771 JCExpression[] odStack = newOdStack(); 772 List<Token[]> savedOp = opStackSupply.elems; 773 Token[] opStack = newOpStack(); 774 // optimization, was odStack = new Tree[...]; opStack = new Tree[...]; 775 int top = 0; 776 odStack[0] = t; 777 int startPos = S.pos(); 778 Token topOp = ERROR; 779 while (prec(S.token()) >= minprec) { 780 opStack[top] = topOp; 781 top++; 782 topOp = S.token(); 783 int pos = S.pos(); 784 S.nextToken(); 785 odStack[top] = topOp == INSTANCEOF ? parseType() : term3(); 786 while (top > 0 && prec(topOp) >= prec(S.token())) { 787 odStack[top-1] = makeOp(pos, topOp, odStack[top-1], 788 odStack[top]); 789 top--; 790 topOp = opStack[top]; 791 } 792 } 793 assert top == 0; 794 t = odStack[0]; 795 796 if (t.getTag() == JCTree.PLUS) { 797 StringBuffer buf = foldStrings(t); 798 if (buf != null) { 799 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString())); 800 } 801 } 802 803 odStackSupply.elems = savedOd; // optimization 804 opStackSupply.elems = savedOp; // optimization 805 return t; 806 } 807 //where 808 /** Construct a binary or type test node. 809 */ 810 private JCExpression makeOp(int pos, 811 Token topOp, 812 JCExpression od1, 813 JCExpression od2) 814 { 815 if (topOp == INSTANCEOF) { 816 return F.at(pos).TypeTest(od1, od2); 817 } else { 818 return F.at(pos).Binary(optag(topOp), od1, od2); 819 } 820 } 821 /** If tree is a concatenation of string literals, replace it 822 * by a single literal representing the concatenated string. 823 */ 824 protected StringBuffer foldStrings(JCTree tree) { 825 List<String> buf = List.nil(); 826 while (true) { 827 if (tree.getTag() == JCTree.LITERAL) { 828 JCLiteral lit = (JCLiteral) tree; 829 if (lit.typetag == TypeTags.CLASS) { 830 StringBuffer sbuf = 831 new StringBuffer((String)lit.value); 832 while (buf.nonEmpty()) { 833 sbuf.append(buf.head); 834 buf = buf.tail; 835 } 836 return sbuf; 837 } 838 } else if (tree.getTag() == JCTree.PLUS) { 839 JCBinary op = (JCBinary)tree; 840 if (op.rhs.getTag() == JCTree.LITERAL) { 841 JCLiteral lit = (JCLiteral) op.rhs; 842 if (lit.typetag == TypeTags.CLASS) { 843 buf = buf.prepend((String) lit.value); 844 tree = op.lhs; 845 continue; 846 } 847 } 848 } 849 return null; 850 } 851 } 852 853 /** optimization: To save allocating a new operand/operator stack 854 * for every binary operation, we use supplys. 855 */ 856 ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>(); 857 ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>(); 858 859 private JCExpression[] newOdStack() { 860 if (odStackSupply.elems == odStackSupply.last) 861 odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]); 862 JCExpression[] odStack = odStackSupply.elems.head; 863 odStackSupply.elems = odStackSupply.elems.tail; 864 return odStack; 865 } 866 867 private Token[] newOpStack() { 868 if (opStackSupply.elems == opStackSupply.last) 869 opStackSupply.append(new Token[infixPrecedenceLevels + 1]); 870 Token[] opStack = opStackSupply.elems.head; 871 opStackSupply.elems = opStackSupply.elems.tail; 872 return opStack; 873 } 874 875 /** Expression3 = PrefixOp Expression3 876 * | "(" Expr | TypeNoParams ")" Expression3 877 * | Primary {Selector} {PostfixOp} 878 * Primary = "(" Expression ")" 879 * | Literal 880 * | [TypeArguments] THIS [Arguments] 881 * | [TypeArguments] SUPER SuperSuffix 882 * | NEW [TypeArguments] Creator 883 * | [Annotations] Ident { "." Ident } 884 * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 885 * | Arguments 886 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 887 * ] 888 * | BasicType BracketsOpt "." CLASS 889 * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" 890 * PostfixOp = "++" | "--" 891 * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt 892 * | BasicType 893 * | FunctionType 894 * TypeNoParams3 = Ident { "." Ident } BracketsOpt 895 * Selector = "." [TypeArguments] Ident [Arguments] 896 * | "." THIS 897 * | "." [TypeArguments] SUPER SuperSuffix 898 * | "." NEW [TypeArguments] InnerCreator 899 * | "[" Expression "]" 900 * TypeSelector = "." Ident [TypeArguments] 901 * SuperSuffix = Arguments | "." Ident [Arguments] 902 */ 903 protected JCExpression term3() { 904 int pos = S.pos(); 905 JCExpression t; 906 List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); 907 switch (S.token()) { 908 case QUES: 909 if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { 910 mode = TYPE; 911 return typeArgument(); 912 } else 913 return illegal(); 914 case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: 915 if (typeArgs == null && (mode & EXPR) != 0) { 916 Token token = S.token(); 917 S.nextToken(); 918 mode = EXPR; 919 if (token == SUB && 920 (S.token() == INTLITERAL || S.token() == LONGLITERAL) && 921 S.radix() == 10) { 922 mode = EXPR; 923 t = literal(names.hyphen); 924 } else { 925 t = term3(); 926 return F.at(pos).Unary(unoptag(token), t); 927 } 928 } else return illegal(); 929 break; 930 case LPAREN: 931 if (typeArgs == null && (mode & EXPR) != 0) { 932 S.nextToken(); 933 mode = EXPR | TYPE | NOPARAMS; 934 t = term3(); 935 if ((mode & TYPE) != 0 && S.token() == LT) { 936 // Could be a cast to a parameterized type 937 int op = JCTree.LT; 938 int pos1 = S.pos(); 939 S.nextToken(); 940 mode &= (EXPR | TYPE); 941 mode |= TYPEARG; 942 JCExpression t1 = term3(); 943 if ((mode & TYPE) != 0 && 944 (S.token() == COMMA || S.token() == GT)) { 945 mode = TYPE; 946 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 947 args.append(t1); 948 while (S.token() == COMMA) { 949 S.nextToken(); 950 args.append(typeArgument()); 951 } 952 accept(GT); 953 t = F.at(pos1).TypeApply(t, args.toList()); 954 checkGenerics(); 955 while (S.token() == DOT) { 956 S.nextToken(); 957 mode = TYPE; 958 t = toP(F.at(S.pos()).Select(t, ident())); 959 t = typeArgumentsOpt(t); 960 } 961 t = bracketsOpt(toP(t)); 962 } else if ((mode & EXPR) != 0) { 963 mode = EXPR; 964 t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec)); 965 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 966 } else { 967 accept(GT); 968 } 969 } 970 else { 971 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec))); 972 } 973 accept(RPAREN); 974 lastmode = mode; 975 mode = EXPR; 976 if ((lastmode & EXPR) == 0) { 977 JCExpression t1 = term3(); 978 return F.at(pos).TypeCast(t, t1); 979 } else if ((lastmode & TYPE) != 0) { 980 switch (S.token()) { 981 /*case PLUSPLUS: case SUBSUB: */ 982 case BANG: case TILDE: 983 case LPAREN: case THIS: case SUPER: 984 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: 985 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 986 case TRUE: case FALSE: case NULL: 987 case NEW: case IDENTIFIER: case ASSERT: case ENUM: 988 case BYTE: case SHORT: case CHAR: case INT: 989 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: 990 case VOID: case SHARP: 991 JCExpression t1 = term3(); 992 return F.at(pos).TypeCast(t, t1); 993 } 994 } 995 } else return illegal(); 996 t = toP(F.at(pos).Parens(t)); 997 break; 998 case THIS: 999 if ((mode & EXPR) != 0) { 1000 mode = EXPR; 1001 t = to(F.at(pos).Ident(names._this)); 1002 S.nextToken(); 1003 if (typeArgs == null) 1004 t = argumentsOpt(null, t); 1005 else 1006 t = arguments(typeArgs, t); 1007 typeArgs = null; 1008 } else return illegal(); 1009 break; 1010 case SUPER: 1011 if ((mode & EXPR) != 0) { 1012 mode = EXPR; 1013 t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super))); 1014 typeArgs = null; 1015 } else return illegal(); 1016 break; 1017 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL: 1018 case CHARLITERAL: case STRINGLITERAL: 1019 case TRUE: case FALSE: case NULL: 1020 if (typeArgs == null && (mode & EXPR) != 0) { 1021 mode = EXPR; 1022 t = literal(names.empty); 1023 } else return illegal(); 1024 break; 1025 case NEW: 1026 if (typeArgs != null) return illegal(); 1027 if ((mode & EXPR) != 0) { 1028 mode = EXPR; 1029 S.nextToken(); 1030 if (S.token() == LT) typeArgs = typeArguments(); 1031 t = creator(pos, typeArgs); 1032 typeArgs = null; 1033 } else return illegal(); 1034 break; 1035 case MONKEYS_AT: 1036 1037 // only annotated targetting class literals or cast types are valid 1038 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt(); 1039 if (typeAnnos.isEmpty()) { 1040 // else there would be no '@' 1041 throw new AssertionError("type annos is empty"); 1042 } 1043 1044 JCExpression expr = term3(); 1045 1046 // Type annotations: If term3 just parsed a non-type, expect a 1047 // class literal (and issue a syntax error if there is no class 1048 // literal). Otherwise, create a JCAnnotatedType. 1049 if ((mode & TYPE) == 0) { 1050 if (expr.getTag() != JCTree.SELECT) 1051 return illegal(typeAnnos.head.pos); 1052 JCFieldAccess sel = (JCFieldAccess)expr; 1053 if (sel.name != names._class) 1054 return illegal(); 1055 else { 1056 sel.selected = F.AnnotatedType(typeAnnos, sel.selected); 1057 t = expr; 1058 } 1059 } else { 1060 // type annotation targeting a cast 1061 t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr)); 1062 } 1063 break; 1064 case SHARP: 1065 if (typeArgs != null) illegal(); 1066 JCExpression exprType = bracketsOpt(functionType()); 1067 if (S.token() == DOT) { 1068 exprType = bracketsSuffix(exprType); 1069 } 1070 t = exprType; 1071 break; 1072 case IDENTIFIER: case ASSERT: case ENUM: 1073 if (typeArgs != null) return illegal(); 1074 t = toP(F.at(S.pos()).Ident(ident())); 1075 loop: while (true) { 1076 pos = S.pos(); 1077 final List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 1078 1079 // need to report an error later if LBRACKET is for array 1080 // index access rather than array creation level 1081 if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS) 1082 return illegal(annos.head.pos); 1083 switch (S.token()) { 1084 case LBRACKET: 1085 S.nextToken(); 1086 1087 if (S.token() == RBRACKET) { 1088 1089 S.nextToken(); 1090 1091 t = bracketsOpt(t, annos); 1092 t = toP(F.at(pos).TypeArray(t)); 1093 t = bracketsSuffix(t); 1094 } else { 1095 if ((mode & EXPR) != 0) { 1096 mode = EXPR; 1097 JCExpression t1 = term(); 1098 if (!annos.isEmpty()) t = illegal(annos.head.pos); 1099 t = to(F.at(pos).Indexed(t, t1)); 1100 } 1101 accept(RBRACKET); 1102 } 1103 break loop; 1104 case LPAREN: 1105 if ((mode & EXPR) != 0) { 1106 mode = EXPR; 1107 t = argumentsOrLambda(typeArgs, t); 1108 typeArgs = null; 1109 } 1110 break loop; 1111 case DOT: 1112 S.nextToken(); 1113 int oldmode = mode; 1114 mode &= ~NOPARAMS; 1115 typeArgs = typeArgumentsOpt(EXPR); 1116 mode = oldmode; 1117 if ((mode & EXPR) != 0) { 1118 switch (S.token()) { 1119 case CLASS: 1120 if (typeArgs != null) return illegal(); 1121 mode = EXPR; 1122 t = to(F.at(pos).Select(t, names._class)); 1123 S.nextToken(); 1124 break loop; 1125 case THIS: 1126 if (typeArgs != null) return illegal(); 1127 mode = EXPR; 1128 t = to(F.at(pos).Select(t, names._this)); 1129 S.nextToken(); 1130 break loop; 1131 case SUPER: 1132 mode = EXPR; 1133 t = to(F.at(pos).Select(t, names._super)); 1134 t = superSuffix(typeArgs, t); 1135 typeArgs = null; 1136 break loop; 1137 case NEW: 1138 if (typeArgs != null) return illegal(); 1139 mode = EXPR; 1140 int pos1 = S.pos(); 1141 S.nextToken(); 1142 if (S.token() == LT) typeArgs = typeArguments(); 1143 t = innerCreator(pos1, typeArgs, t); 1144 typeArgs = null; 1145 break loop; 1146 } 1147 } 1148 // typeArgs saved for next loop iteration. 1149 t = toP(F.at(pos).Select(t, ident())); 1150 break; 1151 case ELLIPSIS: 1152 assert this.permitTypeAnnotationsPushBack; 1153 typeAnnotationsPushedBack = annos; 1154 break loop; 1155 default: 1156 break loop; 1157 } 1158 } 1159 if (typeArgs != null) illegal(); 1160 t = typeArgumentsOpt(t); 1161 break; 1162 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1163 case DOUBLE: case BOOLEAN: 1164 if (typeArgs != null) illegal(); 1165 t = bracketsSuffix(bracketsOpt(basicType())); 1166 break; 1167 case VOID: 1168 if (typeArgs != null) illegal(); 1169 if ((mode & EXPR) != 0) { 1170 S.nextToken(); 1171 if (S.token() == DOT) { 1172 JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); 1173 t = bracketsSuffix(ti); 1174 } else { 1175 return illegal(pos); 1176 } 1177 } else { 1178 // Support the corner case of myMethodHandle.<void>invoke() by passing 1179 // a void type (like other primitive types) to the next phase. 1180 // The error will be reported in Attr.attribTypes or Attr.visitApply. 1181 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID)); 1182 S.nextToken(); 1183 return ti; 1184 //return illegal(); 1185 } 1186 break; 1187 default: 1188 return illegal(); 1189 } 1190 if (typeArgs != null) illegal(); 1191 while (true) { 1192 int pos1 = S.pos(); 1193 1194 final List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 1195 1196 if (S.token() == LBRACKET) { 1197 S.nextToken(); 1198 1199 if ((mode & TYPE) != 0) { 1200 int oldmode = mode; 1201 mode = TYPE; 1202 if (S.token() == RBRACKET) { 1203 S.nextToken(); 1204 t = bracketsOpt(t, annos); 1205 t = toP(F.at(pos1).TypeArray(t)); 1206 return t; 1207 } 1208 mode = oldmode; 1209 } 1210 if ((mode & EXPR) != 0) { 1211 mode = EXPR; 1212 JCExpression t1 = term(); 1213 t = to(F.at(pos1).Indexed(t, t1)); 1214 } 1215 accept(RBRACKET); 1216 } else if (S.token() == DOT) { 1217 S.nextToken(); 1218 typeArgs = typeArgumentsOpt(EXPR); 1219 if (S.token() == SUPER && (mode & EXPR) != 0) { 1220 mode = EXPR; 1221 t = to(F.at(pos1).Select(t, names._super)); 1222 S.nextToken(); 1223 t = arguments(typeArgs, t); 1224 typeArgs = null; 1225 } else if (S.token() == NEW && (mode & EXPR) != 0) { 1226 if (typeArgs != null) return illegal(); 1227 mode = EXPR; 1228 int pos2 = S.pos(); 1229 S.nextToken(); 1230 if (S.token() == LT) typeArgs = typeArguments(); 1231 t = innerCreator(pos2, typeArgs, t); 1232 typeArgs = null; 1233 } else { 1234 t = toP(F.at(pos1).Select(t, ident())); 1235 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 1236 typeArgs = null; 1237 } 1238 } else { 1239 if (!annos.isEmpty()) { 1240 if (permitTypeAnnotationsPushBack) 1241 typeAnnotationsPushedBack = annos; 1242 else 1243 return illegal(annos.head.pos); 1244 } 1245 break; 1246 } 1247 } 1248 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 1249 mode = EXPR; 1250 t = to(F.at(S.pos()).Unary( 1251 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 1252 S.nextToken(); 1253 } 1254 1255 return toP(t); 1256 } 1257 1258 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 1259 */ 1260 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 1261 S.nextToken(); 1262 if (S.token() == LPAREN || typeArgs != null) { 1263 t = arguments(typeArgs, t); 1264 } else { 1265 int pos = S.pos(); 1266 accept(DOT); 1267 typeArgs = (S.token() == LT) ? typeArguments() : null; 1268 t = toP(F.at(pos).Select(t, ident())); 1269 t = argumentsOpt(typeArgs, t); 1270 } 1271 return t; 1272 } 1273 1274 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 1275 */ 1276 JCPrimitiveTypeTree basicType() { 1277 JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token()))); 1278 S.nextToken(); 1279 return t; 1280 } 1281 1282 /** FunctionType = "#" Type "(" [Type { "," Type}] ")" 1283 */ 1284 JCExpression functionType() { 1285 checkFunctionType(); 1286 int pos = S.pos(); 1287 S.nextToken(); 1288 JCExpression returnType = parseType(); 1289 accept(LPAREN); 1290 List<JCExpression> parameterTypes = (S.token() != RPAREN)? typeList(): List.<JCExpression>nil(); 1291 accept(RPAREN); 1292 JCFunctionType t = to(F.at(S.pos()).FunctionType(parameterTypes, returnType)); 1293 return t; 1294 } 1295 1296 /** ArgumentsOpt = [ Arguments ] 1297 */ 1298 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 1299 if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) { 1300 mode = EXPR; 1301 return arguments(typeArgs, t); 1302 } else { 1303 return t; 1304 } 1305 } 1306 1307 /** Arguments = "(" [Expression { COMMA Expression }] ")" 1308 */ 1309 List<JCExpression> arguments() { 1310 ListBuffer<JCExpression> args = lb(); 1311 if (S.token() == LPAREN) { 1312 S.nextToken(); 1313 if (S.token() != RPAREN) { 1314 args.append(parseExpression()); 1315 while (S.token() == COMMA) { 1316 S.nextToken(); 1317 args.append(parseExpression()); 1318 } 1319 } 1320 accept(RPAREN); 1321 } else { 1322 syntaxError(S.pos(), "expected", LPAREN); 1323 } 1324 return args.toList(); 1325 } 1326 1327 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 1328 int pos = S.pos(); 1329 List<JCExpression> args = arguments(); 1330 return toP(F.at(pos).Apply(typeArgs, t, args)); 1331 } 1332 1333 JCExpression argumentsOrLambda(List<JCExpression> typeArgs, JCExpression t) { 1334 if (typeArgs != null || 1335 t.getTag() != JCTree.IDENT || 1336 ((JCIdent)t).name != names._lambda) 1337 return arguments(typeArgs, t); 1338 1339 1340 int applyPos = S.pos(); 1341 accept(LPAREN); 1342 1343 if (S.token() != RPAREN) { 1344 int firstFormalPos = S.pos(); 1345 if (S.token() == FINAL || S.token() == MONKEYS_AT) { 1346 return lambdaRest(t.pos, ListBuffer.<JCVariableDecl>lb()); 1347 } 1348 1349 JCExpression exprOrType = term(EXPR | TYPE); 1350 if ((lastmode & TYPE) != 0 && 1351 (S.token() == IDENTIFIER || 1352 S.token() == ASSERT || 1353 S.token() == ENUM)) { 1354 JCModifiers mods = toP(F.at(firstFormalPos).Modifiers(Flags.PARAMETER)); 1355 return lambdaRest(t.pos, ListBuffer.of(variableDeclaratorId(mods, exprOrType))); 1356 } 1357 1358 // not a lambda, so it's a method call 1359 ListBuffer<JCExpression> args = ListBuffer.of(exprOrType); 1360 while (S.token() == COMMA) { 1361 S.nextToken(); 1362 args.append(parseExpression()); 1363 } 1364 accept(RPAREN); 1365 1366 return toP(F.at(applyPos).Apply(typeArgs, t, args.toList())); 1367 } 1368 1369 accept(RPAREN); 1370 1371 switch(S.token()) { 1372 case LPAREN: // lambda expression 1373 return toP(F.at(applyPos).Lambda(List.<JCVariableDecl>nil(), lambdaExpression())); 1374 case LBRACE: // lambda statement 1375 return toP(F.at(applyPos).Lambda(List.<JCVariableDecl>nil(), block())); 1376 default: // method call with no argument 1377 return toP(F.at(applyPos).Apply(typeArgs, t, List.<JCExpression>nil())); 1378 } 1379 } 1380 1381 JCLambda lambdaRest(int pos, ListBuffer<JCVariableDecl> formals) { 1382 if (S.token() != RPAREN) { 1383 if (!formals.isEmpty()) { 1384 accept(COMMA); 1385 } 1386 1387 formals.append(lambdaFormalParameter()); 1388 while (S.token() == COMMA) { 1389 S.nextToken(); 1390 formals.append(lambdaFormalParameter()); 1391 } 1392 } 1393 accept(RPAREN); 1394 1395 if (S.token() == LBRACE) { 1396 return toP(F.at(pos).Lambda(formals.toList(), block())); 1397 } else { 1398 return toP(F.at(pos).Lambda(formals.toList(), lambdaExpression())); 1399 } 1400 } 1401 1402 JCVariableDecl lambdaFormalParameter() { 1403 JCModifiers mods = optFinal(Flags.PARAMETER); 1404 JCExpression type = parseType(); 1405 return variableDeclaratorId(mods, type); 1406 } 1407 1408 JCExpression lambdaExpression() { 1409 accept(LPAREN); 1410 JCExpression expr = parseExpression(); 1411 accept(RPAREN); 1412 return expr; 1413 } 1414 1415 1416 /** TypeArgumentsOpt = [ TypeArguments ] 1417 */ 1418 JCExpression typeArgumentsOpt(JCExpression t) { 1419 if (S.token() == LT && 1420 (mode & TYPE) != 0 && 1421 (mode & NOPARAMS) == 0) { 1422 mode = TYPE; 1423 checkGenerics(); 1424 return typeArguments(t); 1425 } else { 1426 return t; 1427 } 1428 } 1429 List<JCExpression> typeArgumentsOpt() { 1430 return typeArgumentsOpt(TYPE); 1431 } 1432 1433 List<JCExpression> typeArgumentsOpt(int useMode) { 1434 if (S.token() == LT) { 1435 checkGenerics(); 1436 if ((mode & useMode) == 0 || 1437 (mode & NOPARAMS) != 0) { 1438 illegal(); 1439 } 1440 mode = useMode; 1441 return typeArguments(); 1442 } 1443 return null; 1444 } 1445 1446 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 1447 */ 1448 List<JCExpression> typeArguments() { 1449 ListBuffer<JCExpression> args = lb(); 1450 if (S.token() == LT) { 1451 S.nextToken(); 1452 if (S.token() == GT && (mode & DIAMOND) != 0) { 1453 checkDiamond(); 1454 S.nextToken(); 1455 return List.nil(); 1456 } 1457 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1458 while (S.token() == COMMA) { 1459 S.nextToken(); 1460 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1461 } 1462 switch (S.token()) { 1463 case GTGTGTEQ: 1464 S.token(GTGTEQ); 1465 break; 1466 case GTGTEQ: 1467 S.token(GTEQ); 1468 break; 1469 case GTEQ: 1470 S.token(EQ); 1471 break; 1472 case GTGTGT: 1473 S.token(GTGT); 1474 break; 1475 case GTGT: 1476 S.token(GT); 1477 break; 1478 default: 1479 accept(GT); 1480 break; 1481 } 1482 } else { 1483 syntaxError(S.pos(), "expected", LT); 1484 } 1485 return args.toList(); 1486 } 1487 1488 /** TypeArgument = Type 1489 * | [Annotations] "?" 1490 * | [Annotations] "?" EXTENDS Type {"&" Type} 1491 * | [Annotations] "?" SUPER Type 1492 */ 1493 JCExpression typeArgument() { 1494 List<JCTypeAnnotation> annotations = typeAnnotationsOpt(); 1495 if (S.token() != QUES) return parseType(annotations); 1496 int pos = S.pos(); 1497 S.nextToken(); 1498 JCExpression result; 1499 if (S.token() == EXTENDS) { 1500 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS)); 1501 S.nextToken(); 1502 result = F.at(pos).Wildcard(t, parseType()); 1503 } else if (S.token() == SUPER) { 1504 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER)); 1505 S.nextToken(); 1506 result = F.at(pos).Wildcard(t, parseType()); 1507 } else if (S.token() == IDENTIFIER) { 1508 //error recovery 1509 reportSyntaxError(S.prevEndPos(), "expected3", 1510 GT, EXTENDS, SUPER); 1511 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1512 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1513 JCIdent id = toP(F.at(S.pos()).Ident(ident())); 1514 result = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1515 } else { 1516 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1517 result = toP(F.at(pos).Wildcard(t, null)); 1518 } 1519 if (!annotations.isEmpty()) 1520 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result)); 1521 return result; 1522 } 1523 1524 JCTypeApply typeArguments(JCExpression t) { 1525 int pos = S.pos(); 1526 List<JCExpression> args = typeArguments(); 1527 return toP(F.at(pos).TypeApply(t, args)); 1528 } 1529 1530 /** 1531 * BracketsOpt = { [Annotations] "[" "]" } 1532 * 1533 * <p> 1534 * 1535 * <code>annotations</code> is the list of annotations targeting 1536 * the expression <code>t</code>. 1537 */ 1538 private JCExpression bracketsOpt(JCExpression t, 1539 List<JCTypeAnnotation> annotations) { 1540 List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); 1541 1542 if (S.token() == LBRACKET) { 1543 int pos = S.pos(); 1544 S.nextToken(); 1545 1546 JCExpression orig = t; 1547 t = bracketsOptCont(t, pos, nextLevelAnnotations); 1548 } else if (!nextLevelAnnotations.isEmpty()) { 1549 if (permitTypeAnnotationsPushBack) { 1550 this.typeAnnotationsPushedBack = nextLevelAnnotations; 1551 } else 1552 return illegal(nextLevelAnnotations.head.pos); 1553 } 1554 1555 int apos = S.pos(); 1556 if (!annotations.isEmpty()) 1557 t = F.at(apos).AnnotatedType(annotations, t); 1558 return t; 1559 } 1560 1561 /** BracketsOpt = {"[" TypeAnnotations "]"} 1562 */ 1563 private JCExpression bracketsOpt(JCExpression t) { 1564 return bracketsOpt(t, List.<JCTypeAnnotation>nil()); 1565 } 1566 1567 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos, 1568 List<JCTypeAnnotation> annotations) { 1569 accept(RBRACKET); 1570 t = bracketsOpt(t, annotations); 1571 return toP(F.at(pos).TypeArray(t)); 1572 } 1573 1574 /** BracketsSuffixExpr = "." CLASS 1575 * BracketsSuffixType = 1576 */ 1577 JCExpression bracketsSuffix(JCExpression t) { 1578 if ((mode & EXPR) != 0 && S.token() == DOT) { 1579 mode = EXPR; 1580 int pos = S.pos(); 1581 S.nextToken(); 1582 accept(CLASS); 1583 if (S.pos() == errorEndPos) { 1584 // error recovery 1585 Name name = null; 1586 if (S.token() == IDENTIFIER) { 1587 name = S.name(); 1588 S.nextToken(); 1589 } else { 1590 name = names.error; 1591 } 1592 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name)))); 1593 } else { 1594 t = toP(F.at(pos).Select(t, names._class)); 1595 } 1596 } else if ((mode & TYPE) != 0) { 1597 mode = TYPE; 1598 } else { 1599 syntaxError(S.pos(), "dot.class.expected"); 1600 } 1601 return t; 1602 } 1603 1604 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 1605 */ 1606 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 1607 1608 List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt(); 1609 1610 switch (S.token()) { 1611 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1612 case DOUBLE: case BOOLEAN: 1613 if (typeArgs == null) { 1614 if (newAnnotations.isEmpty()) 1615 return arrayCreatorRest(newpos, basicType()); 1616 else 1617 return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType())); 1618 } 1619 break; 1620 default: 1621 } 1622 JCExpression t = qualident(); 1623 // handle type annotations for non primitive arrays 1624 if (!newAnnotations.isEmpty()) 1625 t = F.AnnotatedType(newAnnotations, t); 1626 1627 int oldmode = mode; 1628 mode = TYPE | DIAMOND; 1629 if (S.token() == LT) { 1630 checkGenerics(); 1631 t = typeArguments(t); 1632 } 1633 while (S.token() == DOT) { 1634 int pos = S.pos(); 1635 S.nextToken(); 1636 t = toP(F.at(pos).Select(t, ident())); 1637 if (S.token() == LT) { 1638 checkGenerics(); 1639 t = typeArguments(t); 1640 } 1641 } 1642 mode = oldmode; 1643 if (S.token() == LBRACKET || S.token() == MONKEYS_AT) { 1644 JCExpression e = arrayCreatorRest(newpos, t); 1645 if (typeArgs != null) { 1646 int pos = newpos; 1647 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 1648 // note: this should always happen but we should 1649 // not rely on this as the parser is continuously 1650 // modified to improve error recovery. 1651 pos = typeArgs.head.pos; 1652 } 1653 setErrorEndPos(S.prevEndPos()); 1654 reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 1655 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 1656 } 1657 return e; 1658 } else if (S.token() == LPAREN) { 1659 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); 1660 if (newClass.def != null) { 1661 assert newClass.def.mods.annotations.isEmpty(); 1662 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); 1663 } 1664 return newClass; 1665 } else { 1666 reportSyntaxError(S.pos(), "expected2", 1667 LPAREN, LBRACKET); 1668 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 1669 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 1670 } 1671 } 1672 1673 /** InnerCreator = Ident [TypeArguments] ClassCreatorRest 1674 */ 1675 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 1676 JCExpression t = toP(F.at(S.pos()).Ident(ident())); 1677 if (S.token() == LT) { 1678 int oldmode = mode; 1679 mode |= DIAMOND; 1680 checkGenerics(); 1681 t = typeArguments(t); 1682 mode = oldmode; 1683 } 1684 return classCreatorRest(newpos, encl, typeArgs, t); 1685 } 1686 1687 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer 1688 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt ) 1689 */ 1690 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 1691 1692 List<JCTypeAnnotation> topAnnos = List.nil(); 1693 if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) { 1694 JCAnnotatedType atype = (JCAnnotatedType) elemtype; 1695 topAnnos = atype.annotations; 1696 elemtype = atype.underlyingType; 1697 } 1698 1699 List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 1700 1701 accept(LBRACKET); 1702 1703 if (S.token() == RBRACKET) { 1704 accept(RBRACKET); 1705 1706 elemtype = bracketsOpt(elemtype, annos); 1707 1708 if (S.token() == LBRACE) { 1709 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype); 1710 1711 na.annotations = topAnnos; 1712 1713 return na; 1714 } else { 1715 return syntaxError(S.pos(), "array.dimension.missing"); 1716 } 1717 } else { 1718 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 1719 1720 // maintain array dimension type annotations 1721 ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb(); 1722 dimAnnotations.append(annos); 1723 1724 dims.append(parseExpression()); 1725 accept(RBRACKET); 1726 while (S.token() == LBRACKET 1727 || (S.token() == MONKEYS_AT)) { 1728 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt(); 1729 int pos = S.pos(); 1730 S.nextToken(); 1731 if (S.token() == RBRACKET) { 1732 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 1733 } else { 1734 if (S.token() == RBRACKET) { // no dimension 1735 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 1736 } else { 1737 dimAnnotations.append(maybeDimAnnos); 1738 dims.append(parseExpression()); 1739 accept(RBRACKET); 1740 } 1741 } 1742 } 1743 1744 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); 1745 na.annotations = topAnnos; 1746 na.dimAnnotations = dimAnnotations.toList(); 1747 return na; 1748 } 1749 } 1750 1751 /** ClassCreatorRest = Arguments [ClassBody] 1752 */ 1753 JCNewClass classCreatorRest(int newpos, 1754 JCExpression encl, 1755 List<JCExpression> typeArgs, 1756 JCExpression t) 1757 { 1758 List<JCExpression> args = arguments(); 1759 JCClassDecl body = null; 1760 if (S.token() == LBRACE) { 1761 int pos = S.pos(); 1762 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 1763 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 1764 body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 1765 } 1766 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); 1767 } 1768 1769 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}" 1770 */ 1771 JCExpression arrayInitializer(int newpos, JCExpression t) { 1772 accept(LBRACE); 1773 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 1774 if (S.token() == COMMA) { 1775 S.nextToken(); 1776 } else if (S.token() != RBRACE) { 1777 elems.append(variableInitializer()); 1778 while (S.token() == COMMA) { 1779 S.nextToken(); 1780 if (S.token() == RBRACE) break; 1781 elems.append(variableInitializer()); 1782 } 1783 } 1784 accept(RBRACE); 1785 return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList())); 1786 } 1787 1788 /** VariableInitializer = ArrayInitializer | Expression 1789 */ 1790 public JCExpression variableInitializer() { 1791 return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression(); 1792 } 1793 1794 /** ParExpression = "(" Expression ")" 1795 */ 1796 JCExpression parExpression() { 1797 accept(LPAREN); 1798 JCExpression t = parseExpression(); 1799 accept(RPAREN); 1800 return t; 1801 } 1802 1803 /** Block = "{" BlockStatements "}" 1804 */ 1805 JCBlock block(int pos, long flags) { 1806 accept(LBRACE); 1807 List<JCStatement> stats = blockStatements(); 1808 JCBlock t = F.at(pos).Block(flags, stats); 1809 while (S.token() == CASE || S.token() == DEFAULT) { 1810 syntaxError("orphaned", S.token()); 1811 switchBlockStatementGroups(); 1812 } 1813 // the Block node has a field "endpos" for first char of last token, which is 1814 // usually but not necessarily the last char of the last token. 1815 t.endpos = S.pos(); 1816 accept(RBRACE); 1817 return toP(t); 1818 } 1819 1820 public JCBlock block() { 1821 return block(S.pos(), 0); 1822 } 1823 1824 /** BlockStatements = { BlockStatement } 1825 * BlockStatement = LocalVariableDeclarationStatement 1826 * | ClassOrInterfaceOrEnumDeclaration 1827 * | [Ident ":"] Statement 1828 * LocalVariableDeclarationStatement 1829 * = { FINAL | '@' Annotation } Type VariableDeclarators ";" 1830 */ 1831 @SuppressWarnings("fallthrough") 1832 List<JCStatement> blockStatements() { 1833 //todo: skip to anchor on error(?) 1834 int lastErrPos = -1; 1835 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 1836 while (true) { 1837 int pos = S.pos(); 1838 switch (S.token()) { 1839 case RBRACE: case CASE: case DEFAULT: case EOF: 1840 return stats.toList(); 1841 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 1842 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 1843 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 1844 stats.append(parseStatement()); 1845 break; 1846 case MONKEYS_AT: 1847 case FINAL: { 1848 String dc = S.docComment(); 1849 JCModifiers mods = modifiersOpt(); 1850 if (S.token() == INTERFACE || 1851 S.token() == CLASS || 1852 allowEnums && S.token() == ENUM) { 1853 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 1854 } else { 1855 JCExpression t = parseType(); 1856 stats.appendList(variableDeclarators(mods, t, 1857 new ListBuffer<JCStatement>())); 1858 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 1859 storeEnd(stats.elems.last(), S.endPos()); 1860 accept(SEMI); 1861 } 1862 break; 1863 } 1864 case ABSTRACT: case STRICTFP: { 1865 String dc = S.docComment(); 1866 JCModifiers mods = modifiersOpt(); 1867 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 1868 break; 1869 } 1870 case INTERFACE: 1871 case CLASS: 1872 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 1873 S.docComment())); 1874 break; 1875 case ENUM: 1876 case ASSERT: 1877 if (allowEnums && S.token() == ENUM) { 1878 log.error(S.pos(), "local.enum"); 1879 stats. 1880 append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 1881 S.docComment())); 1882 break; 1883 } else if (allowAsserts && S.token() == ASSERT) { 1884 stats.append(parseStatement()); 1885 break; 1886 } 1887 /* fall through to default */ 1888 default: 1889 Name name = S.name(); 1890 JCExpression t = term(EXPR | TYPE); 1891 if (S.token() == COLON && t.getTag() == JCTree.IDENT) { 1892 S.nextToken(); 1893 JCStatement stat = parseStatement(); 1894 stats.append(F.at(pos).Labelled(name, stat)); 1895 } else if ((lastmode & TYPE) != 0 && 1896 (S.token() == IDENTIFIER || 1897 S.token() == ASSERT || 1898 S.token() == ENUM)) { 1899 pos = S.pos(); 1900 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 1901 F.at(pos); 1902 stats.appendList(variableDeclarators(mods, t, 1903 new ListBuffer<JCStatement>())); 1904 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 1905 storeEnd(stats.elems.last(), S.endPos()); 1906 accept(SEMI); 1907 } else { 1908 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 1909 stats.append(to(F.at(pos).Exec(checkExprStat(t)))); 1910 accept(SEMI); 1911 } 1912 } 1913 1914 // error recovery 1915 if (S.pos() == lastErrPos) 1916 return stats.toList(); 1917 if (S.pos() <= errorEndPos) { 1918 skip(false, true, true, true); 1919 lastErrPos = S.pos(); 1920 } 1921 1922 // ensure no dangling /** @deprecated */ active 1923 S.resetDeprecatedFlag(); 1924 } 1925 } 1926 1927 /** Statement = 1928 * Block 1929 * | IF ParExpression Statement [ELSE Statement] 1930 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement 1931 * | FOR "(" FormalParameter : Expression ")" Statement 1932 * | WHILE ParExpression Statement 1933 * | DO Statement WHILE ParExpression ";" 1934 * | TRY Block ( Catches | [Catches] FinallyPart ) 1935 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" 1936 * | SYNCHRONIZED ParExpression Block 1937 * | RETURN [Expression] ";" 1938 * | THROW Expression ";" 1939 * | BREAK [Ident] ";" 1940 * | CONTINUE [Ident] ";" 1941 * | ASSERT Expression [ ":" Expression ] ";" 1942 * | ";" 1943 * | ExpressionStatement 1944 * | Ident ":" Statement 1945 */ 1946 @SuppressWarnings("fallthrough") 1947 public JCStatement parseStatement() { 1948 int pos = S.pos(); 1949 switch (S.token()) { 1950 case LBRACE: 1951 return block(); 1952 case IF: { 1953 S.nextToken(); 1954 JCExpression cond = parExpression(); 1955 JCStatement thenpart = parseStatement(); 1956 JCStatement elsepart = null; 1957 if (S.token() == ELSE) { 1958 S.nextToken(); 1959 elsepart = parseStatement(); 1960 } 1961 return F.at(pos).If(cond, thenpart, elsepart); 1962 } 1963 case FOR: { 1964 S.nextToken(); 1965 accept(LPAREN); 1966 List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); 1967 if (inits.length() == 1 && 1968 inits.head.getTag() == JCTree.VARDEF && 1969 ((JCVariableDecl) inits.head).init == null && 1970 S.token() == COLON) { 1971 checkForeach(); 1972 JCVariableDecl var = (JCVariableDecl)inits.head; 1973 accept(COLON); 1974 JCExpression expr = parseExpression(); 1975 accept(RPAREN); 1976 JCStatement body = parseStatement(); 1977 return F.at(pos).ForeachLoop(var, expr, body); 1978 } else { 1979 accept(SEMI); 1980 JCExpression cond = S.token() == SEMI ? null : parseExpression(); 1981 accept(SEMI); 1982 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 1983 accept(RPAREN); 1984 JCStatement body = parseStatement(); 1985 return F.at(pos).ForLoop(inits, cond, steps, body); 1986 } 1987 } 1988 case WHILE: { 1989 S.nextToken(); 1990 JCExpression cond = parExpression(); 1991 JCStatement body = parseStatement(); 1992 return F.at(pos).WhileLoop(cond, body); 1993 } 1994 case DO: { 1995 S.nextToken(); 1996 JCStatement body = parseStatement(); 1997 accept(WHILE); 1998 JCExpression cond = parExpression(); 1999 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond)); 2000 accept(SEMI); 2001 return t; 2002 } 2003 case TRY: { 2004 S.nextToken(); 2005 JCBlock body = block(); 2006 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); 2007 JCBlock finalizer = null; 2008 if (S.token() == CATCH || S.token() == FINALLY) { 2009 while (S.token() == CATCH) catchers.append(catchClause()); 2010 if (S.token() == FINALLY) { 2011 S.nextToken(); 2012 finalizer = block(); 2013 } 2014 } else { 2015 log.error(pos, "try.without.catch.or.finally"); 2016 } 2017 return F.at(pos).Try(body, catchers.toList(), finalizer); 2018 } 2019 case SWITCH: { 2020 S.nextToken(); 2021 JCExpression selector = parExpression(); 2022 accept(LBRACE); 2023 List<JCCase> cases = switchBlockStatementGroups(); 2024 JCSwitch t = to(F.at(pos).Switch(selector, cases)); 2025 accept(RBRACE); 2026 return t; 2027 } 2028 case SYNCHRONIZED: { 2029 S.nextToken(); 2030 JCExpression lock = parExpression(); 2031 JCBlock body = block(); 2032 return F.at(pos).Synchronized(lock, body); 2033 } 2034 case RETURN: { 2035 S.nextToken(); 2036 JCExpression result = S.token() == SEMI ? null : parseExpression(); 2037 JCReturn t = to(F.at(pos).Return(result)); 2038 accept(SEMI); 2039 return t; 2040 } 2041 case THROW: { 2042 S.nextToken(); 2043 JCExpression exc = parseExpression(); 2044 JCThrow t = to(F.at(pos).Throw(exc)); 2045 accept(SEMI); 2046 return t; 2047 } 2048 case BREAK: { 2049 S.nextToken(); 2050 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 2051 JCBreak t = to(F.at(pos).Break(label)); 2052 accept(SEMI); 2053 return t; 2054 } 2055 case CONTINUE: { 2056 S.nextToken(); 2057 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 2058 JCContinue t = to(F.at(pos).Continue(label)); 2059 accept(SEMI); 2060 return t; 2061 } 2062 case SEMI: 2063 S.nextToken(); 2064 return toP(F.at(pos).Skip()); 2065 case ELSE: 2066 return toP(F.Exec(syntaxError("else.without.if"))); 2067 case FINALLY: 2068 return toP(F.Exec(syntaxError("finally.without.try"))); 2069 case CATCH: 2070 return toP(F.Exec(syntaxError("catch.without.try"))); 2071 case ASSERT: { 2072 if (allowAsserts && S.token() == ASSERT) { 2073 S.nextToken(); 2074 JCExpression assertion = parseExpression(); 2075 JCExpression message = null; 2076 if (S.token() == COLON) { 2077 S.nextToken(); 2078 message = parseExpression(); 2079 } 2080 JCAssert t = to(F.at(pos).Assert(assertion, message)); 2081 accept(SEMI); 2082 return t; 2083 } 2084 /* else fall through to default case */ 2085 } 2086 case ENUM: 2087 default: 2088 Name name = S.name(); 2089 JCExpression expr = parseExpression(); 2090 if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { 2091 S.nextToken(); 2092 JCStatement stat = parseStatement(); 2093 return F.at(pos).Labelled(name, stat); 2094 } else { 2095 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 2096 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); 2097 accept(SEMI); 2098 return stat; 2099 } 2100 } 2101 } 2102 2103 /** CatchClause = CATCH "(" FormalParameter ")" Block 2104 */ 2105 JCCatch catchClause() { 2106 int pos = S.pos(); 2107 accept(CATCH); 2108 accept(LPAREN); 2109 JCVariableDecl formal = 2110 variableDeclaratorId(optFinal(Flags.PARAMETER), 2111 qualident()); 2112 accept(RPAREN); 2113 JCBlock body = block(); 2114 return F.at(pos).Catch(formal, body); 2115 } 2116 2117 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 2118 * SwitchBlockStatementGroup = SwitchLabel BlockStatements 2119 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 2120 */ 2121 List<JCCase> switchBlockStatementGroups() { 2122 ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); 2123 while (true) { 2124 int pos = S.pos(); 2125 switch (S.token()) { 2126 case CASE: { 2127 S.nextToken(); 2128 JCExpression pat = parseExpression(); 2129 accept(COLON); 2130 List<JCStatement> stats = blockStatements(); 2131 JCCase c = F.at(pos).Case(pat, stats); 2132 if (stats.isEmpty()) 2133 storeEnd(c, S.prevEndPos()); 2134 cases.append(c); 2135 break; 2136 } 2137 case DEFAULT: { 2138 S.nextToken(); 2139 accept(COLON); 2140 List<JCStatement> stats = blockStatements(); 2141 JCCase c = F.at(pos).Case(null, stats); 2142 if (stats.isEmpty()) 2143 storeEnd(c, S.prevEndPos()); 2144 cases.append(c); 2145 break; 2146 } 2147 case RBRACE: case EOF: 2148 return cases.toList(); 2149 default: 2150 S.nextToken(); // to ensure progress 2151 syntaxError(pos, "expected3", 2152 CASE, DEFAULT, RBRACE); 2153 } 2154 } 2155 } 2156 2157 /** MoreStatementExpressions = { COMMA StatementExpression } 2158 */ 2159 <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos, 2160 JCExpression first, 2161 T stats) { 2162 // This Exec is a "StatementExpression"; it subsumes no terminating token 2163 stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 2164 while (S.token() == COMMA) { 2165 S.nextToken(); 2166 pos = S.pos(); 2167 JCExpression t = parseExpression(); 2168 // This Exec is a "StatementExpression"; it subsumes no terminating token 2169 stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 2170 } 2171 return stats; 2172 } 2173 2174 /** ForInit = StatementExpression MoreStatementExpressions 2175 * | { FINAL | '@' Annotation } Type VariableDeclarators 2176 */ 2177 List<JCStatement> forInit() { 2178 ListBuffer<JCStatement> stats = lb(); 2179 int pos = S.pos(); 2180 if (S.token() == FINAL || S.token() == MONKEYS_AT) { 2181 return variableDeclarators(optFinal(0), parseType(), stats).toList(); 2182 } else { 2183 JCExpression t = term(EXPR | TYPE); 2184 if ((lastmode & TYPE) != 0 && 2185 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) 2186 return variableDeclarators(modifiersOpt(), t, stats).toList(); 2187 else 2188 return moreStatementExpressions(pos, t, stats).toList(); 2189 } 2190 } 2191 2192 /** ForUpdate = StatementExpression MoreStatementExpressions 2193 */ 2194 List<JCExpressionStatement> forUpdate() { 2195 return moreStatementExpressions(S.pos(), 2196 parseExpression(), 2197 new ListBuffer<JCExpressionStatement>()).toList(); 2198 } 2199 2200 enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO }; 2201 2202 /** AnnotationsOpt = { '@' Annotation } 2203 */ 2204 List<JCAnnotation> annotationsOpt(AnnotationKind kind) { 2205 if (S.token() != MONKEYS_AT) return List.nil(); // optimization 2206 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 2207 int prevmode = mode; 2208 while (S.token() == MONKEYS_AT) { 2209 int pos = S.pos(); 2210 S.nextToken(); 2211 buf.append(annotation(pos, kind)); 2212 } 2213 lastmode = mode; 2214 mode = prevmode; 2215 List<JCAnnotation> annotations = buf.toList(); 2216 2217 if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO) 2218 System.out.println("TA: parsing " + annotations 2219 + " in " + log.currentSourceFile()); 2220 return annotations; 2221 } 2222 2223 List<JCTypeAnnotation> typeAnnotationsOpt() { 2224 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO); 2225 return List.convert(JCTypeAnnotation.class, annotations); 2226 } 2227 2228 /** ModifiersOpt = { Modifier } 2229 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 2230 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 2231 * | "@" Annotation 2232 */ 2233 JCModifiers modifiersOpt() { 2234 return modifiersOpt(null); 2235 } 2236 JCModifiers modifiersOpt(JCModifiers partial) { 2237 long flags = (partial == null) ? 0 : partial.flags; 2238 if (S.deprecatedFlag()) { 2239 flags |= Flags.DEPRECATED; 2240 S.resetDeprecatedFlag(); 2241 } 2242 ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>(); 2243 if (partial != null) annotations.appendList(partial.annotations); 2244 int pos = S.pos(); 2245 int lastPos = Position.NOPOS; 2246 loop: 2247 while (true) { 2248 long flag; 2249 switch (S.token()) { 2250 case PRIVATE : flag = Flags.PRIVATE; break; 2251 case PROTECTED : flag = Flags.PROTECTED; break; 2252 case PUBLIC : flag = Flags.PUBLIC; break; 2253 case STATIC : flag = Flags.STATIC; break; 2254 case TRANSIENT : flag = Flags.TRANSIENT; break; 2255 case FINAL : flag = Flags.FINAL; break; 2256 case ABSTRACT : flag = Flags.ABSTRACT; break; 2257 case NATIVE : flag = Flags.NATIVE; break; 2258 case VOLATILE : flag = Flags.VOLATILE; break; 2259 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 2260 case STRICTFP : flag = Flags.STRICTFP; break; 2261 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 2262 default: break loop; 2263 } 2264 if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier"); 2265 lastPos = S.pos(); 2266 S.nextToken(); 2267 if (flag == Flags.ANNOTATION) { 2268 checkAnnotations(); 2269 if (S.token() != INTERFACE) { 2270 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO); 2271 // if first modifier is an annotation, set pos to annotation's. 2272 if (flags == 0 && annotations.isEmpty()) 2273 pos = ann.pos; 2274 annotations.append(ann); 2275 lastPos = ann.pos; 2276 flag = 0; 2277 } 2278 } 2279 flags |= flag; 2280 } 2281 switch (S.token()) { 2282 case ENUM: flags |= Flags.ENUM; break; 2283 case INTERFACE: flags |= Flags.INTERFACE; break; 2284 default: break; 2285 } 2286 2287 /* A modifiers tree with no modifier tokens or annotations 2288 * has no text position. */ 2289 if (flags == 0 && annotations.isEmpty()) 2290 pos = Position.NOPOS; 2291 2292 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 2293 if (pos != Position.NOPOS) 2294 storeEnd(mods, S.prevEndPos()); 2295 return mods; 2296 } 2297 2298 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 2299 * @param pos position of "@" token 2300 */ 2301 JCAnnotation annotation(int pos, AnnotationKind kind) { 2302 // accept(AT); // AT consumed by caller 2303 checkAnnotations(); 2304 if (kind == AnnotationKind.TYPE_ANNO) 2305 checkTypeAnnotations(); 2306 JCTree ident = qualident(); 2307 List<JCExpression> fieldValues = annotationFieldValuesOpt(); 2308 JCAnnotation ann; 2309 if (kind == AnnotationKind.DEFAULT_ANNO) 2310 ann = F.at(pos).Annotation(ident, fieldValues); 2311 else 2312 ann = F.at(pos).TypeAnnotation(ident, fieldValues); 2313 storeEnd(ann, S.prevEndPos()); 2314 return ann; 2315 } 2316 2317 List<JCExpression> annotationFieldValuesOpt() { 2318 return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 2319 } 2320 2321 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 2322 List<JCExpression> annotationFieldValues() { 2323 accept(LPAREN); 2324 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 2325 if (S.token() != RPAREN) { 2326 buf.append(annotationFieldValue()); 2327 while (S.token() == COMMA) { 2328 S.nextToken(); 2329 buf.append(annotationFieldValue()); 2330 } 2331 } 2332 accept(RPAREN); 2333 return buf.toList(); 2334 } 2335 2336 /** AnnotationFieldValue = AnnotationValue 2337 * | Identifier "=" AnnotationValue 2338 */ 2339 JCExpression annotationFieldValue() { 2340 if (S.token() == IDENTIFIER) { 2341 mode = EXPR; 2342 JCExpression t1 = term1(); 2343 if (t1.getTag() == JCTree.IDENT && S.token() == EQ) { 2344 int pos = S.pos(); 2345 accept(EQ); 2346 return toP(F.at(pos).Assign(t1, annotationValue())); 2347 } else { 2348 return t1; 2349 } 2350 } 2351 return annotationValue(); 2352 } 2353 2354 /* AnnotationValue = ConditionalExpression 2355 * | Annotation 2356 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}" 2357 */ 2358 JCExpression annotationValue() { 2359 int pos; 2360 switch (S.token()) { 2361 case MONKEYS_AT: 2362 pos = S.pos(); 2363 S.nextToken(); 2364 return annotation(pos, AnnotationKind.DEFAULT_ANNO); 2365 case LBRACE: 2366 pos = S.pos(); 2367 accept(LBRACE); 2368 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 2369 if (S.token() != RBRACE) { 2370 buf.append(annotationValue()); 2371 while (S.token() == COMMA) { 2372 S.nextToken(); 2373 if (S.token() == RBRACE) break; 2374 buf.append(annotationValue()); 2375 } 2376 } 2377 accept(RBRACE); 2378 return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList())); 2379 default: 2380 mode = EXPR; 2381 return term1(); 2382 } 2383 } 2384 2385 /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator } 2386 */ 2387 public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods, 2388 JCExpression type, 2389 T vdefs) 2390 { 2391 return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs); 2392 } 2393 2394 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 2395 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator } 2396 * 2397 * @param reqInit Is an initializer always required? 2398 * @param dc The documentation comment for the variable declarations, or null. 2399 */ 2400 <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos, 2401 JCModifiers mods, 2402 JCExpression type, 2403 Name name, 2404 boolean reqInit, 2405 String dc, 2406 T vdefs) 2407 { 2408 vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc)); 2409 while (S.token() == COMMA) { 2410 // All but last of multiple declarators subsume a comma 2411 storeEnd((JCTree)vdefs.elems.last(), S.endPos()); 2412 S.nextToken(); 2413 vdefs.append(variableDeclarator(mods, type, reqInit, dc)); 2414 } 2415 return vdefs; 2416 } 2417 2418 /** VariableDeclarator = Ident VariableDeclaratorRest 2419 * ConstantDeclarator = Ident ConstantDeclaratorRest 2420 */ 2421 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) { 2422 return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc); 2423 } 2424 2425 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 2426 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer 2427 * 2428 * @param reqInit Is an initializer always required? 2429 * @param dc The documentation comment for the variable declarations, or null. 2430 */ 2431 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, 2432 boolean reqInit, String dc) { 2433 type = bracketsOpt(type); 2434 JCExpression init = null; 2435 if (S.token() == EQ) { 2436 S.nextToken(); 2437 init = variableInitializer(); 2438 } 2439 else if (reqInit) syntaxError(S.pos(), "expected", EQ); 2440 JCVariableDecl result = 2441 toP(F.at(pos).VarDef(mods, name, type, init)); 2442 attach(result, dc); 2443 return result; 2444 } 2445 2446 /** VariableDeclaratorId = Ident BracketsOpt 2447 */ 2448 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 2449 int pos = S.pos(); 2450 Name name = ident(); 2451 if ((mods.flags & Flags.VARARGS) == 0) 2452 type = bracketsOpt(type); 2453 return toP(F.at(pos).VarDef(mods, name, type, null)); 2454 } 2455 2456 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 2457 */ 2458 public JCTree.JCCompilationUnit parseCompilationUnit() { 2459 int pos = S.pos(); 2460 JCExpression pid = null; 2461 String dc = S.docComment(); 2462 JCModifiers mods = null; 2463 List<JCAnnotation> packageAnnotations = List.nil(); 2464 if (S.token() == MONKEYS_AT) 2465 mods = modifiersOpt(); 2466 2467 if (S.token() == PACKAGE) { 2468 if (mods != null) { 2469 checkNoMods(mods.flags); 2470 packageAnnotations = mods.annotations; 2471 mods = null; 2472 } 2473 S.nextToken(); 2474 pid = qualident(); 2475 accept(SEMI); 2476 } 2477 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2478 boolean checkForImports = true; 2479 while (S.token() != EOF) { 2480 if (S.pos() <= errorEndPos) { 2481 // error recovery 2482 skip(checkForImports, false, false, false); 2483 if (S.token() == EOF) 2484 break; 2485 } 2486 if (checkForImports && mods == null && S.token() == IMPORT) { 2487 defs.append(importDeclaration()); 2488 } else { 2489 JCTree def = typeDeclaration(mods); 2490 if (def instanceof JCExpressionStatement) 2491 def = ((JCExpressionStatement)def).expr; 2492 defs.append(def); 2493 if (def instanceof JCClassDecl) 2494 checkForImports = false; 2495 mods = null; 2496 } 2497 } 2498 JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList()); 2499 attach(toplevel, dc); 2500 if (defs.elems.isEmpty()) 2501 storeEnd(toplevel, S.prevEndPos()); 2502 if (keepDocComments) 2503 toplevel.docComments = docComments; 2504 if (keepLineMap) 2505 toplevel.lineMap = S.getLineMap(); 2506 return toplevel; 2507 } 2508 2509 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 2510 */ 2511 JCTree importDeclaration() { 2512 int pos = S.pos(); 2513 S.nextToken(); 2514 boolean importStatic = false; 2515 if (S.token() == STATIC) { 2516 checkStaticImports(); 2517 importStatic = true; 2518 S.nextToken(); 2519 } 2520 JCExpression pid = toP(F.at(S.pos()).Ident(ident())); 2521 do { 2522 int pos1 = S.pos(); 2523 accept(DOT); 2524 if (S.token() == STAR) { 2525 pid = to(F.at(pos1).Select(pid, names.asterisk)); 2526 S.nextToken(); 2527 break; 2528 } else { 2529 pid = toP(F.at(pos1).Select(pid, ident())); 2530 } 2531 } while (S.token() == DOT); 2532 accept(SEMI); 2533 return toP(F.at(pos).Import(pid, importStatic)); 2534 } 2535 2536 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 2537 * | ";" 2538 */ 2539 JCTree typeDeclaration(JCModifiers mods) { 2540 int pos = S.pos(); 2541 if (mods == null && S.token() == SEMI) { 2542 S.nextToken(); 2543 return toP(F.at(pos).Skip()); 2544 } else { 2545 String dc = S.docComment(); 2546 return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc); 2547 } 2548 } 2549 2550 /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt 2551 * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) 2552 * @param mods Any modifiers starting the class or interface declaration 2553 * @param dc The documentation comment for the class, or null. 2554 */ 2555 JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) { 2556 if (S.token() == CLASS) { 2557 return classDeclaration(mods, dc); 2558 } else if (S.token() == INTERFACE) { 2559 return interfaceDeclaration(mods, dc); 2560 } else if (allowEnums) { 2561 if (S.token() == ENUM) { 2562 return enumDeclaration(mods, dc); 2563 } else { 2564 int pos = S.pos(); 2565 List<JCTree> errs; 2566 if (S.token() == IDENTIFIER) { 2567 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2568 setErrorEndPos(S.pos()); 2569 } else { 2570 errs = List.<JCTree>of(mods); 2571 } 2572 return toP(F.Exec(syntaxError(pos, errs, "expected3", 2573 CLASS, INTERFACE, ENUM))); 2574 } 2575 } else { 2576 if (S.token() == ENUM) { 2577 log.error(S.pos(), "enums.not.supported.in.source", source.name); 2578 allowEnums = true; 2579 return enumDeclaration(mods, dc); 2580 } 2581 int pos = S.pos(); 2582 List<JCTree> errs; 2583 if (S.token() == IDENTIFIER) { 2584 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2585 setErrorEndPos(S.pos()); 2586 } else { 2587 errs = List.<JCTree>of(mods); 2588 } 2589 return toP(F.Exec(syntaxError(pos, errs, "expected2", 2590 CLASS, INTERFACE))); 2591 } 2592 } 2593 2594 /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type] 2595 * [IMPLEMENTS TypeList] ClassBody 2596 * @param mods The modifiers starting the class declaration 2597 * @param dc The documentation comment for the class, or null. 2598 */ 2599 JCClassDecl classDeclaration(JCModifiers mods, String dc) { 2600 int pos = S.pos(); 2601 accept(CLASS); 2602 Name name = ident(); 2603 2604 List<JCTypeParameter> typarams = typeParametersOpt(); 2605 2606 JCTree extending = null; 2607 if (S.token() == EXTENDS) { 2608 S.nextToken(); 2609 extending = parseType(); 2610 } 2611 List<JCExpression> implementing = List.nil(); 2612 if (S.token() == IMPLEMENTS) { 2613 S.nextToken(); 2614 implementing = typeList(); 2615 } 2616 List<JCTree> defs = classOrInterfaceBody(name, false); 2617 JCClassDecl result = toP(F.at(pos).ClassDef( 2618 mods, name, typarams, extending, implementing, defs)); 2619 attach(result, dc); 2620 return result; 2621 } 2622 2623 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt 2624 * [EXTENDS TypeList] InterfaceBody 2625 * @param mods The modifiers starting the interface declaration 2626 * @param dc The documentation comment for the interface, or null. 2627 */ 2628 JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 2629 int pos = S.pos(); 2630 accept(INTERFACE); 2631 Name name = ident(); 2632 2633 List<JCTypeParameter> typarams = typeParametersOpt(); 2634 2635 List<JCExpression> extending = List.nil(); 2636 if (S.token() == EXTENDS) { 2637 S.nextToken(); 2638 extending = typeList(); 2639 } 2640 List<JCTree> defs = classOrInterfaceBody(name, true); 2641 JCClassDecl result = toP(F.at(pos).ClassDef( 2642 mods, name, typarams, null, extending, defs)); 2643 attach(result, dc); 2644 return result; 2645 } 2646 2647 /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody 2648 * @param mods The modifiers starting the enum declaration 2649 * @param dc The documentation comment for the enum, or null. 2650 */ 2651 JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 2652 int pos = S.pos(); 2653 accept(ENUM); 2654 Name name = ident(); 2655 2656 List<JCExpression> implementing = List.nil(); 2657 if (S.token() == IMPLEMENTS) { 2658 S.nextToken(); 2659 implementing = typeList(); 2660 } 2661 2662 List<JCTree> defs = enumBody(name); 2663 JCModifiers newMods = 2664 F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations); 2665 JCClassDecl result = toP(F.at(pos). 2666 ClassDef(newMods, name, List.<JCTypeParameter>nil(), 2667 null, implementing, defs)); 2668 attach(result, dc); 2669 return result; 2670 } 2671 2672 /** EnumBody = "{" { EnumeratorDeclarationList } [","] 2673 * [ ";" {ClassBodyDeclaration} ] "}" 2674 */ 2675 List<JCTree> enumBody(Name enumName) { 2676 accept(LBRACE); 2677 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2678 if (S.token() == COMMA) { 2679 S.nextToken(); 2680 } else if (S.token() != RBRACE && S.token() != SEMI) { 2681 defs.append(enumeratorDeclaration(enumName)); 2682 while (S.token() == COMMA) { 2683 S.nextToken(); 2684 if (S.token() == RBRACE || S.token() == SEMI) break; 2685 defs.append(enumeratorDeclaration(enumName)); 2686 } 2687 if (S.token() != SEMI && S.token() != RBRACE) { 2688 defs.append(syntaxError(S.pos(), "expected3", 2689 COMMA, RBRACE, SEMI)); 2690 S.nextToken(); 2691 } 2692 } 2693 if (S.token() == SEMI) { 2694 S.nextToken(); 2695 while (S.token() != RBRACE && S.token() != EOF) { 2696 defs.appendList(classOrInterfaceBodyDeclaration(enumName, 2697 false)); 2698 if (S.pos() <= errorEndPos) { 2699 // error recovery 2700 skip(false, true, true, false); 2701 } 2702 } 2703 } 2704 accept(RBRACE); 2705 return defs.toList(); 2706 } 2707 2708 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 2709 */ 2710 JCTree enumeratorDeclaration(Name enumName) { 2711 String dc = S.docComment(); 2712 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 2713 if (S.deprecatedFlag()) { 2714 flags |= Flags.DEPRECATED; 2715 S.resetDeprecatedFlag(); 2716 } 2717 int pos = S.pos(); 2718 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO); 2719 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 2720 List<JCExpression> typeArgs = typeArgumentsOpt(); 2721 int identPos = S.pos(); 2722 Name name = ident(); 2723 int createPos = S.pos(); 2724 List<JCExpression> args = (S.token() == LPAREN) 2725 ? arguments() : List.<JCExpression>nil(); 2726 JCClassDecl body = null; 2727 if (S.token() == LBRACE) { 2728 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC); 2729 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 2730 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 2731 } 2732 if (args.isEmpty() && body == null) 2733 createPos = Position.NOPOS; 2734 JCIdent ident = F.at(Position.NOPOS).Ident(enumName); 2735 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 2736 if (createPos != Position.NOPOS) 2737 storeEnd(create, S.prevEndPos()); 2738 ident = F.at(Position.NOPOS).Ident(enumName); 2739 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 2740 attach(result, dc); 2741 return result; 2742 } 2743 2744 /** TypeList = Type {"," Type} 2745 */ 2746 List<JCExpression> typeList() { 2747 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 2748 ts.append(parseType()); 2749 while (S.token() == COMMA) { 2750 S.nextToken(); 2751 ts.append(parseType()); 2752 } 2753 return ts.toList(); 2754 } 2755 2756 /** ClassBody = "{" {ClassBodyDeclaration} "}" 2757 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 2758 */ 2759 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 2760 accept(LBRACE); 2761 if (S.pos() <= errorEndPos) { 2762 // error recovery 2763 skip(false, true, false, false); 2764 if (S.token() == LBRACE) 2765 S.nextToken(); 2766 } 2767 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2768 while (S.token() != RBRACE && S.token() != EOF) { 2769 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 2770 if (S.pos() <= errorEndPos) { 2771 // error recovery 2772 skip(false, true, true, false); 2773 } 2774 } 2775 accept(RBRACE); 2776 return defs.toList(); 2777 } 2778 2779 /** ClassBodyDeclaration = 2780 * ";" 2781 * | [STATIC] Block 2782 * | ModifiersOpt 2783 * ( Type Ident 2784 * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) 2785 * | VOID Ident MethodDeclaratorRest 2786 * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest 2787 * | Ident ConstructorDeclaratorRest 2788 * | TypeParameters Ident ConstructorDeclaratorRest 2789 * | ClassOrInterfaceOrEnumDeclaration 2790 * ) 2791 * InterfaceBodyDeclaration = 2792 * ";" 2793 * | ModifiersOpt Type Ident 2794 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 2795 */ 2796 List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 2797 if (S.token() == SEMI) { 2798 S.nextToken(); 2799 return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil())); 2800 } else { 2801 String dc = S.docComment(); 2802 int pos = S.pos(); 2803 JCModifiers mods = modifiersOpt(); 2804 if (S.token() == CLASS || 2805 S.token() == INTERFACE || 2806 allowEnums && S.token() == ENUM) { 2807 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc)); 2808 } else if (S.token() == LBRACE && !isInterface && 2809 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 2810 mods.annotations.isEmpty()) { 2811 return List.<JCTree>of(block(pos, mods.flags)); 2812 } else { 2813 pos = S.pos(); 2814 List<JCTypeParameter> typarams = typeParametersOpt(); 2815 // Hack alert: if there are type arguments but no Modifiers, the start 2816 // position will be lost unless we set the Modifiers position. There 2817 // should be an AST node for type parameters (BugId 5005090). 2818 if (typarams.length() > 0 && mods.pos == Position.NOPOS) { 2819 mods.pos = pos; 2820 } 2821 2822 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO); 2823 2824 Token token = S.token(); 2825 Name name = S.name(); 2826 pos = S.pos(); 2827 JCExpression type; 2828 boolean isVoid = S.token() == VOID; 2829 if (isVoid) { 2830 if (annosAfterParams.nonEmpty()) 2831 illegal(annosAfterParams.head.pos); 2832 type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 2833 S.nextToken(); 2834 } else { 2835 mods.annotations = mods.annotations.appendList(annosAfterParams); 2836 // method returns types are un-annotated types 2837 type = unannotatedType(); 2838 } 2839 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 2840 if (isInterface || name != className) 2841 log.error(pos, "invalid.meth.decl.ret.type.req"); 2842 return List.of(methodDeclaratorRest( 2843 pos, mods, null, names.init, typarams, 2844 isInterface, true, dc)); 2845 } else { 2846 pos = S.pos(); 2847 name = ident(); 2848 if (S.token() == LPAREN) { 2849 return List.of(methodDeclaratorRest( 2850 pos, mods, type, name, typarams, 2851 isInterface, isVoid, dc)); 2852 } else if (!isVoid && typarams.isEmpty()) { 2853 List<JCTree> defs = 2854 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 2855 new ListBuffer<JCTree>()).toList(); 2856 storeEnd(defs.last(), S.endPos()); 2857 accept(SEMI); 2858 return defs; 2859 } else { 2860 pos = S.pos(); 2861 List<JCTree> err = isVoid 2862 ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 2863 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null))) 2864 : null; 2865 return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN)); 2866 } 2867 } 2868 } 2869 } 2870 } 2871 2872 /** MethodDeclaratorRest = 2873 * FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 2874 * VoidMethodDeclaratorRest = 2875 * FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";") 2876 * InterfaceMethodDeclaratorRest = 2877 * FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";" 2878 * VoidInterfaceMethodDeclaratorRest = 2879 * FormalParameters [Annotations] [THROWS TypeList] ";" 2880 * ConstructorDeclaratorRest = 2881 * "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody 2882 */ 2883 JCTree methodDeclaratorRest(int pos, 2884 JCModifiers mods, 2885 JCExpression type, 2886 Name name, 2887 List<JCTypeParameter> typarams, 2888 boolean isInterface, boolean isVoid, 2889 String dc) { 2890 List<JCVariableDecl> params = formalParameters(); 2891 2892 List<JCTypeAnnotation> receiverAnnotations; 2893 if (!isVoid) { 2894 // need to distinguish between receiver anno and array anno 2895 // look at typeAnnotationsPushedBack comment 2896 this.permitTypeAnnotationsPushBack = true; 2897 type = methodReturnArrayRest(type); 2898 this.permitTypeAnnotationsPushBack = false; 2899 if (typeAnnotationsPushedBack == null) 2900 receiverAnnotations = List.nil(); 2901 else 2902 receiverAnnotations = typeAnnotationsPushedBack; 2903 typeAnnotationsPushedBack = null; 2904 } else 2905 receiverAnnotations = typeAnnotationsOpt(); 2906 2907 List<JCExpression> thrown = List.nil(); 2908 if (S.token() == THROWS) { 2909 S.nextToken(); 2910 thrown = qualidentList(); 2911 } 2912 JCBlock body = null; 2913 JCExpression defaultValue; 2914 if (S.token() == LBRACE) { 2915 body = block(); 2916 defaultValue = null; 2917 } else { 2918 if (S.token() == DEFAULT) { 2919 accept(DEFAULT); 2920 defaultValue = annotationValue(); 2921 } else { 2922 defaultValue = null; 2923 } 2924 accept(SEMI); 2925 if (S.pos() <= errorEndPos) { 2926 // error recovery 2927 skip(false, true, false, false); 2928 if (S.token() == LBRACE) { 2929 body = block(); 2930 } 2931 } 2932 } 2933 JCMethodDecl result = 2934 toP(F.at(pos).MethodDef(mods, name, type, typarams, 2935 params, receiverAnnotations, thrown, 2936 body, defaultValue)); 2937 attach(result, dc); 2938 return result; 2939 } 2940 2941 /** Parses the array levels after the format parameters list, and append 2942 * them to the return type, while preseving the order of type annotations 2943 */ 2944 private JCExpression methodReturnArrayRest(JCExpression type) { 2945 if (type.getTag() != JCTree.TYPEARRAY) 2946 return bracketsOpt(type); 2947 2948 JCArrayTypeTree baseArray = (JCArrayTypeTree)type; 2949 while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree) 2950 baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype); 2951 2952 if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) { 2953 JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype; 2954 at.underlyingType = bracketsOpt(at.underlyingType); 2955 } else { 2956 baseArray.elemtype = bracketsOpt(baseArray.elemtype); 2957 } 2958 2959 return type; 2960 } 2961 2962 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident} 2963 */ 2964 List<JCExpression> qualidentList() { 2965 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 2966 2967 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt(); 2968 if (!typeAnnos.isEmpty()) 2969 ts.append(F.AnnotatedType(typeAnnos, qualident())); 2970 else 2971 ts.append(qualident()); 2972 while (S.token() == COMMA) { 2973 S.nextToken(); 2974 2975 typeAnnos = typeAnnotationsOpt(); 2976 if (!typeAnnos.isEmpty()) 2977 ts.append(F.AnnotatedType(typeAnnos, qualident())); 2978 else 2979 ts.append(qualident()); 2980 } 2981 return ts.toList(); 2982 } 2983 2984 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 2985 */ 2986 List<JCTypeParameter> typeParametersOpt() { 2987 if (S.token() == LT) { 2988 checkGenerics(); 2989 ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>(); 2990 S.nextToken(); 2991 typarams.append(typeParameter()); 2992 while (S.token() == COMMA) { 2993 S.nextToken(); 2994 typarams.append(typeParameter()); 2995 } 2996 accept(GT); 2997 return typarams.toList(); 2998 } else { 2999 return List.nil(); 3000 } 3001 } 3002 3003 /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound] 3004 * TypeParameterBound = EXTENDS Type {"&" Type} 3005 * TypeVariable = Ident 3006 */ 3007 JCTypeParameter typeParameter() { 3008 int pos = S.pos(); 3009 List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 3010 Name name = ident(); 3011 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 3012 if (S.token() == EXTENDS) { 3013 S.nextToken(); 3014 bounds.append(parseType()); 3015 while (S.token() == AMP) { 3016 S.nextToken(); 3017 bounds.append(parseType()); 3018 } 3019 } 3020 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos)); 3021 } 3022 3023 /** FormalParameters = "(" [ FormalParameterList ] ")" 3024 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 3025 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 3026 */ 3027 List<JCVariableDecl> formalParameters() { 3028 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 3029 JCVariableDecl lastParam = null; 3030 accept(LPAREN); 3031 if (S.token() != RPAREN) { 3032 params.append(lastParam = formalParameter()); 3033 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) { 3034 S.nextToken(); 3035 params.append(lastParam = formalParameter()); 3036 } 3037 } 3038 accept(RPAREN); 3039 return params.toList(); 3040 } 3041 3042 JCModifiers optFinal(long flags) { 3043 JCModifiers mods = modifiersOpt(); 3044 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 3045 mods.flags |= flags; 3046 return mods; 3047 } 3048 3049 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 3050 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 3051 */ 3052 JCVariableDecl formalParameter() { 3053 JCModifiers mods = optFinal(Flags.PARAMETER); 3054 // need to distinguish between vararg annos and array annos 3055 // look at typeAnnotaitonsPushedBack comment 3056 this.permitTypeAnnotationsPushBack = true; 3057 JCExpression type = parseType(); 3058 this.permitTypeAnnotationsPushBack = false; 3059 3060 if (S.token() == ELLIPSIS) { 3061 List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack; 3062 typeAnnotationsPushedBack = null; 3063 checkVarargs(); 3064 mods.flags |= Flags.VARARGS; 3065 // insert var arg type annotations 3066 if (varargsAnnos != null && varargsAnnos.nonEmpty()) 3067 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type); 3068 type = to(F.at(S.pos()).TypeArray(type)); 3069 3070 S.nextToken(); 3071 } else { 3072 // if not a var arg, then typeAnnotationsPushedBack should be null 3073 if (typeAnnotationsPushedBack != null 3074 && !typeAnnotationsPushedBack.isEmpty()) { 3075 reportSyntaxError(typeAnnotationsPushedBack.head.pos, 3076 "illegal.start.of.type"); 3077 } 3078 typeAnnotationsPushedBack = null; 3079 } 3080 return variableDeclaratorId(mods, type); 3081 } 3082 3083 /* ---------- auxiliary methods -------------- */ 3084 3085 /** Check that given tree is a legal expression statement. 3086 */ 3087 protected JCExpression checkExprStat(JCExpression t) { 3088 switch(t.getTag()) { 3089 case JCTree.PREINC: case JCTree.PREDEC: 3090 case JCTree.POSTINC: case JCTree.POSTDEC: 3091 case JCTree.ASSIGN: 3092 case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG: 3093 case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG: 3094 case JCTree.PLUS_ASG: case JCTree.MINUS_ASG: 3095 case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG: 3096 case JCTree.APPLY: case JCTree.NEWCLASS: 3097 case JCTree.ERRONEOUS: 3098 return t; 3099 default: 3100 log.error(t.pos, "not.stmt"); 3101 return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 3102 } 3103 } 3104 3105 /** Return precedence of operator represented by token, 3106 * -1 if token is not a binary operator. @see TreeInfo.opPrec 3107 */ 3108 static int prec(Token token) { 3109 int oc = optag(token); 3110 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 3111 } 3112 3113 /** Return operation tag of binary operator represented by token, 3114 * -1 if token is not a binary operator. 3115 */ 3116 static int optag(Token token) { 3117 switch (token) { 3118 case BARBAR: 3119 return JCTree.OR; 3120 case AMPAMP: 3121 return JCTree.AND; 3122 case BAR: 3123 return JCTree.BITOR; 3124 case BAREQ: 3125 return JCTree.BITOR_ASG; 3126 case CARET: 3127 return JCTree.BITXOR; 3128 case CARETEQ: 3129 return JCTree.BITXOR_ASG; 3130 case AMP: 3131 return JCTree.BITAND; 3132 case AMPEQ: 3133 return JCTree.BITAND_ASG; 3134 case EQEQ: 3135 return JCTree.EQ; 3136 case BANGEQ: 3137 return JCTree.NE; 3138 case LT: 3139 return JCTree.LT; 3140 case GT: 3141 return JCTree.GT; 3142 case LTEQ: 3143 return JCTree.LE; 3144 case GTEQ: 3145 return JCTree.GE; 3146 case LTLT: 3147 return JCTree.SL; 3148 case LTLTEQ: 3149 return JCTree.SL_ASG; 3150 case GTGT: 3151 return JCTree.SR; 3152 case GTGTEQ: 3153 return JCTree.SR_ASG; 3154 case GTGTGT: 3155 return JCTree.USR; 3156 case GTGTGTEQ: 3157 return JCTree.USR_ASG; 3158 case PLUS: 3159 return JCTree.PLUS; 3160 case PLUSEQ: 3161 return JCTree.PLUS_ASG; 3162 case SUB: 3163 return JCTree.MINUS; 3164 case SUBEQ: 3165 return JCTree.MINUS_ASG; 3166 case STAR: 3167 return JCTree.MUL; 3168 case STAREQ: 3169 return JCTree.MUL_ASG; 3170 case SLASH: 3171 return JCTree.DIV; 3172 case SLASHEQ: 3173 return JCTree.DIV_ASG; 3174 case PERCENT: 3175 return JCTree.MOD; 3176 case PERCENTEQ: 3177 return JCTree.MOD_ASG; 3178 case INSTANCEOF: 3179 return JCTree.TYPETEST; 3180 default: 3181 return -1; 3182 } 3183 } 3184 3185 /** Return operation tag of unary operator represented by token, 3186 * -1 if token is not a binary operator. 3187 */ 3188 static int unoptag(Token token) { 3189 switch (token) { 3190 case PLUS: 3191 return JCTree.POS; 3192 case SUB: 3193 return JCTree.NEG; 3194 case BANG: 3195 return JCTree.NOT; 3196 case TILDE: 3197 return JCTree.COMPL; 3198 case PLUSPLUS: 3199 return JCTree.PREINC; 3200 case SUBSUB: 3201 return JCTree.PREDEC; 3202 default: 3203 return -1; 3204 } 3205 } 3206 3207 /** Return type tag of basic type represented by token, 3208 * -1 if token is not a basic type identifier. 3209 */ 3210 static int typetag(Token token) { 3211 switch (token) { 3212 case BYTE: 3213 return TypeTags.BYTE; 3214 case CHAR: 3215 return TypeTags.CHAR; 3216 case SHORT: 3217 return TypeTags.SHORT; 3218 case INT: 3219 return TypeTags.INT; 3220 case LONG: 3221 return TypeTags.LONG; 3222 case FLOAT: 3223 return TypeTags.FLOAT; 3224 case DOUBLE: 3225 return TypeTags.DOUBLE; 3226 case BOOLEAN: 3227 return TypeTags.BOOLEAN; 3228 default: 3229 return -1; 3230 } 3231 } 3232 3233 void checkDiamond() { 3234 if (!allowDiamond) { 3235 log.error(S.pos(), "diamond.not.supported.in.source", source.name); 3236 allowDiamond = true; 3237 } 3238 } 3239 void checkGenerics() { 3240 if (!allowGenerics) { 3241 log.error(S.pos(), "generics.not.supported.in.source", source.name); 3242 allowGenerics = true; 3243 } 3244 } 3245 void checkVarargs() { 3246 if (!allowVarargs) { 3247 log.error(S.pos(), "varargs.not.supported.in.source", source.name); 3248 allowVarargs = true; 3249 } 3250 } 3251 void checkForeach() { 3252 if (!allowForeach) { 3253 log.error(S.pos(), "foreach.not.supported.in.source", source.name); 3254 allowForeach = true; 3255 } 3256 } 3257 void checkStaticImports() { 3258 if (!allowStaticImport) { 3259 log.error(S.pos(), "static.import.not.supported.in.source", source.name); 3260 allowStaticImport = true; 3261 } 3262 } 3263 void checkAnnotations() { 3264 if (!allowAnnotations) { 3265 log.error(S.pos(), "annotations.not.supported.in.source", source.name); 3266 allowAnnotations = true; 3267 } 3268 } 3269 void checkTypeAnnotations() { 3270 if (!allowTypeAnnotations) { 3271 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name); 3272 allowTypeAnnotations = true; 3273 } 3274 } 3275 void checkFunctionType() { 3276 if (!allowFunctionType) { 3277 log.error(S.pos(), "function.type.not.supported.in.source", source.name); 3278 allowFunctionType = true; 3279 } 3280 } 3281 void checkLambda() { 3282 if (!allowLambda) { 3283 log.error(S.pos(), "lambda.not.supported.in.source", source.name); 3284 allowLambda = true; 3285 } 3286 } 3287 }