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