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