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

Wed, 16 Oct 2013 16:33:04 -0400

author
emc
date
Wed, 16 Oct 2013 16:33:04 -0400
changeset 2136
7f6481e5fe3a
parent 2080
1e6088da1740
child 2211
fb8c59cf26c8
permissions
-rw-r--r--

8026286: Improper locking of annotation queues causes assertion failures.
8026063: Calls to annotate.flush() cause incorrect type annotations to be generated.
Summary: Fix locking in ClassReader.java
Reviewed-by: jfranck

     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.keepDocComments = keepDocComments;
   165         docComments = newDocCommentTable(keepDocComments, fac);
   166         this.keepLineMap = keepLineMap;
   167         this.errorTree = F.Erroneous();
   168         endPosTable = newEndPosTable(keepEndPositions);
   169     }
   171     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
   172         return  keepEndPositions
   173                 ? new SimpleEndPosTable(this)
   174                 : new EmptyEndPosTable(this);
   175     }
   177     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
   178         return keepDocComments ? new LazyDocCommentTable(fac) : null;
   179     }
   181     /** Switch: Should generics be recognized?
   182      */
   183     boolean allowGenerics;
   185     /** Switch: Should diamond operator be recognized?
   186      */
   187     boolean allowDiamond;
   189     /** Switch: Should multicatch clause be accepted?
   190      */
   191     boolean allowMulticatch;
   193     /** Switch: Should varargs be recognized?
   194      */
   195     boolean allowVarargs;
   197     /** Switch: should we recognize assert statements, or just give a warning?
   198      */
   199     boolean allowAsserts;
   201     /** Switch: should we recognize enums, or just give a warning?
   202      */
   203     boolean allowEnums;
   205     /** Switch: should we recognize foreach?
   206      */
   207     boolean allowForeach;
   209     /** Switch: should we recognize foreach?
   210      */
   211     boolean allowStaticImport;
   213     /** Switch: should we recognize annotations?
   214      */
   215     boolean allowAnnotations;
   217     /** Switch: should we recognize try-with-resources?
   218      */
   219     boolean allowTWR;
   221     /** Switch: should we fold strings?
   222      */
   223     boolean allowStringFolding;
   225     /** Switch: should we recognize lambda expressions?
   226      */
   227     boolean allowLambda;
   229     /** Switch: should we allow method/constructor references?
   230      */
   231     boolean allowMethodReferences;
   233     /** Switch: should we allow default methods in interfaces?
   234      */
   235     boolean allowDefaultMethods;
   237     /** Switch: should we allow static methods in interfaces?
   238      */
   239     boolean allowStaticInterfaceMethods;
   241     /** Switch: should we allow intersection types in cast?
   242      */
   243     boolean allowIntersectionTypesInCast;
   245     /** Switch: should we keep docComments?
   246      */
   247     boolean keepDocComments;
   249     /** Switch: should we keep line table?
   250      */
   251     boolean keepLineMap;
   253     /** Switch: should we recognize type annotations?
   254      */
   255     boolean allowTypeAnnotations;
   257     /** Switch: is "this" allowed as an identifier?
   258      * This is needed to parse receiver types.
   259      */
   260     boolean allowThisIdent;
   262     /** The type of the method receiver, as specified by a first "this" parameter.
   263      */
   264     JCVariableDecl receiverParam;
   267     /** When terms are parsed, the mode determines which is expected:
   268      *     mode = EXPR        : an expression
   269      *     mode = TYPE        : a type
   270      *     mode = NOPARAMS    : no parameters allowed for type
   271      *     mode = TYPEARG     : type argument
   272      */
   273     static final int EXPR = 0x1;
   274     static final int TYPE = 0x2;
   275     static final int NOPARAMS = 0x4;
   276     static final int TYPEARG = 0x8;
   277     static final int DIAMOND = 0x10;
   279     /** The current mode.
   280      */
   281     private int mode = 0;
   283     /** The mode of the term that was parsed last.
   284      */
   285     private int lastmode = 0;
   287     /* ---------- token management -------------- */
   289     protected Token token;
   291     public Token token() {
   292         return token;
   293     }
   295     public void nextToken() {
   296         S.nextToken();
   297         token = S.token();
   298     }
   300     protected boolean peekToken(Filter<TokenKind> tk) {
   301         return peekToken(0, tk);
   302     }
   304     protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
   305         return tk.accepts(S.token(lookahead + 1).kind);
   306     }
   308     protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
   309         return peekToken(0, tk1, tk2);
   310     }
   312     protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
   313         return tk1.accepts(S.token(lookahead + 1).kind) &&
   314                 tk2.accepts(S.token(lookahead + 2).kind);
   315     }
   317     protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
   318         return peekToken(0, tk1, tk2, tk3);
   319     }
   321     protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
   322         return tk1.accepts(S.token(lookahead + 1).kind) &&
   323                 tk2.accepts(S.token(lookahead + 2).kind) &&
   324                 tk3.accepts(S.token(lookahead + 3).kind);
   325     }
   327     @SuppressWarnings("unchecked")
   328     protected boolean peekToken(Filter<TokenKind>... kinds) {
   329         return peekToken(0, kinds);
   330     }
   332     @SuppressWarnings("unchecked")
   333     protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
   334         for (; lookahead < kinds.length ; lookahead++) {
   335             if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
   336                 return false;
   337             }
   338         }
   339         return true;
   340     }
   342     /* ---------- error recovery -------------- */
   344     private JCErroneous errorTree;
   346     /** Skip forward until a suitable stop token is found.
   347      */
   348     private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   349          while (true) {
   350              switch (token.kind) {
   351                 case SEMI:
   352                     nextToken();
   353                     return;
   354                 case PUBLIC:
   355                 case FINAL:
   356                 case ABSTRACT:
   357                 case MONKEYS_AT:
   358                 case EOF:
   359                 case CLASS:
   360                 case INTERFACE:
   361                 case ENUM:
   362                     return;
   363                 case IMPORT:
   364                     if (stopAtImport)
   365                         return;
   366                     break;
   367                 case LBRACE:
   368                 case RBRACE:
   369                 case PRIVATE:
   370                 case PROTECTED:
   371                 case STATIC:
   372                 case TRANSIENT:
   373                 case NATIVE:
   374                 case VOLATILE:
   375                 case SYNCHRONIZED:
   376                 case STRICTFP:
   377                 case LT:
   378                 case BYTE:
   379                 case SHORT:
   380                 case CHAR:
   381                 case INT:
   382                 case LONG:
   383                 case FLOAT:
   384                 case DOUBLE:
   385                 case BOOLEAN:
   386                 case VOID:
   387                     if (stopAtMemberDecl)
   388                         return;
   389                     break;
   390                 case UNDERSCORE:
   391                 case IDENTIFIER:
   392                    if (stopAtIdentifier)
   393                         return;
   394                     break;
   395                 case CASE:
   396                 case DEFAULT:
   397                 case IF:
   398                 case FOR:
   399                 case WHILE:
   400                 case DO:
   401                 case TRY:
   402                 case SWITCH:
   403                 case RETURN:
   404                 case THROW:
   405                 case BREAK:
   406                 case CONTINUE:
   407                 case ELSE:
   408                 case FINALLY:
   409                 case CATCH:
   410                     if (stopAtStatement)
   411                         return;
   412                     break;
   413             }
   414             nextToken();
   415         }
   416     }
   418     private JCErroneous syntaxError(int pos, String key, TokenKind... args) {
   419         return syntaxError(pos, List.<JCTree>nil(), key, args);
   420     }
   422     private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
   423         setErrorEndPos(pos);
   424         JCErroneous err = F.at(pos).Erroneous(errs);
   425         reportSyntaxError(err, key, (Object[])args);
   426         if (errs != null) {
   427             JCTree last = errs.last();
   428             if (last != null)
   429                 storeEnd(last, pos);
   430         }
   431         return toP(err);
   432     }
   434     private int errorPos = Position.NOPOS;
   436     /**
   437      * Report a syntax using the given the position parameter and arguments,
   438      * unless one was already reported at the same position.
   439      */
   440     private void reportSyntaxError(int pos, String key, Object... args) {
   441         JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
   442         reportSyntaxError(diag, key, args);
   443     }
   445     /**
   446      * Report a syntax error using the given DiagnosticPosition object and
   447      * arguments, unless one was already reported at the same position.
   448      */
   449     private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
   450         int pos = diagPos.getPreferredPosition();
   451         if (pos > S.errPos() || pos == Position.NOPOS) {
   452             if (token.kind == EOF) {
   453                 error(diagPos, "premature.eof");
   454             } else {
   455                 error(diagPos, key, args);
   456             }
   457         }
   458         S.errPos(pos);
   459         if (token.pos == errorPos)
   460             nextToken(); // guarantee progress
   461         errorPos = token.pos;
   462     }
   465     /** Generate a syntax error at current position unless one was already
   466      *  reported at the same position.
   467      */
   468     private JCErroneous syntaxError(String key) {
   469         return syntaxError(token.pos, key);
   470     }
   472     /** Generate a syntax error at current position unless one was
   473      *  already reported at the same position.
   474      */
   475     private JCErroneous syntaxError(String key, TokenKind arg) {
   476         return syntaxError(token.pos, key, arg);
   477     }
   479     /** If next input token matches given token, skip it, otherwise report
   480      *  an error.
   481      */
   482     public void accept(TokenKind tk) {
   483         if (token.kind == tk) {
   484             nextToken();
   485         } else {
   486             setErrorEndPos(token.pos);
   487             reportSyntaxError(S.prevToken().endPos, "expected", tk);
   488         }
   489     }
   491     /** Report an illegal start of expression/type error at given position.
   492      */
   493     JCExpression illegal(int pos) {
   494         setErrorEndPos(pos);
   495         if ((mode & EXPR) != 0)
   496             return syntaxError(pos, "illegal.start.of.expr");
   497         else
   498             return syntaxError(pos, "illegal.start.of.type");
   500     }
   502     /** Report an illegal start of expression/type error at current position.
   503      */
   504     JCExpression illegal() {
   505         return illegal(token.pos);
   506     }
   508     /** Diagnose a modifier flag from the set, if any. */
   509     void checkNoMods(long mods) {
   510         if (mods != 0) {
   511             long lowestMod = mods & -mods;
   512             error(token.pos, "mod.not.allowed.here",
   513                       Flags.asFlagSet(lowestMod));
   514         }
   515     }
   517 /* ---------- doc comments --------- */
   519     /** A table to store all documentation comments
   520      *  indexed by the tree nodes they refer to.
   521      *  defined only if option flag keepDocComment is set.
   522      */
   523     private final DocCommentTable docComments;
   525     /** Make an entry into docComments hashtable,
   526      *  provided flag keepDocComments is set and given doc comment is non-null.
   527      *  @param tree   The tree to be used as index in the hashtable
   528      *  @param dc     The doc comment to associate with the tree, or null.
   529      */
   530     void attach(JCTree tree, Comment dc) {
   531         if (keepDocComments && dc != null) {
   532 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   533             docComments.putComment(tree, dc);
   534         }
   535     }
   537 /* -------- source positions ------- */
   539     private void setErrorEndPos(int errPos) {
   540         endPosTable.setErrorEndPos(errPos);
   541     }
   543     private void storeEnd(JCTree tree, int endpos) {
   544         endPosTable.storeEnd(tree, endpos);
   545     }
   547     private <T extends JCTree> T to(T t) {
   548         return endPosTable.to(t);
   549     }
   551     private <T extends JCTree> T toP(T t) {
   552         return endPosTable.toP(t);
   553     }
   555     /** Get the start position for a tree node.  The start position is
   556      * defined to be the position of the first character of the first
   557      * token of the node's source text.
   558      * @param tree  The tree node
   559      */
   560     public int getStartPos(JCTree tree) {
   561         return TreeInfo.getStartPos(tree);
   562     }
   564     /**
   565      * Get the end position for a tree node.  The end position is
   566      * defined to be the position of the last character of the last
   567      * token of the node's source text.  Returns Position.NOPOS if end
   568      * positions are not generated or the position is otherwise not
   569      * found.
   570      * @param tree  The tree node
   571      */
   572     public int getEndPos(JCTree tree) {
   573         return endPosTable.getEndPos(tree);
   574     }
   578 /* ---------- parsing -------------- */
   580     /**
   581      * Ident = IDENTIFIER
   582      */
   583     Name ident() {
   584         if (token.kind == IDENTIFIER) {
   585             Name name = token.name();
   586             nextToken();
   587             return name;
   588         } else if (token.kind == ASSERT) {
   589             if (allowAsserts) {
   590                 error(token.pos, "assert.as.identifier");
   591                 nextToken();
   592                 return names.error;
   593             } else {
   594                 warning(token.pos, "assert.as.identifier");
   595                 Name name = token.name();
   596                 nextToken();
   597                 return name;
   598             }
   599         } else if (token.kind == ENUM) {
   600             if (allowEnums) {
   601                 error(token.pos, "enum.as.identifier");
   602                 nextToken();
   603                 return names.error;
   604             } else {
   605                 warning(token.pos, "enum.as.identifier");
   606                 Name name = token.name();
   607                 nextToken();
   608                 return name;
   609             }
   610         } else if (token.kind == THIS) {
   611             if (allowThisIdent) {
   612                 // Make sure we're using a supported source version.
   613                 checkTypeAnnotations();
   614                 Name name = token.name();
   615                 nextToken();
   616                 return name;
   617             } else {
   618                 error(token.pos, "this.as.identifier");
   619                 nextToken();
   620                 return names.error;
   621             }
   622         } else if (token.kind == UNDERSCORE) {
   623             warning(token.pos, "underscore.as.identifier");
   624             Name name = token.name();
   625             nextToken();
   626             return name;
   627         } else {
   628             accept(IDENTIFIER);
   629             return names.error;
   630         }
   631     }
   633     /**
   634      * Qualident = Ident { DOT [Annotations] Ident }
   635      */
   636     public JCExpression qualident(boolean allowAnnos) {
   637         JCExpression t = toP(F.at(token.pos).Ident(ident()));
   638         while (token.kind == DOT) {
   639             int pos = token.pos;
   640             nextToken();
   641             List<JCAnnotation> tyannos = null;
   642             if (allowAnnos) {
   643                 tyannos = typeAnnotationsOpt();
   644             }
   645             t = toP(F.at(pos).Select(t, ident()));
   646             if (tyannos != null && tyannos.nonEmpty()) {
   647                 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
   648             }
   649         }
   650         return t;
   651     }
   653     JCExpression literal(Name prefix) {
   654         return literal(prefix, token.pos);
   655     }
   657     /**
   658      * Literal =
   659      *     INTLITERAL
   660      *   | LONGLITERAL
   661      *   | FLOATLITERAL
   662      *   | DOUBLELITERAL
   663      *   | CHARLITERAL
   664      *   | STRINGLITERAL
   665      *   | TRUE
   666      *   | FALSE
   667      *   | NULL
   668      */
   669     JCExpression literal(Name prefix, int pos) {
   670         JCExpression t = errorTree;
   671         switch (token.kind) {
   672         case INTLITERAL:
   673             try {
   674                 t = F.at(pos).Literal(
   675                     TypeTag.INT,
   676                     Convert.string2int(strval(prefix), token.radix()));
   677             } catch (NumberFormatException ex) {
   678                 error(token.pos, "int.number.too.large", strval(prefix));
   679             }
   680             break;
   681         case LONGLITERAL:
   682             try {
   683                 t = F.at(pos).Literal(
   684                     TypeTag.LONG,
   685                     new Long(Convert.string2long(strval(prefix), token.radix())));
   686             } catch (NumberFormatException ex) {
   687                 error(token.pos, "int.number.too.large", strval(prefix));
   688             }
   689             break;
   690         case FLOATLITERAL: {
   691             String proper = token.radix() == 16 ?
   692                     ("0x"+ token.stringVal()) :
   693                     token.stringVal();
   694             Float n;
   695             try {
   696                 n = Float.valueOf(proper);
   697             } catch (NumberFormatException ex) {
   698                 // error already reported in scanner
   699                 n = Float.NaN;
   700             }
   701             if (n.floatValue() == 0.0f && !isZero(proper))
   702                 error(token.pos, "fp.number.too.small");
   703             else if (n.floatValue() == Float.POSITIVE_INFINITY)
   704                 error(token.pos, "fp.number.too.large");
   705             else
   706                 t = F.at(pos).Literal(TypeTag.FLOAT, n);
   707             break;
   708         }
   709         case DOUBLELITERAL: {
   710             String proper = token.radix() == 16 ?
   711                     ("0x"+ token.stringVal()) :
   712                     token.stringVal();
   713             Double n;
   714             try {
   715                 n = Double.valueOf(proper);
   716             } catch (NumberFormatException ex) {
   717                 // error already reported in scanner
   718                 n = Double.NaN;
   719             }
   720             if (n.doubleValue() == 0.0d && !isZero(proper))
   721                 error(token.pos, "fp.number.too.small");
   722             else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   723                 error(token.pos, "fp.number.too.large");
   724             else
   725                 t = F.at(pos).Literal(TypeTag.DOUBLE, n);
   726             break;
   727         }
   728         case CHARLITERAL:
   729             t = F.at(pos).Literal(
   730                 TypeTag.CHAR,
   731                 token.stringVal().charAt(0) + 0);
   732             break;
   733         case STRINGLITERAL:
   734             t = F.at(pos).Literal(
   735                 TypeTag.CLASS,
   736                 token.stringVal());
   737             break;
   738         case TRUE: case FALSE:
   739             t = F.at(pos).Literal(
   740                 TypeTag.BOOLEAN,
   741                 (token.kind == TRUE ? 1 : 0));
   742             break;
   743         case NULL:
   744             t = F.at(pos).Literal(
   745                 TypeTag.BOT,
   746                 null);
   747             break;
   748         default:
   749             Assert.error();
   750         }
   751         if (t == errorTree)
   752             t = F.at(pos).Erroneous();
   753         storeEnd(t, token.endPos);
   754         nextToken();
   755         return t;
   756     }
   757     //where
   758         boolean isZero(String s) {
   759             char[] cs = s.toCharArray();
   760             int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
   761             int i = ((base==16) ? 2 : 0);
   762             while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   763             return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   764         }
   766         String strval(Name prefix) {
   767             String s = token.stringVal();
   768             return prefix.isEmpty() ? s : prefix + s;
   769         }
   771     /** terms can be either expressions or types.
   772      */
   773     public JCExpression parseExpression() {
   774         return term(EXPR);
   775     }
   777     /**
   778      * parses (optional) type annotations followed by a type. If the
   779      * annotations are present before the type and are not consumed during array
   780      * parsing, this method returns a {@link JCAnnotatedType} consisting of
   781      * these annotations and the underlying type. Otherwise, it returns the
   782      * underlying type.
   783      *
   784      * <p>
   785      *
   786      * Note that this method sets {@code mode} to {@code TYPE} first, before
   787      * parsing annotations.
   788      */
   789     public JCExpression parseType() {
   790         List<JCAnnotation> annotations = typeAnnotationsOpt();
   791         return parseType(annotations);
   792     }
   794     public JCExpression parseType(List<JCAnnotation> annotations) {
   795         JCExpression result = unannotatedType();
   797         if (annotations.nonEmpty()) {
   798             result = insertAnnotationsToMostInner(result, annotations, false);
   799         }
   801         return result;
   802     }
   804     public JCExpression unannotatedType() {
   805         return term(TYPE);
   806     }
   808     JCExpression term(int newmode) {
   809         int prevmode = mode;
   810         mode = newmode;
   811         JCExpression t = term();
   812         lastmode = mode;
   813         mode = prevmode;
   814         return t;
   815     }
   817     /**
   818      *  {@literal
   819      *  Expression = Expression1 [ExpressionRest]
   820      *  ExpressionRest = [AssignmentOperator Expression1]
   821      *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   822      *                       "&=" | "|=" | "^=" |
   823      *                       "%=" | "<<=" | ">>=" | ">>>="
   824      *  Type = Type1
   825      *  TypeNoParams = TypeNoParams1
   826      *  StatementExpression = Expression
   827      *  ConstantExpression = Expression
   828      *  }
   829      */
   830     JCExpression term() {
   831         JCExpression t = term1();
   832         if ((mode & EXPR) != 0 &&
   833             token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0)
   834             return termRest(t);
   835         else
   836             return t;
   837     }
   839     JCExpression termRest(JCExpression t) {
   840         switch (token.kind) {
   841         case EQ: {
   842             int pos = token.pos;
   843             nextToken();
   844             mode = EXPR;
   845             JCExpression t1 = term();
   846             return toP(F.at(pos).Assign(t, t1));
   847         }
   848         case PLUSEQ:
   849         case SUBEQ:
   850         case STAREQ:
   851         case SLASHEQ:
   852         case PERCENTEQ:
   853         case AMPEQ:
   854         case BAREQ:
   855         case CARETEQ:
   856         case LTLTEQ:
   857         case GTGTEQ:
   858         case GTGTGTEQ:
   859             int pos = token.pos;
   860             TokenKind tk = token.kind;
   861             nextToken();
   862             mode = EXPR;
   863             JCExpression t1 = term();
   864             return F.at(pos).Assignop(optag(tk), t, t1);
   865         default:
   866             return t;
   867         }
   868     }
   870     /** Expression1   = Expression2 [Expression1Rest]
   871      *  Type1         = Type2
   872      *  TypeNoParams1 = TypeNoParams2
   873      */
   874     JCExpression term1() {
   875         JCExpression t = term2();
   876         if ((mode & EXPR) != 0 && token.kind == QUES) {
   877             mode = EXPR;
   878             return term1Rest(t);
   879         } else {
   880             return t;
   881         }
   882     }
   884     /** Expression1Rest = ["?" Expression ":" Expression1]
   885      */
   886     JCExpression term1Rest(JCExpression t) {
   887         if (token.kind == QUES) {
   888             int pos = token.pos;
   889             nextToken();
   890             JCExpression t1 = term();
   891             accept(COLON);
   892             JCExpression t2 = term1();
   893             return F.at(pos).Conditional(t, t1, t2);
   894         } else {
   895             return t;
   896         }
   897     }
   899     /** Expression2   = Expression3 [Expression2Rest]
   900      *  Type2         = Type3
   901      *  TypeNoParams2 = TypeNoParams3
   902      */
   903     JCExpression term2() {
   904         JCExpression t = term3();
   905         if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) {
   906             mode = EXPR;
   907             return term2Rest(t, TreeInfo.orPrec);
   908         } else {
   909             return t;
   910         }
   911     }
   913     /*  Expression2Rest = {infixop Expression3}
   914      *                  | Expression3 instanceof Type
   915      *  infixop         = "||"
   916      *                  | "&&"
   917      *                  | "|"
   918      *                  | "^"
   919      *                  | "&"
   920      *                  | "==" | "!="
   921      *                  | "<" | ">" | "<=" | ">="
   922      *                  | "<<" | ">>" | ">>>"
   923      *                  | "+" | "-"
   924      *                  | "*" | "/" | "%"
   925      */
   926     JCExpression term2Rest(JCExpression t, int minprec) {
   927         JCExpression[] odStack = newOdStack();
   928         Token[] opStack = newOpStack();
   930         // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   931         int top = 0;
   932         odStack[0] = t;
   933         int startPos = token.pos;
   934         Token topOp = Tokens.DUMMY;
   935         while (prec(token.kind) >= minprec) {
   936             opStack[top] = topOp;
   937             top++;
   938             topOp = token;
   939             nextToken();
   940             odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
   941             while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
   942                 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
   943                                         odStack[top]);
   944                 top--;
   945                 topOp = opStack[top];
   946             }
   947         }
   948         Assert.check(top == 0);
   949         t = odStack[0];
   951         if (t.hasTag(JCTree.Tag.PLUS)) {
   952             StringBuilder buf = foldStrings(t);
   953             if (buf != null) {
   954                 t = toP(F.at(startPos).Literal(TypeTag.CLASS, buf.toString()));
   955             }
   956         }
   958         odStackSupply.add(odStack);
   959         opStackSupply.add(opStack);
   960         return t;
   961     }
   962     //where
   963         /** Construct a binary or type test node.
   964          */
   965         private JCExpression makeOp(int pos,
   966                                     TokenKind topOp,
   967                                     JCExpression od1,
   968                                     JCExpression od2)
   969         {
   970             if (topOp == INSTANCEOF) {
   971                 return F.at(pos).TypeTest(od1, od2);
   972             } else {
   973                 return F.at(pos).Binary(optag(topOp), od1, od2);
   974             }
   975         }
   976         /** If tree is a concatenation of string literals, replace it
   977          *  by a single literal representing the concatenated string.
   978          */
   979         protected StringBuilder foldStrings(JCTree tree) {
   980             if (!allowStringFolding)
   981                 return null;
   982             List<String> buf = List.nil();
   983             while (true) {
   984                 if (tree.hasTag(LITERAL)) {
   985                     JCLiteral lit = (JCLiteral) tree;
   986                     if (lit.typetag == TypeTag.CLASS) {
   987                         StringBuilder sbuf =
   988                             new StringBuilder((String)lit.value);
   989                         while (buf.nonEmpty()) {
   990                             sbuf.append(buf.head);
   991                             buf = buf.tail;
   992                         }
   993                         return sbuf;
   994                     }
   995                 } else if (tree.hasTag(JCTree.Tag.PLUS)) {
   996                     JCBinary op = (JCBinary)tree;
   997                     if (op.rhs.hasTag(LITERAL)) {
   998                         JCLiteral lit = (JCLiteral) op.rhs;
   999                         if (lit.typetag == TypeTag.CLASS) {
  1000                             buf = buf.prepend((String) lit.value);
  1001                             tree = op.lhs;
  1002                             continue;
  1006                 return null;
  1010         /** optimization: To save allocating a new operand/operator stack
  1011          *  for every binary operation, we use supplys.
  1012          */
  1013         ArrayList<JCExpression[]> odStackSupply = new ArrayList<JCExpression[]>();
  1014         ArrayList<Token[]> opStackSupply = new ArrayList<Token[]>();
  1016         private JCExpression[] newOdStack() {
  1017             if (odStackSupply.isEmpty())
  1018                 return new JCExpression[infixPrecedenceLevels + 1];
  1019             return odStackSupply.remove(odStackSupply.size() - 1);
  1022         private Token[] newOpStack() {
  1023             if (opStackSupply.isEmpty())
  1024                 return new Token[infixPrecedenceLevels + 1];
  1025             return opStackSupply.remove(opStackSupply.size() - 1);
  1028     /**
  1029      *  Expression3    = PrefixOp Expression3
  1030      *                 | "(" Expr | TypeNoParams ")" Expression3
  1031      *                 | Primary {Selector} {PostfixOp}
  1033      *  {@literal
  1034      *  Primary        = "(" Expression ")"
  1035      *                 | Literal
  1036      *                 | [TypeArguments] THIS [Arguments]
  1037      *                 | [TypeArguments] SUPER SuperSuffix
  1038      *                 | NEW [TypeArguments] Creator
  1039      *                 | "(" Arguments ")" "->" ( Expression | Block )
  1040      *                 | Ident "->" ( Expression | Block )
  1041      *                 | [Annotations] Ident { "." [Annotations] Ident }
  1042      *                 | Expression3 MemberReferenceSuffix
  1043      *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
  1044      *                   | Arguments
  1045      *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
  1046      *                   ]
  1047      *                 | BasicType BracketsOpt "." CLASS
  1048      *  }
  1050      *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
  1051      *  PostfixOp      = "++" | "--"
  1052      *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
  1053      *                 | BasicType
  1054      *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
  1055      *  Selector       = "." [TypeArguments] Ident [Arguments]
  1056      *                 | "." THIS
  1057      *                 | "." [TypeArguments] SUPER SuperSuffix
  1058      *                 | "." NEW [TypeArguments] InnerCreator
  1059      *                 | "[" Expression "]"
  1060      *  TypeSelector   = "." Ident [TypeArguments]
  1061      *  SuperSuffix    = Arguments | "." Ident [Arguments]
  1062      */
  1063     protected JCExpression term3() {
  1064         int pos = token.pos;
  1065         JCExpression t;
  1066         List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
  1067         switch (token.kind) {
  1068         case QUES:
  1069             if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
  1070                 mode = TYPE;
  1071                 return typeArgument();
  1072             } else
  1073                 return illegal();
  1074         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
  1075             if (typeArgs == null && (mode & EXPR) != 0) {
  1076                 TokenKind tk = token.kind;
  1077                 nextToken();
  1078                 mode = EXPR;
  1079                 if (tk == SUB &&
  1080                     (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
  1081                     token.radix() == 10) {
  1082                     mode = EXPR;
  1083                     t = literal(names.hyphen, pos);
  1084                 } else {
  1085                     t = term3();
  1086                     return F.at(pos).Unary(unoptag(tk), t);
  1088             } else return illegal();
  1089             break;
  1090         case LPAREN:
  1091             if (typeArgs == null && (mode & EXPR) != 0) {
  1092                 ParensResult pres = analyzeParens();
  1093                 switch (pres) {
  1094                     case CAST:
  1095                        accept(LPAREN);
  1096                        mode = TYPE;
  1097                        int pos1 = pos;
  1098                        List<JCExpression> targets = List.of(t = term3());
  1099                        while (token.kind == AMP) {
  1100                            checkIntersectionTypesInCast();
  1101                            accept(AMP);
  1102                            targets = targets.prepend(term3());
  1104                        if (targets.length() > 1) {
  1105                            t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
  1107                        accept(RPAREN);
  1108                        mode = EXPR;
  1109                        JCExpression t1 = term3();
  1110                        return F.at(pos).TypeCast(t, t1);
  1111                     case IMPLICIT_LAMBDA:
  1112                     case EXPLICIT_LAMBDA:
  1113                         t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
  1114                         break;
  1115                     default: //PARENS
  1116                         accept(LPAREN);
  1117                         mode = EXPR;
  1118                         t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec)));
  1119                         accept(RPAREN);
  1120                         t = toP(F.at(pos).Parens(t));
  1121                         break;
  1123             } else {
  1124                 return illegal();
  1126             break;
  1127         case THIS:
  1128             if ((mode & EXPR) != 0) {
  1129                 mode = EXPR;
  1130                 t = to(F.at(pos).Ident(names._this));
  1131                 nextToken();
  1132                 if (typeArgs == null)
  1133                     t = argumentsOpt(null, t);
  1134                 else
  1135                     t = arguments(typeArgs, t);
  1136                 typeArgs = null;
  1137             } else return illegal();
  1138             break;
  1139         case SUPER:
  1140             if ((mode & EXPR) != 0) {
  1141                 mode = EXPR;
  1142                 t = to(F.at(pos).Ident(names._super));
  1143                 t = superSuffix(typeArgs, t);
  1144                 typeArgs = null;
  1145             } else return illegal();
  1146             break;
  1147         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
  1148         case CHARLITERAL: case STRINGLITERAL:
  1149         case TRUE: case FALSE: case NULL:
  1150             if (typeArgs == null && (mode & EXPR) != 0) {
  1151                 mode = EXPR;
  1152                 t = literal(names.empty);
  1153             } else return illegal();
  1154             break;
  1155         case NEW:
  1156             if (typeArgs != null) return illegal();
  1157             if ((mode & EXPR) != 0) {
  1158                 mode = EXPR;
  1159                 nextToken();
  1160                 if (token.kind == LT) typeArgs = typeArguments(false);
  1161                 t = creator(pos, typeArgs);
  1162                 typeArgs = null;
  1163             } else return illegal();
  1164             break;
  1165         case MONKEYS_AT:
  1166             // Only annotated cast types and method references are valid
  1167             List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  1168             if (typeAnnos.isEmpty()) {
  1169                 // else there would be no '@'
  1170                 throw new AssertionError("Expected type annotations, but found none!");
  1173             JCExpression expr = term3();
  1175             if ((mode & TYPE) == 0) {
  1176                 // Type annotations on class literals no longer legal
  1177                 switch (expr.getTag()) {
  1178                 case REFERENCE: {
  1179                     JCMemberReference mref = (JCMemberReference) expr;
  1180                     mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
  1181                     t = mref;
  1182                     break;
  1184                 case SELECT: {
  1185                     JCFieldAccess sel = (JCFieldAccess) expr;
  1187                     if (sel.name != names._class) {
  1188                         return illegal();
  1189                     } else {
  1190                         log.error(token.pos, "no.annotations.on.dot.class");
  1191                         return expr;
  1194                 default:
  1195                     return illegal(typeAnnos.head.pos);
  1198             } else {
  1199                 // Type annotations targeting a cast
  1200                 t = insertAnnotationsToMostInner(expr, typeAnnos, false);
  1202             break;
  1203         case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
  1204             if (typeArgs != null) return illegal();
  1205             if ((mode & EXPR) != 0 && peekToken(ARROW)) {
  1206                 t = lambdaExpressionOrStatement(false, false, pos);
  1207             } else {
  1208                 t = toP(F.at(token.pos).Ident(ident()));
  1209                 loop: while (true) {
  1210                     pos = token.pos;
  1211                     final List<JCAnnotation> annos = typeAnnotationsOpt();
  1213                     // need to report an error later if LBRACKET is for array
  1214                     // index access rather than array creation level
  1215                     if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
  1216                         return illegal(annos.head.pos);
  1218                     switch (token.kind) {
  1219                     case LBRACKET:
  1220                         nextToken();
  1221                         if (token.kind == RBRACKET) {
  1222                             nextToken();
  1223                             t = bracketsOpt(t);
  1224                             t = toP(F.at(pos).TypeArray(t));
  1225                             if (annos.nonEmpty()) {
  1226                                 t = toP(F.at(pos).AnnotatedType(annos, t));
  1228                             // .class is only allowed if there were no annotations
  1229                             JCExpression nt = bracketsSuffix(t);
  1230                             if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) {
  1231                                 // t and nt are different if bracketsSuffix parsed a .class.
  1232                                 // The check for nonEmpty covers the case when the whole array is annotated.
  1233                                 // Helper method isAnnotated looks for annos deeply within t.
  1234                                 syntaxError("no.annotations.on.dot.class");
  1236                             t = nt;
  1237                         } else {
  1238                             if ((mode & EXPR) != 0) {
  1239                                 mode = EXPR;
  1240                                 JCExpression t1 = term();
  1241                                 if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1242                                 t = to(F.at(pos).Indexed(t, t1));
  1244                             accept(RBRACKET);
  1246                         break loop;
  1247                     case LPAREN:
  1248                         if ((mode & EXPR) != 0) {
  1249                             mode = EXPR;
  1250                             t = arguments(typeArgs, t);
  1251                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1252                             typeArgs = null;
  1254                         break loop;
  1255                     case DOT:
  1256                         nextToken();
  1257                         int oldmode = mode;
  1258                         mode &= ~NOPARAMS;
  1259                         typeArgs = typeArgumentsOpt(EXPR);
  1260                         mode = oldmode;
  1261                         if ((mode & EXPR) != 0) {
  1262                             switch (token.kind) {
  1263                             case CLASS:
  1264                                 if (typeArgs != null) return illegal();
  1265                                 mode = EXPR;
  1266                                 t = to(F.at(pos).Select(t, names._class));
  1267                                 nextToken();
  1268                                 break loop;
  1269                             case THIS:
  1270                                 if (typeArgs != null) return illegal();
  1271                                 mode = EXPR;
  1272                                 t = to(F.at(pos).Select(t, names._this));
  1273                                 nextToken();
  1274                                 break loop;
  1275                             case SUPER:
  1276                                 mode = EXPR;
  1277                                 t = to(F.at(pos).Select(t, names._super));
  1278                                 t = superSuffix(typeArgs, t);
  1279                                 typeArgs = null;
  1280                                 break loop;
  1281                             case NEW:
  1282                                 if (typeArgs != null) return illegal();
  1283                                 mode = EXPR;
  1284                                 int pos1 = token.pos;
  1285                                 nextToken();
  1286                                 if (token.kind == LT) typeArgs = typeArguments(false);
  1287                                 t = innerCreator(pos1, typeArgs, t);
  1288                                 typeArgs = null;
  1289                                 break loop;
  1293                         List<JCAnnotation> tyannos = null;
  1294                         if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
  1295                             tyannos = typeAnnotationsOpt();
  1297                         // typeArgs saved for next loop iteration.
  1298                         t = toP(F.at(pos).Select(t, ident()));
  1299                         if (tyannos != null && tyannos.nonEmpty()) {
  1300                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  1302                         break;
  1303                     case ELLIPSIS:
  1304                         if (this.permitTypeAnnotationsPushBack) {
  1305                             this.typeAnnotationsPushedBack = annos;
  1306                         } else if (annos.nonEmpty()) {
  1307                             // Don't return here -- error recovery attempt
  1308                             illegal(annos.head.pos);
  1310                         break loop;
  1311                     case LT:
  1312                         if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
  1313                             //this is an unbound method reference whose qualifier
  1314                             //is a generic type i.e. A<S>::m
  1315                             int pos1 = token.pos;
  1316                             accept(LT);
  1317                             ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
  1318                             args.append(typeArgument());
  1319                             while (token.kind == COMMA) {
  1320                                 nextToken();
  1321                                 args.append(typeArgument());
  1323                             accept(GT);
  1324                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
  1325                             checkGenerics();
  1326                             while (token.kind == DOT) {
  1327                                 nextToken();
  1328                                 mode = TYPE;
  1329                                 t = toP(F.at(token.pos).Select(t, ident()));
  1330                                 t = typeArgumentsOpt(t);
  1332                             t = bracketsOpt(t);
  1333                             if (token.kind != COLCOL) {
  1334                                 //method reference expected here
  1335                                 t = illegal();
  1337                             mode = EXPR;
  1338                             return term3Rest(t, typeArgs);
  1340                         break loop;
  1341                     default:
  1342                         break loop;
  1346             if (typeArgs != null) illegal();
  1347             t = typeArgumentsOpt(t);
  1348             break;
  1349         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1350         case DOUBLE: case BOOLEAN:
  1351             if (typeArgs != null) illegal();
  1352             t = bracketsSuffix(bracketsOpt(basicType()));
  1353             break;
  1354         case VOID:
  1355             if (typeArgs != null) illegal();
  1356             if ((mode & EXPR) != 0) {
  1357                 nextToken();
  1358                 if (token.kind == DOT) {
  1359                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
  1360                     t = bracketsSuffix(ti);
  1361                 } else {
  1362                     return illegal(pos);
  1364             } else {
  1365                 // Support the corner case of myMethodHandle.<void>invoke() by passing
  1366                 // a void type (like other primitive types) to the next phase.
  1367                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
  1368                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
  1369                 nextToken();
  1370                 return ti;
  1371                 //return illegal();
  1373             break;
  1374         default:
  1375             return illegal();
  1377         return term3Rest(t, typeArgs);
  1380     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
  1381         if (typeArgs != null) illegal();
  1382         while (true) {
  1383             int pos1 = token.pos;
  1384             final List<JCAnnotation> annos = typeAnnotationsOpt();
  1386             if (token.kind == LBRACKET) {
  1387                 nextToken();
  1388                 if ((mode & TYPE) != 0) {
  1389                     int oldmode = mode;
  1390                     mode = TYPE;
  1391                     if (token.kind == RBRACKET) {
  1392                         nextToken();
  1393                         t = bracketsOpt(t);
  1394                         t = toP(F.at(pos1).TypeArray(t));
  1395                         if (token.kind == COLCOL) {
  1396                             mode = EXPR;
  1397                             continue;
  1399                         if (annos.nonEmpty()) {
  1400                             t = toP(F.at(pos1).AnnotatedType(annos, t));
  1402                         return t;
  1404                     mode = oldmode;
  1406                 if ((mode & EXPR) != 0) {
  1407                     mode = EXPR;
  1408                     JCExpression t1 = term();
  1409                     t = to(F.at(pos1).Indexed(t, t1));
  1411                 accept(RBRACKET);
  1412             } else if (token.kind == DOT) {
  1413                 nextToken();
  1414                 typeArgs = typeArgumentsOpt(EXPR);
  1415                 if (token.kind == SUPER && (mode & EXPR) != 0) {
  1416                     mode = EXPR;
  1417                     t = to(F.at(pos1).Select(t, names._super));
  1418                     nextToken();
  1419                     t = arguments(typeArgs, t);
  1420                     typeArgs = null;
  1421                 } else if (token.kind == NEW && (mode & EXPR) != 0) {
  1422                     if (typeArgs != null) return illegal();
  1423                     mode = EXPR;
  1424                     int pos2 = token.pos;
  1425                     nextToken();
  1426                     if (token.kind == LT) typeArgs = typeArguments(false);
  1427                     t = innerCreator(pos2, typeArgs, t);
  1428                     typeArgs = null;
  1429                 } else {
  1430                     List<JCAnnotation> tyannos = null;
  1431                     if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
  1432                         // is the mode check needed?
  1433                         tyannos = typeAnnotationsOpt();
  1435                     t = toP(F.at(pos1).Select(t, ident()));
  1436                     if (tyannos != null && tyannos.nonEmpty()) {
  1437                         t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  1439                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  1440                     typeArgs = null;
  1442             } else if ((mode & EXPR) != 0 && token.kind == COLCOL) {
  1443                 mode = EXPR;
  1444                 if (typeArgs != null) return illegal();
  1445                 accept(COLCOL);
  1446                 t = memberReferenceSuffix(pos1, t);
  1447             } else {
  1448                 if (!annos.isEmpty()) {
  1449                     if (permitTypeAnnotationsPushBack)
  1450                         typeAnnotationsPushedBack = annos;
  1451                     else
  1452                         return illegal(annos.head.pos);
  1454                 break;
  1457         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
  1458             mode = EXPR;
  1459             t = to(F.at(token.pos).Unary(
  1460                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
  1461             nextToken();
  1463         return toP(t);
  1466     /**
  1467      * If we see an identifier followed by a '&lt;' it could be an unbound
  1468      * method reference or a binary expression. To disambiguate, look for a
  1469      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
  1470      */
  1471     @SuppressWarnings("fallthrough")
  1472     boolean isUnboundMemberRef() {
  1473         int pos = 0, depth = 0;
  1474         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
  1475             switch (t.kind) {
  1476                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
  1477                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
  1478                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
  1479                 case DOUBLE: case BOOLEAN: case CHAR:
  1480                 case MONKEYS_AT:
  1481                     break;
  1483                 case LPAREN:
  1484                     // skip annotation values
  1485                     int nesting = 0;
  1486                     for (; ; pos++) {
  1487                         TokenKind tk2 = S.token(pos).kind;
  1488                         switch (tk2) {
  1489                             case EOF:
  1490                                 return false;
  1491                             case LPAREN:
  1492                                 nesting++;
  1493                                 break;
  1494                             case RPAREN:
  1495                                 nesting--;
  1496                                 if (nesting == 0) {
  1497                                     continue outer;
  1499                                 break;
  1503                 case LT:
  1504                     depth++; break;
  1505                 case GTGTGT:
  1506                     depth--;
  1507                 case GTGT:
  1508                     depth--;
  1509                 case GT:
  1510                     depth--;
  1511                     if (depth == 0) {
  1512                         TokenKind nextKind = S.token(pos + 1).kind;
  1513                         return
  1514                             nextKind == TokenKind.DOT ||
  1515                             nextKind == TokenKind.LBRACKET ||
  1516                             nextKind == TokenKind.COLCOL;
  1518                     break;
  1519                 default:
  1520                     return false;
  1525     /**
  1526      * If we see an identifier followed by a '&lt;' it could be an unbound
  1527      * method reference or a binary expression. To disambiguate, look for a
  1528      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
  1529      */
  1530     @SuppressWarnings("fallthrough")
  1531     ParensResult analyzeParens() {
  1532         int depth = 0;
  1533         boolean type = false;
  1534         outer: for (int lookahead = 0 ; ; lookahead++) {
  1535             TokenKind tk = S.token(lookahead).kind;
  1536             switch (tk) {
  1537                 case COMMA:
  1538                     type = true;
  1539                 case EXTENDS: case SUPER: case DOT: case AMP:
  1540                     //skip
  1541                     break;
  1542                 case QUES:
  1543                     if (peekToken(lookahead, EXTENDS) ||
  1544                             peekToken(lookahead, SUPER)) {
  1545                         //wildcards
  1546                         type = true;
  1548                     break;
  1549                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
  1550                 case DOUBLE: case BOOLEAN: case CHAR:
  1551                     if (peekToken(lookahead, RPAREN)) {
  1552                         //Type, ')' -> cast
  1553                         return ParensResult.CAST;
  1554                     } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
  1555                         //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
  1556                         return ParensResult.EXPLICIT_LAMBDA;
  1558                     break;
  1559                 case LPAREN:
  1560                     if (lookahead != 0) {
  1561                         // '(' in a non-starting position -> parens
  1562                         return ParensResult.PARENS;
  1563                     } else if (peekToken(lookahead, RPAREN)) {
  1564                         // '(', ')' -> explicit lambda
  1565                         return ParensResult.EXPLICIT_LAMBDA;
  1567                     break;
  1568                 case RPAREN:
  1569                     // if we have seen something that looks like a type,
  1570                     // then it's a cast expression
  1571                     if (type) return ParensResult.CAST;
  1572                     // otherwise, disambiguate cast vs. parenthesized expression
  1573                     // based on subsequent token.
  1574                     switch (S.token(lookahead + 1).kind) {
  1575                         /*case PLUSPLUS: case SUBSUB: */
  1576                         case BANG: case TILDE:
  1577                         case LPAREN: case THIS: case SUPER:
  1578                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
  1579                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
  1580                         case TRUE: case FALSE: case NULL:
  1581                         case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
  1582                         case BYTE: case SHORT: case CHAR: case INT:
  1583                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
  1584                             return ParensResult.CAST;
  1585                         default:
  1586                             return ParensResult.PARENS;
  1588                 case UNDERSCORE:
  1589                 case ASSERT:
  1590                 case ENUM:
  1591                 case IDENTIFIER:
  1592                     if (peekToken(lookahead, LAX_IDENTIFIER)) {
  1593                         // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
  1594                         return ParensResult.EXPLICIT_LAMBDA;
  1595                     } else if (peekToken(lookahead, RPAREN, ARROW)) {
  1596                         // Identifier, ')' '->' -> implicit lambda
  1597                         return ParensResult.IMPLICIT_LAMBDA;
  1599                     break;
  1600                 case FINAL:
  1601                 case ELLIPSIS:
  1602                     //those can only appear in explicit lambdas
  1603                     return ParensResult.EXPLICIT_LAMBDA;
  1604                 case MONKEYS_AT:
  1605                     type = true;
  1606                     lookahead += 1; //skip '@'
  1607                     while (peekToken(lookahead, DOT)) {
  1608                         lookahead += 2;
  1610                     if (peekToken(lookahead, LPAREN)) {
  1611                         lookahead++;
  1612                         //skip annotation values
  1613                         int nesting = 0;
  1614                         for (; ; lookahead++) {
  1615                             TokenKind tk2 = S.token(lookahead).kind;
  1616                             switch (tk2) {
  1617                                 case EOF:
  1618                                     return ParensResult.PARENS;
  1619                                 case LPAREN:
  1620                                     nesting++;
  1621                                     break;
  1622                                 case RPAREN:
  1623                                     nesting--;
  1624                                     if (nesting == 0) {
  1625                                         continue outer;
  1627                                 break;
  1631                     break;
  1632                 case LBRACKET:
  1633                     if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
  1634                         // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
  1635                         return ParensResult.EXPLICIT_LAMBDA;
  1636                     } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
  1637                             peekToken(lookahead, RBRACKET, AMP)) {
  1638                         // '[', ']', ')' -> cast
  1639                         // '[', ']', '&' -> cast (intersection type)
  1640                         return ParensResult.CAST;
  1641                     } else if (peekToken(lookahead, RBRACKET)) {
  1642                         //consume the ']' and skip
  1643                         type = true;
  1644                         lookahead++;
  1645                         break;
  1646                     } else {
  1647                         return ParensResult.PARENS;
  1649                 case LT:
  1650                     depth++; break;
  1651                 case GTGTGT:
  1652                     depth--;
  1653                 case GTGT:
  1654                     depth--;
  1655                 case GT:
  1656                     depth--;
  1657                     if (depth == 0) {
  1658                         if (peekToken(lookahead, RPAREN) ||
  1659                                 peekToken(lookahead, AMP)) {
  1660                             // '>', ')' -> cast
  1661                             // '>', '&' -> cast
  1662                             return ParensResult.CAST;
  1663                         } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
  1664                                 peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
  1665                                 peekToken(lookahead, ELLIPSIS)) {
  1666                             // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
  1667                             // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
  1668                             // '>', '...' -> explicit lambda
  1669                             return ParensResult.EXPLICIT_LAMBDA;
  1671                         //it looks a type, but could still be (i) a cast to generic type,
  1672                         //(ii) an unbound method reference or (iii) an explicit lambda
  1673                         type = true;
  1674                         break;
  1675                     } else if (depth < 0) {
  1676                         //unbalanced '<', '>' - not a generic type
  1677                         return ParensResult.PARENS;
  1679                     break;
  1680                 default:
  1681                     //this includes EOF
  1682                     return ParensResult.PARENS;
  1687     /** Accepts all identifier-like tokens */
  1688     Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
  1689         public boolean accepts(TokenKind t) {
  1690             return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
  1692     };
  1694     enum ParensResult {
  1695         CAST,
  1696         EXPLICIT_LAMBDA,
  1697         IMPLICIT_LAMBDA,
  1698         PARENS;
  1701     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
  1702         List<JCVariableDecl> params = explicitParams ?
  1703                 formalParameters(true) :
  1704                 implicitParameters(hasParens);
  1706         return lambdaExpressionOrStatementRest(params, pos);
  1709     JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
  1710         checkLambda();
  1711         accept(ARROW);
  1713         return token.kind == LBRACE ?
  1714             lambdaStatement(args, pos, pos) :
  1715             lambdaExpression(args, pos);
  1718     JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) {
  1719         JCBlock block = block(pos2, 0);
  1720         return toP(F.at(pos).Lambda(args, block));
  1723     JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
  1724         JCTree expr = parseExpression();
  1725         return toP(F.at(pos).Lambda(args, expr));
  1728     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  1729      */
  1730     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  1731         nextToken();
  1732         if (token.kind == LPAREN || typeArgs != null) {
  1733             t = arguments(typeArgs, t);
  1734         } else if (token.kind == COLCOL) {
  1735             if (typeArgs != null) return illegal();
  1736             t = memberReferenceSuffix(t);
  1737         } else {
  1738             int pos = token.pos;
  1739             accept(DOT);
  1740             typeArgs = (token.kind == LT) ? typeArguments(false) : null;
  1741             t = toP(F.at(pos).Select(t, ident()));
  1742             t = argumentsOpt(typeArgs, t);
  1744         return t;
  1747     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  1748      */
  1749     JCPrimitiveTypeTree basicType() {
  1750         JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
  1751         nextToken();
  1752         return t;
  1755     /** ArgumentsOpt = [ Arguments ]
  1756      */
  1757     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  1758         if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
  1759             mode = EXPR;
  1760             return arguments(typeArgs, t);
  1761         } else {
  1762             return t;
  1766     /** Arguments = "(" [Expression { COMMA Expression }] ")"
  1767      */
  1768     List<JCExpression> arguments() {
  1769         ListBuffer<JCExpression> args = new ListBuffer<>();
  1770         if (token.kind == LPAREN) {
  1771             nextToken();
  1772             if (token.kind != RPAREN) {
  1773                 args.append(parseExpression());
  1774                 while (token.kind == COMMA) {
  1775                     nextToken();
  1776                     args.append(parseExpression());
  1779             accept(RPAREN);
  1780         } else {
  1781             syntaxError(token.pos, "expected", LPAREN);
  1783         return args.toList();
  1786     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  1787         int pos = token.pos;
  1788         List<JCExpression> args = arguments();
  1789         return toP(F.at(pos).Apply(typeArgs, t, args));
  1792     /**  TypeArgumentsOpt = [ TypeArguments ]
  1793      */
  1794     JCExpression typeArgumentsOpt(JCExpression t) {
  1795         if (token.kind == LT &&
  1796             (mode & TYPE) != 0 &&
  1797             (mode & NOPARAMS) == 0) {
  1798             mode = TYPE;
  1799             checkGenerics();
  1800             return typeArguments(t, false);
  1801         } else {
  1802             return t;
  1805     List<JCExpression> typeArgumentsOpt() {
  1806         return typeArgumentsOpt(TYPE);
  1809     List<JCExpression> typeArgumentsOpt(int useMode) {
  1810         if (token.kind == LT) {
  1811             checkGenerics();
  1812             if ((mode & useMode) == 0 ||
  1813                 (mode & NOPARAMS) != 0) {
  1814                 illegal();
  1816             mode = useMode;
  1817             return typeArguments(false);
  1819         return null;
  1822     /**
  1823      *  {@literal
  1824      *  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  1825      *  }
  1826      */
  1827     List<JCExpression> typeArguments(boolean diamondAllowed) {
  1828         if (token.kind == LT) {
  1829             nextToken();
  1830             if (token.kind == GT && diamondAllowed) {
  1831                 checkDiamond();
  1832                 mode |= DIAMOND;
  1833                 nextToken();
  1834                 return List.nil();
  1835             } else {
  1836                 ListBuffer<JCExpression> args = new ListBuffer<>();
  1837                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1838                 while (token.kind == COMMA) {
  1839                     nextToken();
  1840                     args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1842                 switch (token.kind) {
  1844                 case GTGTGTEQ: case GTGTEQ: case GTEQ:
  1845                 case GTGTGT: case GTGT:
  1846                     token = S.split();
  1847                     break;
  1848                 case GT:
  1849                     nextToken();
  1850                     break;
  1851                 default:
  1852                     args.append(syntaxError(token.pos, "expected", GT));
  1853                     break;
  1855                 return args.toList();
  1857         } else {
  1858             return List.<JCExpression>of(syntaxError(token.pos, "expected", LT));
  1862     /**
  1863      *  {@literal
  1864      *  TypeArgument = Type
  1865      *               | [Annotations] "?"
  1866      *               | [Annotations] "?" EXTENDS Type {"&" Type}
  1867      *               | [Annotations] "?" SUPER Type
  1868      *  }
  1869      */
  1870     JCExpression typeArgument() {
  1871         List<JCAnnotation> annotations = typeAnnotationsOpt();
  1872         if (token.kind != QUES) return parseType(annotations);
  1873         int pos = token.pos;
  1874         nextToken();
  1875         JCExpression result;
  1876         if (token.kind == EXTENDS) {
  1877             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
  1878             nextToken();
  1879             JCExpression bound = parseType();
  1880             result = F.at(pos).Wildcard(t, bound);
  1881         } else if (token.kind == SUPER) {
  1882             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
  1883             nextToken();
  1884             JCExpression bound = parseType();
  1885             result = F.at(pos).Wildcard(t, bound);
  1886         } else if (LAX_IDENTIFIER.accepts(token.kind)) {
  1887             //error recovery
  1888             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  1889             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  1890             JCIdent id = toP(F.at(token.pos).Ident(ident()));
  1891             JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  1892             reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
  1893             result = err;
  1894         } else {
  1895             TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
  1896             result = toP(F.at(pos).Wildcard(t, null));
  1898         if (!annotations.isEmpty()) {
  1899             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
  1901         return result;
  1904     JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
  1905         int pos = token.pos;
  1906         List<JCExpression> args = typeArguments(diamondAllowed);
  1907         return toP(F.at(pos).TypeApply(t, args));
  1910     /**
  1911      * BracketsOpt = { [Annotations] "[" "]" }*
  1913      * <p>
  1915      * <code>annotations</code> is the list of annotations targeting
  1916      * the expression <code>t</code>.
  1917      */
  1918     private JCExpression bracketsOpt(JCExpression t,
  1919             List<JCAnnotation> annotations) {
  1920         List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
  1922         if (token.kind == LBRACKET) {
  1923             int pos = token.pos;
  1924             nextToken();
  1925             t = bracketsOptCont(t, pos, nextLevelAnnotations);
  1926         } else if (!nextLevelAnnotations.isEmpty()) {
  1927             if (permitTypeAnnotationsPushBack) {
  1928                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
  1929             } else {
  1930                 return illegal(nextLevelAnnotations.head.pos);
  1934         if (!annotations.isEmpty()) {
  1935             t = toP(F.at(token.pos).AnnotatedType(annotations, t));
  1937         return t;
  1940     /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ]
  1941      */
  1942     private JCExpression bracketsOpt(JCExpression t) {
  1943         return bracketsOpt(t, List.<JCAnnotation>nil());
  1946     private JCExpression bracketsOptCont(JCExpression t, int pos,
  1947             List<JCAnnotation> annotations) {
  1948         accept(RBRACKET);
  1949         t = bracketsOpt(t);
  1950         t = toP(F.at(pos).TypeArray(t));
  1951         if (annotations.nonEmpty()) {
  1952             t = toP(F.at(pos).AnnotatedType(annotations, t));
  1954         return t;
  1957     /** BracketsSuffixExpr = "." CLASS
  1958      *  BracketsSuffixType =
  1959      */
  1960     JCExpression bracketsSuffix(JCExpression t) {
  1961         if ((mode & EXPR) != 0 && token.kind == DOT) {
  1962             mode = EXPR;
  1963             int pos = token.pos;
  1964             nextToken();
  1965             accept(CLASS);
  1966             if (token.pos == endPosTable.errorEndPos) {
  1967                 // error recovery
  1968                 Name name;
  1969                 if (LAX_IDENTIFIER.accepts(token.kind)) {
  1970                     name = token.name();
  1971                     nextToken();
  1972                 } else {
  1973                     name = names.error;
  1975                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  1976             } else {
  1977                 t = toP(F.at(pos).Select(t, names._class));
  1979         } else if ((mode & TYPE) != 0) {
  1980             if (token.kind != COLCOL) {
  1981                 mode = TYPE;
  1983         } else if (token.kind != COLCOL) {
  1984             syntaxError(token.pos, "dot.class.expected");
  1986         return t;
  1989     /**
  1990      * MemberReferenceSuffix = "::" [TypeArguments] Ident
  1991      *                       | "::" [TypeArguments] "new"
  1992      */
  1993     JCExpression memberReferenceSuffix(JCExpression t) {
  1994         int pos1 = token.pos;
  1995         accept(COLCOL);
  1996         return memberReferenceSuffix(pos1, t);
  1999     JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
  2000         checkMethodReferences();
  2001         mode = EXPR;
  2002         List<JCExpression> typeArgs = null;
  2003         if (token.kind == LT) {
  2004             typeArgs = typeArguments(false);
  2006         Name refName;
  2007         ReferenceMode refMode;
  2008         if (token.kind == NEW) {
  2009             refMode = ReferenceMode.NEW;
  2010             refName = names.init;
  2011             nextToken();
  2012         } else {
  2013             refMode = ReferenceMode.INVOKE;
  2014             refName = ident();
  2016         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
  2019     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  2020      */
  2021     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  2022         List<JCAnnotation> newAnnotations = annotationsOpt(Tag.ANNOTATION);
  2024         switch (token.kind) {
  2025         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  2026         case DOUBLE: case BOOLEAN:
  2027             if (typeArgs == null) {
  2028                 if (newAnnotations.isEmpty()) {
  2029                     return arrayCreatorRest(newpos, basicType());
  2030                 } else {
  2031                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
  2034             break;
  2035         default:
  2037         JCExpression t = qualident(true);
  2039         int oldmode = mode;
  2040         mode = TYPE;
  2041         boolean diamondFound = false;
  2042         int lastTypeargsPos = -1;
  2043         if (token.kind == LT) {
  2044             checkGenerics();
  2045             lastTypeargsPos = token.pos;
  2046             t = typeArguments(t, true);
  2047             diamondFound = (mode & DIAMOND) != 0;
  2049         while (token.kind == DOT) {
  2050             if (diamondFound) {
  2051                 //cannot select after a diamond
  2052                 illegal();
  2054             int pos = token.pos;
  2055             nextToken();
  2056             List<JCAnnotation> tyannos = typeAnnotationsOpt();
  2057             t = toP(F.at(pos).Select(t, ident()));
  2059             if (tyannos != null && tyannos.nonEmpty()) {
  2060                 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  2063             if (token.kind == LT) {
  2064                 lastTypeargsPos = token.pos;
  2065                 checkGenerics();
  2066                 t = typeArguments(t, true);
  2067                 diamondFound = (mode & DIAMOND) != 0;
  2070         mode = oldmode;
  2071         if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
  2072             // handle type annotations for non primitive arrays
  2073             if (newAnnotations.nonEmpty()) {
  2074                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
  2077             JCExpression e = arrayCreatorRest(newpos, t);
  2078             if (diamondFound) {
  2079                 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
  2080                 return toP(F.at(newpos).Erroneous(List.of(e)));
  2082             else if (typeArgs != null) {
  2083                 int pos = newpos;
  2084                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  2085                     // note: this should always happen but we should
  2086                     // not rely on this as the parser is continuously
  2087                     // modified to improve error recovery.
  2088                     pos = typeArgs.head.pos;
  2090                 setErrorEndPos(S.prevToken().endPos);
  2091                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
  2092                 reportSyntaxError(err, "cannot.create.array.with.type.arguments");
  2093                 return toP(err);
  2095             return e;
  2096         } else if (token.kind == LPAREN) {
  2097             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
  2098             if (newClass.def != null) {
  2099                 assert newClass.def.mods.annotations.isEmpty();
  2100                 if (newAnnotations.nonEmpty()) {
  2101                     // Add type and declaration annotations to the new class;
  2102                     // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
  2103                     // will later remove all type annotations and only leave the
  2104                     // declaration annotations.
  2105                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
  2106                     newClass.def.mods.annotations = newAnnotations;
  2108             } else {
  2109                 // handle type annotations for instantiations
  2110                 if (newAnnotations.nonEmpty()) {
  2111                     t = insertAnnotationsToMostInner(t, newAnnotations, false);
  2112                     newClass.clazz = t;
  2115             return newClass;
  2116         } else {
  2117             setErrorEndPos(token.pos);
  2118             reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET);
  2119             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  2120             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  2124     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
  2125      */
  2126     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  2127         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
  2129         JCExpression t = toP(F.at(token.pos).Ident(ident()));
  2131         if (newAnnotations.nonEmpty()) {
  2132             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
  2135         if (token.kind == LT) {
  2136             int oldmode = mode;
  2137             checkGenerics();
  2138             t = typeArguments(t, true);
  2139             mode = oldmode;
  2141         return classCreatorRest(newpos, encl, typeArgs, t);
  2144     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
  2145      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
  2146      */
  2147     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  2148         List<JCAnnotation> annos = typeAnnotationsOpt();
  2150         accept(LBRACKET);
  2151         if (token.kind == RBRACKET) {
  2152             accept(RBRACKET);
  2153             elemtype = bracketsOpt(elemtype, annos);
  2154             if (token.kind == LBRACE) {
  2155                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
  2156                 if (annos.nonEmpty()) {
  2157                     // when an array initializer is present then
  2158                     // the parsed annotations should target the
  2159                     // new array tree
  2160                     // bracketsOpt inserts the annotation in
  2161                     // elemtype, and it needs to be corrected
  2162                     //
  2163                     JCAnnotatedType annotated = (JCAnnotatedType)elemtype;
  2164                     assert annotated.annotations == annos;
  2165                     na.annotations = annotated.annotations;
  2166                     na.elemtype = annotated.underlyingType;
  2168                 return na;
  2169             } else {
  2170                 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
  2171                 return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
  2173         } else {
  2174             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  2176             // maintain array dimension type annotations
  2177             ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
  2178             dimAnnotations.append(annos);
  2180             dims.append(parseExpression());
  2181             accept(RBRACKET);
  2182             while (token.kind == LBRACKET
  2183                     || token.kind == MONKEYS_AT) {
  2184                 List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt();
  2185                 int pos = token.pos;
  2186                 nextToken();
  2187                 if (token.kind == RBRACKET) {
  2188                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  2189                 } else {
  2190                     if (token.kind == RBRACKET) { // no dimension
  2191                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  2192                     } else {
  2193                         dimAnnotations.append(maybeDimAnnos);
  2194                         dims.append(parseExpression());
  2195                         accept(RBRACKET);
  2200             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  2201             na.dimAnnotations = dimAnnotations.toList();
  2202             return na;
  2206     /** ClassCreatorRest = Arguments [ClassBody]
  2207      */
  2208     JCNewClass classCreatorRest(int newpos,
  2209                                   JCExpression encl,
  2210                                   List<JCExpression> typeArgs,
  2211                                   JCExpression t)
  2213         List<JCExpression> args = arguments();
  2214         JCClassDecl body = null;
  2215         if (token.kind == LBRACE) {
  2216             int pos = token.pos;
  2217             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  2218             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2219             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  2221         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  2224     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  2225      */
  2226     JCExpression arrayInitializer(int newpos, JCExpression t) {
  2227         accept(LBRACE);
  2228         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  2229         if (token.kind == COMMA) {
  2230             nextToken();
  2231         } else if (token.kind != RBRACE) {
  2232             elems.append(variableInitializer());
  2233             while (token.kind == COMMA) {
  2234                 nextToken();
  2235                 if (token.kind == RBRACE) break;
  2236                 elems.append(variableInitializer());
  2239         accept(RBRACE);
  2240         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  2243     /** VariableInitializer = ArrayInitializer | Expression
  2244      */
  2245     public JCExpression variableInitializer() {
  2246         return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
  2249     /** ParExpression = "(" Expression ")"
  2250      */
  2251     JCExpression parExpression() {
  2252         int pos = token.pos;
  2253         accept(LPAREN);
  2254         JCExpression t = parseExpression();
  2255         accept(RPAREN);
  2256         return toP(F.at(pos).Parens(t));
  2259     /** Block = "{" BlockStatements "}"
  2260      */
  2261     JCBlock block(int pos, long flags) {
  2262         accept(LBRACE);
  2263         List<JCStatement> stats = blockStatements();
  2264         JCBlock t = F.at(pos).Block(flags, stats);
  2265         while (token.kind == CASE || token.kind == DEFAULT) {
  2266             syntaxError("orphaned", token.kind);
  2267             switchBlockStatementGroups();
  2269         // the Block node has a field "endpos" for first char of last token, which is
  2270         // usually but not necessarily the last char of the last token.
  2271         t.endpos = token.pos;
  2272         accept(RBRACE);
  2273         return toP(t);
  2276     public JCBlock block() {
  2277         return block(token.pos, 0);
  2280     /** BlockStatements = { BlockStatement }
  2281      *  BlockStatement  = LocalVariableDeclarationStatement
  2282      *                  | ClassOrInterfaceOrEnumDeclaration
  2283      *                  | [Ident ":"] Statement
  2284      *  LocalVariableDeclarationStatement
  2285      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  2286      */
  2287     @SuppressWarnings("fallthrough")
  2288     List<JCStatement> blockStatements() {
  2289         //todo: skip to anchor on error(?)
  2290         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  2291         while (true) {
  2292             List<JCStatement> stat = blockStatement();
  2293             if (stat.isEmpty()) {
  2294                 return stats.toList();
  2295             } else {
  2296                 if (token.pos <= endPosTable.errorEndPos) {
  2297                     skip(false, true, true, true);
  2299                 stats.addAll(stat);
  2304     /*
  2305      * This method parses a statement treating it as a block, relaxing the
  2306      * JLS restrictions, allows us to parse more faulty code, doing so
  2307      * enables us to provide better and accurate diagnostics to the user.
  2308      */
  2309     JCStatement parseStatementAsBlock() {
  2310         int pos = token.pos;
  2311         List<JCStatement> stats = blockStatement();
  2312         if (stats.isEmpty()) {
  2313             JCErroneous e = F.at(pos).Erroneous();
  2314             error(e, "illegal.start.of.stmt");
  2315             return F.at(pos).Exec(e);
  2316         } else {
  2317             JCStatement first = stats.head;
  2318             String error = null;
  2319             switch (first.getTag()) {
  2320             case CLASSDEF:
  2321                 error = "class.not.allowed";
  2322                 break;
  2323             case VARDEF:
  2324                 error = "variable.not.allowed";
  2325                 break;
  2327             if (error != null) {
  2328                 error(first, error);
  2329                 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
  2330                 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
  2332             return first;
  2336     @SuppressWarnings("fallthrough")
  2337     List<JCStatement> blockStatement() {
  2338         //todo: skip to anchor on error(?)
  2339         int pos = token.pos;
  2340         switch (token.kind) {
  2341         case RBRACE: case CASE: case DEFAULT: case EOF:
  2342             return List.nil();
  2343         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  2344         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  2345         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  2346             return List.of(parseStatement());
  2347         case MONKEYS_AT:
  2348         case FINAL: {
  2349             Comment dc = token.comment(CommentStyle.JAVADOC);
  2350             JCModifiers mods = modifiersOpt();
  2351             if (token.kind == INTERFACE ||
  2352                 token.kind == CLASS ||
  2353                 allowEnums && token.kind == ENUM) {
  2354                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2355             } else {
  2356                 JCExpression t = parseType();
  2357                 ListBuffer<JCStatement> stats =
  2358                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  2359                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2360                 storeEnd(stats.last(), token.endPos);
  2361                 accept(SEMI);
  2362                 return stats.toList();
  2365         case ABSTRACT: case STRICTFP: {
  2366             Comment dc = token.comment(CommentStyle.JAVADOC);
  2367             JCModifiers mods = modifiersOpt();
  2368             return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2370         case INTERFACE:
  2371         case CLASS:
  2372             Comment dc = token.comment(CommentStyle.JAVADOC);
  2373             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2374         case ENUM:
  2375         case ASSERT:
  2376             if (allowEnums && token.kind == ENUM) {
  2377                 error(token.pos, "local.enum");
  2378                 dc = token.comment(CommentStyle.JAVADOC);
  2379                 return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  2380             } else if (allowAsserts && token.kind == ASSERT) {
  2381                 return List.of(parseStatement());
  2383             /* fall through to default */
  2384         default:
  2385             Token prevToken = token;
  2386             JCExpression t = term(EXPR | TYPE);
  2387             if (token.kind == COLON && t.hasTag(IDENT)) {
  2388                 nextToken();
  2389                 JCStatement stat = parseStatement();
  2390                 return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
  2391             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2392                 pos = token.pos;
  2393                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  2394                 F.at(pos);
  2395                 ListBuffer<JCStatement> stats =
  2396                         variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  2397                 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  2398                 storeEnd(stats.last(), token.endPos);
  2399                 accept(SEMI);
  2400                 return stats.toList();
  2401             } else {
  2402                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  2403                 JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
  2404                 accept(SEMI);
  2405                 return List.<JCStatement>of(expr);
  2410     /** Statement =
  2411      *       Block
  2412      *     | IF ParExpression Statement [ELSE Statement]
  2413      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  2414      *     | FOR "(" FormalParameter : Expression ")" Statement
  2415      *     | WHILE ParExpression Statement
  2416      *     | DO Statement WHILE ParExpression ";"
  2417      *     | TRY Block ( Catches | [Catches] FinallyPart )
  2418      *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
  2419      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  2420      *     | SYNCHRONIZED ParExpression Block
  2421      *     | RETURN [Expression] ";"
  2422      *     | THROW Expression ";"
  2423      *     | BREAK [Ident] ";"
  2424      *     | CONTINUE [Ident] ";"
  2425      *     | ASSERT Expression [ ":" Expression ] ";"
  2426      *     | ";"
  2427      *     | ExpressionStatement
  2428      *     | Ident ":" Statement
  2429      */
  2430     @SuppressWarnings("fallthrough")
  2431     public JCStatement parseStatement() {
  2432         int pos = token.pos;
  2433         switch (token.kind) {
  2434         case LBRACE:
  2435             return block();
  2436         case IF: {
  2437             nextToken();
  2438             JCExpression cond = parExpression();
  2439             JCStatement thenpart = parseStatementAsBlock();
  2440             JCStatement elsepart = null;
  2441             if (token.kind == ELSE) {
  2442                 nextToken();
  2443                 elsepart = parseStatementAsBlock();
  2445             return F.at(pos).If(cond, thenpart, elsepart);
  2447         case FOR: {
  2448             nextToken();
  2449             accept(LPAREN);
  2450             List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
  2451             if (inits.length() == 1 &&
  2452                 inits.head.hasTag(VARDEF) &&
  2453                 ((JCVariableDecl) inits.head).init == null &&
  2454                 token.kind == COLON) {
  2455                 checkForeach();
  2456                 JCVariableDecl var = (JCVariableDecl)inits.head;
  2457                 accept(COLON);
  2458                 JCExpression expr = parseExpression();
  2459                 accept(RPAREN);
  2460                 JCStatement body = parseStatementAsBlock();
  2461                 return F.at(pos).ForeachLoop(var, expr, body);
  2462             } else {
  2463                 accept(SEMI);
  2464                 JCExpression cond = token.kind == SEMI ? null : parseExpression();
  2465                 accept(SEMI);
  2466                 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  2467                 accept(RPAREN);
  2468                 JCStatement body = parseStatementAsBlock();
  2469                 return F.at(pos).ForLoop(inits, cond, steps, body);
  2472         case WHILE: {
  2473             nextToken();
  2474             JCExpression cond = parExpression();
  2475             JCStatement body = parseStatementAsBlock();
  2476             return F.at(pos).WhileLoop(cond, body);
  2478         case DO: {
  2479             nextToken();
  2480             JCStatement body = parseStatementAsBlock();
  2481             accept(WHILE);
  2482             JCExpression cond = parExpression();
  2483             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  2484             accept(SEMI);
  2485             return t;
  2487         case TRY: {
  2488             nextToken();
  2489             List<JCTree> resources = List.<JCTree>nil();
  2490             if (token.kind == LPAREN) {
  2491                 checkTryWithResources();
  2492                 nextToken();
  2493                 resources = resources();
  2494                 accept(RPAREN);
  2496             JCBlock body = block();
  2497             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  2498             JCBlock finalizer = null;
  2499             if (token.kind == CATCH || token.kind == FINALLY) {
  2500                 while (token.kind == CATCH) catchers.append(catchClause());
  2501                 if (token.kind == FINALLY) {
  2502                     nextToken();
  2503                     finalizer = block();
  2505             } else {
  2506                 if (allowTWR) {
  2507                     if (resources.isEmpty())
  2508                         error(pos, "try.without.catch.finally.or.resource.decls");
  2509                 } else
  2510                     error(pos, "try.without.catch.or.finally");
  2512             return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
  2514         case SWITCH: {
  2515             nextToken();
  2516             JCExpression selector = parExpression();
  2517             accept(LBRACE);
  2518             List<JCCase> cases = switchBlockStatementGroups();
  2519             JCSwitch t = to(F.at(pos).Switch(selector, cases));
  2520             accept(RBRACE);
  2521             return t;
  2523         case SYNCHRONIZED: {
  2524             nextToken();
  2525             JCExpression lock = parExpression();
  2526             JCBlock body = block();
  2527             return F.at(pos).Synchronized(lock, body);
  2529         case RETURN: {
  2530             nextToken();
  2531             JCExpression result = token.kind == SEMI ? null : parseExpression();
  2532             JCReturn t = to(F.at(pos).Return(result));
  2533             accept(SEMI);
  2534             return t;
  2536         case THROW: {
  2537             nextToken();
  2538             JCExpression exc = parseExpression();
  2539             JCThrow t = to(F.at(pos).Throw(exc));
  2540             accept(SEMI);
  2541             return t;
  2543         case BREAK: {
  2544             nextToken();
  2545             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
  2546             JCBreak t = to(F.at(pos).Break(label));
  2547             accept(SEMI);
  2548             return t;
  2550         case CONTINUE: {
  2551             nextToken();
  2552             Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
  2553             JCContinue t =  to(F.at(pos).Continue(label));
  2554             accept(SEMI);
  2555             return t;
  2557         case SEMI:
  2558             nextToken();
  2559             return toP(F.at(pos).Skip());
  2560         case ELSE:
  2561             int elsePos = token.pos;
  2562             nextToken();
  2563             return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
  2564         case FINALLY:
  2565             int finallyPos = token.pos;
  2566             nextToken();
  2567             return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
  2568         case CATCH:
  2569             return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
  2570         case ASSERT: {
  2571             if (allowAsserts && token.kind == ASSERT) {
  2572                 nextToken();
  2573                 JCExpression assertion = parseExpression();
  2574                 JCExpression message = null;
  2575                 if (token.kind == COLON) {
  2576                     nextToken();
  2577                     message = parseExpression();
  2579                 JCAssert t = to(F.at(pos).Assert(assertion, message));
  2580                 accept(SEMI);
  2581                 return t;
  2583             /* else fall through to default case */
  2585         case ENUM:
  2586         default:
  2587             Token prevToken = token;
  2588             JCExpression expr = parseExpression();
  2589             if (token.kind == COLON && expr.hasTag(IDENT)) {
  2590                 nextToken();
  2591                 JCStatement stat = parseStatement();
  2592                 return F.at(pos).Labelled(prevToken.name(), stat);
  2593             } else {
  2594                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  2595                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  2596                 accept(SEMI);
  2597                 return stat;
  2602     private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
  2603         int errPos = S.errPos();
  2604         JCTree stm = action.doRecover(this);
  2605         S.errPos(errPos);
  2606         return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
  2609     /** CatchClause     = CATCH "(" FormalParameter ")" Block
  2610      * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
  2611      */
  2612     protected JCCatch catchClause() {
  2613         int pos = token.pos;
  2614         accept(CATCH);
  2615         accept(LPAREN);
  2616         JCModifiers mods = optFinal(Flags.PARAMETER);
  2617         List<JCExpression> catchTypes = catchTypes();
  2618         JCExpression paramType = catchTypes.size() > 1 ?
  2619                 toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
  2620                 catchTypes.head;
  2621         JCVariableDecl formal = variableDeclaratorId(mods, paramType);
  2622         accept(RPAREN);
  2623         JCBlock body = block();
  2624         return F.at(pos).Catch(formal, body);
  2627     List<JCExpression> catchTypes() {
  2628         ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
  2629         catchTypes.add(parseType());
  2630         while (token.kind == BAR) {
  2631             checkMulticatch();
  2632             nextToken();
  2633             // Instead of qualident this is now parseType.
  2634             // But would that allow too much, e.g. arrays or generics?
  2635             catchTypes.add(parseType());
  2637         return catchTypes.toList();
  2640     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  2641      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  2642      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  2643      */
  2644     List<JCCase> switchBlockStatementGroups() {
  2645         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  2646         while (true) {
  2647             int pos = token.pos;
  2648             switch (token.kind) {
  2649             case CASE:
  2650             case DEFAULT:
  2651                 cases.append(switchBlockStatementGroup());
  2652                 break;
  2653             case RBRACE: case EOF:
  2654                 return cases.toList();
  2655             default:
  2656                 nextToken(); // to ensure progress
  2657                 syntaxError(pos, "expected3",
  2658                     CASE, DEFAULT, RBRACE);
  2663     protected JCCase switchBlockStatementGroup() {
  2664         int pos = token.pos;
  2665         List<JCStatement> stats;
  2666         JCCase c;
  2667         switch (token.kind) {
  2668         case CASE:
  2669             nextToken();
  2670             JCExpression pat = parseExpression();
  2671             accept(COLON);
  2672             stats = blockStatements();
  2673             c = F.at(pos).Case(pat, stats);
  2674             if (stats.isEmpty())
  2675                 storeEnd(c, S.prevToken().endPos);
  2676             return c;
  2677         case DEFAULT:
  2678             nextToken();
  2679             accept(COLON);
  2680             stats = blockStatements();
  2681             c = F.at(pos).Case(null, stats);
  2682             if (stats.isEmpty())
  2683                 storeEnd(c, S.prevToken().endPos);
  2684             return c;
  2686         throw new AssertionError("should not reach here");
  2689     /** MoreStatementExpressions = { COMMA StatementExpression }
  2690      */
  2691     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  2692                                                                     JCExpression first,
  2693                                                                     T stats) {
  2694         // This Exec is a "StatementExpression"; it subsumes no terminating token
  2695         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  2696         while (token.kind == COMMA) {
  2697             nextToken();
  2698             pos = token.pos;
  2699             JCExpression t = parseExpression();
  2700             // This Exec is a "StatementExpression"; it subsumes no terminating token
  2701             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  2703         return stats;
  2706     /** ForInit = StatementExpression MoreStatementExpressions
  2707      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  2708      */
  2709     List<JCStatement> forInit() {
  2710         ListBuffer<JCStatement> stats = new ListBuffer<>();
  2711         int pos = token.pos;
  2712         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
  2713             return variableDeclarators(optFinal(0), parseType(), stats).toList();
  2714         } else {
  2715             JCExpression t = term(EXPR | TYPE);
  2716             if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  2717                 return variableDeclarators(modifiersOpt(), t, stats).toList();
  2718             } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
  2719                 error(pos, "bad.initializer", "for-loop");
  2720                 return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
  2721             } else {
  2722                 return moreStatementExpressions(pos, t, stats).toList();
  2727     /** ForUpdate = StatementExpression MoreStatementExpressions
  2728      */
  2729     List<JCExpressionStatement> forUpdate() {
  2730         return moreStatementExpressions(token.pos,
  2731                                         parseExpression(),
  2732                                         new ListBuffer<JCExpressionStatement>()).toList();
  2735     /** AnnotationsOpt = { '@' Annotation }
  2737      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2738      */
  2739     List<JCAnnotation> annotationsOpt(Tag kind) {
  2740         if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  2741         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  2742         int prevmode = mode;
  2743         while (token.kind == MONKEYS_AT) {
  2744             int pos = token.pos;
  2745             nextToken();
  2746             buf.append(annotation(pos, kind));
  2748         lastmode = mode;
  2749         mode = prevmode;
  2750         List<JCAnnotation> annotations = buf.toList();
  2752         return annotations;
  2755     List<JCAnnotation> typeAnnotationsOpt() {
  2756         List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
  2757         return annotations;
  2760     /** ModifiersOpt = { Modifier }
  2761      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  2762      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  2763      *           | "@" Annotation
  2764      */
  2765     JCModifiers modifiersOpt() {
  2766         return modifiersOpt(null);
  2768     protected JCModifiers modifiersOpt(JCModifiers partial) {
  2769         long flags;
  2770         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  2771         int pos;
  2772         if (partial == null) {
  2773             flags = 0;
  2774             pos = token.pos;
  2775         } else {
  2776             flags = partial.flags;
  2777             annotations.appendList(partial.annotations);
  2778             pos = partial.pos;
  2780         if (token.deprecatedFlag()) {
  2781             flags |= Flags.DEPRECATED;
  2783         int lastPos;
  2784     loop:
  2785         while (true) {
  2786             long flag;
  2787             switch (token.kind) {
  2788             case PRIVATE     : flag = Flags.PRIVATE; break;
  2789             case PROTECTED   : flag = Flags.PROTECTED; break;
  2790             case PUBLIC      : flag = Flags.PUBLIC; break;
  2791             case STATIC      : flag = Flags.STATIC; break;
  2792             case TRANSIENT   : flag = Flags.TRANSIENT; break;
  2793             case FINAL       : flag = Flags.FINAL; break;
  2794             case ABSTRACT    : flag = Flags.ABSTRACT; break;
  2795             case NATIVE      : flag = Flags.NATIVE; break;
  2796             case VOLATILE    : flag = Flags.VOLATILE; break;
  2797             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  2798             case STRICTFP    : flag = Flags.STRICTFP; break;
  2799             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  2800             case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
  2801             case ERROR       : flag = 0; nextToken(); break;
  2802             default: break loop;
  2804             if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
  2805             lastPos = token.pos;
  2806             nextToken();
  2807             if (flag == Flags.ANNOTATION) {
  2808                 checkAnnotations();
  2809                 if (token.kind != INTERFACE) {
  2810                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
  2811                     // if first modifier is an annotation, set pos to annotation's.
  2812                     if (flags == 0 && annotations.isEmpty())
  2813                         pos = ann.pos;
  2814                     annotations.append(ann);
  2815                     flag = 0;
  2818             flags |= flag;
  2820         switch (token.kind) {
  2821         case ENUM: flags |= Flags.ENUM; break;
  2822         case INTERFACE: flags |= Flags.INTERFACE; break;
  2823         default: break;
  2826         /* A modifiers tree with no modifier tokens or annotations
  2827          * has no text position. */
  2828         if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
  2829             pos = Position.NOPOS;
  2831         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  2832         if (pos != Position.NOPOS)
  2833             storeEnd(mods, S.prevToken().endPos);
  2834         return mods;
  2837     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  2839      * @param pos position of "@" token
  2840      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  2841      */
  2842     JCAnnotation annotation(int pos, Tag kind) {
  2843         // accept(AT); // AT consumed by caller
  2844         checkAnnotations();
  2845         if (kind == Tag.TYPE_ANNOTATION) {
  2846             checkTypeAnnotations();
  2848         JCTree ident = qualident(false);
  2849         List<JCExpression> fieldValues = annotationFieldValuesOpt();
  2850         JCAnnotation ann;
  2851         if (kind == Tag.ANNOTATION) {
  2852             ann = F.at(pos).Annotation(ident, fieldValues);
  2853         } else if (kind == Tag.TYPE_ANNOTATION) {
  2854             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
  2855         } else {
  2856             throw new AssertionError("Unhandled annotation kind: " + kind);
  2859         storeEnd(ann, S.prevToken().endPos);
  2860         return ann;
  2863     List<JCExpression> annotationFieldValuesOpt() {
  2864         return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  2867     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  2868     List<JCExpression> annotationFieldValues() {
  2869         accept(LPAREN);
  2870         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2871         if (token.kind != RPAREN) {
  2872             buf.append(annotationFieldValue());
  2873             while (token.kind == COMMA) {
  2874                 nextToken();
  2875                 buf.append(annotationFieldValue());
  2878         accept(RPAREN);
  2879         return buf.toList();
  2882     /** AnnotationFieldValue    = AnnotationValue
  2883      *                          | Identifier "=" AnnotationValue
  2884      */
  2885     JCExpression annotationFieldValue() {
  2886         if (LAX_IDENTIFIER.accepts(token.kind)) {
  2887             mode = EXPR;
  2888             JCExpression t1 = term1();
  2889             if (t1.hasTag(IDENT) && token.kind == EQ) {
  2890                 int pos = token.pos;
  2891                 accept(EQ);
  2892                 JCExpression v = annotationValue();
  2893                 return toP(F.at(pos).Assign(t1, v));
  2894             } else {
  2895                 return t1;
  2898         return annotationValue();
  2901     /* AnnotationValue          = ConditionalExpression
  2902      *                          | Annotation
  2903      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
  2904      */
  2905     JCExpression annotationValue() {
  2906         int pos;
  2907         switch (token.kind) {
  2908         case MONKEYS_AT:
  2909             pos = token.pos;
  2910             nextToken();
  2911             return annotation(pos, Tag.ANNOTATION);
  2912         case LBRACE:
  2913             pos = token.pos;
  2914             accept(LBRACE);
  2915             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2916             if (token.kind == COMMA) {
  2917                 nextToken();
  2918             } else if (token.kind != RBRACE) {
  2919                 buf.append(annotationValue());
  2920                 while (token.kind == COMMA) {
  2921                     nextToken();
  2922                     if (token.kind == RBRACE) break;
  2923                     buf.append(annotationValue());
  2926             accept(RBRACE);
  2927             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  2928         default:
  2929             mode = EXPR;
  2930             return term1();
  2934     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  2935      */
  2936     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  2937                                                                          JCExpression type,
  2938                                                                          T vdefs)
  2940         return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
  2943     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  2944      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  2946      *  @param reqInit  Is an initializer always required?
  2947      *  @param dc       The documentation comment for the variable declarations, or null.
  2948      */
  2949     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  2950                                                                      JCModifiers mods,
  2951                                                                      JCExpression type,
  2952                                                                      Name name,
  2953                                                                      boolean reqInit,
  2954                                                                      Comment dc,
  2955                                                                      T vdefs)
  2957         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  2958         while (token.kind == COMMA) {
  2959             // All but last of multiple declarators subsume a comma
  2960             storeEnd((JCTree)vdefs.last(), token.endPos);
  2961             nextToken();
  2962             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  2964         return vdefs;
  2967     /** VariableDeclarator = Ident VariableDeclaratorRest
  2968      *  ConstantDeclarator = Ident ConstantDeclaratorRest
  2969      */
  2970     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
  2971         return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
  2974     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  2975      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  2977      *  @param reqInit  Is an initializer always required?
  2978      *  @param dc       The documentation comment for the variable declarations, or null.
  2979      */
  2980     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  2981                                   boolean reqInit, Comment dc) {
  2982         type = bracketsOpt(type);
  2983         JCExpression init = null;
  2984         if (token.kind == EQ) {
  2985             nextToken();
  2986             init = variableInitializer();
  2988         else if (reqInit) syntaxError(token.pos, "expected", EQ);
  2989         JCVariableDecl result =
  2990             toP(F.at(pos).VarDef(mods, name, type, init));
  2991         attach(result, dc);
  2992         return result;
  2995     /** VariableDeclaratorId = Ident BracketsOpt
  2996      */
  2997     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  2998         return variableDeclaratorId(mods, type, false);
  3000     //where
  3001     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
  3002         int pos = token.pos;
  3003         Name name;
  3004         if (lambdaParameter && token.kind == UNDERSCORE) {
  3005             log.error(pos, "underscore.as.identifier.in.lambda");
  3006             name = token.name();
  3007             nextToken();
  3008         } else {
  3009             if (allowThisIdent) {
  3010                 JCExpression pn = qualident(false);
  3011                 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
  3012                     name = ((JCIdent)pn).name;
  3013                 } else {
  3014                     if ((mods.flags & Flags.VARARGS) != 0) {
  3015                         log.error(token.pos, "varargs.and.receiver");
  3017                     if (token.kind == LBRACKET) {
  3018                         log.error(token.pos, "array.and.receiver");
  3020                     return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
  3022             } else {
  3023                 name = ident();
  3026         if ((mods.flags & Flags.VARARGS) != 0 &&
  3027                 token.kind == LBRACKET) {
  3028             log.error(token.pos, "varargs.and.old.array.syntax");
  3030         type = bracketsOpt(type);
  3031         return toP(F.at(pos).VarDef(mods, name, type, null));
  3034     /** Resources = Resource { ";" Resources }
  3035      */
  3036     List<JCTree> resources() {
  3037         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3038         defs.append(resource());
  3039         while (token.kind == SEMI) {
  3040             // All but last of multiple declarators must subsume a semicolon
  3041             storeEnd(defs.last(), token.endPos);
  3042             int semiColonPos = token.pos;
  3043             nextToken();
  3044             if (token.kind == RPAREN) { // Optional trailing semicolon
  3045                                        // after last resource
  3046                 break;
  3048             defs.append(resource());
  3050         return defs.toList();
  3053     /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
  3054      */
  3055     protected JCTree resource() {
  3056         JCModifiers optFinal = optFinal(Flags.FINAL);
  3057         JCExpression type = parseType();
  3058         int pos = token.pos;
  3059         Name ident = ident();
  3060         return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
  3063     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  3064      */
  3065     public JCTree.JCCompilationUnit parseCompilationUnit() {
  3066         Token firstToken = token;
  3067         JCExpression pid = null;
  3068         JCModifiers mods = null;
  3069         boolean consumedToplevelDoc = false;
  3070         boolean seenImport = false;
  3071         boolean seenPackage = false;
  3072         List<JCAnnotation> packageAnnotations = List.nil();
  3073         if (token.kind == MONKEYS_AT)
  3074             mods = modifiersOpt();
  3076         if (token.kind == PACKAGE) {
  3077             seenPackage = true;
  3078             if (mods != null) {
  3079                 checkNoMods(mods.flags);
  3080                 packageAnnotations = mods.annotations;
  3081                 mods = null;
  3083             nextToken();
  3084             pid = qualident(false);
  3085             accept(SEMI);
  3087         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3088         boolean checkForImports = true;
  3089         boolean firstTypeDecl = true;
  3090         while (token.kind != EOF) {
  3091             if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
  3092                 // error recovery
  3093                 skip(checkForImports, false, false, false);
  3094                 if (token.kind == EOF)
  3095                     break;
  3097             if (checkForImports && mods == null && token.kind == IMPORT) {
  3098                 seenImport = true;
  3099                 defs.append(importDeclaration());
  3100             } else {
  3101                 Comment docComment = token.comment(CommentStyle.JAVADOC);
  3102                 if (firstTypeDecl && !seenImport && !seenPackage) {
  3103                     docComment = firstToken.comment(CommentStyle.JAVADOC);
  3104                     consumedToplevelDoc = true;
  3106                 JCTree def = typeDeclaration(mods, docComment);
  3107                 if (def instanceof JCExpressionStatement)
  3108                     def = ((JCExpressionStatement)def).expr;
  3109                 defs.append(def);
  3110                 if (def instanceof JCClassDecl)
  3111                     checkForImports = false;
  3112                 mods = null;
  3113                 firstTypeDecl = false;
  3116         JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
  3117         if (!consumedToplevelDoc)
  3118             attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
  3119         if (defs.isEmpty())
  3120             storeEnd(toplevel, S.prevToken().endPos);
  3121         if (keepDocComments)
  3122             toplevel.docComments = docComments;
  3123         if (keepLineMap)
  3124             toplevel.lineMap = S.getLineMap();
  3125         this.endPosTable.setParser(null); // remove reference to parser
  3126         toplevel.endPositions = this.endPosTable;
  3127         return toplevel;
  3130     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  3131      */
  3132     JCTree importDeclaration() {
  3133         int pos = token.pos;
  3134         nextToken();
  3135         boolean importStatic = false;
  3136         if (token.kind == STATIC) {
  3137             checkStaticImports();
  3138             importStatic = true;
  3139             nextToken();
  3141         JCExpression pid = toP(F.at(token.pos).Ident(ident()));
  3142         do {
  3143             int pos1 = token.pos;
  3144             accept(DOT);
  3145             if (token.kind == STAR) {
  3146                 pid = to(F.at(pos1).Select(pid, names.asterisk));
  3147                 nextToken();
  3148                 break;
  3149             } else {
  3150                 pid = toP(F.at(pos1).Select(pid, ident()));
  3152         } while (token.kind == DOT);
  3153         accept(SEMI);
  3154         return toP(F.at(pos).Import(pid, importStatic));
  3157     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  3158      *                  | ";"
  3159      */
  3160     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
  3161         int pos = token.pos;
  3162         if (mods == null && token.kind == SEMI) {
  3163             nextToken();
  3164             return toP(F.at(pos).Skip());
  3165         } else {
  3166             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
  3170     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  3171      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  3172      *  @param mods     Any modifiers starting the class or interface declaration
  3173      *  @param dc       The documentation comment for the class, or null.
  3174      */
  3175     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
  3176         if (token.kind == CLASS) {
  3177             return classDeclaration(mods, dc);
  3178         } else if (token.kind == INTERFACE) {
  3179             return interfaceDeclaration(mods, dc);
  3180         } else if (allowEnums) {
  3181             if (token.kind == ENUM) {
  3182                 return enumDeclaration(mods, dc);
  3183             } else {
  3184                 int pos = token.pos;
  3185                 List<JCTree> errs;
  3186                 if (LAX_IDENTIFIER.accepts(token.kind)) {
  3187                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  3188                     setErrorEndPos(token.pos);
  3189                 } else {
  3190                     errs = List.<JCTree>of(mods);
  3192                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
  3193                                               CLASS, INTERFACE, ENUM)));
  3195         } else {
  3196             if (token.kind == ENUM) {
  3197                 error(token.pos, "enums.not.supported.in.source", source.name);
  3198                 allowEnums = true;
  3199                 return enumDeclaration(mods, dc);
  3201             int pos = token.pos;
  3202             List<JCTree> errs;
  3203             if (LAX_IDENTIFIER.accepts(token.kind)) {
  3204                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  3205                 setErrorEndPos(token.pos);
  3206             } else {
  3207                 errs = List.<JCTree>of(mods);
  3209             return toP(F.Exec(syntaxError(pos, errs, "expected2",
  3210                                           CLASS, INTERFACE)));
  3214     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  3215      *                     [IMPLEMENTS TypeList] ClassBody
  3216      *  @param mods    The modifiers starting the class declaration
  3217      *  @param dc       The documentation comment for the class, or null.
  3218      */
  3219     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
  3220         int pos = token.pos;
  3221         accept(CLASS);
  3222         Name name = ident();
  3224         List<JCTypeParameter> typarams = typeParametersOpt();
  3226         JCExpression extending = null;
  3227         if (token.kind == EXTENDS) {
  3228             nextToken();
  3229             extending = parseType();
  3231         List<JCExpression> implementing = List.nil();
  3232         if (token.kind == IMPLEMENTS) {
  3233             nextToken();
  3234             implementing = typeList();
  3236         List<JCTree> defs = classOrInterfaceBody(name, false);
  3237         JCClassDecl result = toP(F.at(pos).ClassDef(
  3238             mods, name, typarams, extending, implementing, defs));
  3239         attach(result, dc);
  3240         return result;
  3243     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  3244      *                         [EXTENDS TypeList] InterfaceBody
  3245      *  @param mods    The modifiers starting the interface declaration
  3246      *  @param dc       The documentation comment for the interface, or null.
  3247      */
  3248     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
  3249         int pos = token.pos;
  3250         accept(INTERFACE);
  3251         Name name = ident();
  3253         List<JCTypeParameter> typarams = typeParametersOpt();
  3255         List<JCExpression> extending = List.nil();
  3256         if (token.kind == EXTENDS) {
  3257             nextToken();
  3258             extending = typeList();
  3260         List<JCTree> defs = classOrInterfaceBody(name, true);
  3261         JCClassDecl result = toP(F.at(pos).ClassDef(
  3262             mods, name, typarams, null, extending, defs));
  3263         attach(result, dc);
  3264         return result;
  3267     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  3268      *  @param mods    The modifiers starting the enum declaration
  3269      *  @param dc       The documentation comment for the enum, or null.
  3270      */
  3271     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
  3272         int pos = token.pos;
  3273         accept(ENUM);
  3274         Name name = ident();
  3276         List<JCExpression> implementing = List.nil();
  3277         if (token.kind == IMPLEMENTS) {
  3278             nextToken();
  3279             implementing = typeList();
  3282         List<JCTree> defs = enumBody(name);
  3283         mods.flags |= Flags.ENUM;
  3284         JCClassDecl result = toP(F.at(pos).
  3285             ClassDef(mods, name, List.<JCTypeParameter>nil(),
  3286                 null, implementing, defs));
  3287         attach(result, dc);
  3288         return result;
  3291     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  3292      *                  [ ";" {ClassBodyDeclaration} ] "}"
  3293      */
  3294     List<JCTree> enumBody(Name enumName) {
  3295         accept(LBRACE);
  3296         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3297         if (token.kind == COMMA) {
  3298             nextToken();
  3299         } else if (token.kind != RBRACE && token.kind != SEMI) {
  3300             defs.append(enumeratorDeclaration(enumName));
  3301             while (token.kind == COMMA) {
  3302                 nextToken();
  3303                 if (token.kind == RBRACE || token.kind == SEMI) break;
  3304                 defs.append(enumeratorDeclaration(enumName));
  3306             if (token.kind != SEMI && token.kind != RBRACE) {
  3307                 defs.append(syntaxError(token.pos, "expected3",
  3308                                 COMMA, RBRACE, SEMI));
  3309                 nextToken();
  3312         if (token.kind == SEMI) {
  3313             nextToken();
  3314             while (token.kind != RBRACE && token.kind != EOF) {
  3315                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  3316                                                                 false));
  3317                 if (token.pos <= endPosTable.errorEndPos) {
  3318                     // error recovery
  3319                    skip(false, true, true, false);
  3323         accept(RBRACE);
  3324         return defs.toList();
  3327     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  3328      */
  3329     JCTree enumeratorDeclaration(Name enumName) {
  3330         Comment dc = token.comment(CommentStyle.JAVADOC);
  3331         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  3332         if (token.deprecatedFlag()) {
  3333             flags |= Flags.DEPRECATED;
  3335         int pos = token.pos;
  3336         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
  3337         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  3338         List<JCExpression> typeArgs = typeArgumentsOpt();
  3339         int identPos = token.pos;
  3340         Name name = ident();
  3341         int createPos = token.pos;
  3342         List<JCExpression> args = (token.kind == LPAREN)
  3343             ? arguments() : List.<JCExpression>nil();
  3344         JCClassDecl body = null;
  3345         if (token.kind == LBRACE) {
  3346             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  3347             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  3348             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  3350         if (args.isEmpty() && body == null)
  3351             createPos = identPos;
  3352         JCIdent ident = F.at(identPos).Ident(enumName);
  3353         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  3354         if (createPos != identPos)
  3355             storeEnd(create, S.prevToken().endPos);
  3356         ident = F.at(identPos).Ident(enumName);
  3357         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  3358         attach(result, dc);
  3359         return result;
  3362     /** TypeList = Type {"," Type}
  3363      */
  3364     List<JCExpression> typeList() {
  3365         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  3366         ts.append(parseType());
  3367         while (token.kind == COMMA) {
  3368             nextToken();
  3369             ts.append(parseType());
  3371         return ts.toList();
  3374     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  3375      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  3376      */
  3377     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  3378         accept(LBRACE);
  3379         if (token.pos <= endPosTable.errorEndPos) {
  3380             // error recovery
  3381             skip(false, true, false, false);
  3382             if (token.kind == LBRACE)
  3383                 nextToken();
  3385         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  3386         while (token.kind != RBRACE && token.kind != EOF) {
  3387             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  3388             if (token.pos <= endPosTable.errorEndPos) {
  3389                // error recovery
  3390                skip(false, true, true, false);
  3393         accept(RBRACE);
  3394         return defs.toList();
  3397     /** ClassBodyDeclaration =
  3398      *      ";"
  3399      *    | [STATIC] Block
  3400      *    | ModifiersOpt
  3401      *      ( Type Ident
  3402      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  3403      *      | VOID Ident MethodDeclaratorRest
  3404      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
  3405      *      | Ident ConstructorDeclaratorRest
  3406      *      | TypeParameters Ident ConstructorDeclaratorRest
  3407      *      | ClassOrInterfaceOrEnumDeclaration
  3408      *      )
  3409      *  InterfaceBodyDeclaration =
  3410      *      ";"
  3411      *    | ModifiersOpt Type Ident
  3412      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
  3413      */
  3414     protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  3415         if (token.kind == SEMI) {
  3416             nextToken();
  3417             return List.<JCTree>nil();
  3418         } else {
  3419             Comment dc = token.comment(CommentStyle.JAVADOC);
  3420             int pos = token.pos;
  3421             JCModifiers mods = modifiersOpt();
  3422             if (token.kind == CLASS ||
  3423                 token.kind == INTERFACE ||
  3424                 allowEnums && token.kind == ENUM) {
  3425                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  3426             } else if (token.kind == LBRACE && !isInterface &&
  3427                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  3428                        mods.annotations.isEmpty()) {
  3429                 return List.<JCTree>of(block(pos, mods.flags));
  3430             } else {
  3431                 pos = token.pos;
  3432                 List<JCTypeParameter> typarams = typeParametersOpt();
  3433                 // if there are type parameters but no modifiers, save the start
  3434                 // position of the method in the modifiers.
  3435                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
  3436                     mods.pos = pos;
  3437                     storeEnd(mods, pos);
  3439                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
  3441                 Token tk = token;
  3442                 pos = token.pos;
  3443                 JCExpression type;
  3444                 boolean isVoid = token.kind == VOID;
  3445                 if (isVoid) {
  3446                     if (annosAfterParams.nonEmpty())
  3447                         illegal(annosAfterParams.head.pos);
  3448                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
  3449                     nextToken();
  3450                 } else {
  3451                     if (annosAfterParams.nonEmpty()) {
  3452                         mods.annotations = mods.annotations.appendList(annosAfterParams);
  3453                         if (mods.pos == Position.NOPOS)
  3454                             mods.pos = mods.annotations.head.pos;
  3456                     // method returns types are un-annotated types
  3457                     type = unannotatedType();
  3459                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
  3460                     if (isInterface || tk.name() != className)
  3461                         error(pos, "invalid.meth.decl.ret.type.req");
  3462                     return List.of(methodDeclaratorRest(
  3463                         pos, mods, null, names.init, typarams,
  3464                         isInterface, true, dc));
  3465                 } else {
  3466                     pos = token.pos;
  3467                     Name name = ident();
  3468                     if (token.kind == LPAREN) {
  3469                         return List.of(methodDeclaratorRest(
  3470                             pos, mods, type, name, typarams,
  3471                             isInterface, isVoid, dc));
  3472                     } else if (!isVoid && typarams.isEmpty()) {
  3473                         List<JCTree> defs =
  3474                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  3475                                                     new ListBuffer<JCTree>()).toList();
  3476                         storeEnd(defs.last(), token.endPos);
  3477                         accept(SEMI);
  3478                         return defs;
  3479                     } else {
  3480                         pos = token.pos;
  3481                         List<JCTree> err = isVoid
  3482                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  3483                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  3484                             : null;
  3485                         return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
  3492     /** MethodDeclaratorRest =
  3493      *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  3494      *  VoidMethodDeclaratorRest =
  3495      *      FormalParameters [Throws TypeList] ( MethodBody | ";")
  3496      *  InterfaceMethodDeclaratorRest =
  3497      *      FormalParameters BracketsOpt [THROWS TypeList] ";"
  3498      *  VoidInterfaceMethodDeclaratorRest =
  3499      *      FormalParameters [THROWS TypeList] ";"
  3500      *  ConstructorDeclaratorRest =
  3501      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
  3502      */
  3503     protected JCTree methodDeclaratorRest(int pos,
  3504                               JCModifiers mods,
  3505                               JCExpression type,
  3506                               Name name,
  3507                               List<JCTypeParameter> typarams,
  3508                               boolean isInterface, boolean isVoid,
  3509                               Comment dc) {
  3510         if (isInterface && (mods.flags & Flags.STATIC) != 0) {
  3511             checkStaticInterfaceMethods();
  3513         JCVariableDecl prevReceiverParam = this.receiverParam;
  3514         try {
  3515             this.receiverParam = null;
  3516             // Parsing formalParameters sets the receiverParam, if present
  3517             List<JCVariableDecl> params = formalParameters();
  3518             if (!isVoid) type = bracketsOpt(type);
  3519             List<JCExpression> thrown = List.nil();
  3520             if (token.kind == THROWS) {
  3521                 nextToken();
  3522                 thrown = qualidentList();
  3524             JCBlock body = null;
  3525             JCExpression defaultValue;
  3526             if (token.kind == LBRACE) {
  3527                 body = block();
  3528                 defaultValue = null;
  3529             } else {
  3530                 if (token.kind == DEFAULT) {
  3531                     accept(DEFAULT);
  3532                     defaultValue = annotationValue();
  3533                 } else {
  3534                     defaultValue = null;
  3536                 accept(SEMI);
  3537                 if (token.pos <= endPosTable.errorEndPos) {
  3538                     // error recovery
  3539                     skip(false, true, false, false);
  3540                     if (token.kind == LBRACE) {
  3541                         body = block();
  3546             JCMethodDecl result =
  3547                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
  3548                                             receiverParam, params, thrown,
  3549                                             body, defaultValue));
  3550             attach(result, dc);
  3551             return result;
  3552         } finally {
  3553             this.receiverParam = prevReceiverParam;
  3557     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  3558      */
  3559     List<JCExpression> qualidentList() {
  3560         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  3562         List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  3563         JCExpression qi = qualident(true);
  3564         if (!typeAnnos.isEmpty()) {
  3565             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  3566             ts.append(at);
  3567         } else {
  3568             ts.append(qi);
  3570         while (token.kind == COMMA) {
  3571             nextToken();
  3573             typeAnnos = typeAnnotationsOpt();
  3574             qi = qualident(true);
  3575             if (!typeAnnos.isEmpty()) {
  3576                 JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  3577                 ts.append(at);
  3578             } else {
  3579                 ts.append(qi);
  3582         return ts.toList();
  3585     /**
  3586      *  {@literal
  3587      *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  3588      *  }
  3589      */
  3590     List<JCTypeParameter> typeParametersOpt() {
  3591         if (token.kind == LT) {
  3592             checkGenerics();
  3593             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  3594             nextToken();
  3595             typarams.append(typeParameter());
  3596             while (token.kind == COMMA) {
  3597                 nextToken();
  3598                 typarams.append(typeParameter());
  3600             accept(GT);
  3601             return typarams.toList();
  3602         } else {
  3603             return List.nil();
  3607     /**
  3608      *  {@literal
  3609      *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
  3610      *  TypeParameterBound = EXTENDS Type {"&" Type}
  3611      *  TypeVariable = Ident
  3612      *  }
  3613      */
  3614     JCTypeParameter typeParameter() {
  3615         int pos = token.pos;
  3616         List<JCAnnotation> annos = typeAnnotationsOpt();
  3617         Name name = ident();
  3618         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  3619         if (token.kind == EXTENDS) {
  3620             nextToken();
  3621             bounds.append(parseType());
  3622             while (token.kind == AMP) {
  3623                 nextToken();
  3624                 bounds.append(parseType());
  3627         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
  3630     /** FormalParameters = "(" [ FormalParameterList ] ")"
  3631      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  3632      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  3633      */
  3634     List<JCVariableDecl> formalParameters() {
  3635         return formalParameters(false);
  3637     List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
  3638         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  3639         JCVariableDecl lastParam;
  3640         accept(LPAREN);
  3641         if (token.kind != RPAREN) {
  3642             this.allowThisIdent = true;
  3643             lastParam = formalParameter(lambdaParameters);
  3644             if (lastParam.nameexpr != null) {
  3645                 this.receiverParam = lastParam;
  3646             } else {
  3647                 params.append(lastParam);
  3649             this.allowThisIdent = false;
  3650             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
  3651                 nextToken();
  3652                 params.append(lastParam = formalParameter(lambdaParameters));
  3655         accept(RPAREN);
  3656         return params.toList();
  3659     List<JCVariableDecl> implicitParameters(boolean hasParens) {
  3660         if (hasParens) {
  3661             accept(LPAREN);
  3663         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  3664         if (token.kind != RPAREN && token.kind != ARROW) {
  3665             params.append(implicitParameter());
  3666             while (token.kind == COMMA) {
  3667                 nextToken();
  3668                 params.append(implicitParameter());
  3671         if (hasParens) {
  3672             accept(RPAREN);
  3674         return params.toList();
  3677     JCModifiers optFinal(long flags) {
  3678         JCModifiers mods = modifiersOpt();
  3679         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  3680         mods.flags |= flags;
  3681         return mods;
  3684     /**
  3685      * Inserts the annotations (and possibly a new array level)
  3686      * to the left-most type in an array or nested type.
  3688      * When parsing a type like {@code @B Outer.Inner @A []}, the
  3689      * {@code @A} annotation should target the array itself, while
  3690      * {@code @B} targets the nested type {@code Outer}.
  3692      * Currently the parser parses the annotation first, then
  3693      * the array, and then inserts the annotation to the left-most
  3694      * nested type.
  3696      * When {@code createNewLevel} is true, then a new array
  3697      * level is inserted as the most inner type, and have the
  3698      * annotations target it.  This is useful in the case of
  3699      * varargs, e.g. {@code String @A [] @B ...}, as the parser
  3700      * first parses the type {@code String @A []} then inserts
  3701      * a new array level with {@code @B} annotation.
  3702      */
  3703     private JCExpression insertAnnotationsToMostInner(
  3704             JCExpression type, List<JCAnnotation> annos,
  3705             boolean createNewLevel) {
  3706         int origEndPos = getEndPos(type);
  3707         JCExpression mostInnerType = type;
  3708         JCArrayTypeTree mostInnerArrayType = null;
  3709         while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
  3710             mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
  3711             mostInnerType = mostInnerArrayType.elemtype;
  3714         if (createNewLevel) {
  3715             mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
  3718         JCExpression mostInnerTypeToReturn = mostInnerType;
  3719         if (annos.nonEmpty()) {
  3720             JCExpression lastToModify = mostInnerType;
  3722             while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
  3723                     TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
  3724                 while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
  3725                     lastToModify = mostInnerType;
  3726                     mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
  3728                 while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
  3729                     lastToModify = mostInnerType;
  3730                     mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
  3734             mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
  3736             if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
  3737                 ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
  3738             } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
  3739                 ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
  3740             } else {
  3741                 // We never saw a SELECT or TYPEAPPLY, return the annotated type.
  3742                 mostInnerTypeToReturn = mostInnerType;
  3746         if (mostInnerArrayType == null) {
  3747             return mostInnerTypeToReturn;
  3748         } else {
  3749             mostInnerArrayType.elemtype = mostInnerTypeToReturn;
  3750             storeEnd(type, origEndPos);
  3751             return type;
  3755     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  3756      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  3757      */
  3758     protected JCVariableDecl formalParameter() {
  3759         return formalParameter(false);
  3761     protected JCVariableDecl formalParameter(boolean lambdaParameter) {
  3762         JCModifiers mods = optFinal(Flags.PARAMETER);
  3763         // need to distinguish between vararg annos and array annos
  3764         // look at typeAnnotationsPushedBack comment
  3765         this.permitTypeAnnotationsPushBack = true;
  3766         JCExpression type = parseType();
  3767         this.permitTypeAnnotationsPushBack = false;
  3769         if (token.kind == ELLIPSIS) {
  3770             List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
  3771             typeAnnotationsPushedBack = List.nil();
  3772             checkVarargs();
  3773             mods.flags |= Flags.VARARGS;
  3774             // insert var arg type annotations
  3775             type = insertAnnotationsToMostInner(type, varargsAnnos, true);
  3776             nextToken();
  3777         } else {
  3778             // if not a var arg, then typeAnnotationsPushedBack should be null
  3779             if (typeAnnotationsPushedBack.nonEmpty()) {
  3780                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
  3781                         "illegal.start.of.type");
  3783             typeAnnotationsPushedBack = List.nil();
  3785         return variableDeclaratorId(mods, type, lambdaParameter);
  3788     protected JCVariableDecl implicitParameter() {
  3789         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
  3790         return variableDeclaratorId(mods, null, true);
  3793 /* ---------- auxiliary methods -------------- */
  3795     void error(int pos, String key, Object ... args) {
  3796         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
  3799     void error(DiagnosticPosition pos, String key, Object ... args) {
  3800         log.error(DiagnosticFlag.SYNTAX, pos, key, args);
  3803     void warning(int pos, String key, Object ... args) {
  3804         log.warning(pos, key, args);
  3807     /** Check that given tree is a legal expression statement.
  3808      */
  3809     protected JCExpression checkExprStat(JCExpression t) {
  3810         if (!TreeInfo.isExpressionStatement(t)) {
  3811             JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
  3812             error(ret, "not.stmt");
  3813             return ret;
  3814         } else {
  3815             return t;
  3819     /** Return precedence of operator represented by token,
  3820      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  3821      */
  3822     static int prec(TokenKind token) {
  3823         JCTree.Tag oc = optag(token);
  3824         return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
  3827     /**
  3828      * Return the lesser of two positions, making allowance for either one
  3829      * being unset.
  3830      */
  3831     static int earlier(int pos1, int pos2) {
  3832         if (pos1 == Position.NOPOS)
  3833             return pos2;
  3834         if (pos2 == Position.NOPOS)
  3835             return pos1;
  3836         return (pos1 < pos2 ? pos1 : pos2);
  3839     /** Return operation tag of binary operator represented by token,
  3840      *  No_TAG if token is not a binary operator.
  3841      */
  3842     static JCTree.Tag optag(TokenKind token) {
  3843         switch (token) {
  3844         case BARBAR:
  3845             return OR;
  3846         case AMPAMP:
  3847             return AND;
  3848         case BAR:
  3849             return BITOR;
  3850         case BAREQ:
  3851             return BITOR_ASG;
  3852         case CARET:
  3853             return BITXOR;
  3854         case CARETEQ:
  3855             return BITXOR_ASG;
  3856         case AMP:
  3857             return BITAND;
  3858         case AMPEQ:
  3859             return BITAND_ASG;
  3860         case EQEQ:
  3861             return JCTree.Tag.EQ;
  3862         case BANGEQ:
  3863             return NE;
  3864         case LT:
  3865             return JCTree.Tag.LT;
  3866         case GT:
  3867             return JCTree.Tag.GT;
  3868         case LTEQ:
  3869             return LE;
  3870         case GTEQ:
  3871             return GE;
  3872         case LTLT:
  3873             return SL;
  3874         case LTLTEQ:
  3875             return SL_ASG;
  3876         case GTGT:
  3877             return SR;
  3878         case GTGTEQ:
  3879             return SR_ASG;
  3880         case GTGTGT:
  3881             return USR;
  3882         case GTGTGTEQ:
  3883             return USR_ASG;
  3884         case PLUS:
  3885             return JCTree.Tag.PLUS;
  3886         case PLUSEQ:
  3887             return PLUS_ASG;
  3888         case SUB:
  3889             return MINUS;
  3890         case SUBEQ:
  3891             return MINUS_ASG;
  3892         case STAR:
  3893             return MUL;
  3894         case STAREQ:
  3895             return MUL_ASG;
  3896         case SLASH:
  3897             return DIV;
  3898         case SLASHEQ:
  3899             return DIV_ASG;
  3900         case PERCENT:
  3901             return MOD;
  3902         case PERCENTEQ:
  3903             return MOD_ASG;
  3904         case INSTANCEOF:
  3905             return TYPETEST;
  3906         default:
  3907             return NO_TAG;
  3911     /** Return operation tag of unary operator represented by token,
  3912      *  No_TAG if token is not a binary operator.
  3913      */
  3914     static JCTree.Tag unoptag(TokenKind token) {
  3915         switch (token) {
  3916         case PLUS:
  3917             return POS;
  3918         case SUB:
  3919             return NEG;
  3920         case BANG:
  3921             return NOT;
  3922         case TILDE:
  3923             return COMPL;
  3924         case PLUSPLUS:
  3925             return PREINC;
  3926         case SUBSUB:
  3927             return PREDEC;
  3928         default:
  3929             return NO_TAG;
  3933     /** Return type tag of basic type represented by token,
  3934      *  NONE if token is not a basic type identifier.
  3935      */
  3936     static TypeTag typetag(TokenKind token) {
  3937         switch (token) {
  3938         case BYTE:
  3939             return TypeTag.BYTE;
  3940         case CHAR:
  3941             return TypeTag.CHAR;
  3942         case SHORT:
  3943             return TypeTag.SHORT;
  3944         case INT:
  3945             return TypeTag.INT;
  3946         case LONG:
  3947             return TypeTag.LONG;
  3948         case FLOAT:
  3949             return TypeTag.FLOAT;
  3950         case DOUBLE:
  3951             return TypeTag.DOUBLE;
  3952         case BOOLEAN:
  3953             return TypeTag.BOOLEAN;
  3954         default:
  3955             return TypeTag.NONE;
  3959     void checkGenerics() {
  3960         if (!allowGenerics) {
  3961             error(token.pos, "generics.not.supported.in.source", source.name);
  3962             allowGenerics = true;
  3965     void checkVarargs() {
  3966         if (!allowVarargs) {
  3967             error(token.pos, "varargs.not.supported.in.source", source.name);
  3968             allowVarargs = true;
  3971     void checkForeach() {
  3972         if (!allowForeach) {
  3973             error(token.pos, "foreach.not.supported.in.source", source.name);
  3974             allowForeach = true;
  3977     void checkStaticImports() {
  3978         if (!allowStaticImport) {
  3979             error(token.pos, "static.import.not.supported.in.source", source.name);
  3980             allowStaticImport = true;
  3983     void checkAnnotations() {
  3984         if (!allowAnnotations) {
  3985             error(token.pos, "annotations.not.supported.in.source", source.name);
  3986             allowAnnotations = true;
  3989     void checkDiamond() {
  3990         if (!allowDiamond) {
  3991             error(token.pos, "diamond.not.supported.in.source", source.name);
  3992             allowDiamond = true;
  3995     void checkMulticatch() {
  3996         if (!allowMulticatch) {
  3997             error(token.pos, "multicatch.not.supported.in.source", source.name);
  3998             allowMulticatch = true;
  4001     void checkTryWithResources() {
  4002         if (!allowTWR) {
  4003             error(token.pos, "try.with.resources.not.supported.in.source", source.name);
  4004             allowTWR = true;
  4007     void checkLambda() {
  4008         if (!allowLambda) {
  4009             log.error(token.pos, "lambda.not.supported.in.source", source.name);
  4010             allowLambda = true;
  4013     void checkMethodReferences() {
  4014         if (!allowMethodReferences) {
  4015             log.error(token.pos, "method.references.not.supported.in.source", source.name);
  4016             allowMethodReferences = true;
  4019     void checkDefaultMethods() {
  4020         if (!allowDefaultMethods) {
  4021             log.error(token.pos, "default.methods.not.supported.in.source", source.name);
  4022             allowDefaultMethods = true;
  4025     void checkIntersectionTypesInCast() {
  4026         if (!allowIntersectionTypesInCast) {
  4027             log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
  4028             allowIntersectionTypesInCast = true;
  4031     void checkStaticInterfaceMethods() {
  4032         if (!allowStaticInterfaceMethods) {
  4033             log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
  4034             allowStaticInterfaceMethods = true;
  4037     void checkTypeAnnotations() {
  4038         if (!allowTypeAnnotations) {
  4039             log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
  4040             allowTypeAnnotations = true;
  4044     /*
  4045      * a functional source tree and end position mappings
  4046      */
  4047     protected static class SimpleEndPosTable extends AbstractEndPosTable {
  4049         private final Map<JCTree, Integer> endPosMap;
  4051         SimpleEndPosTable(JavacParser parser) {
  4052             super(parser);
  4053             endPosMap = new HashMap<JCTree, Integer>();
  4056         public void storeEnd(JCTree tree, int endpos) {
  4057             endPosMap.put(tree, errorEndPos > endpos ? errorEndPos : endpos);
  4060         protected <T extends JCTree> T to(T t) {
  4061             storeEnd(t, parser.token.endPos);
  4062             return t;
  4065         protected <T extends JCTree> T toP(T t) {
  4066             storeEnd(t, parser.S.prevToken().endPos);
  4067             return t;
  4070         public int getEndPos(JCTree tree) {
  4071             Integer value = endPosMap.get(tree);
  4072             return (value == null) ? Position.NOPOS : value;
  4075         public int replaceTree(JCTree oldTree, JCTree newTree) {
  4076             Integer pos = endPosMap.remove(oldTree);
  4077             if (pos != null) {
  4078                 endPosMap.put(newTree, pos);
  4079                 return pos;
  4081             return Position.NOPOS;
  4085     /*
  4086      * a default skeletal implementation without any mapping overhead.
  4087      */
  4088     protected static class EmptyEndPosTable extends AbstractEndPosTable {
  4090         EmptyEndPosTable(JavacParser parser) {
  4091             super(parser);
  4094         public void storeEnd(JCTree tree, int endpos) { /* empty */ }
  4096         protected <T extends JCTree> T to(T t) {
  4097             return t;
  4100         protected <T extends JCTree> T toP(T t) {
  4101             return t;
  4104         public int getEndPos(JCTree tree) {
  4105             return Position.NOPOS;
  4108         public int replaceTree(JCTree oldTree, JCTree newTree) {
  4109             return Position.NOPOS;
  4114     protected static abstract class AbstractEndPosTable implements EndPosTable {
  4115         /**
  4116          * The current parser.
  4117          */
  4118         protected JavacParser parser;
  4120         /**
  4121          * Store the last error position.
  4122          */
  4123         protected int errorEndPos;
  4125         public AbstractEndPosTable(JavacParser parser) {
  4126             this.parser = parser;
  4129         /**
  4130          * Store current token's ending position for a tree, the value of which
  4131          * will be the greater of last error position and the ending position of
  4132          * the current token.
  4133          * @param t The tree.
  4134          */
  4135         protected abstract <T extends JCTree> T to(T t);
  4137         /**
  4138          * Store current token's ending position for a tree, the value of which
  4139          * will be the greater of last error position and the ending position of
  4140          * the previous token.
  4141          * @param t The tree.
  4142          */
  4143         protected abstract <T extends JCTree> T toP(T t);
  4145         /**
  4146          * Set the error position during the parsing phases, the value of which
  4147          * will be set only if it is greater than the last stored error position.
  4148          * @param errPos The error position
  4149          */
  4150         protected void setErrorEndPos(int errPos) {
  4151             if (errPos > errorEndPos) {
  4152                 errorEndPos = errPos;
  4156         protected void setParser(JavacParser parser) {
  4157             this.parser = parser;

mercurial