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

Fri, 26 Jun 2009 18:51:39 -0700

author
jjg
date
Fri, 26 Jun 2009 18:51:39 -0700
changeset 308
03944ee4fac4
parent 267
e2722bd43f3a
child 310
7c154fdc3547
permissions
-rw-r--r--

6843077: JSR 308: Annotations on types
Reviewed-by: jjg, mcimadamore, darcy
Contributed-by: mernst@cs.washington.edu, mali@csail.mit.edu, mpapi@csail.mit.edu

     1 /*
     2  * Copyright 1999-2009 Sun Microsystems, Inc.  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.  Sun designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    22  * CA 95054 USA or visit www.sun.com if you need additional information or
    23  * have any questions.
    24  */
    26 package com.sun.tools.javac.parser;
    28 import java.util.*;
    30 import com.sun.tools.javac.tree.*;
    31 import com.sun.tools.javac.code.*;
    32 import com.sun.tools.javac.util.*;
    33 import com.sun.tools.javac.util.List;
    34 import static com.sun.tools.javac.util.ListBuffer.lb;
    36 import com.sun.tools.javac.tree.JCTree.*;
    38 import static com.sun.tools.javac.parser.Token.*;
    40 /** The parser maps a token sequence into an abstract syntax
    41  *  tree. It operates by recursive descent, with code derived
    42  *  systematically from an LL(1) grammar. For efficiency reasons, an
    43  *  operator precedence scheme is used for parsing binary operation
    44  *  expressions.
    45  *
    46  *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    47  *  you write code that depends on this, you do so at your own risk.
    48  *  This code and its internal interfaces are subject to change or
    49  *  deletion without notice.</b>
    50  */
    51 public class JavacParser implements Parser {
    53     /** The number of precedence levels of infix operators.
    54      */
    55     private static final int infixPrecedenceLevels = 10;
    57     /** The scanner used for lexical analysis.
    58      */
    59     private Lexer S;
    61     /** The factory to be used for abstract syntax tree construction.
    62      */
    63     protected TreeMaker F;
    65     /** The log to be used for error diagnostics.
    66      */
    67     private Log log;
    69     /** The keyword table. */
    70     private Keywords keywords;
    72     /** The Source language setting. */
    73     private Source source;
    75     /** The name table. */
    76     private Names names;
    78     // Because of javac's limited lookahead, some contexts are ambiguous in
    79     // the presence of type annotations even though they are not ambiguous
    80     // in the absence of type annotations.  Consider this code:
    81     //   void m(String [] m) { }
    82     //   void m(String ... m) { }
    83     // After parsing "String", javac calls bracketsOpt which immediately
    84     // returns if the next character is not '['.  Similarly, javac can see
    85     // if the next token is ... and in that case parse an ellipsis.  But in
    86     // the presence of type annotations:
    87     //   void m(String @A [] m) { }
    88     //   void m(String @A ... m) { }
    89     // no finite lookahead is enough to determine whether to read array
    90     // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
    91     // bracketsOpt first reads all the leading annotations and only then
    92     // discovers that it needs to fail.  bracketsOpt needs a way to push
    93     // back the extra annotations that it read.  (But, bracketsOpt should
    94     // not *always* be allowed to push back extra annotations that it finds
    95     // -- in most contexts, any such extra annotation is an error.
    96     // Another similar case occurs with arrays and receiver annotations:
    97     //   String b() @Array [] @Receiver { }
    98     //   String b() @Receiver { }
    99     //
   100     // The following two variables permit type annotations that have
   101     // already been read to be stored for later use.  Alternate
   102     // implementations are possible but would cause much larger changes to
   103     // the parser.
   104     /** Type annotations that have already been read but have not yet been used. **/
   105     private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
   106     /**
   107      * If the parser notices extra annotations, then it either immediately
   108      * issues an error (if this variable is false) or places the extra
   109      * annotations in variable typeAnnotationsPushedBack (if this variable
   110      * is true).
   111      */
   112     private boolean permitTypeAnnotationsPushBack = false;
   114     /** Construct a parser from a given scanner, tree factory and log.
   115      */
   116     protected JavacParser(ParserFactory fac,
   117                      Lexer S,
   118                      boolean keepDocComments,
   119                      boolean keepLineMap) {
   120         this.S = S;
   121         S.nextToken(); // prime the pump
   122         this.F = fac.F;
   123         this.log = fac.log;
   124         this.names = fac.names;
   125         this.keywords = fac.keywords;
   126         this.source = fac.source;
   127         this.allowGenerics = source.allowGenerics();
   128         this.allowVarargs = source.allowVarargs();
   129         this.allowAsserts = source.allowAsserts();
   130         this.allowEnums = source.allowEnums();
   131         this.allowForeach = source.allowForeach();
   132         this.allowStaticImport = source.allowStaticImport();
   133         this.allowAnnotations = source.allowAnnotations();
   134         this.allowTypeAnnotations = source.allowTypeAnnotations();
   135         this.keepDocComments = keepDocComments;
   136         if (keepDocComments)
   137             docComments = new HashMap<JCTree,String>();
   138         this.keepLineMap = keepLineMap;
   139         this.errorTree = F.Erroneous();
   140         this.debugJSR308 = fac.options.get("TA:parser") != null;
   141     }
   143     /** Switch: debug output for type-annotations operations
   144      */
   145     boolean debugJSR308;
   147     /** Switch: Should generics be recognized?
   148      */
   149     boolean allowGenerics;
   151     /** Switch: Should varargs be recognized?
   152      */
   153     boolean allowVarargs;
   155     /** Switch: should we recognize assert statements, or just give a warning?
   156      */
   157     boolean allowAsserts;
   159     /** Switch: should we recognize enums, or just give a warning?
   160      */
   161     boolean allowEnums;
   163     /** Switch: should we recognize foreach?
   164      */
   165     boolean allowForeach;
   167     /** Switch: should we recognize foreach?
   168      */
   169     boolean allowStaticImport;
   171     /** Switch: should we recognize annotations?
   172      */
   173     boolean allowAnnotations;
   175     /** Switch: should we recognize type annotations?
   176      */
   177     boolean allowTypeAnnotations;
   179     /** Switch: should we keep docComments?
   180      */
   181     boolean keepDocComments;
   183     /** Switch: should we keep line table?
   184      */
   185     boolean keepLineMap;
   187     /** When terms are parsed, the mode determines which is expected:
   188      *     mode = EXPR        : an expression
   189      *     mode = TYPE        : a type
   190      *     mode = NOPARAMS    : no parameters allowed for type
   191      *     mode = TYPEARG     : type argument
   192      */
   193     static final int EXPR = 1;
   194     static final int TYPE = 2;
   195     static final int NOPARAMS = 4;
   196     static final int TYPEARG = 8;
   198     /** The current mode.
   199      */
   200     private int mode = 0;
   202     /** The mode of the term that was parsed last.
   203      */
   204     private int lastmode = 0;
   206 /* ---------- error recovery -------------- */
   208     private JCErroneous errorTree;
   210     /** Skip forward until a suitable stop token is found.
   211      */
   212     private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   213          while (true) {
   214              switch (S.token()) {
   215                 case SEMI:
   216                     S.nextToken();
   217                     return;
   218                 case PUBLIC:
   219                 case FINAL:
   220                 case ABSTRACT:
   221                 case MONKEYS_AT:
   222                 case EOF:
   223                 case CLASS:
   224                 case INTERFACE:
   225                 case ENUM:
   226                     return;
   227                 case IMPORT:
   228                     if (stopAtImport)
   229                         return;
   230                     break;
   231                 case LBRACE:
   232                 case RBRACE:
   233                 case PRIVATE:
   234                 case PROTECTED:
   235                 case STATIC:
   236                 case TRANSIENT:
   237                 case NATIVE:
   238                 case VOLATILE:
   239                 case SYNCHRONIZED:
   240                 case STRICTFP:
   241                 case LT:
   242                 case BYTE:
   243                 case SHORT:
   244                 case CHAR:
   245                 case INT:
   246                 case LONG:
   247                 case FLOAT:
   248                 case DOUBLE:
   249                 case BOOLEAN:
   250                 case VOID:
   251                     if (stopAtMemberDecl)
   252                         return;
   253                     break;
   254                 case IDENTIFIER:
   255                    if (stopAtIdentifier)
   256                         return;
   257                     break;
   258                 case CASE:
   259                 case DEFAULT:
   260                 case IF:
   261                 case FOR:
   262                 case WHILE:
   263                 case DO:
   264                 case TRY:
   265                 case SWITCH:
   266                 case RETURN:
   267                 case THROW:
   268                 case BREAK:
   269                 case CONTINUE:
   270                 case ELSE:
   271                 case FINALLY:
   272                 case CATCH:
   273                     if (stopAtStatement)
   274                         return;
   275                     break;
   276             }
   277             S.nextToken();
   278         }
   279     }
   281     private JCErroneous syntaxError(int pos, String key, Token... args) {
   282         return syntaxError(pos, null, key, args);
   283     }
   285     private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
   286         setErrorEndPos(pos);
   287         reportSyntaxError(pos, key, (Object[])args);
   288         return toP(F.at(pos).Erroneous(errs));
   289     }
   291     private int errorPos = Position.NOPOS;
   292     /**
   293      * Report a syntax error at given position using the given
   294      * argument unless one was already reported at the same position.
   295      */
   296     private void reportSyntaxError(int pos, String key, Object... args) {
   297         if (pos > S.errPos() || pos == Position.NOPOS) {
   298             if (S.token() == EOF)
   299                 log.error(pos, "premature.eof");
   300             else
   301                 log.error(pos, key, args);
   302         }
   303         S.errPos(pos);
   304         if (S.pos() == errorPos)
   305             S.nextToken(); // guarantee progress
   306         errorPos = S.pos();
   307     }
   310     /** Generate a syntax error at current position unless one was already
   311      *  reported at the same position.
   312      */
   313     private JCErroneous syntaxError(String key) {
   314         return syntaxError(S.pos(), key);
   315     }
   317     /** Generate a syntax error at current position unless one was
   318      *  already reported at the same position.
   319      */
   320     private JCErroneous syntaxError(String key, Token arg) {
   321         return syntaxError(S.pos(), key, arg);
   322     }
   324     /** If next input token matches given token, skip it, otherwise report
   325      *  an error.
   326      */
   327     public void accept(Token token) {
   328         if (S.token() == token) {
   329             S.nextToken();
   330         } else {
   331             setErrorEndPos(S.pos());
   332             reportSyntaxError(S.prevEndPos(), "expected", token);
   333         }
   334     }
   336     /** Report an illegal start of expression/type error at given position.
   337      */
   338     JCExpression illegal(int pos) {
   339         setErrorEndPos(S.pos());
   340         if ((mode & EXPR) != 0)
   341             return syntaxError(pos, "illegal.start.of.expr");
   342         else
   343             return syntaxError(pos, "illegal.start.of.type");
   345     }
   347     /** Report an illegal start of expression/type error at current position.
   348      */
   349     JCExpression illegal() {
   350         return illegal(S.pos());
   351     }
   353     /** Diagnose a modifier flag from the set, if any. */
   354     void checkNoMods(long mods) {
   355         if (mods != 0) {
   356             long lowestMod = mods & -mods;
   357             log.error(S.pos(), "mod.not.allowed.here",
   358                       Flags.asFlagSet(lowestMod));
   359         }
   360     }
   362 /* ---------- doc comments --------- */
   364     /** A hashtable to store all documentation comments
   365      *  indexed by the tree nodes they refer to.
   366      *  defined only if option flag keepDocComment is set.
   367      */
   368     Map<JCTree, String> docComments;
   370     /** Make an entry into docComments hashtable,
   371      *  provided flag keepDocComments is set and given doc comment is non-null.
   372      *  @param tree   The tree to be used as index in the hashtable
   373      *  @param dc     The doc comment to associate with the tree, or null.
   374      */
   375     void attach(JCTree tree, String dc) {
   376         if (keepDocComments && dc != null) {
   377 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   378             docComments.put(tree, dc);
   379         }
   380     }
   382 /* -------- source positions ------- */
   384     private int errorEndPos = -1;
   386     private void setErrorEndPos(int errPos) {
   387         if (errPos > errorEndPos)
   388             errorEndPos = errPos;
   389     }
   391     protected int getErrorEndPos() {
   392         return errorEndPos;
   393     }
   395     /**
   396      * Store ending position for a tree.
   397      * @param tree   The tree.
   398      * @param endpos The ending position to associate with the tree.
   399      */
   400     protected void storeEnd(JCTree tree, int endpos) {}
   402     /**
   403      * Store ending position for a tree.  The ending position should
   404      * be the ending position of the current token.
   405      * @param t The tree.
   406      */
   407     protected <T extends JCTree> T to(T t) { return t; }
   409     /**
   410      * Store ending position for a tree.  The ending position should
   411      * be greater of the ending position of the previous token and errorEndPos.
   412      * @param t The tree.
   413      */
   414     protected <T extends JCTree> T toP(T t) { return t; }
   416     /** Get the start position for a tree node.  The start position is
   417      * defined to be the position of the first character of the first
   418      * token of the node's source text.
   419      * @param tree  The tree node
   420      */
   421     public int getStartPos(JCTree tree) {
   422         return TreeInfo.getStartPos(tree);
   423     }
   425     /**
   426      * Get the end position for a tree node.  The end position is
   427      * defined to be the position of the last character of the last
   428      * token of the node's source text.  Returns Position.NOPOS if end
   429      * positions are not generated or the position is otherwise not
   430      * found.
   431      * @param tree  The tree node
   432      */
   433     public int getEndPos(JCTree tree) {
   434         return Position.NOPOS;
   435     }
   439 /* ---------- parsing -------------- */
   441     /**
   442      * Ident = IDENTIFIER
   443      */
   444     Name ident() {
   445         if (S.token() == IDENTIFIER) {
   446             Name name = S.name();
   447             S.nextToken();
   448             return name;
   449         } else if (S.token() == ASSERT) {
   450             if (allowAsserts) {
   451                 log.error(S.pos(), "assert.as.identifier");
   452                 S.nextToken();
   453                 return names.error;
   454             } else {
   455                 log.warning(S.pos(), "assert.as.identifier");
   456                 Name name = S.name();
   457                 S.nextToken();
   458                 return name;
   459             }
   460         } else if (S.token() == ENUM) {
   461             if (allowEnums) {
   462                 log.error(S.pos(), "enum.as.identifier");
   463                 S.nextToken();
   464                 return names.error;
   465             } else {
   466                 log.warning(S.pos(), "enum.as.identifier");
   467                 Name name = S.name();
   468                 S.nextToken();
   469                 return name;
   470             }
   471         } else {
   472             accept(IDENTIFIER);
   473             return names.error;
   474         }
   475 }
   477     /**
   478      * Qualident = Ident { DOT Ident }
   479      */
   480     public JCExpression qualident() {
   481         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
   482         while (S.token() == DOT) {
   483             int pos = S.pos();
   484             S.nextToken();
   485             t = toP(F.at(pos).Select(t, ident()));
   486         }
   487         return t;
   488     }
   490     /**
   491      * Literal =
   492      *     INTLITERAL
   493      *   | LONGLITERAL
   494      *   | FLOATLITERAL
   495      *   | DOUBLELITERAL
   496      *   | CHARLITERAL
   497      *   | STRINGLITERAL
   498      *   | TRUE
   499      *   | FALSE
   500      *   | NULL
   501      */
   502     JCExpression literal(Name prefix) {
   503         int pos = S.pos();
   504         JCExpression t = errorTree;
   505         switch (S.token()) {
   506         case INTLITERAL:
   507             try {
   508                 t = F.at(pos).Literal(
   509                     TypeTags.INT,
   510                     Convert.string2int(strval(prefix), S.radix()));
   511             } catch (NumberFormatException ex) {
   512                 log.error(S.pos(), "int.number.too.large", strval(prefix));
   513             }
   514             break;
   515         case LONGLITERAL:
   516             try {
   517                 t = F.at(pos).Literal(
   518                     TypeTags.LONG,
   519                     new Long(Convert.string2long(strval(prefix), S.radix())));
   520             } catch (NumberFormatException ex) {
   521                 log.error(S.pos(), "int.number.too.large", strval(prefix));
   522             }
   523             break;
   524         case FLOATLITERAL: {
   525             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   526             Float n;
   527             try {
   528                 n = Float.valueOf(proper);
   529             } catch (NumberFormatException ex) {
   530                 // error already repoted in scanner
   531                 n = Float.NaN;
   532             }
   533             if (n.floatValue() == 0.0f && !isZero(proper))
   534                 log.error(S.pos(), "fp.number.too.small");
   535             else if (n.floatValue() == Float.POSITIVE_INFINITY)
   536                 log.error(S.pos(), "fp.number.too.large");
   537             else
   538                 t = F.at(pos).Literal(TypeTags.FLOAT, n);
   539             break;
   540         }
   541         case DOUBLELITERAL: {
   542             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   543             Double n;
   544             try {
   545                 n = Double.valueOf(proper);
   546             } catch (NumberFormatException ex) {
   547                 // error already reported in scanner
   548                 n = Double.NaN;
   549             }
   550             if (n.doubleValue() == 0.0d && !isZero(proper))
   551                 log.error(S.pos(), "fp.number.too.small");
   552             else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   553                 log.error(S.pos(), "fp.number.too.large");
   554             else
   555                 t = F.at(pos).Literal(TypeTags.DOUBLE, n);
   556             break;
   557         }
   558         case CHARLITERAL:
   559             t = F.at(pos).Literal(
   560                 TypeTags.CHAR,
   561                 S.stringVal().charAt(0) + 0);
   562             break;
   563         case STRINGLITERAL:
   564             t = F.at(pos).Literal(
   565                 TypeTags.CLASS,
   566                 S.stringVal());
   567             break;
   568         case TRUE: case FALSE:
   569             t = F.at(pos).Literal(
   570                 TypeTags.BOOLEAN,
   571                 (S.token() == TRUE ? 1 : 0));
   572             break;
   573         case NULL:
   574             t = F.at(pos).Literal(
   575                 TypeTags.BOT,
   576                 null);
   577             break;
   578         default:
   579             assert false;
   580         }
   581         if (t == errorTree)
   582             t = F.at(pos).Erroneous();
   583         storeEnd(t, S.endPos());
   584         S.nextToken();
   585         return t;
   586     }
   587 //where
   588         boolean isZero(String s) {
   589             char[] cs = s.toCharArray();
   590             int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10);
   591             int i = ((base==16) ? 2 : 0);
   592             while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   593             return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   594         }
   596         String strval(Name prefix) {
   597             String s = S.stringVal();
   598             return prefix.isEmpty() ? s : prefix + s;
   599         }
   601     /** terms can be either expressions or types.
   602      */
   603     public JCExpression parseExpression() {
   604         return term(EXPR);
   605     }
   607     /**
   608      * parses (optional) type annotations followed by a type. If the
   609      * annotations are present before the type and are not consumed during array
   610      * parsing, this method returns a {@link JCAnnotatedType} consisting of
   611      * these annotations and the underlying type. Otherwise, it returns the
   612      * underlying type.
   613      *
   614      * <p>
   615      *
   616      * Note that this method sets {@code mode} to {@code TYPE} first, before
   617      * parsing annotations.
   618      */
   619     public JCExpression parseType() {
   620         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
   621         return parseType(annotations);
   622     }
   624     public JCExpression parseType(List<JCTypeAnnotation> annotations) {
   625         JCExpression result = unannotatedType();
   627         if (!annotations.isEmpty())
   628             result = F.AnnotatedType(annotations, result);
   630         return result;
   631     }
   633     public JCExpression unannotatedType() {
   634         return term(TYPE);
   635     }
   637     JCExpression term(int newmode) {
   638         int prevmode = mode;
   639         mode = newmode;
   640         JCExpression t = term();
   641         lastmode = mode;
   642         mode = prevmode;
   643         return t;
   644     }
   646     /**
   647      *  Expression = Expression1 [ExpressionRest]
   648      *  ExpressionRest = [AssignmentOperator Expression1]
   649      *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   650      *                       "&=" | "|=" | "^=" |
   651      *                       "%=" | "<<=" | ">>=" | ">>>="
   652      *  Type = Type1
   653      *  TypeNoParams = TypeNoParams1
   654      *  StatementExpression = Expression
   655      *  ConstantExpression = Expression
   656      */
   657     JCExpression term() {
   658         JCExpression t = term1();
   659         if ((mode & EXPR) != 0 &&
   660             S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
   661             return termRest(t);
   662         else
   663             return t;
   664     }
   666     JCExpression termRest(JCExpression t) {
   667         switch (S.token()) {
   668         case EQ: {
   669             int pos = S.pos();
   670             S.nextToken();
   671             mode = EXPR;
   672             JCExpression t1 = term();
   673             return toP(F.at(pos).Assign(t, t1));
   674         }
   675         case PLUSEQ:
   676         case SUBEQ:
   677         case STAREQ:
   678         case SLASHEQ:
   679         case PERCENTEQ:
   680         case AMPEQ:
   681         case BAREQ:
   682         case CARETEQ:
   683         case LTLTEQ:
   684         case GTGTEQ:
   685         case GTGTGTEQ:
   686             int pos = S.pos();
   687             Token token = S.token();
   688             S.nextToken();
   689             mode = EXPR;
   690             JCExpression t1 = term();
   691             return F.at(pos).Assignop(optag(token), t, t1);
   692         default:
   693             return t;
   694         }
   695     }
   697     /** Expression1   = Expression2 [Expression1Rest]
   698      *  Type1         = Type2
   699      *  TypeNoParams1 = TypeNoParams2
   700      */
   701     JCExpression term1() {
   702         JCExpression t = term2();
   703         if ((mode & EXPR) != 0 && S.token() == QUES) {
   704             mode = EXPR;
   705             return term1Rest(t);
   706         } else {
   707             return t;
   708         }
   709     }
   711     /** Expression1Rest = ["?" Expression ":" Expression1]
   712      */
   713     JCExpression term1Rest(JCExpression t) {
   714         if (S.token() == QUES) {
   715             int pos = S.pos();
   716             S.nextToken();
   717             JCExpression t1 = term();
   718             accept(COLON);
   719             JCExpression t2 = term1();
   720             return F.at(pos).Conditional(t, t1, t2);
   721         } else {
   722             return t;
   723         }
   724     }
   726     /** Expression2   = Expression3 [Expression2Rest]
   727      *  Type2         = Type3
   728      *  TypeNoParams2 = TypeNoParams3
   729      */
   730     JCExpression term2() {
   731         JCExpression t = term3();
   732         if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
   733             mode = EXPR;
   734             return term2Rest(t, TreeInfo.orPrec);
   735         } else {
   736             return t;
   737         }
   738     }
   740     /*  Expression2Rest = {infixop Expression3}
   741      *                  | Expression3 instanceof Type
   742      *  infixop         = "||"
   743      *                  | "&&"
   744      *                  | "|"
   745      *                  | "^"
   746      *                  | "&"
   747      *                  | "==" | "!="
   748      *                  | "<" | ">" | "<=" | ">="
   749      *                  | "<<" | ">>" | ">>>"
   750      *                  | "+" | "-"
   751      *                  | "*" | "/" | "%"
   752      */
   753     JCExpression term2Rest(JCExpression t, int minprec) {
   754         List<JCExpression[]> savedOd = odStackSupply.elems;
   755         JCExpression[] odStack = newOdStack();
   756         List<Token[]> savedOp = opStackSupply.elems;
   757         Token[] opStack = newOpStack();
   758         // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   759         int top = 0;
   760         odStack[0] = t;
   761         int startPos = S.pos();
   762         Token topOp = ERROR;
   763         while (prec(S.token()) >= minprec) {
   764             opStack[top] = topOp;
   765             top++;
   766             topOp = S.token();
   767             int pos = S.pos();
   768             S.nextToken();
   769             odStack[top] = topOp == INSTANCEOF ? parseType() : term3();
   770             while (top > 0 && prec(topOp) >= prec(S.token())) {
   771                 odStack[top-1] = makeOp(pos, topOp, odStack[top-1],
   772                                         odStack[top]);
   773                 top--;
   774                 topOp = opStack[top];
   775             }
   776         }
   777         assert top == 0;
   778         t = odStack[0];
   780         if (t.getTag() == JCTree.PLUS) {
   781             StringBuffer buf = foldStrings(t);
   782             if (buf != null) {
   783                 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
   784             }
   785         }
   787         odStackSupply.elems = savedOd; // optimization
   788         opStackSupply.elems = savedOp; // optimization
   789         return t;
   790     }
   791 //where
   792         /** Construct a binary or type test node.
   793          */
   794         private JCExpression makeOp(int pos,
   795                                     Token topOp,
   796                                     JCExpression od1,
   797                                     JCExpression od2)
   798         {
   799             if (topOp == INSTANCEOF) {
   800                 return F.at(pos).TypeTest(od1, od2);
   801             } else {
   802                 return F.at(pos).Binary(optag(topOp), od1, od2);
   803             }
   804         }
   805         /** If tree is a concatenation of string literals, replace it
   806          *  by a single literal representing the concatenated string.
   807          */
   808         protected StringBuffer foldStrings(JCTree tree) {
   809             List<String> buf = List.nil();
   810             while (true) {
   811                 if (tree.getTag() == JCTree.LITERAL) {
   812                     JCLiteral lit = (JCLiteral) tree;
   813                     if (lit.typetag == TypeTags.CLASS) {
   814                         StringBuffer sbuf =
   815                             new StringBuffer((String)lit.value);
   816                         while (buf.nonEmpty()) {
   817                             sbuf.append(buf.head);
   818                             buf = buf.tail;
   819                         }
   820                         return sbuf;
   821                     }
   822                 } else if (tree.getTag() == JCTree.PLUS) {
   823                     JCBinary op = (JCBinary)tree;
   824                     if (op.rhs.getTag() == JCTree.LITERAL) {
   825                         JCLiteral lit = (JCLiteral) op.rhs;
   826                         if (lit.typetag == TypeTags.CLASS) {
   827                             buf = buf.prepend((String) lit.value);
   828                             tree = op.lhs;
   829                             continue;
   830                         }
   831                     }
   832                 }
   833                 return null;
   834             }
   835         }
   837         /** optimization: To save allocating a new operand/operator stack
   838          *  for every binary operation, we use supplys.
   839          */
   840         ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
   841         ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
   843         private JCExpression[] newOdStack() {
   844             if (odStackSupply.elems == odStackSupply.last)
   845                 odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
   846             JCExpression[] odStack = odStackSupply.elems.head;
   847             odStackSupply.elems = odStackSupply.elems.tail;
   848             return odStack;
   849         }
   851         private Token[] newOpStack() {
   852             if (opStackSupply.elems == opStackSupply.last)
   853                 opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
   854             Token[] opStack = opStackSupply.elems.head;
   855             opStackSupply.elems = opStackSupply.elems.tail;
   856             return opStack;
   857         }
   859     /** Expression3    = PrefixOp Expression3
   860      *                 | "(" Expr | TypeNoParams ")" Expression3
   861      *                 | Primary {Selector} {PostfixOp}
   862      *  Primary        = "(" Expression ")"
   863      *                 | Literal
   864      *                 | [TypeArguments] THIS [Arguments]
   865      *                 | [TypeArguments] SUPER SuperSuffix
   866      *                 | NEW [TypeArguments] Creator
   867      *                 | [Annotations] Ident { "." Ident }
   868      *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   869      *                   | Arguments
   870      *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
   871      *                   ]
   872      *                 | BasicType BracketsOpt "." CLASS
   873      *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
   874      *  PostfixOp      = "++" | "--"
   875      *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
   876      *                 | BasicType
   877      *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
   878      *  Selector       = "." [TypeArguments] Ident [Arguments]
   879      *                 | "." THIS
   880      *                 | "." [TypeArguments] SUPER SuperSuffix
   881      *                 | "." NEW [TypeArguments] InnerCreator
   882      *                 | "[" Expression "]"
   883      *  TypeSelector   = "." Ident [TypeArguments]
   884      *  SuperSuffix    = Arguments | "." Ident [Arguments]
   885      */
   886     protected JCExpression term3() {
   887         int pos = S.pos();
   888         JCExpression t;
   889         List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
   890         switch (S.token()) {
   891         case QUES:
   892             if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
   893                 mode = TYPE;
   894                 return typeArgument();
   895             } else
   896                 return illegal();
   897         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
   898             if (typeArgs == null && (mode & EXPR) != 0) {
   899                 Token token = S.token();
   900                 S.nextToken();
   901                 mode = EXPR;
   902                 if (token == SUB &&
   903                     (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
   904                     S.radix() == 10) {
   905                     mode = EXPR;
   906                     t = literal(names.hyphen);
   907                 } else {
   908                     t = term3();
   909                     return F.at(pos).Unary(unoptag(token), t);
   910                 }
   911             } else return illegal();
   912             break;
   913         case LPAREN:
   914             if (typeArgs == null && (mode & EXPR) != 0) {
   915                 S.nextToken();
   916                 mode = EXPR | TYPE | NOPARAMS;
   917                 t = term3();
   918                 if ((mode & TYPE) != 0 && S.token() == LT) {
   919                     // Could be a cast to a parameterized type
   920                     int op = JCTree.LT;
   921                     int pos1 = S.pos();
   922                     S.nextToken();
   923                     mode &= (EXPR | TYPE);
   924                     mode |= TYPEARG;
   925                     JCExpression t1 = term3();
   926                     if ((mode & TYPE) != 0 &&
   927                         (S.token() == COMMA || S.token() == GT)) {
   928                         mode = TYPE;
   929                         ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
   930                         args.append(t1);
   931                         while (S.token() == COMMA) {
   932                             S.nextToken();
   933                             args.append(typeArgument());
   934                         }
   935                         accept(GT);
   936                         t = F.at(pos1).TypeApply(t, args.toList());
   937                         checkGenerics();
   938                         while (S.token() == DOT) {
   939                             S.nextToken();
   940                             mode = TYPE;
   941                             t = toP(F.at(S.pos()).Select(t, ident()));
   942                             t = typeArgumentsOpt(t);
   943                         }
   944                         t = bracketsOpt(toP(t));
   945                     } else if ((mode & EXPR) != 0) {
   946                         mode = EXPR;
   947                         t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec));
   948                         t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   949                     } else {
   950                         accept(GT);
   951                     }
   952                 }
   953                 else {
   954                     t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   955                 }
   956                 accept(RPAREN);
   957                 lastmode = mode;
   958                 mode = EXPR;
   959                 if ((lastmode & EXPR) == 0) {
   960                     JCExpression t1 = term3();
   961                     return F.at(pos).TypeCast(t, t1);
   962                 } else if ((lastmode & TYPE) != 0) {
   963                     switch (S.token()) {
   964                     /*case PLUSPLUS: case SUBSUB: */
   965                     case BANG: case TILDE:
   966                     case LPAREN: case THIS: case SUPER:
   967                     case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
   968                     case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
   969                     case TRUE: case FALSE: case NULL:
   970                     case NEW: case IDENTIFIER: case ASSERT: case ENUM:
   971                     case BYTE: case SHORT: case CHAR: case INT:
   972                     case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
   973                         JCExpression t1 = term3();
   974                         return F.at(pos).TypeCast(t, t1);
   975                     }
   976                 }
   977             } else return illegal();
   978             t = toP(F.at(pos).Parens(t));
   979             break;
   980         case THIS:
   981             if ((mode & EXPR) != 0) {
   982                 mode = EXPR;
   983                 t = to(F.at(pos).Ident(names._this));
   984                 S.nextToken();
   985                 if (typeArgs == null)
   986                     t = argumentsOpt(null, t);
   987                 else
   988                     t = arguments(typeArgs, t);
   989                 typeArgs = null;
   990             } else return illegal();
   991             break;
   992         case SUPER:
   993             if ((mode & EXPR) != 0) {
   994                 mode = EXPR;
   995                 t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super)));
   996                 typeArgs = null;
   997             } else return illegal();
   998             break;
   999         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
  1000         case CHARLITERAL: case STRINGLITERAL:
  1001         case TRUE: case FALSE: case NULL:
  1002             if (typeArgs == null && (mode & EXPR) != 0) {
  1003                 mode = EXPR;
  1004                 t = literal(names.empty);
  1005             } else return illegal();
  1006             break;
  1007         case NEW:
  1008             if (typeArgs != null) return illegal();
  1009             if ((mode & EXPR) != 0) {
  1010                 mode = EXPR;
  1011                 S.nextToken();
  1012                 if (S.token() == LT) typeArgs = typeArguments();
  1013                 t = creator(pos, typeArgs);
  1014                 typeArgs = null;
  1015             } else return illegal();
  1016             break;
  1017         case MONKEYS_AT:
  1019             // only annotated targetting class literals or cast types are valid
  1020             List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
  1021             if (typeAnnos.isEmpty()) {
  1022                 // else there would be no '@'
  1023                 throw new AssertionError("type annos is empty");
  1026             JCExpression expr = term3();
  1028             // Type annotations: If term3 just parsed a non-type, expect a
  1029             // class literal (and issue a syntax error if there is no class
  1030             // literal). Otherwise, create a JCAnnotatedType.
  1031             if ((mode & TYPE) == 0) {
  1032                 if (expr.getTag() != JCTree.SELECT)
  1033                     return illegal(typeAnnos.head.pos);
  1034                 JCFieldAccess sel = (JCFieldAccess)expr;
  1035                 if (sel.name != names._class)
  1036                     return illegal();
  1037                 else {
  1038                     sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
  1039                     t = expr;
  1041             } else {
  1042                 // type annotation targeting a cast
  1043                 t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
  1045             break;
  1046         case IDENTIFIER: case ASSERT: case ENUM:
  1047             if (typeArgs != null) return illegal();
  1048             t = toP(F.at(S.pos()).Ident(ident()));
  1049             loop: while (true) {
  1050                 pos = S.pos();
  1051                 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1053                 // need to report an error later if LBRACKET is for array
  1054                 // index access rather than array creation level
  1055                 if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
  1056                     return illegal(annos.head.pos);
  1057                 switch (S.token()) {
  1058                 case LBRACKET:
  1059                     S.nextToken();
  1061                     if (S.token() == RBRACKET) {
  1063                         S.nextToken();
  1065                         t = bracketsOpt(t, annos);
  1066                         t = toP(F.at(pos).TypeArray(t));
  1067                         t = bracketsSuffix(t);
  1068                     } else {
  1069                         if ((mode & EXPR) != 0) {
  1070                             mode = EXPR;
  1071                             JCExpression t1 = term();
  1072                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1073                             t = to(F.at(pos).Indexed(t, t1));
  1075                         accept(RBRACKET);
  1077                     break loop;
  1078                 case LPAREN:
  1079                     if ((mode & EXPR) != 0) {
  1080                         mode = EXPR;
  1081                         t = arguments(typeArgs, t);
  1082                         typeArgs = null;
  1084                     break loop;
  1085                 case DOT:
  1086                     S.nextToken();
  1087                     int oldmode = mode;
  1088                     mode &= ~NOPARAMS;
  1089                     typeArgs = typeArgumentsOpt(EXPR);
  1090                     mode = oldmode;
  1091                     if ((mode & EXPR) != 0) {
  1092                         switch (S.token()) {
  1093                         case CLASS:
  1094                             if (typeArgs != null) return illegal();
  1095                             mode = EXPR;
  1096                             t = to(F.at(pos).Select(t, names._class));
  1097                             S.nextToken();
  1098                             break loop;
  1099                         case THIS:
  1100                             if (typeArgs != null) return illegal();
  1101                             mode = EXPR;
  1102                             t = to(F.at(pos).Select(t, names._this));
  1103                             S.nextToken();
  1104                             break loop;
  1105                         case SUPER:
  1106                             mode = EXPR;
  1107                             t = to(F.at(pos).Select(t, names._super));
  1108                             t = superSuffix(typeArgs, t);
  1109                             typeArgs = null;
  1110                             break loop;
  1111                         case NEW:
  1112                             if (typeArgs != null) return illegal();
  1113                             mode = EXPR;
  1114                             int pos1 = S.pos();
  1115                             S.nextToken();
  1116                             if (S.token() == LT) typeArgs = typeArguments();
  1117                             t = innerCreator(pos1, typeArgs, t);
  1118                             typeArgs = null;
  1119                             break loop;
  1122                     // typeArgs saved for next loop iteration.
  1123                     t = toP(F.at(pos).Select(t, ident()));
  1124                     break;
  1125                 case ELLIPSIS:
  1126                     assert this.permitTypeAnnotationsPushBack;
  1127                     typeAnnotationsPushedBack = annos;
  1128                     break loop;
  1129                 default:
  1130                     break loop;
  1133             if (typeArgs != null) illegal();
  1134             t = typeArgumentsOpt(t);
  1135             break;
  1136         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1137         case DOUBLE: case BOOLEAN:
  1138             if (typeArgs != null) illegal();
  1139             t = bracketsSuffix(bracketsOpt(basicType()));
  1140             break;
  1141         case VOID:
  1142             if (typeArgs != null) illegal();
  1143             if ((mode & EXPR) != 0) {
  1144                 S.nextToken();
  1145                 if (S.token() == DOT) {
  1146                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
  1147                     t = bracketsSuffix(ti);
  1148                 } else {
  1149                     return illegal(pos);
  1151             } else {
  1152                 // Support the corner case of myMethodHandle.<void>invoke() by passing
  1153                 // a void type (like other primitive types) to the next phase.
  1154                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
  1155                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
  1156                 S.nextToken();
  1157                 return ti;
  1158                 //return illegal();
  1160             break;
  1161         default:
  1162             return illegal();
  1164         if (typeArgs != null) illegal();
  1165         while (true) {
  1166             int pos1 = S.pos();
  1168             final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1170             if (S.token() == LBRACKET) {
  1171                 S.nextToken();
  1173                 if ((mode & TYPE) != 0) {
  1174                     int oldmode = mode;
  1175                     mode = TYPE;
  1176                     if (S.token() == RBRACKET) {
  1177                         S.nextToken();
  1178                         t = bracketsOpt(t, annos);
  1179                         t = toP(F.at(pos1).TypeArray(t));
  1180                         return t;
  1182                     mode = oldmode;
  1184                 if ((mode & EXPR) != 0) {
  1185                     mode = EXPR;
  1186                     JCExpression t1 = term();
  1187                     t = to(F.at(pos1).Indexed(t, t1));
  1189                 accept(RBRACKET);
  1190             } else if (S.token() == DOT) {
  1191                 S.nextToken();
  1192                 typeArgs = typeArgumentsOpt(EXPR);
  1193                 if (S.token() == SUPER && (mode & EXPR) != 0) {
  1194                     mode = EXPR;
  1195                     t = to(F.at(pos1).Select(t, names._super));
  1196                     S.nextToken();
  1197                     t = arguments(typeArgs, t);
  1198                     typeArgs = null;
  1199                 } else if (S.token() == NEW && (mode & EXPR) != 0) {
  1200                     if (typeArgs != null) return illegal();
  1201                     mode = EXPR;
  1202                     int pos2 = S.pos();
  1203                     S.nextToken();
  1204                     if (S.token() == LT) typeArgs = typeArguments();
  1205                     t = innerCreator(pos2, typeArgs, t);
  1206                     typeArgs = null;
  1207                 } else {
  1208                     t = toP(F.at(pos1).Select(t, ident()));
  1209                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  1210                     typeArgs = null;
  1212             } else {
  1213                 if (!annos.isEmpty()) {
  1214                     illegal(0);
  1215                     if (permitTypeAnnotationsPushBack)
  1216                         typeAnnotationsPushedBack = annos;
  1217                     else
  1218                         return illegal(annos.head.pos);
  1220                 break;
  1223         while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
  1224             mode = EXPR;
  1225             t = to(F.at(S.pos()).Unary(
  1226                   S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  1227             S.nextToken();
  1230         return toP(t);
  1233     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  1234      */
  1235     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  1236         S.nextToken();
  1237         if (S.token() == LPAREN || typeArgs != null) {
  1238             t = arguments(typeArgs, t);
  1239         } else {
  1240             int pos = S.pos();
  1241             accept(DOT);
  1242             typeArgs = (S.token() == LT) ? typeArguments() : null;
  1243             t = toP(F.at(pos).Select(t, ident()));
  1244             t = argumentsOpt(typeArgs, t);
  1246         return t;
  1249     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  1250      */
  1251     JCPrimitiveTypeTree basicType() {
  1252         JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
  1253         S.nextToken();
  1254         return t;
  1257     /** ArgumentsOpt = [ Arguments ]
  1258      */
  1259     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  1260         if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
  1261             mode = EXPR;
  1262             return arguments(typeArgs, t);
  1263         } else {
  1264             return t;
  1268     /** Arguments = "(" [Expression { COMMA Expression }] ")"
  1269      */
  1270     List<JCExpression> arguments() {
  1271         ListBuffer<JCExpression> args = lb();
  1272         if (S.token() == LPAREN) {
  1273             S.nextToken();
  1274             if (S.token() != RPAREN) {
  1275                 args.append(parseExpression());
  1276                 while (S.token() == COMMA) {
  1277                     S.nextToken();
  1278                     args.append(parseExpression());
  1281             accept(RPAREN);
  1282         } else {
  1283             syntaxError(S.pos(), "expected", LPAREN);
  1285         return args.toList();
  1288     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  1289         int pos = S.pos();
  1290         List<JCExpression> args = arguments();
  1291         return toP(F.at(pos).Apply(typeArgs, t, args));
  1294     /**  TypeArgumentsOpt = [ TypeArguments ]
  1295      */
  1296     JCExpression typeArgumentsOpt(JCExpression t) {
  1297         if (S.token() == LT &&
  1298             (mode & TYPE) != 0 &&
  1299             (mode & NOPARAMS) == 0) {
  1300             mode = TYPE;
  1301             checkGenerics();
  1302             return typeArguments(t);
  1303         } else {
  1304             return t;
  1307     List<JCExpression> typeArgumentsOpt() {
  1308         return typeArgumentsOpt(TYPE);
  1311     List<JCExpression> typeArgumentsOpt(int useMode) {
  1312         if (S.token() == LT) {
  1313             checkGenerics();
  1314             if ((mode & useMode) == 0 ||
  1315                 (mode & NOPARAMS) != 0) {
  1316                 illegal();
  1318             mode = useMode;
  1319             return typeArguments();
  1321         return null;
  1324     /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  1325      */
  1326     List<JCExpression> typeArguments() {
  1327         ListBuffer<JCExpression> args = lb();
  1328         if (S.token() == LT) {
  1329             S.nextToken();
  1330             args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1331             while (S.token() == COMMA) {
  1332                 S.nextToken();
  1333                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1335             switch (S.token()) {
  1336             case GTGTGTEQ:
  1337                 S.token(GTGTEQ);
  1338                 break;
  1339             case GTGTEQ:
  1340                 S.token(GTEQ);
  1341                 break;
  1342             case GTEQ:
  1343                 S.token(EQ);
  1344                 break;
  1345             case GTGTGT:
  1346                 S.token(GTGT);
  1347                 break;
  1348             case GTGT:
  1349                 S.token(GT);
  1350                 break;
  1351             default:
  1352                 accept(GT);
  1353                 break;
  1355         } else {
  1356             syntaxError(S.pos(), "expected", LT);
  1358         return args.toList();
  1361     /** TypeArgument = Type
  1362      *               | [Annotations] "?"
  1363      *               | [Annotations] "?" EXTENDS Type {"&" Type}
  1364      *               | [Annotations] "?" SUPER Type
  1365      */
  1366     JCExpression typeArgument() {
  1367         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
  1368         if (S.token() != QUES) return parseType(annotations);
  1369         int pos = S.pos();
  1370         S.nextToken();
  1371         JCExpression result;
  1372         if (S.token() == EXTENDS) {
  1373             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
  1374             S.nextToken();
  1375             result = F.at(pos).Wildcard(t, parseType());
  1376         } else if (S.token() == SUPER) {
  1377             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
  1378             S.nextToken();
  1379             result = F.at(pos).Wildcard(t, parseType());
  1380         } else if (S.token() == IDENTIFIER) {
  1381             //error recovery
  1382             reportSyntaxError(S.prevEndPos(), "expected3",
  1383                     GT, EXTENDS, SUPER);
  1384             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  1385             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  1386             JCIdent id = toP(F.at(S.pos()).Ident(ident()));
  1387             result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  1388         } else {
  1389             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  1390             result = toP(F.at(pos).Wildcard(t, null));
  1392         if (!annotations.isEmpty())
  1393             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
  1394         return result;
  1397     JCTypeApply typeArguments(JCExpression t) {
  1398         int pos = S.pos();
  1399         List<JCExpression> args = typeArguments();
  1400         return toP(F.at(pos).TypeApply(t, args));
  1403     /**
  1404      * BracketsOpt = { [Annotations] "[" "]" }
  1406      * <p>
  1408      * <code>annotations</code> is the list of annotations targeting
  1409      * the expression <code>t</code>.
  1410      */
  1411     private JCExpression bracketsOpt(JCExpression t,
  1412             List<JCTypeAnnotation> annotations) {
  1413         List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
  1415         if (S.token() == LBRACKET) {
  1416             int pos = S.pos();
  1417             S.nextToken();
  1419             JCExpression orig = t;
  1420             t = bracketsOptCont(t, pos, nextLevelAnnotations);
  1421         } else if (!nextLevelAnnotations.isEmpty()) {
  1422             if (permitTypeAnnotationsPushBack) {
  1423                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
  1424             } else
  1425                 return illegal(nextLevelAnnotations.head.pos);
  1428         int apos = S.pos();
  1429         if (!annotations.isEmpty())
  1430             t = F.at(apos).AnnotatedType(annotations, t);
  1431         return t;
  1434     /** BracketsOpt = {"[" TypeAnnotations "]"}
  1435      */
  1436     private JCExpression bracketsOpt(JCExpression t) {
  1437         return bracketsOpt(t, List.<JCTypeAnnotation>nil());
  1440     private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
  1441             List<JCTypeAnnotation> annotations) {
  1442         accept(RBRACKET);
  1443         t = bracketsOpt(t, annotations);
  1444         return toP(F.at(pos).TypeArray(t));
  1447     /** BracketsSuffixExpr = "." CLASS
  1448      *  BracketsSuffixType =
  1449      */
  1450     JCExpression bracketsSuffix(JCExpression t) {
  1451         if ((mode & EXPR) != 0 && S.token() == DOT) {
  1452             mode = EXPR;
  1453             int pos = S.pos();
  1454             S.nextToken();
  1455             accept(CLASS);
  1456             if (S.pos() == errorEndPos) {
  1457                 // error recovery
  1458                 Name name = null;
  1459                 if (S.token() == IDENTIFIER) {
  1460                     name = S.name();
  1461                     S.nextToken();
  1462                 } else {
  1463                     name = names.error;
  1465                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  1466             } else {
  1467                 t = toP(F.at(pos).Select(t, names._class));
  1469         } else if ((mode & TYPE) != 0) {
  1470             mode = TYPE;
  1471         } else {
  1472             syntaxError(S.pos(), "dot.class.expected");
  1474         return t;
  1477     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  1478      */
  1479     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  1481         List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
  1483         switch (S.token()) {
  1484         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1485         case DOUBLE: case BOOLEAN:
  1486             if (typeArgs == null) {
  1487                 if (newAnnotations.isEmpty())
  1488                     return arrayCreatorRest(newpos, basicType());
  1489                 else
  1490                     return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
  1492             break;
  1493         default:
  1495         JCExpression t = qualident();
  1496         // handle type annotations for non primitive arrays
  1497         if (!newAnnotations.isEmpty())
  1498             t = F.AnnotatedType(newAnnotations, t);
  1500         int oldmode = mode;
  1501         mode = TYPE;
  1502         if (S.token() == LT) {
  1503             checkGenerics();
  1504             t = typeArguments(t);
  1506         while (S.token() == DOT) {
  1507             int pos = S.pos();
  1508             S.nextToken();
  1509             t = toP(F.at(pos).Select(t, ident()));
  1510             if (S.token() == LT) {
  1511                 checkGenerics();
  1512                 t = typeArguments(t);
  1515         mode = oldmode;
  1516         if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
  1517             JCExpression e = arrayCreatorRest(newpos, t);
  1518             if (typeArgs != null) {
  1519                 int pos = newpos;
  1520                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  1521                     // note: this should always happen but we should
  1522                     // not rely on this as the parser is continuously
  1523                     // modified to improve error recovery.
  1524                     pos = typeArgs.head.pos;
  1526                 setErrorEndPos(S.prevEndPos());
  1527                 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
  1528                 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
  1530             return e;
  1531         } else if (S.token() == LPAREN) {
  1532             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
  1533             if (newClass.def != null) {
  1534                 assert newClass.def.mods.annotations.isEmpty();
  1535                 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
  1537             return newClass;
  1538         } else {
  1539             reportSyntaxError(S.pos(), "expected2",
  1540                                LPAREN, LBRACKET);
  1541             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  1542             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  1546     /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
  1547      */
  1548     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  1549         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
  1550         if (S.token() == LT) {
  1551             checkGenerics();
  1552             t = typeArguments(t);
  1554         return classCreatorRest(newpos, encl, typeArgs, t);
  1557     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
  1558      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
  1559      */
  1560     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  1562         List<JCTypeAnnotation> topAnnos = List.nil();
  1563         if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
  1564             JCAnnotatedType atype = (JCAnnotatedType) elemtype;
  1565             topAnnos = atype.annotations;
  1566             elemtype = atype.underlyingType;
  1569         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1571         accept(LBRACKET);
  1573         if (S.token() == RBRACKET) {
  1574             accept(RBRACKET);
  1576             elemtype = bracketsOpt(elemtype, annos);
  1578             if (S.token() == LBRACE) {
  1579                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
  1581                 na.annotations = topAnnos;
  1583                 return na;
  1584             } else {
  1585                 return syntaxError(S.pos(), "array.dimension.missing");
  1587         } else {
  1588             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  1590             // maintain array dimension type annotations
  1591             ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
  1592             dimAnnotations.append(annos);
  1594             dims.append(parseExpression());
  1595             accept(RBRACKET);
  1596             while (S.token() == LBRACKET
  1597                     || (S.token() == MONKEYS_AT)) {
  1598                 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
  1599                 int pos = S.pos();
  1600                 S.nextToken();
  1601                 if (S.token() == RBRACKET) {
  1602                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1603                 } else {
  1604                     if (S.token() == RBRACKET) { // no dimension
  1605                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1606                     } else {
  1607                         dimAnnotations.append(maybeDimAnnos);
  1608                         dims.append(parseExpression());
  1609                         accept(RBRACKET);
  1614             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  1615             na.annotations = topAnnos;
  1616             na.dimAnnotations = dimAnnotations.toList();
  1617             return na;
  1621     /** ClassCreatorRest = Arguments [ClassBody]
  1622      */
  1623     JCNewClass classCreatorRest(int newpos,
  1624                                   JCExpression encl,
  1625                                   List<JCExpression> typeArgs,
  1626                                   JCExpression t)
  1628         List<JCExpression> args = arguments();
  1629         JCClassDecl body = null;
  1630         if (S.token() == LBRACE) {
  1631             int pos = S.pos();
  1632             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  1633             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1634             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  1636         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  1639     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  1640      */
  1641     JCExpression arrayInitializer(int newpos, JCExpression t) {
  1642         accept(LBRACE);
  1643         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  1644         if (S.token() == COMMA) {
  1645             S.nextToken();
  1646         } else if (S.token() != RBRACE) {
  1647             elems.append(variableInitializer());
  1648             while (S.token() == COMMA) {
  1649                 S.nextToken();
  1650                 if (S.token() == RBRACE) break;
  1651                 elems.append(variableInitializer());
  1654         accept(RBRACE);
  1655         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  1658     /** VariableInitializer = ArrayInitializer | Expression
  1659      */
  1660     public JCExpression variableInitializer() {
  1661         return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
  1664     /** ParExpression = "(" Expression ")"
  1665      */
  1666     JCExpression parExpression() {
  1667         accept(LPAREN);
  1668         JCExpression t = parseExpression();
  1669         accept(RPAREN);
  1670         return t;
  1673     /** Block = "{" BlockStatements "}"
  1674      */
  1675     JCBlock block(int pos, long flags) {
  1676         accept(LBRACE);
  1677         List<JCStatement> stats = blockStatements();
  1678         JCBlock t = F.at(pos).Block(flags, stats);
  1679         while (S.token() == CASE || S.token() == DEFAULT) {
  1680             syntaxError("orphaned", S.token());
  1681             switchBlockStatementGroups();
  1683         // the Block node has a field "endpos" for first char of last token, which is
  1684         // usually but not necessarily the last char of the last token.
  1685         t.endpos = S.pos();
  1686         accept(RBRACE);
  1687         return toP(t);
  1690     public JCBlock block() {
  1691         return block(S.pos(), 0);
  1694     /** BlockStatements = { BlockStatement }
  1695      *  BlockStatement  = LocalVariableDeclarationStatement
  1696      *                  | ClassOrInterfaceOrEnumDeclaration
  1697      *                  | [Ident ":"] Statement
  1698      *  LocalVariableDeclarationStatement
  1699      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  1700      */
  1701     @SuppressWarnings("fallthrough")
  1702     List<JCStatement> blockStatements() {
  1703 //todo: skip to anchor on error(?)
  1704         int lastErrPos = -1;
  1705         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  1706         while (true) {
  1707             int pos = S.pos();
  1708             switch (S.token()) {
  1709             case RBRACE: case CASE: case DEFAULT: case EOF:
  1710                 return stats.toList();
  1711             case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  1712             case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  1713             case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  1714                 stats.append(parseStatement());
  1715                 break;
  1716             case MONKEYS_AT:
  1717             case FINAL: {
  1718                 String dc = S.docComment();
  1719                 JCModifiers mods = modifiersOpt();
  1720                 if (S.token() == INTERFACE ||
  1721                     S.token() == CLASS ||
  1722                     allowEnums && S.token() == ENUM) {
  1723                     stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  1724                 } else {
  1725                     JCExpression t = parseType();
  1726                     stats.appendList(variableDeclarators(mods, t,
  1727                                                          new ListBuffer<JCStatement>()));
  1728                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1729                     storeEnd(stats.elems.last(), S.endPos());
  1730                     accept(SEMI);
  1732                 break;
  1734             case ABSTRACT: case STRICTFP: {
  1735                 String dc = S.docComment();
  1736                 JCModifiers mods = modifiersOpt();
  1737                 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  1738                 break;
  1740             case INTERFACE:
  1741             case CLASS:
  1742                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  1743                                                                S.docComment()));
  1744                 break;
  1745             case ENUM:
  1746             case ASSERT:
  1747                 if (allowEnums && S.token() == ENUM) {
  1748                     log.error(S.pos(), "local.enum");
  1749                     stats.
  1750                         append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  1751                                                                  S.docComment()));
  1752                     break;
  1753                 } else if (allowAsserts && S.token() == ASSERT) {
  1754                     stats.append(parseStatement());
  1755                     break;
  1757                 /* fall through to default */
  1758             default:
  1759                 Name name = S.name();
  1760                 JCExpression t = term(EXPR | TYPE);
  1761                 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
  1762                     S.nextToken();
  1763                     JCStatement stat = parseStatement();
  1764                     stats.append(F.at(pos).Labelled(name, stat));
  1765                 } else if ((lastmode & TYPE) != 0 &&
  1766                            (S.token() == IDENTIFIER ||
  1767                             S.token() == ASSERT ||
  1768                             S.token() == ENUM)) {
  1769                     pos = S.pos();
  1770                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1771                     F.at(pos);
  1772                     stats.appendList(variableDeclarators(mods, t,
  1773                                                          new ListBuffer<JCStatement>()));
  1774                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1775                     storeEnd(stats.elems.last(), S.endPos());
  1776                     accept(SEMI);
  1777                 } else {
  1778                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  1779                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
  1780                     accept(SEMI);
  1784             // error recovery
  1785             if (S.pos() == lastErrPos)
  1786                 return stats.toList();
  1787             if (S.pos() <= errorEndPos) {
  1788                 skip(false, true, true, true);
  1789                 lastErrPos = S.pos();
  1792             // ensure no dangling /** @deprecated */ active
  1793             S.resetDeprecatedFlag();
  1797     /** Statement =
  1798      *       Block
  1799      *     | IF ParExpression Statement [ELSE Statement]
  1800      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  1801      *     | FOR "(" FormalParameter : Expression ")" Statement
  1802      *     | WHILE ParExpression Statement
  1803      *     | DO Statement WHILE ParExpression ";"
  1804      *     | TRY Block ( Catches | [Catches] FinallyPart )
  1805      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  1806      *     | SYNCHRONIZED ParExpression Block
  1807      *     | RETURN [Expression] ";"
  1808      *     | THROW Expression ";"
  1809      *     | BREAK [Ident] ";"
  1810      *     | CONTINUE [Ident] ";"
  1811      *     | ASSERT Expression [ ":" Expression ] ";"
  1812      *     | ";"
  1813      *     | ExpressionStatement
  1814      *     | Ident ":" Statement
  1815      */
  1816     @SuppressWarnings("fallthrough")
  1817     public JCStatement parseStatement() {
  1818         int pos = S.pos();
  1819         switch (S.token()) {
  1820         case LBRACE:
  1821             return block();
  1822         case IF: {
  1823             S.nextToken();
  1824             JCExpression cond = parExpression();
  1825             JCStatement thenpart = parseStatement();
  1826             JCStatement elsepart = null;
  1827             if (S.token() == ELSE) {
  1828                 S.nextToken();
  1829                 elsepart = parseStatement();
  1831             return F.at(pos).If(cond, thenpart, elsepart);
  1833         case FOR: {
  1834             S.nextToken();
  1835             accept(LPAREN);
  1836             List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
  1837             if (inits.length() == 1 &&
  1838                 inits.head.getTag() == JCTree.VARDEF &&
  1839                 ((JCVariableDecl) inits.head).init == null &&
  1840                 S.token() == COLON) {
  1841                 checkForeach();
  1842                 JCVariableDecl var = (JCVariableDecl)inits.head;
  1843                 accept(COLON);
  1844                 JCExpression expr = parseExpression();
  1845                 accept(RPAREN);
  1846                 JCStatement body = parseStatement();
  1847                 return F.at(pos).ForeachLoop(var, expr, body);
  1848             } else {
  1849                 accept(SEMI);
  1850                 JCExpression cond = S.token() == SEMI ? null : parseExpression();
  1851                 accept(SEMI);
  1852                 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  1853                 accept(RPAREN);
  1854                 JCStatement body = parseStatement();
  1855                 return F.at(pos).ForLoop(inits, cond, steps, body);
  1858         case WHILE: {
  1859             S.nextToken();
  1860             JCExpression cond = parExpression();
  1861             JCStatement body = parseStatement();
  1862             return F.at(pos).WhileLoop(cond, body);
  1864         case DO: {
  1865             S.nextToken();
  1866             JCStatement body = parseStatement();
  1867             accept(WHILE);
  1868             JCExpression cond = parExpression();
  1869             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  1870             accept(SEMI);
  1871             return t;
  1873         case TRY: {
  1874             S.nextToken();
  1875             JCBlock body = block();
  1876             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  1877             JCBlock finalizer = null;
  1878             if (S.token() == CATCH || S.token() == FINALLY) {
  1879                 while (S.token() == CATCH) catchers.append(catchClause());
  1880                 if (S.token() == FINALLY) {
  1881                     S.nextToken();
  1882                     finalizer = block();
  1884             } else {
  1885                 log.error(pos, "try.without.catch.or.finally");
  1887             return F.at(pos).Try(body, catchers.toList(), finalizer);
  1889         case SWITCH: {
  1890             S.nextToken();
  1891             JCExpression selector = parExpression();
  1892             accept(LBRACE);
  1893             List<JCCase> cases = switchBlockStatementGroups();
  1894             JCSwitch t = to(F.at(pos).Switch(selector, cases));
  1895             accept(RBRACE);
  1896             return t;
  1898         case SYNCHRONIZED: {
  1899             S.nextToken();
  1900             JCExpression lock = parExpression();
  1901             JCBlock body = block();
  1902             return F.at(pos).Synchronized(lock, body);
  1904         case RETURN: {
  1905             S.nextToken();
  1906             JCExpression result = S.token() == SEMI ? null : parseExpression();
  1907             JCReturn t = to(F.at(pos).Return(result));
  1908             accept(SEMI);
  1909             return t;
  1911         case THROW: {
  1912             S.nextToken();
  1913             JCExpression exc = parseExpression();
  1914             JCThrow t = to(F.at(pos).Throw(exc));
  1915             accept(SEMI);
  1916             return t;
  1918         case BREAK: {
  1919             S.nextToken();
  1920             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  1921             JCBreak t = to(F.at(pos).Break(label));
  1922             accept(SEMI);
  1923             return t;
  1925         case CONTINUE: {
  1926             S.nextToken();
  1927             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  1928             JCContinue t =  to(F.at(pos).Continue(label));
  1929             accept(SEMI);
  1930             return t;
  1932         case SEMI:
  1933             S.nextToken();
  1934             return toP(F.at(pos).Skip());
  1935         case ELSE:
  1936             return toP(F.Exec(syntaxError("else.without.if")));
  1937         case FINALLY:
  1938             return toP(F.Exec(syntaxError("finally.without.try")));
  1939         case CATCH:
  1940             return toP(F.Exec(syntaxError("catch.without.try")));
  1941         case ASSERT: {
  1942             if (allowAsserts && S.token() == ASSERT) {
  1943                 S.nextToken();
  1944                 JCExpression assertion = parseExpression();
  1945                 JCExpression message = null;
  1946                 if (S.token() == COLON) {
  1947                     S.nextToken();
  1948                     message = parseExpression();
  1950                 JCAssert t = to(F.at(pos).Assert(assertion, message));
  1951                 accept(SEMI);
  1952                 return t;
  1954             /* else fall through to default case */
  1956         case ENUM:
  1957         default:
  1958             Name name = S.name();
  1959             JCExpression expr = parseExpression();
  1960             if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
  1961                 S.nextToken();
  1962                 JCStatement stat = parseStatement();
  1963                 return F.at(pos).Labelled(name, stat);
  1964             } else {
  1965                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  1966                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  1967                 accept(SEMI);
  1968                 return stat;
  1973     /** CatchClause     = CATCH "(" FormalParameter ")" Block
  1974      */
  1975     JCCatch catchClause() {
  1976         int pos = S.pos();
  1977         accept(CATCH);
  1978         accept(LPAREN);
  1979         JCVariableDecl formal =
  1980             variableDeclaratorId(optFinal(Flags.PARAMETER),
  1981                                  qualident());
  1982         accept(RPAREN);
  1983         JCBlock body = block();
  1984         return F.at(pos).Catch(formal, body);
  1987     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  1988      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  1989      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  1990      */
  1991     List<JCCase> switchBlockStatementGroups() {
  1992         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  1993         while (true) {
  1994             int pos = S.pos();
  1995             switch (S.token()) {
  1996             case CASE: {
  1997                 S.nextToken();
  1998                 JCExpression pat = parseExpression();
  1999                 accept(COLON);
  2000                 List<JCStatement> stats = blockStatements();
  2001                 JCCase c = F.at(pos).Case(pat, stats);
  2002                 if (stats.isEmpty())
  2003                     storeEnd(c, S.prevEndPos());
  2004                 cases.append(c);
  2005                 break;
  2007             case DEFAULT: {
  2008                 S.nextToken();
  2009                 accept(COLON);
  2010                 List<JCStatement> stats = blockStatements();
  2011                 JCCase c = F.at(pos).Case(null, stats);
  2012                 if (stats.isEmpty())
  2013                     storeEnd(c, S.prevEndPos());
  2014                 cases.append(c);
  2015                 break;
  2017             case RBRACE: case EOF:
  2018                 return cases.toList();
  2019             default:
  2020                 S.nextToken(); // to ensure progress
  2021                 syntaxError(pos, "expected3",
  2022                     CASE, DEFAULT, RBRACE);
  2027     /** MoreStatementExpressions = { COMMA StatementExpression }
  2028      */
  2029     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  2030                                                                     JCExpression first,
  2031                                                                     T stats) {
  2032         // This Exec is a "StatementExpression"; it subsumes no terminating token
  2033         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  2034         while (S.token() == COMMA) {
  2035             S.nextToken();
  2036             pos = S.pos();
  2037             JCExpression t = parseExpression();
  2038             // This Exec is a "StatementExpression"; it subsumes no terminating token
  2039             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  2041         return stats;
  2044     /** ForInit = StatementExpression MoreStatementExpressions
  2045      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  2046      */
  2047     List<JCStatement> forInit() {
  2048         ListBuffer<JCStatement> stats = lb();
  2049         int pos = S.pos();
  2050         if (S.token() == FINAL || S.token() == MONKEYS_AT) {
  2051             return variableDeclarators(optFinal(0), parseType(), stats).toList();
  2052         } else {
  2053             JCExpression t = term(EXPR | TYPE);
  2054             if ((lastmode & TYPE) != 0 &&
  2055                 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
  2056                 return variableDeclarators(modifiersOpt(), t, stats).toList();
  2057             else
  2058                 return moreStatementExpressions(pos, t, stats).toList();
  2062     /** ForUpdate = StatementExpression MoreStatementExpressions
  2063      */
  2064     List<JCExpressionStatement> forUpdate() {
  2065         return moreStatementExpressions(S.pos(),
  2066                                         parseExpression(),
  2067                                         new ListBuffer<JCExpressionStatement>()).toList();
  2070     enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
  2072     /** AnnotationsOpt = { '@' Annotation }
  2073      */
  2074     List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
  2075         if (S.token() != MONKEYS_AT) return List.nil(); // optimization
  2076         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  2077         int prevmode = mode;
  2078         while (S.token() == MONKEYS_AT) {
  2079             int pos = S.pos();
  2080             S.nextToken();
  2081             buf.append(annotation(pos, kind));
  2083         lastmode = mode;
  2084         mode = prevmode;
  2085         List<JCAnnotation> annotations = buf.toList();
  2087         if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
  2088             System.out.println("TA: parsing " + annotations
  2089                     + " in " + log.currentSourceFile());
  2090         return annotations;
  2093     List<JCTypeAnnotation> typeAnnotationsOpt() {
  2094         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
  2095         return List.convert(JCTypeAnnotation.class, annotations);
  2098     /** ModifiersOpt = { Modifier }
  2099      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  2100      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  2101      *           | "@" Annotation
  2102      */
  2103     JCModifiers modifiersOpt() {
  2104         return modifiersOpt(null);
  2106     JCModifiers modifiersOpt(JCModifiers partial) {
  2107         long flags = (partial == null) ? 0 : partial.flags;
  2108         if (S.deprecatedFlag()) {
  2109             flags |= Flags.DEPRECATED;
  2110             S.resetDeprecatedFlag();
  2112         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  2113         if (partial != null) annotations.appendList(partial.annotations);
  2114         int pos = S.pos();
  2115         int lastPos = Position.NOPOS;
  2116     loop:
  2117         while (true) {
  2118             long flag;
  2119             switch (S.token()) {
  2120             case PRIVATE     : flag = Flags.PRIVATE; break;
  2121             case PROTECTED   : flag = Flags.PROTECTED; break;
  2122             case PUBLIC      : flag = Flags.PUBLIC; break;
  2123             case STATIC      : flag = Flags.STATIC; break;
  2124             case TRANSIENT   : flag = Flags.TRANSIENT; break;
  2125             case FINAL       : flag = Flags.FINAL; break;
  2126             case ABSTRACT    : flag = Flags.ABSTRACT; break;
  2127             case NATIVE      : flag = Flags.NATIVE; break;
  2128             case VOLATILE    : flag = Flags.VOLATILE; break;
  2129             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  2130             case STRICTFP    : flag = Flags.STRICTFP; break;
  2131             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  2132             default: break loop;
  2134             if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
  2135             lastPos = S.pos();
  2136             S.nextToken();
  2137             if (flag == Flags.ANNOTATION) {
  2138                 checkAnnotations();
  2139                 if (S.token() != INTERFACE) {
  2140                 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
  2141                 // if first modifier is an annotation, set pos to annotation's.
  2142                 if (flags == 0 && annotations.isEmpty())
  2143                     pos = ann.pos;
  2144                 annotations.append(ann);
  2145                 lastPos = ann.pos;
  2146                     flag = 0;
  2149             flags |= flag;
  2151         switch (S.token()) {
  2152         case ENUM: flags |= Flags.ENUM; break;
  2153         case INTERFACE: flags |= Flags.INTERFACE; break;
  2154         default: break;
  2157         /* A modifiers tree with no modifier tokens or annotations
  2158          * has no text position. */
  2159         if (flags == 0 && annotations.isEmpty())
  2160             pos = Position.NOPOS;
  2162         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  2163         if (pos != Position.NOPOS)
  2164             storeEnd(mods, S.prevEndPos());
  2165         return mods;
  2168     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  2169      * @param pos position of "@" token
  2170      */
  2171     JCAnnotation annotation(int pos, AnnotationKind kind) {
  2172         // accept(AT); // AT consumed by caller
  2173         checkAnnotations();
  2174         if (kind == AnnotationKind.TYPE_ANNO)
  2175             checkTypeAnnotations();
  2176         JCTree ident = qualident();
  2177         List<JCExpression> fieldValues = annotationFieldValuesOpt();
  2178         JCAnnotation ann;
  2179         if (kind == AnnotationKind.DEFAULT_ANNO)
  2180             ann = F.at(pos).Annotation(ident, fieldValues);
  2181         else
  2182             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
  2183         storeEnd(ann, S.prevEndPos());
  2184         return ann;
  2187     List<JCExpression> annotationFieldValuesOpt() {
  2188         return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  2191     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  2192     List<JCExpression> annotationFieldValues() {
  2193         accept(LPAREN);
  2194         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2195         if (S.token() != RPAREN) {
  2196             buf.append(annotationFieldValue());
  2197             while (S.token() == COMMA) {
  2198                 S.nextToken();
  2199                 buf.append(annotationFieldValue());
  2202         accept(RPAREN);
  2203         return buf.toList();
  2206     /** AnnotationFieldValue    = AnnotationValue
  2207      *                          | Identifier "=" AnnotationValue
  2208      */
  2209     JCExpression annotationFieldValue() {
  2210         if (S.token() == IDENTIFIER) {
  2211             mode = EXPR;
  2212             JCExpression t1 = term1();
  2213             if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
  2214                 int pos = S.pos();
  2215                 accept(EQ);
  2216                 return toP(F.at(pos).Assign(t1, annotationValue()));
  2217             } else {
  2218                 return t1;
  2221         return annotationValue();
  2224     /* AnnotationValue          = ConditionalExpression
  2225      *                          | Annotation
  2226      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
  2227      */
  2228     JCExpression annotationValue() {
  2229         int pos;
  2230         switch (S.token()) {
  2231         case MONKEYS_AT:
  2232             pos = S.pos();
  2233             S.nextToken();
  2234             return annotation(pos, AnnotationKind.DEFAULT_ANNO);
  2235         case LBRACE:
  2236             pos = S.pos();
  2237             accept(LBRACE);
  2238             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2239             if (S.token() != RBRACE) {
  2240                 buf.append(annotationValue());
  2241                 while (S.token() == COMMA) {
  2242                     S.nextToken();
  2243                     if (S.token() == RPAREN) break;
  2244                     buf.append(annotationValue());
  2247             accept(RBRACE);
  2248             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  2249         default:
  2250             mode = EXPR;
  2251             return term1();
  2255     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  2256      */
  2257     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  2258                                                                          JCExpression type,
  2259                                                                          T vdefs)
  2261         return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
  2264     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  2265      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  2267      *  @param reqInit  Is an initializer always required?
  2268      *  @param dc       The documentation comment for the variable declarations, or null.
  2269      */
  2270     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  2271                                                                      JCModifiers mods,
  2272                                                                      JCExpression type,
  2273                                                                      Name name,
  2274                                                                      boolean reqInit,
  2275                                                                      String dc,
  2276                                                                      T vdefs)
  2278         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  2279         while (S.token() == COMMA) {
  2280             // All but last of multiple declarators subsume a comma
  2281             storeEnd((JCTree)vdefs.elems.last(), S.endPos());
  2282             S.nextToken();
  2283             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  2285         return vdefs;
  2288     /** VariableDeclarator = Ident VariableDeclaratorRest
  2289      *  ConstantDeclarator = Ident ConstantDeclaratorRest
  2290      */
  2291     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
  2292         return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
  2295     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  2296      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  2298      *  @param reqInit  Is an initializer always required?
  2299      *  @param dc       The documentation comment for the variable declarations, or null.
  2300      */
  2301     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  2302                                   boolean reqInit, String dc) {
  2303         type = bracketsOpt(type);
  2304         JCExpression init = null;
  2305         if (S.token() == EQ) {
  2306             S.nextToken();
  2307             init = variableInitializer();
  2309         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
  2310         JCVariableDecl result =
  2311             toP(F.at(pos).VarDef(mods, name, type, init));
  2312         attach(result, dc);
  2313         return result;
  2316     /** VariableDeclaratorId = Ident BracketsOpt
  2317      */
  2318     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  2319         int pos = S.pos();
  2320         Name name = ident();
  2321         if ((mods.flags & Flags.VARARGS) == 0)
  2322             type = bracketsOpt(type);
  2323         return toP(F.at(pos).VarDef(mods, name, type, null));
  2326     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  2327      */
  2328     public JCTree.JCCompilationUnit parseCompilationUnit() {
  2329         int pos = S.pos();
  2330         JCExpression pid = null;
  2331         String dc = S.docComment();
  2332         JCModifiers mods = null;
  2333         List<JCAnnotation> packageAnnotations = List.nil();
  2334         if (S.token() == MONKEYS_AT)
  2335             mods = modifiersOpt();
  2337         if (S.token() == PACKAGE) {
  2338             if (mods != null) {
  2339                 checkNoMods(mods.flags);
  2340                 packageAnnotations = mods.annotations;
  2341                 mods = null;
  2343             S.nextToken();
  2344             pid = qualident();
  2345             accept(SEMI);
  2347         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2348         boolean checkForImports = true;
  2349         while (S.token() != EOF) {
  2350             if (S.pos() <= errorEndPos) {
  2351                 // error recovery
  2352                 skip(checkForImports, false, false, false);
  2353                 if (S.token() == EOF)
  2354                     break;
  2356             if (checkForImports && mods == null && S.token() == IMPORT) {
  2357                 defs.append(importDeclaration());
  2358             } else {
  2359                 JCTree def = typeDeclaration(mods);
  2360                 if (def instanceof JCExpressionStatement)
  2361                     def = ((JCExpressionStatement)def).expr;
  2362                 defs.append(def);
  2363                 if (def instanceof JCClassDecl)
  2364                     checkForImports = false;
  2365                 mods = null;
  2368         JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
  2369         attach(toplevel, dc);
  2370         if (defs.elems.isEmpty())
  2371             storeEnd(toplevel, S.prevEndPos());
  2372         if (keepDocComments)
  2373             toplevel.docComments = docComments;
  2374         if (keepLineMap)
  2375             toplevel.lineMap = S.getLineMap();
  2376         return toplevel;
  2379     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  2380      */
  2381     JCTree importDeclaration() {
  2382         int pos = S.pos();
  2383         S.nextToken();
  2384         boolean importStatic = false;
  2385         if (S.token() == STATIC) {
  2386             checkStaticImports();
  2387             importStatic = true;
  2388             S.nextToken();
  2390         JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
  2391         do {
  2392             int pos1 = S.pos();
  2393             accept(DOT);
  2394             if (S.token() == STAR) {
  2395                 pid = to(F.at(pos1).Select(pid, names.asterisk));
  2396                 S.nextToken();
  2397                 break;
  2398             } else {
  2399                 pid = toP(F.at(pos1).Select(pid, ident()));
  2401         } while (S.token() == DOT);
  2402         accept(SEMI);
  2403         return toP(F.at(pos).Import(pid, importStatic));
  2406     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  2407      *                  | ";"
  2408      */
  2409     JCTree typeDeclaration(JCModifiers mods) {
  2410         int pos = S.pos();
  2411         if (mods == null && S.token() == SEMI) {
  2412             S.nextToken();
  2413             return toP(F.at(pos).Skip());
  2414         } else {
  2415             String dc = S.docComment();
  2416             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
  2420     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  2421      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  2422      *  @param mods     Any modifiers starting the class or interface declaration
  2423      *  @param dc       The documentation comment for the class, or null.
  2424      */
  2425     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
  2426         if (S.token() == CLASS) {
  2427             return classDeclaration(mods, dc);
  2428         } else if (S.token() == INTERFACE) {
  2429             return interfaceDeclaration(mods, dc);
  2430         } else if (allowEnums) {
  2431             if (S.token() == ENUM) {
  2432                 return enumDeclaration(mods, dc);
  2433             } else {
  2434                 int pos = S.pos();
  2435                 List<JCTree> errs;
  2436                 if (S.token() == IDENTIFIER) {
  2437                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  2438                     setErrorEndPos(S.pos());
  2439                 } else {
  2440                     errs = List.<JCTree>of(mods);
  2442                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
  2443                                               CLASS, INTERFACE, ENUM)));
  2445         } else {
  2446             if (S.token() == ENUM) {
  2447                 log.error(S.pos(), "enums.not.supported.in.source", source.name);
  2448                 allowEnums = true;
  2449                 return enumDeclaration(mods, dc);
  2451             int pos = S.pos();
  2452             List<JCTree> errs;
  2453             if (S.token() == IDENTIFIER) {
  2454                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  2455                 setErrorEndPos(S.pos());
  2456             } else {
  2457                 errs = List.<JCTree>of(mods);
  2459             return toP(F.Exec(syntaxError(pos, errs, "expected2",
  2460                                           CLASS, INTERFACE)));
  2464     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  2465      *                     [IMPLEMENTS TypeList] ClassBody
  2466      *  @param mods    The modifiers starting the class declaration
  2467      *  @param dc       The documentation comment for the class, or null.
  2468      */
  2469     JCClassDecl classDeclaration(JCModifiers mods, String dc) {
  2470         int pos = S.pos();
  2471         accept(CLASS);
  2472         Name name = ident();
  2474         List<JCTypeParameter> typarams = typeParametersOpt();
  2476         JCTree extending = null;
  2477         if (S.token() == EXTENDS) {
  2478             S.nextToken();
  2479             extending = parseType();
  2481         List<JCExpression> implementing = List.nil();
  2482         if (S.token() == IMPLEMENTS) {
  2483             S.nextToken();
  2484             implementing = typeList();
  2486         List<JCTree> defs = classOrInterfaceBody(name, false);
  2487         JCClassDecl result = toP(F.at(pos).ClassDef(
  2488             mods, name, typarams, extending, implementing, defs));
  2489         attach(result, dc);
  2490         return result;
  2493     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  2494      *                         [EXTENDS TypeList] InterfaceBody
  2495      *  @param mods    The modifiers starting the interface declaration
  2496      *  @param dc       The documentation comment for the interface, or null.
  2497      */
  2498     JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
  2499         int pos = S.pos();
  2500         accept(INTERFACE);
  2501         Name name = ident();
  2503         List<JCTypeParameter> typarams = typeParametersOpt();
  2505         List<JCExpression> extending = List.nil();
  2506         if (S.token() == EXTENDS) {
  2507             S.nextToken();
  2508             extending = typeList();
  2510         List<JCTree> defs = classOrInterfaceBody(name, true);
  2511         JCClassDecl result = toP(F.at(pos).ClassDef(
  2512             mods, name, typarams, null, extending, defs));
  2513         attach(result, dc);
  2514         return result;
  2517     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  2518      *  @param mods    The modifiers starting the enum declaration
  2519      *  @param dc       The documentation comment for the enum, or null.
  2520      */
  2521     JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
  2522         int pos = S.pos();
  2523         accept(ENUM);
  2524         Name name = ident();
  2526         List<JCExpression> implementing = List.nil();
  2527         if (S.token() == IMPLEMENTS) {
  2528             S.nextToken();
  2529             implementing = typeList();
  2532         List<JCTree> defs = enumBody(name);
  2533         JCModifiers newMods =
  2534             F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations);
  2535         JCClassDecl result = toP(F.at(pos).
  2536             ClassDef(newMods, name, List.<JCTypeParameter>nil(),
  2537                 null, implementing, defs));
  2538         attach(result, dc);
  2539         return result;
  2542     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  2543      *                  [ ";" {ClassBodyDeclaration} ] "}"
  2544      */
  2545     List<JCTree> enumBody(Name enumName) {
  2546         accept(LBRACE);
  2547         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2548         if (S.token() == COMMA) {
  2549             S.nextToken();
  2550         } else if (S.token() != RBRACE && S.token() != SEMI) {
  2551             defs.append(enumeratorDeclaration(enumName));
  2552             while (S.token() == COMMA) {
  2553                 S.nextToken();
  2554                 if (S.token() == RBRACE || S.token() == SEMI) break;
  2555                 defs.append(enumeratorDeclaration(enumName));
  2557             if (S.token() != SEMI && S.token() != RBRACE) {
  2558                 defs.append(syntaxError(S.pos(), "expected3",
  2559                                 COMMA, RBRACE, SEMI));
  2560                 S.nextToken();
  2563         if (S.token() == SEMI) {
  2564             S.nextToken();
  2565             while (S.token() != RBRACE && S.token() != EOF) {
  2566                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  2567                                                                 false));
  2568                 if (S.pos() <= errorEndPos) {
  2569                     // error recovery
  2570                    skip(false, true, true, false);
  2574         accept(RBRACE);
  2575         return defs.toList();
  2578     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  2579      */
  2580     JCTree enumeratorDeclaration(Name enumName) {
  2581         String dc = S.docComment();
  2582         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  2583         if (S.deprecatedFlag()) {
  2584             flags |= Flags.DEPRECATED;
  2585             S.resetDeprecatedFlag();
  2587         int pos = S.pos();
  2588         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
  2589         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  2590         List<JCExpression> typeArgs = typeArgumentsOpt();
  2591         int identPos = S.pos();
  2592         Name name = ident();
  2593         int createPos = S.pos();
  2594         List<JCExpression> args = (S.token() == LPAREN)
  2595             ? arguments() : List.<JCExpression>nil();
  2596         JCClassDecl body = null;
  2597         if (S.token() == LBRACE) {
  2598             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  2599             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  2600             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  2602         if (args.isEmpty() && body == null)
  2603             createPos = Position.NOPOS;
  2604         JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
  2605         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  2606         if (createPos != Position.NOPOS)
  2607             storeEnd(create, S.prevEndPos());
  2608         ident = F.at(Position.NOPOS).Ident(enumName);
  2609         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  2610         attach(result, dc);
  2611         return result;
  2614     /** TypeList = Type {"," Type}
  2615      */
  2616     List<JCExpression> typeList() {
  2617         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  2618         ts.append(parseType());
  2619         while (S.token() == COMMA) {
  2620             S.nextToken();
  2621             ts.append(parseType());
  2623         return ts.toList();
  2626     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  2627      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  2628      */
  2629     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  2630         accept(LBRACE);
  2631         if (S.pos() <= errorEndPos) {
  2632             // error recovery
  2633             skip(false, true, false, false);
  2634             if (S.token() == LBRACE)
  2635                 S.nextToken();
  2637         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2638         while (S.token() != RBRACE && S.token() != EOF) {
  2639             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  2640             if (S.pos() <= errorEndPos) {
  2641                // error recovery
  2642                skip(false, true, true, false);
  2645         accept(RBRACE);
  2646         return defs.toList();
  2649     /** ClassBodyDeclaration =
  2650      *      ";"
  2651      *    | [STATIC] Block
  2652      *    | ModifiersOpt
  2653      *      ( Type Ident
  2654      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  2655      *      | VOID Ident MethodDeclaratorRest
  2656      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
  2657      *      | Ident ConstructorDeclaratorRest
  2658      *      | TypeParameters Ident ConstructorDeclaratorRest
  2659      *      | ClassOrInterfaceOrEnumDeclaration
  2660      *      )
  2661      *  InterfaceBodyDeclaration =
  2662      *      ";"
  2663      *    | ModifiersOpt Type Ident
  2664      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
  2665      */
  2666     List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  2667         if (S.token() == SEMI) {
  2668             S.nextToken();
  2669             return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
  2670         } else {
  2671             String dc = S.docComment();
  2672             int pos = S.pos();
  2673             JCModifiers mods = modifiersOpt();
  2674             if (S.token() == CLASS ||
  2675                 S.token() == INTERFACE ||
  2676                 allowEnums && S.token() == ENUM) {
  2677                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2678             } else if (S.token() == LBRACE && !isInterface &&
  2679                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  2680                        mods.annotations.isEmpty()) {
  2681                 return List.<JCTree>of(block(pos, mods.flags));
  2682             } else {
  2683                 pos = S.pos();
  2684                 List<JCTypeParameter> typarams = typeParametersOpt();
  2685                 // Hack alert:  if there are type arguments but no Modifiers, the start
  2686                 // position will be lost unless we set the Modifiers position.  There
  2687                 // should be an AST node for type parameters (BugId 5005090).
  2688                 if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
  2689                     mods.pos = pos;
  2692                 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
  2694                 Token token = S.token();
  2695                 Name name = S.name();
  2696                 pos = S.pos();
  2697                 JCExpression type;
  2698                 boolean isVoid = S.token() == VOID;
  2699                 if (isVoid) {
  2700                     if (annosAfterParams.nonEmpty())
  2701                         illegal(annosAfterParams.head.pos);
  2702                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
  2703                     S.nextToken();
  2704                 } else {
  2705                     mods.annotations = mods.annotations.appendList(annosAfterParams);
  2706                     // method returns types are un-annotated types
  2707                     type = unannotatedType();
  2709                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
  2710                     if (isInterface || name != className)
  2711                         log.error(pos, "invalid.meth.decl.ret.type.req");
  2712                     return List.of(methodDeclaratorRest(
  2713                         pos, mods, null, names.init, typarams,
  2714                         isInterface, true, dc));
  2715                 } else {
  2716                     pos = S.pos();
  2717                     name = ident();
  2718                     if (S.token() == LPAREN) {
  2719                         return List.of(methodDeclaratorRest(
  2720                             pos, mods, type, name, typarams,
  2721                             isInterface, isVoid, dc));
  2722                     } else if (!isVoid && typarams.isEmpty()) {
  2723                         List<JCTree> defs =
  2724                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  2725                                                     new ListBuffer<JCTree>()).toList();
  2726                         storeEnd(defs.last(), S.endPos());
  2727                         accept(SEMI);
  2728                         return defs;
  2729                     } else {
  2730                         pos = S.pos();
  2731                         List<JCTree> err = isVoid
  2732                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  2733                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  2734                             : null;
  2735                         return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
  2742     /** MethodDeclaratorRest =
  2743      *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  2744      *  VoidMethodDeclaratorRest =
  2745      *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
  2746      *  InterfaceMethodDeclaratorRest =
  2747      *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
  2748      *  VoidInterfaceMethodDeclaratorRest =
  2749      *      FormalParameters [Annotations] [THROWS TypeList] ";"
  2750      *  ConstructorDeclaratorRest =
  2751      *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
  2752      */
  2753     JCTree methodDeclaratorRest(int pos,
  2754                               JCModifiers mods,
  2755                               JCExpression type,
  2756                               Name name,
  2757                               List<JCTypeParameter> typarams,
  2758                               boolean isInterface, boolean isVoid,
  2759                               String dc) {
  2760         List<JCVariableDecl> params = formalParameters();
  2762         List<JCTypeAnnotation> receiverAnnotations;
  2763         if (!isVoid) {
  2764             // need to distinguish between receiver anno and array anno
  2765             // look at typeAnnotationsPushedBack comment
  2766             this.permitTypeAnnotationsPushBack = true;
  2767             type = methodReturnArrayRest(type);
  2768             this.permitTypeAnnotationsPushBack = false;
  2769             if (typeAnnotationsPushedBack == null)
  2770                 receiverAnnotations = List.nil();
  2771             else
  2772                 receiverAnnotations = typeAnnotationsPushedBack;
  2773             typeAnnotationsPushedBack = null;
  2774         } else
  2775             receiverAnnotations = typeAnnotationsOpt();
  2777         List<JCExpression> thrown = List.nil();
  2778         if (S.token() == THROWS) {
  2779             S.nextToken();
  2780             thrown = qualidentList();
  2782         JCBlock body = null;
  2783         JCExpression defaultValue;
  2784         if (S.token() == LBRACE) {
  2785             body = block();
  2786             defaultValue = null;
  2787         } else {
  2788             if (S.token() == DEFAULT) {
  2789                 accept(DEFAULT);
  2790                 defaultValue = annotationValue();
  2791             } else {
  2792                 defaultValue = null;
  2794             accept(SEMI);
  2795             if (S.pos() <= errorEndPos) {
  2796                 // error recovery
  2797                 skip(false, true, false, false);
  2798                 if (S.token() == LBRACE) {
  2799                     body = block();
  2803         JCMethodDecl result =
  2804             toP(F.at(pos).MethodDef(mods, name, type, typarams,
  2805                                     params, receiverAnnotations, thrown,
  2806                                     body, defaultValue));
  2807         attach(result, dc);
  2808         return result;
  2811     /** Parses the array levels after the format parameters list, and append
  2812      * them to the return type, while preseving the order of type annotations
  2813      */
  2814     private JCExpression methodReturnArrayRest(JCExpression type) {
  2815         if (type.getTag() != JCTree.TYPEARRAY)
  2816             return bracketsOpt(type);
  2818         JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
  2819         while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
  2820             baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
  2822         if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
  2823             JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
  2824             at.underlyingType = bracketsOpt(at.underlyingType);
  2825         } else {
  2826             baseArray.elemtype = bracketsOpt(baseArray.elemtype);
  2829         return type;
  2832     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  2833      */
  2834     List<JCExpression> qualidentList() {
  2835         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  2837         List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
  2838         if (!typeAnnos.isEmpty())
  2839             ts.append(F.AnnotatedType(typeAnnos, qualident()));
  2840         else
  2841             ts.append(qualident());
  2842         while (S.token() == COMMA) {
  2843             S.nextToken();
  2845             typeAnnos = typeAnnotationsOpt();
  2846             if (!typeAnnos.isEmpty())
  2847                 ts.append(F.AnnotatedType(typeAnnos, qualident()));
  2848             else
  2849                 ts.append(qualident());
  2851         return ts.toList();
  2854     /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  2855      */
  2856     List<JCTypeParameter> typeParametersOpt() {
  2857         if (S.token() == LT) {
  2858             checkGenerics();
  2859             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  2860             S.nextToken();
  2861             typarams.append(typeParameter());
  2862             while (S.token() == COMMA) {
  2863                 S.nextToken();
  2864                 typarams.append(typeParameter());
  2866             accept(GT);
  2867             return typarams.toList();
  2868         } else {
  2869             return List.nil();
  2873     /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
  2874      *  TypeParameterBound = EXTENDS Type {"&" Type}
  2875      *  TypeVariable = Ident
  2876      */
  2877     JCTypeParameter typeParameter() {
  2878         int pos = S.pos();
  2879         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  2880         Name name = ident();
  2881         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  2882         if (S.token() == EXTENDS) {
  2883             S.nextToken();
  2884             bounds.append(parseType());
  2885             while (S.token() == AMP) {
  2886                 S.nextToken();
  2887                 bounds.append(parseType());
  2890         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
  2893     /** FormalParameters = "(" [ FormalParameterList ] ")"
  2894      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  2895      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  2896      */
  2897     List<JCVariableDecl> formalParameters() {
  2898         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  2899         JCVariableDecl lastParam = null;
  2900         accept(LPAREN);
  2901         if (S.token() != RPAREN) {
  2902             params.append(lastParam = formalParameter());
  2903             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
  2904                 S.nextToken();
  2905                 params.append(lastParam = formalParameter());
  2908         accept(RPAREN);
  2909         return params.toList();
  2912     JCModifiers optFinal(long flags) {
  2913         JCModifiers mods = modifiersOpt();
  2914         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  2915         mods.flags |= flags;
  2916         return mods;
  2919     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  2920      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  2921      */
  2922     JCVariableDecl formalParameter() {
  2923         JCModifiers mods = optFinal(Flags.PARAMETER);
  2924         // need to distinguish between vararg annos and array annos
  2925         // look at typeAnnotaitonsPushedBack comment
  2926         this.permitTypeAnnotationsPushBack = true;
  2927         JCExpression type = parseType();
  2928         this.permitTypeAnnotationsPushBack = false;
  2930         if (S.token() == ELLIPSIS) {
  2931             List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
  2932             typeAnnotationsPushedBack = null;
  2933             checkVarargs();
  2934             mods.flags |= Flags.VARARGS;
  2935             // insert var arg type annotations
  2936             if (varargsAnnos != null && varargsAnnos.nonEmpty())
  2937                 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
  2938             type = to(F.at(S.pos()).TypeArray(type));
  2940             S.nextToken();
  2941         } else {
  2942             // if not a var arg, then typeAnnotationsPushedBack should be null
  2943             if (typeAnnotationsPushedBack != null
  2944                     && !typeAnnotationsPushedBack.isEmpty()) {
  2945                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
  2946                         "illegal.start.of.type");
  2948             typeAnnotationsPushedBack = null;
  2950         return variableDeclaratorId(mods, type);
  2953 /* ---------- auxiliary methods -------------- */
  2955     /** Check that given tree is a legal expression statement.
  2956      */
  2957     protected JCExpression checkExprStat(JCExpression t) {
  2958         switch(t.getTag()) {
  2959         case JCTree.PREINC: case JCTree.PREDEC:
  2960         case JCTree.POSTINC: case JCTree.POSTDEC:
  2961         case JCTree.ASSIGN:
  2962         case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
  2963         case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
  2964         case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
  2965         case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
  2966         case JCTree.APPLY: case JCTree.NEWCLASS:
  2967         case JCTree.ERRONEOUS:
  2968             return t;
  2969         default:
  2970             log.error(t.pos, "not.stmt");
  2971             return F.at(t.pos).Erroneous(List.<JCTree>of(t));
  2975     /** Return precedence of operator represented by token,
  2976      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  2977      */
  2978     static int prec(Token token) {
  2979         int oc = optag(token);
  2980         return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
  2983     /** Return operation tag of binary operator represented by token,
  2984      *  -1 if token is not a binary operator.
  2985      */
  2986     static int optag(Token token) {
  2987         switch (token) {
  2988         case BARBAR:
  2989             return JCTree.OR;
  2990         case AMPAMP:
  2991             return JCTree.AND;
  2992         case BAR:
  2993             return JCTree.BITOR;
  2994         case BAREQ:
  2995             return JCTree.BITOR_ASG;
  2996         case CARET:
  2997             return JCTree.BITXOR;
  2998         case CARETEQ:
  2999             return JCTree.BITXOR_ASG;
  3000         case AMP:
  3001             return JCTree.BITAND;
  3002         case AMPEQ:
  3003             return JCTree.BITAND_ASG;
  3004         case EQEQ:
  3005             return JCTree.EQ;
  3006         case BANGEQ:
  3007             return JCTree.NE;
  3008         case LT:
  3009             return JCTree.LT;
  3010         case GT:
  3011             return JCTree.GT;
  3012         case LTEQ:
  3013             return JCTree.LE;
  3014         case GTEQ:
  3015             return JCTree.GE;
  3016         case LTLT:
  3017             return JCTree.SL;
  3018         case LTLTEQ:
  3019             return JCTree.SL_ASG;
  3020         case GTGT:
  3021             return JCTree.SR;
  3022         case GTGTEQ:
  3023             return JCTree.SR_ASG;
  3024         case GTGTGT:
  3025             return JCTree.USR;
  3026         case GTGTGTEQ:
  3027             return JCTree.USR_ASG;
  3028         case PLUS:
  3029             return JCTree.PLUS;
  3030         case PLUSEQ:
  3031             return JCTree.PLUS_ASG;
  3032         case SUB:
  3033             return JCTree.MINUS;
  3034         case SUBEQ:
  3035             return JCTree.MINUS_ASG;
  3036         case STAR:
  3037             return JCTree.MUL;
  3038         case STAREQ:
  3039             return JCTree.MUL_ASG;
  3040         case SLASH:
  3041             return JCTree.DIV;
  3042         case SLASHEQ:
  3043             return JCTree.DIV_ASG;
  3044         case PERCENT:
  3045             return JCTree.MOD;
  3046         case PERCENTEQ:
  3047             return JCTree.MOD_ASG;
  3048         case INSTANCEOF:
  3049             return JCTree.TYPETEST;
  3050         default:
  3051             return -1;
  3055     /** Return operation tag of unary operator represented by token,
  3056      *  -1 if token is not a binary operator.
  3057      */
  3058     static int unoptag(Token token) {
  3059         switch (token) {
  3060         case PLUS:
  3061             return JCTree.POS;
  3062         case SUB:
  3063             return JCTree.NEG;
  3064         case BANG:
  3065             return JCTree.NOT;
  3066         case TILDE:
  3067             return JCTree.COMPL;
  3068         case PLUSPLUS:
  3069             return JCTree.PREINC;
  3070         case SUBSUB:
  3071             return JCTree.PREDEC;
  3072         default:
  3073             return -1;
  3077     /** Return type tag of basic type represented by token,
  3078      *  -1 if token is not a basic type identifier.
  3079      */
  3080     static int typetag(Token token) {
  3081         switch (token) {
  3082         case BYTE:
  3083             return TypeTags.BYTE;
  3084         case CHAR:
  3085             return TypeTags.CHAR;
  3086         case SHORT:
  3087             return TypeTags.SHORT;
  3088         case INT:
  3089             return TypeTags.INT;
  3090         case LONG:
  3091             return TypeTags.LONG;
  3092         case FLOAT:
  3093             return TypeTags.FLOAT;
  3094         case DOUBLE:
  3095             return TypeTags.DOUBLE;
  3096         case BOOLEAN:
  3097             return TypeTags.BOOLEAN;
  3098         default:
  3099             return -1;
  3103     void checkGenerics() {
  3104         if (!allowGenerics) {
  3105             log.error(S.pos(), "generics.not.supported.in.source", source.name);
  3106             allowGenerics = true;
  3109     void checkVarargs() {
  3110         if (!allowVarargs) {
  3111             log.error(S.pos(), "varargs.not.supported.in.source", source.name);
  3112             allowVarargs = true;
  3115     void checkForeach() {
  3116         if (!allowForeach) {
  3117             log.error(S.pos(), "foreach.not.supported.in.source", source.name);
  3118             allowForeach = true;
  3121     void checkStaticImports() {
  3122         if (!allowStaticImport) {
  3123             log.error(S.pos(), "static.import.not.supported.in.source", source.name);
  3124             allowStaticImport = true;
  3127     void checkAnnotations() {
  3128         if (!allowAnnotations) {
  3129             log.error(S.pos(), "annotations.not.supported.in.source", source.name);
  3130             allowAnnotations = true;
  3133     void checkTypeAnnotations() {
  3134         if (!allowTypeAnnotations) {
  3135             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
  3136             allowTypeAnnotations = true;

mercurial