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