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