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