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