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