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