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