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