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