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 assert this.permitTypeAnnotationsPushBack; 1155 typeAnnotationsPushedBack = annos; 1156 break loop; 1157 default: 1158 break loop; 1159 } 1160 } 1161 if (typeArgs != null) illegal(); 1162 t = typeArgumentsOpt(t); 1163 break; 1164 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1165 case DOUBLE: case BOOLEAN: 1166 if (typeArgs != null) illegal(); 1167 t = bracketsSuffix(bracketsOpt(basicType())); 1168 break; 1169 case VOID: 1170 if (typeArgs != null) illegal(); 1171 if ((mode & EXPR) != 0) { 1172 S.nextToken(); 1173 if (S.token() == DOT) { 1174 JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); 1175 t = bracketsSuffix(ti); 1176 } else { 1177 return illegal(pos); 1178 } 1179 } else { 1180 // Support the corner case of myMethodHandle.<void>invoke() by passing 1181 // a void type (like other primitive types) to the next phase. 1182 // The error will be reported in Attr.attribTypes or Attr.visitApply. 1183 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID)); 1184 S.nextToken(); 1185 return ti; 1186 //return illegal(); 1187 } 1188 break; 1189 default: 1190 return illegal(); 1191 } 1192 if (typeArgs != null) illegal(); 1193 while (true) { 1194 int pos1 = S.pos(); 1195 1196 final List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 1197 1198 if (S.token() == LBRACKET) { 1199 S.nextToken(); 1200 1201 if ((mode & TYPE) != 0) { 1202 int oldmode = mode; 1203 mode = TYPE; 1204 if (S.token() == RBRACKET) { 1205 S.nextToken(); 1206 t = bracketsOpt(t, annos); 1207 t = toP(F.at(pos1).TypeArray(t)); 1208 return t; 1209 } 1210 mode = oldmode; 1211 } 1212 if ((mode & EXPR) != 0) { 1213 mode = EXPR; 1214 JCExpression t1 = term(); 1215 t = to(F.at(pos1).Indexed(t, t1)); 1216 } 1217 accept(RBRACKET); 1218 } else if (S.token() == DOT) { 1219 S.nextToken(); 1220 typeArgs = typeArgumentsOpt(EXPR); 1221 if (S.token() == SUPER && (mode & EXPR) != 0) { 1222 mode = EXPR; 1223 t = to(F.at(pos1).Select(t, names._super)); 1224 S.nextToken(); 1225 t = arguments(typeArgs, t); 1226 typeArgs = null; 1227 } else if (S.token() == NEW && (mode & EXPR) != 0) { 1228 if (typeArgs != null) return illegal(); 1229 mode = EXPR; 1230 int pos2 = S.pos(); 1231 S.nextToken(); 1232 if (S.token() == LT) typeArgs = typeArguments(); 1233 t = innerCreator(pos2, typeArgs, t); 1234 typeArgs = null; 1235 } else { 1236 t = toP(F.at(pos1).Select(t, ident())); 1237 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 1238 typeArgs = null; 1239 } 1240 } else { 1241 if (!annos.isEmpty()) { 1242 if (permitTypeAnnotationsPushBack) 1243 typeAnnotationsPushedBack = annos; 1244 else 1245 return illegal(annos.head.pos); 1246 } 1247 break; 1248 } 1249 } 1250 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 1251 mode = EXPR; 1252 t = to(F.at(S.pos()).Unary( 1253 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 1254 S.nextToken(); 1255 } 1256 1257 return toP(t); 1258 } 1259 1260 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 1261 */ 1262 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 1263 S.nextToken(); 1264 if (S.token() == LPAREN || typeArgs != null) { 1265 t = arguments(typeArgs, t); 1266 } else { 1267 int pos = S.pos(); 1268 accept(DOT); 1269 typeArgs = (S.token() == LT) ? typeArguments() : null; 1270 t = toP(F.at(pos).Select(t, ident())); 1271 t = argumentsOpt(typeArgs, t); 1272 } 1273 return t; 1274 } 1275 1276 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 1277 */ 1278 JCPrimitiveTypeTree basicType() { 1279 JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token()))); 1280 S.nextToken(); 1281 return t; 1282 } 1283 1284 /** ArgumentsOpt = [ Arguments ] 1285 */ 1286 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 1287 if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) { 1288 mode = EXPR; 1289 return arguments(typeArgs, t); 1290 } else { 1291 return t; 1292 } 1293 } 1294 1295 /** Arguments = "(" [Expression { COMMA Expression }] ")" 1296 */ 1297 List<JCExpression> arguments() { 1298 ListBuffer<JCExpression> args = lb(); 1299 if (S.token() == LPAREN) { 1300 S.nextToken(); 1301 if (S.token() != RPAREN) { 1302 args.append(parseExpression()); 1303 while (S.token() == COMMA) { 1304 S.nextToken(); 1305 args.append(parseExpression()); 1306 } 1307 } 1308 accept(RPAREN); 1309 } else { 1310 syntaxError(S.pos(), "expected", LPAREN); 1311 } 1312 return args.toList(); 1313 } 1314 1315 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 1316 int pos = S.pos(); 1317 List<JCExpression> args = arguments(); 1318 return toP(F.at(pos).Apply(typeArgs, t, args)); 1319 } 1320 1321 /** TypeArgumentsOpt = [ TypeArguments ] 1322 */ 1323 JCExpression typeArgumentsOpt(JCExpression t) { 1324 if (S.token() == LT && 1325 (mode & TYPE) != 0 && 1326 (mode & NOPARAMS) == 0) { 1327 mode = TYPE; 1328 checkGenerics(); 1329 return typeArguments(t); 1330 } else { 1331 return t; 1332 } 1333 } 1334 List<JCExpression> typeArgumentsOpt() { 1335 return typeArgumentsOpt(TYPE); 1336 } 1337 1338 List<JCExpression> typeArgumentsOpt(int useMode) { 1339 if (S.token() == LT) { 1340 checkGenerics(); 1341 if ((mode & useMode) == 0 || 1342 (mode & NOPARAMS) != 0) { 1343 illegal(); 1344 } 1345 mode = useMode; 1346 return typeArguments(); 1347 } 1348 return null; 1349 } 1350 1351 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 1352 */ 1353 List<JCExpression> typeArguments() { 1354 ListBuffer<JCExpression> args = lb(); 1355 if (S.token() == LT) { 1356 S.nextToken(); 1357 if (S.token() == GT && (mode & DIAMOND) != 0) { 1358 checkDiamond(); 1359 S.nextToken(); 1360 return List.nil(); 1361 } 1362 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1363 while (S.token() == COMMA) { 1364 S.nextToken(); 1365 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 1366 } 1367 switch (S.token()) { 1368 case GTGTGTEQ: 1369 S.token(GTGTEQ); 1370 break; 1371 case GTGTEQ: 1372 S.token(GTEQ); 1373 break; 1374 case GTEQ: 1375 S.token(EQ); 1376 break; 1377 case GTGTGT: 1378 S.token(GTGT); 1379 break; 1380 case GTGT: 1381 S.token(GT); 1382 break; 1383 default: 1384 accept(GT); 1385 break; 1386 } 1387 } else { 1388 syntaxError(S.pos(), "expected", LT); 1389 } 1390 return args.toList(); 1391 } 1392 1393 /** TypeArgument = Type 1394 * | [Annotations] "?" 1395 * | [Annotations] "?" EXTENDS Type {"&" Type} 1396 * | [Annotations] "?" SUPER Type 1397 */ 1398 JCExpression typeArgument() { 1399 List<JCTypeAnnotation> annotations = typeAnnotationsOpt(); 1400 if (S.token() != QUES) return parseType(annotations); 1401 int pos = S.pos(); 1402 S.nextToken(); 1403 JCExpression result; 1404 if (S.token() == EXTENDS) { 1405 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS)); 1406 S.nextToken(); 1407 JCExpression bound = parseType(); 1408 result = F.at(pos).Wildcard(t, bound); 1409 } else if (S.token() == SUPER) { 1410 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); 1411 S.nextToken(); 1412 JCExpression bound = parseType(); 1413 result = F.at(pos).Wildcard(t, bound); 1414 } else if (S.token() == IDENTIFIER) { 1415 //error recovery 1416 reportSyntaxError(S.prevEndPos(), "expected3", 1417 GT, EXTENDS, SUPER); 1418 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1419 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1420 JCIdent id = toP(F.at(S.pos()).Ident(ident())); 1421 result = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1422 } else { 1423 TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND)); 1424 result = toP(F.at(pos).Wildcard(t, null)); 1425 } 1426 if (!annotations.isEmpty()) 1427 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result)); 1428 return result; 1429 } 1430 1431 JCTypeApply typeArguments(JCExpression t) { 1432 int pos = S.pos(); 1433 List<JCExpression> args = typeArguments(); 1434 return toP(F.at(pos).TypeApply(t, args)); 1435 } 1436 1437 /** 1438 * BracketsOpt = { [Annotations] "[" "]" } 1439 * 1440 * <p> 1441 * 1442 * <code>annotations</code> is the list of annotations targeting 1443 * the expression <code>t</code>. 1444 */ 1445 private JCExpression bracketsOpt(JCExpression t, 1446 List<JCTypeAnnotation> annotations) { 1447 List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt(); 1448 1449 if (S.token() == LBRACKET) { 1450 int pos = S.pos(); 1451 S.nextToken(); 1452 1453 JCExpression orig = t; 1454 t = bracketsOptCont(t, pos, nextLevelAnnotations); 1455 } else if (!nextLevelAnnotations.isEmpty()) { 1456 if (permitTypeAnnotationsPushBack) { 1457 this.typeAnnotationsPushedBack = nextLevelAnnotations; 1458 } else 1459 return illegal(nextLevelAnnotations.head.pos); 1460 } 1461 1462 int apos = S.pos(); 1463 if (!annotations.isEmpty()) 1464 t = F.at(apos).AnnotatedType(annotations, t); 1465 return t; 1466 } 1467 1468 /** BracketsOpt = {"[" TypeAnnotations "]"} 1469 */ 1470 private JCExpression bracketsOpt(JCExpression t) { 1471 return bracketsOpt(t, List.<JCTypeAnnotation>nil()); 1472 } 1473 1474 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos, 1475 List<JCTypeAnnotation> annotations) { 1476 accept(RBRACKET); 1477 t = bracketsOpt(t, annotations); 1478 return toP(F.at(pos).TypeArray(t)); 1479 } 1480 1481 /** BracketsSuffixExpr = "." CLASS 1482 * BracketsSuffixType = 1483 */ 1484 JCExpression bracketsSuffix(JCExpression t) { 1485 if ((mode & EXPR) != 0 && S.token() == DOT) { 1486 mode = EXPR; 1487 int pos = S.pos(); 1488 S.nextToken(); 1489 accept(CLASS); 1490 if (S.pos() == errorEndPos) { 1491 // error recovery 1492 Name name = null; 1493 if (S.token() == IDENTIFIER) { 1494 name = S.name(); 1495 S.nextToken(); 1496 } else { 1497 name = names.error; 1498 } 1499 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name)))); 1500 } else { 1501 t = toP(F.at(pos).Select(t, names._class)); 1502 } 1503 } else if ((mode & TYPE) != 0) { 1504 mode = TYPE; 1505 } else { 1506 syntaxError(S.pos(), "dot.class.expected"); 1507 } 1508 return t; 1509 } 1510 1511 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 1512 */ 1513 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 1514 1515 List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt(); 1516 1517 switch (S.token()) { 1518 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1519 case DOUBLE: case BOOLEAN: 1520 if (typeArgs == null) { 1521 if (newAnnotations.isEmpty()) 1522 return arrayCreatorRest(newpos, basicType()); 1523 else 1524 return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType())); 1525 } 1526 break; 1527 default: 1528 } 1529 JCExpression t = qualident(); 1530 // handle type annotations for non primitive arrays 1531 if (!newAnnotations.isEmpty()) 1532 t = F.AnnotatedType(newAnnotations, t); 1533 1534 int oldmode = mode; 1535 mode = TYPE | DIAMOND; 1536 if (S.token() == LT) { 1537 checkGenerics(); 1538 t = typeArguments(t); 1539 } 1540 while (S.token() == DOT) { 1541 int pos = S.pos(); 1542 S.nextToken(); 1543 t = toP(F.at(pos).Select(t, ident())); 1544 if (S.token() == LT) { 1545 checkGenerics(); 1546 t = typeArguments(t); 1547 } 1548 } 1549 mode = oldmode; 1550 if (S.token() == LBRACKET || S.token() == MONKEYS_AT) { 1551 JCExpression e = arrayCreatorRest(newpos, t); 1552 if (typeArgs != null) { 1553 int pos = newpos; 1554 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 1555 // note: this should always happen but we should 1556 // not rely on this as the parser is continuously 1557 // modified to improve error recovery. 1558 pos = typeArgs.head.pos; 1559 } 1560 setErrorEndPos(S.prevEndPos()); 1561 reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 1562 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 1563 } 1564 return e; 1565 } else if (S.token() == LPAREN) { 1566 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t); 1567 if (newClass.def != null) { 1568 assert newClass.def.mods.annotations.isEmpty(); 1569 if (newAnnotations.nonEmpty()) { 1570 newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos); 1571 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations); 1572 } 1573 } 1574 return newClass; 1575 } else { 1576 reportSyntaxError(S.pos(), "expected2", 1577 LPAREN, LBRACKET); 1578 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 1579 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 1580 } 1581 } 1582 1583 /** InnerCreator = Ident [TypeArguments] ClassCreatorRest 1584 */ 1585 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 1586 JCExpression t = toP(F.at(S.pos()).Ident(ident())); 1587 if (S.token() == LT) { 1588 int oldmode = mode; 1589 mode |= DIAMOND; 1590 checkGenerics(); 1591 t = typeArguments(t); 1592 mode = oldmode; 1593 } 1594 return classCreatorRest(newpos, encl, typeArgs, t); 1595 } 1596 1597 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer 1598 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt ) 1599 */ 1600 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 1601 1602 List<JCTypeAnnotation> topAnnos = List.nil(); 1603 if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) { 1604 JCAnnotatedType atype = (JCAnnotatedType) elemtype; 1605 topAnnos = atype.annotations; 1606 elemtype = atype.underlyingType; 1607 } 1608 1609 List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 1610 1611 accept(LBRACKET); 1612 1613 if (S.token() == RBRACKET) { 1614 accept(RBRACKET); 1615 1616 elemtype = bracketsOpt(elemtype, annos); 1617 1618 if (S.token() == LBRACE) { 1619 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype); 1620 1621 na.annotations = topAnnos; 1622 1623 return na; 1624 } else { 1625 return syntaxError(S.pos(), "array.dimension.missing"); 1626 } 1627 } else { 1628 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 1629 1630 // maintain array dimension type annotations 1631 ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb(); 1632 dimAnnotations.append(annos); 1633 1634 dims.append(parseExpression()); 1635 accept(RBRACKET); 1636 while (S.token() == LBRACKET 1637 || (S.token() == MONKEYS_AT)) { 1638 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt(); 1639 int pos = S.pos(); 1640 S.nextToken(); 1641 if (S.token() == RBRACKET) { 1642 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 1643 } else { 1644 if (S.token() == RBRACKET) { // no dimension 1645 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos); 1646 } else { 1647 dimAnnotations.append(maybeDimAnnos); 1648 dims.append(parseExpression()); 1649 accept(RBRACKET); 1650 } 1651 } 1652 } 1653 1654 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); 1655 na.annotations = topAnnos; 1656 na.dimAnnotations = dimAnnotations.toList(); 1657 return na; 1658 } 1659 } 1660 1661 /** ClassCreatorRest = Arguments [ClassBody] 1662 */ 1663 JCNewClass classCreatorRest(int newpos, 1664 JCExpression encl, 1665 List<JCExpression> typeArgs, 1666 JCExpression t) 1667 { 1668 List<JCExpression> args = arguments(); 1669 JCClassDecl body = null; 1670 if (S.token() == LBRACE) { 1671 int pos = S.pos(); 1672 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 1673 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 1674 body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 1675 } 1676 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body)); 1677 } 1678 1679 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}" 1680 */ 1681 JCExpression arrayInitializer(int newpos, JCExpression t) { 1682 accept(LBRACE); 1683 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 1684 if (S.token() == COMMA) { 1685 S.nextToken(); 1686 } else if (S.token() != RBRACE) { 1687 elems.append(variableInitializer()); 1688 while (S.token() == COMMA) { 1689 S.nextToken(); 1690 if (S.token() == RBRACE) break; 1691 elems.append(variableInitializer()); 1692 } 1693 } 1694 accept(RBRACE); 1695 return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList())); 1696 } 1697 1698 /** VariableInitializer = ArrayInitializer | Expression 1699 */ 1700 public JCExpression variableInitializer() { 1701 return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression(); 1702 } 1703 1704 /** ParExpression = "(" Expression ")" 1705 */ 1706 JCExpression parExpression() { 1707 accept(LPAREN); 1708 JCExpression t = parseExpression(); 1709 accept(RPAREN); 1710 return t; 1711 } 1712 1713 /** Block = "{" BlockStatements "}" 1714 */ 1715 JCBlock block(int pos, long flags) { 1716 accept(LBRACE); 1717 List<JCStatement> stats = blockStatements(); 1718 JCBlock t = F.at(pos).Block(flags, stats); 1719 while (S.token() == CASE || S.token() == DEFAULT) { 1720 syntaxError("orphaned", S.token()); 1721 switchBlockStatementGroups(); 1722 } 1723 // the Block node has a field "endpos" for first char of last token, which is 1724 // usually but not necessarily the last char of the last token. 1725 t.endpos = S.pos(); 1726 accept(RBRACE); 1727 return toP(t); 1728 } 1729 1730 public JCBlock block() { 1731 return block(S.pos(), 0); 1732 } 1733 1734 /** BlockStatements = { BlockStatement } 1735 * BlockStatement = LocalVariableDeclarationStatement 1736 * | ClassOrInterfaceOrEnumDeclaration 1737 * | [Ident ":"] Statement 1738 * LocalVariableDeclarationStatement 1739 * = { FINAL | '@' Annotation } Type VariableDeclarators ";" 1740 */ 1741 @SuppressWarnings("fallthrough") 1742 List<JCStatement> blockStatements() { 1743 //todo: skip to anchor on error(?) 1744 int lastErrPos = -1; 1745 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 1746 while (true) { 1747 int pos = S.pos(); 1748 switch (S.token()) { 1749 case RBRACE: case CASE: case DEFAULT: case EOF: 1750 return stats.toList(); 1751 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 1752 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK: 1753 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH: 1754 stats.append(parseStatement()); 1755 break; 1756 case MONKEYS_AT: 1757 case FINAL: { 1758 String dc = S.docComment(); 1759 JCModifiers mods = modifiersOpt(); 1760 if (S.token() == INTERFACE || 1761 S.token() == CLASS || 1762 allowEnums && S.token() == ENUM) { 1763 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 1764 } else { 1765 JCExpression t = parseType(); 1766 stats.appendList(variableDeclarators(mods, t, 1767 new ListBuffer<JCStatement>())); 1768 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 1769 storeEnd(stats.elems.last(), S.endPos()); 1770 accept(SEMI); 1771 } 1772 break; 1773 } 1774 case ABSTRACT: case STRICTFP: { 1775 String dc = S.docComment(); 1776 JCModifiers mods = modifiersOpt(); 1777 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 1778 break; 1779 } 1780 case INTERFACE: 1781 case CLASS: 1782 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 1783 S.docComment())); 1784 break; 1785 case ENUM: 1786 case ASSERT: 1787 if (allowEnums && S.token() == ENUM) { 1788 log.error(S.pos(), "local.enum"); 1789 stats. 1790 append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 1791 S.docComment())); 1792 break; 1793 } else if (allowAsserts && S.token() == ASSERT) { 1794 stats.append(parseStatement()); 1795 break; 1796 } 1797 /* fall through to default */ 1798 default: 1799 Name name = S.name(); 1800 JCExpression t = term(EXPR | TYPE); 1801 if (S.token() == COLON && t.getTag() == JCTree.IDENT) { 1802 S.nextToken(); 1803 JCStatement stat = parseStatement(); 1804 stats.append(F.at(pos).Labelled(name, stat)); 1805 } else if ((lastmode & TYPE) != 0 && 1806 (S.token() == IDENTIFIER || 1807 S.token() == ASSERT || 1808 S.token() == ENUM)) { 1809 pos = S.pos(); 1810 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 1811 F.at(pos); 1812 stats.appendList(variableDeclarators(mods, t, 1813 new ListBuffer<JCStatement>())); 1814 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 1815 storeEnd(stats.elems.last(), S.endPos()); 1816 accept(SEMI); 1817 } else { 1818 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 1819 stats.append(to(F.at(pos).Exec(checkExprStat(t)))); 1820 accept(SEMI); 1821 } 1822 } 1823 1824 // error recovery 1825 if (S.pos() == lastErrPos) 1826 return stats.toList(); 1827 if (S.pos() <= errorEndPos) { 1828 skip(false, true, true, true); 1829 lastErrPos = S.pos(); 1830 } 1831 1832 // ensure no dangling /** @deprecated */ active 1833 S.resetDeprecatedFlag(); 1834 } 1835 } 1836 1837 /** Statement = 1838 * Block 1839 * | IF ParExpression Statement [ELSE Statement] 1840 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement 1841 * | FOR "(" FormalParameter : Expression ")" Statement 1842 * | WHILE ParExpression Statement 1843 * | DO Statement WHILE ParExpression ";" 1844 * | TRY Block ( Catches | [Catches] FinallyPart ) 1845 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}" 1846 * | SYNCHRONIZED ParExpression Block 1847 * | RETURN [Expression] ";" 1848 * | THROW Expression ";" 1849 * | BREAK [Ident] ";" 1850 * | CONTINUE [Ident] ";" 1851 * | ASSERT Expression [ ":" Expression ] ";" 1852 * | ";" 1853 * | ExpressionStatement 1854 * | Ident ":" Statement 1855 */ 1856 @SuppressWarnings("fallthrough") 1857 public JCStatement parseStatement() { 1858 int pos = S.pos(); 1859 switch (S.token()) { 1860 case LBRACE: 1861 return block(); 1862 case IF: { 1863 S.nextToken(); 1864 JCExpression cond = parExpression(); 1865 JCStatement thenpart = parseStatement(); 1866 JCStatement elsepart = null; 1867 if (S.token() == ELSE) { 1868 S.nextToken(); 1869 elsepart = parseStatement(); 1870 } 1871 return F.at(pos).If(cond, thenpart, elsepart); 1872 } 1873 case FOR: { 1874 S.nextToken(); 1875 accept(LPAREN); 1876 List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); 1877 if (inits.length() == 1 && 1878 inits.head.getTag() == JCTree.VARDEF && 1879 ((JCVariableDecl) inits.head).init == null && 1880 S.token() == COLON) { 1881 checkForeach(); 1882 JCVariableDecl var = (JCVariableDecl)inits.head; 1883 accept(COLON); 1884 JCExpression expr = parseExpression(); 1885 accept(RPAREN); 1886 JCStatement body = parseStatement(); 1887 return F.at(pos).ForeachLoop(var, expr, body); 1888 } else { 1889 accept(SEMI); 1890 JCExpression cond = S.token() == SEMI ? null : parseExpression(); 1891 accept(SEMI); 1892 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 1893 accept(RPAREN); 1894 JCStatement body = parseStatement(); 1895 return F.at(pos).ForLoop(inits, cond, steps, body); 1896 } 1897 } 1898 case WHILE: { 1899 S.nextToken(); 1900 JCExpression cond = parExpression(); 1901 JCStatement body = parseStatement(); 1902 return F.at(pos).WhileLoop(cond, body); 1903 } 1904 case DO: { 1905 S.nextToken(); 1906 JCStatement body = parseStatement(); 1907 accept(WHILE); 1908 JCExpression cond = parExpression(); 1909 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond)); 1910 accept(SEMI); 1911 return t; 1912 } 1913 case TRY: { 1914 S.nextToken(); 1915 JCBlock body = block(); 1916 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); 1917 JCBlock finalizer = null; 1918 if (S.token() == CATCH || S.token() == FINALLY) { 1919 while (S.token() == CATCH) catchers.append(catchClause()); 1920 if (S.token() == FINALLY) { 1921 S.nextToken(); 1922 finalizer = block(); 1923 } 1924 } else { 1925 log.error(pos, "try.without.catch.or.finally"); 1926 } 1927 return F.at(pos).Try(body, catchers.toList(), finalizer); 1928 } 1929 case SWITCH: { 1930 S.nextToken(); 1931 JCExpression selector = parExpression(); 1932 accept(LBRACE); 1933 List<JCCase> cases = switchBlockStatementGroups(); 1934 JCSwitch t = to(F.at(pos).Switch(selector, cases)); 1935 accept(RBRACE); 1936 return t; 1937 } 1938 case SYNCHRONIZED: { 1939 S.nextToken(); 1940 JCExpression lock = parExpression(); 1941 JCBlock body = block(); 1942 return F.at(pos).Synchronized(lock, body); 1943 } 1944 case RETURN: { 1945 S.nextToken(); 1946 JCExpression result = S.token() == SEMI ? null : parseExpression(); 1947 JCReturn t = to(F.at(pos).Return(result)); 1948 accept(SEMI); 1949 return t; 1950 } 1951 case THROW: { 1952 S.nextToken(); 1953 JCExpression exc = parseExpression(); 1954 JCThrow t = to(F.at(pos).Throw(exc)); 1955 accept(SEMI); 1956 return t; 1957 } 1958 case BREAK: { 1959 S.nextToken(); 1960 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 1961 JCBreak t = to(F.at(pos).Break(label)); 1962 accept(SEMI); 1963 return t; 1964 } 1965 case CONTINUE: { 1966 S.nextToken(); 1967 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 1968 JCContinue t = to(F.at(pos).Continue(label)); 1969 accept(SEMI); 1970 return t; 1971 } 1972 case SEMI: 1973 S.nextToken(); 1974 return toP(F.at(pos).Skip()); 1975 case ELSE: 1976 return toP(F.Exec(syntaxError("else.without.if"))); 1977 case FINALLY: 1978 return toP(F.Exec(syntaxError("finally.without.try"))); 1979 case CATCH: 1980 return toP(F.Exec(syntaxError("catch.without.try"))); 1981 case ASSERT: { 1982 if (allowAsserts && S.token() == ASSERT) { 1983 S.nextToken(); 1984 JCExpression assertion = parseExpression(); 1985 JCExpression message = null; 1986 if (S.token() == COLON) { 1987 S.nextToken(); 1988 message = parseExpression(); 1989 } 1990 JCAssert t = to(F.at(pos).Assert(assertion, message)); 1991 accept(SEMI); 1992 return t; 1993 } 1994 /* else fall through to default case */ 1995 } 1996 case ENUM: 1997 default: 1998 Name name = S.name(); 1999 JCExpression expr = parseExpression(); 2000 if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { 2001 S.nextToken(); 2002 JCStatement stat = parseStatement(); 2003 return F.at(pos).Labelled(name, stat); 2004 } else { 2005 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 2006 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); 2007 accept(SEMI); 2008 return stat; 2009 } 2010 } 2011 } 2012 2013 /** CatchClause = CATCH "(" FormalParameter ")" Block 2014 */ 2015 JCCatch catchClause() { 2016 int pos = S.pos(); 2017 accept(CATCH); 2018 accept(LPAREN); 2019 JCModifiers mods = optFinal(Flags.PARAMETER); 2020 List<JCExpression> catchTypes = catchTypes(); 2021 JCExpression paramType = catchTypes.size() > 1 ? 2022 toP(F.at(catchTypes.head.getStartPosition()).TypeDisjoint(catchTypes)) : 2023 catchTypes.head; 2024 JCVariableDecl formal = variableDeclaratorId(mods, paramType); 2025 accept(RPAREN); 2026 JCBlock body = block(); 2027 return F.at(pos).Catch(formal, body); 2028 } 2029 2030 List<JCExpression> catchTypes() { 2031 ListBuffer<JCExpression> catchTypes = ListBuffer.lb(); 2032 catchTypes.add(parseType()); 2033 while (S.token() == BAR) { 2034 checkMulticatch(); 2035 S.nextToken(); 2036 catchTypes.add(qualident()); 2037 } 2038 return catchTypes.toList(); 2039 } 2040 2041 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup } 2042 * SwitchBlockStatementGroup = SwitchLabel BlockStatements 2043 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":" 2044 */ 2045 List<JCCase> switchBlockStatementGroups() { 2046 ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); 2047 while (true) { 2048 int pos = S.pos(); 2049 switch (S.token()) { 2050 case CASE: { 2051 S.nextToken(); 2052 JCExpression pat = parseExpression(); 2053 accept(COLON); 2054 List<JCStatement> stats = blockStatements(); 2055 JCCase c = F.at(pos).Case(pat, stats); 2056 if (stats.isEmpty()) 2057 storeEnd(c, S.prevEndPos()); 2058 cases.append(c); 2059 break; 2060 } 2061 case DEFAULT: { 2062 S.nextToken(); 2063 accept(COLON); 2064 List<JCStatement> stats = blockStatements(); 2065 JCCase c = F.at(pos).Case(null, stats); 2066 if (stats.isEmpty()) 2067 storeEnd(c, S.prevEndPos()); 2068 cases.append(c); 2069 break; 2070 } 2071 case RBRACE: case EOF: 2072 return cases.toList(); 2073 default: 2074 S.nextToken(); // to ensure progress 2075 syntaxError(pos, "expected3", 2076 CASE, DEFAULT, RBRACE); 2077 } 2078 } 2079 } 2080 2081 /** MoreStatementExpressions = { COMMA StatementExpression } 2082 */ 2083 <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos, 2084 JCExpression first, 2085 T stats) { 2086 // This Exec is a "StatementExpression"; it subsumes no terminating token 2087 stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 2088 while (S.token() == COMMA) { 2089 S.nextToken(); 2090 pos = S.pos(); 2091 JCExpression t = parseExpression(); 2092 // This Exec is a "StatementExpression"; it subsumes no terminating token 2093 stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 2094 } 2095 return stats; 2096 } 2097 2098 /** ForInit = StatementExpression MoreStatementExpressions 2099 * | { FINAL | '@' Annotation } Type VariableDeclarators 2100 */ 2101 List<JCStatement> forInit() { 2102 ListBuffer<JCStatement> stats = lb(); 2103 int pos = S.pos(); 2104 if (S.token() == FINAL || S.token() == MONKEYS_AT) { 2105 return variableDeclarators(optFinal(0), parseType(), stats).toList(); 2106 } else { 2107 JCExpression t = term(EXPR | TYPE); 2108 if ((lastmode & TYPE) != 0 && 2109 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) 2110 return variableDeclarators(modifiersOpt(), t, stats).toList(); 2111 else 2112 return moreStatementExpressions(pos, t, stats).toList(); 2113 } 2114 } 2115 2116 /** ForUpdate = StatementExpression MoreStatementExpressions 2117 */ 2118 List<JCExpressionStatement> forUpdate() { 2119 return moreStatementExpressions(S.pos(), 2120 parseExpression(), 2121 new ListBuffer<JCExpressionStatement>()).toList(); 2122 } 2123 2124 enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO }; 2125 2126 /** AnnotationsOpt = { '@' Annotation } 2127 */ 2128 List<JCAnnotation> annotationsOpt(AnnotationKind kind) { 2129 if (S.token() != MONKEYS_AT) return List.nil(); // optimization 2130 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 2131 int prevmode = mode; 2132 while (S.token() == MONKEYS_AT) { 2133 int pos = S.pos(); 2134 S.nextToken(); 2135 buf.append(annotation(pos, kind)); 2136 } 2137 lastmode = mode; 2138 mode = prevmode; 2139 List<JCAnnotation> annotations = buf.toList(); 2140 2141 if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO) 2142 System.out.println("TA: parsing " + annotations 2143 + " in " + log.currentSourceFile()); 2144 return annotations; 2145 } 2146 2147 List<JCTypeAnnotation> typeAnnotationsOpt() { 2148 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO); 2149 return List.convert(JCTypeAnnotation.class, annotations); 2150 } 2151 2152 /** ModifiersOpt = { Modifier } 2153 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 2154 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 2155 * | "@" Annotation 2156 */ 2157 JCModifiers modifiersOpt() { 2158 return modifiersOpt(null); 2159 } 2160 JCModifiers modifiersOpt(JCModifiers partial) { 2161 long flags; 2162 ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>(); 2163 int pos; 2164 if (partial == null) { 2165 flags = 0; 2166 pos = S.pos(); 2167 } else { 2168 flags = partial.flags; 2169 annotations.appendList(partial.annotations); 2170 pos = partial.pos; 2171 } 2172 if (S.deprecatedFlag()) { 2173 flags |= Flags.DEPRECATED; 2174 S.resetDeprecatedFlag(); 2175 } 2176 int lastPos = Position.NOPOS; 2177 loop: 2178 while (true) { 2179 long flag; 2180 switch (S.token()) { 2181 case PRIVATE : flag = Flags.PRIVATE; break; 2182 case PROTECTED : flag = Flags.PROTECTED; break; 2183 case PUBLIC : flag = Flags.PUBLIC; break; 2184 case STATIC : flag = Flags.STATIC; break; 2185 case TRANSIENT : flag = Flags.TRANSIENT; break; 2186 case FINAL : flag = Flags.FINAL; break; 2187 case ABSTRACT : flag = Flags.ABSTRACT; break; 2188 case NATIVE : flag = Flags.NATIVE; break; 2189 case VOLATILE : flag = Flags.VOLATILE; break; 2190 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 2191 case STRICTFP : flag = Flags.STRICTFP; break; 2192 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 2193 default: break loop; 2194 } 2195 if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier"); 2196 lastPos = S.pos(); 2197 S.nextToken(); 2198 if (flag == Flags.ANNOTATION) { 2199 checkAnnotations(); 2200 if (S.token() != INTERFACE) { 2201 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO); 2202 // if first modifier is an annotation, set pos to annotation's. 2203 if (flags == 0 && annotations.isEmpty()) 2204 pos = ann.pos; 2205 annotations.append(ann); 2206 lastPos = ann.pos; 2207 flag = 0; 2208 } 2209 } 2210 flags |= flag; 2211 } 2212 switch (S.token()) { 2213 case ENUM: flags |= Flags.ENUM; break; 2214 case INTERFACE: flags |= Flags.INTERFACE; break; 2215 default: break; 2216 } 2217 2218 /* A modifiers tree with no modifier tokens or annotations 2219 * has no text position. */ 2220 if ((flags & Flags.ModifierFlags) == 0 && annotations.isEmpty()) 2221 pos = Position.NOPOS; 2222 2223 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 2224 if (pos != Position.NOPOS) 2225 storeEnd(mods, S.prevEndPos()); 2226 return mods; 2227 } 2228 2229 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 2230 * @param pos position of "@" token 2231 */ 2232 JCAnnotation annotation(int pos, AnnotationKind kind) { 2233 // accept(AT); // AT consumed by caller 2234 checkAnnotations(); 2235 if (kind == AnnotationKind.TYPE_ANNO) 2236 checkTypeAnnotations(); 2237 JCTree ident = qualident(); 2238 List<JCExpression> fieldValues = annotationFieldValuesOpt(); 2239 JCAnnotation ann; 2240 if (kind == AnnotationKind.DEFAULT_ANNO) 2241 ann = F.at(pos).Annotation(ident, fieldValues); 2242 else 2243 ann = F.at(pos).TypeAnnotation(ident, fieldValues); 2244 storeEnd(ann, S.prevEndPos()); 2245 return ann; 2246 } 2247 2248 List<JCExpression> annotationFieldValuesOpt() { 2249 return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 2250 } 2251 2252 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 2253 List<JCExpression> annotationFieldValues() { 2254 accept(LPAREN); 2255 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 2256 if (S.token() != RPAREN) { 2257 buf.append(annotationFieldValue()); 2258 while (S.token() == COMMA) { 2259 S.nextToken(); 2260 buf.append(annotationFieldValue()); 2261 } 2262 } 2263 accept(RPAREN); 2264 return buf.toList(); 2265 } 2266 2267 /** AnnotationFieldValue = AnnotationValue 2268 * | Identifier "=" AnnotationValue 2269 */ 2270 JCExpression annotationFieldValue() { 2271 if (S.token() == IDENTIFIER) { 2272 mode = EXPR; 2273 JCExpression t1 = term1(); 2274 if (t1.getTag() == JCTree.IDENT && S.token() == EQ) { 2275 int pos = S.pos(); 2276 accept(EQ); 2277 JCExpression v = annotationValue(); 2278 return toP(F.at(pos).Assign(t1, v)); 2279 } else { 2280 return t1; 2281 } 2282 } 2283 return annotationValue(); 2284 } 2285 2286 /* AnnotationValue = ConditionalExpression 2287 * | Annotation 2288 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}" 2289 */ 2290 JCExpression annotationValue() { 2291 int pos; 2292 switch (S.token()) { 2293 case MONKEYS_AT: 2294 pos = S.pos(); 2295 S.nextToken(); 2296 return annotation(pos, AnnotationKind.DEFAULT_ANNO); 2297 case LBRACE: 2298 pos = S.pos(); 2299 accept(LBRACE); 2300 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 2301 if (S.token() != RBRACE) { 2302 buf.append(annotationValue()); 2303 while (S.token() == COMMA) { 2304 S.nextToken(); 2305 if (S.token() == RBRACE) break; 2306 buf.append(annotationValue()); 2307 } 2308 } 2309 accept(RBRACE); 2310 return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList())); 2311 default: 2312 mode = EXPR; 2313 return term1(); 2314 } 2315 } 2316 2317 /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator } 2318 */ 2319 public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods, 2320 JCExpression type, 2321 T vdefs) 2322 { 2323 return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs); 2324 } 2325 2326 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 2327 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator } 2328 * 2329 * @param reqInit Is an initializer always required? 2330 * @param dc The documentation comment for the variable declarations, or null. 2331 */ 2332 <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos, 2333 JCModifiers mods, 2334 JCExpression type, 2335 Name name, 2336 boolean reqInit, 2337 String dc, 2338 T vdefs) 2339 { 2340 vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc)); 2341 while (S.token() == COMMA) { 2342 // All but last of multiple declarators subsume a comma 2343 storeEnd((JCTree)vdefs.elems.last(), S.endPos()); 2344 S.nextToken(); 2345 vdefs.append(variableDeclarator(mods, type, reqInit, dc)); 2346 } 2347 return vdefs; 2348 } 2349 2350 /** VariableDeclarator = Ident VariableDeclaratorRest 2351 * ConstantDeclarator = Ident ConstantDeclaratorRest 2352 */ 2353 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) { 2354 return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc); 2355 } 2356 2357 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 2358 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer 2359 * 2360 * @param reqInit Is an initializer always required? 2361 * @param dc The documentation comment for the variable declarations, or null. 2362 */ 2363 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name, 2364 boolean reqInit, String dc) { 2365 type = bracketsOpt(type); 2366 JCExpression init = null; 2367 if (S.token() == EQ) { 2368 S.nextToken(); 2369 init = variableInitializer(); 2370 } 2371 else if (reqInit) syntaxError(S.pos(), "expected", EQ); 2372 JCVariableDecl result = 2373 toP(F.at(pos).VarDef(mods, name, type, init)); 2374 attach(result, dc); 2375 return result; 2376 } 2377 2378 /** VariableDeclaratorId = Ident BracketsOpt 2379 */ 2380 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 2381 int pos = S.pos(); 2382 Name name = ident(); 2383 if ((mods.flags & Flags.VARARGS) == 0) 2384 type = bracketsOpt(type); 2385 return toP(F.at(pos).VarDef(mods, name, type, null)); 2386 } 2387 2388 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 2389 */ 2390 public JCTree.JCCompilationUnit parseCompilationUnit() { 2391 int pos = S.pos(); 2392 JCExpression pid = null; 2393 String dc = S.docComment(); 2394 JCModifiers mods = null; 2395 List<JCAnnotation> packageAnnotations = List.nil(); 2396 if (S.token() == MONKEYS_AT) 2397 mods = modifiersOpt(); 2398 2399 if (S.token() == PACKAGE) { 2400 if (mods != null) { 2401 checkNoMods(mods.flags); 2402 packageAnnotations = mods.annotations; 2403 mods = null; 2404 } 2405 S.nextToken(); 2406 pid = qualident(); 2407 accept(SEMI); 2408 } 2409 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2410 boolean checkForImports = true; 2411 while (S.token() != EOF) { 2412 if (S.pos() <= errorEndPos) { 2413 // error recovery 2414 skip(checkForImports, false, false, false); 2415 if (S.token() == EOF) 2416 break; 2417 } 2418 if (checkForImports && mods == null && S.token() == IMPORT) { 2419 defs.append(importDeclaration()); 2420 } else { 2421 JCTree def = typeDeclaration(mods); 2422 if (def instanceof JCExpressionStatement) 2423 def = ((JCExpressionStatement)def).expr; 2424 defs.append(def); 2425 if (def instanceof JCClassDecl) 2426 checkForImports = false; 2427 mods = null; 2428 } 2429 } 2430 JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList()); 2431 attach(toplevel, dc); 2432 if (defs.elems.isEmpty()) 2433 storeEnd(toplevel, S.prevEndPos()); 2434 if (keepDocComments) 2435 toplevel.docComments = docComments; 2436 if (keepLineMap) 2437 toplevel.lineMap = S.getLineMap(); 2438 return toplevel; 2439 } 2440 2441 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 2442 */ 2443 JCTree importDeclaration() { 2444 int pos = S.pos(); 2445 S.nextToken(); 2446 boolean importStatic = false; 2447 if (S.token() == STATIC) { 2448 checkStaticImports(); 2449 importStatic = true; 2450 S.nextToken(); 2451 } 2452 JCExpression pid = toP(F.at(S.pos()).Ident(ident())); 2453 do { 2454 int pos1 = S.pos(); 2455 accept(DOT); 2456 if (S.token() == STAR) { 2457 pid = to(F.at(pos1).Select(pid, names.asterisk)); 2458 S.nextToken(); 2459 break; 2460 } else { 2461 pid = toP(F.at(pos1).Select(pid, ident())); 2462 } 2463 } while (S.token() == DOT); 2464 accept(SEMI); 2465 return toP(F.at(pos).Import(pid, importStatic)); 2466 } 2467 2468 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 2469 * | ";" 2470 */ 2471 JCTree typeDeclaration(JCModifiers mods) { 2472 int pos = S.pos(); 2473 if (mods == null && S.token() == SEMI) { 2474 S.nextToken(); 2475 return toP(F.at(pos).Skip()); 2476 } else { 2477 String dc = S.docComment(); 2478 return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc); 2479 } 2480 } 2481 2482 /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt 2483 * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration) 2484 * @param mods Any modifiers starting the class or interface declaration 2485 * @param dc The documentation comment for the class, or null. 2486 */ 2487 JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) { 2488 if (S.token() == CLASS) { 2489 return classDeclaration(mods, dc); 2490 } else if (S.token() == INTERFACE) { 2491 return interfaceDeclaration(mods, dc); 2492 } else if (allowEnums) { 2493 if (S.token() == ENUM) { 2494 return enumDeclaration(mods, dc); 2495 } else { 2496 int pos = S.pos(); 2497 List<JCTree> errs; 2498 if (S.token() == IDENTIFIER) { 2499 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2500 setErrorEndPos(S.pos()); 2501 } else { 2502 errs = List.<JCTree>of(mods); 2503 } 2504 return toP(F.Exec(syntaxError(pos, errs, "expected3", 2505 CLASS, INTERFACE, ENUM))); 2506 } 2507 } else { 2508 if (S.token() == ENUM) { 2509 log.error(S.pos(), "enums.not.supported.in.source", source.name); 2510 allowEnums = true; 2511 return enumDeclaration(mods, dc); 2512 } 2513 int pos = S.pos(); 2514 List<JCTree> errs; 2515 if (S.token() == IDENTIFIER) { 2516 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 2517 setErrorEndPos(S.pos()); 2518 } else { 2519 errs = List.<JCTree>of(mods); 2520 } 2521 return toP(F.Exec(syntaxError(pos, errs, "expected2", 2522 CLASS, INTERFACE))); 2523 } 2524 } 2525 2526 /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type] 2527 * [IMPLEMENTS TypeList] ClassBody 2528 * @param mods The modifiers starting the class declaration 2529 * @param dc The documentation comment for the class, or null. 2530 */ 2531 JCClassDecl classDeclaration(JCModifiers mods, String dc) { 2532 int pos = S.pos(); 2533 accept(CLASS); 2534 Name name = ident(); 2535 2536 List<JCTypeParameter> typarams = typeParametersOpt(); 2537 2538 JCTree extending = null; 2539 if (S.token() == EXTENDS) { 2540 S.nextToken(); 2541 extending = parseType(); 2542 } 2543 List<JCExpression> implementing = List.nil(); 2544 if (S.token() == IMPLEMENTS) { 2545 S.nextToken(); 2546 implementing = typeList(); 2547 } 2548 List<JCTree> defs = classOrInterfaceBody(name, false); 2549 JCClassDecl result = toP(F.at(pos).ClassDef( 2550 mods, name, typarams, extending, implementing, defs)); 2551 attach(result, dc); 2552 return result; 2553 } 2554 2555 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt 2556 * [EXTENDS TypeList] InterfaceBody 2557 * @param mods The modifiers starting the interface declaration 2558 * @param dc The documentation comment for the interface, or null. 2559 */ 2560 JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 2561 int pos = S.pos(); 2562 accept(INTERFACE); 2563 Name name = ident(); 2564 2565 List<JCTypeParameter> typarams = typeParametersOpt(); 2566 2567 List<JCExpression> extending = List.nil(); 2568 if (S.token() == EXTENDS) { 2569 S.nextToken(); 2570 extending = typeList(); 2571 } 2572 List<JCTree> defs = classOrInterfaceBody(name, true); 2573 JCClassDecl result = toP(F.at(pos).ClassDef( 2574 mods, name, typarams, null, extending, defs)); 2575 attach(result, dc); 2576 return result; 2577 } 2578 2579 /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody 2580 * @param mods The modifiers starting the enum declaration 2581 * @param dc The documentation comment for the enum, or null. 2582 */ 2583 JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 2584 int pos = S.pos(); 2585 accept(ENUM); 2586 Name name = ident(); 2587 2588 List<JCExpression> implementing = List.nil(); 2589 if (S.token() == IMPLEMENTS) { 2590 S.nextToken(); 2591 implementing = typeList(); 2592 } 2593 2594 List<JCTree> defs = enumBody(name); 2595 mods.flags |= Flags.ENUM; 2596 JCClassDecl result = toP(F.at(pos). 2597 ClassDef(mods, name, List.<JCTypeParameter>nil(), 2598 null, implementing, defs)); 2599 attach(result, dc); 2600 return result; 2601 } 2602 2603 /** EnumBody = "{" { EnumeratorDeclarationList } [","] 2604 * [ ";" {ClassBodyDeclaration} ] "}" 2605 */ 2606 List<JCTree> enumBody(Name enumName) { 2607 accept(LBRACE); 2608 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2609 if (S.token() == COMMA) { 2610 S.nextToken(); 2611 } else if (S.token() != RBRACE && S.token() != SEMI) { 2612 defs.append(enumeratorDeclaration(enumName)); 2613 while (S.token() == COMMA) { 2614 S.nextToken(); 2615 if (S.token() == RBRACE || S.token() == SEMI) break; 2616 defs.append(enumeratorDeclaration(enumName)); 2617 } 2618 if (S.token() != SEMI && S.token() != RBRACE) { 2619 defs.append(syntaxError(S.pos(), "expected3", 2620 COMMA, RBRACE, SEMI)); 2621 S.nextToken(); 2622 } 2623 } 2624 if (S.token() == SEMI) { 2625 S.nextToken(); 2626 while (S.token() != RBRACE && S.token() != EOF) { 2627 defs.appendList(classOrInterfaceBodyDeclaration(enumName, 2628 false)); 2629 if (S.pos() <= errorEndPos) { 2630 // error recovery 2631 skip(false, true, true, false); 2632 } 2633 } 2634 } 2635 accept(RBRACE); 2636 return defs.toList(); 2637 } 2638 2639 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 2640 */ 2641 JCTree enumeratorDeclaration(Name enumName) { 2642 String dc = S.docComment(); 2643 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 2644 if (S.deprecatedFlag()) { 2645 flags |= Flags.DEPRECATED; 2646 S.resetDeprecatedFlag(); 2647 } 2648 int pos = S.pos(); 2649 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO); 2650 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 2651 List<JCExpression> typeArgs = typeArgumentsOpt(); 2652 int identPos = S.pos(); 2653 Name name = ident(); 2654 int createPos = S.pos(); 2655 List<JCExpression> args = (S.token() == LPAREN) 2656 ? arguments() : List.<JCExpression>nil(); 2657 JCClassDecl body = null; 2658 if (S.token() == LBRACE) { 2659 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC); 2660 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 2661 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 2662 } 2663 if (args.isEmpty() && body == null) 2664 createPos = identPos; 2665 JCIdent ident = F.at(identPos).Ident(enumName); 2666 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 2667 if (createPos != identPos) 2668 storeEnd(create, S.prevEndPos()); 2669 ident = F.at(identPos).Ident(enumName); 2670 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 2671 attach(result, dc); 2672 return result; 2673 } 2674 2675 /** TypeList = Type {"," Type} 2676 */ 2677 List<JCExpression> typeList() { 2678 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 2679 ts.append(parseType()); 2680 while (S.token() == COMMA) { 2681 S.nextToken(); 2682 ts.append(parseType()); 2683 } 2684 return ts.toList(); 2685 } 2686 2687 /** ClassBody = "{" {ClassBodyDeclaration} "}" 2688 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}" 2689 */ 2690 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 2691 accept(LBRACE); 2692 if (S.pos() <= errorEndPos) { 2693 // error recovery 2694 skip(false, true, false, false); 2695 if (S.token() == LBRACE) 2696 S.nextToken(); 2697 } 2698 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 2699 while (S.token() != RBRACE && S.token() != EOF) { 2700 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 2701 if (S.pos() <= errorEndPos) { 2702 // error recovery 2703 skip(false, true, true, false); 2704 } 2705 } 2706 accept(RBRACE); 2707 return defs.toList(); 2708 } 2709 2710 /** ClassBodyDeclaration = 2711 * ";" 2712 * | [STATIC] Block 2713 * | ModifiersOpt 2714 * ( Type Ident 2715 * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest ) 2716 * | VOID Ident MethodDeclaratorRest 2717 * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest 2718 * | Ident ConstructorDeclaratorRest 2719 * | TypeParameters Ident ConstructorDeclaratorRest 2720 * | ClassOrInterfaceOrEnumDeclaration 2721 * ) 2722 * InterfaceBodyDeclaration = 2723 * ";" 2724 * | ModifiersOpt Type Ident 2725 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 2726 */ 2727 List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 2728 if (S.token() == SEMI) { 2729 S.nextToken(); 2730 return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil())); 2731 } else { 2732 String dc = S.docComment(); 2733 int pos = S.pos(); 2734 JCModifiers mods = modifiersOpt(); 2735 if (S.token() == CLASS || 2736 S.token() == INTERFACE || 2737 allowEnums && S.token() == ENUM) { 2738 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc)); 2739 } else if (S.token() == LBRACE && !isInterface && 2740 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 2741 mods.annotations.isEmpty()) { 2742 return List.<JCTree>of(block(pos, mods.flags)); 2743 } else { 2744 pos = S.pos(); 2745 List<JCTypeParameter> typarams = typeParametersOpt(); 2746 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO); 2747 2748 Name name = S.name(); 2749 pos = S.pos(); 2750 JCExpression type; 2751 boolean isVoid = S.token() == VOID; 2752 if (isVoid) { 2753 if (annosAfterParams.nonEmpty()) 2754 illegal(annosAfterParams.head.pos); 2755 type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 2756 S.nextToken(); 2757 } else { 2758 if (annosAfterParams.nonEmpty()) { 2759 mods.annotations = mods.annotations.appendList(annosAfterParams); 2760 if (mods.pos == Position.NOPOS) 2761 mods.pos = mods.annotations.head.pos; 2762 } 2763 // method returns types are un-annotated types 2764 type = unannotatedType(); 2765 } 2766 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 2767 if (isInterface || name != className) 2768 log.error(pos, "invalid.meth.decl.ret.type.req"); 2769 return List.of(methodDeclaratorRest( 2770 pos, mods, null, names.init, typarams, 2771 isInterface, true, dc)); 2772 } else { 2773 pos = S.pos(); 2774 name = ident(); 2775 if (S.token() == LPAREN) { 2776 return List.of(methodDeclaratorRest( 2777 pos, mods, type, name, typarams, 2778 isInterface, isVoid, dc)); 2779 } else if (!isVoid && typarams.isEmpty()) { 2780 List<JCTree> defs = 2781 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 2782 new ListBuffer<JCTree>()).toList(); 2783 storeEnd(defs.last(), S.endPos()); 2784 accept(SEMI); 2785 return defs; 2786 } else { 2787 pos = S.pos(); 2788 List<JCTree> err = isVoid 2789 ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 2790 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null))) 2791 : null; 2792 return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN)); 2793 } 2794 } 2795 } 2796 } 2797 } 2798 2799 /** MethodDeclaratorRest = 2800 * FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 2801 * VoidMethodDeclaratorRest = 2802 * FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";") 2803 * InterfaceMethodDeclaratorRest = 2804 * FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";" 2805 * VoidInterfaceMethodDeclaratorRest = 2806 * FormalParameters [Annotations] [THROWS TypeList] ";" 2807 * ConstructorDeclaratorRest = 2808 * "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody 2809 */ 2810 JCTree methodDeclaratorRest(int pos, 2811 JCModifiers mods, 2812 JCExpression type, 2813 Name name, 2814 List<JCTypeParameter> typarams, 2815 boolean isInterface, boolean isVoid, 2816 String dc) { 2817 List<JCVariableDecl> params = formalParameters(); 2818 2819 List<JCTypeAnnotation> receiverAnnotations; 2820 if (!isVoid) { 2821 // need to distinguish between receiver anno and array anno 2822 // look at typeAnnotationsPushedBack comment 2823 this.permitTypeAnnotationsPushBack = true; 2824 type = methodReturnArrayRest(type); 2825 this.permitTypeAnnotationsPushBack = false; 2826 if (typeAnnotationsPushedBack == null) 2827 receiverAnnotations = List.nil(); 2828 else 2829 receiverAnnotations = typeAnnotationsPushedBack; 2830 typeAnnotationsPushedBack = null; 2831 } else 2832 receiverAnnotations = typeAnnotationsOpt(); 2833 2834 List<JCExpression> thrown = List.nil(); 2835 if (S.token() == THROWS) { 2836 S.nextToken(); 2837 thrown = qualidentList(); 2838 } 2839 JCBlock body = null; 2840 JCExpression defaultValue; 2841 if (S.token() == LBRACE) { 2842 body = block(); 2843 defaultValue = null; 2844 } else { 2845 if (S.token() == DEFAULT) { 2846 accept(DEFAULT); 2847 defaultValue = annotationValue(); 2848 } else { 2849 defaultValue = null; 2850 } 2851 accept(SEMI); 2852 if (S.pos() <= errorEndPos) { 2853 // error recovery 2854 skip(false, true, false, false); 2855 if (S.token() == LBRACE) { 2856 body = block(); 2857 } 2858 } 2859 } 2860 2861 JCMethodDecl result = 2862 toP(F.at(pos).MethodDef(mods, name, type, typarams, 2863 params, receiverAnnotations, thrown, 2864 body, defaultValue)); 2865 attach(result, dc); 2866 return result; 2867 } 2868 2869 /** Parses the array levels after the format parameters list, and append 2870 * them to the return type, while preseving the order of type annotations 2871 */ 2872 private JCExpression methodReturnArrayRest(JCExpression type) { 2873 if (type.getTag() != JCTree.TYPEARRAY) 2874 return bracketsOpt(type); 2875 2876 JCArrayTypeTree baseArray = (JCArrayTypeTree)type; 2877 while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree) 2878 baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype); 2879 2880 if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) { 2881 JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype; 2882 at.underlyingType = bracketsOpt(at.underlyingType); 2883 } else { 2884 baseArray.elemtype = bracketsOpt(baseArray.elemtype); 2885 } 2886 2887 return type; 2888 } 2889 2890 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident} 2891 */ 2892 List<JCExpression> qualidentList() { 2893 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 2894 2895 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt(); 2896 if (!typeAnnos.isEmpty()) 2897 ts.append(F.AnnotatedType(typeAnnos, qualident())); 2898 else 2899 ts.append(qualident()); 2900 while (S.token() == COMMA) { 2901 S.nextToken(); 2902 2903 typeAnnos = typeAnnotationsOpt(); 2904 if (!typeAnnos.isEmpty()) 2905 ts.append(F.AnnotatedType(typeAnnos, qualident())); 2906 else 2907 ts.append(qualident()); 2908 } 2909 return ts.toList(); 2910 } 2911 2912 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 2913 */ 2914 List<JCTypeParameter> typeParametersOpt() { 2915 if (S.token() == LT) { 2916 checkGenerics(); 2917 ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>(); 2918 S.nextToken(); 2919 typarams.append(typeParameter()); 2920 while (S.token() == COMMA) { 2921 S.nextToken(); 2922 typarams.append(typeParameter()); 2923 } 2924 accept(GT); 2925 return typarams.toList(); 2926 } else { 2927 return List.nil(); 2928 } 2929 } 2930 2931 /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound] 2932 * TypeParameterBound = EXTENDS Type {"&" Type} 2933 * TypeVariable = Ident 2934 */ 2935 JCTypeParameter typeParameter() { 2936 int pos = S.pos(); 2937 List<JCTypeAnnotation> annos = typeAnnotationsOpt(); 2938 Name name = ident(); 2939 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 2940 if (S.token() == EXTENDS) { 2941 S.nextToken(); 2942 bounds.append(parseType()); 2943 while (S.token() == AMP) { 2944 S.nextToken(); 2945 bounds.append(parseType()); 2946 } 2947 } 2948 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos)); 2949 } 2950 2951 /** FormalParameters = "(" [ FormalParameterList ] ")" 2952 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 2953 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 2954 */ 2955 List<JCVariableDecl> formalParameters() { 2956 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 2957 JCVariableDecl lastParam = null; 2958 accept(LPAREN); 2959 if (S.token() != RPAREN) { 2960 params.append(lastParam = formalParameter()); 2961 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) { 2962 S.nextToken(); 2963 params.append(lastParam = formalParameter()); 2964 } 2965 } 2966 accept(RPAREN); 2967 return params.toList(); 2968 } 2969 2970 JCModifiers optFinal(long flags) { 2971 JCModifiers mods = modifiersOpt(); 2972 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED)); 2973 mods.flags |= flags; 2974 return mods; 2975 } 2976 2977 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 2978 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 2979 */ 2980 JCVariableDecl formalParameter() { 2981 JCModifiers mods = optFinal(Flags.PARAMETER); 2982 // need to distinguish between vararg annos and array annos 2983 // look at typeAnnotaitonsPushedBack comment 2984 this.permitTypeAnnotationsPushBack = true; 2985 JCExpression type = parseType(); 2986 this.permitTypeAnnotationsPushBack = false; 2987 2988 if (S.token() == ELLIPSIS) { 2989 List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack; 2990 typeAnnotationsPushedBack = null; 2991 checkVarargs(); 2992 mods.flags |= Flags.VARARGS; 2993 // insert var arg type annotations 2994 if (varargsAnnos != null && varargsAnnos.nonEmpty()) 2995 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type); 2996 type = to(F.at(S.pos()).TypeArray(type)); 2997 2998 S.nextToken(); 2999 } else { 3000 // if not a var arg, then typeAnnotationsPushedBack should be null 3001 if (typeAnnotationsPushedBack != null 3002 && !typeAnnotationsPushedBack.isEmpty()) { 3003 reportSyntaxError(typeAnnotationsPushedBack.head.pos, 3004 "illegal.start.of.type"); 3005 } 3006 typeAnnotationsPushedBack = null; 3007 } 3008 return variableDeclaratorId(mods, type); 3009 } 3010 3011 /* ---------- auxiliary methods -------------- */ 3012 3013 /** Check that given tree is a legal expression statement. 3014 */ 3015 protected JCExpression checkExprStat(JCExpression t) { 3016 switch(t.getTag()) { 3017 case JCTree.PREINC: case JCTree.PREDEC: 3018 case JCTree.POSTINC: case JCTree.POSTDEC: 3019 case JCTree.ASSIGN: 3020 case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG: 3021 case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG: 3022 case JCTree.PLUS_ASG: case JCTree.MINUS_ASG: 3023 case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG: 3024 case JCTree.APPLY: case JCTree.NEWCLASS: 3025 case JCTree.ERRONEOUS: 3026 return t; 3027 default: 3028 log.error(t.pos, "not.stmt"); 3029 return F.at(t.pos).Erroneous(List.<JCTree>of(t)); 3030 } 3031 } 3032 3033 /** Return precedence of operator represented by token, 3034 * -1 if token is not a binary operator. @see TreeInfo.opPrec 3035 */ 3036 static int prec(Token token) { 3037 int oc = optag(token); 3038 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 3039 } 3040 3041 /** 3042 * Return the lesser of two positions, making allowance for either one 3043 * being unset. 3044 */ 3045 static int earlier(int pos1, int pos2) { 3046 if (pos1 == Position.NOPOS) 3047 return pos2; 3048 if (pos2 == Position.NOPOS) 3049 return pos1; 3050 return (pos1 < pos2 ? pos1 : pos2); 3051 } 3052 3053 /** Return operation tag of binary operator represented by token, 3054 * -1 if token is not a binary operator. 3055 */ 3056 static int optag(Token token) { 3057 switch (token) { 3058 case BARBAR: 3059 return JCTree.OR; 3060 case AMPAMP: 3061 return JCTree.AND; 3062 case BAR: 3063 return JCTree.BITOR; 3064 case BAREQ: 3065 return JCTree.BITOR_ASG; 3066 case CARET: 3067 return JCTree.BITXOR; 3068 case CARETEQ: 3069 return JCTree.BITXOR_ASG; 3070 case AMP: 3071 return JCTree.BITAND; 3072 case AMPEQ: 3073 return JCTree.BITAND_ASG; 3074 case EQEQ: 3075 return JCTree.EQ; 3076 case BANGEQ: 3077 return JCTree.NE; 3078 case LT: 3079 return JCTree.LT; 3080 case GT: 3081 return JCTree.GT; 3082 case LTEQ: 3083 return JCTree.LE; 3084 case GTEQ: 3085 return JCTree.GE; 3086 case LTLT: 3087 return JCTree.SL; 3088 case LTLTEQ: 3089 return JCTree.SL_ASG; 3090 case GTGT: 3091 return JCTree.SR; 3092 case GTGTEQ: 3093 return JCTree.SR_ASG; 3094 case GTGTGT: 3095 return JCTree.USR; 3096 case GTGTGTEQ: 3097 return JCTree.USR_ASG; 3098 case PLUS: 3099 return JCTree.PLUS; 3100 case PLUSEQ: 3101 return JCTree.PLUS_ASG; 3102 case SUB: 3103 return JCTree.MINUS; 3104 case SUBEQ: 3105 return JCTree.MINUS_ASG; 3106 case STAR: 3107 return JCTree.MUL; 3108 case STAREQ: 3109 return JCTree.MUL_ASG; 3110 case SLASH: 3111 return JCTree.DIV; 3112 case SLASHEQ: 3113 return JCTree.DIV_ASG; 3114 case PERCENT: 3115 return JCTree.MOD; 3116 case PERCENTEQ: 3117 return JCTree.MOD_ASG; 3118 case INSTANCEOF: 3119 return JCTree.TYPETEST; 3120 default: 3121 return -1; 3122 } 3123 } 3124 3125 /** Return operation tag of unary operator represented by token, 3126 * -1 if token is not a binary operator. 3127 */ 3128 static int unoptag(Token token) { 3129 switch (token) { 3130 case PLUS: 3131 return JCTree.POS; 3132 case SUB: 3133 return JCTree.NEG; 3134 case BANG: 3135 return JCTree.NOT; 3136 case TILDE: 3137 return JCTree.COMPL; 3138 case PLUSPLUS: 3139 return JCTree.PREINC; 3140 case SUBSUB: 3141 return JCTree.PREDEC; 3142 default: 3143 return -1; 3144 } 3145 } 3146 3147 /** Return type tag of basic type represented by token, 3148 * -1 if token is not a basic type identifier. 3149 */ 3150 static int typetag(Token token) { 3151 switch (token) { 3152 case BYTE: 3153 return TypeTags.BYTE; 3154 case CHAR: 3155 return TypeTags.CHAR; 3156 case SHORT: 3157 return TypeTags.SHORT; 3158 case INT: 3159 return TypeTags.INT; 3160 case LONG: 3161 return TypeTags.LONG; 3162 case FLOAT: 3163 return TypeTags.FLOAT; 3164 case DOUBLE: 3165 return TypeTags.DOUBLE; 3166 case BOOLEAN: 3167 return TypeTags.BOOLEAN; 3168 default: 3169 return -1; 3170 } 3171 } 3172 3173 void checkGenerics() { 3174 if (!allowGenerics) { 3175 log.error(S.pos(), "generics.not.supported.in.source", source.name); 3176 allowGenerics = true; 3177 } 3178 } 3179 void checkVarargs() { 3180 if (!allowVarargs) { 3181 log.error(S.pos(), "varargs.not.supported.in.source", source.name); 3182 allowVarargs = true; 3183 } 3184 } 3185 void checkForeach() { 3186 if (!allowForeach) { 3187 log.error(S.pos(), "foreach.not.supported.in.source", source.name); 3188 allowForeach = true; 3189 } 3190 } 3191 void checkStaticImports() { 3192 if (!allowStaticImport) { 3193 log.error(S.pos(), "static.import.not.supported.in.source", source.name); 3194 allowStaticImport = true; 3195 } 3196 } 3197 void checkAnnotations() { 3198 if (!allowAnnotations) { 3199 log.error(S.pos(), "annotations.not.supported.in.source", source.name); 3200 allowAnnotations = true; 3201 } 3202 } 3203 void checkTypeAnnotations() { 3204 if (!allowTypeAnnotations) { 3205 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name); 3206 allowTypeAnnotations = true; 3207 } 3208 } 3209 void checkDiamond() { 3210 if (!allowDiamond) { 3211 log.error(S.pos(), "diamond.not.supported.in.source", source.name); 3212 allowDiamond = true; 3213 } 3214 } 3215 void checkMulticatch() { 3216 if (!allowMulticatch) { 3217 log.error(S.pos(), "multicatch.not.supported.in.source", source.name); 3218 allowMulticatch = true; 3219 } 3220 } 3221 }