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