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     protected 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                     e.endpos = token.pos;
1396                     accept(RBRACE);
1397                     return e;
1398                 default:
1399                     nextToken(); // to ensure progress
1400                     syntaxError(pos, Errors.Expected3(CASE, DEFAULT, RBRACE));
1401                 }
1402             }
1403         default:
1404             return illegal();
1405         }
1406         return term3Rest(t, typeArgs);
1407     }
1408 
1409     private List<JCCase> switchExpressionStatementGroup() {
1410         ListBuffer<JCCase> caseExprs = new ListBuffer<>();
1411         int casePos = token.pos;
1412         ListBuffer<JCExpression> pats = new ListBuffer<>();
1413 
1414         if (token.kind == DEFAULT) {
1415             nextToken();
1416         } else {
1417             accept(CASE);
1418             while (true) {
1419                 pats.append(term(EXPR | NOLAMBDA));
1420                 if (token.kind != COMMA) break;
1421                 checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS);
1422                 nextToken();
1423             };
1424         }
1425         List<JCStatement> stats = null;
1426         JCTree body = null;
1427         @SuppressWarnings("removal")
1428         CaseKind kind;
1429         switch (token.kind) {
1430             case ARROW:
1431                 checkSourceLevel(Feature.SWITCH_RULE);
1432                 nextToken();
1433                 if (token.kind == TokenKind.THROW || token.kind == TokenKind.LBRACE) {
1434                     stats = List.of(parseStatement());
1435                     body = stats.head;
1436                     kind = JCCase.RULE;
1437                 } else {
1438                     JCExpression value = parseExpression();
1439                     stats = List.of(to(F.at(value).Break(value)));
1440                     body = value;
1441                     kind = JCCase.RULE;
1442                     accept(SEMI);
1443                 }
1444                 break;
1445             default:
1446                 accept(COLON, tk -> Errors.Expected2(COLON, ARROW));
1447                 stats = blockStatements();
1448                 kind = JCCase.STATEMENT;
1449                 break;
1450         }
1451         caseExprs.append(toP(F.at(casePos).Case(kind, pats.toList(), stats, body)));
1452         return caseExprs.toList();
1453     }
1454 
1455     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1456         if (typeArgs != null) illegal();
1457         while (true) {
1458             int pos1 = token.pos;
1459             final List<JCAnnotation> annos = typeAnnotationsOpt();
1460 
1461             if (token.kind == LBRACKET) {
1462                 nextToken();
1463                 if ((mode & TYPE) != 0) {
1464                     int oldmode = mode;
1465                     selectTypeMode();
1466                     if (token.kind == RBRACKET) {
1467                         nextToken();
1468                         t = bracketsOpt(t);
1469                         t = toP(F.at(pos1).TypeArray(t));
1470                         if (token.kind == COLCOL) {
1471                             selectExprMode();
1472                             continue;
1473                         }
1474                         if (annos.nonEmpty()) {
1475                             t = toP(F.at(pos1).AnnotatedType(annos, t));
1476                         }
1477                         return t;
1478                     }
1479                     mode = oldmode;
1480                 }
1481                 if ((mode & EXPR) != 0) {
1482                     selectExprMode();
1483                     JCExpression t1 = term();
1484                     t = to(F.at(pos1).Indexed(t, t1));
1485                 }
1486                 accept(RBRACKET);
1487             } else if (token.kind == DOT) {
1488                 nextToken();
1489                 typeArgs = typeArgumentsOpt(EXPR);
1490                 if (token.kind == SUPER && (mode & EXPR) != 0) {
1491                     selectExprMode();
1492                     t = to(F.at(pos1).Select(t, names._super));
1493                     nextToken();
1494                     t = arguments(typeArgs, t);
1495                     typeArgs = null;
1496                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1497                     if (typeArgs != null) return illegal();
1498                     selectExprMode();
1499                     int pos2 = token.pos;
1500                     nextToken();
1501                     if (token.kind == LT) typeArgs = typeArguments(false);
1502                     t = innerCreator(pos2, typeArgs, t);
1503                     typeArgs = null;
1504                 } else {
1505                     List<JCAnnotation> tyannos = null;
1506                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1507                         // is the mode check needed?
1508                         tyannos = typeAnnotationsOpt();
1509                     }
1510                     t = toP(F.at(pos1).Select(t, ident(true)));
1511                     if (tyannos != null && tyannos.nonEmpty()) {
1512                         t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1513                     }
1514                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1515                     typeArgs = null;
1516                 }
1517             } else if ((mode & EXPR) != 0 && token.kind == COLCOL) {
1518                 selectExprMode();
1519                 if (typeArgs != null) return illegal();
1520                 accept(COLCOL);
1521                 t = memberReferenceSuffix(pos1, t);
1522             } else {
1523                 if (!annos.isEmpty()) {
1524                     if (permitTypeAnnotationsPushBack)
1525                         typeAnnotationsPushedBack = annos;
1526                     else
1527                         return illegal(annos.head.pos);
1528                 }
1529                 break;
1530             }
1531         }
1532         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1533             selectExprMode();
1534             t = to(F.at(token.pos).Unary(
1535                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1536             nextToken();
1537         }
1538         return toP(t);
1539     }
1540 
1541     /**
1542      * If we see an identifier followed by a '&lt;' it could be an unbound
1543      * method reference or a binary expression. To disambiguate, look for a
1544      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1545      */
1546     @SuppressWarnings("fallthrough")
1547     boolean isUnboundMemberRef() {
1548         int pos = 0, depth = 0;
1549         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1550             switch (t.kind) {
1551                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1552                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1553                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1554                 case DOUBLE: case BOOLEAN: case CHAR:
1555                 case MONKEYS_AT:
1556                     break;
1557 
1558                 case LPAREN:
1559                     // skip annotation values
1560                     int nesting = 0;
1561                     for (; ; pos++) {
1562                         TokenKind tk2 = S.token(pos).kind;
1563                         switch (tk2) {
1564                             case EOF:
1565                                 return false;
1566                             case LPAREN:
1567                                 nesting++;
1568                                 break;
1569                             case RPAREN:
1570                                 nesting--;
1571                                 if (nesting == 0) {
1572                                     continue outer;
1573                                 }
1574                                 break;
1575                         }
1576                     }
1577 
1578                 case LT:
1579                     depth++; break;
1580                 case GTGTGT:
1581                     depth--;
1582                 case GTGT:
1583                     depth--;
1584                 case GT:
1585                     depth--;
1586                     if (depth == 0) {
1587                         TokenKind nextKind = S.token(pos + 1).kind;
1588                         return
1589                             nextKind == TokenKind.DOT ||
1590                             nextKind == TokenKind.LBRACKET ||
1591                             nextKind == TokenKind.COLCOL;
1592                     }
1593                     break;
1594                 default:
1595                     return false;
1596             }
1597         }
1598     }
1599 
1600     /**
1601      * If we see an identifier followed by a '&lt;' it could be an unbound
1602      * method reference or a binary expression. To disambiguate, look for a
1603      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1604      */
1605     @SuppressWarnings("fallthrough")
1606     ParensResult analyzeParens() {
1607         int depth = 0;
1608         boolean type = false;
1609         ParensResult defaultResult = ParensResult.PARENS;
1610         outer: for (int lookahead = 0 ; ; lookahead++) {
1611             TokenKind tk = S.token(lookahead).kind;
1612             switch (tk) {
1613                 case COMMA:
1614                     type = true;
1615                 case EXTENDS: case SUPER: case DOT: case AMP:
1616                     //skip
1617                     break;
1618                 case QUES:
1619                     if (peekToken(lookahead, EXTENDS) ||
1620                             peekToken(lookahead, SUPER)) {
1621                         //wildcards
1622                         type = true;
1623                     }
1624                     break;
1625                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1626                 case DOUBLE: case BOOLEAN: case CHAR: case VOID:
1627                     if (peekToken(lookahead, RPAREN)) {
1628                         //Type, ')' -> cast
1629                         return ParensResult.CAST;
1630                     } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
1631                         //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
1632                         return ParensResult.EXPLICIT_LAMBDA;
1633                     }
1634                     break;
1635                 case LPAREN:
1636                     if (lookahead != 0) {
1637                         // '(' in a non-starting position -> parens
1638                         return ParensResult.PARENS;
1639                     } else if (peekToken(lookahead, RPAREN)) {
1640                         // '(', ')' -> explicit lambda
1641                         return ParensResult.EXPLICIT_LAMBDA;
1642                     }
1643                     break;
1644                 case RPAREN:
1645                     // if we have seen something that looks like a type,
1646                     // then it's a cast expression
1647                     if (type) return ParensResult.CAST;
1648                     // otherwise, disambiguate cast vs. parenthesized expression
1649                     // based on subsequent token.
1650                     switch (S.token(lookahead + 1).kind) {
1651                         /*case PLUSPLUS: case SUBSUB: */
1652                         case BANG: case TILDE:
1653                         case LPAREN: case THIS: case SUPER:
1654                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1655                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1656                         case TRUE: case FALSE: case NULL:
1657                         case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1658                         case BYTE: case SHORT: case CHAR: case INT:
1659                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1660                             return ParensResult.CAST;
1661                         default:
1662                             return defaultResult;
1663                     }
1664                 case UNDERSCORE:
1665                 case ASSERT:
1666                 case ENUM:
1667                 case IDENTIFIER:
1668                     if (peekToken(lookahead, LAX_IDENTIFIER)) {
1669                         // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
1670                         return ParensResult.EXPLICIT_LAMBDA;
1671                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
1672                         // Identifier, ')' '->' -> implicit lambda
1673                         return (mode & NOLAMBDA) == 0 ? ParensResult.IMPLICIT_LAMBDA
1674                                                       : ParensResult.PARENS;
1675                     } else if (depth == 0 && peekToken(lookahead, COMMA)) {
1676                         defaultResult = ParensResult.IMPLICIT_LAMBDA;
1677                     }
1678                     type = false;
1679                     break;
1680                 case FINAL:
1681                 case ELLIPSIS:
1682                     //those can only appear in explicit lambdas
1683                     return ParensResult.EXPLICIT_LAMBDA;
1684                 case MONKEYS_AT:
1685                     type = true;
1686                     lookahead += 1; //skip '@'
1687                     while (peekToken(lookahead, DOT)) {
1688                         lookahead += 2;
1689                     }
1690                     if (peekToken(lookahead, LPAREN)) {
1691                         lookahead++;
1692                         //skip annotation values
1693                         int nesting = 0;
1694                         for (; ; lookahead++) {
1695                             TokenKind tk2 = S.token(lookahead).kind;
1696                             switch (tk2) {
1697                                 case EOF:
1698                                     return ParensResult.PARENS;
1699                                 case LPAREN:
1700                                     nesting++;
1701                                     break;
1702                                 case RPAREN:
1703                                     nesting--;
1704                                     if (nesting == 0) {
1705                                         continue outer;
1706                                     }
1707                                 break;
1708                             }
1709                         }
1710                     }
1711                     break;
1712                 case LBRACKET:
1713                     if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
1714                         // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
1715                         return ParensResult.EXPLICIT_LAMBDA;
1716                     } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
1717                             peekToken(lookahead, RBRACKET, AMP)) {
1718                         // '[', ']', ')' -> cast
1719                         // '[', ']', '&' -> cast (intersection type)
1720                         return ParensResult.CAST;
1721                     } else if (peekToken(lookahead, RBRACKET)) {
1722                         //consume the ']' and skip
1723                         type = true;
1724                         lookahead++;
1725                         break;
1726                     } else {
1727                         return ParensResult.PARENS;
1728                     }
1729                 case LT:
1730                     depth++; break;
1731                 case GTGTGT:
1732                     depth--;
1733                 case GTGT:
1734                     depth--;
1735                 case GT:
1736                     depth--;
1737                     if (depth == 0) {
1738                         if (peekToken(lookahead, RPAREN) ||
1739                                 peekToken(lookahead, AMP)) {
1740                             // '>', ')' -> cast
1741                             // '>', '&' -> cast
1742                             return ParensResult.CAST;
1743                         } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1744                                 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
1745                                 peekToken(lookahead, ELLIPSIS)) {
1746                             // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1747                             // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1748                             // '>', '...' -> explicit lambda
1749                             return ParensResult.EXPLICIT_LAMBDA;
1750                         }
1751                         //it looks a type, but could still be (i) a cast to generic type,
1752                         //(ii) an unbound method reference or (iii) an explicit lambda
1753                         type = true;
1754                         break;
1755                     } else if (depth < 0) {
1756                         //unbalanced '<', '>' - not a generic type
1757                         return ParensResult.PARENS;
1758                     }
1759                     break;
1760                 default:
1761                     //this includes EOF
1762                     return defaultResult;
1763             }
1764         }
1765     }
1766 
1767     /** Accepts all identifier-like tokens */
1768     protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
1769 
1770     enum ParensResult {
1771         CAST,
1772         EXPLICIT_LAMBDA,
1773         IMPLICIT_LAMBDA,
1774         PARENS
1775     }
1776 
1777     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
1778         List<JCVariableDecl> params = explicitParams ?
1779                 formalParameters(true) :
1780                 implicitParameters(hasParens);
1781         if (explicitParams) {
1782             LambdaClassifier lambdaClassifier = new LambdaClassifier();
1783             for (JCVariableDecl param: params) {
1784                 if (param.vartype != null &&
1785                         isRestrictedLocalVarTypeName(param.vartype, false) &&
1786                         param.vartype.hasTag(TYPEARRAY)) {
1787                     log.error(DiagnosticFlag.SYNTAX, param.pos,
1788                         Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source)
1789                             ? Errors.VarNotAllowedArray : Errors.VarNotAllowedHere);
1790                 }
1791                 lambdaClassifier.addParameter(param);
1792                 if (lambdaClassifier.result() == LambdaParameterKind.ERROR) {
1793                     break;
1794                 }
1795             }
1796             if (lambdaClassifier.diagFragment != null) {
1797                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidLambdaParameterDeclaration(lambdaClassifier.diagFragment));
1798             }
1799             for (JCVariableDecl param: params) {
1800                 if (param.vartype != null
1801                         && isRestrictedLocalVarTypeName(param.vartype, true)) {
1802                     checkSourceLevel(param.pos, Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS);
1803                     param.startPos = TreeInfo.getStartPos(param.vartype);
1804                     param.vartype = null;
1805                 }
1806             }
1807         }
1808         return lambdaExpressionOrStatementRest(params, pos);
1809     }
1810 
1811     enum LambdaParameterKind {
1812         VAR(0),
1813         EXPLICIT(1),
1814         IMPLICIT(2),
1815         ERROR(-1);
1816 
1817         private final int index;
1818 
1819         LambdaParameterKind(int index) {
1820             this.index = index;
1821         }
1822     }
1823 
1824     private final static Fragment[][] decisionTable = new Fragment[][] {
1825         /*              VAR                              EXPLICIT                         IMPLICIT  */
1826         /* VAR      */ {null,                            VarAndExplicitNotAllowed,        VarAndImplicitNotAllowed},
1827         /* EXPLICIT */ {VarAndExplicitNotAllowed,        null,                            ImplicitAndExplicitNotAllowed},
1828         /* IMPLICIT */ {VarAndImplicitNotAllowed,        ImplicitAndExplicitNotAllowed,   null},
1829     };
1830 
1831     class LambdaClassifier {
1832 
1833         LambdaParameterKind kind;
1834         Fragment diagFragment;
1835         List<JCVariableDecl> params;
1836 
1837         void addParameter(JCVariableDecl param) {
1838             if (param.vartype != null && param.name != names.empty) {
1839                 if (isRestrictedLocalVarTypeName(param.vartype, false)) {
1840                     reduce(LambdaParameterKind.VAR);
1841                 } else {
1842                     reduce(LambdaParameterKind.EXPLICIT);
1843                 }
1844             }
1845             if (param.vartype == null && param.name != names.empty ||
1846                 param.vartype != null && param.name == names.empty) {
1847                 reduce(LambdaParameterKind.IMPLICIT);
1848             }
1849         }
1850 
1851         private void reduce(LambdaParameterKind newKind) {
1852             if (kind == null) {
1853                 kind = newKind;
1854             } else if (kind != newKind && kind != LambdaParameterKind.ERROR) {
1855                 LambdaParameterKind currentKind = kind;
1856                 kind = LambdaParameterKind.ERROR;
1857                 boolean varIndex = currentKind.index == LambdaParameterKind.VAR.index ||
1858                         newKind.index == LambdaParameterKind.VAR.index;
1859                 diagFragment = Feature.VAR_SYNTAX_IMPLICIT_LAMBDAS.allowedInSource(source) || !varIndex ?
1860                         decisionTable[currentKind.index][newKind.index] : null;
1861             }
1862         }
1863 
1864         LambdaParameterKind result() {
1865             return kind;
1866         }
1867     }
1868 
1869     JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
1870         checkSourceLevel(Feature.LAMBDA);
1871         accept(ARROW);
1872 
1873         return token.kind == LBRACE ?
1874             lambdaStatement(args, pos, token.pos) :
1875             lambdaExpression(args, pos);
1876     }
1877 
1878     JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) {
1879         JCBlock block = block(pos2, 0);
1880         return toP(F.at(pos).Lambda(args, block));
1881     }
1882 
1883     JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
1884         JCTree expr = parseExpression();
1885         return toP(F.at(pos).Lambda(args, expr));
1886     }
1887 
1888     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1889      */
1890     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1891         nextToken();
1892         if (token.kind == LPAREN || typeArgs != null) {
1893             t = arguments(typeArgs, t);
1894         } else if (token.kind == COLCOL) {
1895             if (typeArgs != null) return illegal();
1896             t = memberReferenceSuffix(t);
1897         } else {
1898             int pos = token.pos;
1899             accept(DOT);
1900             typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1901             t = toP(F.at(pos).Select(t, ident()));
1902             t = argumentsOpt(typeArgs, t);
1903         }
1904         return t;
1905     }
1906 
1907     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1908      */
1909     JCPrimitiveTypeTree basicType() {
1910         JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
1911         nextToken();
1912         return t;
1913     }
1914 
1915     /** ArgumentsOpt = [ Arguments ]
1916      */
1917     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1918         if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
1919             selectExprMode();
1920             return arguments(typeArgs, t);
1921         } else {
1922             return t;
1923         }
1924     }
1925 
1926     /** Arguments = "(" [Expression { COMMA Expression }] ")"
1927      */
1928     List<JCExpression> arguments() {
1929         ListBuffer<JCExpression> args = new ListBuffer<>();
1930         if (token.kind == LPAREN) {
1931             nextToken();
1932             if (token.kind != RPAREN) {
1933                 args.append(parseExpression());
1934                 while (token.kind == COMMA) {
1935                     nextToken();
1936                     args.append(parseExpression());
1937                 }
1938             }
1939             accept(RPAREN);
1940         } else {
1941             syntaxError(token.pos, Errors.Expected(LPAREN));
1942         }
1943         return args.toList();
1944     }
1945 
1946     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1947         int pos = token.pos;
1948         List<JCExpression> args = arguments();
1949         return toP(F.at(pos).Apply(typeArgs, t, args));
1950     }
1951 
1952     /**  TypeArgumentsOpt = [ TypeArguments ]
1953      */
1954     JCExpression typeArgumentsOpt(JCExpression t) {
1955         if (token.kind == LT &&
1956             (mode & TYPE) != 0 &&
1957             (mode & NOPARAMS) == 0) {
1958             selectTypeMode();
1959             return typeArguments(t, false);
1960         } else {
1961             return t;
1962         }
1963     }
1964     List<JCExpression> typeArgumentsOpt() {
1965         return typeArgumentsOpt(TYPE);
1966     }
1967 
1968     List<JCExpression> typeArgumentsOpt(int useMode) {
1969         if (token.kind == LT) {
1970             if ((mode & useMode) == 0 ||
1971                 (mode & NOPARAMS) != 0) {
1972                 illegal();
1973             }
1974             mode = useMode;
1975             return typeArguments(false);
1976         }
1977         return null;
1978     }
1979 
1980     /**
1981      *  {@literal
1982      *  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1983      *  }
1984      */
1985     List<JCExpression> typeArguments(boolean diamondAllowed) {
1986         if (token.kind == LT) {
1987             nextToken();
1988             if (token.kind == GT && diamondAllowed) {
1989                 checkSourceLevel(Feature.DIAMOND);
1990                 mode |= DIAMOND;
1991                 nextToken();
1992                 return List.nil();
1993             } else {
1994                 ListBuffer<JCExpression> args = new ListBuffer<>();
1995                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1996                 while (token.kind == COMMA) {
1997                     nextToken();
1998                     args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1999                 }
2000                 switch (token.kind) {
2001 
2002                 case GTGTGTEQ: case GTGTEQ: case GTEQ:
2003                 case GTGTGT: case GTGT:
2004                     token = S.split();
2005                     break;
2006                 case GT:
2007                     nextToken();
2008                     break;
2009                 default:
2010                     args.append(syntaxError(token.pos, Errors.Expected(GT)));
2011                     break;
2012                 }
2013                 return args.toList();
2014             }
2015         } else {
2016             return List.of(syntaxError(token.pos, Errors.Expected(LT)));
2017         }
2018     }
2019 
2020     /**
2021      *  {@literal
2022      *  TypeArgument = Type
2023      *               | [Annotations] "?"
2024      *               | [Annotations] "?" EXTENDS Type {"&" Type}
2025      *               | [Annotations] "?" SUPER Type
2026      *  }
2027      */
2028     JCExpression typeArgument() {
2029         List<JCAnnotation> annotations = typeAnnotationsOpt();
2030         if (token.kind != QUES) return parseType(false, annotations);
2031         int pos = token.pos;
2032         nextToken();
2033         JCExpression result;
2034         if (token.kind == EXTENDS) {
2035             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
2036             nextToken();
2037             JCExpression bound = parseType();
2038             result = F.at(pos).Wildcard(t, bound);
2039         } else if (token.kind == SUPER) {
2040             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
2041             nextToken();
2042             JCExpression bound = parseType();
2043             result = F.at(pos).Wildcard(t, bound);
2044         } else if (LAX_IDENTIFIER.accepts(token.kind)) {
2045             //error recovery
2046             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
2047             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
2048             JCIdent id = toP(F.at(token.pos).Ident(ident()));
2049             JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
2050             reportSyntaxError(err, Errors.Expected3(GT, EXTENDS, SUPER));
2051             result = err;
2052         } else {
2053             TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
2054             result = toP(F.at(pos).Wildcard(t, null));
2055         }
2056         if (!annotations.isEmpty()) {
2057             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
2058         }
2059         return result;
2060     }
2061 
2062     JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
2063         int pos = token.pos;
2064         List<JCExpression> args = typeArguments(diamondAllowed);
2065         return toP(F.at(pos).TypeApply(t, args));
2066     }
2067 
2068     /**
2069      * BracketsOpt = { [Annotations] "[" "]" }*
2070      *
2071      * <p>
2072      *
2073      * <code>annotations</code> is the list of annotations targeting
2074      * the expression <code>t</code>.
2075      */
2076     private JCExpression bracketsOpt(JCExpression t,
2077             List<JCAnnotation> annotations) {
2078         List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
2079 
2080         if (token.kind == LBRACKET) {
2081             int pos = token.pos;
2082             nextToken();
2083             t = bracketsOptCont(t, pos, nextLevelAnnotations);
2084         } else if (!nextLevelAnnotations.isEmpty()) {
2085             if (permitTypeAnnotationsPushBack) {
2086                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
2087             } else {
2088                 return illegal(nextLevelAnnotations.head.pos);
2089             }
2090         }
2091 
2092         if (!annotations.isEmpty()) {
2093             t = toP(F.at(token.pos).AnnotatedType(annotations, t));
2094         }
2095         return t;
2096     }
2097 
2098     /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ]
2099      */
2100     private JCExpression bracketsOpt(JCExpression t) {
2101         return bracketsOpt(t, List.nil());
2102     }
2103 
2104     private JCExpression bracketsOptCont(JCExpression t, int pos,
2105             List<JCAnnotation> annotations) {
2106         accept(RBRACKET);
2107         t = bracketsOpt(t);
2108         t = toP(F.at(pos).TypeArray(t));
2109         if (annotations.nonEmpty()) {
2110             t = toP(F.at(pos).AnnotatedType(annotations, t));
2111         }
2112         return t;
2113     }
2114 
2115     /** BracketsSuffixExpr = "." CLASS
2116      *  BracketsSuffixType =
2117      */
2118     JCExpression bracketsSuffix(JCExpression t) {
2119         if ((mode & EXPR) != 0 && token.kind == DOT) {
2120             selectExprMode();
2121             int pos = token.pos;
2122             nextToken();
2123             accept(CLASS);
2124             if (token.pos == endPosTable.errorEndPos) {
2125                 // error recovery
2126                 Name name;
2127                 if (LAX_IDENTIFIER.accepts(token.kind)) {
2128                     name = token.name();
2129                     nextToken();
2130                 } else {
2131                     name = names.error;
2132                 }
2133                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2134             } else {
2135                 Tag tag = t.getTag();
2136                 // Type annotations are illegal on class literals. Annotated non array class literals
2137                 // are complained about directly in term3(), Here check for type annotations on dimensions
2138                 // taking care to handle some interior dimension(s) being annotated.
2139                 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2140                     syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2141                 t = toP(F.at(pos).Select(t, names._class));
2142             }
2143         } else if ((mode & TYPE) != 0) {
2144             if (token.kind != COLCOL) {
2145                 selectTypeMode();
2146             }
2147         } else if (token.kind != COLCOL) {
2148             syntaxError(token.pos, Errors.DotClassExpected);
2149         }
2150         return t;
2151     }
2152 
2153     /**
2154      * MemberReferenceSuffix = "::" [TypeArguments] Ident
2155      *                       | "::" [TypeArguments] "new"
2156      */
2157     JCExpression memberReferenceSuffix(JCExpression t) {
2158         int pos1 = token.pos;
2159         accept(COLCOL);
2160         return memberReferenceSuffix(pos1, t);
2161     }
2162 
2163     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2164         checkSourceLevel(Feature.METHOD_REFERENCES);
2165         selectExprMode();
2166         List<JCExpression> typeArgs = null;
2167         if (token.kind == LT) {
2168             typeArgs = typeArguments(false);
2169         }
2170         Name refName;
2171         ReferenceMode refMode;
2172         if (token.kind == NEW) {
2173             refMode = ReferenceMode.NEW;
2174             refName = names.init;
2175             nextToken();
2176         } else {
2177             refMode = ReferenceMode.INVOKE;
2178             refName = ident();
2179         }
2180         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2181     }
2182 
2183     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2184      */
2185     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2186         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2187 
2188         switch (token.kind) {
2189         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2190         case DOUBLE: case BOOLEAN:
2191             if (typeArgs == null) {
2192                 if (newAnnotations.isEmpty()) {
2193                     return arrayCreatorRest(newpos, basicType());
2194                 } else {
2195                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2196                 }
2197             }
2198             break;
2199         default:
2200         }
2201         JCExpression t = qualident(true);
2202 
2203         int oldmode = mode;
2204         selectTypeMode();
2205         boolean diamondFound = false;
2206         int lastTypeargsPos = -1;
2207         if (token.kind == LT) {
2208             lastTypeargsPos = token.pos;
2209             t = typeArguments(t, true);
2210             diamondFound = (mode & DIAMOND) != 0;
2211         }
2212         while (token.kind == DOT) {
2213             if (diamondFound) {
2214                 //cannot select after a diamond
2215                 illegal();
2216             }
2217             int pos = token.pos;
2218             nextToken();
2219             List<JCAnnotation> tyannos = typeAnnotationsOpt();
2220             t = toP(F.at(pos).Select(t, ident()));
2221 
2222             if (tyannos != null && tyannos.nonEmpty()) {
2223                 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
2224             }
2225 
2226             if (token.kind == LT) {
2227                 lastTypeargsPos = token.pos;
2228                 t = typeArguments(t, true);
2229                 diamondFound = (mode & DIAMOND) != 0;
2230             }
2231         }
2232         mode = oldmode;
2233         if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
2234             // handle type annotations for non primitive arrays
2235             if (newAnnotations.nonEmpty()) {
2236                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2237             }
2238 
2239             JCExpression e = arrayCreatorRest(newpos, t);
2240             if (diamondFound) {
2241                 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2242                 return toP(F.at(newpos).Erroneous(List.of(e)));
2243             }
2244             else if (typeArgs != null) {
2245                 int pos = newpos;
2246                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2247                     // note: this should always happen but we should
2248                     // not rely on this as the parser is continuously
2249                     // modified to improve error recovery.
2250                     pos = typeArgs.head.pos;
2251                 }
2252                 setErrorEndPos(S.prevToken().endPos);
2253                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2254                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2255                 return toP(err);
2256             }
2257             return e;
2258         } else if (token.kind == LPAREN) {
2259             // handle type annotations for instantiations and anonymous classes
2260             if (newAnnotations.nonEmpty()) {
2261                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2262             }
2263             return classCreatorRest(newpos, null, typeArgs, t);
2264         } else {
2265             setErrorEndPos(token.pos);
2266             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2267             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2268             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2269         }
2270     }
2271 
2272     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2273      */
2274     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2275         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2276 
2277         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2278 
2279         if (newAnnotations.nonEmpty()) {
2280             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2281         }
2282 
2283         if (token.kind == LT) {
2284             int oldmode = mode;
2285             t = typeArguments(t, true);
2286             mode = oldmode;
2287         }
2288         return classCreatorRest(newpos, encl, typeArgs, t);
2289     }
2290 
2291     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2292      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2293      */
2294     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2295         List<JCAnnotation> annos = typeAnnotationsOpt();
2296 
2297         accept(LBRACKET);
2298         if (token.kind == RBRACKET) {
2299             accept(RBRACKET);
2300             elemtype = bracketsOpt(elemtype, annos);
2301             if (token.kind == LBRACE) {
2302                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2303                 if (annos.nonEmpty()) {
2304                     // when an array initializer is present then
2305                     // the parsed annotations should target the
2306                     // new array tree
2307                     // bracketsOpt inserts the annotation in
2308                     // elemtype, and it needs to be corrected
2309                     //
2310                     JCAnnotatedType annotated = (JCAnnotatedType)elemtype;
2311                     assert annotated.annotations == annos;
2312                     na.annotations = annotated.annotations;
2313                     na.elemtype = annotated.underlyingType;
2314                 }
2315                 return na;
2316             } else {
2317                 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.nil(), null));
2318                 return syntaxError(token.pos, List.of(t), Errors.ArrayDimensionMissing);
2319             }
2320         } else {
2321             ListBuffer<JCExpression> dims = new ListBuffer<>();
2322 
2323             // maintain array dimension type annotations
2324             ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
2325             dimAnnotations.append(annos);
2326 
2327             dims.append(parseExpression());
2328             accept(RBRACKET);
2329             while (token.kind == LBRACKET
2330                     || token.kind == MONKEYS_AT) {
2331                 List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt();
2332                 int pos = token.pos;
2333                 nextToken();
2334                 if (token.kind == RBRACKET) {
2335                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2336                 } else {
2337                     if (token.kind == RBRACKET) { // no dimension
2338                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2339                     } else {
2340                         dimAnnotations.append(maybeDimAnnos);
2341                         dims.append(parseExpression());
2342                         accept(RBRACKET);
2343                     }
2344                 }
2345             }
2346 
2347             List<JCExpression> elems = null;
2348             int errpos = token.pos;
2349 
2350             if (token.kind == LBRACE) {
2351                 elems = arrayInitializerElements(newpos, elemtype);
2352             }
2353 
2354             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2355             na.dimAnnotations = dimAnnotations.toList();
2356 
2357             if (elems != null) {
2358                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2359             }
2360 
2361             return na;
2362         }
2363     }
2364 
2365     /** ClassCreatorRest = Arguments [ClassBody]
2366      */
2367     JCNewClass classCreatorRest(int newpos,
2368                                   JCExpression encl,
2369                                   List<JCExpression> typeArgs,
2370                                   JCExpression t)
2371     {
2372         List<JCExpression> args = arguments();
2373         JCClassDecl body = null;
2374         if (token.kind == LBRACE) {
2375             int pos = token.pos;
2376             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2377             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2378             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2379         }
2380         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2381     }
2382 
2383     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2384      */
2385     JCExpression arrayInitializer(int newpos, JCExpression t) {
2386         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2387         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2388     }
2389 
2390     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2391         accept(LBRACE);
2392         ListBuffer<JCExpression> elems = new ListBuffer<>();
2393         if (token.kind == COMMA) {
2394             nextToken();
2395         } else if (token.kind != RBRACE) {
2396             elems.append(variableInitializer());
2397             while (token.kind == COMMA) {
2398                 nextToken();
2399                 if (token.kind == RBRACE) break;
2400                 elems.append(variableInitializer());
2401             }
2402         }
2403         accept(RBRACE);
2404         return elems.toList();
2405     }
2406 
2407     /** VariableInitializer = ArrayInitializer | Expression
2408      */
2409     public JCExpression variableInitializer() {
2410         return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
2411     }
2412 
2413     /** ParExpression = "(" Expression ")"
2414      */
2415     JCExpression parExpression() {
2416         int pos = token.pos;
2417         accept(LPAREN);
2418         JCExpression t = parseExpression();
2419         accept(RPAREN);
2420         return toP(F.at(pos).Parens(t));
2421     }
2422 
2423     /** Block = "{" BlockStatements "}"
2424      */
2425     JCBlock block(int pos, long flags) {
2426         accept(LBRACE);
2427         List<JCStatement> stats = blockStatements();
2428         JCBlock t = F.at(pos).Block(flags, stats);
2429         while (token.kind == CASE || token.kind == DEFAULT) {
2430             syntaxError(token.pos, Errors.Orphaned(token.kind));
2431             switchBlockStatementGroups();
2432         }
2433         // the Block node has a field "endpos" for first char of last token, which is
2434         // usually but not necessarily the last char of the last token.
2435         t.endpos = token.pos;
2436         accept(RBRACE);
2437         return toP(t);
2438     }
2439 
2440     public JCBlock block() {
2441         return block(token.pos, 0);
2442     }
2443 
2444     /** BlockStatements = { BlockStatement }
2445      *  BlockStatement  = LocalVariableDeclarationStatement
2446      *                  | ClassOrInterfaceOrEnumDeclaration
2447      *                  | [Ident ":"] Statement
2448      *  LocalVariableDeclarationStatement
2449      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
2450      */
2451     @SuppressWarnings("fallthrough")
2452     List<JCStatement> blockStatements() {
2453         //todo: skip to anchor on error(?)
2454         int lastErrPos = -1;
2455         ListBuffer<JCStatement> stats = new ListBuffer<>();
2456         while (true) {
2457             List<JCStatement> stat = blockStatement();
2458             if (stat.isEmpty()) {
2459                 return stats.toList();
2460             } else {
2461                 // error recovery
2462                 if (token.pos == lastErrPos)
2463                     return stats.toList();
2464                 if (token.pos <= endPosTable.errorEndPos) {
2465                     skip(false, true, true, true);
2466                     lastErrPos = token.pos;
2467                 }
2468                 stats.addAll(stat);
2469             }
2470         }
2471     }
2472 
2473     /*
2474      * Parse a Statement (JLS 14.5). As an enhancement to improve error recovery,
2475      * this method will also recognize variable and class declarations (which are
2476      * not legal for a Statement) by delegating the parsing to BlockStatement (JLS 14.2).
2477      * If any illegal declarations are found, they will be wrapped in an erroneous tree,
2478      * and an error will be produced by this method.
2479      */
2480     JCStatement parseStatementAsBlock() {
2481         int pos = token.pos;
2482         List<JCStatement> stats = blockStatement();
2483         if (stats.isEmpty()) {
2484             JCErroneous e = syntaxError(pos, Errors.IllegalStartOfStmt);
2485             return toP(F.at(pos).Exec(e));
2486         } else {
2487             JCStatement first = stats.head;
2488             Error error = null;
2489             switch (first.getTag()) {
2490             case CLASSDEF:
2491                 error = Errors.ClassNotAllowed;
2492                 break;
2493             case VARDEF:
2494                 error = Errors.VariableNotAllowed;
2495                 break;
2496             }
2497             if (error != null) {
2498                 log.error(DiagnosticFlag.SYNTAX, first, error);
2499                 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2500                 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2501             }
2502             return first;
2503         }
2504     }
2505 
2506     /**This method parses a statement appearing inside a block.
2507      */
2508     List<JCStatement> blockStatement() {
2509         //todo: skip to anchor on error(?)
2510         Comment dc;
2511         int pos = token.pos;
2512         switch (token.kind) {
2513         case RBRACE: case CASE: case DEFAULT: case EOF:
2514             return List.nil();
2515         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2516         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2517         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2518         case ASSERT:
2519             return List.of(parseSimpleStatement());
2520         case MONKEYS_AT:
2521         case FINAL: {
2522             dc = token.comment(CommentStyle.JAVADOC);
2523             JCModifiers mods = modifiersOpt();
2524             if (token.kind == INTERFACE ||
2525                 token.kind == CLASS ||
2526                 token.kind == ENUM) {
2527                 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
2528             } else {
2529                 JCExpression t = parseType(true);
2530                 return localVariableDeclarations(mods, t);
2531             }
2532         }
2533         case ABSTRACT: case STRICTFP: {
2534             dc = token.comment(CommentStyle.JAVADOC);
2535             JCModifiers mods = modifiersOpt();
2536             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
2537         }
2538         case INTERFACE:
2539         case CLASS:
2540             dc = token.comment(CommentStyle.JAVADOC);
2541             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2542         case ENUM:
2543             log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
2544             dc = token.comment(CommentStyle.JAVADOC);
2545             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2546         }
2547         if (isRecordDeclaration()) {
2548             JCModifiers mods = modifiersOpt();
2549             dc = token.comment(CommentStyle.JAVADOC);
2550             return List.of(recordDeclaration(mods, dc));
2551         } else {
2552             Token prevToken = token;
2553             JCExpression t = term(EXPR | TYPE);
2554             if (token.kind == COLON && t.hasTag(IDENT)) {
2555                 nextToken();
2556                 JCStatement stat = parseStatementAsBlock();
2557                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2558             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2559                 pos = token.pos;
2560                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2561                 F.at(pos);
2562                 return localVariableDeclarations(mods, t);
2563             } else {
2564                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2565                 t = checkExprStat(t);
2566                 accept(SEMI);
2567                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
2568                 return List.of(expr);
2569             }
2570         }
2571     }
2572     //where
2573         private List<JCStatement> localVariableDeclarations(JCModifiers mods, JCExpression type) {
2574             ListBuffer<JCStatement> stats =
2575                     variableDeclarators(mods, type, new ListBuffer<>(), true);
2576             // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2577             accept(SEMI);
2578             storeEnd(stats.last(), S.prevToken().endPos);
2579             return stats.toList();
2580         }
2581 
2582     /** Statement =
2583      *       Block
2584      *     | IF ParExpression Statement [ELSE Statement]
2585      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
2586      *     | FOR "(" FormalParameter : Expression ")" Statement
2587      *     | WHILE ParExpression Statement
2588      *     | DO Statement WHILE ParExpression ";"
2589      *     | TRY Block ( Catches | [Catches] FinallyPart )
2590      *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
2591      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
2592      *     | SYNCHRONIZED ParExpression Block
2593      *     | RETURN [Expression] ";"
2594      *     | THROW Expression ";"
2595      *     | BREAK [Ident] ";"
2596      *     | CONTINUE [Ident] ";"
2597      *     | ASSERT Expression [ ":" Expression ] ";"
2598      *     | ";"
2599      */
2600     public JCStatement parseSimpleStatement() {
2601         int pos = token.pos;
2602         switch (token.kind) {
2603         case LBRACE:
2604             return block();
2605         case IF: {
2606             nextToken();
2607             JCExpression cond = parExpression();
2608             JCStatement thenpart = parseStatementAsBlock();
2609             JCStatement elsepart = null;
2610             if (token.kind == ELSE) {
2611                 nextToken();
2612                 elsepart = parseStatementAsBlock();
2613             }
2614             return F.at(pos).If(cond, thenpart, elsepart);
2615         }
2616         case FOR: {
2617             nextToken();
2618             accept(LPAREN);
2619             List<JCStatement> inits = token.kind == SEMI ? List.nil() : forInit();
2620             if (inits.length() == 1 &&
2621                 inits.head.hasTag(VARDEF) &&
2622                 ((JCVariableDecl) inits.head).init == null &&
2623                 token.kind == COLON) {
2624                 JCVariableDecl var = (JCVariableDecl)inits.head;
2625                 accept(COLON);
2626                 JCExpression expr = parseExpression();
2627                 accept(RPAREN);
2628                 JCStatement body = parseStatementAsBlock();
2629                 return F.at(pos).ForeachLoop(var, expr, body);
2630             } else {
2631                 accept(SEMI);
2632                 JCExpression cond = token.kind == SEMI ? null : parseExpression();
2633                 accept(SEMI);
2634                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.nil() : forUpdate();
2635                 accept(RPAREN);
2636                 JCStatement body = parseStatementAsBlock();
2637                 return F.at(pos).ForLoop(inits, cond, steps, body);
2638             }
2639         }
2640         case WHILE: {
2641             nextToken();
2642             JCExpression cond = parExpression();
2643             JCStatement body = parseStatementAsBlock();
2644             return F.at(pos).WhileLoop(cond, body);
2645         }
2646         case DO: {
2647             nextToken();
2648             JCStatement body = parseStatementAsBlock();
2649             accept(WHILE);
2650             JCExpression cond = parExpression();
2651             accept(SEMI);
2652             JCDoWhileLoop t = toP(F.at(pos).DoLoop(body, cond));
2653             return t;
2654         }
2655         case TRY: {
2656             nextToken();
2657             List<JCTree> resources = List.nil();
2658             if (token.kind == LPAREN) {
2659                 nextToken();
2660                 resources = resources();
2661                 accept(RPAREN);
2662             }
2663             JCBlock body = block();
2664             ListBuffer<JCCatch> catchers = new ListBuffer<>();
2665             JCBlock finalizer = null;
2666             if (token.kind == CATCH || token.kind == FINALLY) {
2667                 while (token.kind == CATCH) catchers.append(catchClause());
2668                 if (token.kind == FINALLY) {
2669                     nextToken();
2670                     finalizer = block();
2671                 }
2672             } else {
2673                 if (resources.isEmpty()) {
2674                     log.error(DiagnosticFlag.SYNTAX, pos, Errors.TryWithoutCatchFinallyOrResourceDecls);
2675                 }
2676             }
2677             return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
2678         }
2679         case SWITCH: {
2680             nextToken();
2681             JCExpression selector = parExpression();
2682             accept(LBRACE);
2683             List<JCCase> cases = switchBlockStatementGroups();
2684             JCSwitch t = to(F.at(pos).Switch(selector, cases));
2685             accept(RBRACE);
2686             return t;
2687         }
2688         case SYNCHRONIZED: {
2689             nextToken();
2690             JCExpression lock = parExpression();
2691             JCBlock body = block();
2692             return F.at(pos).Synchronized(lock, body);
2693         }
2694         case RETURN: {
2695             nextToken();
2696             JCExpression result = token.kind == SEMI ? null : parseExpression();
2697             accept(SEMI);
2698             JCReturn t = toP(F.at(pos).Return(result));
2699             return t;
2700         }
2701         case THROW: {
2702             nextToken();
2703             JCExpression exc = parseExpression();
2704             accept(SEMI);
2705             JCThrow t = toP(F.at(pos).Throw(exc));
2706             return t;
2707         }
2708         case BREAK: {
2709             nextToken();
2710             JCExpression value = token.kind == SEMI ? null : parseExpression();
2711             accept(SEMI);
2712             JCBreak t = toP(F.at(pos).Break(value));
2713             return t;
2714         }
2715         case CONTINUE: {
2716             nextToken();
2717             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2718             accept(SEMI);
2719             JCContinue t =  toP(F.at(pos).Continue(label));
2720             return t;
2721         }
2722         case SEMI:
2723             nextToken();
2724             return toP(F.at(pos).Skip());
2725         case ELSE:
2726             int elsePos = token.pos;
2727             nextToken();
2728             return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.ElseWithoutIf);
2729         case FINALLY:
2730             int finallyPos = token.pos;
2731             nextToken();
2732             return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, Errors.FinallyWithoutTry);
2733         case CATCH:
2734             return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, Errors.CatchWithoutTry);
2735         case ASSERT: {
2736             nextToken();
2737             JCExpression assertion = parseExpression();
2738             JCExpression message = null;
2739             if (token.kind == COLON) {
2740                 nextToken();
2741                 message = parseExpression();
2742             }
2743             accept(SEMI);
2744             JCAssert t = toP(F.at(pos).Assert(assertion, message));
2745             return t;
2746         }
2747         default:
2748             Assert.error();
2749             return null;
2750         }
2751     }
2752 
2753     @Override
2754     public JCStatement parseStatement() {
2755         return parseStatementAsBlock();
2756     }
2757 
2758     private JCStatement doRecover(int startPos, ErrorRecoveryAction action, Error errorKey) {
2759         int errPos = S.errPos();
2760         JCTree stm = action.doRecover(this);
2761         S.errPos(errPos);
2762         return toP(F.Exec(syntaxError(startPos, List.of(stm), errorKey)));
2763     }
2764 
2765     /** CatchClause     = CATCH "(" FormalParameter ")" Block
2766      * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
2767      */
2768     protected JCCatch catchClause() {
2769         int pos = token.pos;
2770         accept(CATCH);
2771         accept(LPAREN);
2772         JCModifiers mods = optFinal(Flags.PARAMETER);
2773         List<JCExpression> catchTypes = catchTypes();
2774         JCExpression paramType = catchTypes.size() > 1 ?
2775                 toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
2776                 catchTypes.head;
2777         JCVariableDecl formal = variableDeclaratorId(mods, paramType);
2778         accept(RPAREN);
2779         JCBlock body = block();
2780         return F.at(pos).Catch(formal, body);
2781     }
2782 
2783     List<JCExpression> catchTypes() {
2784         ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
2785         catchTypes.add(parseType());
2786         while (token.kind == BAR) {
2787             nextToken();
2788             // Instead of qualident this is now parseType.
2789             // But would that allow too much, e.g. arrays or generics?
2790             catchTypes.add(parseType());
2791         }
2792         return catchTypes.toList();
2793     }
2794 
2795     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2796      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2797      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2798      */
2799     List<JCCase> switchBlockStatementGroups() {
2800         ListBuffer<JCCase> cases = new ListBuffer<>();
2801         while (true) {
2802             int pos = token.pos;
2803             switch (token.kind) {
2804             case CASE:
2805             case DEFAULT:
2806                 cases.appendList(switchBlockStatementGroup());
2807                 break;
2808             case RBRACE: case EOF:
2809                 return cases.toList();
2810             default:
2811                 nextToken(); // to ensure progress
2812                 syntaxError(pos, Errors.Expected3(CASE, DEFAULT, RBRACE));
2813             }
2814         }
2815     }
2816 
2817     protected List<JCCase> switchBlockStatementGroup() {
2818         int pos = token.pos;
2819         List<JCStatement> stats;
2820         JCCase c;
2821         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2822         switch (token.kind) {
2823         case CASE: {
2824             nextToken();
2825             ListBuffer<JCExpression> pats = new ListBuffer<>();
2826             while (true) {
2827                 pats.append(term(EXPR | NOLAMBDA));
2828                 if (token.kind != COMMA) break;
2829                 nextToken();
2830                 checkSourceLevel(Feature.SWITCH_MULTIPLE_CASE_LABELS);
2831             };
2832             @SuppressWarnings("removal")
2833             CaseKind caseKind;
2834             JCTree body = null;
2835             if (token.kind == ARROW) {
2836                 checkSourceLevel(Feature.SWITCH_RULE);
2837                 accept(ARROW);
2838                 caseKind = JCCase.RULE;
2839                 JCStatement statement = parseStatementAsBlock();
2840                 if (!statement.hasTag(EXEC) && !statement.hasTag(BLOCK) && !statement.hasTag(Tag.THROW)) {
2841                     log.error(statement.pos(), Errors.SwitchCaseUnexpectedStatement);
2842                 }
2843                 stats = List.of(statement);
2844                 body = stats.head;
2845             } else {
2846                 accept(COLON, tk -> Errors.Expected2(COLON, ARROW));
2847                 caseKind = JCCase.STATEMENT;
2848                 stats = blockStatements();
2849             }
2850             c = F.at(pos).Case(caseKind, pats.toList(), stats, body);
2851             if (stats.isEmpty())
2852                 storeEnd(c, S.prevToken().endPos);
2853             return cases.append(c).toList();
2854         }
2855         case DEFAULT: {
2856             nextToken();
2857             @SuppressWarnings("removal")
2858             CaseKind caseKind;
2859             JCTree body = null;
2860             if (token.kind == ARROW) {
2861                 checkSourceLevel(Feature.SWITCH_RULE);
2862                 accept(ARROW);
2863                 caseKind = JCCase.RULE;
2864                 JCStatement statement = parseStatementAsBlock();
2865                 if (!statement.hasTag(EXEC) && !statement.hasTag(BLOCK) && !statement.hasTag(Tag.THROW)) {
2866                     log.error(statement.pos(), Errors.SwitchCaseUnexpectedStatement);
2867                 }
2868                 stats = List.of(statement);
2869                 body = stats.head;
2870             } else {
2871                 accept(COLON, tk -> Errors.Expected2(COLON, ARROW));
2872                 caseKind = JCCase.STATEMENT;
2873                 stats = blockStatements();
2874             }
2875             c = F.at(pos).Case(caseKind, List.nil(), stats, body);
2876             if (stats.isEmpty())
2877                 storeEnd(c, S.prevToken().endPos);
2878             return cases.append(c).toList();
2879         }
2880         }
2881         throw new AssertionError("should not reach here");
2882     }
2883 
2884     /** MoreStatementExpressions = { COMMA StatementExpression }
2885      */
2886     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2887                                                                     JCExpression first,
2888                                                                     T stats) {
2889         // This Exec is a "StatementExpression"; it subsumes no terminating token
2890         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2891         while (token.kind == COMMA) {
2892             nextToken();
2893             pos = token.pos;
2894             JCExpression t = parseExpression();
2895             // This Exec is a "StatementExpression"; it subsumes no terminating token
2896             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2897         }
2898         return stats;
2899     }
2900 
2901     /** ForInit = StatementExpression MoreStatementExpressions
2902      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2903      */
2904     List<JCStatement> forInit() {
2905         ListBuffer<JCStatement> stats = new ListBuffer<>();
2906         int pos = token.pos;
2907         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
2908             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
2909         } else {
2910             JCExpression t = term(EXPR | TYPE);
2911             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2912                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();
2913             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
2914                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
2915                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
2916             } else {
2917                 return moreStatementExpressions(pos, t, stats).toList();
2918             }
2919         }
2920     }
2921 
2922     /** ForUpdate = StatementExpression MoreStatementExpressions
2923      */
2924     List<JCExpressionStatement> forUpdate() {
2925         return moreStatementExpressions(token.pos,
2926                                         parseExpression(),
2927                                         new ListBuffer<JCExpressionStatement>()).toList();
2928     }
2929 
2930     /** AnnotationsOpt = { '@' Annotation }
2931      *
2932      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2933      */
2934     protected List<JCAnnotation> annotationsOpt(Tag kind) {
2935         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
2936         ListBuffer<JCAnnotation> buf = new ListBuffer<>();
2937         int prevmode = mode;
2938         while (token.kind == MONKEYS_AT) {
2939             int pos = token.pos;
2940             nextToken();
2941             buf.append(annotation(pos, kind));
2942         }
2943         lastmode = mode;
2944         mode = prevmode;
2945         List<JCAnnotation> annotations = buf.toList();
2946 
2947         return annotations;
2948     }
2949 
2950     List<JCAnnotation> typeAnnotationsOpt() {
2951         List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
2952         return annotations;
2953     }
2954 
2955     /** ModifiersOpt = { Modifier }
2956      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2957      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2958      *           | "@" Annotation
2959      */
2960     protected JCModifiers modifiersOpt() {
2961         return modifiersOpt(null);
2962     }
2963     protected JCModifiers modifiersOpt(JCModifiers partial) {
2964         long flags;
2965         ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
2966         int pos;
2967         if (partial == null) {
2968             flags = 0;
2969             pos = token.pos;
2970         } else {
2971             flags = partial.flags;
2972             annotations.appendList(partial.annotations);
2973             pos = partial.pos;
2974         }
2975         if (token.deprecatedFlag()) {
2976             flags |= Flags.DEPRECATED;
2977         }
2978         int lastPos;
2979     loop:
2980         while (true) {
2981             long flag;
2982             switch (token.kind) {
2983             case PRIVATE     : flag = Flags.PRIVATE; break;
2984             case PROTECTED   : flag = Flags.PROTECTED; break;
2985             case PUBLIC      : flag = Flags.PUBLIC; break;
2986             case STATIC      : flag = Flags.STATIC; break;
2987             case TRANSIENT   : flag = Flags.TRANSIENT; break;
2988             case FINAL       : flag = Flags.FINAL; break;
2989             case ABSTRACT    : flag = Flags.ABSTRACT; break;
2990             case NATIVE      : flag = Flags.NATIVE; break;
2991             case VOLATILE    : flag = Flags.VOLATILE; break;
2992             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2993             case STRICTFP    : flag = Flags.STRICTFP; break;
2994             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2995             case DEFAULT     : checkSourceLevel(Feature.DEFAULT_METHODS); flag = Flags.DEFAULT; break;
2996             case ERROR       : flag = 0; nextToken(); break;
2997             case IDENTIFIER  : {
2998                 if (token.name() == names.non && peekToken(0, TokenKind.SUB, TokenKind.FINAL)) {
2999                     Token tokenSub = S.token(1);
3000                     Token tokenFinal = S.token(2);
3001                     if (token.endPos == tokenSub.pos && tokenSub.endPos == tokenFinal.pos) {
3002                         flag = Flags.NON_FINAL;
3003                         nextToken();
3004                         nextToken();
3005                         break;
3006                     }
3007                 }
3008                 if (isSealedClassDeclaration()) {
3009                     flag = Flags.SEALED;
3010                     break;
3011                 }
3012                 break loop;
3013             }
3014             default: break loop;
3015             }
3016             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3017             lastPos = token.pos;
3018             nextToken();
3019             if (flag == Flags.ANNOTATION) {
3020                 if (token.kind != INTERFACE) {
3021                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3022                     // if first modifier is an annotation, set pos to annotation's.
3023                     if (flags == 0 && annotations.isEmpty())
3024                         pos = ann.pos;
3025                     annotations.append(ann);
3026                     flag = 0;
3027                 }
3028             }
3029             flags |= flag;
3030         }
3031         switch (token.kind) {
3032         case ENUM: flags |= Flags.ENUM; break;
3033         case INTERFACE: flags |= Flags.INTERFACE; break;
3034         default: break;
3035         }
3036 
3037         /* A modifiers tree with no modifier tokens or annotations
3038          * has no text position. */
3039         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
3040             pos = Position.NOPOS;
3041 
3042         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
3043         if (pos != Position.NOPOS)
3044             storeEnd(mods, S.prevToken().endPos);
3045         return mods;
3046     }
3047 
3048     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
3049      *
3050      * @param pos position of "@" token
3051      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3052      */
3053     JCAnnotation annotation(int pos, Tag kind) {
3054         // accept(AT); // AT consumed by caller
3055         if (kind == Tag.TYPE_ANNOTATION) {
3056             checkSourceLevel(Feature.TYPE_ANNOTATIONS);
3057         }
3058         JCTree ident = qualident(false);
3059         List<JCExpression> fieldValues = annotationFieldValuesOpt();
3060         JCAnnotation ann;
3061         if (kind == Tag.ANNOTATION) {
3062             ann = F.at(pos).Annotation(ident, fieldValues);
3063         } else if (kind == Tag.TYPE_ANNOTATION) {
3064             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
3065         } else {
3066             throw new AssertionError("Unhandled annotation kind: " + kind);
3067         }
3068 
3069         storeEnd(ann, S.prevToken().endPos);
3070         return ann;
3071     }
3072 
3073     List<JCExpression> annotationFieldValuesOpt() {
3074         return (token.kind == LPAREN) ? annotationFieldValues() : List.nil();
3075     }
3076 
3077     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
3078     List<JCExpression> annotationFieldValues() {
3079         accept(LPAREN);
3080         ListBuffer<JCExpression> buf = new ListBuffer<>();
3081         if (token.kind != RPAREN) {
3082             buf.append(annotationFieldValue());
3083             while (token.kind == COMMA) {
3084                 nextToken();
3085                 buf.append(annotationFieldValue());
3086             }
3087         }
3088         accept(RPAREN);
3089         return buf.toList();
3090     }
3091 
3092     /** AnnotationFieldValue    = AnnotationValue
3093      *                          | Identifier "=" AnnotationValue
3094      */
3095     JCExpression annotationFieldValue() {
3096         if (LAX_IDENTIFIER.accepts(token.kind)) {
3097             selectExprMode();
3098             JCExpression t1 = term1();
3099             if (t1.hasTag(IDENT) && token.kind == EQ) {
3100                 int pos = token.pos;
3101                 accept(EQ);
3102                 JCExpression v = annotationValue();
3103                 return toP(F.at(pos).Assign(t1, v));
3104             } else {
3105                 return t1;
3106             }
3107         }
3108         return annotationValue();
3109     }
3110 
3111     /* AnnotationValue          = ConditionalExpression
3112      *                          | Annotation
3113      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
3114      */
3115     JCExpression annotationValue() {
3116         int pos;
3117         switch (token.kind) {
3118         case MONKEYS_AT:
3119             pos = token.pos;
3120             nextToken();
3121             return annotation(pos, Tag.ANNOTATION);
3122         case LBRACE:
3123             pos = token.pos;
3124             accept(LBRACE);
3125             ListBuffer<JCExpression> buf = new ListBuffer<>();
3126             if (token.kind == COMMA) {
3127                 nextToken();
3128             } else if (token.kind != RBRACE) {
3129                 buf.append(annotationValue());
3130                 while (token.kind == COMMA) {
3131                     nextToken();
3132                     if (token.kind == RBRACE) break;
3133                     buf.append(annotationValue());
3134                 }
3135             }
3136             accept(RBRACE);
3137             return toP(F.at(pos).NewArray(null, List.nil(), buf.toList()));
3138         default:
3139             selectExprMode();
3140             return term1();
3141         }
3142     }
3143 
3144     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
3145      */
3146     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
3147                                                                          JCExpression type,
3148                                                                          T vdefs,
3149                                                                          boolean localDecl)
3150     {
3151         return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs, localDecl);
3152     }
3153 
3154     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
3155      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
3156      *
3157      *  @param reqInit  Is an initializer always required?
3158      *  @param dc       The documentation comment for the variable declarations, or null.
3159      */
3160     protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
3161                                                                      JCModifiers mods,
3162                                                                      JCExpression type,
3163                                                                      Name name,
3164                                                                      boolean reqInit,
3165                                                                      Comment dc,
3166                                                                      T vdefs,
3167                                                                      boolean localDecl)
3168     {
3169         JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl, false);
3170         vdefs.append(head);
3171         while (token.kind == COMMA) {
3172             // All but last of multiple declarators subsume a comma
3173             storeEnd((JCTree)vdefs.last(), token.endPos);
3174             nextToken();
3175             vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
3176         }
3177         return vdefs;
3178     }
3179 
3180     /** VariableDeclarator = Ident VariableDeclaratorRest
3181      *  ConstantDeclarator = Ident ConstantDeclaratorRest
3182      */
3183     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) {
3184         return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl, true);
3185     }
3186 
3187     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
3188      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
3189      *
3190      *  @param reqInit  Is an initializer always required?
3191      *  @param dc       The documentation comment for the variable declarations, or null.
3192      */
3193     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
3194                                   boolean reqInit, Comment dc, boolean localDecl, boolean compound) {
3195         type = bracketsOpt(type);
3196         JCExpression init = null;
3197         if (token.kind == EQ) {
3198             nextToken();
3199             init = variableInitializer();
3200         }
3201         else if (reqInit) syntaxError(token.pos, Errors.Expected(EQ));
3202         JCTree elemType = TreeInfo.innermostType(type, true);
3203         int startPos = Position.NOPOS;
3204         if (elemType.hasTag(IDENT)) {
3205             Name typeName = ((JCIdent)elemType).name;
3206             if (isRestrictedLocalVarTypeName(typeName, pos, !compound && localDecl)) {
3207                 if (type.hasTag(TYPEARRAY) && !compound) {
3208                     //error - 'var' and arrays
3209                     reportSyntaxError(pos, Errors.VarNotAllowedArray);
3210                 } else {
3211                     if(compound)
3212                         //error - 'var' in compound local var decl
3213                         reportSyntaxError(pos, Errors.VarNotAllowedCompound);
3214                     startPos = TreeInfo.getStartPos(mods);
3215                     if (startPos == Position.NOPOS)
3216                         startPos = TreeInfo.getStartPos(type);
3217                     //implicit type
3218                     type = null;
3219                 }
3220             }
3221         }
3222         JCVariableDecl result =
3223             toP(F.at(pos).VarDef(mods, name, type, init));
3224         attach(result, dc);
3225         result.startPos = startPos;
3226         return result;
3227     }
3228 
3229     boolean isRestrictedLocalVarTypeName(JCExpression e, boolean shouldWarn) {
3230         switch (e.getTag()) {
3231             case IDENT:
3232                 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos, shouldWarn);
3233             case TYPEARRAY:
3234                 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
3235             default:
3236                 return false;
3237         }
3238     }
3239 
3240     boolean isRestrictedLocalVarTypeName(Name name, int pos, boolean shouldWarn) {
3241         if (name == names.var) {
3242             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3243                 return true;
3244             } else if (shouldWarn) {
3245                 log.warning(pos, Warnings.VarNotAllowed);
3246             }
3247         }
3248         return false;
3249     }
3250 
3251     boolean isRestrictedRecordTypeName(Name name) {
3252         return Feature.RECORDS.allowedInSource(source) && name == names.record;
3253     }
3254 
3255     /** VariableDeclaratorId = Ident BracketsOpt
3256      */
3257     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3258         return variableDeclaratorId(mods, type, false);
3259     }
3260     //where
3261     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3262         int pos = token.pos;
3263         Name name;
3264         if (lambdaParameter && token.kind == UNDERSCORE) {
3265             log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3266             name = token.name();
3267             nextToken();
3268         } else {
3269             if (allowThisIdent ||
3270                 !lambdaParameter ||
3271                 LAX_IDENTIFIER.accepts(token.kind) ||
3272                 mods.flags != Flags.PARAMETER ||
3273                 mods.annotations.nonEmpty()) {
3274                 JCExpression pn = qualident(false);
3275                 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3276                     name = ((JCIdent)pn).name;
3277                 } else {
3278                     if (allowThisIdent) {
3279                         if ((mods.flags & Flags.VARARGS) != 0) {
3280                             log.error(token.pos, Errors.VarargsAndReceiver);
3281                         }
3282                         if (token.kind == LBRACKET) {
3283                             log.error(token.pos, Errors.ArrayAndReceiver);
3284                         }
3285                         if (pn.hasTag(Tag.SELECT) && ((JCFieldAccess)pn).name != names._this) {
3286                             log.error(token.pos, Errors.WrongReceiver);
3287                         }
3288                     }
3289                     return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
3290                 }
3291             } else {
3292                 /** if it is a lambda parameter and the token kind is not an identifier,
3293                  *  and there are no modifiers or annotations, then this means that the compiler
3294                  *  supposed the lambda to be explicit but it can contain a mix of implicit,
3295                  *  var or explicit parameters. So we assign the error name to the parameter name
3296                  *  instead of issuing an error and analyze the lambda parameters as a whole at
3297                  *  a higher level.
3298                  */
3299                 name = names.empty;
3300             }
3301         }
3302         if ((mods.flags & Flags.VARARGS) != 0 &&
3303                 token.kind == LBRACKET) {
3304             log.error(token.pos, Errors.VarargsAndOldArraySyntax);
3305         }
3306         type = bracketsOpt(type);
3307         return toP(F.at(pos).VarDef(mods, name, type, null));
3308     }
3309 
3310     /** Resources = Resource { ";" Resources }
3311      */
3312     List<JCTree> resources() {
3313         ListBuffer<JCTree> defs = new ListBuffer<>();
3314         defs.append(resource());
3315         while (token.kind == SEMI) {
3316             // All but last of multiple declarators must subsume a semicolon
3317             storeEnd(defs.last(), token.endPos);
3318             int semiColonPos = token.pos;
3319             nextToken();
3320             if (token.kind == RPAREN) { // Optional trailing semicolon
3321                                        // after last resource
3322                 break;
3323             }
3324             defs.append(resource());
3325         }
3326         return defs.toList();
3327     }
3328 
3329     /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
3330      *           | Expression
3331      */
3332     protected JCTree resource() {
3333         int startPos = token.pos;
3334         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3335             JCModifiers mods = optFinal(Flags.FINAL);
3336             JCExpression t = parseType(true);
3337             return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true, false);
3338         }
3339         JCExpression t = term(EXPR | TYPE);
3340         if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
3341             JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
3342             return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true, false);
3343         } else {
3344             checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES);
3345             if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
3346                 log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar);
3347             }
3348 
3349             return t;
3350         }
3351     }
3352 
3353     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
3354      */
3355     public JCTree.JCCompilationUnit parseCompilationUnit() {
3356         Token firstToken = token;
3357         JCModifiers mods = null;
3358         boolean consumedToplevelDoc = false;
3359         boolean seenImport = false;
3360         boolean seenPackage = false;
3361         ListBuffer<JCTree> defs = new ListBuffer<>();
3362         if (token.kind == MONKEYS_AT)
3363             mods = modifiersOpt();
3364 
3365         if (token.kind == PACKAGE) {
3366             int packagePos = token.pos;
3367             List<JCAnnotation> annotations = List.nil();
3368             seenPackage = true;
3369             if (mods != null) {
3370                 checkNoMods(mods.flags);
3371                 annotations = mods.annotations;
3372                 mods = null;
3373             }
3374             nextToken();
3375             JCExpression pid = qualident(false);
3376             accept(SEMI);
3377             JCPackageDecl pd = toP(F.at(packagePos).PackageDecl(annotations, pid));
3378             attach(pd, firstToken.comment(CommentStyle.JAVADOC));
3379             consumedToplevelDoc = true;
3380             defs.append(pd);
3381         }
3382 
3383         boolean checkForImports = true;
3384         boolean firstTypeDecl = true;
3385         while (token.kind != EOF) {
3386             if (token.pos <= endPosTable.errorEndPos) {
3387                 // error recovery
3388                 skip(checkForImports, false, false, false);
3389                 if (token.kind == EOF)
3390                     break;
3391             }
3392             if (checkForImports && mods == null && token.kind == IMPORT) {
3393                 seenImport = true;
3394                 defs.append(importDeclaration());
3395             } else {
3396                 Comment docComment = token.comment(CommentStyle.JAVADOC);
3397                 if (firstTypeDecl && !seenImport && !seenPackage) {
3398                     docComment = firstToken.comment(CommentStyle.JAVADOC);
3399                     consumedToplevelDoc = true;
3400                 }
3401                 if (mods != null || token.kind != SEMI)
3402                     mods = modifiersOpt(mods);
3403                 if (firstTypeDecl && token.kind == IDENTIFIER) {
3404                     ModuleKind kind = ModuleKind.STRONG;
3405                     if (token.name() == names.open) {
3406                         kind = ModuleKind.OPEN;
3407                         nextToken();
3408                     }
3409                     if (token.kind == IDENTIFIER && token.name() == names.module) {
3410                         if (mods != null) {
3411                             checkNoMods(mods.flags & ~Flags.DEPRECATED);
3412                         }
3413                         defs.append(moduleDecl(mods, kind, docComment));
3414                         consumedToplevelDoc = true;
3415                         break;
3416                     } else if (kind != ModuleKind.STRONG) {
3417                         reportSyntaxError(token.pos, Errors.ExpectedModule);
3418                     }
3419                 }
3420                 JCTree def = typeDeclaration(mods, docComment);
3421                 if (def instanceof JCExpressionStatement)
3422                     def = ((JCExpressionStatement)def).expr;
3423                 defs.append(def);
3424                 if (def instanceof JCClassDecl)
3425                     checkForImports = false;
3426                 mods = null;
3427                 firstTypeDecl = false;
3428             }
3429         }
3430         JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
3431         if (!consumedToplevelDoc)
3432             attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
3433         if (defs.isEmpty())
3434             storeEnd(toplevel, S.prevToken().endPos);
3435         if (keepDocComments)
3436             toplevel.docComments = docComments;
3437         if (keepLineMap)
3438             toplevel.lineMap = S.getLineMap();
3439         this.endPosTable.setParser(null); // remove reference to parser
3440         toplevel.endPositions = this.endPosTable;
3441         return toplevel;
3442     }
3443 
3444     JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
3445         int pos = token.pos;
3446         checkSourceLevel(Feature.MODULES);
3447 
3448         nextToken();
3449         JCExpression name = qualident(false);
3450         List<JCDirective> directives = null;
3451 
3452         accept(LBRACE);
3453         directives = moduleDirectiveList();
3454         accept(RBRACE);
3455         accept(EOF);
3456 
3457         JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives));
3458         attach(result, dc);
3459         return result;
3460     }
3461 
3462     List<JCDirective> moduleDirectiveList() {
3463         ListBuffer<JCDirective> defs = new ListBuffer<>();
3464         while (token.kind == IDENTIFIER) {
3465             int pos = token.pos;
3466             if (token.name() == names.requires) {
3467                 nextToken();
3468                 boolean isTransitive = false;
3469                 boolean isStaticPhase = false;
3470             loop:
3471                 while (true) {
3472                     switch (token.kind) {
3473                         case IDENTIFIER:
3474                             if (token.name() == names.transitive && !isTransitive) {
3475                                 Token t1 = S.token(1);
3476                                 if (t1.kind == SEMI || t1.kind == DOT) {
3477                                     break loop;
3478                                 }
3479                                 isTransitive = true;
3480                                 break;
3481                             } else {
3482                                 break loop;
3483                             }
3484                         case STATIC:
3485                             if (isStaticPhase) {
3486                                 log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3487                             }
3488                             isStaticPhase = true;
3489                             break;
3490                         default:
3491                             break loop;
3492                     }
3493                     nextToken();
3494                 }
3495                 JCExpression moduleName = qualident(false);
3496                 accept(SEMI);
3497                 defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName)));
3498             } else if (token.name() == names.exports || token.name() == names.opens) {
3499                 boolean exports = token.name() == names.exports;
3500                 nextToken();
3501                 JCExpression pkgName = qualident(false);
3502                 List<JCExpression> moduleNames = null;
3503                 if (token.kind == IDENTIFIER && token.name() == names.to) {
3504                     nextToken();
3505                     moduleNames = qualidentList(false);
3506                 }
3507                 accept(SEMI);
3508                 JCDirective d;
3509                 if (exports) {
3510                     d = F.at(pos).Exports(pkgName, moduleNames);
3511                 } else {
3512                     d = F.at(pos).Opens(pkgName, moduleNames);
3513                 }
3514                 defs.append(toP(d));
3515             } else if (token.name() == names.provides) {
3516                 nextToken();
3517                 JCExpression serviceName = qualident(false);
3518                 if (token.kind == IDENTIFIER && token.name() == names.with) {
3519                     nextToken();
3520                     List<JCExpression> implNames = qualidentList(false);
3521                     accept(SEMI);
3522                     defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
3523                 } else {
3524                     log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.ExpectedStr("'" + names.with + "'"));
3525                     skip(false, false, false, false);
3526                 }
3527             } else if (token.name() == names.uses) {
3528                 nextToken();
3529                 JCExpression service = qualident(false);
3530                 accept(SEMI);
3531                 defs.append(toP(F.at(pos).Uses(service)));
3532             } else {
3533                 setErrorEndPos(pos);
3534                 reportSyntaxError(pos, Errors.InvalidModuleDirective);
3535                 break;
3536             }
3537         }
3538         return defs.toList();
3539     }
3540 
3541     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
3542      */
3543     protected JCTree importDeclaration() {
3544         int pos = token.pos;
3545         nextToken();
3546         boolean importStatic = false;
3547         if (token.kind == STATIC) {
3548             importStatic = true;
3549             nextToken();
3550         }
3551         JCExpression pid = toP(F.at(token.pos).Ident(ident()));
3552         do {
3553             int pos1 = token.pos;
3554             accept(DOT);
3555             if (token.kind == STAR) {
3556                 pid = to(F.at(pos1).Select(pid, names.asterisk));
3557                 nextToken();
3558                 break;
3559             } else {
3560                 pid = toP(F.at(pos1).Select(pid, ident()));
3561             }
3562         } while (token.kind == DOT);
3563         accept(SEMI);
3564         return toP(F.at(pos).Import(pid, importStatic));
3565     }
3566 
3567     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3568      *                  | ";"
3569      */
3570     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3571         int pos = token.pos;
3572         if (mods == null && token.kind == SEMI) {
3573             nextToken();
3574             return toP(F.at(pos).Skip());
3575         } else {
3576             return classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3577         }
3578     }
3579 
3580     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3581      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3582      *  @param mods     Any modifiers starting the class or interface declaration
3583      *  @param dc       The documentation comment for the class, or null.
3584      */
3585     protected JCStatement classOrRecordOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3586         if (token.kind == CLASS) {
3587             return classDeclaration(mods, dc);
3588         } if (isRecordDeclaration()) {
3589             return recordDeclaration(mods, dc);
3590         } else if (token.kind == INTERFACE) {
3591             return interfaceDeclaration(mods, dc);
3592         } else if (token.kind == ENUM) {
3593             return enumDeclaration(mods, dc);
3594         } else {
3595             int pos = token.pos;
3596             List<JCTree> errs;
3597             if (LAX_IDENTIFIER.accepts(token.kind)) {
3598                 errs = List.of(mods, toP(F.at(pos).Ident(ident())));
3599                 setErrorEndPos(token.pos);
3600             } else {
3601                 errs = List.of(mods);
3602             }
3603             final JCErroneous erroneousTree;
3604             if (parseModuleInfo) {
3605                 erroneousTree = syntaxError(pos, errs, Errors.ExpectedModuleOrOpen);
3606             } else {
3607                 erroneousTree = syntaxError(pos, errs, Errors.Expected4(CLASS, INTERFACE, ENUM, RECORD));
3608             }
3609             return toP(F.Exec(erroneousTree));
3610         }
3611     }
3612 
3613     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3614      *                     [IMPLEMENTS TypeList] ClassBody
3615      *  @param mods    The modifiers starting the class declaration
3616      *  @param dc       The documentation comment for the class, or null.
3617      */
3618     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3619         int pos = token.pos;
3620         accept(CLASS);
3621         Name name = typeName();
3622 
3623         List<JCTypeParameter> typarams = typeParametersOpt();
3624 
3625         JCExpression extending = null;
3626         if (token.kind == EXTENDS) {
3627             nextToken();
3628             extending = parseType();
3629         }
3630         List<JCExpression> implementing = List.nil();
3631         if (token.kind == IMPLEMENTS) {
3632             nextToken();
3633             implementing = typeList();
3634         }
3635         List<JCExpression> permitting = List.nil();
3636         if (token.kind == IDENTIFIER && token.name() == names.permits) {
3637             if ((mods.flags & Flags.SEALED) == 0) {
3638                 log.error(token.pos, Errors.PermitsInNoSealedClass);
3639             }
3640             nextToken();
3641             permitting = typeList();
3642         }
3643         List<JCTree> defs = classInterfaceOrRecordBody(name, false, false);
3644         JCClassDecl result = toP(F.at(pos).ClassDef(
3645             mods, name, typarams, extending, implementing, permitting, defs));
3646         attach(result, dc);
3647         return result;
3648     }
3649 
3650     protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
3651         int pos = token.pos;
3652         if ((mods.flags & Flags.ABSTRACT) != 0) {
3653             log.error(mods.pos, Errors.RecordCantBeAbstract);
3654         }
3655         nextToken();
3656         mods.flags |= Flags.RECORD | Flags.STATIC | Flags.FINAL;
3657         Name name = typeName();
3658 
3659         List<JCTypeParameter> typarams = typeParametersOpt();
3660 
3661         Map<Name, JCVariableDecl> optHeaderFields = headerFields(mods);
3662 
3663         List<JCExpression> implementing = List.nil();
3664         if (token.kind == IMPLEMENTS) {
3665             nextToken();
3666             implementing = typeList();
3667         }
3668         List<JCTree> defs = List.nil();
3669         if (token.kind == LBRACE) {
3670             defs = classInterfaceOrRecordBody(name, false, true);
3671         } else {
3672             accept(SEMI);
3673         }
3674         java.util.List<JCVariableDecl> fields = new ArrayList<>();
3675         for (JCVariableDecl field : optHeaderFields.values()) {
3676             fields.add(field);
3677         }
3678         for (JCTree def : defs) {
3679             if (def.hasTag(METHODDEF)) {
3680                 JCMethodDecl methDef = (JCMethodDecl) def;
3681                 if (methDef.name == names.init && methDef.params.isEmpty()) {
3682                     if ((methDef.mods.flags & Flags.PUBLIC) == 0) {
3683                         log.error(methDef, Errors.MethodMustBePublic(names.init));
3684                     }
3685                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
3686                     for (JCVariableDecl param : fields) {
3687                         tmpParams.add(F.at(param).VarDef(F.Modifiers(Flags.PARAMETER), param.name, param.vartype, null));
3688                     }
3689                     methDef.params = tmpParams.toList();
3690                 }
3691             }
3692         }
3693         for (int i = fields.size() - 1; i >= 0; i--) {
3694             defs = defs.prepend(fields.get(i));
3695         }
3696         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
3697         attach(result, dc);
3698         return result;
3699     }
3700 
3701     Name typeName() {
3702         int pos = token.pos;
3703         Name name = ident();
3704         if (isRestrictedLocalVarTypeName(name, pos, true)) {
3705             reportSyntaxError(pos, Errors.VarNotAllowed);
3706         }
3707 
3708         if (isRestrictedRecordTypeName(name)) {
3709             reportSyntaxError(pos, Errors.RecordNotAllowed(name));
3710         }
3711         return name;
3712     }
3713 
3714     Map<Name, JCVariableDecl> headerFields(JCModifiers recordClassMods) {
3715         accept(LPAREN);
3716         Map<Name, JCVariableDecl> fields = new LinkedHashMap<>();
3717         while (token.kind != RPAREN) {
3718             JCModifiers mods = modifiersOpt();
3719             if (mods.flags != 0) {
3720                 log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
3721             }
3722             mods.flags |= Flags.RECORD | Flags.FINAL;
3723             mods.flags |= (recordClassMods.flags & Flags.ABSTRACT) != 0 ? Flags.PROTECTED : 0;
3724             JCExpression type = parseType();
3725             int pos = token.pos;
3726             Name id = ident();
3727             if (!fields.containsKey(id)) {
3728                 List<Pair<Accessors.Kind, Name>> accessors = List.of(new Pair<>(Accessors.Kind.GET, id));
3729                 fields.put(id, toP(F.at(pos).VarDef(mods, id, type, null, accessors)));
3730             } else {
3731                 log.error(pos, Errors.RecordCantDeclareDuplicateFields);
3732             }
3733             if (token.kind == COMMA) {
3734                 nextToken();
3735             }
3736         }
3737         accept(RPAREN);
3738         return fields;
3739     }
3740 
3741     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3742      *                         [EXTENDS TypeList] InterfaceBody
3743      *  @param mods    The modifiers starting the interface declaration
3744      *  @param dc       The documentation comment for the interface, or null.
3745      */
3746     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3747         int pos = token.pos;
3748         accept(INTERFACE);
3749 
3750         Name name = typeName();
3751 
3752         List<JCTypeParameter> typarams = typeParametersOpt();
3753 
3754         List<JCExpression> extending = List.nil();
3755         if (token.kind == EXTENDS) {
3756             nextToken();
3757             extending = typeList();
3758         }
3759         List<JCExpression> permitting = List.nil();
3760         if (token.kind == IDENTIFIER && token.name() == names.permits) {
3761             if ((mods.flags & Flags.SEALED) == 0) {
3762                 log.error(token.pos, Errors.PermitsInNoSealedClass);
3763             }
3764             nextToken();
3765             permitting = typeList();
3766         }
3767         List<JCTree> defs;
3768         if (token.kind == LBRACE) {
3769             defs = classInterfaceOrRecordBody(name, true, false);
3770         } else {
3771             accept(SEMI);
3772             defs = List.nil();
3773         }
3774         JCClassDecl result = toP(F.at(pos).ClassDef(
3775             mods, name, typarams, null, extending, permitting, defs));
3776         attach(result, dc);
3777         return result;
3778     }
3779 
3780     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3781      *  @param mods    The modifiers starting the enum declaration
3782      *  @param dc       The documentation comment for the enum, or null.
3783      */
3784     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3785         int pos = token.pos;
3786         accept(ENUM);
3787 
3788         Name name = typeName();
3789 
3790         List<JCExpression> implementing = List.nil();
3791         if (token.kind == IMPLEMENTS) {
3792             nextToken();
3793             implementing = typeList();
3794         }
3795 
3796         List<JCTree> defs = enumBody(name);
3797         mods.flags |= Flags.ENUM;
3798         JCClassDecl result = toP(F.at(pos).
3799             ClassDef(mods, name, List.nil(),
3800                      null, implementing, defs));
3801         attach(result, dc);
3802         return result;
3803     }
3804 
3805     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
3806      *                  [ ";" {ClassBodyDeclaration} ] "}"
3807      */
3808     List<JCTree> enumBody(Name enumName) {
3809         accept(LBRACE);
3810         ListBuffer<JCTree> defs = new ListBuffer<>();
3811         if (token.kind == COMMA) {
3812             nextToken();
3813         } else if (token.kind != RBRACE && token.kind != SEMI) {
3814             defs.append(enumeratorDeclaration(enumName));
3815             while (token.kind == COMMA) {
3816                 nextToken();
3817                 if (token.kind == RBRACE || token.kind == SEMI) break;
3818                 defs.append(enumeratorDeclaration(enumName));
3819             }
3820             if (token.kind != SEMI && token.kind != RBRACE) {
3821                 defs.append(syntaxError(token.pos, Errors.Expected3(COMMA, RBRACE, SEMI)));
3822                 nextToken();
3823             }
3824         }
3825         if (token.kind == SEMI) {
3826             nextToken();
3827             while (token.kind != RBRACE && token.kind != EOF) {
3828                 defs.appendList(classOrInterfaceOrRecordBodyDeclaration(enumName,
3829                                                                 false, false));
3830                 if (token.pos <= endPosTable.errorEndPos) {
3831                     // error recovery
3832                    skip(false, true, true, false);
3833                 }
3834             }
3835         }
3836         accept(RBRACE);
3837         return defs.toList();
3838     }
3839 
3840     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3841      */
3842     JCTree enumeratorDeclaration(Name enumName) {
3843         Comment dc = token.comment(CommentStyle.JAVADOC);
3844         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3845         if (token.deprecatedFlag()) {
3846             flags |= Flags.DEPRECATED;
3847         }
3848         int pos = token.pos;
3849         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3850         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3851         List<JCExpression> typeArgs = typeArgumentsOpt();
3852         int identPos = token.pos;
3853         Name name = ident();
3854         int createPos = token.pos;
3855         List<JCExpression> args = (token.kind == LPAREN)
3856             ? arguments() : List.nil();
3857         JCClassDecl body = null;
3858         if (token.kind == LBRACE) {
3859             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3860             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
3861             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3862         }
3863         if (args.isEmpty() && body == null)
3864             createPos = identPos;
3865         JCIdent ident = F.at(identPos).Ident(enumName);
3866         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3867         if (createPos != identPos)
3868             storeEnd(create, S.prevToken().endPos);
3869         ident = F.at(identPos).Ident(enumName);
3870         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3871         attach(result, dc);
3872         return result;
3873     }
3874 
3875     /** TypeList = Type {"," Type}
3876      */
3877     List<JCExpression> typeList() {
3878         ListBuffer<JCExpression> ts = new ListBuffer<>();
3879         ts.append(parseType());
3880         while (token.kind == COMMA) {
3881             nextToken();
3882             ts.append(parseType());
3883         }
3884         return ts.toList();
3885     }
3886 
3887     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3888      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3889      */
3890     List<JCTree> classInterfaceOrRecordBody(Name className, boolean isInterface, boolean isRecord) {
3891         accept(LBRACE);
3892         if (token.pos <= endPosTable.errorEndPos) {
3893             // error recovery
3894             skip(false, true, false, false);
3895             if (token.kind == LBRACE)
3896                 nextToken();
3897         }
3898         ListBuffer<JCTree> defs = new ListBuffer<>();
3899         while (token.kind != RBRACE && token.kind != EOF) {
3900             defs.appendList(classOrInterfaceOrRecordBodyDeclaration(className, isInterface, isRecord));
3901             if (token.pos <= endPosTable.errorEndPos) {
3902                // error recovery
3903                skip(false, true, true, false);
3904            }
3905         }
3906         accept(RBRACE);
3907         return defs.toList();
3908     }
3909 
3910     /** ClassBodyDeclaration =
3911      *      ";"
3912      *    | [STATIC] Block
3913      *    | ModifiersOpt
3914      *      ( Type Ident
3915      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3916      *      | VOID Ident VoidMethodDeclaratorRest
3917      *      | TypeParameters [Annotations]
3918      *        ( Type Ident MethodDeclaratorRest
3919      *        | VOID Ident VoidMethodDeclaratorRest
3920      *        )
3921      *      | Ident ConstructorDeclaratorRest
3922      *      | TypeParameters Ident ConstructorDeclaratorRest
3923      *      | ClassOrInterfaceOrEnumDeclaration
3924      *      )
3925      *  InterfaceBodyDeclaration =
3926      *      ";"
3927      *    | ModifiersOpt
3928      *      ( Type Ident
3929      *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3930      *      | VOID Ident MethodDeclaratorRest
3931      *      | TypeParameters [Annotations]
3932      *        ( Type Ident MethodDeclaratorRest
3933      *        | VOID Ident VoidMethodDeclaratorRest
3934      *        )
3935      *      | ClassOrInterfaceOrEnumDeclaration
3936      *      )
3937      *
3938      */
3939     protected List<JCTree> classOrInterfaceOrRecordBodyDeclaration(Name className, boolean isInterface, boolean isRecord) {
3940         if (token.kind == SEMI) {
3941             nextToken();
3942             return List.nil();
3943         } else {
3944             Comment dc = token.comment(CommentStyle.JAVADOC);
3945             int pos = token.pos;
3946             JCModifiers mods = modifiersOpt();
3947             if (token.kind == CLASS ||
3948                 isRecordDeclaration() ||
3949                 token.kind == INTERFACE ||
3950                 token.kind == ENUM) {
3951                 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
3952             } else if (token.kind == LBRACE &&
3953                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3954                        mods.annotations.isEmpty()) {
3955                 if (isInterface) {
3956                     log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.InitializerNotAllowed);
3957                 }
3958                 return List.of(block(pos, mods.flags));
3959             } else {
3960                 pos = token.pos;
3961                 List<JCTypeParameter> typarams = typeParametersOpt();
3962                 // if there are type parameters but no modifiers, save the start
3963                 // position of the method in the modifiers.
3964                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3965                     mods.pos = pos;
3966                     storeEnd(mods, pos);
3967                 }
3968                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3969 
3970                 if (annosAfterParams.nonEmpty()) {
3971                     checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
3972                     mods.annotations = mods.annotations.appendList(annosAfterParams);
3973                     if (mods.pos == Position.NOPOS)
3974                         mods.pos = mods.annotations.head.pos;
3975                 }
3976 
3977                 Token tk = token;
3978                 pos = token.pos;
3979                 JCExpression type;
3980                 boolean isVoid = token.kind == VOID;
3981                 if (isVoid) {
3982                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3983                     nextToken();
3984                 } else {
3985                     // method returns types are un-annotated types
3986                     type = unannotatedType(false);
3987                 }
3988                 if ((token.kind == LPAREN && !isInterface ||
3989                         isRecord && token.kind == LBRACE) && type.hasTag(IDENT)) {
3990                     if (isInterface || tk.name() != className)
3991                         log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidMethDeclRetTypeReq);
3992                     else if (annosAfterParams.nonEmpty())
3993                         illegal(annosAfterParams.head.pos);
3994                     return List.of(methodDeclaratorRest(
3995                         pos, mods, null, names.init, typarams,
3996                         isInterface, true, isRecord, dc));
3997                 } else {
3998                     pos = token.pos;
3999                     Name name = ident();
4000                     if (token.kind == LPAREN) {
4001                         return List.of(methodDeclaratorRest(
4002                             pos, mods, type, name, typarams,
4003                             isInterface, isVoid, false, dc));
4004                     } else if (!isVoid && typarams.isEmpty()) {
4005                         if (!isRecord || (isRecord && (mods.flags & Flags.STATIC) != 0)) {
4006                             List<JCTree> defs =
4007                                     variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
4008                                             new ListBuffer<JCTree>(), false).toList();
4009                             accept(SEMI);
4010                             storeEnd(defs.last(), S.prevToken().endPos);
4011                             return defs;
4012                         } else {
4013                             nextToken();
4014                             return List.of(syntaxError(pos, null, Errors.RecordFieldsMustBeInHeader));
4015                         }
4016                     } else {
4017                         pos = token.pos;
4018                         List<JCTree> err;
4019                         if (isVoid || typarams.nonEmpty()) {
4020                             JCMethodDecl m =
4021                                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
4022                                                             List.nil(), List.nil(), null, null));
4023                             attach(m, dc);
4024                             err = List.of(m);
4025                         } else {
4026                             err = List.nil();
4027                         }
4028                         return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
4029                     }
4030                 }
4031             }
4032         }
4033     }
4034 
4035     boolean isRecordDeclaration() {
4036         return token.kind == IDENTIFIER && token.name() == names.record &&
4037                 (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
4038                 peekToken(TokenKind.IDENTIFIER, TokenKind.LT));
4039     }
4040 
4041     boolean isSealedClassDeclaration() {
4042         Token next = S.token(1);
4043         return token.kind == IDENTIFIER && token.name() == names.sealed &&
4044                 (peekToken(TokenKind.CLASS) ||
4045                         peekToken(TokenKind.INTERFACE) ||
4046                         peekToken(TokenKind.ABSTRACT) ||
4047                         next.kind == IDENTIFIER && next.name() == names.record);
4048     }
4049 
4050     /** MethodDeclaratorRest =
4051      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4052      *  VoidMethodDeclaratorRest =
4053      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4054      *  ConstructorDeclaratorRest =
4055      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4056      */
4057     protected JCTree methodDeclaratorRest(int pos,
4058                               JCModifiers mods,
4059                               JCExpression type,
4060                               Name name,
4061                               List<JCTypeParameter> typarams,
4062                               boolean isInterface, boolean isVoid,
4063                               boolean isRecord,
4064                               Comment dc) {
4065         if (isInterface) {
4066             if ((mods.flags & Flags.STATIC) != 0) {
4067                 checkSourceLevel(Feature.STATIC_INTERFACE_METHODS);
4068             }
4069             if ((mods.flags & Flags.PRIVATE) != 0) {
4070                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4071             }
4072         }
4073         JCVariableDecl prevReceiverParam = this.receiverParam;
4074         try {
4075             this.receiverParam = null;
4076             // Parsing formalParameters sets the receiverParam, if present
4077             List<JCVariableDecl> params = List.nil();
4078             List<JCExpression> thrown = List.nil();
4079             if (!isRecord || name != names.init || token.kind == LPAREN) {
4080                 params = formalParameters();
4081                 if (!isVoid) type = bracketsOpt(type);
4082                 if (token.kind == THROWS) {
4083                     nextToken();
4084                     thrown = qualidentList(true);
4085                 }
4086             }
4087             JCBlock body = null;
4088             JCExpression defaultValue;
4089             if (token.kind == LBRACE) {
4090                 body = block();
4091                 defaultValue = null;
4092             } else {
4093                 if (token.kind == DEFAULT) {
4094                     accept(DEFAULT);
4095                     defaultValue = annotationValue();
4096                 } else {
4097                     defaultValue = null;
4098                 }
4099                 accept(SEMI);
4100                 if (token.pos <= endPosTable.errorEndPos) {
4101                     // error recovery
4102                     skip(false, true, false, false);
4103                     if (token.kind == LBRACE) {
4104                         body = block();
4105                     }
4106                 }
4107             }
4108             JCMethodDecl result =
4109                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
4110                                             receiverParam, params, thrown,
4111                                             body, defaultValue));
4112             attach(result, dc);
4113             return result;
4114         } finally {
4115             this.receiverParam = prevReceiverParam;
4116         }
4117     }
4118 
4119     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
4120      */
4121     List<JCExpression> qualidentList(boolean allowAnnos) {
4122         ListBuffer<JCExpression> ts = new ListBuffer<>();
4123 
4124         List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
4125         JCExpression qi = qualident(allowAnnos);
4126         if (!typeAnnos.isEmpty()) {
4127             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
4128             ts.append(at);
4129         } else {
4130             ts.append(qi);
4131         }
4132         while (token.kind == COMMA) {
4133             nextToken();
4134 
4135             typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
4136             qi = qualident(allowAnnos);
4137             if (!typeAnnos.isEmpty()) {
4138                 JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
4139                 ts.append(at);
4140             } else {
4141                 ts.append(qi);
4142             }
4143         }
4144         return ts.toList();
4145     }
4146 
4147     /**
4148      *  {@literal
4149      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
4150      *  }
4151      */
4152     protected List<JCTypeParameter> typeParametersOpt() {
4153         if (token.kind == LT) {
4154             ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
4155             nextToken();
4156             typarams.append(typeParameter());
4157             while (token.kind == COMMA) {
4158                 nextToken();
4159                 typarams.append(typeParameter());
4160             }
4161             accept(GT);
4162             return typarams.toList();
4163         } else {
4164             return List.nil();
4165         }
4166     }
4167 
4168     /**
4169      *  {@literal
4170      *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
4171      *  TypeParameterBound = EXTENDS Type {"&" Type}
4172      *  TypeVariable = Ident
4173      *  }
4174      */
4175     JCTypeParameter typeParameter() {
4176         int pos = token.pos;
4177         List<JCAnnotation> annos = typeAnnotationsOpt();
4178         Name name = typeName();
4179         ListBuffer<JCExpression> bounds = new ListBuffer<>();
4180         if (token.kind == EXTENDS) {
4181             nextToken();
4182             bounds.append(parseType());
4183             while (token.kind == AMP) {
4184                 nextToken();
4185                 bounds.append(parseType());
4186             }
4187         }
4188         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
4189     }
4190 
4191     /** FormalParameters = "(" [ FormalParameterList ] ")"
4192      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
4193      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
4194      */
4195     List<JCVariableDecl> formalParameters() {
4196         return formalParameters(false);
4197     }
4198     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
4199         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
4200         JCVariableDecl lastParam;
4201         accept(LPAREN);
4202         if (token.kind != RPAREN) {
4203             this.allowThisIdent = !lambdaParameters;
4204             lastParam = formalParameter(lambdaParameters);
4205             if (lastParam.nameexpr != null) {
4206                 this.receiverParam = lastParam;
4207             } else {
4208                 params.append(lastParam);
4209             }
4210             this.allowThisIdent = false;
4211             while (token.kind == COMMA) {
4212                 if ((lastParam.mods.flags & Flags.VARARGS) != 0) {
4213                     log.error(DiagnosticFlag.SYNTAX, lastParam, Errors.VarargsMustBeLast);
4214                 }
4215                 nextToken();
4216                 params.append(lastParam = formalParameter(lambdaParameters));
4217             }
4218         }
4219         if (token.kind == RPAREN) {
4220             nextToken();
4221         } else {
4222             setErrorEndPos(token.pos);
4223             reportSyntaxError(S.prevToken().endPos, Errors.Expected3(COMMA, RPAREN, LBRACKET));
4224         }
4225         return params.toList();
4226     }
4227 
4228     List<JCVariableDecl> implicitParameters(boolean hasParens) {
4229         if (hasParens) {
4230             accept(LPAREN);
4231         }
4232         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
4233         if (token.kind != RPAREN && token.kind != ARROW) {
4234             params.append(implicitParameter());
4235             while (token.kind == COMMA) {
4236                 nextToken();
4237                 params.append(implicitParameter());
4238             }
4239         }
4240         if (hasParens) {
4241             accept(RPAREN);
4242         }
4243         return params.toList();
4244     }
4245 
4246     JCModifiers optFinal(long flags) {
4247         JCModifiers mods = modifiersOpt();
4248         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
4249         mods.flags |= flags;
4250         return mods;
4251     }
4252 
4253     /**
4254      * Inserts the annotations (and possibly a new array level)
4255      * to the left-most type in an array or nested type.
4256      *
4257      * When parsing a type like {@code @B Outer.Inner @A []}, the
4258      * {@code @A} annotation should target the array itself, while
4259      * {@code @B} targets the nested type {@code Outer}.
4260      *
4261      * Currently the parser parses the annotation first, then
4262      * the array, and then inserts the annotation to the left-most
4263      * nested type.
4264      *
4265      * When {@code createNewLevel} is true, then a new array
4266      * level is inserted as the most inner type, and have the
4267      * annotations target it.  This is useful in the case of
4268      * varargs, e.g. {@code String @A [] @B ...}, as the parser
4269      * first parses the type {@code String @A []} then inserts
4270      * a new array level with {@code @B} annotation.
4271      */
4272     private JCExpression insertAnnotationsToMostInner(
4273             JCExpression type, List<JCAnnotation> annos,
4274             boolean createNewLevel) {
4275         int origEndPos = getEndPos(type);
4276         JCExpression mostInnerType = type;
4277         JCArrayTypeTree mostInnerArrayType = null;
4278         while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
4279             mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
4280             mostInnerType = mostInnerArrayType.elemtype;
4281         }
4282 
4283         if (createNewLevel) {
4284             mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
4285         }
4286 
4287         JCExpression mostInnerTypeToReturn = mostInnerType;
4288         if (annos.nonEmpty()) {
4289             JCExpression lastToModify = mostInnerType;
4290 
4291             while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
4292                     TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
4293                 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
4294                     lastToModify = mostInnerType;
4295                     mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
4296                 }
4297                 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
4298                     lastToModify = mostInnerType;
4299                     mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
4300                 }
4301             }
4302 
4303             mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
4304 
4305             if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
4306                 ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
4307             } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
4308                 ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
4309             } else {
4310                 // We never saw a SELECT or TYPEAPPLY, return the annotated type.
4311                 mostInnerTypeToReturn = mostInnerType;
4312             }
4313         }
4314 
4315         if (mostInnerArrayType == null) {
4316             return mostInnerTypeToReturn;
4317         } else {
4318             mostInnerArrayType.elemtype = mostInnerTypeToReturn;
4319             storeEnd(type, origEndPos);
4320             return type;
4321         }
4322     }
4323 
4324     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
4325      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
4326      */
4327     protected JCVariableDecl formalParameter() {
4328         return formalParameter(false);
4329     }
4330     protected JCVariableDecl formalParameter(boolean lambdaParameter) {
4331         JCModifiers mods = optFinal(Flags.PARAMETER);
4332         // need to distinguish between vararg annos and array annos
4333         // look at typeAnnotationsPushedBack comment
4334         this.permitTypeAnnotationsPushBack = true;
4335         JCExpression type = parseType(lambdaParameter);
4336         this.permitTypeAnnotationsPushBack = false;
4337 
4338         if (token.kind == ELLIPSIS) {
4339             List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
4340             typeAnnotationsPushedBack = List.nil();
4341             mods.flags |= Flags.VARARGS;
4342             // insert var arg type annotations
4343             type = insertAnnotationsToMostInner(type, varargsAnnos, true);
4344             nextToken();
4345         } else {
4346             // if not a var arg, then typeAnnotationsPushedBack should be null
4347             if (typeAnnotationsPushedBack.nonEmpty()) {
4348                 reportSyntaxError(typeAnnotationsPushedBack.head.pos, Errors.IllegalStartOfType);
4349             }
4350             typeAnnotationsPushedBack = List.nil();
4351         }
4352         return variableDeclaratorId(mods, type, lambdaParameter);
4353     }
4354 
4355     protected JCVariableDecl implicitParameter() {
4356         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
4357         return variableDeclaratorId(mods, null, true);
4358     }
4359 
4360 /* ---------- auxiliary methods -------------- */
4361     /** Check that given tree is a legal expression statement.
4362      */
4363     protected JCExpression checkExprStat(JCExpression t) {
4364         if (!TreeInfo.isExpressionStatement(t)) {
4365             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
4366             log.error(DiagnosticFlag.SYNTAX, ret, Errors.NotStmt);
4367             return ret;
4368         } else {
4369             return t;
4370         }
4371     }
4372 
4373     /** Return precedence of operator represented by token,
4374      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
4375      */
4376     static int prec(TokenKind token) {
4377         JCTree.Tag oc = optag(token);
4378         return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
4379     }
4380 
4381     /**
4382      * Return the lesser of two positions, making allowance for either one
4383      * being unset.
4384      */
4385     static int earlier(int pos1, int pos2) {
4386         if (pos1 == Position.NOPOS)
4387             return pos2;
4388         if (pos2 == Position.NOPOS)
4389             return pos1;
4390         return (pos1 < pos2 ? pos1 : pos2);
4391     }
4392 
4393     /** Return operation tag of binary operator represented by token,
4394      *  No_TAG if token is not a binary operator.
4395      */
4396     static JCTree.Tag optag(TokenKind token) {
4397         switch (token) {
4398         case BARBAR:
4399             return OR;
4400         case AMPAMP:
4401             return AND;
4402         case BAR:
4403             return BITOR;
4404         case BAREQ:
4405             return BITOR_ASG;
4406         case CARET:
4407             return BITXOR;
4408         case CARETEQ:
4409             return BITXOR_ASG;
4410         case AMP:
4411             return BITAND;
4412         case AMPEQ:
4413             return BITAND_ASG;
4414         case EQEQ:
4415             return JCTree.Tag.EQ;
4416         case BANGEQ:
4417             return NE;
4418         case LT:
4419             return JCTree.Tag.LT;
4420         case GT:
4421             return JCTree.Tag.GT;
4422         case LTEQ:
4423             return LE;
4424         case GTEQ:
4425             return GE;
4426         case LTLT:
4427             return SL;
4428         case LTLTEQ:
4429             return SL_ASG;
4430         case GTGT:
4431             return SR;
4432         case GTGTEQ:
4433             return SR_ASG;
4434         case GTGTGT:
4435             return USR;
4436         case GTGTGTEQ:
4437             return USR_ASG;
4438         case PLUS:
4439             return JCTree.Tag.PLUS;
4440         case PLUSEQ:
4441             return PLUS_ASG;
4442         case SUB:
4443             return MINUS;
4444         case SUBEQ:
4445             return MINUS_ASG;
4446         case STAR:
4447             return MUL;
4448         case STAREQ:
4449             return MUL_ASG;
4450         case SLASH:
4451             return DIV;
4452         case SLASHEQ:
4453             return DIV_ASG;
4454         case PERCENT:
4455             return MOD;
4456         case PERCENTEQ:
4457             return MOD_ASG;
4458         case INSTANCEOF:
4459             return TYPETEST;
4460         default:
4461             return NO_TAG;
4462         }
4463     }
4464 
4465     /** Return operation tag of unary operator represented by token,
4466      *  No_TAG if token is not a binary operator.
4467      */
4468     static JCTree.Tag unoptag(TokenKind token) {
4469         switch (token) {
4470         case PLUS:
4471             return POS;
4472         case SUB:
4473             return NEG;
4474         case BANG:
4475             return NOT;
4476         case TILDE:
4477             return COMPL;
4478         case PLUSPLUS:
4479             return PREINC;
4480         case SUBSUB:
4481             return PREDEC;
4482         default:
4483             return NO_TAG;
4484         }
4485     }
4486 
4487     /** Return type tag of basic type represented by token,
4488      *  NONE if token is not a basic type identifier.
4489      */
4490     static TypeTag typetag(TokenKind token) {
4491         switch (token) {
4492         case BYTE:
4493             return TypeTag.BYTE;
4494         case CHAR:
4495             return TypeTag.CHAR;
4496         case SHORT:
4497             return TypeTag.SHORT;
4498         case INT:
4499             return TypeTag.INT;
4500         case LONG:
4501             return TypeTag.LONG;
4502         case FLOAT:
4503             return TypeTag.FLOAT;
4504         case DOUBLE:
4505             return TypeTag.DOUBLE;
4506         case BOOLEAN:
4507             return TypeTag.BOOLEAN;
4508         default:
4509             return TypeTag.NONE;
4510         }
4511     }
4512 
4513     void checkSourceLevel(Feature feature) {
4514         checkSourceLevel(token.pos, feature);
4515     }
4516 
4517     protected void checkSourceLevel(int pos, Feature feature) {
4518         if (preview.isPreview(feature) && !preview.isEnabled()) {
4519             //preview feature without --preview flag, error
4520             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
4521         } else if (!feature.allowedInSource(source)) {
4522             //incompatible source level, error
4523             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
4524         } else if (preview.isPreview(feature)) {
4525             //use of preview feature, warn
4526             preview.warnPreview(pos, feature);
4527         }
4528     }
4529 
4530     /*
4531      * a functional source tree and end position mappings
4532      */
4533     protected static class SimpleEndPosTable extends AbstractEndPosTable {
4534 
4535         private final IntHashTable endPosMap;
4536 
4537         SimpleEndPosTable(JavacParser parser) {
4538             super(parser);
4539             endPosMap = new IntHashTable();
4540         }
4541 
4542         public void storeEnd(JCTree tree, int endpos) {
4543             endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos,
4544                                  endPosMap.lookup(tree));
4545         }
4546 
4547         protected <T extends JCTree> T to(T t) {
4548             storeEnd(t, parser.token.endPos);
4549             return t;
4550         }
4551 
4552         protected <T extends JCTree> T toP(T t) {
4553             storeEnd(t, parser.S.prevToken().endPos);
4554             return t;
4555         }
4556 
4557         public int getEndPos(JCTree tree) {
4558             int value = endPosMap.getFromIndex(endPosMap.lookup(tree));
4559             // As long as Position.NOPOS==-1, this just returns value.
4560             return (value == -1) ? Position.NOPOS : value;
4561         }
4562 
4563         public int replaceTree(JCTree oldTree, JCTree newTree) {
4564             int pos = endPosMap.remove(oldTree);
4565             if (pos != -1) {
4566                 storeEnd(newTree, pos);
4567                 return pos;
4568             }
4569             return Position.NOPOS;
4570         }
4571     }
4572 
4573     /*
4574      * a default skeletal implementation without any mapping overhead.
4575      */
4576     protected static class EmptyEndPosTable extends AbstractEndPosTable {
4577 
4578         EmptyEndPosTable(JavacParser parser) {
4579             super(parser);
4580         }
4581 
4582         public void storeEnd(JCTree tree, int endpos) { /* empty */ }
4583 
4584         protected <T extends JCTree> T to(T t) {
4585             return t;
4586         }
4587 
4588         protected <T extends JCTree> T toP(T t) {
4589             return t;
4590         }
4591 
4592         public int getEndPos(JCTree tree) {
4593             return Position.NOPOS;
4594         }
4595 
4596         public int replaceTree(JCTree oldTree, JCTree newTree) {
4597             return Position.NOPOS;
4598         }
4599 
4600     }
4601 
4602     protected static abstract class AbstractEndPosTable implements EndPosTable {
4603         /**
4604          * The current parser.
4605          */
4606         protected JavacParser parser;
4607 
4608         /**
4609          * Store the last error position.
4610          */
4611         public int errorEndPos = Position.NOPOS;
4612 
4613         public AbstractEndPosTable(JavacParser parser) {
4614             this.parser = parser;
4615         }
4616 
4617         /**
4618          * Store current token's ending position for a tree, the value of which
4619          * will be the greater of last error position and the ending position of
4620          * the current token.
4621          * @param t The tree.
4622          */
4623         protected abstract <T extends JCTree> T to(T t);
4624 
4625         /**
4626          * Store current token's ending position for a tree, the value of which
4627          * will be the greater of last error position and the ending position of
4628          * the previous token.
4629          * @param t The tree.
4630          */
4631         protected abstract <T extends JCTree> T toP(T t);
4632 
4633         /**
4634          * Set the error position during the parsing phases, the value of which
4635          * will be set only if it is greater than the last stored error position.
4636          * @param errPos The error position
4637          */
4638         public void setErrorEndPos(int errPos) {
4639             if (errPos > errorEndPos) {
4640                 errorEndPos = errPos;
4641             }
4642         }
4643 
4644         public void setParser(JavacParser parser) {
4645             this.parser = parser;
4646         }
4647     }
4648 }