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