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