src/share/classes/com/sun/tools/javac/parser/JavacParser.java

Thu, 24 May 2018 16:48:51 +0800

author
aoqi
date
Thu, 24 May 2018 16:48:51 +0800
changeset 3295
859dc787b52b
parent 3074
ca136b17b9f4
parent 2893
ca5783d9a597
child 3446
e468915bad3a
permissions
-rw-r--r--

Merge

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

mercurial