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()
 175                 : new EmptyEndPosTable();
 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 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                 if (!expr.hasTag(Tag.SELECT)) {
1179                     return illegal(typeAnnos.head.pos);
1180                 }
1181                 JCFieldAccess sel = (JCFieldAccess)expr;
1182 
1183                 if (sel.name != names._class) {
1184                     return illegal();
1185                 } else {
1186                     log.error(token.pos, "no.annotations.on.dot.class");
1187                     return expr;
1188                 }
1189             } else {
1190                 // Type annotations targeting a cast
1191                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
1192             }
1193             break;
1194         case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
1195             if (typeArgs != null) return illegal();
1196             if ((mode & EXPR) != 0 && peekToken(ARROW)) {
1197                 t = lambdaExpressionOrStatement(false, false, pos);
1198             } else {
1199                 t = toP(F.at(token.pos).Ident(ident()));
1200                 loop: while (true) {
1201                     pos = token.pos;
1202                     final List<JCAnnotation> annos = typeAnnotationsOpt();
1203 
1204                     // need to report an error later if LBRACKET is for array
1205                     // index access rather than array creation level
1206                     if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
1207                         return illegal(annos.head.pos);
1208 
1209                     switch (token.kind) {
1210                     case LBRACKET:
1211                         nextToken();
1212                         if (token.kind == RBRACKET) {
1213                             nextToken();
1214                             t = bracketsOpt(t);
1215                             t = toP(F.at(pos).TypeArray(t));
1216                             if (annos.nonEmpty()) {
1217                                 t = toP(F.at(pos).AnnotatedType(annos, t));
1218                             }
1219                             // .class is only allowed if there were no annotations
1220                             JCExpression nt = bracketsSuffix(t);
1221                             if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) {
1222                                 // t and nt are different if bracketsSuffix parsed a .class.
1223                                 // The check for nonEmpty covers the case when the whole array is annotated.
1224                                 // Helper method isAnnotated looks for annos deeply within t.
1225                                 syntaxError("no.annotations.on.dot.class");
1226                             }
1227                             t = nt;
1228                         } else {
1229                             if ((mode & EXPR) != 0) {
1230                                 mode = EXPR;
1231                                 JCExpression t1 = term();
1232                                 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1233                                 t = to(F.at(pos).Indexed(t, t1));
1234                             }
1235                             accept(RBRACKET);
1236                         }
1237                         break loop;
1238                     case LPAREN:
1239                         if ((mode & EXPR) != 0) {
1240                             mode = EXPR;
1241                             t = arguments(typeArgs, t);
1242                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
1243                             typeArgs = null;
1244                         }
1245                         break loop;
1246                     case DOT:
1247                         nextToken();
1248                         int oldmode = mode;
1249                         mode &= ~NOPARAMS;
1250                         typeArgs = typeArgumentsOpt(EXPR);
1251                         mode = oldmode;
1252                         if ((mode & EXPR) != 0) {
1253                             switch (token.kind) {
1254                             case CLASS:
1255                                 if (typeArgs != null) return illegal();
1256                                 mode = EXPR;
1257                                 t = to(F.at(pos).Select(t, names._class));
1258                                 nextToken();
1259                                 break loop;
1260                             case THIS:
1261                                 if (typeArgs != null) return illegal();
1262                                 mode = EXPR;
1263                                 t = to(F.at(pos).Select(t, names._this));
1264                                 nextToken();
1265                                 break loop;
1266                             case SUPER:
1267                                 mode = EXPR;
1268                                 t = to(F.at(pos).Select(t, names._super));
1269                                 t = superSuffix(typeArgs, t);
1270                                 typeArgs = null;
1271                                 break loop;
1272                             case NEW:
1273                                 if (typeArgs != null) return illegal();
1274                                 mode = EXPR;
1275                                 int pos1 = token.pos;
1276                                 nextToken();
1277                                 if (token.kind == LT) typeArgs = typeArguments(false);
1278                                 t = innerCreator(pos1, typeArgs, t);
1279                                 typeArgs = null;
1280                                 break loop;
1281                             }
1282                         }
1283 
1284                         List<JCAnnotation> tyannos = null;
1285                         if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1286                             tyannos = typeAnnotationsOpt();
1287                         }
1288                         // typeArgs saved for next loop iteration.
1289                         t = toP(F.at(pos).Select(t, ident()));
1290                         if (tyannos != null && tyannos.nonEmpty()) {
1291                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1292                         }
1293                         break;
1294                     case ELLIPSIS:
1295                         if (this.permitTypeAnnotationsPushBack) {
1296                             this.typeAnnotationsPushedBack = annos;
1297                         } else if (annos.nonEmpty()) {
1298                             // Don't return here -- error recovery attempt
1299                             illegal(annos.head.pos);
1300                         }
1301                         break loop;
1302                     case LT:
1303                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1304                             //this is an unbound method reference whose qualifier
1305                             //is a generic type i.e. A<S>::m
1306                             int pos1 = token.pos;
1307                             accept(LT);
1308                             ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
1309                             args.append(typeArgument());
1310                             while (token.kind == COMMA) {
1311                                 nextToken();
1312                                 args.append(typeArgument());
1313                             }
1314                             accept(GT);
1315                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1316                             checkGenerics();
1317                             while (token.kind == DOT) {
1318                                 nextToken();
1319                                 mode = TYPE;
1320                                 t = toP(F.at(token.pos).Select(t, ident()));
1321                                 t = typeArgumentsOpt(t);
1322                             }
1323                             t = bracketsOpt(t);
1324                             if (token.kind != COLCOL) {
1325                                 //method reference expected here
1326                                 t = illegal();
1327                             }
1328                             mode = EXPR;
1329                             return term3Rest(t, typeArgs);
1330                         }
1331                         break loop;
1332                     default:
1333                         break loop;
1334                     }
1335                 }
1336             }
1337             if (typeArgs != null) illegal();
1338             t = typeArgumentsOpt(t);
1339             break;
1340         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1341         case DOUBLE: case BOOLEAN:
1342             if (typeArgs != null) illegal();
1343             t = bracketsSuffix(bracketsOpt(basicType()));
1344             break;
1345         case VOID:
1346             if (typeArgs != null) illegal();
1347             if ((mode & EXPR) != 0) {
1348                 nextToken();
1349                 if (token.kind == DOT) {
1350                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
1351                     t = bracketsSuffix(ti);
1352                 } else {
1353                     return illegal(pos);
1354                 }
1355             } else {
1356                 // Support the corner case of myMethodHandle.<void>invoke() by passing
1357                 // a void type (like other primitive types) to the next phase.
1358                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1359                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
1360                 nextToken();
1361                 return ti;
1362                 //return illegal();
1363             }
1364             break;
1365         default:
1366             return illegal();
1367         }
1368         return term3Rest(t, typeArgs);
1369     }
1370 
1371     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1372         if (typeArgs != null) illegal();
1373         while (true) {
1374             int pos1 = token.pos;
1375             final List<JCAnnotation> annos = typeAnnotationsOpt();
1376 
1377             if (token.kind == LBRACKET) {
1378                 nextToken();
1379                 if ((mode & TYPE) != 0) {
1380                     int oldmode = mode;
1381                     mode = TYPE;
1382                     if (token.kind == RBRACKET) {
1383                         nextToken();
1384                         t = bracketsOpt(t);
1385                         t = toP(F.at(pos1).TypeArray(t));
1386                         if (token.kind == COLCOL) {
1387                             mode = EXPR;
1388                             continue;
1389                         }
1390                         if (annos.nonEmpty()) {
1391                             t = toP(F.at(pos1).AnnotatedType(annos, t));
1392                         }
1393                         return t;
1394                     }
1395                     mode = oldmode;
1396                 }
1397                 if ((mode & EXPR) != 0) {
1398                     mode = EXPR;
1399                     JCExpression t1 = term();
1400                     t = to(F.at(pos1).Indexed(t, t1));
1401                 }
1402                 accept(RBRACKET);
1403             } else if (token.kind == DOT) {
1404                 nextToken();
1405                 typeArgs = typeArgumentsOpt(EXPR);
1406                 if (token.kind == SUPER && (mode & EXPR) != 0) {
1407                     mode = EXPR;
1408                     t = to(F.at(pos1).Select(t, names._super));
1409                     nextToken();
1410                     t = arguments(typeArgs, t);
1411                     typeArgs = null;
1412                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1413                     if (typeArgs != null) return illegal();
1414                     mode = EXPR;
1415                     int pos2 = token.pos;
1416                     nextToken();
1417                     if (token.kind == LT) typeArgs = typeArguments(false);
1418                     t = innerCreator(pos2, typeArgs, t);
1419                     typeArgs = null;
1420                 } else {
1421                     List<JCAnnotation> tyannos = null;
1422                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1423                         // is the mode check needed?
1424                         tyannos = typeAnnotationsOpt();
1425                     }
1426                     t = toP(F.at(pos1).Select(t, ident()));
1427                     if (tyannos != null && tyannos.nonEmpty()) {
1428                         t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1429                     }
1430                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1431                     typeArgs = null;
1432                 }
1433             } else if ((mode & EXPR) != 0 && token.kind == COLCOL) {
1434                 mode = EXPR;
1435                 if (typeArgs != null) return illegal();
1436                 accept(COLCOL);
1437                 t = memberReferenceSuffix(pos1, t);
1438             } else {
1439                 if (!annos.isEmpty()) {
1440                     if (permitTypeAnnotationsPushBack)
1441                         typeAnnotationsPushedBack = annos;
1442                     else
1443                         return illegal(annos.head.pos);
1444                 }
1445                 break;
1446             }
1447         }
1448         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1449             mode = EXPR;
1450             t = to(F.at(token.pos).Unary(
1451                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1452             nextToken();
1453         }
1454         return toP(t);
1455     }
1456 
1457     /**
1458      * If we see an identifier followed by a '&lt;' it could be an unbound
1459      * method reference or a binary expression. To disambiguate, look for a
1460      * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
1461      */
1462     @SuppressWarnings("fallthrough")
1463     boolean isUnboundMemberRef() {
1464         int pos = 0, depth = 0;
1465         for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1466             switch (t.kind) {
1467                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1468                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1469                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1470                 case DOUBLE: case BOOLEAN: case CHAR:
1471                     break;
1472                 case LT:
1473                     depth++; break;
1474                 case GTGTGT:
1475                     depth--;
1476                 case GTGT:
1477                     depth--;
1478                 case GT:
1479                     depth--;
1480                     if (depth == 0) {
1481                         TokenKind nextKind = S.token(pos + 1).kind;
1482                         return
1483                             nextKind == TokenKind.DOT ||
1484                             nextKind == TokenKind.LBRACKET ||
1485                             nextKind == TokenKind.COLCOL;
1486                     }
1487                     break;
1488                 default:
1489                     return false;
1490             }
1491         }
1492     }
1493 
1494     /**
1495      * If we see an identifier followed by a '&lt;' it could be an unbound
1496      * method reference or a binary expression. To disambiguate, look for a
1497      * matching '&gt;' and see if the subsequent terminal is either '.' or '#'.
1498      */
1499     @SuppressWarnings("fallthrough")
1500     ParensResult analyzeParens() {
1501         int depth = 0;
1502         boolean type = false;
1503         outer: for (int lookahead = 0 ; ; lookahead++) {
1504             TokenKind tk = S.token(lookahead).kind;
1505             switch (tk) {
1506                 case EXTENDS: case SUPER: case COMMA:
1507                     type = true;
1508                 case QUES: case DOT: case AMP:
1509                     //skip
1510                     break;
1511                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1512                 case DOUBLE: case BOOLEAN: case CHAR:
1513                     if (peekToken(lookahead, RPAREN)) {
1514                         //Type, ')' -> cast
1515                         return ParensResult.CAST;
1516                     } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
1517                         //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
1518                         return ParensResult.EXPLICIT_LAMBDA;
1519                     }
1520                     break;
1521                 case LPAREN:
1522                     if (lookahead != 0) {
1523                         // '(' in a non-starting position -> parens
1524                         return ParensResult.PARENS;
1525                     } else if (peekToken(lookahead, RPAREN)) {
1526                         // '(', ')' -> explicit lambda
1527                         return ParensResult.EXPLICIT_LAMBDA;
1528                     }
1529                     break;
1530                 case RPAREN:
1531                     // if we have seen something that looks like a type,
1532                     // then it's a cast expression
1533                     if (type) return ParensResult.CAST;
1534                     // otherwise, disambiguate cast vs. parenthesized expression
1535                     // based on subsequent token.
1536                     switch (S.token(lookahead + 1).kind) {
1537                         /*case PLUSPLUS: case SUBSUB: */
1538                         case BANG: case TILDE:
1539                         case LPAREN: case THIS: case SUPER:
1540                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1541                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1542                         case TRUE: case FALSE: case NULL:
1543                         case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1544                         case BYTE: case SHORT: case CHAR: case INT:
1545                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1546                             return ParensResult.CAST;
1547                         default:
1548                             return ParensResult.PARENS;
1549                     }
1550                 case UNDERSCORE:
1551                 case ASSERT:
1552                 case ENUM:
1553                 case IDENTIFIER:
1554                     if (peekToken(lookahead, LAX_IDENTIFIER)) {
1555                         // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
1556                         return ParensResult.EXPLICIT_LAMBDA;
1557                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
1558                         // Identifier, ')' '->' -> implicit lambda
1559                         return ParensResult.IMPLICIT_LAMBDA;
1560                     }
1561                     break;
1562                 case FINAL:
1563                 case ELLIPSIS:
1564                     //those can only appear in explicit lambdas
1565                     return ParensResult.EXPLICIT_LAMBDA;
1566                 case MONKEYS_AT:
1567                     type = true;
1568                     lookahead += 1; //skip '@'
1569                     while (peekToken(lookahead, DOT)) {
1570                         lookahead += 2;
1571                     }
1572                     if (peekToken(lookahead, LPAREN)) {
1573                         lookahead++;
1574                         //skip annotation values
1575                         int nesting = 0;
1576                         for (; ; lookahead++) {
1577                             TokenKind tk2 = S.token(lookahead).kind;
1578                             switch (tk2) {
1579                                 case EOF:
1580                                     return ParensResult.PARENS;
1581                                 case LPAREN:
1582                                     nesting++;
1583                                     break;
1584                                 case RPAREN:
1585                                     nesting--;
1586                                     if (nesting == 0) {
1587                                         continue outer;
1588                                     }
1589                                 break;
1590                             }
1591                         }
1592                     }
1593                     break;
1594                 case LBRACKET:
1595                     if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
1596                         // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
1597                         return ParensResult.EXPLICIT_LAMBDA;
1598                     } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
1599                             peekToken(lookahead, RBRACKET, AMP)) {
1600                         // '[', ']', ')' -> cast
1601                         // '[', ']', '&' -> cast (intersection type)
1602                         return ParensResult.CAST;
1603                     } else if (peekToken(lookahead, RBRACKET)) {
1604                         //consume the ']' and skip
1605                         type = true;
1606                         lookahead++;
1607                         break;
1608                     } else {
1609                         return ParensResult.PARENS;
1610                     }
1611                 case LT:
1612                     depth++; break;
1613                 case GTGTGT:
1614                     depth--;
1615                 case GTGT:
1616                     depth--;
1617                 case GT:
1618                     depth--;
1619                     if (depth == 0) {
1620                         if (peekToken(lookahead, RPAREN) ||
1621                                 peekToken(lookahead, AMP)) {
1622                             // '>', ')' -> cast
1623                             // '>', '&' -> cast
1624                             return ParensResult.CAST;
1625                         } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1626                                 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
1627                                 peekToken(lookahead, ELLIPSIS)) {
1628                             // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1629                             // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1630                             // '>', '...' -> explicit lambda
1631                             return ParensResult.EXPLICIT_LAMBDA;
1632                         }
1633                         //it looks a type, but could still be (i) a cast to generic type,
1634                         //(ii) an unbound method reference or (iii) an explicit lambda
1635                         type = true;
1636                         break;
1637                     } else if (depth < 0) {
1638                         //unbalanced '<', '>' - not a generic type
1639                         return ParensResult.PARENS;
1640                     }
1641                     break;
1642                 default:
1643                     //this includes EOF
1644                     return ParensResult.PARENS;
1645             }
1646         }
1647     }
1648 
1649     /** Accepts all identifier-like tokens */
1650     Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
1651         public boolean accepts(TokenKind t) {
1652             return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
1653         }
1654     };
1655 
1656     enum ParensResult {
1657         CAST,
1658         EXPLICIT_LAMBDA,
1659         IMPLICIT_LAMBDA,
1660         PARENS;
1661     }
1662 
1663     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
1664         List<JCVariableDecl> params = explicitParams ?
1665                 formalParameters(true) :
1666                 implicitParameters(hasParens);
1667 
1668         return lambdaExpressionOrStatementRest(params, pos);
1669     }
1670 
1671     JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
1672         checkLambda();
1673         accept(ARROW);
1674 
1675         return token.kind == LBRACE ?
1676             lambdaStatement(args, pos, pos) :
1677             lambdaExpression(args, pos);
1678     }
1679 
1680     JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) {
1681         JCBlock block = block(pos2, 0);
1682         return toP(F.at(pos).Lambda(args, block));
1683     }
1684 
1685     JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
1686         JCTree expr = parseExpression();
1687         return toP(F.at(pos).Lambda(args, expr));
1688     }
1689 
1690     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1691      */
1692     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1693         nextToken();
1694         if (token.kind == LPAREN || typeArgs != null) {
1695             t = arguments(typeArgs, t);
1696         } else if (token.kind == COLCOL) {
1697             if (typeArgs != null) return illegal();
1698             t = memberReferenceSuffix(t);
1699         } else {
1700             int pos = token.pos;
1701             accept(DOT);
1702             typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1703             t = toP(F.at(pos).Select(t, ident()));
1704             t = argumentsOpt(typeArgs, t);
1705         }
1706         return t;
1707     }
1708 
1709     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1710      */
1711     JCPrimitiveTypeTree basicType() {
1712         JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
1713         nextToken();
1714         return t;
1715     }
1716 
1717     /** ArgumentsOpt = [ Arguments ]
1718      */
1719     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1720         if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
1721             mode = EXPR;
1722             return arguments(typeArgs, t);
1723         } else {
1724             return t;
1725         }
1726     }
1727 
1728     /** Arguments = "(" [Expression { COMMA Expression }] ")"
1729      */
1730     List<JCExpression> arguments() {
1731         ListBuffer<JCExpression> args = lb();
1732         if (token.kind == LPAREN) {
1733             nextToken();
1734             if (token.kind != RPAREN) {
1735                 args.append(parseExpression());
1736                 while (token.kind == COMMA) {
1737                     nextToken();
1738                     args.append(parseExpression());
1739                 }
1740             }
1741             accept(RPAREN);
1742         } else {
1743             syntaxError(token.pos, "expected", LPAREN);
1744         }
1745         return args.toList();
1746     }
1747 
1748     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1749         int pos = token.pos;
1750         List<JCExpression> args = arguments();
1751         return toP(F.at(pos).Apply(typeArgs, t, args));
1752     }
1753 
1754     /**  TypeArgumentsOpt = [ TypeArguments ]
1755      */
1756     JCExpression typeArgumentsOpt(JCExpression t) {
1757         if (token.kind == LT &&
1758             (mode & TYPE) != 0 &&
1759             (mode & NOPARAMS) == 0) {
1760             mode = TYPE;
1761             checkGenerics();
1762             return typeArguments(t, false);
1763         } else {
1764             return t;
1765         }
1766     }
1767     List<JCExpression> typeArgumentsOpt() {
1768         return typeArgumentsOpt(TYPE);
1769     }
1770 
1771     List<JCExpression> typeArgumentsOpt(int useMode) {
1772         if (token.kind == LT) {
1773             checkGenerics();
1774             if ((mode & useMode) == 0 ||
1775                 (mode & NOPARAMS) != 0) {
1776                 illegal();
1777             }
1778             mode = useMode;
1779             return typeArguments(false);
1780         }
1781         return null;
1782     }
1783 
1784     /**
1785      *  {@literal
1786      *  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1787      *  }
1788      */
1789     List<JCExpression> typeArguments(boolean diamondAllowed) {
1790         if (token.kind == LT) {
1791             nextToken();
1792             if (token.kind == GT && diamondAllowed) {
1793                 checkDiamond();
1794                 mode |= DIAMOND;
1795                 nextToken();
1796                 return List.nil();
1797             } else {
1798                 ListBuffer<JCExpression> args = ListBuffer.lb();
1799                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1800                 while (token.kind == COMMA) {
1801                     nextToken();
1802                     args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1803                 }
1804                 switch (token.kind) {
1805 
1806                 case GTGTGTEQ: case GTGTEQ: case GTEQ:
1807                 case GTGTGT: case GTGT:
1808                     token = S.split();
1809                     break;
1810                 case GT:
1811                     nextToken();
1812                     break;
1813                 default:
1814                     args.append(syntaxError(token.pos, "expected", GT));
1815                     break;
1816                 }
1817                 return args.toList();
1818             }
1819         } else {
1820             return List.<JCExpression>of(syntaxError(token.pos, "expected", LT));
1821         }
1822     }
1823 
1824     /**
1825      *  {@literal
1826      *  TypeArgument = Type
1827      *               | [Annotations] "?"
1828      *               | [Annotations] "?" EXTENDS Type {"&" Type}
1829      *               | [Annotations] "?" SUPER Type
1830      *  }
1831      */
1832     JCExpression typeArgument() {
1833         List<JCAnnotation> annotations = typeAnnotationsOpt();
1834         if (token.kind != QUES) return parseType(annotations);
1835         int pos = token.pos;
1836         nextToken();
1837         JCExpression result;
1838         if (token.kind == EXTENDS) {
1839             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
1840             nextToken();
1841             JCExpression bound = parseType();
1842             result = F.at(pos).Wildcard(t, bound);
1843         } else if (token.kind == SUPER) {
1844             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
1845             nextToken();
1846             JCExpression bound = parseType();
1847             result = F.at(pos).Wildcard(t, bound);
1848         } else if (LAX_IDENTIFIER.accepts(token.kind)) {
1849             //error recovery
1850             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1851             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1852             JCIdent id = toP(F.at(token.pos).Ident(ident()));
1853             JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1854             reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
1855             result = err;
1856         } else {
1857             TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
1858             result = toP(F.at(pos).Wildcard(t, null));
1859         }
1860         if (!annotations.isEmpty()) {
1861             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1862         }
1863         return result;
1864     }
1865 
1866     JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
1867         int pos = token.pos;
1868         List<JCExpression> args = typeArguments(diamondAllowed);
1869         return toP(F.at(pos).TypeApply(t, args));
1870     }
1871 
1872     /**
1873      * BracketsOpt = { [Annotations] "[" "]" }*
1874      *
1875      * <p>
1876      *
1877      * <code>annotations</code> is the list of annotations targeting
1878      * the expression <code>t</code>.
1879      */
1880     private JCExpression bracketsOpt(JCExpression t,
1881             List<JCAnnotation> annotations) {
1882         List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1883 
1884         if (token.kind == LBRACKET) {
1885             int pos = token.pos;
1886             nextToken();
1887             t = bracketsOptCont(t, pos, nextLevelAnnotations);
1888         } else if (!nextLevelAnnotations.isEmpty()) {
1889             if (permitTypeAnnotationsPushBack) {
1890                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1891             } else {
1892                 return illegal(nextLevelAnnotations.head.pos);
1893             }
1894         }
1895 
1896         if (!annotations.isEmpty()) {
1897             t = toP(F.at(token.pos).AnnotatedType(annotations, t));
1898         }
1899         return t;
1900     }
1901 
1902     /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ]
1903      */
1904     private JCExpression bracketsOpt(JCExpression t) {
1905         return bracketsOpt(t, List.<JCAnnotation>nil());
1906     }
1907 
1908     private JCExpression bracketsOptCont(JCExpression t, int pos,
1909             List<JCAnnotation> annotations) {
1910         accept(RBRACKET);
1911         t = bracketsOpt(t);
1912         t = toP(F.at(pos).TypeArray(t));
1913         if (annotations.nonEmpty()) {
1914             t = toP(F.at(pos).AnnotatedType(annotations, t));
1915         }
1916         return t;
1917     }
1918 
1919     /** BracketsSuffixExpr = "." CLASS
1920      *  BracketsSuffixType =
1921      */
1922     JCExpression bracketsSuffix(JCExpression t) {
1923         if ((mode & EXPR) != 0 && token.kind == DOT) {
1924             mode = EXPR;
1925             int pos = token.pos;
1926             nextToken();
1927             accept(CLASS);
1928             if (token.pos == endPosTable.errorEndPos) {
1929                 // error recovery
1930                 Name name;
1931                 if (LAX_IDENTIFIER.accepts(token.kind)) {
1932                     name = token.name();
1933                     nextToken();
1934                 } else {
1935                     name = names.error;
1936                 }
1937                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
1938             } else {
1939                 t = toP(F.at(pos).Select(t, names._class));
1940             }
1941         } else if ((mode & TYPE) != 0) {
1942             if (token.kind != COLCOL) {
1943                 mode = TYPE;
1944             }
1945         } else if (token.kind != COLCOL) {
1946             syntaxError(token.pos, "dot.class.expected");
1947         }
1948         return t;
1949     }
1950 
1951     /**
1952      * MemberReferenceSuffix = "::" [TypeArguments] Ident
1953      *                       | "::" [TypeArguments] "new"
1954      */
1955     JCExpression memberReferenceSuffix(JCExpression t) {
1956         int pos1 = token.pos;
1957         accept(COLCOL);
1958         return memberReferenceSuffix(pos1, t);
1959     }
1960 
1961     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
1962         checkMethodReferences();
1963         mode = EXPR;
1964         List<JCExpression> typeArgs = null;
1965         if (token.kind == LT) {
1966             typeArgs = typeArguments(false);
1967         }
1968         Name refName;
1969         ReferenceMode refMode;
1970         if (token.kind == NEW) {
1971             refMode = ReferenceMode.NEW;
1972             refName = names.init;
1973             nextToken();
1974         } else {
1975             refMode = ReferenceMode.INVOKE;
1976             refName = ident();
1977         }
1978         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
1979     }
1980 
1981     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1982      */
1983     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1984         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
1985 
1986         switch (token.kind) {
1987         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1988         case DOUBLE: case BOOLEAN:
1989             if (typeArgs == null) {
1990                 if (newAnnotations.isEmpty()) {
1991                     return arrayCreatorRest(newpos, basicType());
1992                 } else {
1993                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
1994                 }
1995             }
1996             break;
1997         default:
1998         }
1999         JCExpression t = qualident(true);
2000 
2001         // handle type annotations for non primitive arrays
2002         if (newAnnotations.nonEmpty()) {
2003             t = insertAnnotationsToMostInner(t, newAnnotations, false);
2004         }
2005 
2006         int oldmode = mode;
2007         mode = TYPE;
2008         boolean diamondFound = false;
2009         int lastTypeargsPos = -1;
2010         if (token.kind == LT) {
2011             checkGenerics();
2012             lastTypeargsPos = token.pos;
2013             t = typeArguments(t, true);
2014             diamondFound = (mode & DIAMOND) != 0;
2015         }
2016         while (token.kind == DOT) {
2017             if (diamondFound) {
2018                 //cannot select after a diamond
2019                 illegal();
2020             }
2021             int pos = token.pos;
2022             nextToken();
2023             List<JCAnnotation> tyannos = typeAnnotationsOpt();
2024             t = toP(F.at(pos).Select(t, ident()));
2025 
2026             if (tyannos != null && tyannos.nonEmpty()) {
2027                 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
2028             }
2029 
2030             if (token.kind == LT) {
2031                 lastTypeargsPos = token.pos;
2032                 checkGenerics();
2033                 t = typeArguments(t, true);
2034                 diamondFound = (mode & DIAMOND) != 0;
2035             }
2036         }
2037         mode = oldmode;
2038         if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
2039             JCExpression e = arrayCreatorRest(newpos, t);
2040             if (diamondFound) {
2041                 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
2042                 return toP(F.at(newpos).Erroneous(List.of(e)));
2043             }
2044             else if (typeArgs != null) {
2045                 int pos = newpos;
2046                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2047                     // note: this should always happen but we should
2048                     // not rely on this as the parser is continuously
2049                     // modified to improve error recovery.
2050                     pos = typeArgs.head.pos;
2051                 }
2052                 setErrorEndPos(S.prevToken().endPos);
2053                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2054                 reportSyntaxError(err, "cannot.create.array.with.type.arguments");
2055                 return toP(err);
2056             }
2057             return e;
2058         } else if (token.kind == LPAREN) {
2059             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
2060             if (newClass.def != null) {
2061                 assert newClass.def.mods.annotations.isEmpty();
2062                 if (newAnnotations.nonEmpty()) {
2063                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
2064                     newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
2065                 }
2066             }
2067             return newClass;
2068         } else {
2069             setErrorEndPos(token.pos);
2070             reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET);
2071             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
2072             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2073         }
2074     }
2075 
2076     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2077      */
2078     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2079         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2080 
2081         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2082 
2083         if (newAnnotations.nonEmpty()) {
2084             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2085         }
2086 
2087         if (token.kind == LT) {
2088             int oldmode = mode;
2089             checkGenerics();
2090             t = typeArguments(t, true);
2091             mode = oldmode;
2092         }
2093         return classCreatorRest(newpos, encl, typeArgs, t);
2094     }
2095 
2096     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2097      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2098      */
2099     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2100         List<JCAnnotation> annos = typeAnnotationsOpt();
2101 
2102         accept(LBRACKET);
2103         if (token.kind == RBRACKET) {
2104             accept(RBRACKET);
2105             elemtype = bracketsOpt(elemtype, annos);
2106             if (token.kind == LBRACE) {
2107                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2108                 if (annos.nonEmpty()) {
2109                     // when an array initializer is present then
2110                     // the parsed annotations should target the
2111                     // new array tree
2112                     // bracketsOpt inserts the annotation in
2113                     // elemtype, and it needs to be corrected
2114                     //
2115                     JCAnnotatedType annotated = (JCAnnotatedType)elemtype;
2116                     assert annotated.annotations == annos;
2117                     na.annotations = annotated.annotations;
2118                     na.elemtype = annotated.underlyingType;
2119                 }
2120                 return na;
2121             } else {
2122                 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
2123                 return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
2124             }
2125         } else {
2126             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
2127 
2128             // maintain array dimension type annotations
2129             ListBuffer<List<JCAnnotation>> dimAnnotations = ListBuffer.lb();
2130             dimAnnotations.append(annos);
2131 
2132             dims.append(parseExpression());
2133             accept(RBRACKET);
2134             while (token.kind == LBRACKET
2135                     || token.kind == MONKEYS_AT) {
2136                 List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt();
2137                 int pos = token.pos;
2138                 nextToken();
2139                 if (token.kind == RBRACKET) {
2140                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2141                 } else {
2142                     if (token.kind == RBRACKET) { // no dimension
2143                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2144                     } else {
2145                         dimAnnotations.append(maybeDimAnnos);
2146                         dims.append(parseExpression());
2147                         accept(RBRACKET);
2148                     }
2149                 }
2150             }
2151 
2152             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
2153             na.dimAnnotations = dimAnnotations.toList();
2154             return na;
2155         }
2156     }
2157 
2158     /** ClassCreatorRest = Arguments [ClassBody]
2159      */
2160     JCNewClass classCreatorRest(int newpos,
2161                                   JCExpression encl,
2162                                   List<JCExpression> typeArgs,
2163                                   JCExpression t)
2164     {
2165         List<JCExpression> args = arguments();
2166         JCClassDecl body = null;
2167         if (token.kind == LBRACE) {
2168             int pos = token.pos;
2169             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2170             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2171             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2172         }
2173         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2174     }
2175 
2176     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2177      */
2178     JCExpression arrayInitializer(int newpos, JCExpression t) {
2179         accept(LBRACE);
2180         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
2181         if (token.kind == COMMA) {
2182             nextToken();
2183         } else if (token.kind != RBRACE) {
2184             elems.append(variableInitializer());
2185             while (token.kind == COMMA) {
2186                 nextToken();
2187                 if (token.kind == RBRACE) break;
2188                 elems.append(variableInitializer());
2189             }
2190         }
2191         accept(RBRACE);
2192         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
2193     }
2194 
2195     /** VariableInitializer = ArrayInitializer | Expression
2196      */
2197     public JCExpression variableInitializer() {
2198         return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
2199     }
2200 
2201     /** ParExpression = "(" Expression ")"
2202      */
2203     JCExpression parExpression() {
2204         int pos = token.pos;
2205         accept(LPAREN);
2206         JCExpression t = parseExpression();
2207         accept(RPAREN);
2208         return toP(F.at(pos).Parens(t));
2209     }
2210 
2211     /** Block = "{" BlockStatements "}"
2212      */
2213     JCBlock block(int pos, long flags) {
2214         accept(LBRACE);
2215         List<JCStatement> stats = blockStatements();
2216         JCBlock t = F.at(pos).Block(flags, stats);
2217         while (token.kind == CASE || token.kind == DEFAULT) {
2218             syntaxError("orphaned", token.kind);
2219             switchBlockStatementGroups();
2220         }
2221         // the Block node has a field "endpos" for first char of last token, which is
2222         // usually but not necessarily the last char of the last token.
2223         t.endpos = token.pos;
2224         accept(RBRACE);
2225         return toP(t);
2226     }
2227 
2228     public JCBlock block() {
2229         return block(token.pos, 0);
2230     }
2231 
2232     /** BlockStatements = { BlockStatement }
2233      *  BlockStatement  = LocalVariableDeclarationStatement
2234      *                  | ClassOrInterfaceOrEnumDeclaration
2235      *                  | [Ident ":"] Statement
2236      *  LocalVariableDeclarationStatement
2237      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
2238      */
2239     @SuppressWarnings("fallthrough")
2240     List<JCStatement> blockStatements() {
2241         //todo: skip to anchor on error(?)
2242         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
2243         while (true) {
2244             List<JCStatement> stat = blockStatement();
2245             if (stat.isEmpty()) {
2246                 return stats.toList();
2247             } else {
2248                 if (token.pos <= endPosTable.errorEndPos) {
2249                     skip(false, true, true, true);
2250                 }
2251                 stats.addAll(stat);
2252             }
2253         }
2254     }
2255 
2256     /*
2257      * This method parses a statement treating it as a block, relaxing the
2258      * JLS restrictions, allows us to parse more faulty code, doing so
2259      * enables us to provide better and accurate diagnostics to the user.
2260      */
2261     JCStatement parseStatementAsBlock() {
2262         int pos = token.pos;
2263         List<JCStatement> stats = blockStatement();
2264         if (stats.isEmpty()) {
2265             JCErroneous e = F.at(pos).Erroneous();
2266             error(e, "illegal.start.of.stmt");
2267             return F.at(pos).Exec(e);
2268         } else {
2269             JCStatement first = stats.head;
2270             String error = null;
2271             switch (first.getTag()) {
2272             case CLASSDEF:
2273                 error = "class.not.allowed";
2274                 break;
2275             case VARDEF:
2276                 error = "variable.not.allowed";
2277                 break;
2278             }
2279             if (error != null) {
2280                 error(first, error);
2281                 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2282                 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2283             }
2284             return first;
2285         }
2286     }
2287 
2288     @SuppressWarnings("fallthrough")
2289     List<JCStatement> blockStatement() {
2290         //todo: skip to anchor on error(?)
2291         int pos = token.pos;
2292         switch (token.kind) {
2293         case RBRACE: case CASE: case DEFAULT: case EOF:
2294             return List.nil();
2295         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2296         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2297         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2298             return List.of(parseStatement());
2299         case MONKEYS_AT:
2300         case FINAL: {
2301             Comment dc = token.comment(CommentStyle.JAVADOC);
2302             JCModifiers mods = modifiersOpt();
2303             if (token.kind == INTERFACE ||
2304                 token.kind == CLASS ||
2305                 allowEnums && token.kind == ENUM) {
2306                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2307             } else {
2308                 JCExpression t = parseType();
2309                 ListBuffer<JCStatement> stats =
2310                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2311                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2312                 storeEnd(stats.last(), token.endPos);
2313                 accept(SEMI);
2314                 return stats.toList();
2315             }
2316         }
2317         case ABSTRACT: case STRICTFP: {
2318             Comment dc = token.comment(CommentStyle.JAVADOC);
2319             JCModifiers mods = modifiersOpt();
2320             return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2321         }
2322         case INTERFACE:
2323         case CLASS:
2324             Comment dc = token.comment(CommentStyle.JAVADOC);
2325             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2326         case ENUM:
2327         case ASSERT:
2328             if (allowEnums && token.kind == ENUM) {
2329                 error(token.pos, "local.enum");
2330                 dc = token.comment(CommentStyle.JAVADOC);
2331                 return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2332             } else if (allowAsserts && token.kind == ASSERT) {
2333                 return List.of(parseStatement());
2334             }
2335             /* fall through to default */
2336         default:
2337             Token prevToken = token;
2338             JCExpression t = term(EXPR | TYPE);
2339             if (token.kind == COLON && t.hasTag(IDENT)) {
2340                 nextToken();
2341                 JCStatement stat = parseStatement();
2342                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
2343             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2344                 pos = token.pos;
2345                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2346                 F.at(pos);
2347                 ListBuffer<JCStatement> stats =
2348                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2349                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2350                 storeEnd(stats.last(), token.endPos);
2351                 accept(SEMI);
2352                 return stats.toList();
2353             } else {
2354                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2355                 JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
2356                 accept(SEMI);
2357                 return List.<JCStatement>of(expr);
2358             }
2359         }
2360     }
2361 
2362     /** Statement =
2363      *       Block
2364      *     | IF ParExpression Statement [ELSE Statement]
2365      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
2366      *     | FOR "(" FormalParameter : Expression ")" Statement
2367      *     | WHILE ParExpression Statement
2368      *     | DO Statement WHILE ParExpression ";"
2369      *     | TRY Block ( Catches | [Catches] FinallyPart )
2370      *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
2371      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
2372      *     | SYNCHRONIZED ParExpression Block
2373      *     | RETURN [Expression] ";"
2374      *     | THROW Expression ";"
2375      *     | BREAK [Ident] ";"
2376      *     | CONTINUE [Ident] ";"
2377      *     | ASSERT Expression [ ":" Expression ] ";"
2378      *     | ";"
2379      *     | ExpressionStatement
2380      *     | Ident ":" Statement
2381      */
2382     @SuppressWarnings("fallthrough")
2383     public JCStatement parseStatement() {
2384         int pos = token.pos;
2385         switch (token.kind) {
2386         case LBRACE:
2387             return block();
2388         case IF: {
2389             nextToken();
2390             JCExpression cond = parExpression();
2391             JCStatement thenpart = parseStatementAsBlock();
2392             JCStatement elsepart = null;
2393             if (token.kind == ELSE) {
2394                 nextToken();
2395                 elsepart = parseStatementAsBlock();
2396             }
2397             return F.at(pos).If(cond, thenpart, elsepart);
2398         }
2399         case FOR: {
2400             nextToken();
2401             accept(LPAREN);
2402             List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
2403             if (inits.length() == 1 &&
2404                 inits.head.hasTag(VARDEF) &&
2405                 ((JCVariableDecl) inits.head).init == null &&
2406                 token.kind == COLON) {
2407                 checkForeach();
2408                 JCVariableDecl var = (JCVariableDecl)inits.head;
2409                 accept(COLON);
2410                 JCExpression expr = parseExpression();
2411                 accept(RPAREN);
2412                 JCStatement body = parseStatementAsBlock();
2413                 return F.at(pos).ForeachLoop(var, expr, body);
2414             } else {
2415                 accept(SEMI);
2416                 JCExpression cond = token.kind == SEMI ? null : parseExpression();
2417                 accept(SEMI);
2418                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
2419                 accept(RPAREN);
2420                 JCStatement body = parseStatementAsBlock();
2421                 return F.at(pos).ForLoop(inits, cond, steps, body);
2422             }
2423         }
2424         case WHILE: {
2425             nextToken();
2426             JCExpression cond = parExpression();
2427             JCStatement body = parseStatementAsBlock();
2428             return F.at(pos).WhileLoop(cond, body);
2429         }
2430         case DO: {
2431             nextToken();
2432             JCStatement body = parseStatementAsBlock();
2433             accept(WHILE);
2434             JCExpression cond = parExpression();
2435             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
2436             accept(SEMI);
2437             return t;
2438         }
2439         case TRY: {
2440             nextToken();
2441             List<JCTree> resources = List.<JCTree>nil();
2442             if (token.kind == LPAREN) {
2443                 checkTryWithResources();
2444                 nextToken();
2445                 resources = resources();
2446                 accept(RPAREN);
2447             }
2448             JCBlock body = block();
2449             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
2450             JCBlock finalizer = null;
2451             if (token.kind == CATCH || token.kind == FINALLY) {
2452                 while (token.kind == CATCH) catchers.append(catchClause());
2453                 if (token.kind == FINALLY) {
2454                     nextToken();
2455                     finalizer = block();
2456                 }
2457             } else {
2458                 if (allowTWR) {
2459                     if (resources.isEmpty())
2460                         error(pos, "try.without.catch.finally.or.resource.decls");
2461                 } else
2462                     error(pos, "try.without.catch.or.finally");
2463             }
2464             return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
2465         }
2466         case SWITCH: {
2467             nextToken();
2468             JCExpression selector = parExpression();
2469             accept(LBRACE);
2470             List<JCCase> cases = switchBlockStatementGroups();
2471             JCSwitch t = to(F.at(pos).Switch(selector, cases));
2472             accept(RBRACE);
2473             return t;
2474         }
2475         case SYNCHRONIZED: {
2476             nextToken();
2477             JCExpression lock = parExpression();
2478             JCBlock body = block();
2479             return F.at(pos).Synchronized(lock, body);
2480         }
2481         case RETURN: {
2482             nextToken();
2483             JCExpression result = token.kind == SEMI ? null : parseExpression();
2484             JCReturn t = to(F.at(pos).Return(result));
2485             accept(SEMI);
2486             return t;
2487         }
2488         case THROW: {
2489             nextToken();
2490             JCExpression exc = parseExpression();
2491             JCThrow t = to(F.at(pos).Throw(exc));
2492             accept(SEMI);
2493             return t;
2494         }
2495         case BREAK: {
2496             nextToken();
2497             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2498             JCBreak t = to(F.at(pos).Break(label));
2499             accept(SEMI);
2500             return t;
2501         }
2502         case CONTINUE: {
2503             nextToken();
2504             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2505             JCContinue t =  to(F.at(pos).Continue(label));
2506             accept(SEMI);
2507             return t;
2508         }
2509         case SEMI:
2510             nextToken();
2511             return toP(F.at(pos).Skip());
2512         case ELSE:
2513             int elsePos = token.pos;
2514             nextToken();
2515             return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
2516         case FINALLY:
2517             int finallyPos = token.pos;
2518             nextToken();
2519             return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
2520         case CATCH:
2521             return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
2522         case ASSERT: {
2523             if (allowAsserts && token.kind == ASSERT) {
2524                 nextToken();
2525                 JCExpression assertion = parseExpression();
2526                 JCExpression message = null;
2527                 if (token.kind == COLON) {
2528                     nextToken();
2529                     message = parseExpression();
2530                 }
2531                 JCAssert t = to(F.at(pos).Assert(assertion, message));
2532                 accept(SEMI);
2533                 return t;
2534             }
2535             /* else fall through to default case */
2536         }
2537         case ENUM:
2538         default:
2539             Token prevToken = token;
2540             JCExpression expr = parseExpression();
2541             if (token.kind == COLON && expr.hasTag(IDENT)) {
2542                 nextToken();
2543                 JCStatement stat = parseStatement();
2544                 return F.at(pos).Labelled(prevToken.name(), stat);
2545             } else {
2546                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2547                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
2548                 accept(SEMI);
2549                 return stat;
2550             }
2551         }
2552     }
2553 
2554     private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
2555         int errPos = S.errPos();
2556         JCTree stm = action.doRecover(this);
2557         S.errPos(errPos);
2558         return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
2559     }
2560 
2561     /** CatchClause     = CATCH "(" FormalParameter ")" Block
2562      * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
2563      */
2564     protected JCCatch catchClause() {
2565         int pos = token.pos;
2566         accept(CATCH);
2567         accept(LPAREN);
2568         JCModifiers mods = optFinal(Flags.PARAMETER);
2569         List<JCExpression> catchTypes = catchTypes();
2570         JCExpression paramType = catchTypes.size() > 1 ?
2571                 toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
2572                 catchTypes.head;
2573         JCVariableDecl formal = variableDeclaratorId(mods, paramType);
2574         accept(RPAREN);
2575         JCBlock body = block();
2576         return F.at(pos).Catch(formal, body);
2577     }
2578 
2579     List<JCExpression> catchTypes() {
2580         ListBuffer<JCExpression> catchTypes = ListBuffer.lb();
2581         catchTypes.add(parseType());
2582         while (token.kind == BAR) {
2583             checkMulticatch();
2584             nextToken();
2585             // Instead of qualident this is now parseType.
2586             // But would that allow too much, e.g. arrays or generics?
2587             catchTypes.add(parseType());
2588         }
2589         return catchTypes.toList();
2590     }
2591 
2592     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2593      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2594      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2595      */
2596     List<JCCase> switchBlockStatementGroups() {
2597         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2598         while (true) {
2599             int pos = token.pos;
2600             switch (token.kind) {
2601             case CASE:
2602             case DEFAULT:
2603                 cases.append(switchBlockStatementGroup());
2604                 break;
2605             case RBRACE: case EOF:
2606                 return cases.toList();
2607             default:
2608                 nextToken(); // to ensure progress
2609                 syntaxError(pos, "expected3",
2610                     CASE, DEFAULT, RBRACE);
2611             }
2612         }
2613     }
2614 
2615     protected JCCase switchBlockStatementGroup() {
2616         int pos = token.pos;
2617         List<JCStatement> stats;
2618         JCCase c;
2619         switch (token.kind) {
2620         case CASE:
2621             nextToken();
2622             JCExpression pat = parseExpression();
2623             accept(COLON);
2624             stats = blockStatements();
2625             c = F.at(pos).Case(pat, stats);
2626             if (stats.isEmpty())
2627                 storeEnd(c, S.prevToken().endPos);
2628             return c;
2629         case DEFAULT:
2630             nextToken();
2631             accept(COLON);
2632             stats = blockStatements();
2633             c = F.at(pos).Case(null, stats);
2634             if (stats.isEmpty())
2635                 storeEnd(c, S.prevToken().endPos);
2636             return c;
2637         }
2638         throw new AssertionError("should not reach here");
2639     }
2640 
2641     /** MoreStatementExpressions = { COMMA StatementExpression }
2642      */
2643     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2644                                                                     JCExpression first,
2645                                                                     T stats) {
2646         // This Exec is a "StatementExpression"; it subsumes no terminating token
2647         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2648         while (token.kind == COMMA) {
2649             nextToken();
2650             pos = token.pos;
2651             JCExpression t = parseExpression();
2652             // This Exec is a "StatementExpression"; it subsumes no terminating token
2653             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2654         }
2655         return stats;
2656     }
2657 
2658     /** ForInit = StatementExpression MoreStatementExpressions
2659      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2660      */
2661     List<JCStatement> forInit() {
2662         ListBuffer<JCStatement> stats = lb();
2663         int pos = token.pos;
2664         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
2665             return variableDeclarators(optFinal(0), parseType(), stats).toList();
2666         } else {
2667             JCExpression t = term(EXPR | TYPE);
2668             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2669                 return variableDeclarators(modifiersOpt(), t, stats).toList();
2670             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
2671                 error(pos, "bad.initializer", "for-loop");
2672                 return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
2673             } else {
2674                 return moreStatementExpressions(pos, t, stats).toList();
2675             }
2676         }
2677     }
2678 
2679     /** ForUpdate = StatementExpression MoreStatementExpressions
2680      */
2681     List<JCExpressionStatement> forUpdate() {
2682         return moreStatementExpressions(token.pos,
2683                                         parseExpression(),
2684                                         new ListBuffer<JCExpressionStatement>()).toList();
2685     }
2686 
2687     /** AnnotationsOpt = { '@' Annotation }
2688      *
2689      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2690      */
2691     List<JCAnnotation> annotationsOpt(Tag kind) {
2692         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
2693         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2694         int prevmode = mode;
2695         while (token.kind == MONKEYS_AT) {
2696             int pos = token.pos;
2697             nextToken();
2698             buf.append(annotation(pos, kind));
2699         }
2700         lastmode = mode;
2701         mode = prevmode;
2702         List<JCAnnotation> annotations = buf.toList();
2703 
2704         return annotations;
2705     }
2706 
2707     List<JCAnnotation> typeAnnotationsOpt() {
2708         List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
2709         return annotations;
2710     }
2711 
2712     /** ModifiersOpt = { Modifier }
2713      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2714      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2715      *           | "@" Annotation
2716      */
2717     JCModifiers modifiersOpt() {
2718         return modifiersOpt(null);
2719     }
2720     protected JCModifiers modifiersOpt(JCModifiers partial) {
2721         long flags;
2722         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2723         int pos;
2724         if (partial == null) {
2725             flags = 0;
2726             pos = token.pos;
2727         } else {
2728             flags = partial.flags;
2729             annotations.appendList(partial.annotations);
2730             pos = partial.pos;
2731         }
2732         if (token.deprecatedFlag()) {
2733             flags |= Flags.DEPRECATED;
2734         }
2735         int lastPos;
2736     loop:
2737         while (true) {
2738             long flag;
2739             switch (token.kind) {
2740             case PRIVATE     : flag = Flags.PRIVATE; break;
2741             case PROTECTED   : flag = Flags.PROTECTED; break;
2742             case PUBLIC      : flag = Flags.PUBLIC; break;
2743             case STATIC      : flag = Flags.STATIC; break;
2744             case TRANSIENT   : flag = Flags.TRANSIENT; break;
2745             case FINAL       : flag = Flags.FINAL; break;
2746             case ABSTRACT    : flag = Flags.ABSTRACT; break;
2747             case NATIVE      : flag = Flags.NATIVE; break;
2748             case VOLATILE    : flag = Flags.VOLATILE; break;
2749             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2750             case STRICTFP    : flag = Flags.STRICTFP; break;
2751             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2752             case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
2753             case ERROR       : flag = 0; nextToken(); break;
2754             default: break loop;
2755             }
2756             if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
2757             lastPos = token.pos;
2758             nextToken();
2759             if (flag == Flags.ANNOTATION) {
2760                 checkAnnotations();
2761                 if (token.kind != INTERFACE) {
2762                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
2763                     // if first modifier is an annotation, set pos to annotation's.
2764                     if (flags == 0 && annotations.isEmpty())
2765                         pos = ann.pos;
2766                     annotations.append(ann);
2767                     flag = 0;
2768                 }
2769             }
2770             flags |= flag;
2771         }
2772         switch (token.kind) {
2773         case ENUM: flags |= Flags.ENUM; break;
2774         case INTERFACE: flags |= Flags.INTERFACE; break;
2775         default: break;
2776         }
2777 
2778         /* A modifiers tree with no modifier tokens or annotations
2779          * has no text position. */
2780         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
2781             pos = Position.NOPOS;
2782 
2783         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2784         if (pos != Position.NOPOS)
2785             storeEnd(mods, S.prevToken().endPos);
2786         return mods;
2787     }
2788 
2789     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2790      *
2791      * @param pos position of "@" token
2792      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2793      */
2794     JCAnnotation annotation(int pos, Tag kind) {
2795         // accept(AT); // AT consumed by caller
2796         checkAnnotations();
2797         if (kind == Tag.TYPE_ANNOTATION) {
2798             checkTypeAnnotations();
2799         }
2800         JCTree ident = qualident(false);
2801         List<JCExpression> fieldValues = annotationFieldValuesOpt();
2802         JCAnnotation ann;
2803         if (kind == Tag.ANNOTATION) {
2804             ann = F.at(pos).Annotation(ident, fieldValues);
2805         } else if (kind == Tag.TYPE_ANNOTATION) {
2806             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2807         } else {
2808             throw new AssertionError("Unhandled annotation kind: " + kind);
2809         }
2810 
2811         storeEnd(ann, S.prevToken().endPos);
2812         return ann;
2813     }
2814 
2815     List<JCExpression> annotationFieldValuesOpt() {
2816         return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2817     }
2818 
2819     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2820     List<JCExpression> annotationFieldValues() {
2821         accept(LPAREN);
2822         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2823         if (token.kind != RPAREN) {
2824             buf.append(annotationFieldValue());
2825             while (token.kind == COMMA) {
2826                 nextToken();
2827                 buf.append(annotationFieldValue());
2828             }
2829         }
2830         accept(RPAREN);
2831         return buf.toList();
2832     }
2833 
2834     /** AnnotationFieldValue    = AnnotationValue
2835      *                          | Identifier "=" AnnotationValue
2836      */
2837     JCExpression annotationFieldValue() {
2838         if (token.kind == IDENTIFIER) {
2839             mode = EXPR;
2840             JCExpression t1 = term1();
2841             if (t1.hasTag(IDENT) && token.kind == EQ) {
2842                 int pos = token.pos;
2843                 accept(EQ);
2844                 JCExpression v = annotationValue();
2845                 return toP(F.at(pos).Assign(t1, v));
2846             } else {
2847                 return t1;
2848             }
2849         }
2850         return annotationValue();
2851     }
2852 
2853     /* AnnotationValue          = ConditionalExpression
2854      *                          | Annotation
2855      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2856      */
2857     JCExpression annotationValue() {
2858         int pos;
2859         switch (token.kind) {
2860         case MONKEYS_AT:
2861             pos = token.pos;
2862             nextToken();
2863             return annotation(pos, Tag.ANNOTATION);
2864         case LBRACE:
2865             pos = token.pos;
2866             accept(LBRACE);
2867             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2868             if (token.kind != RBRACE) {
2869                 buf.append(annotationValue());
2870                 while (token.kind == COMMA) {
2871                     nextToken();
2872                     if (token.kind == RBRACE) break;
2873                     buf.append(annotationValue());
2874                 }
2875             }
2876             accept(RBRACE);
2877             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2878         default:
2879             mode = EXPR;
2880             return term1();
2881         }
2882     }
2883 
2884     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2885      */
2886     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2887                                                                          JCExpression type,
2888                                                                          T vdefs)
2889     {
2890         return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
2891     }
2892 
2893     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2894      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2895      *
2896      *  @param reqInit  Is an initializer always required?
2897      *  @param dc       The documentation comment for the variable declarations, or null.
2898      */
2899     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2900                                                                      JCModifiers mods,
2901                                                                      JCExpression type,
2902                                                                      Name name,
2903                                                                      boolean reqInit,
2904                                                                      Comment dc,
2905                                                                      T vdefs)
2906     {
2907         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2908         while (token.kind == COMMA) {
2909             // All but last of multiple declarators subsume a comma
2910             storeEnd((JCTree)vdefs.last(), token.endPos);
2911             nextToken();
2912             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2913         }
2914         return vdefs;
2915     }
2916 
2917     /** VariableDeclarator = Ident VariableDeclaratorRest
2918      *  ConstantDeclarator = Ident ConstantDeclaratorRest
2919      */
2920     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
2921         return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
2922     }
2923 
2924     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2925      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2926      *
2927      *  @param reqInit  Is an initializer always required?
2928      *  @param dc       The documentation comment for the variable declarations, or null.
2929      */
2930     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2931                                   boolean reqInit, Comment dc) {
2932         type = bracketsOpt(type);
2933         JCExpression init = null;
2934         if (token.kind == EQ) {
2935             nextToken();
2936             init = variableInitializer();
2937         }
2938         else if (reqInit) syntaxError(token.pos, "expected", EQ);
2939         JCVariableDecl result =
2940             toP(F.at(pos).VarDef(mods, name, type, init));
2941         attach(result, dc);
2942         return result;
2943     }
2944 
2945     /** VariableDeclaratorId = Ident BracketsOpt
2946      */
2947     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2948         return variableDeclaratorId(mods, type, false);
2949     }
2950     //where
2951     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
2952         int pos = token.pos;
2953         Name name;
2954         if (lambdaParameter && token.kind == UNDERSCORE) {
2955             syntaxError(pos, "expected", IDENTIFIER);
2956             name = token.name();
2957         } else {
2958             name = ident();
2959         }
2960         if ((mods.flags & Flags.VARARGS) != 0 &&
2961                 token.kind == LBRACKET) {
2962             log.error(token.pos, "varargs.and.old.array.syntax");
2963         }
2964         type = bracketsOpt(type);
2965         return toP(F.at(pos).VarDef(mods, name, type, null));
2966     }
2967 
2968     /** Resources = Resource { ";" Resources }
2969      */
2970     List<JCTree> resources() {
2971         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2972         defs.append(resource());
2973         while (token.kind == SEMI) {
2974             // All but last of multiple declarators must subsume a semicolon
2975             storeEnd(defs.last(), token.endPos);
2976             int semiColonPos = token.pos;
2977             nextToken();
2978             if (token.kind == RPAREN) { // Optional trailing semicolon
2979                                        // after last resource
2980                 break;
2981             }
2982             defs.append(resource());
2983         }
2984         return defs.toList();
2985     }
2986 
2987     /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
2988      */
2989     protected JCTree resource() {
2990         JCModifiers optFinal = optFinal(Flags.FINAL);
2991         JCExpression type = parseType();
2992         int pos = token.pos;
2993         Name ident = ident();
2994         return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
2995     }
2996 
2997     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2998      */
2999     public JCTree.JCCompilationUnit parseCompilationUnit() {
3000         Token firstToken = token;
3001         JCExpression pid = null;
3002         JCModifiers mods = null;
3003         boolean consumedToplevelDoc = false;
3004         boolean seenImport = false;
3005         boolean seenPackage = false;
3006         List<JCAnnotation> packageAnnotations = List.nil();
3007         if (token.kind == MONKEYS_AT)
3008             mods = modifiersOpt();
3009 
3010         if (token.kind == PACKAGE) {
3011             seenPackage = true;
3012             if (mods != null) {
3013                 checkNoMods(mods.flags);
3014                 packageAnnotations = mods.annotations;
3015                 mods = null;
3016             }
3017             nextToken();
3018             pid = qualident(false);
3019             accept(SEMI);
3020         }
3021         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
3022         boolean checkForImports = true;
3023         boolean firstTypeDecl = true;
3024         while (token.kind != EOF) {
3025             if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
3026                 // error recovery
3027                 skip(checkForImports, false, false, false);
3028                 if (token.kind == EOF)
3029                     break;
3030             }
3031             if (checkForImports && mods == null && token.kind == IMPORT) {
3032                 seenImport = true;
3033                 defs.append(importDeclaration());
3034             } else {
3035                 Comment docComment = token.comment(CommentStyle.JAVADOC);
3036                 if (firstTypeDecl && !seenImport && !seenPackage) {
3037                     docComment = firstToken.comment(CommentStyle.JAVADOC);
3038                     consumedToplevelDoc = true;
3039                 }
3040                 JCTree def = typeDeclaration(mods, docComment);
3041                 if (def instanceof JCExpressionStatement)
3042                     def = ((JCExpressionStatement)def).expr;
3043                 defs.append(def);
3044                 if (def instanceof JCClassDecl)
3045                     checkForImports = false;
3046                 mods = null;
3047                 firstTypeDecl = false;
3048             }
3049         }
3050         JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
3051         if (!consumedToplevelDoc)
3052             attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
3053         if (defs.isEmpty())
3054             storeEnd(toplevel, S.prevToken().endPos);
3055         if (keepDocComments)
3056             toplevel.docComments = docComments;
3057         if (keepLineMap)
3058             toplevel.lineMap = S.getLineMap();
3059         toplevel.endPositions = this.endPosTable;
3060         return toplevel;
3061     }
3062 
3063     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
3064      */
3065     JCTree importDeclaration() {
3066         int pos = token.pos;
3067         nextToken();
3068         boolean importStatic = false;
3069         if (token.kind == STATIC) {
3070             checkStaticImports();
3071             importStatic = true;
3072             nextToken();
3073         }
3074         JCExpression pid = toP(F.at(token.pos).Ident(ident()));
3075         do {
3076             int pos1 = token.pos;
3077             accept(DOT);
3078             if (token.kind == STAR) {
3079                 pid = to(F.at(pos1).Select(pid, names.asterisk));
3080                 nextToken();
3081                 break;
3082             } else {
3083                 pid = toP(F.at(pos1).Select(pid, ident()));
3084             }
3085         } while (token.kind == DOT);
3086         accept(SEMI);
3087         return toP(F.at(pos).Import(pid, importStatic));
3088     }
3089 
3090     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3091      *                  | ";"
3092      */
3093     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3094         int pos = token.pos;
3095         if (mods == null && token.kind == SEMI) {
3096             nextToken();
3097             return toP(F.at(pos).Skip());
3098         } else {
3099             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3100         }
3101     }
3102 
3103     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3104      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3105      *  @param mods     Any modifiers starting the class or interface declaration
3106      *  @param dc       The documentation comment for the class, or null.
3107      */
3108     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3109         if (token.kind == CLASS) {
3110             return classDeclaration(mods, dc);
3111         } else if (token.kind == INTERFACE) {
3112             return interfaceDeclaration(mods, dc);
3113         } else if (allowEnums) {
3114             if (token.kind == ENUM) {
3115                 return enumDeclaration(mods, dc);
3116             } else {
3117                 int pos = token.pos;
3118                 List<JCTree> errs;
3119                 if (LAX_IDENTIFIER.accepts(token.kind)) {
3120                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
3121                     setErrorEndPos(token.pos);
3122                 } else {
3123                     errs = List.<JCTree>of(mods);
3124                 }
3125                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
3126                                               CLASS, INTERFACE, ENUM)));
3127             }
3128         } else {
3129             if (token.kind == ENUM) {
3130                 error(token.pos, "enums.not.supported.in.source", source.name);
3131                 allowEnums = true;
3132                 return enumDeclaration(mods, dc);
3133             }
3134             int pos = token.pos;
3135             List<JCTree> errs;
3136             if (LAX_IDENTIFIER.accepts(token.kind)) {
3137                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
3138                 setErrorEndPos(token.pos);
3139             } else {
3140                 errs = List.<JCTree>of(mods);
3141             }
3142             return toP(F.Exec(syntaxError(pos, errs, "expected2",
3143                                           CLASS, INTERFACE)));
3144         }
3145     }
3146 
3147     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3148      *                     [IMPLEMENTS TypeList] ClassBody
3149      *  @param mods    The modifiers starting the class declaration
3150      *  @param dc       The documentation comment for the class, or null.
3151      */
3152     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3153         int pos = token.pos;
3154         accept(CLASS);
3155         Name name = ident();
3156 
3157         List<JCTypeParameter> typarams = typeParametersOpt();
3158 
3159         JCExpression extending = null;
3160         if (token.kind == EXTENDS) {
3161             nextToken();
3162             extending = parseType();
3163         }
3164         List<JCExpression> implementing = List.nil();
3165         if (token.kind == IMPLEMENTS) {
3166             nextToken();
3167             implementing = typeList();
3168         }
3169         List<JCTree> defs = classOrInterfaceBody(name, false);
3170         JCClassDecl result = toP(F.at(pos).ClassDef(
3171             mods, name, typarams, extending, implementing, defs));
3172         attach(result, dc);
3173         return result;
3174     }
3175 
3176     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3177      *                         [EXTENDS TypeList] InterfaceBody
3178      *  @param mods    The modifiers starting the interface declaration
3179      *  @param dc       The documentation comment for the interface, or null.
3180      */
3181     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3182         int pos = token.pos;
3183         accept(INTERFACE);
3184         Name name = ident();
3185 
3186         List<JCTypeParameter> typarams = typeParametersOpt();
3187 
3188         List<JCExpression> extending = List.nil();
3189         if (token.kind == EXTENDS) {
3190             nextToken();
3191             extending = typeList();
3192         }
3193         List<JCTree> defs = classOrInterfaceBody(name, true);
3194         JCClassDecl result = toP(F.at(pos).ClassDef(
3195             mods, name, typarams, null, extending, defs));
3196         attach(result, dc);
3197         return result;
3198     }
3199 
3200     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3201      *  @param mods    The modifiers starting the enum declaration
3202      *  @param dc       The documentation comment for the enum, or null.
3203      */
3204     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3205         int pos = token.pos;
3206         accept(ENUM);
3207         Name name = ident();
3208 
3209         List<JCExpression> implementing = List.nil();
3210         if (token.kind == IMPLEMENTS) {
3211             nextToken();
3212             implementing = typeList();
3213         }
3214 
3215         List<JCTree> defs = enumBody(name);
3216         mods.flags |= Flags.ENUM;
3217         JCClassDecl result = toP(F.at(pos).
3218             ClassDef(mods, name, List.<JCTypeParameter>nil(),
3219                 null, implementing, defs));
3220         attach(result, dc);
3221         return result;
3222     }
3223 
3224     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
3225      *                  [ ";" {ClassBodyDeclaration} ] "}"
3226      */
3227     List<JCTree> enumBody(Name enumName) {
3228         accept(LBRACE);
3229         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
3230         if (token.kind == COMMA) {
3231             nextToken();
3232         } else if (token.kind != RBRACE && token.kind != SEMI) {
3233             defs.append(enumeratorDeclaration(enumName));
3234             while (token.kind == COMMA) {
3235                 nextToken();
3236                 if (token.kind == RBRACE || token.kind == SEMI) break;
3237                 defs.append(enumeratorDeclaration(enumName));
3238             }
3239             if (token.kind != SEMI && token.kind != RBRACE) {
3240                 defs.append(syntaxError(token.pos, "expected3",
3241                                 COMMA, RBRACE, SEMI));
3242                 nextToken();
3243             }
3244         }
3245         if (token.kind == SEMI) {
3246             nextToken();
3247             while (token.kind != RBRACE && token.kind != EOF) {
3248                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
3249                                                                 false));
3250                 if (token.pos <= endPosTable.errorEndPos) {
3251                     // error recovery
3252                    skip(false, true, true, false);
3253                 }
3254             }
3255         }
3256         accept(RBRACE);
3257         return defs.toList();
3258     }
3259 
3260     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3261      */
3262     JCTree enumeratorDeclaration(Name enumName) {
3263         Comment dc = token.comment(CommentStyle.JAVADOC);
3264         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3265         if (token.deprecatedFlag()) {
3266             flags |= Flags.DEPRECATED;
3267         }
3268         int pos = token.pos;
3269         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3270         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3271         List<JCExpression> typeArgs = typeArgumentsOpt();
3272         int identPos = token.pos;
3273         Name name = ident();
3274         int createPos = token.pos;
3275         List<JCExpression> args = (token.kind == LPAREN)
3276             ? arguments() : List.<JCExpression>nil();
3277         JCClassDecl body = null;
3278         if (token.kind == LBRACE) {
3279             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
3280             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
3281             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3282         }
3283         if (args.isEmpty() && body == null)
3284             createPos = identPos;
3285         JCIdent ident = F.at(identPos).Ident(enumName);
3286         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3287         if (createPos != identPos)
3288             storeEnd(create, S.prevToken().endPos);
3289         ident = F.at(identPos).Ident(enumName);
3290         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3291         attach(result, dc);
3292         return result;
3293     }
3294 
3295     /** TypeList = Type {"," Type}
3296      */
3297     List<JCExpression> typeList() {
3298         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
3299         ts.append(parseType());
3300         while (token.kind == COMMA) {
3301             nextToken();
3302             ts.append(parseType());
3303         }
3304         return ts.toList();
3305     }
3306 
3307     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3308      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3309      */
3310     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
3311         accept(LBRACE);
3312         if (token.pos <= endPosTable.errorEndPos) {
3313             // error recovery
3314             skip(false, true, false, false);
3315             if (token.kind == LBRACE)
3316                 nextToken();
3317         }
3318         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
3319         while (token.kind != RBRACE && token.kind != EOF) {
3320             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
3321             if (token.pos <= endPosTable.errorEndPos) {
3322                // error recovery
3323                skip(false, true, true, false);
3324            }
3325         }
3326         accept(RBRACE);
3327         return defs.toList();
3328     }
3329 
3330     /** ClassBodyDeclaration =
3331      *      ";"
3332      *    | [STATIC] Block
3333      *    | ModifiersOpt
3334      *      ( Type Ident
3335      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3336      *      | VOID Ident MethodDeclaratorRest
3337      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
3338      *      | Ident ConstructorDeclaratorRest
3339      *      | TypeParameters Ident ConstructorDeclaratorRest
3340      *      | ClassOrInterfaceOrEnumDeclaration
3341      *      )
3342      *  InterfaceBodyDeclaration =
3343      *      ";"
3344      *    | ModifiersOpt Type Ident
3345      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
3346      */
3347     protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3348         if (token.kind == SEMI) {
3349             nextToken();
3350             return List.<JCTree>nil();
3351         } else {
3352             Comment dc = token.comment(CommentStyle.JAVADOC);
3353             int pos = token.pos;
3354             JCModifiers mods = modifiersOpt();
3355             if (token.kind == CLASS ||
3356                 token.kind == INTERFACE ||
3357                 allowEnums && token.kind == ENUM) {
3358                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
3359             } else if (token.kind == LBRACE && !isInterface &&
3360                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3361                        mods.annotations.isEmpty()) {
3362                 return List.<JCTree>of(block(pos, mods.flags));
3363             } else {
3364                 pos = token.pos;
3365                 List<JCTypeParameter> typarams = typeParametersOpt();
3366                 // if there are type parameters but no modifiers, save the start
3367                 // position of the method in the modifiers.
3368                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3369                     mods.pos = pos;
3370                     storeEnd(mods, pos);
3371                 }
3372                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3373 
3374                 Token tk = token;
3375                 pos = token.pos;
3376                 JCExpression type;
3377                 boolean isVoid = token.kind == VOID;
3378                 if (isVoid) {
3379                     if (annosAfterParams.nonEmpty())
3380                         illegal(annosAfterParams.head.pos);
3381                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3382                     nextToken();
3383                 } else {
3384                     if (annosAfterParams.nonEmpty()) {
3385                         mods.annotations = mods.annotations.appendList(annosAfterParams);
3386                         if (mods.pos == Position.NOPOS)
3387                             mods.pos = mods.annotations.head.pos;
3388                     }
3389                     // method returns types are un-annotated types
3390                     type = unannotatedType();
3391                 }
3392                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3393                     if (isInterface || tk.name() != className)
3394                         error(pos, "invalid.meth.decl.ret.type.req");
3395                     return List.of(methodDeclaratorRest(
3396                         pos, mods, null, names.init, typarams,
3397                         isInterface, true, dc));
3398                 } else {
3399                     pos = token.pos;
3400                     Name name = ident();
3401                     if (token.kind == LPAREN) {
3402                         return List.of(methodDeclaratorRest(
3403                             pos, mods, type, name, typarams,
3404                             isInterface, isVoid, dc));
3405                     } else if (!isVoid && typarams.isEmpty()) {
3406                         List<JCTree> defs =
3407                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3408                                                     new ListBuffer<JCTree>()).toList();
3409                         storeEnd(defs.last(), token.endPos);
3410                         accept(SEMI);
3411                         return defs;
3412                     } else {
3413                         pos = token.pos;
3414                         List<JCTree> err = isVoid
3415                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
3416                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
3417                             : null;
3418                         return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
3419                     }
3420                 }
3421             }
3422         }
3423     }
3424 
3425     /** MethodDeclaratorRest =
3426      *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
3427      *  VoidMethodDeclaratorRest =
3428      *      FormalParameters [Throws TypeList] ( MethodBody | ";")
3429      *  InterfaceMethodDeclaratorRest =
3430      *      FormalParameters BracketsOpt [THROWS TypeList] ";"
3431      *  VoidInterfaceMethodDeclaratorRest =
3432      *      FormalParameters [THROWS TypeList] ";"
3433      *  ConstructorDeclaratorRest =
3434      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
3435      */
3436     protected JCTree methodDeclaratorRest(int pos,
3437                               JCModifiers mods,
3438                               JCExpression type,
3439                               Name name,
3440                               List<JCTypeParameter> typarams,
3441                               boolean isInterface, boolean isVoid,
3442                               Comment dc) {
3443         if (isInterface && (mods.flags & Flags.STATIC) != 0) {
3444             checkStaticInterfaceMethods();
3445         }
3446         JCVariableDecl prevReceiverParam = this.receiverParam;
3447         try {
3448             this.receiverParam = null;
3449             // Parsing formalParameters sets the receiverParam, if present
3450             List<JCVariableDecl> params = formalParameters();
3451             if (!isVoid) type = bracketsOpt(type);
3452             List<JCExpression> thrown = List.nil();
3453             if (token.kind == THROWS) {
3454                 nextToken();
3455                 thrown = qualidentList();
3456             }
3457             JCBlock body = null;
3458             JCExpression defaultValue;
3459             if (token.kind == LBRACE) {
3460                 body = block();
3461                 defaultValue = null;
3462             } else {
3463                 if (token.kind == DEFAULT) {
3464                     accept(DEFAULT);
3465                     defaultValue = annotationValue();
3466                 } else {
3467                     defaultValue = null;
3468                 }
3469                 accept(SEMI);
3470                 if (token.pos <= endPosTable.errorEndPos) {
3471                     // error recovery
3472                     skip(false, true, false, false);
3473                     if (token.kind == LBRACE) {
3474                         body = block();
3475                     }
3476                 }
3477             }
3478 
3479             JCMethodDecl result =
3480                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
3481                                             receiverParam, params, thrown,
3482                                             body, defaultValue));
3483             attach(result, dc);
3484             return result;
3485         } finally {
3486             this.receiverParam = prevReceiverParam;
3487         }
3488     }
3489 
3490     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
3491      */
3492     List<JCExpression> qualidentList() {
3493         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
3494 
3495         List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
3496         if (!typeAnnos.isEmpty())
3497             ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
3498         else
3499             ts.append(qualident(true));
3500         while (token.kind == COMMA) {
3501             nextToken();
3502 
3503             typeAnnos = typeAnnotationsOpt();
3504             if (!typeAnnos.isEmpty())
3505                 ts.append(toP(F.at(typeAnnos.head.pos).AnnotatedType(typeAnnos, qualident(true))));
3506             else
3507                 ts.append(qualident(true));
3508         }
3509         return ts.toList();
3510     }
3511 
3512     /**
3513      *  {@literal
3514      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
3515      *  }
3516      */
3517     List<JCTypeParameter> typeParametersOpt() {
3518         if (token.kind == LT) {
3519             checkGenerics();
3520             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
3521             nextToken();
3522             typarams.append(typeParameter());
3523             while (token.kind == COMMA) {
3524                 nextToken();
3525                 typarams.append(typeParameter());
3526             }
3527             accept(GT);
3528             return typarams.toList();
3529         } else {
3530             return List.nil();
3531         }
3532     }
3533 
3534     /**
3535      *  {@literal
3536      *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
3537      *  TypeParameterBound = EXTENDS Type {"&" Type}
3538      *  TypeVariable = Ident
3539      *  }
3540      */
3541     JCTypeParameter typeParameter() {
3542         int pos = token.pos;
3543         List<JCAnnotation> annos = typeAnnotationsOpt();
3544         Name name = ident();
3545         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
3546         if (token.kind == EXTENDS) {
3547             nextToken();
3548             bounds.append(parseType());
3549             while (token.kind == AMP) {
3550                 nextToken();
3551                 bounds.append(parseType());
3552             }
3553         }
3554         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
3555     }
3556 
3557     /** FormalParameters = "(" [ FormalParameterList ] ")"
3558      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3559      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3560      */
3561     List<JCVariableDecl> formalParameters() {
3562         return formalParameters(false);
3563     }
3564     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
3565         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
3566         JCVariableDecl lastParam;
3567         accept(LPAREN);
3568         if (token.kind != RPAREN) {
3569             this.allowThisIdent = true;
3570             lastParam = formalParameter(lambdaParameters);
3571             if (lastParam.name.contentEquals(TokenKind.THIS.name)) {
3572                 this.receiverParam = lastParam;
3573             } else {
3574                 params.append(lastParam);
3575             }
3576             this.allowThisIdent = false;
3577             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
3578                 nextToken();
3579                 params.append(lastParam = formalParameter(lambdaParameters));
3580             }
3581         }
3582         accept(RPAREN);
3583         return params.toList();
3584     }
3585 
3586     List<JCVariableDecl> implicitParameters(boolean hasParens) {
3587         if (hasParens) {
3588             accept(LPAREN);
3589         }
3590         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
3591         if (token.kind != RPAREN && token.kind != ARROW) {
3592             params.append(implicitParameter());
3593             while (token.kind == COMMA) {
3594                 nextToken();
3595                 params.append(implicitParameter());
3596             }
3597         }
3598         if (hasParens) {
3599             accept(RPAREN);
3600         }
3601         return params.toList();
3602     }
3603 
3604     JCModifiers optFinal(long flags) {
3605         JCModifiers mods = modifiersOpt();
3606         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
3607         mods.flags |= flags;
3608         return mods;
3609     }
3610 
3611     /**
3612      * Inserts the annotations (and possibly a new array level)
3613      * to the left-most type in an array or nested type.
3614      *
3615      * When parsing a type like {@code @B Outer.Inner @A []}, the
3616      * {@code @A} annotation should target the array itself, while
3617      * {@code @B} targets the nested type {@code Outer}.
3618      *
3619      * Currently the parser parses the annotation first, then
3620      * the array, and then inserts the annotation to the left-most
3621      * nested type.
3622      *
3623      * When {@code createNewLevel} is true, then a new array
3624      * level is inserted as the most inner type, and have the
3625      * annotations target it.  This is useful in the case of
3626      * varargs, e.g. {@code String @A [] @B ...}, as the parser
3627      * first parses the type {@code String @A []} then inserts
3628      * a new array level with {@code @B} annotation.
3629      */
3630     private JCExpression insertAnnotationsToMostInner(
3631             JCExpression type, List<JCAnnotation> annos,
3632             boolean createNewLevel) {
3633         int origEndPos = getEndPos(type);
3634         JCExpression mostInnerType = type;
3635         JCArrayTypeTree mostInnerArrayType = null;
3636         while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
3637             mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
3638             mostInnerType = mostInnerArrayType.elemtype;
3639         }
3640 
3641         if (createNewLevel) {
3642             mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
3643         }
3644 
3645         JCExpression mostInnerTypeToReturn = mostInnerType;
3646         if (annos.nonEmpty()) {
3647             JCExpression lastToModify = mostInnerType;
3648 
3649             while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
3650                     TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3651                 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
3652                     lastToModify = mostInnerType;
3653                     mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
3654                 }
3655                 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3656                     lastToModify = mostInnerType;
3657                     mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
3658                 }
3659             }
3660 
3661             mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
3662 
3663             if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
3664                 ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
3665             } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
3666                 ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
3667             } else {
3668                 // We never saw a SELECT or TYPEAPPLY, return the annotated type.
3669                 mostInnerTypeToReturn = mostInnerType;
3670             }
3671         }
3672 
3673         if (mostInnerArrayType == null) {
3674             return mostInnerTypeToReturn;
3675         } else {
3676             mostInnerArrayType.elemtype = mostInnerTypeToReturn;
3677             storeEnd(type, origEndPos);
3678             return type;
3679         }
3680     }
3681 
3682     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3683      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3684      */
3685     protected JCVariableDecl formalParameter() {
3686         return formalParameter(false);
3687     }
3688     protected JCVariableDecl formalParameter(boolean lambdaParameter) {
3689         JCModifiers mods = optFinal(Flags.PARAMETER);
3690         // need to distinguish between vararg annos and array annos
3691         // look at typeAnnotationsPushedBack comment
3692         this.permitTypeAnnotationsPushBack = true;
3693         JCExpression type = parseType();
3694         this.permitTypeAnnotationsPushBack = false;
3695 
3696         if (token.kind == ELLIPSIS) {
3697             List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
3698             typeAnnotationsPushedBack = List.nil();
3699             checkVarargs();
3700             mods.flags |= Flags.VARARGS;
3701             // insert var arg type annotations
3702             type = insertAnnotationsToMostInner(type, varargsAnnos, true);
3703             nextToken();
3704         } else {
3705             // if not a var arg, then typeAnnotationsPushedBack should be null
3706             if (typeAnnotationsPushedBack.nonEmpty()) {
3707                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3708                         "illegal.start.of.type");
3709             }
3710             typeAnnotationsPushedBack = List.nil();
3711         }
3712         return variableDeclaratorId(mods, type, lambdaParameter);
3713     }
3714 
3715     protected JCVariableDecl implicitParameter() {
3716         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
3717         return variableDeclaratorId(mods, null, true);
3718     }
3719 
3720 /* ---------- auxiliary methods -------------- */
3721 
3722     void error(int pos, String key, Object ... args) {
3723         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3724     }
3725 
3726     void error(DiagnosticPosition pos, String key, Object ... args) {
3727         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3728     }
3729 
3730     void warning(int pos, String key, Object ... args) {
3731         log.warning(pos, key, args);
3732     }
3733 
3734     /** Check that given tree is a legal expression statement.
3735      */
3736     protected JCExpression checkExprStat(JCExpression t) {
3737         if (!TreeInfo.isExpressionStatement(t)) {
3738             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
3739             error(ret, "not.stmt");
3740             return ret;
3741         } else {
3742             return t;
3743         }
3744     }
3745 
3746     /** Return precedence of operator represented by token,
3747      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
3748      */
3749     static int prec(TokenKind token) {
3750         JCTree.Tag oc = optag(token);
3751         return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
3752     }
3753 
3754     /**
3755      * Return the lesser of two positions, making allowance for either one
3756      * being unset.
3757      */
3758     static int earlier(int pos1, int pos2) {
3759         if (pos1 == Position.NOPOS)
3760             return pos2;
3761         if (pos2 == Position.NOPOS)
3762             return pos1;
3763         return (pos1 < pos2 ? pos1 : pos2);
3764     }
3765 
3766     /** Return operation tag of binary operator represented by token,
3767      *  No_TAG if token is not a binary operator.
3768      */
3769     static JCTree.Tag optag(TokenKind token) {
3770         switch (token) {
3771         case BARBAR:
3772             return OR;
3773         case AMPAMP:
3774             return AND;
3775         case BAR:
3776             return BITOR;
3777         case BAREQ:
3778             return BITOR_ASG;
3779         case CARET:
3780             return BITXOR;
3781         case CARETEQ:
3782             return BITXOR_ASG;
3783         case AMP:
3784             return BITAND;
3785         case AMPEQ:
3786             return BITAND_ASG;
3787         case EQEQ:
3788             return JCTree.Tag.EQ;
3789         case BANGEQ:
3790             return NE;
3791         case LT:
3792             return JCTree.Tag.LT;
3793         case GT:
3794             return JCTree.Tag.GT;
3795         case LTEQ:
3796             return LE;
3797         case GTEQ:
3798             return GE;
3799         case LTLT:
3800             return SL;
3801         case LTLTEQ:
3802             return SL_ASG;
3803         case GTGT:
3804             return SR;
3805         case GTGTEQ:
3806             return SR_ASG;
3807         case GTGTGT:
3808             return USR;
3809         case GTGTGTEQ:
3810             return USR_ASG;
3811         case PLUS:
3812             return JCTree.Tag.PLUS;
3813         case PLUSEQ:
3814             return PLUS_ASG;
3815         case SUB:
3816             return MINUS;
3817         case SUBEQ:
3818             return MINUS_ASG;
3819         case STAR:
3820             return MUL;
3821         case STAREQ:
3822             return MUL_ASG;
3823         case SLASH:
3824             return DIV;
3825         case SLASHEQ:
3826             return DIV_ASG;
3827         case PERCENT:
3828             return MOD;
3829         case PERCENTEQ:
3830             return MOD_ASG;
3831         case INSTANCEOF:
3832             return TYPETEST;
3833         default:
3834             return NO_TAG;
3835         }
3836     }
3837 
3838     /** Return operation tag of unary operator represented by token,
3839      *  No_TAG if token is not a binary operator.
3840      */
3841     static JCTree.Tag unoptag(TokenKind token) {
3842         switch (token) {
3843         case PLUS:
3844             return POS;
3845         case SUB:
3846             return NEG;
3847         case BANG:
3848             return NOT;
3849         case TILDE:
3850             return COMPL;
3851         case PLUSPLUS:
3852             return PREINC;
3853         case SUBSUB:
3854             return PREDEC;
3855         default:
3856             return NO_TAG;
3857         }
3858     }
3859 
3860     /** Return type tag of basic type represented by token,
3861      *  NONE if token is not a basic type identifier.
3862      */
3863     static TypeTag typetag(TokenKind token) {
3864         switch (token) {
3865         case BYTE:
3866             return TypeTag.BYTE;
3867         case CHAR:
3868             return TypeTag.CHAR;
3869         case SHORT:
3870             return TypeTag.SHORT;
3871         case INT:
3872             return TypeTag.INT;
3873         case LONG:
3874             return TypeTag.LONG;
3875         case FLOAT:
3876             return TypeTag.FLOAT;
3877         case DOUBLE:
3878             return TypeTag.DOUBLE;
3879         case BOOLEAN:
3880             return TypeTag.BOOLEAN;
3881         default:
3882             return TypeTag.NONE;
3883         }
3884     }
3885 
3886     void checkGenerics() {
3887         if (!allowGenerics) {
3888             error(token.pos, "generics.not.supported.in.source", source.name);
3889             allowGenerics = true;
3890         }
3891     }
3892     void checkVarargs() {
3893         if (!allowVarargs) {
3894             error(token.pos, "varargs.not.supported.in.source", source.name);
3895             allowVarargs = true;
3896         }
3897     }
3898     void checkForeach() {
3899         if (!allowForeach) {
3900             error(token.pos, "foreach.not.supported.in.source", source.name);
3901             allowForeach = true;
3902         }
3903     }
3904     void checkStaticImports() {
3905         if (!allowStaticImport) {
3906             error(token.pos, "static.import.not.supported.in.source", source.name);
3907             allowStaticImport = true;
3908         }
3909     }
3910     void checkAnnotations() {
3911         if (!allowAnnotations) {
3912             error(token.pos, "annotations.not.supported.in.source", source.name);
3913             allowAnnotations = true;
3914         }
3915     }
3916     void checkDiamond() {
3917         if (!allowDiamond) {
3918             error(token.pos, "diamond.not.supported.in.source", source.name);
3919             allowDiamond = true;
3920         }
3921     }
3922     void checkMulticatch() {
3923         if (!allowMulticatch) {
3924             error(token.pos, "multicatch.not.supported.in.source", source.name);
3925             allowMulticatch = true;
3926         }
3927     }
3928     void checkTryWithResources() {
3929         if (!allowTWR) {
3930             error(token.pos, "try.with.resources.not.supported.in.source", source.name);
3931             allowTWR = true;
3932         }
3933     }
3934     void checkLambda() {
3935         if (!allowLambda) {
3936             log.error(token.pos, "lambda.not.supported.in.source", source.name);
3937             allowLambda = true;
3938         }
3939     }
3940     void checkMethodReferences() {
3941         if (!allowMethodReferences) {
3942             log.error(token.pos, "method.references.not.supported.in.source", source.name);
3943             allowMethodReferences = true;
3944         }
3945     }
3946     void checkDefaultMethods() {
3947         if (!allowDefaultMethods) {
3948             log.error(token.pos, "default.methods.not.supported.in.source", source.name);
3949             allowDefaultMethods = true;
3950         }
3951     }
3952     void checkIntersectionTypesInCast() {
3953         if (!allowIntersectionTypesInCast) {
3954             log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
3955             allowIntersectionTypesInCast = true;
3956         }
3957     }
3958     void checkStaticInterfaceMethods() {
3959         if (!allowStaticInterfaceMethods) {
3960             log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
3961             allowStaticInterfaceMethods = true;
3962         }
3963     }
3964     void checkTypeAnnotations() {
3965         if (!allowTypeAnnotations) {
3966             log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
3967             allowTypeAnnotations = true;
3968         }
3969     }
3970 
3971     /*
3972      * a functional source tree and end position mappings
3973      */
3974     protected class SimpleEndPosTable extends AbstractEndPosTable {
3975 
3976         private final Map<JCTree, Integer> endPosMap;
3977 
3978         SimpleEndPosTable() {
3979             endPosMap = new HashMap<JCTree, Integer>();
3980         }
3981 
3982         protected void storeEnd(JCTree tree, int endpos) {
3983             endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
3984         }
3985 
3986         protected <T extends JCTree> T to(T t) {
3987             storeEnd(t, token.endPos);
3988             return t;
3989         }
3990 
3991         protected <T extends JCTree> T toP(T t) {
3992             storeEnd(t, S.prevToken().endPos);
3993             return t;
3994         }
3995 
3996         public int getEndPos(JCTree tree) {
3997             Integer value = endPosMap.get(tree);
3998             return (value == null) ? Position.NOPOS : value;
3999         }
4000 
4001         public int replaceTree(JCTree oldTree, JCTree newTree) {
4002             Integer pos = endPosMap.remove(oldTree);
4003             if (pos != null) {
4004                 endPosMap.put(newTree, pos);
4005                 return pos;
4006             }
4007             return Position.NOPOS;
4008         }
4009     }
4010 
4011     /*
4012      * a default skeletal implementation without any mapping overhead.
4013      */
4014     protected class EmptyEndPosTable extends AbstractEndPosTable {
4015 
4016         protected void storeEnd(JCTree tree, int endpos) { /* empty */ }
4017 
4018         protected <T extends JCTree> T to(T t) {
4019             return t;
4020         }
4021 
4022         protected <T extends JCTree> T toP(T t) {
4023             return t;
4024         }
4025 
4026         public int getEndPos(JCTree tree) {
4027             return Position.NOPOS;
4028         }
4029 
4030         public int replaceTree(JCTree oldTree, JCTree newTree) {
4031             return Position.NOPOS;
4032         }
4033 
4034     }
4035 
4036     protected abstract class AbstractEndPosTable implements EndPosTable {
4037 
4038         /**
4039          * Store the last error position.
4040          */
4041         protected int errorEndPos;
4042 
4043         /**
4044          * Store ending position for a tree, the value of which is the greater
4045          * of last error position and the given ending position.
4046          * @param tree   The tree.
4047          * @param endpos The ending position to associate with the tree.
4048          */
4049         protected abstract void storeEnd(JCTree tree, int endpos);
4050 
4051         /**
4052          * Store current token's ending position for a tree, the value of which
4053          * will be the greater of last error position and the ending position of
4054          * the current token.
4055          * @param t The tree.
4056          */
4057         protected abstract <T extends JCTree> T to(T t);
4058 
4059         /**
4060          * Store current token's ending position for a tree, the value of which
4061          * will be the greater of last error position and the ending position of
4062          * the previous token.
4063          * @param t The tree.
4064          */
4065         protected abstract <T extends JCTree> T toP(T t);
4066 
4067         /**
4068          * Set the error position during the parsing phases, the value of which
4069          * will be set only if it is greater than the last stored error position.
4070          * @param errPos The error position
4071          */
4072         protected void setErrorEndPos(int errPos) {
4073             if (errPos > errorEndPos) {
4074                 errorEndPos = errPos;
4075             }
4076         }
4077     }
4078 }