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

Tue, 25 May 2010 15:54:51 -0700

author
ohair
date
Tue, 25 May 2010 15:54:51 -0700
changeset 554
9d9f26857129
parent 550
a6f2911a7c55
child 581
f2fdd52e4e87
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

     1 /*
     2  * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package com.sun.tools.javac.parser;
    28 import java.util.*;
    30 import com.sun.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.allowDiamond = source.allowDiamond();
   135         this.allowMulticatch = source.allowMulticatch();
   136         this.allowTypeAnnotations = source.allowTypeAnnotations();
   137         this.keepDocComments = keepDocComments;
   138         if (keepDocComments)
   139             docComments = new HashMap<JCTree,String>();
   140         this.keepLineMap = keepLineMap;
   141         this.errorTree = F.Erroneous();
   142         this.debugJSR308 = fac.options.get("TA:parser") != null;
   143     }
   145     /** Switch: debug output for type-annotations operations
   146      */
   147     boolean debugJSR308;
   149     /** Switch: Should generics be recognized?
   150      */
   151     boolean allowGenerics;
   153     /** Switch: Should diamond operator be recognized?
   154      */
   155     boolean allowDiamond;
   157     /** Switch: Should multicatch clause be accepted?
   158      */
   159     boolean allowMulticatch;
   161     /** Switch: Should varargs be recognized?
   162      */
   163     boolean allowVarargs;
   165     /** Switch: should we recognize assert statements, or just give a warning?
   166      */
   167     boolean allowAsserts;
   169     /** Switch: should we recognize enums, or just give a warning?
   170      */
   171     boolean allowEnums;
   173     /** Switch: should we recognize foreach?
   174      */
   175     boolean allowForeach;
   177     /** Switch: should we recognize foreach?
   178      */
   179     boolean allowStaticImport;
   181     /** Switch: should we recognize annotations?
   182      */
   183     boolean allowAnnotations;
   185     /** Switch: should we recognize type annotations?
   186      */
   187     boolean allowTypeAnnotations;
   189     /** Switch: should we keep docComments?
   190      */
   191     boolean keepDocComments;
   193     /** Switch: should we keep line table?
   194      */
   195     boolean keepLineMap;
   197     /** When terms are parsed, the mode determines which is expected:
   198      *     mode = EXPR        : an expression
   199      *     mode = TYPE        : a type
   200      *     mode = NOPARAMS    : no parameters allowed for type
   201      *     mode = TYPEARG     : type argument
   202      */
   203     static final int EXPR = 0x1;
   204     static final int TYPE = 0x2;
   205     static final int NOPARAMS = 0x4;
   206     static final int TYPEARG = 0x8;
   207     static final int DIAMOND = 0x10;
   209     /** The current mode.
   210      */
   211     private int mode = 0;
   213     /** The mode of the term that was parsed last.
   214      */
   215     private int lastmode = 0;
   217 /* ---------- error recovery -------------- */
   219     private JCErroneous errorTree;
   221     /** Skip forward until a suitable stop token is found.
   222      */
   223     private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   224          while (true) {
   225              switch (S.token()) {
   226                 case SEMI:
   227                     S.nextToken();
   228                     return;
   229                 case PUBLIC:
   230                 case FINAL:
   231                 case ABSTRACT:
   232                 case MONKEYS_AT:
   233                 case EOF:
   234                 case CLASS:
   235                 case INTERFACE:
   236                 case ENUM:
   237                     return;
   238                 case IMPORT:
   239                     if (stopAtImport)
   240                         return;
   241                     break;
   242                 case LBRACE:
   243                 case RBRACE:
   244                 case PRIVATE:
   245                 case PROTECTED:
   246                 case STATIC:
   247                 case TRANSIENT:
   248                 case NATIVE:
   249                 case VOLATILE:
   250                 case SYNCHRONIZED:
   251                 case STRICTFP:
   252                 case LT:
   253                 case BYTE:
   254                 case SHORT:
   255                 case CHAR:
   256                 case INT:
   257                 case LONG:
   258                 case FLOAT:
   259                 case DOUBLE:
   260                 case BOOLEAN:
   261                 case VOID:
   262                     if (stopAtMemberDecl)
   263                         return;
   264                     break;
   265                 case IDENTIFIER:
   266                    if (stopAtIdentifier)
   267                         return;
   268                     break;
   269                 case CASE:
   270                 case DEFAULT:
   271                 case IF:
   272                 case FOR:
   273                 case WHILE:
   274                 case DO:
   275                 case TRY:
   276                 case SWITCH:
   277                 case RETURN:
   278                 case THROW:
   279                 case BREAK:
   280                 case CONTINUE:
   281                 case ELSE:
   282                 case FINALLY:
   283                 case CATCH:
   284                     if (stopAtStatement)
   285                         return;
   286                     break;
   287             }
   288             S.nextToken();
   289         }
   290     }
   292     private JCErroneous syntaxError(int pos, String key, Token... args) {
   293         return syntaxError(pos, null, key, args);
   294     }
   296     private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
   297         setErrorEndPos(pos);
   298         reportSyntaxError(pos, key, (Object[])args);
   299         return toP(F.at(pos).Erroneous(errs));
   300     }
   302     private int errorPos = Position.NOPOS;
   303     /**
   304      * Report a syntax error at given position using the given
   305      * argument unless one was already reported at the same position.
   306      */
   307     private void reportSyntaxError(int pos, String key, Object... args) {
   308         if (pos > S.errPos() || pos == Position.NOPOS) {
   309             if (S.token() == EOF)
   310                 log.error(pos, "premature.eof");
   311             else
   312                 log.error(pos, key, args);
   313         }
   314         S.errPos(pos);
   315         if (S.pos() == errorPos)
   316             S.nextToken(); // guarantee progress
   317         errorPos = S.pos();
   318     }
   321     /** Generate a syntax error at current position unless one was already
   322      *  reported at the same position.
   323      */
   324     private JCErroneous syntaxError(String key) {
   325         return syntaxError(S.pos(), key);
   326     }
   328     /** Generate a syntax error at current position unless one was
   329      *  already reported at the same position.
   330      */
   331     private JCErroneous syntaxError(String key, Token arg) {
   332         return syntaxError(S.pos(), key, arg);
   333     }
   335     /** If next input token matches given token, skip it, otherwise report
   336      *  an error.
   337      */
   338     public void accept(Token token) {
   339         if (S.token() == token) {
   340             S.nextToken();
   341         } else {
   342             setErrorEndPos(S.pos());
   343             reportSyntaxError(S.prevEndPos(), "expected", token);
   344         }
   345     }
   347     /** Report an illegal start of expression/type error at given position.
   348      */
   349     JCExpression illegal(int pos) {
   350         setErrorEndPos(S.pos());
   351         if ((mode & EXPR) != 0)
   352             return syntaxError(pos, "illegal.start.of.expr");
   353         else
   354             return syntaxError(pos, "illegal.start.of.type");
   356     }
   358     /** Report an illegal start of expression/type error at current position.
   359      */
   360     JCExpression illegal() {
   361         return illegal(S.pos());
   362     }
   364     /** Diagnose a modifier flag from the set, if any. */
   365     void checkNoMods(long mods) {
   366         if (mods != 0) {
   367             long lowestMod = mods & -mods;
   368             log.error(S.pos(), "mod.not.allowed.here",
   369                       Flags.asFlagSet(lowestMod));
   370         }
   371     }
   373 /* ---------- doc comments --------- */
   375     /** A hashtable to store all documentation comments
   376      *  indexed by the tree nodes they refer to.
   377      *  defined only if option flag keepDocComment is set.
   378      */
   379     Map<JCTree, String> docComments;
   381     /** Make an entry into docComments hashtable,
   382      *  provided flag keepDocComments is set and given doc comment is non-null.
   383      *  @param tree   The tree to be used as index in the hashtable
   384      *  @param dc     The doc comment to associate with the tree, or null.
   385      */
   386     void attach(JCTree tree, String dc) {
   387         if (keepDocComments && dc != null) {
   388 //          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   389             docComments.put(tree, dc);
   390         }
   391     }
   393 /* -------- source positions ------- */
   395     private int errorEndPos = -1;
   397     private void setErrorEndPos(int errPos) {
   398         if (errPos > errorEndPos)
   399             errorEndPos = errPos;
   400     }
   402     protected int getErrorEndPos() {
   403         return errorEndPos;
   404     }
   406     /**
   407      * Store ending position for a tree.
   408      * @param tree   The tree.
   409      * @param endpos The ending position to associate with the tree.
   410      */
   411     protected void storeEnd(JCTree tree, int endpos) {}
   413     /**
   414      * Store ending position for a tree.  The ending position should
   415      * be the ending position of the current token.
   416      * @param t The tree.
   417      */
   418     protected <T extends JCTree> T to(T t) { return t; }
   420     /**
   421      * Store ending position for a tree.  The ending position should
   422      * be greater of the ending position of the previous token and errorEndPos.
   423      * @param t The tree.
   424      */
   425     protected <T extends JCTree> T toP(T t) { return t; }
   427     /** Get the start position for a tree node.  The start position is
   428      * defined to be the position of the first character of the first
   429      * token of the node's source text.
   430      * @param tree  The tree node
   431      */
   432     public int getStartPos(JCTree tree) {
   433         return TreeInfo.getStartPos(tree);
   434     }
   436     /**
   437      * Get the end position for a tree node.  The end position is
   438      * defined to be the position of the last character of the last
   439      * token of the node's source text.  Returns Position.NOPOS if end
   440      * positions are not generated or the position is otherwise not
   441      * found.
   442      * @param tree  The tree node
   443      */
   444     public int getEndPos(JCTree tree) {
   445         return Position.NOPOS;
   446     }
   450 /* ---------- parsing -------------- */
   452     /**
   453      * Ident = IDENTIFIER
   454      */
   455     Name ident() {
   456         if (S.token() == IDENTIFIER) {
   457             Name name = S.name();
   458             S.nextToken();
   459             return name;
   460         } else if (S.token() == ASSERT) {
   461             if (allowAsserts) {
   462                 log.error(S.pos(), "assert.as.identifier");
   463                 S.nextToken();
   464                 return names.error;
   465             } else {
   466                 log.warning(S.pos(), "assert.as.identifier");
   467                 Name name = S.name();
   468                 S.nextToken();
   469                 return name;
   470             }
   471         } else if (S.token() == ENUM) {
   472             if (allowEnums) {
   473                 log.error(S.pos(), "enum.as.identifier");
   474                 S.nextToken();
   475                 return names.error;
   476             } else {
   477                 log.warning(S.pos(), "enum.as.identifier");
   478                 Name name = S.name();
   479                 S.nextToken();
   480                 return name;
   481             }
   482         } else {
   483             accept(IDENTIFIER);
   484             return names.error;
   485         }
   486 }
   488     /**
   489      * Qualident = Ident { DOT Ident }
   490      */
   491     public JCExpression qualident() {
   492         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
   493         while (S.token() == DOT) {
   494             int pos = S.pos();
   495             S.nextToken();
   496             t = toP(F.at(pos).Select(t, ident()));
   497         }
   498         return t;
   499     }
   501     /**
   502      * Literal =
   503      *     INTLITERAL
   504      *   | LONGLITERAL
   505      *   | FLOATLITERAL
   506      *   | DOUBLELITERAL
   507      *   | CHARLITERAL
   508      *   | STRINGLITERAL
   509      *   | TRUE
   510      *   | FALSE
   511      *   | NULL
   512      */
   513     JCExpression literal(Name prefix) {
   514         int pos = S.pos();
   515         JCExpression t = errorTree;
   516         switch (S.token()) {
   517         case INTLITERAL:
   518             try {
   519                 t = F.at(pos).Literal(
   520                     TypeTags.INT,
   521                     Convert.string2int(strval(prefix), S.radix()));
   522             } catch (NumberFormatException ex) {
   523                 log.error(S.pos(), "int.number.too.large", strval(prefix));
   524             }
   525             break;
   526         case LONGLITERAL:
   527             try {
   528                 t = F.at(pos).Literal(
   529                     TypeTags.LONG,
   530                     new Long(Convert.string2long(strval(prefix), S.radix())));
   531             } catch (NumberFormatException ex) {
   532                 log.error(S.pos(), "int.number.too.large", strval(prefix));
   533             }
   534             break;
   535         case FLOATLITERAL: {
   536             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   537             Float n;
   538             try {
   539                 n = Float.valueOf(proper);
   540             } catch (NumberFormatException ex) {
   541                 // error already repoted in scanner
   542                 n = Float.NaN;
   543             }
   544             if (n.floatValue() == 0.0f && !isZero(proper))
   545                 log.error(S.pos(), "fp.number.too.small");
   546             else if (n.floatValue() == Float.POSITIVE_INFINITY)
   547                 log.error(S.pos(), "fp.number.too.large");
   548             else
   549                 t = F.at(pos).Literal(TypeTags.FLOAT, n);
   550             break;
   551         }
   552         case DOUBLELITERAL: {
   553             String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   554             Double n;
   555             try {
   556                 n = Double.valueOf(proper);
   557             } catch (NumberFormatException ex) {
   558                 // error already reported in scanner
   559                 n = Double.NaN;
   560             }
   561             if (n.doubleValue() == 0.0d && !isZero(proper))
   562                 log.error(S.pos(), "fp.number.too.small");
   563             else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   564                 log.error(S.pos(), "fp.number.too.large");
   565             else
   566                 t = F.at(pos).Literal(TypeTags.DOUBLE, n);
   567             break;
   568         }
   569         case CHARLITERAL:
   570             t = F.at(pos).Literal(
   571                 TypeTags.CHAR,
   572                 S.stringVal().charAt(0) + 0);
   573             break;
   574         case STRINGLITERAL:
   575             t = F.at(pos).Literal(
   576                 TypeTags.CLASS,
   577                 S.stringVal());
   578             break;
   579         case TRUE: case FALSE:
   580             t = F.at(pos).Literal(
   581                 TypeTags.BOOLEAN,
   582                 (S.token() == TRUE ? 1 : 0));
   583             break;
   584         case NULL:
   585             t = F.at(pos).Literal(
   586                 TypeTags.BOT,
   587                 null);
   588             break;
   589         default:
   590             assert false;
   591         }
   592         if (t == errorTree)
   593             t = F.at(pos).Erroneous();
   594         storeEnd(t, S.endPos());
   595         S.nextToken();
   596         return t;
   597     }
   598 //where
   599         boolean isZero(String s) {
   600             char[] cs = s.toCharArray();
   601             int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
   602             int i = ((base==16) ? 2 : 0);
   603             while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   604             return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   605         }
   607         String strval(Name prefix) {
   608             String s = S.stringVal();
   609             return prefix.isEmpty() ? s : prefix + s;
   610         }
   612     /** terms can be either expressions or types.
   613      */
   614     public JCExpression parseExpression() {
   615         return term(EXPR);
   616     }
   618     /**
   619      * parses (optional) type annotations followed by a type. If the
   620      * annotations are present before the type and are not consumed during array
   621      * parsing, this method returns a {@link JCAnnotatedType} consisting of
   622      * these annotations and the underlying type. Otherwise, it returns the
   623      * underlying type.
   624      *
   625      * <p>
   626      *
   627      * Note that this method sets {@code mode} to {@code TYPE} first, before
   628      * parsing annotations.
   629      */
   630     public JCExpression parseType() {
   631         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
   632         return parseType(annotations);
   633     }
   635     public JCExpression parseType(List<JCTypeAnnotation> annotations) {
   636         JCExpression result = unannotatedType();
   638         if (!annotations.isEmpty())
   639             result = F.AnnotatedType(annotations, result);
   641         return result;
   642     }
   644     public JCExpression unannotatedType() {
   645         return term(TYPE);
   646     }
   648     JCExpression term(int newmode) {
   649         int prevmode = mode;
   650         mode = newmode;
   651         JCExpression t = term();
   652         lastmode = mode;
   653         mode = prevmode;
   654         return t;
   655     }
   657     /**
   658      *  Expression = Expression1 [ExpressionRest]
   659      *  ExpressionRest = [AssignmentOperator Expression1]
   660      *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   661      *                       "&=" | "|=" | "^=" |
   662      *                       "%=" | "<<=" | ">>=" | ">>>="
   663      *  Type = Type1
   664      *  TypeNoParams = TypeNoParams1
   665      *  StatementExpression = Expression
   666      *  ConstantExpression = Expression
   667      */
   668     JCExpression term() {
   669         JCExpression t = term1();
   670         if ((mode & EXPR) != 0 &&
   671             S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
   672             return termRest(t);
   673         else
   674             return t;
   675     }
   677     JCExpression termRest(JCExpression t) {
   678         switch (S.token()) {
   679         case EQ: {
   680             int pos = S.pos();
   681             S.nextToken();
   682             mode = EXPR;
   683             JCExpression t1 = term();
   684             return toP(F.at(pos).Assign(t, t1));
   685         }
   686         case PLUSEQ:
   687         case SUBEQ:
   688         case STAREQ:
   689         case SLASHEQ:
   690         case PERCENTEQ:
   691         case AMPEQ:
   692         case BAREQ:
   693         case CARETEQ:
   694         case LTLTEQ:
   695         case GTGTEQ:
   696         case GTGTGTEQ:
   697             int pos = S.pos();
   698             Token token = S.token();
   699             S.nextToken();
   700             mode = EXPR;
   701             JCExpression t1 = term();
   702             return F.at(pos).Assignop(optag(token), t, t1);
   703         default:
   704             return t;
   705         }
   706     }
   708     /** Expression1   = Expression2 [Expression1Rest]
   709      *  Type1         = Type2
   710      *  TypeNoParams1 = TypeNoParams2
   711      */
   712     JCExpression term1() {
   713         JCExpression t = term2();
   714         if ((mode & EXPR) != 0 && S.token() == QUES) {
   715             mode = EXPR;
   716             return term1Rest(t);
   717         } else {
   718             return t;
   719         }
   720     }
   722     /** Expression1Rest = ["?" Expression ":" Expression1]
   723      */
   724     JCExpression term1Rest(JCExpression t) {
   725         if (S.token() == QUES) {
   726             int pos = S.pos();
   727             S.nextToken();
   728             JCExpression t1 = term();
   729             accept(COLON);
   730             JCExpression t2 = term1();
   731             return F.at(pos).Conditional(t, t1, t2);
   732         } else {
   733             return t;
   734         }
   735     }
   737     /** Expression2   = Expression3 [Expression2Rest]
   738      *  Type2         = Type3
   739      *  TypeNoParams2 = TypeNoParams3
   740      */
   741     JCExpression term2() {
   742         JCExpression t = term3();
   743         if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
   744             mode = EXPR;
   745             return term2Rest(t, TreeInfo.orPrec);
   746         } else {
   747             return t;
   748         }
   749     }
   751     /*  Expression2Rest = {infixop Expression3}
   752      *                  | Expression3 instanceof Type
   753      *  infixop         = "||"
   754      *                  | "&&"
   755      *                  | "|"
   756      *                  | "^"
   757      *                  | "&"
   758      *                  | "==" | "!="
   759      *                  | "<" | ">" | "<=" | ">="
   760      *                  | "<<" | ">>" | ">>>"
   761      *                  | "+" | "-"
   762      *                  | "*" | "/" | "%"
   763      */
   764     JCExpression term2Rest(JCExpression t, int minprec) {
   765         List<JCExpression[]> savedOd = odStackSupply.elems;
   766         JCExpression[] odStack = newOdStack();
   767         List<Token[]> savedOp = opStackSupply.elems;
   768         Token[] opStack = newOpStack();
   769         List<int[]> savedPos = posStackSupply.elems;
   770         int[] posStack = newPosStack();
   771         // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   772         int top = 0;
   773         odStack[0] = t;
   774         int startPos = S.pos();
   775         Token topOp = ERROR;
   776         int topOpPos = Position.NOPOS;
   777         while (prec(S.token()) >= minprec) {
   778             posStack[top] = topOpPos;
   779             opStack[top] = topOp;
   780             top++;
   781             topOp = S.token();
   782             topOpPos = S.pos();
   783             S.nextToken();
   784             odStack[top] = (topOp == INSTANCEOF) ? parseType() : term3();
   785             while (top > 0 && prec(topOp) >= prec(S.token())) {
   786                 odStack[top-1] = makeOp(topOpPos, topOp, odStack[top-1],
   787                                         odStack[top]);
   788                 top--;
   789                 topOp = opStack[top];
   790                 topOpPos = posStack[top];
   791             }
   792         }
   793         assert top == 0;
   794         t = odStack[0];
   796         if (t.getTag() == JCTree.PLUS) {
   797             StringBuffer buf = foldStrings(t);
   798             if (buf != null) {
   799                 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
   800             }
   801         }
   803         odStackSupply.elems = savedOd; // optimization
   804         opStackSupply.elems = savedOp; // optimization
   805         posStackSupply.elems = savedPos; // optimization
   806         return t;
   807     }
   808 //where
   809         /** Construct a binary or type test node.
   810          */
   811         private JCExpression makeOp(int pos,
   812                                     Token topOp,
   813                                     JCExpression od1,
   814                                     JCExpression od2)
   815         {
   816             if (topOp == INSTANCEOF) {
   817                 return F.at(pos).TypeTest(od1, od2);
   818             } else {
   819                 return F.at(pos).Binary(optag(topOp), od1, od2);
   820             }
   821         }
   822         /** If tree is a concatenation of string literals, replace it
   823          *  by a single literal representing the concatenated string.
   824          */
   825         protected StringBuffer foldStrings(JCTree tree) {
   826             List<String> buf = List.nil();
   827             while (true) {
   828                 if (tree.getTag() == JCTree.LITERAL) {
   829                     JCLiteral lit = (JCLiteral) tree;
   830                     if (lit.typetag == TypeTags.CLASS) {
   831                         StringBuffer sbuf =
   832                             new StringBuffer((String)lit.value);
   833                         while (buf.nonEmpty()) {
   834                             sbuf.append(buf.head);
   835                             buf = buf.tail;
   836                         }
   837                         return sbuf;
   838                     }
   839                 } else if (tree.getTag() == JCTree.PLUS) {
   840                     JCBinary op = (JCBinary)tree;
   841                     if (op.rhs.getTag() == JCTree.LITERAL) {
   842                         JCLiteral lit = (JCLiteral) op.rhs;
   843                         if (lit.typetag == TypeTags.CLASS) {
   844                             buf = buf.prepend((String) lit.value);
   845                             tree = op.lhs;
   846                             continue;
   847                         }
   848                     }
   849                 }
   850                 return null;
   851             }
   852         }
   854         /** optimization: To save allocating a new operand/operator stack
   855          *  for every binary operation, we use supplys.
   856          */
   857         ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
   858         ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
   859         ListBuffer<int[]> posStackSupply = new ListBuffer<int[]>();
   861         private JCExpression[] newOdStack() {
   862             if (odStackSupply.elems == odStackSupply.last)
   863                 odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
   864             JCExpression[] odStack = odStackSupply.elems.head;
   865             odStackSupply.elems = odStackSupply.elems.tail;
   866             return odStack;
   867         }
   869         private Token[] newOpStack() {
   870             if (opStackSupply.elems == opStackSupply.last)
   871                 opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
   872             Token[] opStack = opStackSupply.elems.head;
   873             opStackSupply.elems = opStackSupply.elems.tail;
   874             return opStack;
   875         }
   877         private int[] newPosStack() {
   878             if (posStackSupply.elems == posStackSupply.last)
   879                 posStackSupply.append(new int[infixPrecedenceLevels + 1]);
   880             int[] posStack = posStackSupply.elems.head;
   881             posStackSupply.elems = posStackSupply.elems.tail;
   882             return posStack;
   883         }
   885     /** Expression3    = PrefixOp Expression3
   886      *                 | "(" Expr | TypeNoParams ")" Expression3
   887      *                 | Primary {Selector} {PostfixOp}
   888      *  Primary        = "(" Expression ")"
   889      *                 | Literal
   890      *                 | [TypeArguments] THIS [Arguments]
   891      *                 | [TypeArguments] SUPER SuperSuffix
   892      *                 | NEW [TypeArguments] Creator
   893      *                 | [Annotations] Ident { "." Ident }
   894      *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   895      *                   | Arguments
   896      *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
   897      *                   ]
   898      *                 | BasicType BracketsOpt "." CLASS
   899      *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
   900      *  PostfixOp      = "++" | "--"
   901      *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
   902      *                 | BasicType
   903      *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
   904      *  Selector       = "." [TypeArguments] Ident [Arguments]
   905      *                 | "." THIS
   906      *                 | "." [TypeArguments] SUPER SuperSuffix
   907      *                 | "." NEW [TypeArguments] InnerCreator
   908      *                 | "[" Expression "]"
   909      *  TypeSelector   = "." Ident [TypeArguments]
   910      *  SuperSuffix    = Arguments | "." Ident [Arguments]
   911      */
   912     protected JCExpression term3() {
   913         int pos = S.pos();
   914         JCExpression t;
   915         List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
   916         switch (S.token()) {
   917         case QUES:
   918             if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
   919                 mode = TYPE;
   920                 return typeArgument();
   921             } else
   922                 return illegal();
   923         case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
   924             if (typeArgs == null && (mode & EXPR) != 0) {
   925                 Token token = S.token();
   926                 S.nextToken();
   927                 mode = EXPR;
   928                 if (token == SUB &&
   929                     (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
   930                     S.radix() == 10) {
   931                     mode = EXPR;
   932                     t = literal(names.hyphen);
   933                 } else {
   934                     t = term3();
   935                     return F.at(pos).Unary(unoptag(token), t);
   936                 }
   937             } else return illegal();
   938             break;
   939         case LPAREN:
   940             if (typeArgs == null && (mode & EXPR) != 0) {
   941                 S.nextToken();
   942                 mode = EXPR | TYPE | NOPARAMS;
   943                 t = term3();
   944                 if ((mode & TYPE) != 0 && S.token() == LT) {
   945                     // Could be a cast to a parameterized type
   946                     int op = JCTree.LT;
   947                     int pos1 = S.pos();
   948                     S.nextToken();
   949                     mode &= (EXPR | TYPE);
   950                     mode |= TYPEARG;
   951                     JCExpression t1 = term3();
   952                     if ((mode & TYPE) != 0 &&
   953                         (S.token() == COMMA || S.token() == GT)) {
   954                         mode = TYPE;
   955                         ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
   956                         args.append(t1);
   957                         while (S.token() == COMMA) {
   958                             S.nextToken();
   959                             args.append(typeArgument());
   960                         }
   961                         accept(GT);
   962                         t = toP(F.at(pos1).TypeApply(t, args.toList()));
   963                         checkGenerics();
   964                         while (S.token() == DOT) {
   965                             S.nextToken();
   966                             mode = TYPE;
   967                             t = toP(F.at(S.pos()).Select(t, ident()));
   968                             t = typeArgumentsOpt(t);
   969                         }
   970                         t = bracketsOpt(toP(t));
   971                     } else if ((mode & EXPR) != 0) {
   972                         mode = EXPR;
   973                         JCExpression e = term2Rest(t1, TreeInfo.shiftPrec);
   974                         t = F.at(pos1).Binary(op, t, e);
   975                         t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   976                     } else {
   977                         accept(GT);
   978                     }
   979                 }
   980                 else {
   981                     t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   982                 }
   983                 accept(RPAREN);
   984                 lastmode = mode;
   985                 mode = EXPR;
   986                 if ((lastmode & EXPR) == 0) {
   987                     JCExpression t1 = term3();
   988                     return F.at(pos).TypeCast(t, t1);
   989                 } else if ((lastmode & TYPE) != 0) {
   990                     switch (S.token()) {
   991                     /*case PLUSPLUS: case SUBSUB: */
   992                     case BANG: case TILDE:
   993                     case LPAREN: case THIS: case SUPER:
   994                     case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
   995                     case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
   996                     case TRUE: case FALSE: case NULL:
   997                     case NEW: case IDENTIFIER: case ASSERT: case ENUM:
   998                     case BYTE: case SHORT: case CHAR: case INT:
   999                     case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
  1000                         JCExpression t1 = term3();
  1001                         return F.at(pos).TypeCast(t, t1);
  1004             } else return illegal();
  1005             t = toP(F.at(pos).Parens(t));
  1006             break;
  1007         case THIS:
  1008             if ((mode & EXPR) != 0) {
  1009                 mode = EXPR;
  1010                 t = to(F.at(pos).Ident(names._this));
  1011                 S.nextToken();
  1012                 if (typeArgs == null)
  1013                     t = argumentsOpt(null, t);
  1014                 else
  1015                     t = arguments(typeArgs, t);
  1016                 typeArgs = null;
  1017             } else return illegal();
  1018             break;
  1019         case SUPER:
  1020             if ((mode & EXPR) != 0) {
  1021                 mode = EXPR;
  1022                 t = to(F.at(pos).Ident(names._super));
  1023                 t = superSuffix(typeArgs, t);
  1024                 typeArgs = null;
  1025             } else return illegal();
  1026             break;
  1027         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
  1028         case CHARLITERAL: case STRINGLITERAL:
  1029         case TRUE: case FALSE: case NULL:
  1030             if (typeArgs == null && (mode & EXPR) != 0) {
  1031                 mode = EXPR;
  1032                 t = literal(names.empty);
  1033             } else return illegal();
  1034             break;
  1035         case NEW:
  1036             if (typeArgs != null) return illegal();
  1037             if ((mode & EXPR) != 0) {
  1038                 mode = EXPR;
  1039                 S.nextToken();
  1040                 if (S.token() == LT) typeArgs = typeArguments();
  1041                 t = creator(pos, typeArgs);
  1042                 typeArgs = null;
  1043             } else return illegal();
  1044             break;
  1045         case MONKEYS_AT:
  1047             // only annotated targetting class literals or cast types are valid
  1048             List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
  1049             if (typeAnnos.isEmpty()) {
  1050                 // else there would be no '@'
  1051                 throw new AssertionError("type annos is empty");
  1054             JCExpression expr = term3();
  1056             // Type annotations: If term3 just parsed a non-type, expect a
  1057             // class literal (and issue a syntax error if there is no class
  1058             // literal). Otherwise, create a JCAnnotatedType.
  1059             if ((mode & TYPE) == 0) {
  1060                 if (expr.getTag() != JCTree.SELECT)
  1061                     return illegal(typeAnnos.head.pos);
  1062                 JCFieldAccess sel = (JCFieldAccess)expr;
  1063                 if (sel.name != names._class)
  1064                     return illegal();
  1065                 else {
  1066                     sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
  1067                     t = expr;
  1069             } else {
  1070                 // type annotation targeting a cast
  1071                 t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
  1073             break;
  1074         case IDENTIFIER: case ASSERT: case ENUM:
  1075             if (typeArgs != null) return illegal();
  1076             t = toP(F.at(S.pos()).Ident(ident()));
  1077             loop: while (true) {
  1078                 pos = S.pos();
  1079                 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1081                 // need to report an error later if LBRACKET is for array
  1082                 // index access rather than array creation level
  1083                 if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
  1084                     return illegal(annos.head.pos);
  1085                 switch (S.token()) {
  1086                 case LBRACKET:
  1087                     S.nextToken();
  1089                     if (S.token() == RBRACKET) {
  1091                         S.nextToken();
  1093                         t = bracketsOpt(t, annos);
  1094                         t = toP(F.at(pos).TypeArray(t));
  1095                         t = bracketsSuffix(t);
  1096                     } else {
  1097                         if ((mode & EXPR) != 0) {
  1098                             mode = EXPR;
  1099                             JCExpression t1 = term();
  1100                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1101                             t = to(F.at(pos).Indexed(t, t1));
  1103                         accept(RBRACKET);
  1105                     break loop;
  1106                 case LPAREN:
  1107                     if ((mode & EXPR) != 0) {
  1108                         mode = EXPR;
  1109                         t = arguments(typeArgs, t);
  1110                         typeArgs = null;
  1112                     break loop;
  1113                 case DOT:
  1114                     S.nextToken();
  1115                     int oldmode = mode;
  1116                     mode &= ~NOPARAMS;
  1117                     typeArgs = typeArgumentsOpt(EXPR);
  1118                     mode = oldmode;
  1119                     if ((mode & EXPR) != 0) {
  1120                         switch (S.token()) {
  1121                         case CLASS:
  1122                             if (typeArgs != null) return illegal();
  1123                             mode = EXPR;
  1124                             t = to(F.at(pos).Select(t, names._class));
  1125                             S.nextToken();
  1126                             break loop;
  1127                         case THIS:
  1128                             if (typeArgs != null) return illegal();
  1129                             mode = EXPR;
  1130                             t = to(F.at(pos).Select(t, names._this));
  1131                             S.nextToken();
  1132                             break loop;
  1133                         case SUPER:
  1134                             mode = EXPR;
  1135                             t = to(F.at(pos).Select(t, names._super));
  1136                             t = superSuffix(typeArgs, t);
  1137                             typeArgs = null;
  1138                             break loop;
  1139                         case NEW:
  1140                             if (typeArgs != null) return illegal();
  1141                             mode = EXPR;
  1142                             int pos1 = S.pos();
  1143                             S.nextToken();
  1144                             if (S.token() == LT) typeArgs = typeArguments();
  1145                             t = innerCreator(pos1, typeArgs, t);
  1146                             typeArgs = null;
  1147                             break loop;
  1150                     // typeArgs saved for next loop iteration.
  1151                     t = toP(F.at(pos).Select(t, ident()));
  1152                     break;
  1153                 case ELLIPSIS:
  1154                     assert this.permitTypeAnnotationsPushBack;
  1155                     typeAnnotationsPushedBack = annos;
  1156                     break loop;
  1157                 default:
  1158                     break loop;
  1161             if (typeArgs != null) illegal();
  1162             t = typeArgumentsOpt(t);
  1163             break;
  1164         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1165         case DOUBLE: case BOOLEAN:
  1166             if (typeArgs != null) illegal();
  1167             t = bracketsSuffix(bracketsOpt(basicType()));
  1168             break;
  1169         case VOID:
  1170             if (typeArgs != null) illegal();
  1171             if ((mode & EXPR) != 0) {
  1172                 S.nextToken();
  1173                 if (S.token() == DOT) {
  1174                     JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
  1175                     t = bracketsSuffix(ti);
  1176                 } else {
  1177                     return illegal(pos);
  1179             } else {
  1180                 // Support the corner case of myMethodHandle.<void>invoke() by passing
  1181                 // a void type (like other primitive types) to the next phase.
  1182                 // The error will be reported in Attr.attribTypes or Attr.visitApply.
  1183                 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
  1184                 S.nextToken();
  1185                 return ti;
  1186                 //return illegal();
  1188             break;
  1189         default:
  1190             return illegal();
  1192         if (typeArgs != null) illegal();
  1193         while (true) {
  1194             int pos1 = S.pos();
  1196             final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1198             if (S.token() == LBRACKET) {
  1199                 S.nextToken();
  1201                 if ((mode & TYPE) != 0) {
  1202                     int oldmode = mode;
  1203                     mode = TYPE;
  1204                     if (S.token() == RBRACKET) {
  1205                         S.nextToken();
  1206                         t = bracketsOpt(t, annos);
  1207                         t = toP(F.at(pos1).TypeArray(t));
  1208                         return t;
  1210                     mode = oldmode;
  1212                 if ((mode & EXPR) != 0) {
  1213                     mode = EXPR;
  1214                     JCExpression t1 = term();
  1215                     t = to(F.at(pos1).Indexed(t, t1));
  1217                 accept(RBRACKET);
  1218             } else if (S.token() == DOT) {
  1219                 S.nextToken();
  1220                 typeArgs = typeArgumentsOpt(EXPR);
  1221                 if (S.token() == SUPER && (mode & EXPR) != 0) {
  1222                     mode = EXPR;
  1223                     t = to(F.at(pos1).Select(t, names._super));
  1224                     S.nextToken();
  1225                     t = arguments(typeArgs, t);
  1226                     typeArgs = null;
  1227                 } else if (S.token() == NEW && (mode & EXPR) != 0) {
  1228                     if (typeArgs != null) return illegal();
  1229                     mode = EXPR;
  1230                     int pos2 = S.pos();
  1231                     S.nextToken();
  1232                     if (S.token() == LT) typeArgs = typeArguments();
  1233                     t = innerCreator(pos2, typeArgs, t);
  1234                     typeArgs = null;
  1235                 } else {
  1236                     t = toP(F.at(pos1).Select(t, ident()));
  1237                     t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  1238                     typeArgs = null;
  1240             } else {
  1241                 if (!annos.isEmpty()) {
  1242                     if (permitTypeAnnotationsPushBack)
  1243                         typeAnnotationsPushedBack = annos;
  1244                     else
  1245                         return illegal(annos.head.pos);
  1247                 break;
  1250         while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
  1251             mode = EXPR;
  1252             t = to(F.at(S.pos()).Unary(
  1253                   S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  1254             S.nextToken();
  1257         return toP(t);
  1260     /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  1261      */
  1262     JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  1263         S.nextToken();
  1264         if (S.token() == LPAREN || typeArgs != null) {
  1265             t = arguments(typeArgs, t);
  1266         } else {
  1267             int pos = S.pos();
  1268             accept(DOT);
  1269             typeArgs = (S.token() == LT) ? typeArguments() : null;
  1270             t = toP(F.at(pos).Select(t, ident()));
  1271             t = argumentsOpt(typeArgs, t);
  1273         return t;
  1276     /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  1277      */
  1278     JCPrimitiveTypeTree basicType() {
  1279         JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
  1280         S.nextToken();
  1281         return t;
  1284     /** ArgumentsOpt = [ Arguments ]
  1285      */
  1286     JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  1287         if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
  1288             mode = EXPR;
  1289             return arguments(typeArgs, t);
  1290         } else {
  1291             return t;
  1295     /** Arguments = "(" [Expression { COMMA Expression }] ")"
  1296      */
  1297     List<JCExpression> arguments() {
  1298         ListBuffer<JCExpression> args = lb();
  1299         if (S.token() == LPAREN) {
  1300             S.nextToken();
  1301             if (S.token() != RPAREN) {
  1302                 args.append(parseExpression());
  1303                 while (S.token() == COMMA) {
  1304                     S.nextToken();
  1305                     args.append(parseExpression());
  1308             accept(RPAREN);
  1309         } else {
  1310             syntaxError(S.pos(), "expected", LPAREN);
  1312         return args.toList();
  1315     JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  1316         int pos = S.pos();
  1317         List<JCExpression> args = arguments();
  1318         return toP(F.at(pos).Apply(typeArgs, t, args));
  1321     /**  TypeArgumentsOpt = [ TypeArguments ]
  1322      */
  1323     JCExpression typeArgumentsOpt(JCExpression t) {
  1324         if (S.token() == LT &&
  1325             (mode & TYPE) != 0 &&
  1326             (mode & NOPARAMS) == 0) {
  1327             mode = TYPE;
  1328             checkGenerics();
  1329             return typeArguments(t);
  1330         } else {
  1331             return t;
  1334     List<JCExpression> typeArgumentsOpt() {
  1335         return typeArgumentsOpt(TYPE);
  1338     List<JCExpression> typeArgumentsOpt(int useMode) {
  1339         if (S.token() == LT) {
  1340             checkGenerics();
  1341             if ((mode & useMode) == 0 ||
  1342                 (mode & NOPARAMS) != 0) {
  1343                 illegal();
  1345             mode = useMode;
  1346             return typeArguments();
  1348         return null;
  1351     /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  1352      */
  1353     List<JCExpression> typeArguments() {
  1354         ListBuffer<JCExpression> args = lb();
  1355         if (S.token() == LT) {
  1356             S.nextToken();
  1357             if (S.token() == GT && (mode & DIAMOND) != 0) {
  1358                 checkDiamond();
  1359                 S.nextToken();
  1360                 return List.nil();
  1362             args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1363             while (S.token() == COMMA) {
  1364                 S.nextToken();
  1365                 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1367             switch (S.token()) {
  1368             case GTGTGTEQ:
  1369                 S.token(GTGTEQ);
  1370                 break;
  1371             case GTGTEQ:
  1372                 S.token(GTEQ);
  1373                 break;
  1374             case GTEQ:
  1375                 S.token(EQ);
  1376                 break;
  1377             case GTGTGT:
  1378                 S.token(GTGT);
  1379                 break;
  1380             case GTGT:
  1381                 S.token(GT);
  1382                 break;
  1383             default:
  1384                 accept(GT);
  1385                 break;
  1387         } else {
  1388             syntaxError(S.pos(), "expected", LT);
  1390         return args.toList();
  1393     /** TypeArgument = Type
  1394      *               | [Annotations] "?"
  1395      *               | [Annotations] "?" EXTENDS Type {"&" Type}
  1396      *               | [Annotations] "?" SUPER Type
  1397      */
  1398     JCExpression typeArgument() {
  1399         List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
  1400         if (S.token() != QUES) return parseType(annotations);
  1401         int pos = S.pos();
  1402         S.nextToken();
  1403         JCExpression result;
  1404         if (S.token() == EXTENDS) {
  1405             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
  1406             S.nextToken();
  1407             JCExpression bound = parseType();
  1408             result = F.at(pos).Wildcard(t, bound);
  1409         } else if (S.token() == SUPER) {
  1410             TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
  1411             S.nextToken();
  1412             JCExpression bound = parseType();
  1413             result = F.at(pos).Wildcard(t, bound);
  1414         } else if (S.token() == IDENTIFIER) {
  1415             //error recovery
  1416             reportSyntaxError(S.prevEndPos(), "expected3",
  1417                     GT, EXTENDS, SUPER);
  1418             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  1419             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  1420             JCIdent id = toP(F.at(S.pos()).Ident(ident()));
  1421             result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  1422         } else {
  1423             TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
  1424             result = toP(F.at(pos).Wildcard(t, null));
  1426         if (!annotations.isEmpty())
  1427             result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
  1428         return result;
  1431     JCTypeApply typeArguments(JCExpression t) {
  1432         int pos = S.pos();
  1433         List<JCExpression> args = typeArguments();
  1434         return toP(F.at(pos).TypeApply(t, args));
  1437     /**
  1438      * BracketsOpt = { [Annotations] "[" "]" }
  1440      * <p>
  1442      * <code>annotations</code> is the list of annotations targeting
  1443      * the expression <code>t</code>.
  1444      */
  1445     private JCExpression bracketsOpt(JCExpression t,
  1446             List<JCTypeAnnotation> annotations) {
  1447         List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
  1449         if (S.token() == LBRACKET) {
  1450             int pos = S.pos();
  1451             S.nextToken();
  1453             JCExpression orig = t;
  1454             t = bracketsOptCont(t, pos, nextLevelAnnotations);
  1455         } else if (!nextLevelAnnotations.isEmpty()) {
  1456             if (permitTypeAnnotationsPushBack) {
  1457                 this.typeAnnotationsPushedBack = nextLevelAnnotations;
  1458             } else
  1459                 return illegal(nextLevelAnnotations.head.pos);
  1462         int apos = S.pos();
  1463         if (!annotations.isEmpty())
  1464             t = F.at(apos).AnnotatedType(annotations, t);
  1465         return t;
  1468     /** BracketsOpt = {"[" TypeAnnotations "]"}
  1469      */
  1470     private JCExpression bracketsOpt(JCExpression t) {
  1471         return bracketsOpt(t, List.<JCTypeAnnotation>nil());
  1474     private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
  1475             List<JCTypeAnnotation> annotations) {
  1476         accept(RBRACKET);
  1477         t = bracketsOpt(t, annotations);
  1478         return toP(F.at(pos).TypeArray(t));
  1481     /** BracketsSuffixExpr = "." CLASS
  1482      *  BracketsSuffixType =
  1483      */
  1484     JCExpression bracketsSuffix(JCExpression t) {
  1485         if ((mode & EXPR) != 0 && S.token() == DOT) {
  1486             mode = EXPR;
  1487             int pos = S.pos();
  1488             S.nextToken();
  1489             accept(CLASS);
  1490             if (S.pos() == errorEndPos) {
  1491                 // error recovery
  1492                 Name name = null;
  1493                 if (S.token() == IDENTIFIER) {
  1494                     name = S.name();
  1495                     S.nextToken();
  1496                 } else {
  1497                     name = names.error;
  1499                 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  1500             } else {
  1501                 t = toP(F.at(pos).Select(t, names._class));
  1503         } else if ((mode & TYPE) != 0) {
  1504             mode = TYPE;
  1505         } else {
  1506             syntaxError(S.pos(), "dot.class.expected");
  1508         return t;
  1511     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  1512      */
  1513     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  1515         List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
  1517         switch (S.token()) {
  1518         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1519         case DOUBLE: case BOOLEAN:
  1520             if (typeArgs == null) {
  1521                 if (newAnnotations.isEmpty())
  1522                     return arrayCreatorRest(newpos, basicType());
  1523                 else
  1524                     return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
  1526             break;
  1527         default:
  1529         JCExpression t = qualident();
  1530         // handle type annotations for non primitive arrays
  1531         if (!newAnnotations.isEmpty())
  1532             t = F.AnnotatedType(newAnnotations, t);
  1534         int oldmode = mode;
  1535         mode = TYPE | DIAMOND;
  1536         if (S.token() == LT) {
  1537             checkGenerics();
  1538             t = typeArguments(t);
  1540         while (S.token() == DOT) {
  1541             int pos = S.pos();
  1542             S.nextToken();
  1543             t = toP(F.at(pos).Select(t, ident()));
  1544             if (S.token() == LT) {
  1545                 checkGenerics();
  1546                 t = typeArguments(t);
  1549         mode = oldmode;
  1550         if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
  1551             JCExpression e = arrayCreatorRest(newpos, t);
  1552             if (typeArgs != null) {
  1553                 int pos = newpos;
  1554                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  1555                     // note: this should always happen but we should
  1556                     // not rely on this as the parser is continuously
  1557                     // modified to improve error recovery.
  1558                     pos = typeArgs.head.pos;
  1560                 setErrorEndPos(S.prevEndPos());
  1561                 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
  1562                 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
  1564             return e;
  1565         } else if (S.token() == LPAREN) {
  1566             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
  1567             if (newClass.def != null) {
  1568                 assert newClass.def.mods.annotations.isEmpty();
  1569                 if (newAnnotations.nonEmpty()) {
  1570                     newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
  1571                     newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
  1574             return newClass;
  1575         } else {
  1576             reportSyntaxError(S.pos(), "expected2",
  1577                                LPAREN, LBRACKET);
  1578             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  1579             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  1583     /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
  1584      */
  1585     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  1586         JCExpression t = toP(F.at(S.pos()).Ident(ident()));
  1587         if (S.token() == LT) {
  1588             int oldmode = mode;
  1589             mode |= DIAMOND;
  1590             checkGenerics();
  1591             t = typeArguments(t);
  1592             mode = oldmode;
  1594         return classCreatorRest(newpos, encl, typeArgs, t);
  1597     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
  1598      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
  1599      */
  1600     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  1602         List<JCTypeAnnotation> topAnnos = List.nil();
  1603         if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
  1604             JCAnnotatedType atype = (JCAnnotatedType) elemtype;
  1605             topAnnos = atype.annotations;
  1606             elemtype = atype.underlyingType;
  1609         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  1611         accept(LBRACKET);
  1613         if (S.token() == RBRACKET) {
  1614             accept(RBRACKET);
  1616             elemtype = bracketsOpt(elemtype, annos);
  1618             if (S.token() == LBRACE) {
  1619                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
  1621                 na.annotations = topAnnos;
  1623                 return na;
  1624             } else {
  1625                 return syntaxError(S.pos(), "array.dimension.missing");
  1627         } else {
  1628             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  1630             // maintain array dimension type annotations
  1631             ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
  1632             dimAnnotations.append(annos);
  1634             dims.append(parseExpression());
  1635             accept(RBRACKET);
  1636             while (S.token() == LBRACKET
  1637                     || (S.token() == MONKEYS_AT)) {
  1638                 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
  1639                 int pos = S.pos();
  1640                 S.nextToken();
  1641                 if (S.token() == RBRACKET) {
  1642                     elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1643                 } else {
  1644                     if (S.token() == RBRACKET) { // no dimension
  1645                         elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1646                     } else {
  1647                         dimAnnotations.append(maybeDimAnnos);
  1648                         dims.append(parseExpression());
  1649                         accept(RBRACKET);
  1654             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  1655             na.annotations = topAnnos;
  1656             na.dimAnnotations = dimAnnotations.toList();
  1657             return na;
  1661     /** ClassCreatorRest = Arguments [ClassBody]
  1662      */
  1663     JCNewClass classCreatorRest(int newpos,
  1664                                   JCExpression encl,
  1665                                   List<JCExpression> typeArgs,
  1666                                   JCExpression t)
  1668         List<JCExpression> args = arguments();
  1669         JCClassDecl body = null;
  1670         if (S.token() == LBRACE) {
  1671             int pos = S.pos();
  1672             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  1673             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1674             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  1676         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  1679     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  1680      */
  1681     JCExpression arrayInitializer(int newpos, JCExpression t) {
  1682         accept(LBRACE);
  1683         ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  1684         if (S.token() == COMMA) {
  1685             S.nextToken();
  1686         } else if (S.token() != RBRACE) {
  1687             elems.append(variableInitializer());
  1688             while (S.token() == COMMA) {
  1689                 S.nextToken();
  1690                 if (S.token() == RBRACE) break;
  1691                 elems.append(variableInitializer());
  1694         accept(RBRACE);
  1695         return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  1698     /** VariableInitializer = ArrayInitializer | Expression
  1699      */
  1700     public JCExpression variableInitializer() {
  1701         return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
  1704     /** ParExpression = "(" Expression ")"
  1705      */
  1706     JCExpression parExpression() {
  1707         accept(LPAREN);
  1708         JCExpression t = parseExpression();
  1709         accept(RPAREN);
  1710         return t;
  1713     /** Block = "{" BlockStatements "}"
  1714      */
  1715     JCBlock block(int pos, long flags) {
  1716         accept(LBRACE);
  1717         List<JCStatement> stats = blockStatements();
  1718         JCBlock t = F.at(pos).Block(flags, stats);
  1719         while (S.token() == CASE || S.token() == DEFAULT) {
  1720             syntaxError("orphaned", S.token());
  1721             switchBlockStatementGroups();
  1723         // the Block node has a field "endpos" for first char of last token, which is
  1724         // usually but not necessarily the last char of the last token.
  1725         t.endpos = S.pos();
  1726         accept(RBRACE);
  1727         return toP(t);
  1730     public JCBlock block() {
  1731         return block(S.pos(), 0);
  1734     /** BlockStatements = { BlockStatement }
  1735      *  BlockStatement  = LocalVariableDeclarationStatement
  1736      *                  | ClassOrInterfaceOrEnumDeclaration
  1737      *                  | [Ident ":"] Statement
  1738      *  LocalVariableDeclarationStatement
  1739      *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  1740      */
  1741     @SuppressWarnings("fallthrough")
  1742     List<JCStatement> blockStatements() {
  1743 //todo: skip to anchor on error(?)
  1744         int lastErrPos = -1;
  1745         ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  1746         while (true) {
  1747             int pos = S.pos();
  1748             switch (S.token()) {
  1749             case RBRACE: case CASE: case DEFAULT: case EOF:
  1750                 return stats.toList();
  1751             case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  1752             case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  1753             case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  1754                 stats.append(parseStatement());
  1755                 break;
  1756             case MONKEYS_AT:
  1757             case FINAL: {
  1758                 String dc = S.docComment();
  1759                 JCModifiers mods = modifiersOpt();
  1760                 if (S.token() == INTERFACE ||
  1761                     S.token() == CLASS ||
  1762                     allowEnums && S.token() == ENUM) {
  1763                     stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  1764                 } else {
  1765                     JCExpression t = parseType();
  1766                     stats.appendList(variableDeclarators(mods, t,
  1767                                                          new ListBuffer<JCStatement>()));
  1768                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1769                     storeEnd(stats.elems.last(), S.endPos());
  1770                     accept(SEMI);
  1772                 break;
  1774             case ABSTRACT: case STRICTFP: {
  1775                 String dc = S.docComment();
  1776                 JCModifiers mods = modifiersOpt();
  1777                 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  1778                 break;
  1780             case INTERFACE:
  1781             case CLASS:
  1782                 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  1783                                                                S.docComment()));
  1784                 break;
  1785             case ENUM:
  1786             case ASSERT:
  1787                 if (allowEnums && S.token() == ENUM) {
  1788                     log.error(S.pos(), "local.enum");
  1789                     stats.
  1790                         append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  1791                                                                  S.docComment()));
  1792                     break;
  1793                 } else if (allowAsserts && S.token() == ASSERT) {
  1794                     stats.append(parseStatement());
  1795                     break;
  1797                 /* fall through to default */
  1798             default:
  1799                 Name name = S.name();
  1800                 JCExpression t = term(EXPR | TYPE);
  1801                 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
  1802                     S.nextToken();
  1803                     JCStatement stat = parseStatement();
  1804                     stats.append(F.at(pos).Labelled(name, stat));
  1805                 } else if ((lastmode & TYPE) != 0 &&
  1806                            (S.token() == IDENTIFIER ||
  1807                             S.token() == ASSERT ||
  1808                             S.token() == ENUM)) {
  1809                     pos = S.pos();
  1810                     JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1811                     F.at(pos);
  1812                     stats.appendList(variableDeclarators(mods, t,
  1813                                                          new ListBuffer<JCStatement>()));
  1814                     // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1815                     storeEnd(stats.elems.last(), S.endPos());
  1816                     accept(SEMI);
  1817                 } else {
  1818                     // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  1819                     stats.append(to(F.at(pos).Exec(checkExprStat(t))));
  1820                     accept(SEMI);
  1824             // error recovery
  1825             if (S.pos() == lastErrPos)
  1826                 return stats.toList();
  1827             if (S.pos() <= errorEndPos) {
  1828                 skip(false, true, true, true);
  1829                 lastErrPos = S.pos();
  1832             // ensure no dangling /** @deprecated */ active
  1833             S.resetDeprecatedFlag();
  1837     /** Statement =
  1838      *       Block
  1839      *     | IF ParExpression Statement [ELSE Statement]
  1840      *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  1841      *     | FOR "(" FormalParameter : Expression ")" Statement
  1842      *     | WHILE ParExpression Statement
  1843      *     | DO Statement WHILE ParExpression ";"
  1844      *     | TRY Block ( Catches | [Catches] FinallyPart )
  1845      *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  1846      *     | SYNCHRONIZED ParExpression Block
  1847      *     | RETURN [Expression] ";"
  1848      *     | THROW Expression ";"
  1849      *     | BREAK [Ident] ";"
  1850      *     | CONTINUE [Ident] ";"
  1851      *     | ASSERT Expression [ ":" Expression ] ";"
  1852      *     | ";"
  1853      *     | ExpressionStatement
  1854      *     | Ident ":" Statement
  1855      */
  1856     @SuppressWarnings("fallthrough")
  1857     public JCStatement parseStatement() {
  1858         int pos = S.pos();
  1859         switch (S.token()) {
  1860         case LBRACE:
  1861             return block();
  1862         case IF: {
  1863             S.nextToken();
  1864             JCExpression cond = parExpression();
  1865             JCStatement thenpart = parseStatement();
  1866             JCStatement elsepart = null;
  1867             if (S.token() == ELSE) {
  1868                 S.nextToken();
  1869                 elsepart = parseStatement();
  1871             return F.at(pos).If(cond, thenpart, elsepart);
  1873         case FOR: {
  1874             S.nextToken();
  1875             accept(LPAREN);
  1876             List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
  1877             if (inits.length() == 1 &&
  1878                 inits.head.getTag() == JCTree.VARDEF &&
  1879                 ((JCVariableDecl) inits.head).init == null &&
  1880                 S.token() == COLON) {
  1881                 checkForeach();
  1882                 JCVariableDecl var = (JCVariableDecl)inits.head;
  1883                 accept(COLON);
  1884                 JCExpression expr = parseExpression();
  1885                 accept(RPAREN);
  1886                 JCStatement body = parseStatement();
  1887                 return F.at(pos).ForeachLoop(var, expr, body);
  1888             } else {
  1889                 accept(SEMI);
  1890                 JCExpression cond = S.token() == SEMI ? null : parseExpression();
  1891                 accept(SEMI);
  1892                 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  1893                 accept(RPAREN);
  1894                 JCStatement body = parseStatement();
  1895                 return F.at(pos).ForLoop(inits, cond, steps, body);
  1898         case WHILE: {
  1899             S.nextToken();
  1900             JCExpression cond = parExpression();
  1901             JCStatement body = parseStatement();
  1902             return F.at(pos).WhileLoop(cond, body);
  1904         case DO: {
  1905             S.nextToken();
  1906             JCStatement body = parseStatement();
  1907             accept(WHILE);
  1908             JCExpression cond = parExpression();
  1909             JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  1910             accept(SEMI);
  1911             return t;
  1913         case TRY: {
  1914             S.nextToken();
  1915             JCBlock body = block();
  1916             ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  1917             JCBlock finalizer = null;
  1918             if (S.token() == CATCH || S.token() == FINALLY) {
  1919                 while (S.token() == CATCH) catchers.append(catchClause());
  1920                 if (S.token() == FINALLY) {
  1921                     S.nextToken();
  1922                     finalizer = block();
  1924             } else {
  1925                 log.error(pos, "try.without.catch.or.finally");
  1927             return F.at(pos).Try(body, catchers.toList(), finalizer);
  1929         case SWITCH: {
  1930             S.nextToken();
  1931             JCExpression selector = parExpression();
  1932             accept(LBRACE);
  1933             List<JCCase> cases = switchBlockStatementGroups();
  1934             JCSwitch t = to(F.at(pos).Switch(selector, cases));
  1935             accept(RBRACE);
  1936             return t;
  1938         case SYNCHRONIZED: {
  1939             S.nextToken();
  1940             JCExpression lock = parExpression();
  1941             JCBlock body = block();
  1942             return F.at(pos).Synchronized(lock, body);
  1944         case RETURN: {
  1945             S.nextToken();
  1946             JCExpression result = S.token() == SEMI ? null : parseExpression();
  1947             JCReturn t = to(F.at(pos).Return(result));
  1948             accept(SEMI);
  1949             return t;
  1951         case THROW: {
  1952             S.nextToken();
  1953             JCExpression exc = parseExpression();
  1954             JCThrow t = to(F.at(pos).Throw(exc));
  1955             accept(SEMI);
  1956             return t;
  1958         case BREAK: {
  1959             S.nextToken();
  1960             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  1961             JCBreak t = to(F.at(pos).Break(label));
  1962             accept(SEMI);
  1963             return t;
  1965         case CONTINUE: {
  1966             S.nextToken();
  1967             Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  1968             JCContinue t =  to(F.at(pos).Continue(label));
  1969             accept(SEMI);
  1970             return t;
  1972         case SEMI:
  1973             S.nextToken();
  1974             return toP(F.at(pos).Skip());
  1975         case ELSE:
  1976             return toP(F.Exec(syntaxError("else.without.if")));
  1977         case FINALLY:
  1978             return toP(F.Exec(syntaxError("finally.without.try")));
  1979         case CATCH:
  1980             return toP(F.Exec(syntaxError("catch.without.try")));
  1981         case ASSERT: {
  1982             if (allowAsserts && S.token() == ASSERT) {
  1983                 S.nextToken();
  1984                 JCExpression assertion = parseExpression();
  1985                 JCExpression message = null;
  1986                 if (S.token() == COLON) {
  1987                     S.nextToken();
  1988                     message = parseExpression();
  1990                 JCAssert t = to(F.at(pos).Assert(assertion, message));
  1991                 accept(SEMI);
  1992                 return t;
  1994             /* else fall through to default case */
  1996         case ENUM:
  1997         default:
  1998             Name name = S.name();
  1999             JCExpression expr = parseExpression();
  2000             if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
  2001                 S.nextToken();
  2002                 JCStatement stat = parseStatement();
  2003                 return F.at(pos).Labelled(name, stat);
  2004             } else {
  2005                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  2006                 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  2007                 accept(SEMI);
  2008                 return stat;
  2013     /** CatchClause     = CATCH "(" FormalParameter ")" Block
  2014      */
  2015     JCCatch catchClause() {
  2016         int pos = S.pos();
  2017         accept(CATCH);
  2018         accept(LPAREN);
  2019         JCModifiers mods = optFinal(Flags.PARAMETER);
  2020         List<JCExpression> catchTypes = catchTypes();
  2021         JCExpression paramType = catchTypes.size() > 1 ?
  2022                 toP(F.at(catchTypes.head.getStartPosition()).TypeDisjoint(catchTypes)) :
  2023                 catchTypes.head;
  2024         JCVariableDecl formal = variableDeclaratorId(mods, paramType);
  2025         accept(RPAREN);
  2026         JCBlock body = block();
  2027         return F.at(pos).Catch(formal, body);
  2030     List<JCExpression> catchTypes() {
  2031         ListBuffer<JCExpression> catchTypes = ListBuffer.lb();
  2032         catchTypes.add(parseType());
  2033         while (S.token() == BAR) {
  2034             checkMulticatch();
  2035             S.nextToken();
  2036             catchTypes.add(qualident());
  2038         return catchTypes.toList();
  2041     /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  2042      *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  2043      *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  2044      */
  2045     List<JCCase> switchBlockStatementGroups() {
  2046         ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  2047         while (true) {
  2048             int pos = S.pos();
  2049             switch (S.token()) {
  2050             case CASE: {
  2051                 S.nextToken();
  2052                 JCExpression pat = parseExpression();
  2053                 accept(COLON);
  2054                 List<JCStatement> stats = blockStatements();
  2055                 JCCase c = F.at(pos).Case(pat, stats);
  2056                 if (stats.isEmpty())
  2057                     storeEnd(c, S.prevEndPos());
  2058                 cases.append(c);
  2059                 break;
  2061             case DEFAULT: {
  2062                 S.nextToken();
  2063                 accept(COLON);
  2064                 List<JCStatement> stats = blockStatements();
  2065                 JCCase c = F.at(pos).Case(null, stats);
  2066                 if (stats.isEmpty())
  2067                     storeEnd(c, S.prevEndPos());
  2068                 cases.append(c);
  2069                 break;
  2071             case RBRACE: case EOF:
  2072                 return cases.toList();
  2073             default:
  2074                 S.nextToken(); // to ensure progress
  2075                 syntaxError(pos, "expected3",
  2076                     CASE, DEFAULT, RBRACE);
  2081     /** MoreStatementExpressions = { COMMA StatementExpression }
  2082      */
  2083     <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  2084                                                                     JCExpression first,
  2085                                                                     T stats) {
  2086         // This Exec is a "StatementExpression"; it subsumes no terminating token
  2087         stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  2088         while (S.token() == COMMA) {
  2089             S.nextToken();
  2090             pos = S.pos();
  2091             JCExpression t = parseExpression();
  2092             // This Exec is a "StatementExpression"; it subsumes no terminating token
  2093             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  2095         return stats;
  2098     /** ForInit = StatementExpression MoreStatementExpressions
  2099      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  2100      */
  2101     List<JCStatement> forInit() {
  2102         ListBuffer<JCStatement> stats = lb();
  2103         int pos = S.pos();
  2104         if (S.token() == FINAL || S.token() == MONKEYS_AT) {
  2105             return variableDeclarators(optFinal(0), parseType(), stats).toList();
  2106         } else {
  2107             JCExpression t = term(EXPR | TYPE);
  2108             if ((lastmode & TYPE) != 0 &&
  2109                 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
  2110                 return variableDeclarators(modifiersOpt(), t, stats).toList();
  2111             else
  2112                 return moreStatementExpressions(pos, t, stats).toList();
  2116     /** ForUpdate = StatementExpression MoreStatementExpressions
  2117      */
  2118     List<JCExpressionStatement> forUpdate() {
  2119         return moreStatementExpressions(S.pos(),
  2120                                         parseExpression(),
  2121                                         new ListBuffer<JCExpressionStatement>()).toList();
  2124     enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
  2126     /** AnnotationsOpt = { '@' Annotation }
  2127      */
  2128     List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
  2129         if (S.token() != MONKEYS_AT) return List.nil(); // optimization
  2130         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  2131         int prevmode = mode;
  2132         while (S.token() == MONKEYS_AT) {
  2133             int pos = S.pos();
  2134             S.nextToken();
  2135             buf.append(annotation(pos, kind));
  2137         lastmode = mode;
  2138         mode = prevmode;
  2139         List<JCAnnotation> annotations = buf.toList();
  2141         if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
  2142             System.out.println("TA: parsing " + annotations
  2143                     + " in " + log.currentSourceFile());
  2144         return annotations;
  2147     List<JCTypeAnnotation> typeAnnotationsOpt() {
  2148         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
  2149         return List.convert(JCTypeAnnotation.class, annotations);
  2152     /** ModifiersOpt = { Modifier }
  2153      *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  2154      *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  2155      *           | "@" Annotation
  2156      */
  2157     JCModifiers modifiersOpt() {
  2158         return modifiersOpt(null);
  2160     JCModifiers modifiersOpt(JCModifiers partial) {
  2161         long flags;
  2162         ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  2163         int pos;
  2164         if (partial == null) {
  2165             flags = 0;
  2166             pos = S.pos();
  2167         } else {
  2168             flags = partial.flags;
  2169             annotations.appendList(partial.annotations);
  2170             pos = partial.pos;
  2172         if (S.deprecatedFlag()) {
  2173             flags |= Flags.DEPRECATED;
  2174             S.resetDeprecatedFlag();
  2176         int lastPos = Position.NOPOS;
  2177     loop:
  2178         while (true) {
  2179             long flag;
  2180             switch (S.token()) {
  2181             case PRIVATE     : flag = Flags.PRIVATE; break;
  2182             case PROTECTED   : flag = Flags.PROTECTED; break;
  2183             case PUBLIC      : flag = Flags.PUBLIC; break;
  2184             case STATIC      : flag = Flags.STATIC; break;
  2185             case TRANSIENT   : flag = Flags.TRANSIENT; break;
  2186             case FINAL       : flag = Flags.FINAL; break;
  2187             case ABSTRACT    : flag = Flags.ABSTRACT; break;
  2188             case NATIVE      : flag = Flags.NATIVE; break;
  2189             case VOLATILE    : flag = Flags.VOLATILE; break;
  2190             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  2191             case STRICTFP    : flag = Flags.STRICTFP; break;
  2192             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  2193             default: break loop;
  2195             if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
  2196             lastPos = S.pos();
  2197             S.nextToken();
  2198             if (flag == Flags.ANNOTATION) {
  2199                 checkAnnotations();
  2200                 if (S.token() != INTERFACE) {
  2201                     JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
  2202                     // if first modifier is an annotation, set pos to annotation's.
  2203                     if (flags == 0 && annotations.isEmpty())
  2204                         pos = ann.pos;
  2205                     annotations.append(ann);
  2206                     lastPos = ann.pos;
  2207                     flag = 0;
  2210             flags |= flag;
  2212         switch (S.token()) {
  2213         case ENUM: flags |= Flags.ENUM; break;
  2214         case INTERFACE: flags |= Flags.INTERFACE; break;
  2215         default: break;
  2218         /* A modifiers tree with no modifier tokens or annotations
  2219          * has no text position. */
  2220         if ((flags & Flags.ModifierFlags) == 0 && annotations.isEmpty())
  2221             pos = Position.NOPOS;
  2223         JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  2224         if (pos != Position.NOPOS)
  2225             storeEnd(mods, S.prevEndPos());
  2226         return mods;
  2229     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  2230      * @param pos position of "@" token
  2231      */
  2232     JCAnnotation annotation(int pos, AnnotationKind kind) {
  2233         // accept(AT); // AT consumed by caller
  2234         checkAnnotations();
  2235         if (kind == AnnotationKind.TYPE_ANNO)
  2236             checkTypeAnnotations();
  2237         JCTree ident = qualident();
  2238         List<JCExpression> fieldValues = annotationFieldValuesOpt();
  2239         JCAnnotation ann;
  2240         if (kind == AnnotationKind.DEFAULT_ANNO)
  2241             ann = F.at(pos).Annotation(ident, fieldValues);
  2242         else
  2243             ann = F.at(pos).TypeAnnotation(ident, fieldValues);
  2244         storeEnd(ann, S.prevEndPos());
  2245         return ann;
  2248     List<JCExpression> annotationFieldValuesOpt() {
  2249         return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  2252     /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  2253     List<JCExpression> annotationFieldValues() {
  2254         accept(LPAREN);
  2255         ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2256         if (S.token() != RPAREN) {
  2257             buf.append(annotationFieldValue());
  2258             while (S.token() == COMMA) {
  2259                 S.nextToken();
  2260                 buf.append(annotationFieldValue());
  2263         accept(RPAREN);
  2264         return buf.toList();
  2267     /** AnnotationFieldValue    = AnnotationValue
  2268      *                          | Identifier "=" AnnotationValue
  2269      */
  2270     JCExpression annotationFieldValue() {
  2271         if (S.token() == IDENTIFIER) {
  2272             mode = EXPR;
  2273             JCExpression t1 = term1();
  2274             if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
  2275                 int pos = S.pos();
  2276                 accept(EQ);
  2277                 JCExpression v = annotationValue();
  2278                 return toP(F.at(pos).Assign(t1, v));
  2279             } else {
  2280                 return t1;
  2283         return annotationValue();
  2286     /* AnnotationValue          = ConditionalExpression
  2287      *                          | Annotation
  2288      *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
  2289      */
  2290     JCExpression annotationValue() {
  2291         int pos;
  2292         switch (S.token()) {
  2293         case MONKEYS_AT:
  2294             pos = S.pos();
  2295             S.nextToken();
  2296             return annotation(pos, AnnotationKind.DEFAULT_ANNO);
  2297         case LBRACE:
  2298             pos = S.pos();
  2299             accept(LBRACE);
  2300             ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  2301             if (S.token() != RBRACE) {
  2302                 buf.append(annotationValue());
  2303                 while (S.token() == COMMA) {
  2304                     S.nextToken();
  2305                     if (S.token() == RBRACE) break;
  2306                     buf.append(annotationValue());
  2309             accept(RBRACE);
  2310             return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  2311         default:
  2312             mode = EXPR;
  2313             return term1();
  2317     /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  2318      */
  2319     public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  2320                                                                          JCExpression type,
  2321                                                                          T vdefs)
  2323         return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
  2326     /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  2327      *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  2329      *  @param reqInit  Is an initializer always required?
  2330      *  @param dc       The documentation comment for the variable declarations, or null.
  2331      */
  2332     <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  2333                                                                      JCModifiers mods,
  2334                                                                      JCExpression type,
  2335                                                                      Name name,
  2336                                                                      boolean reqInit,
  2337                                                                      String dc,
  2338                                                                      T vdefs)
  2340         vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  2341         while (S.token() == COMMA) {
  2342             // All but last of multiple declarators subsume a comma
  2343             storeEnd((JCTree)vdefs.elems.last(), S.endPos());
  2344             S.nextToken();
  2345             vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  2347         return vdefs;
  2350     /** VariableDeclarator = Ident VariableDeclaratorRest
  2351      *  ConstantDeclarator = Ident ConstantDeclaratorRest
  2352      */
  2353     JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
  2354         return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
  2357     /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  2358      *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  2360      *  @param reqInit  Is an initializer always required?
  2361      *  @param dc       The documentation comment for the variable declarations, or null.
  2362      */
  2363     JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  2364                                   boolean reqInit, String dc) {
  2365         type = bracketsOpt(type);
  2366         JCExpression init = null;
  2367         if (S.token() == EQ) {
  2368             S.nextToken();
  2369             init = variableInitializer();
  2371         else if (reqInit) syntaxError(S.pos(), "expected", EQ);
  2372         JCVariableDecl result =
  2373             toP(F.at(pos).VarDef(mods, name, type, init));
  2374         attach(result, dc);
  2375         return result;
  2378     /** VariableDeclaratorId = Ident BracketsOpt
  2379      */
  2380     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  2381         int pos = S.pos();
  2382         Name name = ident();
  2383         if ((mods.flags & Flags.VARARGS) == 0)
  2384             type = bracketsOpt(type);
  2385         return toP(F.at(pos).VarDef(mods, name, type, null));
  2388     /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  2389      */
  2390     public JCTree.JCCompilationUnit parseCompilationUnit() {
  2391         int pos = S.pos();
  2392         JCExpression pid = null;
  2393         String dc = S.docComment();
  2394         JCModifiers mods = null;
  2395         List<JCAnnotation> packageAnnotations = List.nil();
  2396         if (S.token() == MONKEYS_AT)
  2397             mods = modifiersOpt();
  2399         if (S.token() == PACKAGE) {
  2400             if (mods != null) {
  2401                 checkNoMods(mods.flags);
  2402                 packageAnnotations = mods.annotations;
  2403                 mods = null;
  2405             S.nextToken();
  2406             pid = qualident();
  2407             accept(SEMI);
  2409         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2410         boolean checkForImports = true;
  2411         while (S.token() != EOF) {
  2412             if (S.pos() <= errorEndPos) {
  2413                 // error recovery
  2414                 skip(checkForImports, false, false, false);
  2415                 if (S.token() == EOF)
  2416                     break;
  2418             if (checkForImports && mods == null && S.token() == IMPORT) {
  2419                 defs.append(importDeclaration());
  2420             } else {
  2421                 JCTree def = typeDeclaration(mods);
  2422                 if (def instanceof JCExpressionStatement)
  2423                     def = ((JCExpressionStatement)def).expr;
  2424                 defs.append(def);
  2425                 if (def instanceof JCClassDecl)
  2426                     checkForImports = false;
  2427                 mods = null;
  2430         JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
  2431         attach(toplevel, dc);
  2432         if (defs.elems.isEmpty())
  2433             storeEnd(toplevel, S.prevEndPos());
  2434         if (keepDocComments)
  2435             toplevel.docComments = docComments;
  2436         if (keepLineMap)
  2437             toplevel.lineMap = S.getLineMap();
  2438         return toplevel;
  2441     /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  2442      */
  2443     JCTree importDeclaration() {
  2444         int pos = S.pos();
  2445         S.nextToken();
  2446         boolean importStatic = false;
  2447         if (S.token() == STATIC) {
  2448             checkStaticImports();
  2449             importStatic = true;
  2450             S.nextToken();
  2452         JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
  2453         do {
  2454             int pos1 = S.pos();
  2455             accept(DOT);
  2456             if (S.token() == STAR) {
  2457                 pid = to(F.at(pos1).Select(pid, names.asterisk));
  2458                 S.nextToken();
  2459                 break;
  2460             } else {
  2461                 pid = toP(F.at(pos1).Select(pid, ident()));
  2463         } while (S.token() == DOT);
  2464         accept(SEMI);
  2465         return toP(F.at(pos).Import(pid, importStatic));
  2468     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  2469      *                  | ";"
  2470      */
  2471     JCTree typeDeclaration(JCModifiers mods) {
  2472         int pos = S.pos();
  2473         if (mods == null && S.token() == SEMI) {
  2474             S.nextToken();
  2475             return toP(F.at(pos).Skip());
  2476         } else {
  2477             String dc = S.docComment();
  2478             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
  2482     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  2483      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  2484      *  @param mods     Any modifiers starting the class or interface declaration
  2485      *  @param dc       The documentation comment for the class, or null.
  2486      */
  2487     JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
  2488         if (S.token() == CLASS) {
  2489             return classDeclaration(mods, dc);
  2490         } else if (S.token() == INTERFACE) {
  2491             return interfaceDeclaration(mods, dc);
  2492         } else if (allowEnums) {
  2493             if (S.token() == ENUM) {
  2494                 return enumDeclaration(mods, dc);
  2495             } else {
  2496                 int pos = S.pos();
  2497                 List<JCTree> errs;
  2498                 if (S.token() == IDENTIFIER) {
  2499                     errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  2500                     setErrorEndPos(S.pos());
  2501                 } else {
  2502                     errs = List.<JCTree>of(mods);
  2504                 return toP(F.Exec(syntaxError(pos, errs, "expected3",
  2505                                               CLASS, INTERFACE, ENUM)));
  2507         } else {
  2508             if (S.token() == ENUM) {
  2509                 log.error(S.pos(), "enums.not.supported.in.source", source.name);
  2510                 allowEnums = true;
  2511                 return enumDeclaration(mods, dc);
  2513             int pos = S.pos();
  2514             List<JCTree> errs;
  2515             if (S.token() == IDENTIFIER) {
  2516                 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  2517                 setErrorEndPos(S.pos());
  2518             } else {
  2519                 errs = List.<JCTree>of(mods);
  2521             return toP(F.Exec(syntaxError(pos, errs, "expected2",
  2522                                           CLASS, INTERFACE)));
  2526     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  2527      *                     [IMPLEMENTS TypeList] ClassBody
  2528      *  @param mods    The modifiers starting the class declaration
  2529      *  @param dc       The documentation comment for the class, or null.
  2530      */
  2531     JCClassDecl classDeclaration(JCModifiers mods, String dc) {
  2532         int pos = S.pos();
  2533         accept(CLASS);
  2534         Name name = ident();
  2536         List<JCTypeParameter> typarams = typeParametersOpt();
  2538         JCTree extending = null;
  2539         if (S.token() == EXTENDS) {
  2540             S.nextToken();
  2541             extending = parseType();
  2543         List<JCExpression> implementing = List.nil();
  2544         if (S.token() == IMPLEMENTS) {
  2545             S.nextToken();
  2546             implementing = typeList();
  2548         List<JCTree> defs = classOrInterfaceBody(name, false);
  2549         JCClassDecl result = toP(F.at(pos).ClassDef(
  2550             mods, name, typarams, extending, implementing, defs));
  2551         attach(result, dc);
  2552         return result;
  2555     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  2556      *                         [EXTENDS TypeList] InterfaceBody
  2557      *  @param mods    The modifiers starting the interface declaration
  2558      *  @param dc       The documentation comment for the interface, or null.
  2559      */
  2560     JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
  2561         int pos = S.pos();
  2562         accept(INTERFACE);
  2563         Name name = ident();
  2565         List<JCTypeParameter> typarams = typeParametersOpt();
  2567         List<JCExpression> extending = List.nil();
  2568         if (S.token() == EXTENDS) {
  2569             S.nextToken();
  2570             extending = typeList();
  2572         List<JCTree> defs = classOrInterfaceBody(name, true);
  2573         JCClassDecl result = toP(F.at(pos).ClassDef(
  2574             mods, name, typarams, null, extending, defs));
  2575         attach(result, dc);
  2576         return result;
  2579     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  2580      *  @param mods    The modifiers starting the enum declaration
  2581      *  @param dc       The documentation comment for the enum, or null.
  2582      */
  2583     JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
  2584         int pos = S.pos();
  2585         accept(ENUM);
  2586         Name name = ident();
  2588         List<JCExpression> implementing = List.nil();
  2589         if (S.token() == IMPLEMENTS) {
  2590             S.nextToken();
  2591             implementing = typeList();
  2594         List<JCTree> defs = enumBody(name);
  2595         mods.flags |= Flags.ENUM;
  2596         JCClassDecl result = toP(F.at(pos).
  2597             ClassDef(mods, name, List.<JCTypeParameter>nil(),
  2598                 null, implementing, defs));
  2599         attach(result, dc);
  2600         return result;
  2603     /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  2604      *                  [ ";" {ClassBodyDeclaration} ] "}"
  2605      */
  2606     List<JCTree> enumBody(Name enumName) {
  2607         accept(LBRACE);
  2608         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2609         if (S.token() == COMMA) {
  2610             S.nextToken();
  2611         } else if (S.token() != RBRACE && S.token() != SEMI) {
  2612             defs.append(enumeratorDeclaration(enumName));
  2613             while (S.token() == COMMA) {
  2614                 S.nextToken();
  2615                 if (S.token() == RBRACE || S.token() == SEMI) break;
  2616                 defs.append(enumeratorDeclaration(enumName));
  2618             if (S.token() != SEMI && S.token() != RBRACE) {
  2619                 defs.append(syntaxError(S.pos(), "expected3",
  2620                                 COMMA, RBRACE, SEMI));
  2621                 S.nextToken();
  2624         if (S.token() == SEMI) {
  2625             S.nextToken();
  2626             while (S.token() != RBRACE && S.token() != EOF) {
  2627                 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  2628                                                                 false));
  2629                 if (S.pos() <= errorEndPos) {
  2630                     // error recovery
  2631                    skip(false, true, true, false);
  2635         accept(RBRACE);
  2636         return defs.toList();
  2639     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  2640      */
  2641     JCTree enumeratorDeclaration(Name enumName) {
  2642         String dc = S.docComment();
  2643         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  2644         if (S.deprecatedFlag()) {
  2645             flags |= Flags.DEPRECATED;
  2646             S.resetDeprecatedFlag();
  2648         int pos = S.pos();
  2649         List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
  2650         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  2651         List<JCExpression> typeArgs = typeArgumentsOpt();
  2652         int identPos = S.pos();
  2653         Name name = ident();
  2654         int createPos = S.pos();
  2655         List<JCExpression> args = (S.token() == LPAREN)
  2656             ? arguments() : List.<JCExpression>nil();
  2657         JCClassDecl body = null;
  2658         if (S.token() == LBRACE) {
  2659             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  2660             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  2661             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  2663         if (args.isEmpty() && body == null)
  2664             createPos = identPos;
  2665         JCIdent ident = F.at(identPos).Ident(enumName);
  2666         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  2667         if (createPos != identPos)
  2668             storeEnd(create, S.prevEndPos());
  2669         ident = F.at(identPos).Ident(enumName);
  2670         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  2671         attach(result, dc);
  2672         return result;
  2675     /** TypeList = Type {"," Type}
  2676      */
  2677     List<JCExpression> typeList() {
  2678         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  2679         ts.append(parseType());
  2680         while (S.token() == COMMA) {
  2681             S.nextToken();
  2682             ts.append(parseType());
  2684         return ts.toList();
  2687     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  2688      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  2689      */
  2690     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  2691         accept(LBRACE);
  2692         if (S.pos() <= errorEndPos) {
  2693             // error recovery
  2694             skip(false, true, false, false);
  2695             if (S.token() == LBRACE)
  2696                 S.nextToken();
  2698         ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  2699         while (S.token() != RBRACE && S.token() != EOF) {
  2700             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  2701             if (S.pos() <= errorEndPos) {
  2702                // error recovery
  2703                skip(false, true, true, false);
  2706         accept(RBRACE);
  2707         return defs.toList();
  2710     /** ClassBodyDeclaration =
  2711      *      ";"
  2712      *    | [STATIC] Block
  2713      *    | ModifiersOpt
  2714      *      ( Type Ident
  2715      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  2716      *      | VOID Ident MethodDeclaratorRest
  2717      *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
  2718      *      | Ident ConstructorDeclaratorRest
  2719      *      | TypeParameters Ident ConstructorDeclaratorRest
  2720      *      | ClassOrInterfaceOrEnumDeclaration
  2721      *      )
  2722      *  InterfaceBodyDeclaration =
  2723      *      ";"
  2724      *    | ModifiersOpt Type Ident
  2725      *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
  2726      */
  2727     List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  2728         if (S.token() == SEMI) {
  2729             S.nextToken();
  2730             return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
  2731         } else {
  2732             String dc = S.docComment();
  2733             int pos = S.pos();
  2734             JCModifiers mods = modifiersOpt();
  2735             if (S.token() == CLASS ||
  2736                 S.token() == INTERFACE ||
  2737                 allowEnums && S.token() == ENUM) {
  2738                 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  2739             } else if (S.token() == LBRACE && !isInterface &&
  2740                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  2741                        mods.annotations.isEmpty()) {
  2742                 return List.<JCTree>of(block(pos, mods.flags));
  2743             } else {
  2744                 pos = S.pos();
  2745                 List<JCTypeParameter> typarams = typeParametersOpt();
  2746                 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
  2748                 Name name = S.name();
  2749                 pos = S.pos();
  2750                 JCExpression type;
  2751                 boolean isVoid = S.token() == VOID;
  2752                 if (isVoid) {
  2753                     if (annosAfterParams.nonEmpty())
  2754                         illegal(annosAfterParams.head.pos);
  2755                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
  2756                     S.nextToken();
  2757                 } else {
  2758                     if (annosAfterParams.nonEmpty()) {
  2759                         mods.annotations = mods.annotations.appendList(annosAfterParams);
  2760                         if (mods.pos == Position.NOPOS)
  2761                             mods.pos = mods.annotations.head.pos;
  2763                     // method returns types are un-annotated types
  2764                     type = unannotatedType();
  2766                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
  2767                     if (isInterface || name != className)
  2768                         log.error(pos, "invalid.meth.decl.ret.type.req");
  2769                     return List.of(methodDeclaratorRest(
  2770                         pos, mods, null, names.init, typarams,
  2771                         isInterface, true, dc));
  2772                 } else {
  2773                     pos = S.pos();
  2774                     name = ident();
  2775                     if (S.token() == LPAREN) {
  2776                         return List.of(methodDeclaratorRest(
  2777                             pos, mods, type, name, typarams,
  2778                             isInterface, isVoid, dc));
  2779                     } else if (!isVoid && typarams.isEmpty()) {
  2780                         List<JCTree> defs =
  2781                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  2782                                                     new ListBuffer<JCTree>()).toList();
  2783                         storeEnd(defs.last(), S.endPos());
  2784                         accept(SEMI);
  2785                         return defs;
  2786                     } else {
  2787                         pos = S.pos();
  2788                         List<JCTree> err = isVoid
  2789                             ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  2790                                 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  2791                             : null;
  2792                         return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
  2799     /** MethodDeclaratorRest =
  2800      *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  2801      *  VoidMethodDeclaratorRest =
  2802      *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
  2803      *  InterfaceMethodDeclaratorRest =
  2804      *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
  2805      *  VoidInterfaceMethodDeclaratorRest =
  2806      *      FormalParameters [Annotations] [THROWS TypeList] ";"
  2807      *  ConstructorDeclaratorRest =
  2808      *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
  2809      */
  2810     JCTree methodDeclaratorRest(int pos,
  2811                               JCModifiers mods,
  2812                               JCExpression type,
  2813                               Name name,
  2814                               List<JCTypeParameter> typarams,
  2815                               boolean isInterface, boolean isVoid,
  2816                               String dc) {
  2817         List<JCVariableDecl> params = formalParameters();
  2819         List<JCTypeAnnotation> receiverAnnotations;
  2820         if (!isVoid) {
  2821             // need to distinguish between receiver anno and array anno
  2822             // look at typeAnnotationsPushedBack comment
  2823             this.permitTypeAnnotationsPushBack = true;
  2824             type = methodReturnArrayRest(type);
  2825             this.permitTypeAnnotationsPushBack = false;
  2826             if (typeAnnotationsPushedBack == null)
  2827                 receiverAnnotations = List.nil();
  2828             else
  2829                 receiverAnnotations = typeAnnotationsPushedBack;
  2830             typeAnnotationsPushedBack = null;
  2831         } else
  2832             receiverAnnotations = typeAnnotationsOpt();
  2834         List<JCExpression> thrown = List.nil();
  2835         if (S.token() == THROWS) {
  2836             S.nextToken();
  2837             thrown = qualidentList();
  2839         JCBlock body = null;
  2840         JCExpression defaultValue;
  2841         if (S.token() == LBRACE) {
  2842             body = block();
  2843             defaultValue = null;
  2844         } else {
  2845             if (S.token() == DEFAULT) {
  2846                 accept(DEFAULT);
  2847                 defaultValue = annotationValue();
  2848             } else {
  2849                 defaultValue = null;
  2851             accept(SEMI);
  2852             if (S.pos() <= errorEndPos) {
  2853                 // error recovery
  2854                 skip(false, true, false, false);
  2855                 if (S.token() == LBRACE) {
  2856                     body = block();
  2861         JCMethodDecl result =
  2862             toP(F.at(pos).MethodDef(mods, name, type, typarams,
  2863                                     params, receiverAnnotations, thrown,
  2864                                     body, defaultValue));
  2865         attach(result, dc);
  2866         return result;
  2869     /** Parses the array levels after the format parameters list, and append
  2870      * them to the return type, while preseving the order of type annotations
  2871      */
  2872     private JCExpression methodReturnArrayRest(JCExpression type) {
  2873         if (type.getTag() != JCTree.TYPEARRAY)
  2874             return bracketsOpt(type);
  2876         JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
  2877         while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
  2878             baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
  2880         if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
  2881             JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
  2882             at.underlyingType = bracketsOpt(at.underlyingType);
  2883         } else {
  2884             baseArray.elemtype = bracketsOpt(baseArray.elemtype);
  2887         return type;
  2890     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  2891      */
  2892     List<JCExpression> qualidentList() {
  2893         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  2895         List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
  2896         if (!typeAnnos.isEmpty())
  2897             ts.append(F.AnnotatedType(typeAnnos, qualident()));
  2898         else
  2899             ts.append(qualident());
  2900         while (S.token() == COMMA) {
  2901             S.nextToken();
  2903             typeAnnos = typeAnnotationsOpt();
  2904             if (!typeAnnos.isEmpty())
  2905                 ts.append(F.AnnotatedType(typeAnnos, qualident()));
  2906             else
  2907                 ts.append(qualident());
  2909         return ts.toList();
  2912     /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  2913      */
  2914     List<JCTypeParameter> typeParametersOpt() {
  2915         if (S.token() == LT) {
  2916             checkGenerics();
  2917             ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  2918             S.nextToken();
  2919             typarams.append(typeParameter());
  2920             while (S.token() == COMMA) {
  2921                 S.nextToken();
  2922                 typarams.append(typeParameter());
  2924             accept(GT);
  2925             return typarams.toList();
  2926         } else {
  2927             return List.nil();
  2931     /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
  2932      *  TypeParameterBound = EXTENDS Type {"&" Type}
  2933      *  TypeVariable = Ident
  2934      */
  2935     JCTypeParameter typeParameter() {
  2936         int pos = S.pos();
  2937         List<JCTypeAnnotation> annos = typeAnnotationsOpt();
  2938         Name name = ident();
  2939         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  2940         if (S.token() == EXTENDS) {
  2941             S.nextToken();
  2942             bounds.append(parseType());
  2943             while (S.token() == AMP) {
  2944                 S.nextToken();
  2945                 bounds.append(parseType());
  2948         return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
  2951     /** FormalParameters = "(" [ FormalParameterList ] ")"
  2952      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  2953      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  2954      */
  2955     List<JCVariableDecl> formalParameters() {
  2956         ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  2957         JCVariableDecl lastParam = null;
  2958         accept(LPAREN);
  2959         if (S.token() != RPAREN) {
  2960             params.append(lastParam = formalParameter());
  2961             while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
  2962                 S.nextToken();
  2963                 params.append(lastParam = formalParameter());
  2966         accept(RPAREN);
  2967         return params.toList();
  2970     JCModifiers optFinal(long flags) {
  2971         JCModifiers mods = modifiersOpt();
  2972         checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  2973         mods.flags |= flags;
  2974         return mods;
  2977     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  2978      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  2979      */
  2980     JCVariableDecl formalParameter() {
  2981         JCModifiers mods = optFinal(Flags.PARAMETER);
  2982         // need to distinguish between vararg annos and array annos
  2983         // look at typeAnnotaitonsPushedBack comment
  2984         this.permitTypeAnnotationsPushBack = true;
  2985         JCExpression type = parseType();
  2986         this.permitTypeAnnotationsPushBack = false;
  2988         if (S.token() == ELLIPSIS) {
  2989             List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
  2990             typeAnnotationsPushedBack = null;
  2991             checkVarargs();
  2992             mods.flags |= Flags.VARARGS;
  2993             // insert var arg type annotations
  2994             if (varargsAnnos != null && varargsAnnos.nonEmpty())
  2995                 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
  2996             type = to(F.at(S.pos()).TypeArray(type));
  2998             S.nextToken();
  2999         } else {
  3000             // if not a var arg, then typeAnnotationsPushedBack should be null
  3001             if (typeAnnotationsPushedBack != null
  3002                     && !typeAnnotationsPushedBack.isEmpty()) {
  3003                 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
  3004                         "illegal.start.of.type");
  3006             typeAnnotationsPushedBack = null;
  3008         return variableDeclaratorId(mods, type);
  3011 /* ---------- auxiliary methods -------------- */
  3013     /** Check that given tree is a legal expression statement.
  3014      */
  3015     protected JCExpression checkExprStat(JCExpression t) {
  3016         switch(t.getTag()) {
  3017         case JCTree.PREINC: case JCTree.PREDEC:
  3018         case JCTree.POSTINC: case JCTree.POSTDEC:
  3019         case JCTree.ASSIGN:
  3020         case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
  3021         case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
  3022         case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
  3023         case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
  3024         case JCTree.APPLY: case JCTree.NEWCLASS:
  3025         case JCTree.ERRONEOUS:
  3026             return t;
  3027         default:
  3028             log.error(t.pos, "not.stmt");
  3029             return F.at(t.pos).Erroneous(List.<JCTree>of(t));
  3033     /** Return precedence of operator represented by token,
  3034      *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  3035      */
  3036     static int prec(Token token) {
  3037         int oc = optag(token);
  3038         return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
  3041     /**
  3042      * Return the lesser of two positions, making allowance for either one
  3043      * being unset.
  3044      */
  3045     static int earlier(int pos1, int pos2) {
  3046         if (pos1 == Position.NOPOS)
  3047             return pos2;
  3048         if (pos2 == Position.NOPOS)
  3049             return pos1;
  3050         return (pos1 < pos2 ? pos1 : pos2);
  3053     /** Return operation tag of binary operator represented by token,
  3054      *  -1 if token is not a binary operator.
  3055      */
  3056     static int optag(Token token) {
  3057         switch (token) {
  3058         case BARBAR:
  3059             return JCTree.OR;
  3060         case AMPAMP:
  3061             return JCTree.AND;
  3062         case BAR:
  3063             return JCTree.BITOR;
  3064         case BAREQ:
  3065             return JCTree.BITOR_ASG;
  3066         case CARET:
  3067             return JCTree.BITXOR;
  3068         case CARETEQ:
  3069             return JCTree.BITXOR_ASG;
  3070         case AMP:
  3071             return JCTree.BITAND;
  3072         case AMPEQ:
  3073             return JCTree.BITAND_ASG;
  3074         case EQEQ:
  3075             return JCTree.EQ;
  3076         case BANGEQ:
  3077             return JCTree.NE;
  3078         case LT:
  3079             return JCTree.LT;
  3080         case GT:
  3081             return JCTree.GT;
  3082         case LTEQ:
  3083             return JCTree.LE;
  3084         case GTEQ:
  3085             return JCTree.GE;
  3086         case LTLT:
  3087             return JCTree.SL;
  3088         case LTLTEQ:
  3089             return JCTree.SL_ASG;
  3090         case GTGT:
  3091             return JCTree.SR;
  3092         case GTGTEQ:
  3093             return JCTree.SR_ASG;
  3094         case GTGTGT:
  3095             return JCTree.USR;
  3096         case GTGTGTEQ:
  3097             return JCTree.USR_ASG;
  3098         case PLUS:
  3099             return JCTree.PLUS;
  3100         case PLUSEQ:
  3101             return JCTree.PLUS_ASG;
  3102         case SUB:
  3103             return JCTree.MINUS;
  3104         case SUBEQ:
  3105             return JCTree.MINUS_ASG;
  3106         case STAR:
  3107             return JCTree.MUL;
  3108         case STAREQ:
  3109             return JCTree.MUL_ASG;
  3110         case SLASH:
  3111             return JCTree.DIV;
  3112         case SLASHEQ:
  3113             return JCTree.DIV_ASG;
  3114         case PERCENT:
  3115             return JCTree.MOD;
  3116         case PERCENTEQ:
  3117             return JCTree.MOD_ASG;
  3118         case INSTANCEOF:
  3119             return JCTree.TYPETEST;
  3120         default:
  3121             return -1;
  3125     /** Return operation tag of unary operator represented by token,
  3126      *  -1 if token is not a binary operator.
  3127      */
  3128     static int unoptag(Token token) {
  3129         switch (token) {
  3130         case PLUS:
  3131             return JCTree.POS;
  3132         case SUB:
  3133             return JCTree.NEG;
  3134         case BANG:
  3135             return JCTree.NOT;
  3136         case TILDE:
  3137             return JCTree.COMPL;
  3138         case PLUSPLUS:
  3139             return JCTree.PREINC;
  3140         case SUBSUB:
  3141             return JCTree.PREDEC;
  3142         default:
  3143             return -1;
  3147     /** Return type tag of basic type represented by token,
  3148      *  -1 if token is not a basic type identifier.
  3149      */
  3150     static int typetag(Token token) {
  3151         switch (token) {
  3152         case BYTE:
  3153             return TypeTags.BYTE;
  3154         case CHAR:
  3155             return TypeTags.CHAR;
  3156         case SHORT:
  3157             return TypeTags.SHORT;
  3158         case INT:
  3159             return TypeTags.INT;
  3160         case LONG:
  3161             return TypeTags.LONG;
  3162         case FLOAT:
  3163             return TypeTags.FLOAT;
  3164         case DOUBLE:
  3165             return TypeTags.DOUBLE;
  3166         case BOOLEAN:
  3167             return TypeTags.BOOLEAN;
  3168         default:
  3169             return -1;
  3173     void checkGenerics() {
  3174         if (!allowGenerics) {
  3175             log.error(S.pos(), "generics.not.supported.in.source", source.name);
  3176             allowGenerics = true;
  3179     void checkVarargs() {
  3180         if (!allowVarargs) {
  3181             log.error(S.pos(), "varargs.not.supported.in.source", source.name);
  3182             allowVarargs = true;
  3185     void checkForeach() {
  3186         if (!allowForeach) {
  3187             log.error(S.pos(), "foreach.not.supported.in.source", source.name);
  3188             allowForeach = true;
  3191     void checkStaticImports() {
  3192         if (!allowStaticImport) {
  3193             log.error(S.pos(), "static.import.not.supported.in.source", source.name);
  3194             allowStaticImport = true;
  3197     void checkAnnotations() {
  3198         if (!allowAnnotations) {
  3199             log.error(S.pos(), "annotations.not.supported.in.source", source.name);
  3200             allowAnnotations = true;
  3203     void checkTypeAnnotations() {
  3204         if (!allowTypeAnnotations) {
  3205             log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
  3206             allowTypeAnnotations = true;
  3209     void checkDiamond() {
  3210         if (!allowDiamond) {
  3211             log.error(S.pos(), "diamond.not.supported.in.source", source.name);
  3212             allowDiamond = true;
  3215     void checkMulticatch() {
  3216         if (!allowMulticatch) {
  3217             log.error(S.pos(), "multicatch.not.supported.in.source", source.name);
  3218             allowMulticatch = true;

mercurial