1 /*
   2  * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.parser;
  27 
  28 import java.util.*;
  29 import java.util.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 (isRestrictedLocalVarTypeName(result) && !allowVar) {
 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         JCTree elemType = TreeInfo.innermostType(type, true); // bracketsOpt needed?
2959         if (elemType.hasTag(IDENT)) {
2960             Name typeName = ((JCIdent)elemType).name;
2961             boolean typeNameVarCheck = isRestrictedLocalVarTypeName(typeName, elemType.pos);
2962         }
2963 
2964         JCVariableDecl head = variableDeclaratorRest(pos, mods, type, name, reqInit, dc, localDecl);
2965         boolean implicit = Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && head.vartype == null;
2966         vdefs.append(head);
2967         while (token.kind == COMMA) {
2968             if (implicit) {
2969                 reportSyntaxError(pos, "var.not.allowed.compound");
2970             }
2971             // All but last of multiple declarators subsume a comma
2972             storeEnd((JCTree)vdefs.last(), token.endPos);
2973             nextToken();
2974             vdefs.append(variableDeclarator(mods, type, reqInit, dc, localDecl));
2975         }
2976         return vdefs;
2977     }
2978 
2979     /** VariableDeclarator = Ident VariableDeclaratorRest
2980      *  ConstantDeclarator = Ident ConstantDeclaratorRest
2981      */
2982     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc, boolean localDecl) {
2983         return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc, localDecl);
2984     }
2985 
2986     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2987      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2988      *
2989      *  @param reqInit  Is an initializer always required?
2990      *  @param dc       The documentation comment for the variable declarations, or null.
2991      */
2992     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2993                                   boolean reqInit, Comment dc, boolean localDecl) {
2994         type = bracketsOpt(type);
2995         JCExpression init = null;
2996         if (token.kind == EQ) {
2997             nextToken();
2998             init = variableInitializer();
2999         }
3000         else if (reqInit) syntaxError(token.pos, "expected", EQ);
3001         JCTree elemType = TreeInfo.innermostType(type, true);
3002         int startPos = Position.NOPOS;
3003         if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source) && elemType.hasTag(IDENT)) {
3004             Name typeName = ((JCIdent)elemType).name;
3005             if (isRestrictedLocalVarTypeName(typeName, elemType.pos)) {
3006                 if (type.hasTag(TYPEARRAY)) {
3007                     //error - 'var' and arrays
3008                     reportSyntaxError(pos, "var.not.allowed.array");
3009                 } else {
3010                     startPos = TreeInfo.getStartPos(mods);
3011                     if (startPos == Position.NOPOS)
3012                         startPos = TreeInfo.getStartPos(type);
3013                     //implicit type
3014                     type = null;
3015                 }
3016             }
3017         }
3018         JCVariableDecl result =
3019             toP(F.at(pos).VarDef(mods, name, type, init));
3020         attach(result, dc);
3021         result.startPos = startPos;
3022         return result;
3023     }
3024 
3025     boolean isRestrictedLocalVarTypeName(JCExpression e) {
3026         switch (e.getTag()) {
3027             case IDENT:
3028                 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos);
3029             case TYPEARRAY:
3030                 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype);
3031             default:
3032                 return false;
3033         }
3034     }
3035 
3036     boolean isRestrictedLocalVarTypeName(Name name, int pos) {
3037         if (name == names.var) {
3038             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3039                 return true;
3040             } else {
3041                 warning(pos, "var.not.allowed", name);
3042             }
3043         }
3044         return false;
3045     }
3046 
3047     /** VariableDeclaratorId = Ident BracketsOpt
3048      */
3049     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3050         return variableDeclaratorId(mods, type, false);
3051     }
3052     //where
3053     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3054         int pos = token.pos;
3055         Name name;
3056         if (lambdaParameter && token.kind == UNDERSCORE) {
3057             log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3058             name = token.name();
3059             nextToken();
3060         } else {
3061             if (allowThisIdent && !lambdaParameter) {
3062                 JCExpression pn = qualident(false);
3063                 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3064                     name = ((JCIdent)pn).name;
3065                 } else {
3066                     if ((mods.flags & Flags.VARARGS) != 0) {
3067                         log.error(token.pos, Errors.VarargsAndReceiver);
3068                     }
3069                     if (token.kind == LBRACKET) {
3070                         log.error(token.pos, Errors.ArrayAndReceiver);
3071                     }
3072                     return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
3073                 }
3074             } else {
3075                 name = ident();
3076             }
3077         }
3078         if ((mods.flags & Flags.VARARGS) != 0 &&
3079                 token.kind == LBRACKET) {
3080             log.error(token.pos, Errors.VarargsAndOldArraySyntax);
3081         }
3082         type = bracketsOpt(type);
3083         return toP(F.at(pos).VarDef(mods, name, type, null));
3084     }
3085 
3086     /** Resources = Resource { ";" Resources }
3087      */
3088     List<JCTree> resources() {
3089         ListBuffer<JCTree> defs = new ListBuffer<>();
3090         defs.append(resource());
3091         while (token.kind == SEMI) {
3092             // All but last of multiple declarators must subsume a semicolon
3093             storeEnd(defs.last(), token.endPos);
3094             int semiColonPos = token.pos;
3095             nextToken();
3096             if (token.kind == RPAREN) { // Optional trailing semicolon
3097                                        // after last resource
3098                 break;
3099             }
3100             defs.append(resource());
3101         }
3102         return defs.toList();
3103     }
3104 
3105     /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
3106      *           | Expression
3107      */
3108     protected JCTree resource() {
3109         int startPos = token.pos;
3110         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3111             JCModifiers mods = optFinal(Flags.FINAL);
3112             JCExpression t = parseType(true);
3113             return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true);
3114         }
3115         JCExpression t = term(EXPR | TYPE);
3116         if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
3117             JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
3118             return variableDeclaratorRest(token.pos, mods, t, ident(), true, null, true);
3119         } else {
3120             checkSourceLevel(Feature.EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES);
3121             if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
3122                 log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar);
3123             }
3124 
3125             return t;
3126         }
3127     }
3128 
3129     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
3130      */
3131     public JCTree.JCCompilationUnit parseCompilationUnit() {
3132         Token firstToken = token;
3133         JCModifiers mods = null;
3134         boolean consumedToplevelDoc = false;
3135         boolean seenImport = false;
3136         boolean seenPackage = false;
3137         ListBuffer<JCTree> defs = new ListBuffer<>();
3138         if (token.kind == MONKEYS_AT)
3139             mods = modifiersOpt();
3140 
3141         if (token.kind == PACKAGE) {
3142             int packagePos = token.pos;
3143             List<JCAnnotation> annotations = List.nil();
3144             seenPackage = true;
3145             if (mods != null) {
3146                 checkNoMods(mods.flags);
3147                 annotations = mods.annotations;
3148                 mods = null;
3149             }
3150             nextToken();
3151             JCExpression pid = qualident(false);
3152             accept(SEMI);
3153             JCPackageDecl pd = toP(F.at(packagePos).PackageDecl(annotations, pid));
3154             attach(pd, firstToken.comment(CommentStyle.JAVADOC));
3155             consumedToplevelDoc = true;
3156             defs.append(pd);
3157         }
3158 
3159         boolean checkForImports = true;
3160         boolean firstTypeDecl = true;
3161         while (token.kind != EOF) {
3162             if (token.pos <= endPosTable.errorEndPos) {
3163                 // error recovery
3164                 skip(checkForImports, false, false, false);
3165                 if (token.kind == EOF)
3166                     break;
3167             }
3168             if (checkForImports && mods == null && token.kind == IMPORT) {
3169                 seenImport = true;
3170                 defs.append(importDeclaration());
3171             } else {
3172                 Comment docComment = token.comment(CommentStyle.JAVADOC);
3173                 if (firstTypeDecl && !seenImport && !seenPackage) {
3174                     docComment = firstToken.comment(CommentStyle.JAVADOC);
3175                     consumedToplevelDoc = true;
3176                 }
3177                 if (mods != null || token.kind != SEMI)
3178                     mods = modifiersOpt(mods);
3179                 if (firstTypeDecl && token.kind == IDENTIFIER) {
3180                     ModuleKind kind = ModuleKind.STRONG;
3181                     if (token.name() == names.open) {
3182                         kind = ModuleKind.OPEN;
3183                         nextToken();
3184                     }
3185                     if (token.kind == IDENTIFIER && token.name() == names.module) {
3186                         if (mods != null) {
3187                             checkNoMods(mods.flags & ~Flags.DEPRECATED);
3188                         }
3189                         defs.append(moduleDecl(mods, kind, docComment));
3190                         consumedToplevelDoc = true;
3191                         break;
3192                     } else if (kind != ModuleKind.STRONG) {
3193                         reportSyntaxError(token.pos, "expected.module");
3194                     }
3195                 }
3196                 JCTree def = typeDeclaration(mods, docComment);
3197                 if (def instanceof JCExpressionStatement)
3198                     def = ((JCExpressionStatement)def).expr;
3199                 defs.append(def);
3200                 if (def instanceof JCClassDecl)
3201                     checkForImports = false;
3202                 mods = null;
3203                 firstTypeDecl = false;
3204             }
3205         }
3206         JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
3207         if (!consumedToplevelDoc)
3208             attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
3209         if (defs.isEmpty())
3210             storeEnd(toplevel, S.prevToken().endPos);
3211         if (keepDocComments)
3212             toplevel.docComments = docComments;
3213         if (keepLineMap)
3214             toplevel.lineMap = S.getLineMap();
3215         this.endPosTable.setParser(null); // remove reference to parser
3216         toplevel.endPositions = this.endPosTable;
3217         return toplevel;
3218     }
3219 
3220     JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
3221         int pos = token.pos;
3222         checkSourceLevel(Feature.MODULES);
3223 
3224         nextToken();
3225         JCExpression name = qualident(false);
3226         List<JCDirective> directives = null;
3227 
3228         accept(LBRACE);
3229         directives = moduleDirectiveList();
3230         accept(RBRACE);
3231         accept(EOF);
3232 
3233         JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives));
3234         attach(result, dc);
3235         return result;
3236     }
3237 
3238     List<JCDirective> moduleDirectiveList() {
3239         ListBuffer<JCDirective> defs = new ListBuffer<>();
3240         while (token.kind == IDENTIFIER) {
3241             int pos = token.pos;
3242             if (token.name() == names.requires) {
3243                 nextToken();
3244                 boolean isTransitive = false;
3245                 boolean isStaticPhase = false;
3246             loop:
3247                 while (true) {
3248                     switch (token.kind) {
3249                         case IDENTIFIER:
3250                             if (token.name() == names.transitive && !isTransitive) {
3251                                 Token t1 = S.token(1);
3252                                 if (t1.kind == SEMI || t1.kind == DOT) {
3253                                     break loop;
3254                                 }
3255                                 isTransitive = true;
3256                                 break;
3257                             } else {
3258                                 break loop;
3259                             }
3260                         case STATIC:
3261                             if (isStaticPhase) {
3262                                 error(token.pos, "repeated.modifier");
3263                             }
3264                             isStaticPhase = true;
3265                             break;
3266                         default:
3267                             break loop;
3268                     }
3269                     nextToken();
3270                 }
3271                 JCExpression moduleName = qualident(false);
3272                 accept(SEMI);
3273                 defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName)));
3274             } else if (token.name() == names.exports || token.name() == names.opens) {
3275                 boolean exports = token.name() == names.exports;
3276                 nextToken();
3277                 JCExpression pkgName = qualident(false);
3278                 List<JCExpression> moduleNames = null;
3279                 if (token.kind == IDENTIFIER && token.name() == names.to) {
3280                     nextToken();
3281                     moduleNames = qualidentList(false);
3282                 }
3283                 accept(SEMI);
3284                 JCDirective d;
3285                 if (exports) {
3286                     d = F.at(pos).Exports(pkgName, moduleNames);
3287                 } else {
3288                     d = F.at(pos).Opens(pkgName, moduleNames);
3289                 }
3290                 defs.append(toP(d));
3291             } else if (token.name() == names.provides) {
3292                 nextToken();
3293                 JCExpression serviceName = qualident(false);
3294                 if (token.kind == IDENTIFIER && token.name() == names.with) {
3295                     nextToken();
3296                     List<JCExpression> implNames = qualidentList(false);
3297                     accept(SEMI);
3298                     defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
3299                 } else {
3300                     error(token.pos, "expected", "'" + names.with + "'");
3301                     skip(false, false, false, false);
3302                 }
3303             } else if (token.name() == names.uses) {
3304                 nextToken();
3305                 JCExpression service = qualident(false);
3306                 accept(SEMI);
3307                 defs.append(toP(F.at(pos).Uses(service)));
3308             } else {
3309                 setErrorEndPos(pos);
3310                 reportSyntaxError(pos, "invalid.module.directive");
3311                 break;
3312             }
3313         }
3314         return defs.toList();
3315     }
3316 
3317     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
3318      */
3319     protected JCTree importDeclaration() {
3320         int pos = token.pos;
3321         nextToken();
3322         boolean importStatic = false;
3323         if (token.kind == STATIC) {
3324             importStatic = true;
3325             nextToken();
3326         }
3327         JCExpression pid = toP(F.at(token.pos).Ident(ident()));
3328         do {
3329             int pos1 = token.pos;
3330             accept(DOT);
3331             if (token.kind == STAR) {
3332                 pid = to(F.at(pos1).Select(pid, names.asterisk));
3333                 nextToken();
3334                 break;
3335             } else {
3336                 pid = toP(F.at(pos1).Select(pid, ident()));
3337             }
3338         } while (token.kind == DOT);
3339         accept(SEMI);
3340         return toP(F.at(pos).Import(pid, importStatic));
3341     }
3342 
3343     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3344      *                  | ";"
3345      */
3346     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3347         int pos = token.pos;
3348         if (mods == null && token.kind == SEMI) {
3349             nextToken();
3350             return toP(F.at(pos).Skip());
3351         } else {
3352             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3353         }
3354     }
3355 
3356     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3357      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3358      *  @param mods     Any modifiers starting the class or interface declaration
3359      *  @param dc       The documentation comment for the class, or null.
3360      */
3361     protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3362         if (token.kind == CLASS) {
3363             return classDeclaration(mods, dc);
3364         } else if (token.kind == INTERFACE) {
3365             return interfaceDeclaration(mods, dc);
3366         } else if (token.kind == ENUM) {
3367             return enumDeclaration(mods, dc);
3368         } else {
3369             int pos = token.pos;
3370             List<JCTree> errs;
3371             if (LAX_IDENTIFIER.accepts(token.kind)) {
3372                 errs = List.of(mods, toP(F.at(pos).Ident(ident())));
3373                 setErrorEndPos(token.pos);
3374             } else {
3375                 errs = List.of(mods);
3376             }
3377             final JCErroneous erroneousTree;
3378             if (parseModuleInfo) {
3379                 erroneousTree = syntaxError(pos, errs, "expected.module.or.open");
3380             } else {
3381                 erroneousTree = syntaxError(pos, errs, "expected3", CLASS, INTERFACE, ENUM);
3382             }
3383             return toP(F.Exec(erroneousTree));
3384         }
3385     }
3386 
3387     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3388      *                     [IMPLEMENTS TypeList] ClassBody
3389      *  @param mods    The modifiers starting the class declaration
3390      *  @param dc       The documentation comment for the class, or null.
3391      */
3392     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3393         int pos = token.pos;
3394         accept(CLASS);
3395         Name name = typeName();
3396 
3397         List<JCTypeParameter> typarams = typeParametersOpt();
3398 
3399         JCExpression extending = null;
3400         if (token.kind == EXTENDS) {
3401             nextToken();
3402             extending = parseType();
3403         }
3404         List<JCExpression> implementing = List.nil();
3405         if (token.kind == IMPLEMENTS) {
3406             nextToken();
3407             implementing = typeList();
3408         }
3409         List<JCTree> defs = classOrInterfaceBody(name, false);
3410         JCClassDecl result = toP(F.at(pos).ClassDef(
3411             mods, name, typarams, extending, implementing, defs));
3412         attach(result, dc);
3413         return result;
3414     }
3415 
3416     Name typeName() {
3417         int pos = token.pos;
3418         Name name = ident();
3419         if (isRestrictedLocalVarTypeName(name, pos)) {
3420             reportSyntaxError(pos, "var.not.allowed", name);
3421         }
3422         return name;
3423     }
3424 
3425     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3426      *                         [EXTENDS TypeList] InterfaceBody
3427      *  @param mods    The modifiers starting the interface declaration
3428      *  @param dc       The documentation comment for the interface, or null.
3429      */
3430     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3431         int pos = token.pos;
3432         accept(INTERFACE);
3433 
3434         Name name = typeName();
3435 
3436         List<JCTypeParameter> typarams = typeParametersOpt();
3437 
3438         List<JCExpression> extending = List.nil();
3439         if (token.kind == EXTENDS) {
3440             nextToken();
3441             extending = typeList();
3442         }
3443         List<JCTree> defs = classOrInterfaceBody(name, true);
3444         JCClassDecl result = toP(F.at(pos).ClassDef(
3445             mods, name, typarams, null, extending, defs));
3446         attach(result, dc);
3447         return result;
3448     }
3449 
3450     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3451      *  @param mods    The modifiers starting the enum declaration
3452      *  @param dc       The documentation comment for the enum, or null.
3453      */
3454     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3455         int pos = token.pos;
3456         accept(ENUM);
3457 
3458         Name name = typeName();
3459 
3460         List<JCExpression> implementing = List.nil();
3461         if (token.kind == IMPLEMENTS) {
3462             nextToken();
3463             implementing = typeList();
3464         }
3465 
3466         List<JCTree> defs = enumBody(name);
3467         mods.flags |= Flags.ENUM;
3468         JCClassDecl result = toP(F.at(pos).
3469             ClassDef(mods, name, List.nil(),
3470                      null, implementing, defs));
3471         attach(result, dc);
3472         return result;
3473     }
3474 
3475     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
3476      *                  [ ";" {ClassBodyDeclaration} ] "}"
3477      */
3478     List<JCTree> enumBody(Name enumName) {
3479         accept(LBRACE);
3480         ListBuffer<JCTree> defs = new ListBuffer<>();
3481         if (token.kind == COMMA) {
3482             nextToken();
3483         } else if (token.kind != RBRACE && token.kind != SEMI) {
3484             defs.append(enumeratorDeclaration(enumName));
3485             while (token.kind == COMMA) {
3486                 nextToken();
3487                 if (token.kind == RBRACE || token.kind == SEMI) break;
3488                 defs.append(enumeratorDeclaration(enumName));
3489             }
3490             if (token.kind != SEMI && token.kind != RBRACE) {
3491                 defs.append(syntaxError(token.pos, "expected3",
3492                                 COMMA, RBRACE, SEMI));
3493                 nextToken();
3494             }
3495         }
3496         if (token.kind == SEMI) {
3497             nextToken();
3498             while (token.kind != RBRACE && token.kind != EOF) {
3499                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
3500                                                                 false));
3501                 if (token.pos <= endPosTable.errorEndPos) {
3502                     // error recovery
3503                    skip(false, true, true, false);
3504                 }
3505             }
3506         }
3507         accept(RBRACE);
3508         return defs.toList();
3509     }
3510 
3511     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3512      */
3513     JCTree enumeratorDeclaration(Name enumName) {
3514         Comment dc = token.comment(CommentStyle.JAVADOC);
3515         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3516         if (token.deprecatedFlag()) {
3517             flags |= Flags.DEPRECATED;
3518         }
3519         int pos = token.pos;
3520         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3521         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3522         List<JCExpression> typeArgs = typeArgumentsOpt();
3523         int identPos = token.pos;
3524         Name name = ident();
3525         int createPos = token.pos;
3526         List<JCExpression> args = (token.kind == LPAREN)
3527             ? arguments() : List.nil();
3528         JCClassDecl body = null;
3529         if (token.kind == LBRACE) {
3530             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3531             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
3532             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3533         }
3534         if (args.isEmpty() && body == null)
3535             createPos = identPos;
3536         JCIdent ident = F.at(identPos).Ident(enumName);
3537         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3538         if (createPos != identPos)
3539             storeEnd(create, S.prevToken().endPos);
3540         ident = F.at(identPos).Ident(enumName);
3541         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3542         attach(result, dc);
3543         return result;
3544     }
3545 
3546     /** TypeList = Type {"," Type}
3547      */
3548     List<JCExpression> typeList() {
3549         ListBuffer<JCExpression> ts = new ListBuffer<>();
3550         ts.append(parseType());
3551         while (token.kind == COMMA) {
3552             nextToken();
3553             ts.append(parseType());
3554         }
3555         return ts.toList();
3556     }
3557 
3558     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3559      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3560      */
3561     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
3562         accept(LBRACE);
3563         if (token.pos <= endPosTable.errorEndPos) {
3564             // error recovery
3565             skip(false, true, false, false);
3566             if (token.kind == LBRACE)
3567                 nextToken();
3568         }
3569         ListBuffer<JCTree> defs = new ListBuffer<>();
3570         while (token.kind != RBRACE && token.kind != EOF) {
3571             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
3572             if (token.pos <= endPosTable.errorEndPos) {
3573                // error recovery
3574                skip(false, true, true, false);
3575            }
3576         }
3577         accept(RBRACE);
3578         return defs.toList();
3579     }
3580 
3581     /** ClassBodyDeclaration =
3582      *      ";"
3583      *    | [STATIC] Block
3584      *    | ModifiersOpt
3585      *      ( Type Ident
3586      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3587      *      | VOID Ident VoidMethodDeclaratorRest
3588      *      | TypeParameters [Annotations]
3589      *        ( Type Ident MethodDeclaratorRest
3590      *        | VOID Ident VoidMethodDeclaratorRest
3591      *        )
3592      *      | Ident ConstructorDeclaratorRest
3593      *      | TypeParameters Ident ConstructorDeclaratorRest
3594      *      | ClassOrInterfaceOrEnumDeclaration
3595      *      )
3596      *  InterfaceBodyDeclaration =
3597      *      ";"
3598      *    | ModifiersOpt
3599      *      ( Type Ident
3600      *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3601      *      | VOID Ident MethodDeclaratorRest
3602      *      | TypeParameters [Annotations]
3603      *        ( Type Ident MethodDeclaratorRest
3604      *        | VOID Ident VoidMethodDeclaratorRest
3605      *        )
3606      *      | ClassOrInterfaceOrEnumDeclaration
3607      *      )
3608      *
3609      */
3610     protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3611         if (token.kind == SEMI) {
3612             nextToken();
3613             return List.nil();
3614         } else {
3615             Comment dc = token.comment(CommentStyle.JAVADOC);
3616             int pos = token.pos;
3617             JCModifiers mods = modifiersOpt();
3618             if (token.kind == CLASS ||
3619                 token.kind == INTERFACE ||
3620                 token.kind == ENUM) {
3621                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
3622             } else if (token.kind == LBRACE &&
3623                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3624                        mods.annotations.isEmpty()) {
3625                 if (isInterface) {
3626                     error(token.pos, "initializer.not.allowed");
3627                 }
3628                 return List.of(block(pos, mods.flags));
3629             } else {
3630                 pos = token.pos;
3631                 List<JCTypeParameter> typarams = typeParametersOpt();
3632                 // if there are type parameters but no modifiers, save the start
3633                 // position of the method in the modifiers.
3634                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3635                     mods.pos = pos;
3636                     storeEnd(mods, pos);
3637                 }
3638                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3639 
3640                 if (annosAfterParams.nonEmpty()) {
3641                     checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
3642                     mods.annotations = mods.annotations.appendList(annosAfterParams);
3643                     if (mods.pos == Position.NOPOS)
3644                         mods.pos = mods.annotations.head.pos;
3645                 }
3646 
3647                 Token tk = token;
3648                 pos = token.pos;
3649                 JCExpression type;
3650                 boolean isVoid = token.kind == VOID;
3651                 if (isVoid) {
3652                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3653                     nextToken();
3654                 } else {
3655                     // method returns types are un-annotated types
3656                     type = unannotatedType(false);
3657                 }
3658                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3659                     if (isInterface || tk.name() != className)
3660                         error(pos, "invalid.meth.decl.ret.type.req");
3661                     else if (annosAfterParams.nonEmpty())
3662                         illegal(annosAfterParams.head.pos);
3663                     return List.of(methodDeclaratorRest(
3664                         pos, mods, null, names.init, typarams,
3665                         isInterface, true, dc));
3666                 } else {
3667                     pos = token.pos;
3668                     Name name = ident();
3669                     if (token.kind == LPAREN) {
3670                         return List.of(methodDeclaratorRest(
3671                             pos, mods, type, name, typarams,
3672                             isInterface, isVoid, dc));
3673                     } else if (!isVoid && typarams.isEmpty()) {
3674                         List<JCTree> defs =
3675                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3676                                                     new ListBuffer<JCTree>(), false).toList();
3677                         accept(SEMI);
3678                         storeEnd(defs.last(), S.prevToken().endPos);
3679                         return defs;
3680                     } else {
3681                         pos = token.pos;
3682                         List<JCTree> err = isVoid
3683                             ? List.of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
3684                                 List.nil(), List.nil(), null, null)))
3685                             : null;
3686                         return List.of(syntaxError(token.pos, err, "expected", LPAREN));
3687                     }
3688                 }
3689             }
3690         }
3691     }
3692 
3693     /** MethodDeclaratorRest =
3694      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
3695      *  VoidMethodDeclaratorRest =
3696      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
3697      *  ConstructorDeclaratorRest =
3698      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
3699      */
3700     protected JCTree methodDeclaratorRest(int pos,
3701                               JCModifiers mods,
3702                               JCExpression type,
3703                               Name name,
3704                               List<JCTypeParameter> typarams,
3705                               boolean isInterface, boolean isVoid,
3706                               Comment dc) {
3707         if (isInterface) {
3708             if ((mods.flags & Flags.STATIC) != 0) {
3709                 checkSourceLevel(Feature.STATIC_INTERFACE_METHODS);
3710             }
3711             if ((mods.flags & Flags.PRIVATE) != 0) {
3712                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
3713             }
3714         }
3715         JCVariableDecl prevReceiverParam = this.receiverParam;
3716         try {
3717             this.receiverParam = null;
3718             // Parsing formalParameters sets the receiverParam, if present
3719             List<JCVariableDecl> params = formalParameters();
3720             if (!isVoid) type = bracketsOpt(type);
3721             List<JCExpression> thrown = List.nil();
3722             if (token.kind == THROWS) {
3723                 nextToken();
3724                 thrown = qualidentList(true);
3725             }
3726             JCBlock body = null;
3727             JCExpression defaultValue;
3728             if (token.kind == LBRACE) {
3729                 body = block();
3730                 defaultValue = null;
3731             } else {
3732                 if (token.kind == DEFAULT) {
3733                     accept(DEFAULT);
3734                     defaultValue = annotationValue();
3735                 } else {
3736                     defaultValue = null;
3737                 }
3738                 accept(SEMI);
3739                 if (token.pos <= endPosTable.errorEndPos) {
3740                     // error recovery
3741                     skip(false, true, false, false);
3742                     if (token.kind == LBRACE) {
3743                         body = block();
3744                     }
3745                 }
3746             }
3747 
3748             JCMethodDecl result =
3749                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
3750                                             receiverParam, params, thrown,
3751                                             body, defaultValue));
3752             attach(result, dc);
3753             return result;
3754         } finally {
3755             this.receiverParam = prevReceiverParam;
3756         }
3757     }
3758 
3759     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
3760      */
3761     List<JCExpression> qualidentList(boolean allowAnnos) {
3762         ListBuffer<JCExpression> ts = new ListBuffer<>();
3763 
3764         List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3765         JCExpression qi = qualident(allowAnnos);
3766         if (!typeAnnos.isEmpty()) {
3767             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3768             ts.append(at);
3769         } else {
3770             ts.append(qi);
3771         }
3772         while (token.kind == COMMA) {
3773             nextToken();
3774 
3775             typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3776             qi = qualident(allowAnnos);
3777             if (!typeAnnos.isEmpty()) {
3778                 JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3779                 ts.append(at);
3780             } else {
3781                 ts.append(qi);
3782             }
3783         }
3784         return ts.toList();
3785     }
3786 
3787     /**
3788      *  {@literal
3789      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
3790      *  }
3791      */
3792     protected List<JCTypeParameter> typeParametersOpt() {
3793         if (token.kind == LT) {
3794             ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
3795             nextToken();
3796             typarams.append(typeParameter());
3797             while (token.kind == COMMA) {
3798                 nextToken();
3799                 typarams.append(typeParameter());
3800             }
3801             accept(GT);
3802             return typarams.toList();
3803         } else {
3804             return List.nil();
3805         }
3806     }
3807 
3808     /**
3809      *  {@literal
3810      *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
3811      *  TypeParameterBound = EXTENDS Type {"&" Type}
3812      *  TypeVariable = Ident
3813      *  }
3814      */
3815     JCTypeParameter typeParameter() {
3816         int pos = token.pos;
3817         List<JCAnnotation> annos = typeAnnotationsOpt();
3818         Name name = typeName();
3819         ListBuffer<JCExpression> bounds = new ListBuffer<>();
3820         if (token.kind == EXTENDS) {
3821             nextToken();
3822             bounds.append(parseType());
3823             while (token.kind == AMP) {
3824                 nextToken();
3825                 bounds.append(parseType());
3826             }
3827         }
3828         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
3829     }
3830 
3831     /** FormalParameters = "(" [ FormalParameterList ] ")"
3832      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3833      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3834      */
3835     List<JCVariableDecl> formalParameters() {
3836         return formalParameters(false);
3837     }
3838     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
3839         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3840         JCVariableDecl lastParam;
3841         accept(LPAREN);
3842         if (token.kind != RPAREN) {
3843             this.allowThisIdent = true;
3844             lastParam = formalParameter(lambdaParameters);
3845             if (lastParam.nameexpr != null) {
3846                 this.receiverParam = lastParam;
3847             } else {
3848                 params.append(lastParam);
3849             }
3850             this.allowThisIdent = false;
3851             while (token.kind == COMMA) {
3852                 if ((lastParam.mods.flags & Flags.VARARGS) != 0) {
3853                     error(lastParam, "varargs.must.be.last");
3854                 }
3855                 nextToken();
3856                 params.append(lastParam = formalParameter(lambdaParameters));
3857             }
3858         }
3859         if (token.kind == RPAREN) {
3860             nextToken();
3861         } else {
3862             setErrorEndPos(token.pos);
3863             reportSyntaxError(S.prevToken().endPos, "expected3", COMMA, RPAREN, LBRACKET);
3864         }
3865         return params.toList();
3866     }
3867 
3868     List<JCVariableDecl> implicitParameters(boolean hasParens) {
3869         if (hasParens) {
3870             accept(LPAREN);
3871         }
3872         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3873         if (token.kind != RPAREN && token.kind != ARROW) {
3874             params.append(implicitParameter());
3875             while (token.kind == COMMA) {
3876                 nextToken();
3877                 params.append(implicitParameter());
3878             }
3879         }
3880         if (hasParens) {
3881             accept(RPAREN);
3882         }
3883         return params.toList();
3884     }
3885 
3886     JCModifiers optFinal(long flags) {
3887         JCModifiers mods = modifiersOpt();
3888         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
3889         mods.flags |= flags;
3890         return mods;
3891     }
3892 
3893     /**
3894      * Inserts the annotations (and possibly a new array level)
3895      * to the left-most type in an array or nested type.
3896      *
3897      * When parsing a type like {@code @B Outer.Inner @A []}, the
3898      * {@code @A} annotation should target the array itself, while
3899      * {@code @B} targets the nested type {@code Outer}.
3900      *
3901      * Currently the parser parses the annotation first, then
3902      * the array, and then inserts the annotation to the left-most
3903      * nested type.
3904      *
3905      * When {@code createNewLevel} is true, then a new array
3906      * level is inserted as the most inner type, and have the
3907      * annotations target it.  This is useful in the case of
3908      * varargs, e.g. {@code String @A [] @B ...}, as the parser
3909      * first parses the type {@code String @A []} then inserts
3910      * a new array level with {@code @B} annotation.
3911      */
3912     private JCExpression insertAnnotationsToMostInner(
3913             JCExpression type, List<JCAnnotation> annos,
3914             boolean createNewLevel) {
3915         int origEndPos = getEndPos(type);
3916         JCExpression mostInnerType = type;
3917         JCArrayTypeTree mostInnerArrayType = null;
3918         while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
3919             mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
3920             mostInnerType = mostInnerArrayType.elemtype;
3921         }
3922 
3923         if (createNewLevel) {
3924             mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
3925         }
3926 
3927         JCExpression mostInnerTypeToReturn = mostInnerType;
3928         if (annos.nonEmpty()) {
3929             JCExpression lastToModify = mostInnerType;
3930 
3931             while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
3932                     TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3933                 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
3934                     lastToModify = mostInnerType;
3935                     mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
3936                 }
3937                 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3938                     lastToModify = mostInnerType;
3939                     mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
3940                 }
3941             }
3942 
3943             mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
3944 
3945             if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
3946                 ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
3947             } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
3948                 ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
3949             } else {
3950                 // We never saw a SELECT or TYPEAPPLY, return the annotated type.
3951                 mostInnerTypeToReturn = mostInnerType;
3952             }
3953         }
3954 
3955         if (mostInnerArrayType == null) {
3956             return mostInnerTypeToReturn;
3957         } else {
3958             mostInnerArrayType.elemtype = mostInnerTypeToReturn;
3959             storeEnd(type, origEndPos);
3960             return type;
3961         }
3962     }
3963 
3964     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3965      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3966      */
3967     protected JCVariableDecl formalParameter() {
3968         return formalParameter(false);
3969     }
3970     protected JCVariableDecl formalParameter(boolean lambdaParameter) {
3971         JCModifiers mods = optFinal(Flags.PARAMETER);
3972         // need to distinguish between vararg annos and array annos
3973         // look at typeAnnotationsPushedBack comment
3974         this.permitTypeAnnotationsPushBack = true;
3975         JCExpression type = parseType();
3976         this.permitTypeAnnotationsPushBack = false;
3977 
3978         if (token.kind == ELLIPSIS) {
3979             List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
3980             typeAnnotationsPushedBack = List.nil();
3981             mods.flags |= Flags.VARARGS;
3982             // insert var arg type annotations
3983             type = insertAnnotationsToMostInner(type, varargsAnnos, true);
3984             nextToken();
3985         } else {
3986             // if not a var arg, then typeAnnotationsPushedBack should be null
3987             if (typeAnnotationsPushedBack.nonEmpty()) {
3988                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3989                         "illegal.start.of.type");
3990             }
3991             typeAnnotationsPushedBack = List.nil();
3992         }
3993         return variableDeclaratorId(mods, type, lambdaParameter);
3994     }
3995 
3996     protected JCVariableDecl implicitParameter() {
3997         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
3998         return variableDeclaratorId(mods, null, true);
3999     }
4000 
4001 /* ---------- auxiliary methods -------------- */
4002 
4003     void error(int pos, String key, Object ... args) {
4004         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
4005     }
4006 
4007     void error(DiagnosticPosition pos, String key, Object ... args) {
4008         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
4009     }
4010 
4011     void warning(int pos, String key, Object ... args) {
4012         log.warning(pos, key, args);
4013     }
4014 
4015     /** Check that given tree is a legal expression statement.
4016      */
4017     protected JCExpression checkExprStat(JCExpression t) {
4018         if (!TreeInfo.isExpressionStatement(t)) {
4019             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
4020             error(ret, "not.stmt");
4021             return ret;
4022         } else {
4023             return t;
4024         }
4025     }
4026 
4027     /** Return precedence of operator represented by token,
4028      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
4029      */
4030     static int prec(TokenKind token) {
4031         JCTree.Tag oc = optag(token);
4032         return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
4033     }
4034 
4035     /**
4036      * Return the lesser of two positions, making allowance for either one
4037      * being unset.
4038      */
4039     static int earlier(int pos1, int pos2) {
4040         if (pos1 == Position.NOPOS)
4041             return pos2;
4042         if (pos2 == Position.NOPOS)
4043             return pos1;
4044         return (pos1 < pos2 ? pos1 : pos2);
4045     }
4046 
4047     /** Return operation tag of binary operator represented by token,
4048      *  No_TAG if token is not a binary operator.
4049      */
4050     static JCTree.Tag optag(TokenKind token) {
4051         switch (token) {
4052         case BARBAR:
4053             return OR;
4054         case AMPAMP:
4055             return AND;
4056         case BAR:
4057             return BITOR;
4058         case BAREQ:
4059             return BITOR_ASG;
4060         case CARET:
4061             return BITXOR;
4062         case CARETEQ:
4063             return BITXOR_ASG;
4064         case AMP:
4065             return BITAND;
4066         case AMPEQ:
4067             return BITAND_ASG;
4068         case EQEQ:
4069             return JCTree.Tag.EQ;
4070         case BANGEQ:
4071             return NE;
4072         case LT:
4073             return JCTree.Tag.LT;
4074         case GT:
4075             return JCTree.Tag.GT;
4076         case LTEQ:
4077             return LE;
4078         case GTEQ:
4079             return GE;
4080         case LTLT:
4081             return SL;
4082         case LTLTEQ:
4083             return SL_ASG;
4084         case GTGT:
4085             return SR;
4086         case GTGTEQ:
4087             return SR_ASG;
4088         case GTGTGT:
4089             return USR;
4090         case GTGTGTEQ:
4091             return USR_ASG;
4092         case PLUS:
4093             return JCTree.Tag.PLUS;
4094         case PLUSEQ:
4095             return PLUS_ASG;
4096         case SUB:
4097             return MINUS;
4098         case SUBEQ:
4099             return MINUS_ASG;
4100         case STAR:
4101             return MUL;
4102         case STAREQ:
4103             return MUL_ASG;
4104         case SLASH:
4105             return DIV;
4106         case SLASHEQ:
4107             return DIV_ASG;
4108         case PERCENT:
4109             return MOD;
4110         case PERCENTEQ:
4111             return MOD_ASG;
4112         case INSTANCEOF:
4113             return TYPETEST;
4114         default:
4115             return NO_TAG;
4116         }
4117     }
4118 
4119     /** Return operation tag of unary operator represented by token,
4120      *  No_TAG if token is not a binary operator.
4121      */
4122     static JCTree.Tag unoptag(TokenKind token) {
4123         switch (token) {
4124         case PLUS:
4125             return POS;
4126         case SUB:
4127             return NEG;
4128         case BANG:
4129             return NOT;
4130         case TILDE:
4131             return COMPL;
4132         case PLUSPLUS:
4133             return PREINC;
4134         case SUBSUB:
4135             return PREDEC;
4136         default:
4137             return NO_TAG;
4138         }
4139     }
4140 
4141     /** Return type tag of basic type represented by token,
4142      *  NONE if token is not a basic type identifier.
4143      */
4144     static TypeTag typetag(TokenKind token) {
4145         switch (token) {
4146         case BYTE:
4147             return TypeTag.BYTE;
4148         case CHAR:
4149             return TypeTag.CHAR;
4150         case SHORT:
4151             return TypeTag.SHORT;
4152         case INT:
4153             return TypeTag.INT;
4154         case LONG:
4155             return TypeTag.LONG;
4156         case FLOAT:
4157             return TypeTag.FLOAT;
4158         case DOUBLE:
4159             return TypeTag.DOUBLE;
4160         case BOOLEAN:
4161             return TypeTag.BOOLEAN;
4162         default:
4163             return TypeTag.NONE;
4164         }
4165     }
4166 
4167     void checkSourceLevel(Feature feature) {
4168         checkSourceLevel(token.pos, feature);
4169     }
4170 
4171     protected void checkSourceLevel(int pos, Feature feature) {
4172         if (!feature.allowedInSource(source)) {
4173             log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
4174         }
4175     }
4176 
4177     /*
4178      * a functional source tree and end position mappings
4179      */
4180     protected static class SimpleEndPosTable extends AbstractEndPosTable {
4181 
4182         private final IntHashTable endPosMap;
4183 
4184         SimpleEndPosTable(JavacParser parser) {
4185             super(parser);
4186             endPosMap = new IntHashTable();
4187         }
4188 
4189         public void storeEnd(JCTree tree, int endpos) {
4190             endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos,
4191                                  endPosMap.lookup(tree));
4192         }
4193 
4194         protected <T extends JCTree> T to(T t) {
4195             storeEnd(t, parser.token.endPos);
4196             return t;
4197         }
4198 
4199         protected <T extends JCTree> T toP(T t) {
4200             storeEnd(t, parser.S.prevToken().endPos);
4201             return t;
4202         }
4203 
4204         public int getEndPos(JCTree tree) {
4205             int value = endPosMap.getFromIndex(endPosMap.lookup(tree));
4206             // As long as Position.NOPOS==-1, this just returns value.
4207             return (value == -1) ? Position.NOPOS : value;
4208         }
4209 
4210         public int replaceTree(JCTree oldTree, JCTree newTree) {
4211             int pos = endPosMap.remove(oldTree);
4212             if (pos != -1) {
4213                 storeEnd(newTree, pos);
4214                 return pos;
4215             }
4216             return Position.NOPOS;
4217         }
4218     }
4219 
4220     /*
4221      * a default skeletal implementation without any mapping overhead.
4222      */
4223     protected static class EmptyEndPosTable extends AbstractEndPosTable {
4224 
4225         EmptyEndPosTable(JavacParser parser) {
4226             super(parser);
4227         }
4228 
4229         public void storeEnd(JCTree tree, int endpos) { /* empty */ }
4230 
4231         protected <T extends JCTree> T to(T t) {
4232             return t;
4233         }
4234 
4235         protected <T extends JCTree> T toP(T t) {
4236             return t;
4237         }
4238 
4239         public int getEndPos(JCTree tree) {
4240             return Position.NOPOS;
4241         }
4242 
4243         public int replaceTree(JCTree oldTree, JCTree newTree) {
4244             return Position.NOPOS;
4245         }
4246 
4247     }
4248 
4249     protected static abstract class AbstractEndPosTable implements EndPosTable {
4250         /**
4251          * The current parser.
4252          */
4253         protected JavacParser parser;
4254 
4255         /**
4256          * Store the last error position.
4257          */
4258         public int errorEndPos = Position.NOPOS;
4259 
4260         public AbstractEndPosTable(JavacParser parser) {
4261             this.parser = parser;
4262         }
4263 
4264         /**
4265          * Store current token's ending position for a tree, the value of which
4266          * will be the greater of last error position and the ending position of
4267          * the current token.
4268          * @param t The tree.
4269          */
4270         protected abstract <T extends JCTree> T to(T t);
4271 
4272         /**
4273          * Store current token's ending position for a tree, the value of which
4274          * will be the greater of last error position and the ending position of
4275          * the previous token.
4276          * @param t The tree.
4277          */
4278         protected abstract <T extends JCTree> T toP(T t);
4279 
4280         /**
4281          * Set the error position during the parsing phases, the value of which
4282          * will be set only if it is greater than the last stored error position.
4283          * @param errPos The error position
4284          */
4285         public void setErrorEndPos(int errPos) {
4286             if (errPos > errorEndPos) {
4287                 errorEndPos = errPos;
4288             }
4289         }
4290 
4291         public void setParser(JavacParser parser) {
4292             this.parser = parser;
4293         }
4294     }
4295 }