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