6724118: change JavaCompiler to not use Scanner directly

Tue, 09 Sep 2008 10:40:50 -0700

author
jjg
date
Tue, 09 Sep 2008 10:40:50 -0700
changeset 111
a92b756a888f
parent 110
91eea580fbe9
child 112
7e2249b1c13d

6724118: change JavaCompiler to not use Scanner directly
6736119: refactor Parser and Parser.Factory
Reviewed-by: mcimadamore

src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/main/JavaCompiler.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/EndPosParser.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/JavacParser.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/Parser.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/ParserFactory.java file | annotate | diff | comparison | revisions
test/tools/javac/6304921/TestLog.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Tue Sep 09 10:28:21 2008 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Tue Sep 09 10:40:50 2008 -0700
     1.3 @@ -27,6 +27,7 @@
     1.4  
     1.5  import java.io.File;
     1.6  import java.io.IOException;
     1.7 +import java.nio.CharBuffer;
     1.8  import java.util.*;
     1.9  import java.util.concurrent.atomic.AtomicBoolean;
    1.10  
    1.11 @@ -45,7 +46,7 @@
    1.12  import com.sun.tools.javac.main.*;
    1.13  import com.sun.tools.javac.model.*;
    1.14  import com.sun.tools.javac.parser.Parser;
    1.15 -import com.sun.tools.javac.parser.Scanner;
    1.16 +import com.sun.tools.javac.parser.ParserFactory;
    1.17  import com.sun.tools.javac.tree.*;
    1.18  import com.sun.tools.javac.tree.JCTree.*;
    1.19  import com.sun.tools.javac.util.*;
    1.20 @@ -93,6 +94,9 @@
    1.21          args.getClass();
    1.22          context.getClass();
    1.23          fileObjects.getClass();
    1.24 +
    1.25 +        // force the use of the scanner that captures Javadoc comments
    1.26 +        com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context);
    1.27      }
    1.28  
    1.29      JavacTaskImpl(JavacTool tool,
    1.30 @@ -166,8 +170,6 @@
    1.31              if (!filenames.isEmpty())
    1.32                  throw new IllegalArgumentException("Malformed arguments " + filenames.toString(" "));
    1.33              compiler = JavaCompiler.instance(context);
    1.34 -            // force the use of the scanner that captures Javadoc comments
    1.35 -            com.sun.tools.javac.parser.DocCommentScanner.Factory.preRegister(context);
    1.36              compiler.keepComments = true;
    1.37              compiler.genEndPos = true;
    1.38              // NOTE: this value will be updated after annotation processing
    1.39 @@ -519,14 +521,12 @@
    1.40              throw new IllegalArgumentException();
    1.41          compiler = JavaCompiler.instance(context);
    1.42          JavaFileObject prev = compiler.log.useSource(null);
    1.43 -        Scanner.Factory scannerFactory = Scanner.Factory.instance(context);
    1.44 -        Parser.Factory parserFactory = Parser.Factory.instance(context);
    1.45 +        ParserFactory parserFactory = ParserFactory.instance(context);
    1.46          Attr attr = Attr.instance(context);
    1.47          try {
    1.48 -            Scanner scanner = scannerFactory.newScanner((expr+"\u0000").toCharArray(),
    1.49 -                                                        expr.length());
    1.50 -            Parser parser = parserFactory.newParser(scanner, false, false);
    1.51 -            JCTree tree = parser.type();
    1.52 +            CharBuffer buf = CharBuffer.wrap((expr+"\u0000").toCharArray(), 0, expr.length());
    1.53 +            Parser parser = parserFactory.newParser(buf, false, false, false);
    1.54 +            JCTree tree = parser.parseType();
    1.55              return attr.attribType(tree, (Symbol.TypeSymbol)scope);
    1.56          } finally {
    1.57              compiler.log.useSource(prev);
     2.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Sep 09 10:28:21 2008 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Tue Sep 09 10:40:50 2008 -0700
     2.3 @@ -276,7 +276,7 @@
     2.4  
     2.5      /** Factory for parsers.
     2.6       */
     2.7 -    protected Parser.Factory parserFactory;
     2.8 +    protected ParserFactory parserFactory;
     2.9  
    2.10      /** Optional listener for progress events
    2.11       */
    2.12 @@ -320,7 +320,7 @@
    2.13          todo = Todo.instance(context);
    2.14  
    2.15          fileManager = context.get(JavaFileManager.class);
    2.16 -        parserFactory = Parser.Factory.instance(context);
    2.17 +        parserFactory = ParserFactory.instance(context);
    2.18  
    2.19          try {
    2.20              // catch completion problems with predefineds
    2.21 @@ -510,10 +510,6 @@
    2.22          return parseErrors;
    2.23      }
    2.24  
    2.25 -    protected Scanner.Factory getScannerFactory() {
    2.26 -        return Scanner.Factory.instance(context);
    2.27 -    }
    2.28 -
    2.29      /** Try to open input stream with given name.
    2.30       *  Report an error if this fails.
    2.31       *  @param filename   The file name of the input stream to be opened.
    2.32 @@ -545,13 +541,9 @@
    2.33                  taskListener.started(e);
    2.34              }
    2.35              int initialErrorCount = log.nerrors;
    2.36 -            Scanner scanner = getScannerFactory().newScanner(content);
    2.37 -            Parser parser = parserFactory.newParser(scanner, keepComments(), genEndPos);
    2.38 -            tree = parser.compilationUnit();
    2.39 +            Parser parser = parserFactory.newParser(content, keepComments(), genEndPos, lineDebugInfo);
    2.40 +            tree = parser.parseCompilationUnit();
    2.41              parseErrors |= (log.nerrors > initialErrorCount);
    2.42 -            if (lineDebugInfo) {
    2.43 -                tree.lineMap = scanner.getLineMap();
    2.44 -            }
    2.45              if (verbose) {
    2.46                  printVerbose("parsing.done", Long.toString(elapsed(msec)));
    2.47              }
     3.1 --- a/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java	Tue Sep 09 10:28:21 2008 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java	Tue Sep 09 10:40:50 2008 -0700
     3.3 @@ -41,10 +41,10 @@
     3.4   * This code and its internal interfaces are subject to change or
     3.5   * deletion without notice.</b></p>
     3.6   */
     3.7 -public class EndPosParser extends Parser {
     3.8 +public class EndPosParser extends JavacParser {
     3.9  
    3.10 -    public EndPosParser(Factory fac, Lexer S, boolean keepDocComments) {
    3.11 -        super(fac, S, keepDocComments);
    3.12 +    public EndPosParser(ParserFactory fac, Lexer S, boolean keepDocComments, boolean keepLineMap) {
    3.13 +        super(fac, S, keepDocComments, keepLineMap);
    3.14          this.S = S;
    3.15          endPositions = new HashMap<JCTree,Integer>();
    3.16      }
    3.17 @@ -79,8 +79,8 @@
    3.18      }
    3.19  
    3.20      @Override
    3.21 -    public JCCompilationUnit compilationUnit() {
    3.22 -        JCCompilationUnit t = super.compilationUnit();
    3.23 +    public JCCompilationUnit parseCompilationUnit() {
    3.24 +        JCCompilationUnit t = super.parseCompilationUnit();
    3.25          t.endPositions = endPositions;
    3.26          return t;
    3.27      }
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Sep 09 10:40:50 2008 -0700
     4.3 @@ -0,0 +1,2819 @@
     4.4 +/*
     4.5 + * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
     4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.7 + *
     4.8 + * This code is free software; you can redistribute it and/or modify it
     4.9 + * under the terms of the GNU General Public License version 2 only, as
    4.10 + * published by the Free Software Foundation.  Sun designates this
    4.11 + * particular file as subject to the "Classpath" exception as provided
    4.12 + * by Sun in the LICENSE file that accompanied this code.
    4.13 + *
    4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    4.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    4.17 + * version 2 for more details (a copy is included in the LICENSE file that
    4.18 + * accompanied this code).
    4.19 + *
    4.20 + * You should have received a copy of the GNU General Public License version
    4.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    4.23 + *
    4.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    4.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    4.26 + * have any questions.
    4.27 + */
    4.28 +
    4.29 +package com.sun.tools.javac.parser;
    4.30 +
    4.31 +import java.util.*;
    4.32 +
    4.33 +import com.sun.tools.javac.tree.*;
    4.34 +import com.sun.tools.javac.code.*;
    4.35 +import com.sun.tools.javac.util.*;
    4.36 +import com.sun.tools.javac.util.List;
    4.37 +import static com.sun.tools.javac.util.ListBuffer.lb;
    4.38 +
    4.39 +import com.sun.tools.javac.tree.JCTree.*;
    4.40 +
    4.41 +import static com.sun.tools.javac.parser.Token.*;
    4.42 +
    4.43 +/** The parser maps a token sequence into an abstract syntax
    4.44 + *  tree. It operates by recursive descent, with code derived
    4.45 + *  systematically from an LL(1) grammar. For efficiency reasons, an
    4.46 + *  operator precedence scheme is used for parsing binary operation
    4.47 + *  expressions.
    4.48 + *
    4.49 + *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    4.50 + *  you write code that depends on this, you do so at your own risk.
    4.51 + *  This code and its internal interfaces are subject to change or
    4.52 + *  deletion without notice.</b>
    4.53 + */
    4.54 +public class JavacParser implements Parser {
    4.55 +
    4.56 +    /** The number of precedence levels of infix operators.
    4.57 +     */
    4.58 +    private static final int infixPrecedenceLevels = 10;
    4.59 +
    4.60 +    /** The scanner used for lexical analysis.
    4.61 +     */
    4.62 +    private Lexer S;
    4.63 +
    4.64 +    /** The factory to be used for abstract syntax tree construction.
    4.65 +     */
    4.66 +    protected TreeMaker F;
    4.67 +
    4.68 +    /** The log to be used for error diagnostics.
    4.69 +     */
    4.70 +    private Log log;
    4.71 +
    4.72 +    /** The keyword table. */
    4.73 +    private Keywords keywords;
    4.74 +
    4.75 +    /** The Source language setting. */
    4.76 +    private Source source;
    4.77 +
    4.78 +    /** The name table. */
    4.79 +    private Name.Table names;
    4.80 +
    4.81 +    /** Construct a parser from a given scanner, tree factory and log.
    4.82 +     */
    4.83 +    protected JavacParser(ParserFactory fac,
    4.84 +                     Lexer S,
    4.85 +                     boolean keepDocComments,
    4.86 +                     boolean keepLineMap) {
    4.87 +        this.S = S;
    4.88 +        S.nextToken(); // prime the pump
    4.89 +        this.F = fac.F;
    4.90 +        this.log = fac.log;
    4.91 +        this.names = fac.names;
    4.92 +        this.keywords = fac.keywords;
    4.93 +        this.source = fac.source;
    4.94 +        this.allowGenerics = source.allowGenerics();
    4.95 +        this.allowVarargs = source.allowVarargs();
    4.96 +        this.allowAsserts = source.allowAsserts();
    4.97 +        this.allowEnums = source.allowEnums();
    4.98 +        this.allowForeach = source.allowForeach();
    4.99 +        this.allowStaticImport = source.allowStaticImport();
   4.100 +        this.allowAnnotations = source.allowAnnotations();
   4.101 +        this.keepDocComments = keepDocComments;
   4.102 +        if (keepDocComments)
   4.103 +            docComments = new HashMap<JCTree,String>();
   4.104 +        this.keepLineMap = keepLineMap;
   4.105 +        this.errorTree = F.Erroneous();
   4.106 +    }
   4.107 +
   4.108 +    /** Switch: Should generics be recognized?
   4.109 +     */
   4.110 +    boolean allowGenerics;
   4.111 +
   4.112 +    /** Switch: Should varargs be recognized?
   4.113 +     */
   4.114 +    boolean allowVarargs;
   4.115 +
   4.116 +    /** Switch: should we recognize assert statements, or just give a warning?
   4.117 +     */
   4.118 +    boolean allowAsserts;
   4.119 +
   4.120 +    /** Switch: should we recognize enums, or just give a warning?
   4.121 +     */
   4.122 +    boolean allowEnums;
   4.123 +
   4.124 +    /** Switch: should we recognize foreach?
   4.125 +     */
   4.126 +    boolean allowForeach;
   4.127 +
   4.128 +    /** Switch: should we recognize foreach?
   4.129 +     */
   4.130 +    boolean allowStaticImport;
   4.131 +
   4.132 +    /** Switch: should we recognize annotations?
   4.133 +     */
   4.134 +    boolean allowAnnotations;
   4.135 +
   4.136 +    /** Switch: should we keep docComments?
   4.137 +     */
   4.138 +    boolean keepDocComments;
   4.139 +
   4.140 +    /** Switch: should we keep line table?
   4.141 +     */
   4.142 +    boolean keepLineMap;
   4.143 +
   4.144 +    /** When terms are parsed, the mode determines which is expected:
   4.145 +     *     mode = EXPR        : an expression
   4.146 +     *     mode = TYPE        : a type
   4.147 +     *     mode = NOPARAMS    : no parameters allowed for type
   4.148 +     *     mode = TYPEARG     : type argument
   4.149 +     */
   4.150 +    static final int EXPR = 1;
   4.151 +    static final int TYPE = 2;
   4.152 +    static final int NOPARAMS = 4;
   4.153 +    static final int TYPEARG = 8;
   4.154 +
   4.155 +    /** The current mode.
   4.156 +     */
   4.157 +    private int mode = 0;
   4.158 +
   4.159 +    /** The mode of the term that was parsed last.
   4.160 +     */
   4.161 +    private int lastmode = 0;
   4.162 +
   4.163 +/* ---------- error recovery -------------- */
   4.164 +
   4.165 +    private JCErroneous errorTree;
   4.166 +
   4.167 +    /** Skip forward until a suitable stop token is found.
   4.168 +     */
   4.169 +    private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   4.170 +         while (true) {
   4.171 +             switch (S.token()) {
   4.172 +                case SEMI:
   4.173 +                    S.nextToken();
   4.174 +                    return;
   4.175 +                case PUBLIC:
   4.176 +                case FINAL:
   4.177 +                case ABSTRACT:
   4.178 +                case MONKEYS_AT:
   4.179 +                case EOF:
   4.180 +                case CLASS:
   4.181 +                case INTERFACE:
   4.182 +                case ENUM:
   4.183 +                    return;
   4.184 +                case IMPORT:
   4.185 +                    if (stopAtImport)
   4.186 +                        return;
   4.187 +                    break;
   4.188 +                case LBRACE:
   4.189 +                case RBRACE:
   4.190 +                case PRIVATE:
   4.191 +                case PROTECTED:
   4.192 +                case STATIC:
   4.193 +                case TRANSIENT:
   4.194 +                case NATIVE:
   4.195 +                case VOLATILE:
   4.196 +                case SYNCHRONIZED:
   4.197 +                case STRICTFP:
   4.198 +                case LT:
   4.199 +                case BYTE:
   4.200 +                case SHORT:
   4.201 +                case CHAR:
   4.202 +                case INT:
   4.203 +                case LONG:
   4.204 +                case FLOAT:
   4.205 +                case DOUBLE:
   4.206 +                case BOOLEAN:
   4.207 +                case VOID:
   4.208 +                    if (stopAtMemberDecl)
   4.209 +                        return;
   4.210 +                    break;
   4.211 +                case IDENTIFIER:
   4.212 +                   if (stopAtIdentifier)
   4.213 +                        return;
   4.214 +                    break;
   4.215 +                case CASE:
   4.216 +                case DEFAULT:
   4.217 +                case IF:
   4.218 +                case FOR:
   4.219 +                case WHILE:
   4.220 +                case DO:
   4.221 +                case TRY:
   4.222 +                case SWITCH:
   4.223 +                case RETURN:
   4.224 +                case THROW:
   4.225 +                case BREAK:
   4.226 +                case CONTINUE:
   4.227 +                case ELSE:
   4.228 +                case FINALLY:
   4.229 +                case CATCH:
   4.230 +                    if (stopAtStatement)
   4.231 +                        return;
   4.232 +                    break;
   4.233 +            }
   4.234 +            S.nextToken();
   4.235 +        }
   4.236 +    }
   4.237 +
   4.238 +    private JCErroneous syntaxError(int pos, String key, Token... args) {
   4.239 +        return syntaxError(pos, null, key, args);
   4.240 +    }
   4.241 +
   4.242 +    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
   4.243 +        setErrorEndPos(pos);
   4.244 +        reportSyntaxError(pos, key, (Object[])args);
   4.245 +        return toP(F.at(pos).Erroneous(errs));
   4.246 +    }
   4.247 +
   4.248 +    private int errorPos = Position.NOPOS;
   4.249 +    /**
   4.250 +     * Report a syntax error at given position using the given
   4.251 +     * argument unless one was already reported at the same position.
   4.252 +     */
   4.253 +    private void reportSyntaxError(int pos, String key, Object... args) {
   4.254 +        if (pos > S.errPos() || pos == Position.NOPOS) {
   4.255 +            if (S.token() == EOF)
   4.256 +                log.error(pos, "premature.eof");
   4.257 +            else
   4.258 +                log.error(pos, key, args);
   4.259 +        }
   4.260 +        S.errPos(pos);
   4.261 +        if (S.pos() == errorPos)
   4.262 +            S.nextToken(); // guarantee progress
   4.263 +        errorPos = S.pos();
   4.264 +    }
   4.265 +
   4.266 +
   4.267 +    /** Generate a syntax error at current position unless one was already
   4.268 +     *  reported at the same position.
   4.269 +     */
   4.270 +    private JCErroneous syntaxError(String key) {
   4.271 +        return syntaxError(S.pos(), key);
   4.272 +    }
   4.273 +
   4.274 +    /** Generate a syntax error at current position unless one was
   4.275 +     *  already reported at the same position.
   4.276 +     */
   4.277 +    private JCErroneous syntaxError(String key, Token arg) {
   4.278 +        return syntaxError(S.pos(), key, arg);
   4.279 +    }
   4.280 +
   4.281 +    /** If next input token matches given token, skip it, otherwise report
   4.282 +     *  an error.
   4.283 +     */
   4.284 +    public void accept(Token token) {
   4.285 +        if (S.token() == token) {
   4.286 +            S.nextToken();
   4.287 +        } else {
   4.288 +            setErrorEndPos(S.pos());
   4.289 +            reportSyntaxError(S.prevEndPos(), "expected", token);
   4.290 +        }
   4.291 +    }
   4.292 +
   4.293 +    /** Report an illegal start of expression/type error at given position.
   4.294 +     */
   4.295 +    JCExpression illegal(int pos) {
   4.296 +        setErrorEndPos(S.pos());
   4.297 +        if ((mode & EXPR) != 0)
   4.298 +            return syntaxError(pos, "illegal.start.of.expr");
   4.299 +        else
   4.300 +            return syntaxError(pos, "illegal.start.of.type");
   4.301 +
   4.302 +    }
   4.303 +
   4.304 +    /** Report an illegal start of expression/type error at current position.
   4.305 +     */
   4.306 +    JCExpression illegal() {
   4.307 +        return illegal(S.pos());
   4.308 +    }
   4.309 +
   4.310 +    /** Diagnose a modifier flag from the set, if any. */
   4.311 +    void checkNoMods(long mods) {
   4.312 +        if (mods != 0) {
   4.313 +            long lowestMod = mods & -mods;
   4.314 +            log.error(S.pos(), "mod.not.allowed.here",
   4.315 +                      Flags.asFlagSet(lowestMod));
   4.316 +        }
   4.317 +    }
   4.318 +
   4.319 +/* ---------- doc comments --------- */
   4.320 +
   4.321 +    /** A hashtable to store all documentation comments
   4.322 +     *  indexed by the tree nodes they refer to.
   4.323 +     *  defined only if option flag keepDocComment is set.
   4.324 +     */
   4.325 +    Map<JCTree, String> docComments;
   4.326 +
   4.327 +    /** Make an entry into docComments hashtable,
   4.328 +     *  provided flag keepDocComments is set and given doc comment is non-null.
   4.329 +     *  @param tree   The tree to be used as index in the hashtable
   4.330 +     *  @param dc     The doc comment to associate with the tree, or null.
   4.331 +     */
   4.332 +    void attach(JCTree tree, String dc) {
   4.333 +        if (keepDocComments && dc != null) {
   4.334 +//          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   4.335 +            docComments.put(tree, dc);
   4.336 +        }
   4.337 +    }
   4.338 +
   4.339 +/* -------- source positions ------- */
   4.340 +
   4.341 +    private int errorEndPos = -1;
   4.342 +
   4.343 +    private void setErrorEndPos(int errPos) {
   4.344 +        if (errPos > errorEndPos)
   4.345 +            errorEndPos = errPos;
   4.346 +    }
   4.347 +
   4.348 +    protected int getErrorEndPos() {
   4.349 +        return errorEndPos;
   4.350 +    }
   4.351 +
   4.352 +    /**
   4.353 +     * Store ending position for a tree.
   4.354 +     * @param tree   The tree.
   4.355 +     * @param endpos The ending position to associate with the tree.
   4.356 +     */
   4.357 +    protected void storeEnd(JCTree tree, int endpos) {}
   4.358 +
   4.359 +    /**
   4.360 +     * Store ending position for a tree.  The ending position should
   4.361 +     * be the ending position of the current token.
   4.362 +     * @param t The tree.
   4.363 +     */
   4.364 +    protected <T extends JCTree> T to(T t) { return t; }
   4.365 +
   4.366 +    /**
   4.367 +     * Store ending position for a tree.  The ending position should
   4.368 +     * be greater of the ending position of the previous token and errorEndPos.
   4.369 +     * @param t The tree.
   4.370 +     */
   4.371 +    protected <T extends JCTree> T toP(T t) { return t; }
   4.372 +
   4.373 +    /** Get the start position for a tree node.  The start position is
   4.374 +     * defined to be the position of the first character of the first
   4.375 +     * token of the node's source text.
   4.376 +     * @param tree  The tree node
   4.377 +     */
   4.378 +    public int getStartPos(JCTree tree) {
   4.379 +        return TreeInfo.getStartPos(tree);
   4.380 +    }
   4.381 +
   4.382 +    /**
   4.383 +     * Get the end position for a tree node.  The end position is
   4.384 +     * defined to be the position of the last character of the last
   4.385 +     * token of the node's source text.  Returns Position.NOPOS if end
   4.386 +     * positions are not generated or the position is otherwise not
   4.387 +     * found.
   4.388 +     * @param tree  The tree node
   4.389 +     */
   4.390 +    public int getEndPos(JCTree tree) {
   4.391 +        return Position.NOPOS;
   4.392 +    }
   4.393 +
   4.394 +
   4.395 +
   4.396 +/* ---------- parsing -------------- */
   4.397 +
   4.398 +    /**
   4.399 +     * Ident = IDENTIFIER
   4.400 +     */
   4.401 +    Name ident() {
   4.402 +        if (S.token() == IDENTIFIER) {
   4.403 +            Name name = S.name();
   4.404 +            S.nextToken();
   4.405 +            return name;
   4.406 +        } else if (S.token() == ASSERT) {
   4.407 +            if (allowAsserts) {
   4.408 +                log.error(S.pos(), "assert.as.identifier");
   4.409 +                S.nextToken();
   4.410 +                return names.error;
   4.411 +            } else {
   4.412 +                log.warning(S.pos(), "assert.as.identifier");
   4.413 +                Name name = S.name();
   4.414 +                S.nextToken();
   4.415 +                return name;
   4.416 +            }
   4.417 +        } else if (S.token() == ENUM) {
   4.418 +            if (allowEnums) {
   4.419 +                log.error(S.pos(), "enum.as.identifier");
   4.420 +                S.nextToken();
   4.421 +                return names.error;
   4.422 +            } else {
   4.423 +                log.warning(S.pos(), "enum.as.identifier");
   4.424 +                Name name = S.name();
   4.425 +                S.nextToken();
   4.426 +                return name;
   4.427 +            }
   4.428 +        } else {
   4.429 +            accept(IDENTIFIER);
   4.430 +            return names.error;
   4.431 +        }
   4.432 +}
   4.433 +
   4.434 +    /**
   4.435 +     * Qualident = Ident { DOT Ident }
   4.436 +     */
   4.437 +    public JCExpression qualident() {
   4.438 +        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
   4.439 +        while (S.token() == DOT) {
   4.440 +            int pos = S.pos();
   4.441 +            S.nextToken();
   4.442 +            t = toP(F.at(pos).Select(t, ident()));
   4.443 +        }
   4.444 +        return t;
   4.445 +    }
   4.446 +
   4.447 +    /**
   4.448 +     * Literal =
   4.449 +     *     INTLITERAL
   4.450 +     *   | LONGLITERAL
   4.451 +     *   | FLOATLITERAL
   4.452 +     *   | DOUBLELITERAL
   4.453 +     *   | CHARLITERAL
   4.454 +     *   | STRINGLITERAL
   4.455 +     *   | TRUE
   4.456 +     *   | FALSE
   4.457 +     *   | NULL
   4.458 +     */
   4.459 +    JCExpression literal(Name prefix) {
   4.460 +        int pos = S.pos();
   4.461 +        JCExpression t = errorTree;
   4.462 +        switch (S.token()) {
   4.463 +        case INTLITERAL:
   4.464 +            try {
   4.465 +                t = F.at(pos).Literal(
   4.466 +                    TypeTags.INT,
   4.467 +                    Convert.string2int(strval(prefix), S.radix()));
   4.468 +            } catch (NumberFormatException ex) {
   4.469 +                log.error(S.pos(), "int.number.too.large", strval(prefix));
   4.470 +            }
   4.471 +            break;
   4.472 +        case LONGLITERAL:
   4.473 +            try {
   4.474 +                t = F.at(pos).Literal(
   4.475 +                    TypeTags.LONG,
   4.476 +                    new Long(Convert.string2long(strval(prefix), S.radix())));
   4.477 +            } catch (NumberFormatException ex) {
   4.478 +                log.error(S.pos(), "int.number.too.large", strval(prefix));
   4.479 +            }
   4.480 +            break;
   4.481 +        case FLOATLITERAL: {
   4.482 +            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   4.483 +            Float n;
   4.484 +            try {
   4.485 +                n = Float.valueOf(proper);
   4.486 +            } catch (NumberFormatException ex) {
   4.487 +                // error already repoted in scanner
   4.488 +                n = Float.NaN;
   4.489 +            }
   4.490 +            if (n.floatValue() == 0.0f && !isZero(proper))
   4.491 +                log.error(S.pos(), "fp.number.too.small");
   4.492 +            else if (n.floatValue() == Float.POSITIVE_INFINITY)
   4.493 +                log.error(S.pos(), "fp.number.too.large");
   4.494 +            else
   4.495 +                t = F.at(pos).Literal(TypeTags.FLOAT, n);
   4.496 +            break;
   4.497 +        }
   4.498 +        case DOUBLELITERAL: {
   4.499 +            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   4.500 +            Double n;
   4.501 +            try {
   4.502 +                n = Double.valueOf(proper);
   4.503 +            } catch (NumberFormatException ex) {
   4.504 +                // error already reported in scanner
   4.505 +                n = Double.NaN;
   4.506 +            }
   4.507 +            if (n.doubleValue() == 0.0d && !isZero(proper))
   4.508 +                log.error(S.pos(), "fp.number.too.small");
   4.509 +            else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   4.510 +                log.error(S.pos(), "fp.number.too.large");
   4.511 +            else
   4.512 +                t = F.at(pos).Literal(TypeTags.DOUBLE, n);
   4.513 +            break;
   4.514 +        }
   4.515 +        case CHARLITERAL:
   4.516 +            t = F.at(pos).Literal(
   4.517 +                TypeTags.CHAR,
   4.518 +                S.stringVal().charAt(0) + 0);
   4.519 +            break;
   4.520 +        case STRINGLITERAL:
   4.521 +            t = F.at(pos).Literal(
   4.522 +                TypeTags.CLASS,
   4.523 +                S.stringVal());
   4.524 +            break;
   4.525 +        case TRUE: case FALSE:
   4.526 +            t = F.at(pos).Literal(
   4.527 +                TypeTags.BOOLEAN,
   4.528 +                (S.token() == TRUE ? 1 : 0));
   4.529 +            break;
   4.530 +        case NULL:
   4.531 +            t = F.at(pos).Literal(
   4.532 +                TypeTags.BOT,
   4.533 +                null);
   4.534 +            break;
   4.535 +        default:
   4.536 +            assert false;
   4.537 +        }
   4.538 +        if (t == errorTree)
   4.539 +            t = F.at(pos).Erroneous();
   4.540 +        storeEnd(t, S.endPos());
   4.541 +        S.nextToken();
   4.542 +        return t;
   4.543 +    }
   4.544 +//where
   4.545 +        boolean isZero(String s) {
   4.546 +            char[] cs = s.toCharArray();
   4.547 +            int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10);
   4.548 +            int i = ((base==16) ? 2 : 0);
   4.549 +            while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   4.550 +            return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   4.551 +        }
   4.552 +
   4.553 +        String strval(Name prefix) {
   4.554 +            String s = S.stringVal();
   4.555 +            return (prefix.len == 0) ? s : prefix + s;
   4.556 +        }
   4.557 +
   4.558 +    /** terms can be either expressions or types.
   4.559 +     */
   4.560 +    public JCExpression parseExpression() {
   4.561 +        return term(EXPR);
   4.562 +    }
   4.563 +
   4.564 +    public JCExpression parseType() {
   4.565 +        return term(TYPE);
   4.566 +    }
   4.567 +
   4.568 +    JCExpression term(int newmode) {
   4.569 +        int prevmode = mode;
   4.570 +        mode = newmode;
   4.571 +        JCExpression t = term();
   4.572 +        lastmode = mode;
   4.573 +        mode = prevmode;
   4.574 +        return t;
   4.575 +    }
   4.576 +
   4.577 +    /**
   4.578 +     *  Expression = Expression1 [ExpressionRest]
   4.579 +     *  ExpressionRest = [AssignmentOperator Expression1]
   4.580 +     *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   4.581 +     *                       "&=" | "|=" | "^=" |
   4.582 +     *                       "%=" | "<<=" | ">>=" | ">>>="
   4.583 +     *  Type = Type1
   4.584 +     *  TypeNoParams = TypeNoParams1
   4.585 +     *  StatementExpression = Expression
   4.586 +     *  ConstantExpression = Expression
   4.587 +     */
   4.588 +    JCExpression term() {
   4.589 +        JCExpression t = term1();
   4.590 +        if ((mode & EXPR) != 0 &&
   4.591 +            S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
   4.592 +            return termRest(t);
   4.593 +        else
   4.594 +            return t;
   4.595 +    }
   4.596 +
   4.597 +    JCExpression termRest(JCExpression t) {
   4.598 +        switch (S.token()) {
   4.599 +        case EQ: {
   4.600 +            int pos = S.pos();
   4.601 +            S.nextToken();
   4.602 +            mode = EXPR;
   4.603 +            JCExpression t1 = term();
   4.604 +            return toP(F.at(pos).Assign(t, t1));
   4.605 +        }
   4.606 +        case PLUSEQ:
   4.607 +        case SUBEQ:
   4.608 +        case STAREQ:
   4.609 +        case SLASHEQ:
   4.610 +        case PERCENTEQ:
   4.611 +        case AMPEQ:
   4.612 +        case BAREQ:
   4.613 +        case CARETEQ:
   4.614 +        case LTLTEQ:
   4.615 +        case GTGTEQ:
   4.616 +        case GTGTGTEQ:
   4.617 +            int pos = S.pos();
   4.618 +            Token token = S.token();
   4.619 +            S.nextToken();
   4.620 +            mode = EXPR;
   4.621 +            JCExpression t1 = term();
   4.622 +            return F.at(pos).Assignop(optag(token), t, t1);
   4.623 +        default:
   4.624 +            return t;
   4.625 +        }
   4.626 +    }
   4.627 +
   4.628 +    /** Expression1   = Expression2 [Expression1Rest]
   4.629 +     *  Type1         = Type2
   4.630 +     *  TypeNoParams1 = TypeNoParams2
   4.631 +     */
   4.632 +    JCExpression term1() {
   4.633 +        JCExpression t = term2();
   4.634 +        if ((mode & EXPR) != 0 && S.token() == QUES) {
   4.635 +            mode = EXPR;
   4.636 +            return term1Rest(t);
   4.637 +        } else {
   4.638 +            return t;
   4.639 +        }
   4.640 +    }
   4.641 +
   4.642 +    /** Expression1Rest = ["?" Expression ":" Expression1]
   4.643 +     */
   4.644 +    JCExpression term1Rest(JCExpression t) {
   4.645 +        if (S.token() == QUES) {
   4.646 +            int pos = S.pos();
   4.647 +            S.nextToken();
   4.648 +            JCExpression t1 = term();
   4.649 +            accept(COLON);
   4.650 +            JCExpression t2 = term1();
   4.651 +            return F.at(pos).Conditional(t, t1, t2);
   4.652 +        } else {
   4.653 +            return t;
   4.654 +        }
   4.655 +    }
   4.656 +
   4.657 +    /** Expression2   = Expression3 [Expression2Rest]
   4.658 +     *  Type2         = Type3
   4.659 +     *  TypeNoParams2 = TypeNoParams3
   4.660 +     */
   4.661 +    JCExpression term2() {
   4.662 +        JCExpression t = term3();
   4.663 +        if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
   4.664 +            mode = EXPR;
   4.665 +            return term2Rest(t, TreeInfo.orPrec);
   4.666 +        } else {
   4.667 +            return t;
   4.668 +        }
   4.669 +    }
   4.670 +
   4.671 +    /*  Expression2Rest = {infixop Expression3}
   4.672 +     *                  | Expression3 instanceof Type
   4.673 +     *  infixop         = "||"
   4.674 +     *                  | "&&"
   4.675 +     *                  | "|"
   4.676 +     *                  | "^"
   4.677 +     *                  | "&"
   4.678 +     *                  | "==" | "!="
   4.679 +     *                  | "<" | ">" | "<=" | ">="
   4.680 +     *                  | "<<" | ">>" | ">>>"
   4.681 +     *                  | "+" | "-"
   4.682 +     *                  | "*" | "/" | "%"
   4.683 +     */
   4.684 +    JCExpression term2Rest(JCExpression t, int minprec) {
   4.685 +        List<JCExpression[]> savedOd = odStackSupply.elems;
   4.686 +        JCExpression[] odStack = newOdStack();
   4.687 +        List<Token[]> savedOp = opStackSupply.elems;
   4.688 +        Token[] opStack = newOpStack();
   4.689 +        // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   4.690 +        int top = 0;
   4.691 +        odStack[0] = t;
   4.692 +        int startPos = S.pos();
   4.693 +        Token topOp = ERROR;
   4.694 +        while (prec(S.token()) >= minprec) {
   4.695 +            opStack[top] = topOp;
   4.696 +            top++;
   4.697 +            topOp = S.token();
   4.698 +            int pos = S.pos();
   4.699 +            S.nextToken();
   4.700 +            odStack[top] = topOp == INSTANCEOF ? parseType() : term3();
   4.701 +            while (top > 0 && prec(topOp) >= prec(S.token())) {
   4.702 +                odStack[top-1] = makeOp(pos, topOp, odStack[top-1],
   4.703 +                                        odStack[top]);
   4.704 +                top--;
   4.705 +                topOp = opStack[top];
   4.706 +            }
   4.707 +        }
   4.708 +        assert top == 0;
   4.709 +        t = odStack[0];
   4.710 +
   4.711 +        if (t.getTag() == JCTree.PLUS) {
   4.712 +            StringBuffer buf = foldStrings(t);
   4.713 +            if (buf != null) {
   4.714 +                t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
   4.715 +            }
   4.716 +        }
   4.717 +
   4.718 +        odStackSupply.elems = savedOd; // optimization
   4.719 +        opStackSupply.elems = savedOp; // optimization
   4.720 +        return t;
   4.721 +    }
   4.722 +//where
   4.723 +        /** Construct a binary or type test node.
   4.724 +         */
   4.725 +        private JCExpression makeOp(int pos,
   4.726 +                                    Token topOp,
   4.727 +                                    JCExpression od1,
   4.728 +                                    JCExpression od2)
   4.729 +        {
   4.730 +            if (topOp == INSTANCEOF) {
   4.731 +                return F.at(pos).TypeTest(od1, od2);
   4.732 +            } else {
   4.733 +                return F.at(pos).Binary(optag(topOp), od1, od2);
   4.734 +            }
   4.735 +        }
   4.736 +        /** If tree is a concatenation of string literals, replace it
   4.737 +         *  by a single literal representing the concatenated string.
   4.738 +         */
   4.739 +        protected StringBuffer foldStrings(JCTree tree) {
   4.740 +            List<String> buf = List.nil();
   4.741 +            while (true) {
   4.742 +                if (tree.getTag() == JCTree.LITERAL) {
   4.743 +                    JCLiteral lit = (JCLiteral) tree;
   4.744 +                    if (lit.typetag == TypeTags.CLASS) {
   4.745 +                        StringBuffer sbuf =
   4.746 +                            new StringBuffer((String)lit.value);
   4.747 +                        while (buf.nonEmpty()) {
   4.748 +                            sbuf.append(buf.head);
   4.749 +                            buf = buf.tail;
   4.750 +                        }
   4.751 +                        return sbuf;
   4.752 +                    }
   4.753 +                } else if (tree.getTag() == JCTree.PLUS) {
   4.754 +                    JCBinary op = (JCBinary)tree;
   4.755 +                    if (op.rhs.getTag() == JCTree.LITERAL) {
   4.756 +                        JCLiteral lit = (JCLiteral) op.rhs;
   4.757 +                        if (lit.typetag == TypeTags.CLASS) {
   4.758 +                            buf = buf.prepend((String) lit.value);
   4.759 +                            tree = op.lhs;
   4.760 +                            continue;
   4.761 +                        }
   4.762 +                    }
   4.763 +                }
   4.764 +                return null;
   4.765 +            }
   4.766 +        }
   4.767 +
   4.768 +        /** optimization: To save allocating a new operand/operator stack
   4.769 +         *  for every binary operation, we use supplys.
   4.770 +         */
   4.771 +        ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
   4.772 +        ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
   4.773 +
   4.774 +        private JCExpression[] newOdStack() {
   4.775 +            if (odStackSupply.elems == odStackSupply.last)
   4.776 +                odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
   4.777 +            JCExpression[] odStack = odStackSupply.elems.head;
   4.778 +            odStackSupply.elems = odStackSupply.elems.tail;
   4.779 +            return odStack;
   4.780 +        }
   4.781 +
   4.782 +        private Token[] newOpStack() {
   4.783 +            if (opStackSupply.elems == opStackSupply.last)
   4.784 +                opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
   4.785 +            Token[] opStack = opStackSupply.elems.head;
   4.786 +            opStackSupply.elems = opStackSupply.elems.tail;
   4.787 +            return opStack;
   4.788 +        }
   4.789 +
   4.790 +    /** Expression3    = PrefixOp Expression3
   4.791 +     *                 | "(" Expr | TypeNoParams ")" Expression3
   4.792 +     *                 | Primary {Selector} {PostfixOp}
   4.793 +     *  Primary        = "(" Expression ")"
   4.794 +     *                 | Literal
   4.795 +     *                 | [TypeArguments] THIS [Arguments]
   4.796 +     *                 | [TypeArguments] SUPER SuperSuffix
   4.797 +     *                 | NEW [TypeArguments] Creator
   4.798 +     *                 | Ident { "." Ident }
   4.799 +     *                   [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   4.800 +     *                   | Arguments
   4.801 +     *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
   4.802 +     *                   ]
   4.803 +     *                 | BasicType BracketsOpt "." CLASS
   4.804 +     *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
   4.805 +     *  PostfixOp      = "++" | "--"
   4.806 +     *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
   4.807 +     *                 | BasicType
   4.808 +     *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
   4.809 +     *  Selector       = "." [TypeArguments] Ident [Arguments]
   4.810 +     *                 | "." THIS
   4.811 +     *                 | "." [TypeArguments] SUPER SuperSuffix
   4.812 +     *                 | "." NEW [TypeArguments] InnerCreator
   4.813 +     *                 | "[" Expression "]"
   4.814 +     *  TypeSelector   = "." Ident [TypeArguments]
   4.815 +     *  SuperSuffix    = Arguments | "." Ident [Arguments]
   4.816 +     */
   4.817 +    protected JCExpression term3() {
   4.818 +        int pos = S.pos();
   4.819 +        JCExpression t;
   4.820 +        List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
   4.821 +        switch (S.token()) {
   4.822 +        case QUES:
   4.823 +            if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
   4.824 +                mode = TYPE;
   4.825 +                return typeArgument();
   4.826 +            } else
   4.827 +                return illegal();
   4.828 +        case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
   4.829 +            if (typeArgs == null && (mode & EXPR) != 0) {
   4.830 +                Token token = S.token();
   4.831 +                S.nextToken();
   4.832 +                mode = EXPR;
   4.833 +                if (token == SUB &&
   4.834 +                    (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
   4.835 +                    S.radix() == 10) {
   4.836 +                    mode = EXPR;
   4.837 +                    t = literal(names.hyphen);
   4.838 +                } else {
   4.839 +                    t = term3();
   4.840 +                    return F.at(pos).Unary(unoptag(token), t);
   4.841 +                }
   4.842 +            } else return illegal();
   4.843 +            break;
   4.844 +        case LPAREN:
   4.845 +            if (typeArgs == null && (mode & EXPR) != 0) {
   4.846 +                S.nextToken();
   4.847 +                mode = EXPR | TYPE | NOPARAMS;
   4.848 +                t = term3();
   4.849 +                if ((mode & TYPE) != 0 && S.token() == LT) {
   4.850 +                    // Could be a cast to a parameterized type
   4.851 +                    int op = JCTree.LT;
   4.852 +                    int pos1 = S.pos();
   4.853 +                    S.nextToken();
   4.854 +                    mode &= (EXPR | TYPE);
   4.855 +                    mode |= TYPEARG;
   4.856 +                    JCExpression t1 = term3();
   4.857 +                    if ((mode & TYPE) != 0 &&
   4.858 +                        (S.token() == COMMA || S.token() == GT)) {
   4.859 +                        mode = TYPE;
   4.860 +                        ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
   4.861 +                        args.append(t1);
   4.862 +                        while (S.token() == COMMA) {
   4.863 +                            S.nextToken();
   4.864 +                            args.append(typeArgument());
   4.865 +                        }
   4.866 +                        accept(GT);
   4.867 +                        t = F.at(pos1).TypeApply(t, args.toList());
   4.868 +                        checkGenerics();
   4.869 +                        t = bracketsOpt(toP(t));
   4.870 +                    } else if ((mode & EXPR) != 0) {
   4.871 +                        mode = EXPR;
   4.872 +                        t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec));
   4.873 +                        t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   4.874 +                    } else {
   4.875 +                        accept(GT);
   4.876 +                    }
   4.877 +                } else {
   4.878 +                    t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   4.879 +                }
   4.880 +                accept(RPAREN);
   4.881 +                lastmode = mode;
   4.882 +                mode = EXPR;
   4.883 +                if ((lastmode & EXPR) == 0) {
   4.884 +                    JCExpression t1 = term3();
   4.885 +                    return F.at(pos).TypeCast(t, t1);
   4.886 +                } else if ((lastmode & TYPE) != 0) {
   4.887 +                    switch (S.token()) {
   4.888 +                    /*case PLUSPLUS: case SUBSUB: */
   4.889 +                    case BANG: case TILDE:
   4.890 +                    case LPAREN: case THIS: case SUPER:
   4.891 +                    case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
   4.892 +                    case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
   4.893 +                    case TRUE: case FALSE: case NULL:
   4.894 +                    case NEW: case IDENTIFIER: case ASSERT: case ENUM:
   4.895 +                    case BYTE: case SHORT: case CHAR: case INT:
   4.896 +                    case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
   4.897 +                        JCExpression t1 = term3();
   4.898 +                        return F.at(pos).TypeCast(t, t1);
   4.899 +                    }
   4.900 +                }
   4.901 +            } else return illegal();
   4.902 +            t = toP(F.at(pos).Parens(t));
   4.903 +            break;
   4.904 +        case THIS:
   4.905 +            if ((mode & EXPR) != 0) {
   4.906 +                mode = EXPR;
   4.907 +                t = to(F.at(pos).Ident(names._this));
   4.908 +                S.nextToken();
   4.909 +                if (typeArgs == null)
   4.910 +                    t = argumentsOpt(null, t);
   4.911 +                else
   4.912 +                    t = arguments(typeArgs, t);
   4.913 +                typeArgs = null;
   4.914 +            } else return illegal();
   4.915 +            break;
   4.916 +        case SUPER:
   4.917 +            if ((mode & EXPR) != 0) {
   4.918 +                mode = EXPR;
   4.919 +                t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super)));
   4.920 +                typeArgs = null;
   4.921 +            } else return illegal();
   4.922 +            break;
   4.923 +        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
   4.924 +        case CHARLITERAL: case STRINGLITERAL:
   4.925 +        case TRUE: case FALSE: case NULL:
   4.926 +            if (typeArgs == null && (mode & EXPR) != 0) {
   4.927 +                mode = EXPR;
   4.928 +                t = literal(names.empty);
   4.929 +            } else return illegal();
   4.930 +            break;
   4.931 +        case NEW:
   4.932 +            if (typeArgs != null) return illegal();
   4.933 +            if ((mode & EXPR) != 0) {
   4.934 +                mode = EXPR;
   4.935 +                S.nextToken();
   4.936 +                if (S.token() == LT) typeArgs = typeArguments();
   4.937 +                t = creator(pos, typeArgs);
   4.938 +                typeArgs = null;
   4.939 +            } else return illegal();
   4.940 +            break;
   4.941 +        case IDENTIFIER: case ASSERT: case ENUM:
   4.942 +            if (typeArgs != null) return illegal();
   4.943 +            t = toP(F.at(S.pos()).Ident(ident()));
   4.944 +            loop: while (true) {
   4.945 +                pos = S.pos();
   4.946 +                switch (S.token()) {
   4.947 +                case LBRACKET:
   4.948 +                    S.nextToken();
   4.949 +                    if (S.token() == RBRACKET) {
   4.950 +                        S.nextToken();
   4.951 +                        t = bracketsOpt(t);
   4.952 +                        t = toP(F.at(pos).TypeArray(t));
   4.953 +                        t = bracketsSuffix(t);
   4.954 +                    } else {
   4.955 +                        if ((mode & EXPR) != 0) {
   4.956 +                            mode = EXPR;
   4.957 +                            JCExpression t1 = term();
   4.958 +                            t = to(F.at(pos).Indexed(t, t1));
   4.959 +                        }
   4.960 +                        accept(RBRACKET);
   4.961 +                    }
   4.962 +                    break loop;
   4.963 +                case LPAREN:
   4.964 +                    if ((mode & EXPR) != 0) {
   4.965 +                        mode = EXPR;
   4.966 +                        t = arguments(typeArgs, t);
   4.967 +                        typeArgs = null;
   4.968 +                    }
   4.969 +                    break loop;
   4.970 +                case DOT:
   4.971 +                    S.nextToken();
   4.972 +                    int oldmode = mode;
   4.973 +                    mode &= ~NOPARAMS;
   4.974 +                    typeArgs = typeArgumentsOpt(EXPR);
   4.975 +                    mode = oldmode;
   4.976 +                    if ((mode & EXPR) != 0) {
   4.977 +                        switch (S.token()) {
   4.978 +                        case CLASS:
   4.979 +                            if (typeArgs != null) return illegal();
   4.980 +                            mode = EXPR;
   4.981 +                            t = to(F.at(pos).Select(t, names._class));
   4.982 +                            S.nextToken();
   4.983 +                            break loop;
   4.984 +                        case THIS:
   4.985 +                            if (typeArgs != null) return illegal();
   4.986 +                            mode = EXPR;
   4.987 +                            t = to(F.at(pos).Select(t, names._this));
   4.988 +                            S.nextToken();
   4.989 +                            break loop;
   4.990 +                        case SUPER:
   4.991 +                            mode = EXPR;
   4.992 +                            t = to(F.at(pos).Select(t, names._super));
   4.993 +                            t = superSuffix(typeArgs, t);
   4.994 +                            typeArgs = null;
   4.995 +                            break loop;
   4.996 +                        case NEW:
   4.997 +                            if (typeArgs != null) return illegal();
   4.998 +                            mode = EXPR;
   4.999 +                            int pos1 = S.pos();
  4.1000 +                            S.nextToken();
  4.1001 +                            if (S.token() == LT) typeArgs = typeArguments();
  4.1002 +                            t = innerCreator(pos1, typeArgs, t);
  4.1003 +                            typeArgs = null;
  4.1004 +                            break loop;
  4.1005 +                        }
  4.1006 +                    }
  4.1007 +                    // typeArgs saved for next loop iteration.
  4.1008 +                    t = toP(F.at(pos).Select(t, ident()));
  4.1009 +                    break;
  4.1010 +                default:
  4.1011 +                    break loop;
  4.1012 +                }
  4.1013 +            }
  4.1014 +            if (typeArgs != null) illegal();
  4.1015 +            t = typeArgumentsOpt(t);
  4.1016 +            break;
  4.1017 +        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  4.1018 +        case DOUBLE: case BOOLEAN:
  4.1019 +            if (typeArgs != null) illegal();
  4.1020 +            t = bracketsSuffix(bracketsOpt(basicType()));
  4.1021 +            break;
  4.1022 +        case VOID:
  4.1023 +            if (typeArgs != null) illegal();
  4.1024 +            if ((mode & EXPR) != 0) {
  4.1025 +                S.nextToken();
  4.1026 +                if (S.token() == DOT) {
  4.1027 +                    JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
  4.1028 +                    t = bracketsSuffix(ti);
  4.1029 +                } else {
  4.1030 +                    return illegal(pos);
  4.1031 +                }
  4.1032 +            } else {
  4.1033 +                return illegal();
  4.1034 +            }
  4.1035 +            break;
  4.1036 +        default:
  4.1037 +            return illegal();
  4.1038 +        }
  4.1039 +        if (typeArgs != null) illegal();
  4.1040 +        while (true) {
  4.1041 +            int pos1 = S.pos();
  4.1042 +            if (S.token() == LBRACKET) {
  4.1043 +                S.nextToken();
  4.1044 +                if ((mode & TYPE) != 0) {
  4.1045 +                    int oldmode = mode;
  4.1046 +                    mode = TYPE;
  4.1047 +                    if (S.token() == RBRACKET) {
  4.1048 +                        S.nextToken();
  4.1049 +                        t = bracketsOpt(t);
  4.1050 +                        t = toP(F.at(pos1).TypeArray(t));
  4.1051 +                        return t;
  4.1052 +                    }
  4.1053 +                    mode = oldmode;
  4.1054 +                }
  4.1055 +                if ((mode & EXPR) != 0) {
  4.1056 +                    mode = EXPR;
  4.1057 +                    JCExpression t1 = term();
  4.1058 +                    t = to(F.at(pos1).Indexed(t, t1));
  4.1059 +                }
  4.1060 +                accept(RBRACKET);
  4.1061 +            } else if (S.token() == DOT) {
  4.1062 +                S.nextToken();
  4.1063 +                typeArgs = typeArgumentsOpt(EXPR);
  4.1064 +                if (S.token() == SUPER && (mode & EXPR) != 0) {
  4.1065 +                    mode = EXPR;
  4.1066 +                    t = to(F.at(pos1).Select(t, names._super));
  4.1067 +                    S.nextToken();
  4.1068 +                    t = arguments(typeArgs, t);
  4.1069 +                    typeArgs = null;
  4.1070 +                } else if (S.token() == NEW && (mode & EXPR) != 0) {
  4.1071 +                    if (typeArgs != null) return illegal();
  4.1072 +                    mode = EXPR;
  4.1073 +                    int pos2 = S.pos();
  4.1074 +                    S.nextToken();
  4.1075 +                    if (S.token() == LT) typeArgs = typeArguments();
  4.1076 +                    t = innerCreator(pos2, typeArgs, t);
  4.1077 +                    typeArgs = null;
  4.1078 +                } else {
  4.1079 +                    t = toP(F.at(pos1).Select(t, ident()));
  4.1080 +                    t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  4.1081 +                    typeArgs = null;
  4.1082 +                }
  4.1083 +            } else {
  4.1084 +                break;
  4.1085 +            }
  4.1086 +        }
  4.1087 +        while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
  4.1088 +            mode = EXPR;
  4.1089 +            t = to(F.at(S.pos()).Unary(
  4.1090 +                  S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  4.1091 +            S.nextToken();
  4.1092 +        }
  4.1093 +        return toP(t);
  4.1094 +    }
  4.1095 +
  4.1096 +    /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  4.1097 +     */
  4.1098 +    JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  4.1099 +        S.nextToken();
  4.1100 +        if (S.token() == LPAREN || typeArgs != null) {
  4.1101 +            t = arguments(typeArgs, t);
  4.1102 +        } else {
  4.1103 +            int pos = S.pos();
  4.1104 +            accept(DOT);
  4.1105 +            typeArgs = (S.token() == LT) ? typeArguments() : null;
  4.1106 +            t = toP(F.at(pos).Select(t, ident()));
  4.1107 +            t = argumentsOpt(typeArgs, t);
  4.1108 +        }
  4.1109 +        return t;
  4.1110 +    }
  4.1111 +
  4.1112 +    /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  4.1113 +     */
  4.1114 +    JCPrimitiveTypeTree basicType() {
  4.1115 +        JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
  4.1116 +        S.nextToken();
  4.1117 +        return t;
  4.1118 +    }
  4.1119 +
  4.1120 +    /** ArgumentsOpt = [ Arguments ]
  4.1121 +     */
  4.1122 +    JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  4.1123 +        if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
  4.1124 +            mode = EXPR;
  4.1125 +            return arguments(typeArgs, t);
  4.1126 +        } else {
  4.1127 +            return t;
  4.1128 +        }
  4.1129 +    }
  4.1130 +
  4.1131 +    /** Arguments = "(" [Expression { COMMA Expression }] ")"
  4.1132 +     */
  4.1133 +    List<JCExpression> arguments() {
  4.1134 +        ListBuffer<JCExpression> args = lb();
  4.1135 +        if (S.token() == LPAREN) {
  4.1136 +            S.nextToken();
  4.1137 +            if (S.token() != RPAREN) {
  4.1138 +                args.append(parseExpression());
  4.1139 +                while (S.token() == COMMA) {
  4.1140 +                    S.nextToken();
  4.1141 +                    args.append(parseExpression());
  4.1142 +                }
  4.1143 +            }
  4.1144 +            accept(RPAREN);
  4.1145 +        } else {
  4.1146 +            syntaxError(S.pos(), "expected", LPAREN);
  4.1147 +        }
  4.1148 +        return args.toList();
  4.1149 +    }
  4.1150 +
  4.1151 +    JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  4.1152 +        int pos = S.pos();
  4.1153 +        List<JCExpression> args = arguments();
  4.1154 +        return toP(F.at(pos).Apply(typeArgs, t, args));
  4.1155 +    }
  4.1156 +
  4.1157 +    /**  TypeArgumentsOpt = [ TypeArguments ]
  4.1158 +     */
  4.1159 +    JCExpression typeArgumentsOpt(JCExpression t) {
  4.1160 +        if (S.token() == LT &&
  4.1161 +            (mode & TYPE) != 0 &&
  4.1162 +            (mode & NOPARAMS) == 0) {
  4.1163 +            mode = TYPE;
  4.1164 +            checkGenerics();
  4.1165 +            return typeArguments(t);
  4.1166 +        } else {
  4.1167 +            return t;
  4.1168 +        }
  4.1169 +    }
  4.1170 +    List<JCExpression> typeArgumentsOpt() {
  4.1171 +        return typeArgumentsOpt(TYPE);
  4.1172 +    }
  4.1173 +
  4.1174 +    List<JCExpression> typeArgumentsOpt(int useMode) {
  4.1175 +        if (S.token() == LT) {
  4.1176 +            checkGenerics();
  4.1177 +            if ((mode & useMode) == 0 ||
  4.1178 +                (mode & NOPARAMS) != 0) {
  4.1179 +                illegal();
  4.1180 +            }
  4.1181 +            mode = useMode;
  4.1182 +            return typeArguments();
  4.1183 +        }
  4.1184 +        return null;
  4.1185 +    }
  4.1186 +
  4.1187 +    /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  4.1188 +     */
  4.1189 +    List<JCExpression> typeArguments() {
  4.1190 +        ListBuffer<JCExpression> args = lb();
  4.1191 +        if (S.token() == LT) {
  4.1192 +            S.nextToken();
  4.1193 +            args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  4.1194 +            while (S.token() == COMMA) {
  4.1195 +                S.nextToken();
  4.1196 +                args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  4.1197 +            }
  4.1198 +            switch (S.token()) {
  4.1199 +            case GTGTGTEQ:
  4.1200 +                S.token(GTGTEQ);
  4.1201 +                break;
  4.1202 +            case GTGTEQ:
  4.1203 +                S.token(GTEQ);
  4.1204 +                break;
  4.1205 +            case GTEQ:
  4.1206 +                S.token(EQ);
  4.1207 +                break;
  4.1208 +            case GTGTGT:
  4.1209 +                S.token(GTGT);
  4.1210 +                break;
  4.1211 +            case GTGT:
  4.1212 +                S.token(GT);
  4.1213 +                break;
  4.1214 +            default:
  4.1215 +                accept(GT);
  4.1216 +                break;
  4.1217 +            }
  4.1218 +        } else {
  4.1219 +            syntaxError(S.pos(), "expected", LT);
  4.1220 +        }
  4.1221 +        return args.toList();
  4.1222 +    }
  4.1223 +
  4.1224 +    /** TypeArgument = Type
  4.1225 +     *               | "?"
  4.1226 +     *               | "?" EXTENDS Type {"&" Type}
  4.1227 +     *               | "?" SUPER Type
  4.1228 +     */
  4.1229 +    JCExpression typeArgument() {
  4.1230 +        if (S.token() != QUES) return parseType();
  4.1231 +        int pos = S.pos();
  4.1232 +        S.nextToken();
  4.1233 +        if (S.token() == EXTENDS) {
  4.1234 +            TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
  4.1235 +            S.nextToken();
  4.1236 +            return F.at(pos).Wildcard(t, parseType());
  4.1237 +        } else if (S.token() == SUPER) {
  4.1238 +            TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
  4.1239 +            S.nextToken();
  4.1240 +            return F.at(pos).Wildcard(t, parseType());
  4.1241 +        } else if (S.token() == IDENTIFIER) {
  4.1242 +            //error recovery
  4.1243 +            reportSyntaxError(S.prevEndPos(), "expected3",
  4.1244 +                    GT, EXTENDS, SUPER);
  4.1245 +            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  4.1246 +            JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  4.1247 +            JCIdent id = toP(F.at(S.pos()).Ident(ident()));
  4.1248 +            return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  4.1249 +        } else {
  4.1250 +            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  4.1251 +            return toP(F.at(pos).Wildcard(t, null));
  4.1252 +        }
  4.1253 +    }
  4.1254 +
  4.1255 +    JCTypeApply typeArguments(JCExpression t) {
  4.1256 +        int pos = S.pos();
  4.1257 +        List<JCExpression> args = typeArguments();
  4.1258 +        return toP(F.at(pos).TypeApply(t, args));
  4.1259 +    }
  4.1260 +
  4.1261 +    /** BracketsOpt = {"[" "]"}
  4.1262 +     */
  4.1263 +    private JCExpression bracketsOpt(JCExpression t) {
  4.1264 +        if (S.token() == LBRACKET) {
  4.1265 +            int pos = S.pos();
  4.1266 +            S.nextToken();
  4.1267 +            t = bracketsOptCont(t, pos);
  4.1268 +            F.at(pos);
  4.1269 +        }
  4.1270 +        return t;
  4.1271 +    }
  4.1272 +
  4.1273 +    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
  4.1274 +        accept(RBRACKET);
  4.1275 +        t = bracketsOpt(t);
  4.1276 +        return toP(F.at(pos).TypeArray(t));
  4.1277 +    }
  4.1278 +
  4.1279 +    /** BracketsSuffixExpr = "." CLASS
  4.1280 +     *  BracketsSuffixType =
  4.1281 +     */
  4.1282 +    JCExpression bracketsSuffix(JCExpression t) {
  4.1283 +        if ((mode & EXPR) != 0 && S.token() == DOT) {
  4.1284 +            mode = EXPR;
  4.1285 +            int pos = S.pos();
  4.1286 +            S.nextToken();
  4.1287 +            accept(CLASS);
  4.1288 +            if (S.pos() == errorEndPos) {
  4.1289 +                // error recovery
  4.1290 +                Name name = null;
  4.1291 +                if (S.token() == IDENTIFIER) {
  4.1292 +                    name = S.name();
  4.1293 +                    S.nextToken();
  4.1294 +                } else {
  4.1295 +                    name = names.error;
  4.1296 +                }
  4.1297 +                t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  4.1298 +            } else {
  4.1299 +                t = toP(F.at(pos).Select(t, names._class));
  4.1300 +            }
  4.1301 +        } else if ((mode & TYPE) != 0) {
  4.1302 +            mode = TYPE;
  4.1303 +        } else {
  4.1304 +            syntaxError(S.pos(), "dot.class.expected");
  4.1305 +        }
  4.1306 +        return t;
  4.1307 +    }
  4.1308 +
  4.1309 +    /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  4.1310 +     */
  4.1311 +    JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  4.1312 +        switch (S.token()) {
  4.1313 +        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  4.1314 +        case DOUBLE: case BOOLEAN:
  4.1315 +            if (typeArgs == null)
  4.1316 +                return arrayCreatorRest(newpos, basicType());
  4.1317 +            break;
  4.1318 +        default:
  4.1319 +        }
  4.1320 +        JCExpression t = qualident();
  4.1321 +        int oldmode = mode;
  4.1322 +        mode = TYPE;
  4.1323 +        if (S.token() == LT) {
  4.1324 +            checkGenerics();
  4.1325 +            t = typeArguments(t);
  4.1326 +        }
  4.1327 +        while (S.token() == DOT) {
  4.1328 +            int pos = S.pos();
  4.1329 +            S.nextToken();
  4.1330 +            t = toP(F.at(pos).Select(t, ident()));
  4.1331 +            if (S.token() == LT) {
  4.1332 +                checkGenerics();
  4.1333 +                t = typeArguments(t);
  4.1334 +            }
  4.1335 +        }
  4.1336 +        mode = oldmode;
  4.1337 +        if (S.token() == LBRACKET) {
  4.1338 +            JCExpression e = arrayCreatorRest(newpos, t);
  4.1339 +            if (typeArgs != null) {
  4.1340 +                int pos = newpos;
  4.1341 +                if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  4.1342 +                    // note: this should always happen but we should
  4.1343 +                    // not rely on this as the parser is continuously
  4.1344 +                    // modified to improve error recovery.
  4.1345 +                    pos = typeArgs.head.pos;
  4.1346 +                }
  4.1347 +                setErrorEndPos(S.prevEndPos());
  4.1348 +                reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
  4.1349 +                return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
  4.1350 +            }
  4.1351 +            return e;
  4.1352 +        } else if (S.token() == LPAREN) {
  4.1353 +            return classCreatorRest(newpos, null, typeArgs, t);
  4.1354 +        } else {
  4.1355 +            reportSyntaxError(S.pos(), "expected2",
  4.1356 +                               LPAREN, LBRACKET);
  4.1357 +            t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  4.1358 +            return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  4.1359 +        }
  4.1360 +    }
  4.1361 +
  4.1362 +    /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
  4.1363 +     */
  4.1364 +    JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  4.1365 +        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
  4.1366 +        if (S.token() == LT) {
  4.1367 +            checkGenerics();
  4.1368 +            t = typeArguments(t);
  4.1369 +        }
  4.1370 +        return classCreatorRest(newpos, encl, typeArgs, t);
  4.1371 +    }
  4.1372 +
  4.1373 +    /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
  4.1374 +     *                         | Expression "]" {"[" Expression "]"} BracketsOpt )
  4.1375 +     */
  4.1376 +    JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  4.1377 +        accept(LBRACKET);
  4.1378 +        if (S.token() == RBRACKET) {
  4.1379 +            accept(RBRACKET);
  4.1380 +            elemtype = bracketsOpt(elemtype);
  4.1381 +            if (S.token() == LBRACE) {
  4.1382 +                return arrayInitializer(newpos, elemtype);
  4.1383 +            } else {
  4.1384 +                return syntaxError(S.pos(), "array.dimension.missing");
  4.1385 +            }
  4.1386 +        } else {
  4.1387 +            ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  4.1388 +            dims.append(parseExpression());
  4.1389 +            accept(RBRACKET);
  4.1390 +            while (S.token() == LBRACKET) {
  4.1391 +                int pos = S.pos();
  4.1392 +                S.nextToken();
  4.1393 +                if (S.token() == RBRACKET) {
  4.1394 +                    elemtype = bracketsOptCont(elemtype, pos);
  4.1395 +                } else {
  4.1396 +                    dims.append(parseExpression());
  4.1397 +                    accept(RBRACKET);
  4.1398 +                }
  4.1399 +            }
  4.1400 +            return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  4.1401 +        }
  4.1402 +    }
  4.1403 +
  4.1404 +    /** ClassCreatorRest = Arguments [ClassBody]
  4.1405 +     */
  4.1406 +    JCExpression classCreatorRest(int newpos,
  4.1407 +                                  JCExpression encl,
  4.1408 +                                  List<JCExpression> typeArgs,
  4.1409 +                                  JCExpression t)
  4.1410 +    {
  4.1411 +        List<JCExpression> args = arguments();
  4.1412 +        JCClassDecl body = null;
  4.1413 +        if (S.token() == LBRACE) {
  4.1414 +            int pos = S.pos();
  4.1415 +            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  4.1416 +            JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  4.1417 +            body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  4.1418 +        }
  4.1419 +        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  4.1420 +    }
  4.1421 +
  4.1422 +    /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  4.1423 +     */
  4.1424 +    JCExpression arrayInitializer(int newpos, JCExpression t) {
  4.1425 +        accept(LBRACE);
  4.1426 +        ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  4.1427 +        if (S.token() == COMMA) {
  4.1428 +            S.nextToken();
  4.1429 +        } else if (S.token() != RBRACE) {
  4.1430 +            elems.append(variableInitializer());
  4.1431 +            while (S.token() == COMMA) {
  4.1432 +                S.nextToken();
  4.1433 +                if (S.token() == RBRACE) break;
  4.1434 +                elems.append(variableInitializer());
  4.1435 +            }
  4.1436 +        }
  4.1437 +        accept(RBRACE);
  4.1438 +        return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  4.1439 +    }
  4.1440 +
  4.1441 +    /** VariableInitializer = ArrayInitializer | Expression
  4.1442 +     */
  4.1443 +    public JCExpression variableInitializer() {
  4.1444 +        return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
  4.1445 +    }
  4.1446 +
  4.1447 +    /** ParExpression = "(" Expression ")"
  4.1448 +     */
  4.1449 +    JCExpression parExpression() {
  4.1450 +        accept(LPAREN);
  4.1451 +        JCExpression t = parseExpression();
  4.1452 +        accept(RPAREN);
  4.1453 +        return t;
  4.1454 +    }
  4.1455 +
  4.1456 +    /** Block = "{" BlockStatements "}"
  4.1457 +     */
  4.1458 +    JCBlock block(int pos, long flags) {
  4.1459 +        accept(LBRACE);
  4.1460 +        List<JCStatement> stats = blockStatements();
  4.1461 +        JCBlock t = F.at(pos).Block(flags, stats);
  4.1462 +        while (S.token() == CASE || S.token() == DEFAULT) {
  4.1463 +            syntaxError("orphaned", S.token());
  4.1464 +            switchBlockStatementGroups();
  4.1465 +        }
  4.1466 +        // the Block node has a field "endpos" for first char of last token, which is
  4.1467 +        // usually but not necessarily the last char of the last token.
  4.1468 +        t.endpos = S.pos();
  4.1469 +        accept(RBRACE);
  4.1470 +        return toP(t);
  4.1471 +    }
  4.1472 +
  4.1473 +    public JCBlock block() {
  4.1474 +        return block(S.pos(), 0);
  4.1475 +    }
  4.1476 +
  4.1477 +    /** BlockStatements = { BlockStatement }
  4.1478 +     *  BlockStatement  = LocalVariableDeclarationStatement
  4.1479 +     *                  | ClassOrInterfaceOrEnumDeclaration
  4.1480 +     *                  | [Ident ":"] Statement
  4.1481 +     *  LocalVariableDeclarationStatement
  4.1482 +     *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  4.1483 +     */
  4.1484 +    @SuppressWarnings("fallthrough")
  4.1485 +    List<JCStatement> blockStatements() {
  4.1486 +//todo: skip to anchor on error(?)
  4.1487 +        int lastErrPos = -1;
  4.1488 +        ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  4.1489 +        while (true) {
  4.1490 +            int pos = S.pos();
  4.1491 +            switch (S.token()) {
  4.1492 +            case RBRACE: case CASE: case DEFAULT: case EOF:
  4.1493 +                return stats.toList();
  4.1494 +            case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  4.1495 +            case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  4.1496 +            case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  4.1497 +                stats.append(parseStatement());
  4.1498 +                break;
  4.1499 +            case MONKEYS_AT:
  4.1500 +            case FINAL: {
  4.1501 +                String dc = S.docComment();
  4.1502 +                JCModifiers mods = modifiersOpt();
  4.1503 +                if (S.token() == INTERFACE ||
  4.1504 +                    S.token() == CLASS ||
  4.1505 +                    allowEnums && S.token() == ENUM) {
  4.1506 +                    stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  4.1507 +                } else {
  4.1508 +                    JCExpression t = parseType();
  4.1509 +                    stats.appendList(variableDeclarators(mods, t,
  4.1510 +                                                         new ListBuffer<JCStatement>()));
  4.1511 +                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  4.1512 +                    storeEnd(stats.elems.last(), S.endPos());
  4.1513 +                    accept(SEMI);
  4.1514 +                }
  4.1515 +                break;
  4.1516 +            }
  4.1517 +            case ABSTRACT: case STRICTFP: {
  4.1518 +                String dc = S.docComment();
  4.1519 +                JCModifiers mods = modifiersOpt();
  4.1520 +                stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  4.1521 +                break;
  4.1522 +            }
  4.1523 +            case INTERFACE:
  4.1524 +            case CLASS:
  4.1525 +                stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  4.1526 +                                                               S.docComment()));
  4.1527 +                break;
  4.1528 +            case ENUM:
  4.1529 +            case ASSERT:
  4.1530 +                if (allowEnums && S.token() == ENUM) {
  4.1531 +                    log.error(S.pos(), "local.enum");
  4.1532 +                    stats.
  4.1533 +                        append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  4.1534 +                                                                 S.docComment()));
  4.1535 +                    break;
  4.1536 +                } else if (allowAsserts && S.token() == ASSERT) {
  4.1537 +                    stats.append(parseStatement());
  4.1538 +                    break;
  4.1539 +                }
  4.1540 +                /* fall through to default */
  4.1541 +            default:
  4.1542 +                Name name = S.name();
  4.1543 +                JCExpression t = term(EXPR | TYPE);
  4.1544 +                if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
  4.1545 +                    S.nextToken();
  4.1546 +                    JCStatement stat = parseStatement();
  4.1547 +                    stats.append(F.at(pos).Labelled(name, stat));
  4.1548 +                } else if ((lastmode & TYPE) != 0 &&
  4.1549 +                           (S.token() == IDENTIFIER ||
  4.1550 +                            S.token() == ASSERT ||
  4.1551 +                            S.token() == ENUM)) {
  4.1552 +                    pos = S.pos();
  4.1553 +                    JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  4.1554 +                    F.at(pos);
  4.1555 +                    stats.appendList(variableDeclarators(mods, t,
  4.1556 +                                                         new ListBuffer<JCStatement>()));
  4.1557 +                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  4.1558 +                    storeEnd(stats.elems.last(), S.endPos());
  4.1559 +                    accept(SEMI);
  4.1560 +                } else {
  4.1561 +                    // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  4.1562 +                    stats.append(to(F.at(pos).Exec(checkExprStat(t))));
  4.1563 +                    accept(SEMI);
  4.1564 +                }
  4.1565 +            }
  4.1566 +
  4.1567 +            // error recovery
  4.1568 +            if (S.pos() == lastErrPos)
  4.1569 +                return stats.toList();
  4.1570 +            if (S.pos() <= errorEndPos) {
  4.1571 +                skip(false, true, true, true);
  4.1572 +                lastErrPos = S.pos();
  4.1573 +            }
  4.1574 +
  4.1575 +            // ensure no dangling /** @deprecated */ active
  4.1576 +            S.resetDeprecatedFlag();
  4.1577 +        }
  4.1578 +    }
  4.1579 +
  4.1580 +    /** Statement =
  4.1581 +     *       Block
  4.1582 +     *     | IF ParExpression Statement [ELSE Statement]
  4.1583 +     *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  4.1584 +     *     | FOR "(" FormalParameter : Expression ")" Statement
  4.1585 +     *     | WHILE ParExpression Statement
  4.1586 +     *     | DO Statement WHILE ParExpression ";"
  4.1587 +     *     | TRY Block ( Catches | [Catches] FinallyPart )
  4.1588 +     *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  4.1589 +     *     | SYNCHRONIZED ParExpression Block
  4.1590 +     *     | RETURN [Expression] ";"
  4.1591 +     *     | THROW Expression ";"
  4.1592 +     *     | BREAK [Ident] ";"
  4.1593 +     *     | CONTINUE [Ident] ";"
  4.1594 +     *     | ASSERT Expression [ ":" Expression ] ";"
  4.1595 +     *     | ";"
  4.1596 +     *     | ExpressionStatement
  4.1597 +     *     | Ident ":" Statement
  4.1598 +     */
  4.1599 +    @SuppressWarnings("fallthrough")
  4.1600 +    public JCStatement parseStatement() {
  4.1601 +        int pos = S.pos();
  4.1602 +        switch (S.token()) {
  4.1603 +        case LBRACE:
  4.1604 +            return block();
  4.1605 +        case IF: {
  4.1606 +            S.nextToken();
  4.1607 +            JCExpression cond = parExpression();
  4.1608 +            JCStatement thenpart = parseStatement();
  4.1609 +            JCStatement elsepart = null;
  4.1610 +            if (S.token() == ELSE) {
  4.1611 +                S.nextToken();
  4.1612 +                elsepart = parseStatement();
  4.1613 +            }
  4.1614 +            return F.at(pos).If(cond, thenpart, elsepart);
  4.1615 +        }
  4.1616 +        case FOR: {
  4.1617 +            S.nextToken();
  4.1618 +            accept(LPAREN);
  4.1619 +            List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
  4.1620 +            if (inits.length() == 1 &&
  4.1621 +                inits.head.getTag() == JCTree.VARDEF &&
  4.1622 +                ((JCVariableDecl) inits.head).init == null &&
  4.1623 +                S.token() == COLON) {
  4.1624 +                checkForeach();
  4.1625 +                JCVariableDecl var = (JCVariableDecl)inits.head;
  4.1626 +                accept(COLON);
  4.1627 +                JCExpression expr = parseExpression();
  4.1628 +                accept(RPAREN);
  4.1629 +                JCStatement body = parseStatement();
  4.1630 +                return F.at(pos).ForeachLoop(var, expr, body);
  4.1631 +            } else {
  4.1632 +                accept(SEMI);
  4.1633 +                JCExpression cond = S.token() == SEMI ? null : parseExpression();
  4.1634 +                accept(SEMI);
  4.1635 +                List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  4.1636 +                accept(RPAREN);
  4.1637 +                JCStatement body = parseStatement();
  4.1638 +                return F.at(pos).ForLoop(inits, cond, steps, body);
  4.1639 +            }
  4.1640 +        }
  4.1641 +        case WHILE: {
  4.1642 +            S.nextToken();
  4.1643 +            JCExpression cond = parExpression();
  4.1644 +            JCStatement body = parseStatement();
  4.1645 +            return F.at(pos).WhileLoop(cond, body);
  4.1646 +        }
  4.1647 +        case DO: {
  4.1648 +            S.nextToken();
  4.1649 +            JCStatement body = parseStatement();
  4.1650 +            accept(WHILE);
  4.1651 +            JCExpression cond = parExpression();
  4.1652 +            JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  4.1653 +            accept(SEMI);
  4.1654 +            return t;
  4.1655 +        }
  4.1656 +        case TRY: {
  4.1657 +            S.nextToken();
  4.1658 +            JCBlock body = block();
  4.1659 +            ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  4.1660 +            JCBlock finalizer = null;
  4.1661 +            if (S.token() == CATCH || S.token() == FINALLY) {
  4.1662 +                while (S.token() == CATCH) catchers.append(catchClause());
  4.1663 +                if (S.token() == FINALLY) {
  4.1664 +                    S.nextToken();
  4.1665 +                    finalizer = block();
  4.1666 +                }
  4.1667 +            } else {
  4.1668 +                log.error(pos, "try.without.catch.or.finally");
  4.1669 +            }
  4.1670 +            return F.at(pos).Try(body, catchers.toList(), finalizer);
  4.1671 +        }
  4.1672 +        case SWITCH: {
  4.1673 +            S.nextToken();
  4.1674 +            JCExpression selector = parExpression();
  4.1675 +            accept(LBRACE);
  4.1676 +            List<JCCase> cases = switchBlockStatementGroups();
  4.1677 +            JCSwitch t = to(F.at(pos).Switch(selector, cases));
  4.1678 +            accept(RBRACE);
  4.1679 +            return t;
  4.1680 +        }
  4.1681 +        case SYNCHRONIZED: {
  4.1682 +            S.nextToken();
  4.1683 +            JCExpression lock = parExpression();
  4.1684 +            JCBlock body = block();
  4.1685 +            return F.at(pos).Synchronized(lock, body);
  4.1686 +        }
  4.1687 +        case RETURN: {
  4.1688 +            S.nextToken();
  4.1689 +            JCExpression result = S.token() == SEMI ? null : parseExpression();
  4.1690 +            JCReturn t = to(F.at(pos).Return(result));
  4.1691 +            accept(SEMI);
  4.1692 +            return t;
  4.1693 +        }
  4.1694 +        case THROW: {
  4.1695 +            S.nextToken();
  4.1696 +            JCExpression exc = parseExpression();
  4.1697 +            JCThrow t = to(F.at(pos).Throw(exc));
  4.1698 +            accept(SEMI);
  4.1699 +            return t;
  4.1700 +        }
  4.1701 +        case BREAK: {
  4.1702 +            S.nextToken();
  4.1703 +            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  4.1704 +            JCBreak t = to(F.at(pos).Break(label));
  4.1705 +            accept(SEMI);
  4.1706 +            return t;
  4.1707 +        }
  4.1708 +        case CONTINUE: {
  4.1709 +            S.nextToken();
  4.1710 +            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  4.1711 +            JCContinue t =  to(F.at(pos).Continue(label));
  4.1712 +            accept(SEMI);
  4.1713 +            return t;
  4.1714 +        }
  4.1715 +        case SEMI:
  4.1716 +            S.nextToken();
  4.1717 +            return toP(F.at(pos).Skip());
  4.1718 +        case ELSE:
  4.1719 +            return toP(F.Exec(syntaxError("else.without.if")));
  4.1720 +        case FINALLY:
  4.1721 +            return toP(F.Exec(syntaxError("finally.without.try")));
  4.1722 +        case CATCH:
  4.1723 +            return toP(F.Exec(syntaxError("catch.without.try")));
  4.1724 +        case ASSERT: {
  4.1725 +            if (allowAsserts && S.token() == ASSERT) {
  4.1726 +                S.nextToken();
  4.1727 +                JCExpression assertion = parseExpression();
  4.1728 +                JCExpression message = null;
  4.1729 +                if (S.token() == COLON) {
  4.1730 +                    S.nextToken();
  4.1731 +                    message = parseExpression();
  4.1732 +                }
  4.1733 +                JCAssert t = to(F.at(pos).Assert(assertion, message));
  4.1734 +                accept(SEMI);
  4.1735 +                return t;
  4.1736 +            }
  4.1737 +            /* else fall through to default case */
  4.1738 +        }
  4.1739 +        case ENUM:
  4.1740 +        default:
  4.1741 +            Name name = S.name();
  4.1742 +            JCExpression expr = parseExpression();
  4.1743 +            if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
  4.1744 +                S.nextToken();
  4.1745 +                JCStatement stat = parseStatement();
  4.1746 +                return F.at(pos).Labelled(name, stat);
  4.1747 +            } else {
  4.1748 +                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  4.1749 +                JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  4.1750 +                accept(SEMI);
  4.1751 +                return stat;
  4.1752 +            }
  4.1753 +        }
  4.1754 +    }
  4.1755 +
  4.1756 +    /** CatchClause     = CATCH "(" FormalParameter ")" Block
  4.1757 +     */
  4.1758 +    JCCatch catchClause() {
  4.1759 +        int pos = S.pos();
  4.1760 +        accept(CATCH);
  4.1761 +        accept(LPAREN);
  4.1762 +        JCVariableDecl formal =
  4.1763 +            variableDeclaratorId(optFinal(Flags.PARAMETER),
  4.1764 +                                 qualident());
  4.1765 +        accept(RPAREN);
  4.1766 +        JCBlock body = block();
  4.1767 +        return F.at(pos).Catch(formal, body);
  4.1768 +    }
  4.1769 +
  4.1770 +    /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  4.1771 +     *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  4.1772 +     *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  4.1773 +     */
  4.1774 +    List<JCCase> switchBlockStatementGroups() {
  4.1775 +        ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  4.1776 +        while (true) {
  4.1777 +            int pos = S.pos();
  4.1778 +            switch (S.token()) {
  4.1779 +            case CASE: {
  4.1780 +                S.nextToken();
  4.1781 +                JCExpression pat = parseExpression();
  4.1782 +                accept(COLON);
  4.1783 +                List<JCStatement> stats = blockStatements();
  4.1784 +                JCCase c = F.at(pos).Case(pat, stats);
  4.1785 +                if (stats.isEmpty())
  4.1786 +                    storeEnd(c, S.prevEndPos());
  4.1787 +                cases.append(c);
  4.1788 +                break;
  4.1789 +            }
  4.1790 +            case DEFAULT: {
  4.1791 +                S.nextToken();
  4.1792 +                accept(COLON);
  4.1793 +                List<JCStatement> stats = blockStatements();
  4.1794 +                JCCase c = F.at(pos).Case(null, stats);
  4.1795 +                if (stats.isEmpty())
  4.1796 +                    storeEnd(c, S.prevEndPos());
  4.1797 +                cases.append(c);
  4.1798 +                break;
  4.1799 +            }
  4.1800 +            case RBRACE: case EOF:
  4.1801 +                return cases.toList();
  4.1802 +            default:
  4.1803 +                S.nextToken(); // to ensure progress
  4.1804 +                syntaxError(pos, "expected3",
  4.1805 +                    CASE, DEFAULT, RBRACE);
  4.1806 +            }
  4.1807 +        }
  4.1808 +    }
  4.1809 +
  4.1810 +    /** MoreStatementExpressions = { COMMA StatementExpression }
  4.1811 +     */
  4.1812 +    <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  4.1813 +                                                                    JCExpression first,
  4.1814 +                                                                    T stats) {
  4.1815 +        // This Exec is a "StatementExpression"; it subsumes no terminating token
  4.1816 +        stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  4.1817 +        while (S.token() == COMMA) {
  4.1818 +            S.nextToken();
  4.1819 +            pos = S.pos();
  4.1820 +            JCExpression t = parseExpression();
  4.1821 +            // This Exec is a "StatementExpression"; it subsumes no terminating token
  4.1822 +            stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  4.1823 +        }
  4.1824 +        return stats;
  4.1825 +    }
  4.1826 +
  4.1827 +    /** ForInit = StatementExpression MoreStatementExpressions
  4.1828 +     *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  4.1829 +     */
  4.1830 +    List<JCStatement> forInit() {
  4.1831 +        ListBuffer<JCStatement> stats = lb();
  4.1832 +        int pos = S.pos();
  4.1833 +        if (S.token() == FINAL || S.token() == MONKEYS_AT) {
  4.1834 +            return variableDeclarators(optFinal(0), parseType(), stats).toList();
  4.1835 +        } else {
  4.1836 +            JCExpression t = term(EXPR | TYPE);
  4.1837 +            if ((lastmode & TYPE) != 0 &&
  4.1838 +                (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
  4.1839 +                return variableDeclarators(modifiersOpt(), t, stats).toList();
  4.1840 +            else
  4.1841 +                return moreStatementExpressions(pos, t, stats).toList();
  4.1842 +        }
  4.1843 +    }
  4.1844 +
  4.1845 +    /** ForUpdate = StatementExpression MoreStatementExpressions
  4.1846 +     */
  4.1847 +    List<JCExpressionStatement> forUpdate() {
  4.1848 +        return moreStatementExpressions(S.pos(),
  4.1849 +                                        parseExpression(),
  4.1850 +                                        new ListBuffer<JCExpressionStatement>()).toList();
  4.1851 +    }
  4.1852 +
  4.1853 +    /** AnnotationsOpt = { '@' Annotation }
  4.1854 +     */
  4.1855 +    List<JCAnnotation> annotationsOpt() {
  4.1856 +        if (S.token() != MONKEYS_AT) return List.nil(); // optimization
  4.1857 +        ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  4.1858 +        while (S.token() == MONKEYS_AT) {
  4.1859 +            int pos = S.pos();
  4.1860 +            S.nextToken();
  4.1861 +            buf.append(annotation(pos));
  4.1862 +        }
  4.1863 +        return buf.toList();
  4.1864 +    }
  4.1865 +
  4.1866 +    /** ModifiersOpt = { Modifier }
  4.1867 +     *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  4.1868 +     *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  4.1869 +     *           | "@" Annotation
  4.1870 +     */
  4.1871 +    JCModifiers modifiersOpt() {
  4.1872 +        return modifiersOpt(null);
  4.1873 +    }
  4.1874 +    JCModifiers modifiersOpt(JCModifiers partial) {
  4.1875 +        long flags = (partial == null) ? 0 : partial.flags;
  4.1876 +        if (S.deprecatedFlag()) {
  4.1877 +            flags |= Flags.DEPRECATED;
  4.1878 +            S.resetDeprecatedFlag();
  4.1879 +        }
  4.1880 +        ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  4.1881 +        if (partial != null) annotations.appendList(partial.annotations);
  4.1882 +        int pos = S.pos();
  4.1883 +        int lastPos = Position.NOPOS;
  4.1884 +    loop:
  4.1885 +        while (true) {
  4.1886 +            long flag;
  4.1887 +            switch (S.token()) {
  4.1888 +            case PRIVATE     : flag = Flags.PRIVATE; break;
  4.1889 +            case PROTECTED   : flag = Flags.PROTECTED; break;
  4.1890 +            case PUBLIC      : flag = Flags.PUBLIC; break;
  4.1891 +            case STATIC      : flag = Flags.STATIC; break;
  4.1892 +            case TRANSIENT   : flag = Flags.TRANSIENT; break;
  4.1893 +            case FINAL       : flag = Flags.FINAL; break;
  4.1894 +            case ABSTRACT    : flag = Flags.ABSTRACT; break;
  4.1895 +            case NATIVE      : flag = Flags.NATIVE; break;
  4.1896 +            case VOLATILE    : flag = Flags.VOLATILE; break;
  4.1897 +            case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  4.1898 +            case STRICTFP    : flag = Flags.STRICTFP; break;
  4.1899 +            case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  4.1900 +            default: break loop;
  4.1901 +            }
  4.1902 +            if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
  4.1903 +            lastPos = S.pos();
  4.1904 +            S.nextToken();
  4.1905 +            if (flag == Flags.ANNOTATION) {
  4.1906 +                checkAnnotations();
  4.1907 +                if (S.token() != INTERFACE) {
  4.1908 +                JCAnnotation ann = annotation(lastPos);
  4.1909 +                // if first modifier is an annotation, set pos to annotation's.
  4.1910 +                if (flags == 0 && annotations.isEmpty())
  4.1911 +                    pos = ann.pos;
  4.1912 +                annotations.append(ann);
  4.1913 +                lastPos = ann.pos;
  4.1914 +                    flag = 0;
  4.1915 +                }
  4.1916 +            }
  4.1917 +            flags |= flag;
  4.1918 +        }
  4.1919 +        switch (S.token()) {
  4.1920 +        case ENUM: flags |= Flags.ENUM; break;
  4.1921 +        case INTERFACE: flags |= Flags.INTERFACE; break;
  4.1922 +        default: break;
  4.1923 +        }
  4.1924 +
  4.1925 +        /* A modifiers tree with no modifier tokens or annotations
  4.1926 +         * has no text position. */
  4.1927 +        if (flags == 0 && annotations.isEmpty())
  4.1928 +            pos = Position.NOPOS;
  4.1929 +
  4.1930 +        JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  4.1931 +        if (pos != Position.NOPOS)
  4.1932 +            storeEnd(mods, S.prevEndPos());
  4.1933 +        return mods;
  4.1934 +    }
  4.1935 +
  4.1936 +    /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  4.1937 +     * @param pos position of "@" token
  4.1938 +     */
  4.1939 +    JCAnnotation annotation(int pos) {
  4.1940 +        // accept(AT); // AT consumed by caller
  4.1941 +        checkAnnotations();
  4.1942 +        JCTree ident = qualident();
  4.1943 +        List<JCExpression> fieldValues = annotationFieldValuesOpt();
  4.1944 +        JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
  4.1945 +        storeEnd(ann, S.prevEndPos());
  4.1946 +        return ann;
  4.1947 +    }
  4.1948 +
  4.1949 +    List<JCExpression> annotationFieldValuesOpt() {
  4.1950 +        return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  4.1951 +    }
  4.1952 +
  4.1953 +    /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  4.1954 +    List<JCExpression> annotationFieldValues() {
  4.1955 +        accept(LPAREN);
  4.1956 +        ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  4.1957 +        if (S.token() != RPAREN) {
  4.1958 +            buf.append(annotationFieldValue());
  4.1959 +            while (S.token() == COMMA) {
  4.1960 +                S.nextToken();
  4.1961 +                buf.append(annotationFieldValue());
  4.1962 +            }
  4.1963 +        }
  4.1964 +        accept(RPAREN);
  4.1965 +        return buf.toList();
  4.1966 +    }
  4.1967 +
  4.1968 +    /** AnnotationFieldValue    = AnnotationValue
  4.1969 +     *                          | Identifier "=" AnnotationValue
  4.1970 +     */
  4.1971 +    JCExpression annotationFieldValue() {
  4.1972 +        if (S.token() == IDENTIFIER) {
  4.1973 +            mode = EXPR;
  4.1974 +            JCExpression t1 = term1();
  4.1975 +            if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
  4.1976 +                int pos = S.pos();
  4.1977 +                accept(EQ);
  4.1978 +                return toP(F.at(pos).Assign(t1, annotationValue()));
  4.1979 +            } else {
  4.1980 +                return t1;
  4.1981 +            }
  4.1982 +        }
  4.1983 +        return annotationValue();
  4.1984 +    }
  4.1985 +
  4.1986 +    /* AnnotationValue          = ConditionalExpression
  4.1987 +     *                          | Annotation
  4.1988 +     *                          | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
  4.1989 +     */
  4.1990 +    JCExpression annotationValue() {
  4.1991 +        int pos;
  4.1992 +        switch (S.token()) {
  4.1993 +        case MONKEYS_AT:
  4.1994 +            pos = S.pos();
  4.1995 +            S.nextToken();
  4.1996 +            return annotation(pos);
  4.1997 +        case LBRACE:
  4.1998 +            pos = S.pos();
  4.1999 +            accept(LBRACE);
  4.2000 +            ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  4.2001 +            if (S.token() != RBRACE) {
  4.2002 +                buf.append(annotationValue());
  4.2003 +                while (S.token() == COMMA) {
  4.2004 +                    S.nextToken();
  4.2005 +                    if (S.token() == RPAREN) break;
  4.2006 +                    buf.append(annotationValue());
  4.2007 +                }
  4.2008 +            }
  4.2009 +            accept(RBRACE);
  4.2010 +            return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  4.2011 +        default:
  4.2012 +            mode = EXPR;
  4.2013 +            return term1();
  4.2014 +        }
  4.2015 +    }
  4.2016 +
  4.2017 +    /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  4.2018 +     */
  4.2019 +    public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  4.2020 +                                                                         JCExpression type,
  4.2021 +                                                                         T vdefs)
  4.2022 +    {
  4.2023 +        return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
  4.2024 +    }
  4.2025 +
  4.2026 +    /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  4.2027 +     *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  4.2028 +     *
  4.2029 +     *  @param reqInit  Is an initializer always required?
  4.2030 +     *  @param dc       The documentation comment for the variable declarations, or null.
  4.2031 +     */
  4.2032 +    <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  4.2033 +                                                                     JCModifiers mods,
  4.2034 +                                                                     JCExpression type,
  4.2035 +                                                                     Name name,
  4.2036 +                                                                     boolean reqInit,
  4.2037 +                                                                     String dc,
  4.2038 +                                                                     T vdefs)
  4.2039 +    {
  4.2040 +        vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  4.2041 +        while (S.token() == COMMA) {
  4.2042 +            // All but last of multiple declarators subsume a comma
  4.2043 +            storeEnd((JCTree)vdefs.elems.last(), S.endPos());
  4.2044 +            S.nextToken();
  4.2045 +            vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  4.2046 +        }
  4.2047 +        return vdefs;
  4.2048 +    }
  4.2049 +
  4.2050 +    /** VariableDeclarator = Ident VariableDeclaratorRest
  4.2051 +     *  ConstantDeclarator = Ident ConstantDeclaratorRest
  4.2052 +     */
  4.2053 +    JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
  4.2054 +        return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
  4.2055 +    }
  4.2056 +
  4.2057 +    /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  4.2058 +     *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  4.2059 +     *
  4.2060 +     *  @param reqInit  Is an initializer always required?
  4.2061 +     *  @param dc       The documentation comment for the variable declarations, or null.
  4.2062 +     */
  4.2063 +    JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  4.2064 +                                  boolean reqInit, String dc) {
  4.2065 +        type = bracketsOpt(type);
  4.2066 +        JCExpression init = null;
  4.2067 +        if (S.token() == EQ) {
  4.2068 +            S.nextToken();
  4.2069 +            init = variableInitializer();
  4.2070 +        }
  4.2071 +        else if (reqInit) syntaxError(S.pos(), "expected", EQ);
  4.2072 +        JCVariableDecl result =
  4.2073 +            toP(F.at(pos).VarDef(mods, name, type, init));
  4.2074 +        attach(result, dc);
  4.2075 +        return result;
  4.2076 +    }
  4.2077 +
  4.2078 +    /** VariableDeclaratorId = Ident BracketsOpt
  4.2079 +     */
  4.2080 +    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  4.2081 +        int pos = S.pos();
  4.2082 +        Name name = ident();
  4.2083 +        if ((mods.flags & Flags.VARARGS) == 0)
  4.2084 +            type = bracketsOpt(type);
  4.2085 +        return toP(F.at(pos).VarDef(mods, name, type, null));
  4.2086 +    }
  4.2087 +
  4.2088 +    /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  4.2089 +     */
  4.2090 +    public JCTree.JCCompilationUnit parseCompilationUnit() {
  4.2091 +        int pos = S.pos();
  4.2092 +        JCExpression pid = null;
  4.2093 +        String dc = S.docComment();
  4.2094 +        JCModifiers mods = null;
  4.2095 +        List<JCAnnotation> packageAnnotations = List.nil();
  4.2096 +        if (S.token() == MONKEYS_AT)
  4.2097 +            mods = modifiersOpt();
  4.2098 +
  4.2099 +        if (S.token() == PACKAGE) {
  4.2100 +            if (mods != null) {
  4.2101 +                checkNoMods(mods.flags);
  4.2102 +                packageAnnotations = mods.annotations;
  4.2103 +                mods = null;
  4.2104 +            }
  4.2105 +            S.nextToken();
  4.2106 +            pid = qualident();
  4.2107 +            accept(SEMI);
  4.2108 +        }
  4.2109 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  4.2110 +        boolean checkForImports = true;
  4.2111 +        while (S.token() != EOF) {
  4.2112 +            if (S.pos() <= errorEndPos) {
  4.2113 +                // error recovery
  4.2114 +                skip(checkForImports, false, false, false);
  4.2115 +                if (S.token() == EOF)
  4.2116 +                    break;
  4.2117 +            }
  4.2118 +            if (checkForImports && mods == null && S.token() == IMPORT) {
  4.2119 +                defs.append(importDeclaration());
  4.2120 +            } else {
  4.2121 +                JCTree def = typeDeclaration(mods);
  4.2122 +                if (def instanceof JCExpressionStatement)
  4.2123 +                    def = ((JCExpressionStatement)def).expr;
  4.2124 +                defs.append(def);
  4.2125 +                if (def instanceof JCClassDecl)
  4.2126 +                    checkForImports = false;
  4.2127 +                mods = null;
  4.2128 +            }
  4.2129 +        }
  4.2130 +        JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
  4.2131 +        attach(toplevel, dc);
  4.2132 +        if (defs.elems.isEmpty())
  4.2133 +            storeEnd(toplevel, S.prevEndPos());
  4.2134 +        if (keepDocComments)
  4.2135 +            toplevel.docComments = docComments;
  4.2136 +        if (keepLineMap)
  4.2137 +            toplevel.lineMap = S.getLineMap();
  4.2138 +        return toplevel;
  4.2139 +    }
  4.2140 +
  4.2141 +    /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  4.2142 +     */
  4.2143 +    JCTree importDeclaration() {
  4.2144 +        int pos = S.pos();
  4.2145 +        S.nextToken();
  4.2146 +        boolean importStatic = false;
  4.2147 +        if (S.token() == STATIC) {
  4.2148 +            checkStaticImports();
  4.2149 +            importStatic = true;
  4.2150 +            S.nextToken();
  4.2151 +        }
  4.2152 +        JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
  4.2153 +        do {
  4.2154 +            int pos1 = S.pos();
  4.2155 +            accept(DOT);
  4.2156 +            if (S.token() == STAR) {
  4.2157 +                pid = to(F.at(pos1).Select(pid, names.asterisk));
  4.2158 +                S.nextToken();
  4.2159 +                break;
  4.2160 +            } else {
  4.2161 +                pid = toP(F.at(pos1).Select(pid, ident()));
  4.2162 +            }
  4.2163 +        } while (S.token() == DOT);
  4.2164 +        accept(SEMI);
  4.2165 +        return toP(F.at(pos).Import(pid, importStatic));
  4.2166 +    }
  4.2167 +
  4.2168 +    /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  4.2169 +     *                  | ";"
  4.2170 +     */
  4.2171 +    JCTree typeDeclaration(JCModifiers mods) {
  4.2172 +        int pos = S.pos();
  4.2173 +        if (mods == null && S.token() == SEMI) {
  4.2174 +            S.nextToken();
  4.2175 +            return toP(F.at(pos).Skip());
  4.2176 +        } else {
  4.2177 +            String dc = S.docComment();
  4.2178 +            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
  4.2179 +        }
  4.2180 +    }
  4.2181 +
  4.2182 +    /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  4.2183 +     *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  4.2184 +     *  @param mods     Any modifiers starting the class or interface declaration
  4.2185 +     *  @param dc       The documentation comment for the class, or null.
  4.2186 +     */
  4.2187 +    JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
  4.2188 +        if (S.token() == CLASS) {
  4.2189 +            return classDeclaration(mods, dc);
  4.2190 +        } else if (S.token() == INTERFACE) {
  4.2191 +            return interfaceDeclaration(mods, dc);
  4.2192 +        } else if (allowEnums) {
  4.2193 +            if (S.token() == ENUM) {
  4.2194 +                return enumDeclaration(mods, dc);
  4.2195 +            } else {
  4.2196 +                int pos = S.pos();
  4.2197 +                List<JCTree> errs;
  4.2198 +                if (S.token() == IDENTIFIER) {
  4.2199 +                    errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  4.2200 +                    setErrorEndPos(S.pos());
  4.2201 +                } else {
  4.2202 +                    errs = List.<JCTree>of(mods);
  4.2203 +                }
  4.2204 +                return toP(F.Exec(syntaxError(pos, errs, "expected3",
  4.2205 +                                              CLASS, INTERFACE, ENUM)));
  4.2206 +            }
  4.2207 +        } else {
  4.2208 +            if (S.token() == ENUM) {
  4.2209 +                log.error(S.pos(), "enums.not.supported.in.source", source.name);
  4.2210 +                allowEnums = true;
  4.2211 +                return enumDeclaration(mods, dc);
  4.2212 +            }
  4.2213 +            int pos = S.pos();
  4.2214 +            List<JCTree> errs;
  4.2215 +            if (S.token() == IDENTIFIER) {
  4.2216 +                errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  4.2217 +                setErrorEndPos(S.pos());
  4.2218 +            } else {
  4.2219 +                errs = List.<JCTree>of(mods);
  4.2220 +            }
  4.2221 +            return toP(F.Exec(syntaxError(pos, errs, "expected2",
  4.2222 +                                          CLASS, INTERFACE)));
  4.2223 +        }
  4.2224 +    }
  4.2225 +
  4.2226 +    /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  4.2227 +     *                     [IMPLEMENTS TypeList] ClassBody
  4.2228 +     *  @param mods    The modifiers starting the class declaration
  4.2229 +     *  @param dc       The documentation comment for the class, or null.
  4.2230 +     */
  4.2231 +    JCClassDecl classDeclaration(JCModifiers mods, String dc) {
  4.2232 +        int pos = S.pos();
  4.2233 +        accept(CLASS);
  4.2234 +        Name name = ident();
  4.2235 +
  4.2236 +        List<JCTypeParameter> typarams = typeParametersOpt();
  4.2237 +
  4.2238 +        JCTree extending = null;
  4.2239 +        if (S.token() == EXTENDS) {
  4.2240 +            S.nextToken();
  4.2241 +            extending = parseType();
  4.2242 +        }
  4.2243 +        List<JCExpression> implementing = List.nil();
  4.2244 +        if (S.token() == IMPLEMENTS) {
  4.2245 +            S.nextToken();
  4.2246 +            implementing = typeList();
  4.2247 +        }
  4.2248 +        List<JCTree> defs = classOrInterfaceBody(name, false);
  4.2249 +        JCClassDecl result = toP(F.at(pos).ClassDef(
  4.2250 +            mods, name, typarams, extending, implementing, defs));
  4.2251 +        attach(result, dc);
  4.2252 +        return result;
  4.2253 +    }
  4.2254 +
  4.2255 +    /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  4.2256 +     *                         [EXTENDS TypeList] InterfaceBody
  4.2257 +     *  @param mods    The modifiers starting the interface declaration
  4.2258 +     *  @param dc       The documentation comment for the interface, or null.
  4.2259 +     */
  4.2260 +    JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
  4.2261 +        int pos = S.pos();
  4.2262 +        accept(INTERFACE);
  4.2263 +        Name name = ident();
  4.2264 +
  4.2265 +        List<JCTypeParameter> typarams = typeParametersOpt();
  4.2266 +
  4.2267 +        List<JCExpression> extending = List.nil();
  4.2268 +        if (S.token() == EXTENDS) {
  4.2269 +            S.nextToken();
  4.2270 +            extending = typeList();
  4.2271 +        }
  4.2272 +        List<JCTree> defs = classOrInterfaceBody(name, true);
  4.2273 +        JCClassDecl result = toP(F.at(pos).ClassDef(
  4.2274 +            mods, name, typarams, null, extending, defs));
  4.2275 +        attach(result, dc);
  4.2276 +        return result;
  4.2277 +    }
  4.2278 +
  4.2279 +    /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  4.2280 +     *  @param mods    The modifiers starting the enum declaration
  4.2281 +     *  @param dc       The documentation comment for the enum, or null.
  4.2282 +     */
  4.2283 +    JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
  4.2284 +        int pos = S.pos();
  4.2285 +        accept(ENUM);
  4.2286 +        Name name = ident();
  4.2287 +
  4.2288 +        List<JCExpression> implementing = List.nil();
  4.2289 +        if (S.token() == IMPLEMENTS) {
  4.2290 +            S.nextToken();
  4.2291 +            implementing = typeList();
  4.2292 +        }
  4.2293 +
  4.2294 +        List<JCTree> defs = enumBody(name);
  4.2295 +        JCModifiers newMods =
  4.2296 +            F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations);
  4.2297 +        JCClassDecl result = toP(F.at(pos).
  4.2298 +            ClassDef(newMods, name, List.<JCTypeParameter>nil(),
  4.2299 +                null, implementing, defs));
  4.2300 +        attach(result, dc);
  4.2301 +        return result;
  4.2302 +    }
  4.2303 +
  4.2304 +    /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  4.2305 +     *                  [ ";" {ClassBodyDeclaration} ] "}"
  4.2306 +     */
  4.2307 +    List<JCTree> enumBody(Name enumName) {
  4.2308 +        accept(LBRACE);
  4.2309 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  4.2310 +        if (S.token() == COMMA) {
  4.2311 +            S.nextToken();
  4.2312 +        } else if (S.token() != RBRACE && S.token() != SEMI) {
  4.2313 +            defs.append(enumeratorDeclaration(enumName));
  4.2314 +            while (S.token() == COMMA) {
  4.2315 +                S.nextToken();
  4.2316 +                if (S.token() == RBRACE || S.token() == SEMI) break;
  4.2317 +                defs.append(enumeratorDeclaration(enumName));
  4.2318 +            }
  4.2319 +            if (S.token() != SEMI && S.token() != RBRACE) {
  4.2320 +                defs.append(syntaxError(S.pos(), "expected3",
  4.2321 +                                COMMA, RBRACE, SEMI));
  4.2322 +                S.nextToken();
  4.2323 +            }
  4.2324 +        }
  4.2325 +        if (S.token() == SEMI) {
  4.2326 +            S.nextToken();
  4.2327 +            while (S.token() != RBRACE && S.token() != EOF) {
  4.2328 +                defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  4.2329 +                                                                false));
  4.2330 +                if (S.pos() <= errorEndPos) {
  4.2331 +                    // error recovery
  4.2332 +                   skip(false, true, true, false);
  4.2333 +                }
  4.2334 +            }
  4.2335 +        }
  4.2336 +        accept(RBRACE);
  4.2337 +        return defs.toList();
  4.2338 +    }
  4.2339 +
  4.2340 +    /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  4.2341 +     */
  4.2342 +    JCTree enumeratorDeclaration(Name enumName) {
  4.2343 +        String dc = S.docComment();
  4.2344 +        int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  4.2345 +        if (S.deprecatedFlag()) {
  4.2346 +            flags |= Flags.DEPRECATED;
  4.2347 +            S.resetDeprecatedFlag();
  4.2348 +        }
  4.2349 +        int pos = S.pos();
  4.2350 +        List<JCAnnotation> annotations = annotationsOpt();
  4.2351 +        JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  4.2352 +        List<JCExpression> typeArgs = typeArgumentsOpt();
  4.2353 +        int identPos = S.pos();
  4.2354 +        Name name = ident();
  4.2355 +        int createPos = S.pos();
  4.2356 +        List<JCExpression> args = (S.token() == LPAREN)
  4.2357 +            ? arguments() : List.<JCExpression>nil();
  4.2358 +        JCClassDecl body = null;
  4.2359 +        if (S.token() == LBRACE) {
  4.2360 +            JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  4.2361 +            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  4.2362 +            body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  4.2363 +        }
  4.2364 +        if (args.isEmpty() && body == null)
  4.2365 +            createPos = Position.NOPOS;
  4.2366 +        JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
  4.2367 +        JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  4.2368 +        if (createPos != Position.NOPOS)
  4.2369 +            storeEnd(create, S.prevEndPos());
  4.2370 +        ident = F.at(Position.NOPOS).Ident(enumName);
  4.2371 +        JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  4.2372 +        attach(result, dc);
  4.2373 +        return result;
  4.2374 +    }
  4.2375 +
  4.2376 +    /** TypeList = Type {"," Type}
  4.2377 +     */
  4.2378 +    List<JCExpression> typeList() {
  4.2379 +        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  4.2380 +        ts.append(parseType());
  4.2381 +        while (S.token() == COMMA) {
  4.2382 +            S.nextToken();
  4.2383 +            ts.append(parseType());
  4.2384 +        }
  4.2385 +        return ts.toList();
  4.2386 +    }
  4.2387 +
  4.2388 +    /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  4.2389 +     *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  4.2390 +     */
  4.2391 +    List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  4.2392 +        accept(LBRACE);
  4.2393 +        if (S.pos() <= errorEndPos) {
  4.2394 +            // error recovery
  4.2395 +            skip(false, true, false, false);
  4.2396 +            if (S.token() == LBRACE)
  4.2397 +                S.nextToken();
  4.2398 +        }
  4.2399 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  4.2400 +        while (S.token() != RBRACE && S.token() != EOF) {
  4.2401 +            defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  4.2402 +            if (S.pos() <= errorEndPos) {
  4.2403 +               // error recovery
  4.2404 +               skip(false, true, true, false);
  4.2405 +           }
  4.2406 +        }
  4.2407 +        accept(RBRACE);
  4.2408 +        return defs.toList();
  4.2409 +    }
  4.2410 +
  4.2411 +    /** ClassBodyDeclaration =
  4.2412 +     *      ";"
  4.2413 +     *    | [STATIC] Block
  4.2414 +     *    | ModifiersOpt
  4.2415 +     *      ( Type Ident
  4.2416 +     *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  4.2417 +     *      | VOID Ident MethodDeclaratorRest
  4.2418 +     *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
  4.2419 +     *      | Ident ConstructorDeclaratorRest
  4.2420 +     *      | TypeParameters Ident ConstructorDeclaratorRest
  4.2421 +     *      | ClassOrInterfaceOrEnumDeclaration
  4.2422 +     *      )
  4.2423 +     *  InterfaceBodyDeclaration =
  4.2424 +     *      ";"
  4.2425 +     *    | ModifiersOpt Type Ident
  4.2426 +     *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
  4.2427 +     */
  4.2428 +    List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  4.2429 +        if (S.token() == SEMI) {
  4.2430 +            S.nextToken();
  4.2431 +            return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
  4.2432 +        } else {
  4.2433 +            String dc = S.docComment();
  4.2434 +            int pos = S.pos();
  4.2435 +            JCModifiers mods = modifiersOpt();
  4.2436 +            if (S.token() == CLASS ||
  4.2437 +                S.token() == INTERFACE ||
  4.2438 +                allowEnums && S.token() == ENUM) {
  4.2439 +                return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  4.2440 +            } else if (S.token() == LBRACE && !isInterface &&
  4.2441 +                       (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  4.2442 +                       mods.annotations.isEmpty()) {
  4.2443 +                return List.<JCTree>of(block(pos, mods.flags));
  4.2444 +            } else {
  4.2445 +                pos = S.pos();
  4.2446 +                List<JCTypeParameter> typarams = typeParametersOpt();
  4.2447 +                // Hack alert:  if there are type arguments but no Modifiers, the start
  4.2448 +                // position will be lost unless we set the Modifiers position.  There
  4.2449 +                // should be an AST node for type parameters (BugId 5005090).
  4.2450 +                if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
  4.2451 +                    mods.pos = pos;
  4.2452 +                }
  4.2453 +                Token token = S.token();
  4.2454 +                Name name = S.name();
  4.2455 +                pos = S.pos();
  4.2456 +                JCExpression type;
  4.2457 +                boolean isVoid = S.token() == VOID;
  4.2458 +                if (isVoid) {
  4.2459 +                    type = to(F.at(pos).TypeIdent(TypeTags.VOID));
  4.2460 +                    S.nextToken();
  4.2461 +                } else {
  4.2462 +                    type = parseType();
  4.2463 +                }
  4.2464 +                if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
  4.2465 +                    if (isInterface || name != className)
  4.2466 +                        log.error(pos, "invalid.meth.decl.ret.type.req");
  4.2467 +                    return List.of(methodDeclaratorRest(
  4.2468 +                        pos, mods, null, names.init, typarams,
  4.2469 +                        isInterface, true, dc));
  4.2470 +                } else {
  4.2471 +                    pos = S.pos();
  4.2472 +                    name = ident();
  4.2473 +                    if (S.token() == LPAREN) {
  4.2474 +                        return List.of(methodDeclaratorRest(
  4.2475 +                            pos, mods, type, name, typarams,
  4.2476 +                            isInterface, isVoid, dc));
  4.2477 +                    } else if (!isVoid && typarams.isEmpty()) {
  4.2478 +                        List<JCTree> defs =
  4.2479 +                            variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  4.2480 +                                                    new ListBuffer<JCTree>()).toList();
  4.2481 +                        storeEnd(defs.last(), S.endPos());
  4.2482 +                        accept(SEMI);
  4.2483 +                        return defs;
  4.2484 +                    } else {
  4.2485 +                        pos = S.pos();
  4.2486 +                        List<JCTree> err = isVoid
  4.2487 +                            ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  4.2488 +                                List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  4.2489 +                            : null;
  4.2490 +                        return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
  4.2491 +                    }
  4.2492 +                }
  4.2493 +            }
  4.2494 +        }
  4.2495 +    }
  4.2496 +
  4.2497 +    /** MethodDeclaratorRest =
  4.2498 +     *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  4.2499 +     *  VoidMethodDeclaratorRest =
  4.2500 +     *      FormalParameters [Throws TypeList] ( MethodBody | ";")
  4.2501 +     *  InterfaceMethodDeclaratorRest =
  4.2502 +     *      FormalParameters BracketsOpt [THROWS TypeList] ";"
  4.2503 +     *  VoidInterfaceMethodDeclaratorRest =
  4.2504 +     *      FormalParameters [THROWS TypeList] ";"
  4.2505 +     *  ConstructorDeclaratorRest =
  4.2506 +     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
  4.2507 +     */
  4.2508 +    JCTree methodDeclaratorRest(int pos,
  4.2509 +                              JCModifiers mods,
  4.2510 +                              JCExpression type,
  4.2511 +                              Name name,
  4.2512 +                              List<JCTypeParameter> typarams,
  4.2513 +                              boolean isInterface, boolean isVoid,
  4.2514 +                              String dc) {
  4.2515 +        List<JCVariableDecl> params = formalParameters();
  4.2516 +        if (!isVoid) type = bracketsOpt(type);
  4.2517 +        List<JCExpression> thrown = List.nil();
  4.2518 +        if (S.token() == THROWS) {
  4.2519 +            S.nextToken();
  4.2520 +            thrown = qualidentList();
  4.2521 +        }
  4.2522 +        JCBlock body = null;
  4.2523 +        JCExpression defaultValue;
  4.2524 +        if (S.token() == LBRACE) {
  4.2525 +            body = block();
  4.2526 +            defaultValue = null;
  4.2527 +        } else {
  4.2528 +            if (S.token() == DEFAULT) {
  4.2529 +                accept(DEFAULT);
  4.2530 +                defaultValue = annotationValue();
  4.2531 +            } else {
  4.2532 +                defaultValue = null;
  4.2533 +            }
  4.2534 +            accept(SEMI);
  4.2535 +            if (S.pos() <= errorEndPos) {
  4.2536 +                // error recovery
  4.2537 +                skip(false, true, false, false);
  4.2538 +                if (S.token() == LBRACE) {
  4.2539 +                    body = block();
  4.2540 +                }
  4.2541 +            }
  4.2542 +        }
  4.2543 +        JCMethodDecl result =
  4.2544 +            toP(F.at(pos).MethodDef(mods, name, type, typarams,
  4.2545 +                                    params, thrown,
  4.2546 +                                    body, defaultValue));
  4.2547 +        attach(result, dc);
  4.2548 +        return result;
  4.2549 +    }
  4.2550 +
  4.2551 +    /** QualidentList = Qualident {"," Qualident}
  4.2552 +     */
  4.2553 +    List<JCExpression> qualidentList() {
  4.2554 +        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  4.2555 +        ts.append(qualident());
  4.2556 +        while (S.token() == COMMA) {
  4.2557 +            S.nextToken();
  4.2558 +            ts.append(qualident());
  4.2559 +        }
  4.2560 +        return ts.toList();
  4.2561 +    }
  4.2562 +
  4.2563 +    /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  4.2564 +     */
  4.2565 +    List<JCTypeParameter> typeParametersOpt() {
  4.2566 +        if (S.token() == LT) {
  4.2567 +            checkGenerics();
  4.2568 +            ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  4.2569 +            S.nextToken();
  4.2570 +            typarams.append(typeParameter());
  4.2571 +            while (S.token() == COMMA) {
  4.2572 +                S.nextToken();
  4.2573 +                typarams.append(typeParameter());
  4.2574 +            }
  4.2575 +            accept(GT);
  4.2576 +            return typarams.toList();
  4.2577 +        } else {
  4.2578 +            return List.nil();
  4.2579 +        }
  4.2580 +    }
  4.2581 +
  4.2582 +    /** TypeParameter = TypeVariable [TypeParameterBound]
  4.2583 +     *  TypeParameterBound = EXTENDS Type {"&" Type}
  4.2584 +     *  TypeVariable = Ident
  4.2585 +     */
  4.2586 +    JCTypeParameter typeParameter() {
  4.2587 +        int pos = S.pos();
  4.2588 +        Name name = ident();
  4.2589 +        ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  4.2590 +        if (S.token() == EXTENDS) {
  4.2591 +            S.nextToken();
  4.2592 +            bounds.append(parseType());
  4.2593 +            while (S.token() == AMP) {
  4.2594 +                S.nextToken();
  4.2595 +                bounds.append(parseType());
  4.2596 +            }
  4.2597 +        }
  4.2598 +        return toP(F.at(pos).TypeParameter(name, bounds.toList()));
  4.2599 +    }
  4.2600 +
  4.2601 +    /** FormalParameters = "(" [ FormalParameterList ] ")"
  4.2602 +     *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  4.2603 +     *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  4.2604 +     */
  4.2605 +    List<JCVariableDecl> formalParameters() {
  4.2606 +        ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  4.2607 +        JCVariableDecl lastParam = null;
  4.2608 +        accept(LPAREN);
  4.2609 +        if (S.token() != RPAREN) {
  4.2610 +            params.append(lastParam = formalParameter());
  4.2611 +            while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
  4.2612 +                S.nextToken();
  4.2613 +                params.append(lastParam = formalParameter());
  4.2614 +            }
  4.2615 +        }
  4.2616 +        accept(RPAREN);
  4.2617 +        return params.toList();
  4.2618 +    }
  4.2619 +
  4.2620 +    JCModifiers optFinal(long flags) {
  4.2621 +        JCModifiers mods = modifiersOpt();
  4.2622 +        checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  4.2623 +        mods.flags |= flags;
  4.2624 +        return mods;
  4.2625 +    }
  4.2626 +
  4.2627 +    /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  4.2628 +     *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  4.2629 +     */
  4.2630 +    JCVariableDecl formalParameter() {
  4.2631 +        JCModifiers mods = optFinal(Flags.PARAMETER);
  4.2632 +        JCExpression type = parseType();
  4.2633 +        if (S.token() == ELLIPSIS) {
  4.2634 +            checkVarargs();
  4.2635 +            mods.flags |= Flags.VARARGS;
  4.2636 +            type = to(F.at(S.pos()).TypeArray(type));
  4.2637 +            S.nextToken();
  4.2638 +        }
  4.2639 +        return variableDeclaratorId(mods, type);
  4.2640 +    }
  4.2641 +
  4.2642 +/* ---------- auxiliary methods -------------- */
  4.2643 +
  4.2644 +    /** Check that given tree is a legal expression statement.
  4.2645 +     */
  4.2646 +    protected JCExpression checkExprStat(JCExpression t) {
  4.2647 +        switch(t.getTag()) {
  4.2648 +        case JCTree.PREINC: case JCTree.PREDEC:
  4.2649 +        case JCTree.POSTINC: case JCTree.POSTDEC:
  4.2650 +        case JCTree.ASSIGN:
  4.2651 +        case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
  4.2652 +        case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
  4.2653 +        case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
  4.2654 +        case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
  4.2655 +        case JCTree.APPLY: case JCTree.NEWCLASS:
  4.2656 +        case JCTree.ERRONEOUS:
  4.2657 +            return t;
  4.2658 +        default:
  4.2659 +            log.error(t.pos, "not.stmt");
  4.2660 +            return F.at(t.pos).Erroneous(List.<JCTree>of(t));
  4.2661 +        }
  4.2662 +    }
  4.2663 +
  4.2664 +    /** Return precedence of operator represented by token,
  4.2665 +     *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  4.2666 +     */
  4.2667 +    static int prec(Token token) {
  4.2668 +        int oc = optag(token);
  4.2669 +        return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
  4.2670 +    }
  4.2671 +
  4.2672 +    /** Return operation tag of binary operator represented by token,
  4.2673 +     *  -1 if token is not a binary operator.
  4.2674 +     */
  4.2675 +    static int optag(Token token) {
  4.2676 +        switch (token) {
  4.2677 +        case BARBAR:
  4.2678 +            return JCTree.OR;
  4.2679 +        case AMPAMP:
  4.2680 +            return JCTree.AND;
  4.2681 +        case BAR:
  4.2682 +            return JCTree.BITOR;
  4.2683 +        case BAREQ:
  4.2684 +            return JCTree.BITOR_ASG;
  4.2685 +        case CARET:
  4.2686 +            return JCTree.BITXOR;
  4.2687 +        case CARETEQ:
  4.2688 +            return JCTree.BITXOR_ASG;
  4.2689 +        case AMP:
  4.2690 +            return JCTree.BITAND;
  4.2691 +        case AMPEQ:
  4.2692 +            return JCTree.BITAND_ASG;
  4.2693 +        case EQEQ:
  4.2694 +            return JCTree.EQ;
  4.2695 +        case BANGEQ:
  4.2696 +            return JCTree.NE;
  4.2697 +        case LT:
  4.2698 +            return JCTree.LT;
  4.2699 +        case GT:
  4.2700 +            return JCTree.GT;
  4.2701 +        case LTEQ:
  4.2702 +            return JCTree.LE;
  4.2703 +        case GTEQ:
  4.2704 +            return JCTree.GE;
  4.2705 +        case LTLT:
  4.2706 +            return JCTree.SL;
  4.2707 +        case LTLTEQ:
  4.2708 +            return JCTree.SL_ASG;
  4.2709 +        case GTGT:
  4.2710 +            return JCTree.SR;
  4.2711 +        case GTGTEQ:
  4.2712 +            return JCTree.SR_ASG;
  4.2713 +        case GTGTGT:
  4.2714 +            return JCTree.USR;
  4.2715 +        case GTGTGTEQ:
  4.2716 +            return JCTree.USR_ASG;
  4.2717 +        case PLUS:
  4.2718 +            return JCTree.PLUS;
  4.2719 +        case PLUSEQ:
  4.2720 +            return JCTree.PLUS_ASG;
  4.2721 +        case SUB:
  4.2722 +            return JCTree.MINUS;
  4.2723 +        case SUBEQ:
  4.2724 +            return JCTree.MINUS_ASG;
  4.2725 +        case STAR:
  4.2726 +            return JCTree.MUL;
  4.2727 +        case STAREQ:
  4.2728 +            return JCTree.MUL_ASG;
  4.2729 +        case SLASH:
  4.2730 +            return JCTree.DIV;
  4.2731 +        case SLASHEQ:
  4.2732 +            return JCTree.DIV_ASG;
  4.2733 +        case PERCENT:
  4.2734 +            return JCTree.MOD;
  4.2735 +        case PERCENTEQ:
  4.2736 +            return JCTree.MOD_ASG;
  4.2737 +        case INSTANCEOF:
  4.2738 +            return JCTree.TYPETEST;
  4.2739 +        default:
  4.2740 +            return -1;
  4.2741 +        }
  4.2742 +    }
  4.2743 +
  4.2744 +    /** Return operation tag of unary operator represented by token,
  4.2745 +     *  -1 if token is not a binary operator.
  4.2746 +     */
  4.2747 +    static int unoptag(Token token) {
  4.2748 +        switch (token) {
  4.2749 +        case PLUS:
  4.2750 +            return JCTree.POS;
  4.2751 +        case SUB:
  4.2752 +            return JCTree.NEG;
  4.2753 +        case BANG:
  4.2754 +            return JCTree.NOT;
  4.2755 +        case TILDE:
  4.2756 +            return JCTree.COMPL;
  4.2757 +        case PLUSPLUS:
  4.2758 +            return JCTree.PREINC;
  4.2759 +        case SUBSUB:
  4.2760 +            return JCTree.PREDEC;
  4.2761 +        default:
  4.2762 +            return -1;
  4.2763 +        }
  4.2764 +    }
  4.2765 +
  4.2766 +    /** Return type tag of basic type represented by token,
  4.2767 +     *  -1 if token is not a basic type identifier.
  4.2768 +     */
  4.2769 +    static int typetag(Token token) {
  4.2770 +        switch (token) {
  4.2771 +        case BYTE:
  4.2772 +            return TypeTags.BYTE;
  4.2773 +        case CHAR:
  4.2774 +            return TypeTags.CHAR;
  4.2775 +        case SHORT:
  4.2776 +            return TypeTags.SHORT;
  4.2777 +        case INT:
  4.2778 +            return TypeTags.INT;
  4.2779 +        case LONG:
  4.2780 +            return TypeTags.LONG;
  4.2781 +        case FLOAT:
  4.2782 +            return TypeTags.FLOAT;
  4.2783 +        case DOUBLE:
  4.2784 +            return TypeTags.DOUBLE;
  4.2785 +        case BOOLEAN:
  4.2786 +            return TypeTags.BOOLEAN;
  4.2787 +        default:
  4.2788 +            return -1;
  4.2789 +        }
  4.2790 +    }
  4.2791 +
  4.2792 +    void checkGenerics() {
  4.2793 +        if (!allowGenerics) {
  4.2794 +            log.error(S.pos(), "generics.not.supported.in.source", source.name);
  4.2795 +            allowGenerics = true;
  4.2796 +        }
  4.2797 +    }
  4.2798 +    void checkVarargs() {
  4.2799 +        if (!allowVarargs) {
  4.2800 +            log.error(S.pos(), "varargs.not.supported.in.source", source.name);
  4.2801 +            allowVarargs = true;
  4.2802 +        }
  4.2803 +    }
  4.2804 +    void checkForeach() {
  4.2805 +        if (!allowForeach) {
  4.2806 +            log.error(S.pos(), "foreach.not.supported.in.source", source.name);
  4.2807 +            allowForeach = true;
  4.2808 +        }
  4.2809 +    }
  4.2810 +    void checkStaticImports() {
  4.2811 +        if (!allowStaticImport) {
  4.2812 +            log.error(S.pos(), "static.import.not.supported.in.source", source.name);
  4.2813 +            allowStaticImport = true;
  4.2814 +        }
  4.2815 +    }
  4.2816 +    void checkAnnotations() {
  4.2817 +        if (!allowAnnotations) {
  4.2818 +            log.error(S.pos(), "annotations.not.supported.in.source", source.name);
  4.2819 +            allowAnnotations = true;
  4.2820 +        }
  4.2821 +    }
  4.2822 +}
     5.1 --- a/src/share/classes/com/sun/tools/javac/parser/Parser.java	Tue Sep 09 10:28:21 2008 -0700
     5.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Parser.java	Tue Sep 09 10:40:50 2008 -0700
     5.3 @@ -23,2834 +23,44 @@
     5.4   * have any questions.
     5.5   */
     5.6  
     5.7 +
     5.8  package com.sun.tools.javac.parser;
     5.9  
    5.10 -import java.util.*;
    5.11 +import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
    5.12 +import com.sun.tools.javac.tree.JCTree.JCExpression;
    5.13 +import com.sun.tools.javac.tree.JCTree.JCStatement;
    5.14  
    5.15 -import com.sun.tools.javac.tree.*;
    5.16 -import com.sun.tools.javac.code.*;
    5.17 -import com.sun.tools.javac.util.*;
    5.18 -import com.sun.tools.javac.util.List;
    5.19 -import static com.sun.tools.javac.util.ListBuffer.lb;
    5.20 -
    5.21 -import com.sun.tools.javac.tree.JCTree.*;
    5.22 -
    5.23 -import static com.sun.tools.javac.parser.Token.*;
    5.24 -
    5.25 -/** The parser maps a token sequence into an abstract syntax
    5.26 - *  tree. It operates by recursive descent, with code derived
    5.27 - *  systematically from an LL(1) grammar. For efficiency reasons, an
    5.28 - *  operator precedence scheme is used for parsing binary operation
    5.29 - *  expressions.
    5.30 +/**
    5.31 + * Reads syntactic units from source code.
    5.32 + * Parsers are normally created from a ParserFactory.
    5.33   *
    5.34 - *  <p><b>This is NOT part of any API supported by Sun Microsystems.  If
    5.35 - *  you write code that depends on this, you do so at your own risk.
    5.36 - *  This code and its internal interfaces are subject to change or
    5.37 - *  deletion without notice.</b>
    5.38 + * <p><b>This is NOT part of any API supported by Sun Microsystems.
    5.39 + * If you write code that depends on this, you do so at your own risk.
    5.40 + * This code and its internal interfaces are subject to change or
    5.41 + * deletion without notice.</b>
    5.42   */
    5.43 -public class Parser {
    5.44 -
    5.45 -    /** A factory for creating parsers. */
    5.46 -    public static class Factory {
    5.47 -        /** The context key for the parser factory. */
    5.48 -        protected static final Context.Key<Parser.Factory> parserFactoryKey =
    5.49 -            new Context.Key<Parser.Factory>();
    5.50 -
    5.51 -        /** Get the Factory instance for this context. */
    5.52 -        public static Factory instance(Context context) {
    5.53 -            Factory instance = context.get(parserFactoryKey);
    5.54 -            if (instance == null)
    5.55 -                instance = new Factory(context);
    5.56 -            return instance;
    5.57 -        }
    5.58 -
    5.59 -        final TreeMaker F;
    5.60 -        final Log log;
    5.61 -        final Keywords keywords;
    5.62 -        final Source source;
    5.63 -        final Name.Table names;
    5.64 -        final Options options;
    5.65 -
    5.66 -        /** Create a new parser factory. */
    5.67 -        protected Factory(Context context) {
    5.68 -            context.put(parserFactoryKey, this);
    5.69 -            this.F = TreeMaker.instance(context);
    5.70 -            this.log = Log.instance(context);
    5.71 -            this.names = Name.Table.instance(context);
    5.72 -            this.keywords = Keywords.instance(context);
    5.73 -            this.source = Source.instance(context);
    5.74 -            this.options = Options.instance(context);
    5.75 -        }
    5.76 -
    5.77 -        /**
    5.78 -         * Create a new Parser.
    5.79 -         * @param S Lexer for getting tokens while parsing
    5.80 -         * @param keepDocComments true if javadoc comments should be kept
    5.81 -         * @param genEndPos true if end positions should be generated
    5.82 -         */
    5.83 -        public Parser newParser(Lexer S, boolean keepDocComments, boolean genEndPos) {
    5.84 -            if (!genEndPos)
    5.85 -                return new Parser(this, S, keepDocComments);
    5.86 -            else
    5.87 -                return new EndPosParser(this, S, keepDocComments);
    5.88 -        }
    5.89 -    }
    5.90 -
    5.91 -    /** The number of precedence levels of infix operators.
    5.92 +public interface Parser {
    5.93 +    /**
    5.94 +     * Parse a compilation unit.
    5.95 +     * @return a compilation unit
    5.96       */
    5.97 -    private static final int infixPrecedenceLevels = 10;
    5.98 -
    5.99 -    /** The scanner used for lexical analysis.
   5.100 -     */
   5.101 -    private Lexer S;
   5.102 -
   5.103 -    /** The factory to be used for abstract syntax tree construction.
   5.104 -     */
   5.105 -    protected TreeMaker F;
   5.106 -
   5.107 -    /** The log to be used for error diagnostics.
   5.108 -     */
   5.109 -    private Log log;
   5.110 -
   5.111 -    /** The keyword table. */
   5.112 -    private Keywords keywords;
   5.113 -
   5.114 -    /** The Source language setting. */
   5.115 -    private Source source;
   5.116 -
   5.117 -    /** The name table. */
   5.118 -    private Name.Table names;
   5.119 -
   5.120 -    /** Construct a parser from a given scanner, tree factory and log.
   5.121 -     */
   5.122 -    protected Parser(Factory fac,
   5.123 -                     Lexer S,
   5.124 -                     boolean keepDocComments) {
   5.125 -        this.S = S;
   5.126 -        S.nextToken(); // prime the pump
   5.127 -        this.F = fac.F;
   5.128 -        this.log = fac.log;
   5.129 -        this.names = fac.names;
   5.130 -        this.keywords = fac.keywords;
   5.131 -        this.source = fac.source;
   5.132 -        Options options = fac.options;
   5.133 -        this.allowGenerics = source.allowGenerics();
   5.134 -        this.allowVarargs = source.allowVarargs();
   5.135 -        this.allowAsserts = source.allowAsserts();
   5.136 -        this.allowEnums = source.allowEnums();
   5.137 -        this.allowForeach = source.allowForeach();
   5.138 -        this.allowStaticImport = source.allowStaticImport();
   5.139 -        this.allowAnnotations = source.allowAnnotations();
   5.140 -        this.keepDocComments = keepDocComments;
   5.141 -        if (keepDocComments) docComments = new HashMap<JCTree,String>();
   5.142 -        this.errorTree = F.Erroneous();
   5.143 -    }
   5.144 -
   5.145 -    /** Switch: Should generics be recognized?
   5.146 -     */
   5.147 -    boolean allowGenerics;
   5.148 -
   5.149 -    /** Switch: Should varargs be recognized?
   5.150 -     */
   5.151 -    boolean allowVarargs;
   5.152 -
   5.153 -    /** Switch: should we recognize assert statements, or just give a warning?
   5.154 -     */
   5.155 -    boolean allowAsserts;
   5.156 -
   5.157 -    /** Switch: should we recognize enums, or just give a warning?
   5.158 -     */
   5.159 -    boolean allowEnums;
   5.160 -
   5.161 -    /** Switch: should we recognize foreach?
   5.162 -     */
   5.163 -    boolean allowForeach;
   5.164 -
   5.165 -    /** Switch: should we recognize foreach?
   5.166 -     */
   5.167 -    boolean allowStaticImport;
   5.168 -
   5.169 -    /** Switch: should we recognize annotations?
   5.170 -     */
   5.171 -    boolean allowAnnotations;
   5.172 -
   5.173 -    /** Switch: should we keep docComments?
   5.174 -     */
   5.175 -    boolean keepDocComments;
   5.176 -
   5.177 -    /** When terms are parsed, the mode determines which is expected:
   5.178 -     *     mode = EXPR        : an expression
   5.179 -     *     mode = TYPE        : a type
   5.180 -     *     mode = NOPARAMS    : no parameters allowed for type
   5.181 -     *     mode = TYPEARG     : type argument
   5.182 -     */
   5.183 -    static final int EXPR = 1;
   5.184 -    static final int TYPE = 2;
   5.185 -    static final int NOPARAMS = 4;
   5.186 -    static final int TYPEARG = 8;
   5.187 -
   5.188 -    /** The current mode.
   5.189 -     */
   5.190 -    private int mode = 0;
   5.191 -
   5.192 -    /** The mode of the term that was parsed last.
   5.193 -     */
   5.194 -    private int lastmode = 0;
   5.195 -
   5.196 -/* ---------- error recovery -------------- */
   5.197 -
   5.198 -    private JCErroneous errorTree;
   5.199 -
   5.200 -    /** Skip forward until a suitable stop token is found.
   5.201 -     */
   5.202 -    private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   5.203 -         while (true) {
   5.204 -             switch (S.token()) {
   5.205 -                case SEMI:
   5.206 -                    S.nextToken();
   5.207 -                    return;
   5.208 -                case PUBLIC:
   5.209 -                case FINAL:
   5.210 -                case ABSTRACT:
   5.211 -                case MONKEYS_AT:
   5.212 -                case EOF:
   5.213 -                case CLASS:
   5.214 -                case INTERFACE:
   5.215 -                case ENUM:
   5.216 -                    return;
   5.217 -                case IMPORT:
   5.218 -                    if (stopAtImport)
   5.219 -                        return;
   5.220 -                    break;
   5.221 -                case LBRACE:
   5.222 -                case RBRACE:
   5.223 -                case PRIVATE:
   5.224 -                case PROTECTED:
   5.225 -                case STATIC:
   5.226 -                case TRANSIENT:
   5.227 -                case NATIVE:
   5.228 -                case VOLATILE:
   5.229 -                case SYNCHRONIZED:
   5.230 -                case STRICTFP:
   5.231 -                case LT:
   5.232 -                case BYTE:
   5.233 -                case SHORT:
   5.234 -                case CHAR:
   5.235 -                case INT:
   5.236 -                case LONG:
   5.237 -                case FLOAT:
   5.238 -                case DOUBLE:
   5.239 -                case BOOLEAN:
   5.240 -                case VOID:
   5.241 -                    if (stopAtMemberDecl)
   5.242 -                        return;
   5.243 -                    break;
   5.244 -                case IDENTIFIER:
   5.245 -                   if (stopAtIdentifier)
   5.246 -                        return;
   5.247 -                    break;
   5.248 -                case CASE:
   5.249 -                case DEFAULT:
   5.250 -                case IF:
   5.251 -                case FOR:
   5.252 -                case WHILE:
   5.253 -                case DO:
   5.254 -                case TRY:
   5.255 -                case SWITCH:
   5.256 -                case RETURN:
   5.257 -                case THROW:
   5.258 -                case BREAK:
   5.259 -                case CONTINUE:
   5.260 -                case ELSE:
   5.261 -                case FINALLY:
   5.262 -                case CATCH:
   5.263 -                    if (stopAtStatement)
   5.264 -                        return;
   5.265 -                    break;
   5.266 -            }
   5.267 -            S.nextToken();
   5.268 -        }
   5.269 -    }
   5.270 -
   5.271 -    private JCErroneous syntaxError(int pos, String key, Token... args) {
   5.272 -        return syntaxError(pos, null, key, args);
   5.273 -    }
   5.274 -
   5.275 -    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
   5.276 -        setErrorEndPos(pos);
   5.277 -        reportSyntaxError(pos, key, (Object[])args);
   5.278 -        return toP(F.at(pos).Erroneous(errs));
   5.279 -    }
   5.280 -
   5.281 -    private int errorPos = Position.NOPOS;
   5.282 -    /**
   5.283 -     * Report a syntax error at given position using the given
   5.284 -     * argument unless one was already reported at the same position.
   5.285 -     */
   5.286 -    private void reportSyntaxError(int pos, String key, Object... args) {
   5.287 -        if (pos > S.errPos() || pos == Position.NOPOS) {
   5.288 -            if (S.token() == EOF)
   5.289 -                log.error(pos, "premature.eof");
   5.290 -            else
   5.291 -                log.error(pos, key, args);
   5.292 -        }
   5.293 -        S.errPos(pos);
   5.294 -        if (S.pos() == errorPos)
   5.295 -            S.nextToken(); // guarantee progress
   5.296 -        errorPos = S.pos();
   5.297 -    }
   5.298 -
   5.299 -
   5.300 -    /** Generate a syntax error at current position unless one was already
   5.301 -     *  reported at the same position.
   5.302 -     */
   5.303 -    private JCErroneous syntaxError(String key) {
   5.304 -        return syntaxError(S.pos(), key);
   5.305 -    }
   5.306 -
   5.307 -    /** Generate a syntax error at current position unless one was
   5.308 -     *  already reported at the same position.
   5.309 -     */
   5.310 -    private JCErroneous syntaxError(String key, Token arg) {
   5.311 -        return syntaxError(S.pos(), key, arg);
   5.312 -    }
   5.313 -
   5.314 -    /** If next input token matches given token, skip it, otherwise report
   5.315 -     *  an error.
   5.316 -     */
   5.317 -    public void accept(Token token) {
   5.318 -        if (S.token() == token) {
   5.319 -            S.nextToken();
   5.320 -        } else {
   5.321 -            setErrorEndPos(S.pos());
   5.322 -            reportSyntaxError(S.prevEndPos(), "expected", token);
   5.323 -        }
   5.324 -    }
   5.325 -
   5.326 -    /** Report an illegal start of expression/type error at given position.
   5.327 -     */
   5.328 -    JCExpression illegal(int pos) {
   5.329 -        setErrorEndPos(S.pos());
   5.330 -        if ((mode & EXPR) != 0)
   5.331 -            return syntaxError(pos, "illegal.start.of.expr");
   5.332 -        else
   5.333 -            return syntaxError(pos, "illegal.start.of.type");
   5.334 -
   5.335 -    }
   5.336 -
   5.337 -    /** Report an illegal start of expression/type error at current position.
   5.338 -     */
   5.339 -    JCExpression illegal() {
   5.340 -        return illegal(S.pos());
   5.341 -    }
   5.342 -
   5.343 -    /** Diagnose a modifier flag from the set, if any. */
   5.344 -    void checkNoMods(long mods) {
   5.345 -        if (mods != 0) {
   5.346 -            long lowestMod = mods & -mods;
   5.347 -            log.error(S.pos(), "mod.not.allowed.here",
   5.348 -                      Flags.asFlagSet(lowestMod));
   5.349 -        }
   5.350 -    }
   5.351 -
   5.352 -/* ---------- doc comments --------- */
   5.353 -
   5.354 -    /** A hashtable to store all documentation comments
   5.355 -     *  indexed by the tree nodes they refer to.
   5.356 -     *  defined only if option flag keepDocComment is set.
   5.357 -     */
   5.358 -    Map<JCTree, String> docComments;
   5.359 -
   5.360 -    /** Make an entry into docComments hashtable,
   5.361 -     *  provided flag keepDocComments is set and given doc comment is non-null.
   5.362 -     *  @param tree   The tree to be used as index in the hashtable
   5.363 -     *  @param dc     The doc comment to associate with the tree, or null.
   5.364 -     */
   5.365 -    void attach(JCTree tree, String dc) {
   5.366 -        if (keepDocComments && dc != null) {
   5.367 -//          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   5.368 -            docComments.put(tree, dc);
   5.369 -        }
   5.370 -    }
   5.371 -
   5.372 -/* -------- source positions ------- */
   5.373 -
   5.374 -    private int errorEndPos = -1;
   5.375 -
   5.376 -    private void setErrorEndPos(int errPos) {
   5.377 -        if (errPos > errorEndPos)
   5.378 -            errorEndPos = errPos;
   5.379 -    }
   5.380 -
   5.381 -    protected int getErrorEndPos() {
   5.382 -        return errorEndPos;
   5.383 -    }
   5.384 +    JCCompilationUnit parseCompilationUnit();
   5.385  
   5.386      /**
   5.387 -     * Store ending position for a tree.
   5.388 -     * @param tree   The tree.
   5.389 -     * @param endpos The ending position to associate with the tree.
   5.390 +     * Parse an expression.
   5.391 +     * @return an expression
   5.392       */
   5.393 -    protected void storeEnd(JCTree tree, int endpos) {}
   5.394 +    JCExpression parseExpression();
   5.395  
   5.396      /**
   5.397 -     * Store ending position for a tree.  The ending position should
   5.398 -     * be the ending position of the current token.
   5.399 -     * @param t The tree.
   5.400 +     * Parse a statement.
   5.401 +     * @return an expression
   5.402       */
   5.403 -    protected <T extends JCTree> T to(T t) { return t; }
   5.404 +    JCStatement parseStatement();
   5.405  
   5.406      /**
   5.407 -     * Store ending position for a tree.  The ending position should
   5.408 -     * be greater of the ending position of the previous token and errorEndPos.
   5.409 -     * @param t The tree.
   5.410 +     * Parse a type.
   5.411 +     * @return an expression for a type
   5.412       */
   5.413 -    protected <T extends JCTree> T toP(T t) { return t; }
   5.414 -
   5.415 -    /** Get the start position for a tree node.  The start position is
   5.416 -     * defined to be the position of the first character of the first
   5.417 -     * token of the node's source text.
   5.418 -     * @param tree  The tree node
   5.419 -     */
   5.420 -    public int getStartPos(JCTree tree) {
   5.421 -        return TreeInfo.getStartPos(tree);
   5.422 -    }
   5.423 -
   5.424 -    /**
   5.425 -     * Get the end position for a tree node.  The end position is
   5.426 -     * defined to be the position of the last character of the last
   5.427 -     * token of the node's source text.  Returns Position.NOPOS if end
   5.428 -     * positions are not generated or the position is otherwise not
   5.429 -     * found.
   5.430 -     * @param tree  The tree node
   5.431 -     */
   5.432 -    public int getEndPos(JCTree tree) {
   5.433 -        return Position.NOPOS;
   5.434 -    }
   5.435 -
   5.436 -
   5.437 -
   5.438 -/* ---------- parsing -------------- */
   5.439 -
   5.440 -    /**
   5.441 -     * Ident = IDENTIFIER
   5.442 -     */
   5.443 -    Name ident() {
   5.444 -        if (S.token() == IDENTIFIER) {
   5.445 -            Name name = S.name();
   5.446 -            S.nextToken();
   5.447 -            return name;
   5.448 -        } else if (S.token() == ASSERT) {
   5.449 -            if (allowAsserts) {
   5.450 -                log.error(S.pos(), "assert.as.identifier");
   5.451 -                S.nextToken();
   5.452 -                return names.error;
   5.453 -            } else {
   5.454 -                log.warning(S.pos(), "assert.as.identifier");
   5.455 -                Name name = S.name();
   5.456 -                S.nextToken();
   5.457 -                return name;
   5.458 -            }
   5.459 -        } else if (S.token() == ENUM) {
   5.460 -            if (allowEnums) {
   5.461 -                log.error(S.pos(), "enum.as.identifier");
   5.462 -                S.nextToken();
   5.463 -                return names.error;
   5.464 -            } else {
   5.465 -                log.warning(S.pos(), "enum.as.identifier");
   5.466 -                Name name = S.name();
   5.467 -                S.nextToken();
   5.468 -                return name;
   5.469 -            }
   5.470 -        } else {
   5.471 -            accept(IDENTIFIER);
   5.472 -            return names.error;
   5.473 -        }
   5.474 +    JCExpression parseType();
   5.475  }
   5.476 -
   5.477 -    /**
   5.478 -     * Qualident = Ident { DOT Ident }
   5.479 -     */
   5.480 -    public JCExpression qualident() {
   5.481 -        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
   5.482 -        while (S.token() == DOT) {
   5.483 -            int pos = S.pos();
   5.484 -            S.nextToken();
   5.485 -            t = toP(F.at(pos).Select(t, ident()));
   5.486 -        }
   5.487 -        return t;
   5.488 -    }
   5.489 -
   5.490 -    /**
   5.491 -     * Literal =
   5.492 -     *     INTLITERAL
   5.493 -     *   | LONGLITERAL
   5.494 -     *   | FLOATLITERAL
   5.495 -     *   | DOUBLELITERAL
   5.496 -     *   | CHARLITERAL
   5.497 -     *   | STRINGLITERAL
   5.498 -     *   | TRUE
   5.499 -     *   | FALSE
   5.500 -     *   | NULL
   5.501 -     */
   5.502 -    JCExpression literal(Name prefix) {
   5.503 -        int pos = S.pos();
   5.504 -        JCExpression t = errorTree;
   5.505 -        switch (S.token()) {
   5.506 -        case INTLITERAL:
   5.507 -            try {
   5.508 -                t = F.at(pos).Literal(
   5.509 -                    TypeTags.INT,
   5.510 -                    Convert.string2int(strval(prefix), S.radix()));
   5.511 -            } catch (NumberFormatException ex) {
   5.512 -                log.error(S.pos(), "int.number.too.large", strval(prefix));
   5.513 -            }
   5.514 -            break;
   5.515 -        case LONGLITERAL:
   5.516 -            try {
   5.517 -                t = F.at(pos).Literal(
   5.518 -                    TypeTags.LONG,
   5.519 -                    new Long(Convert.string2long(strval(prefix), S.radix())));
   5.520 -            } catch (NumberFormatException ex) {
   5.521 -                log.error(S.pos(), "int.number.too.large", strval(prefix));
   5.522 -            }
   5.523 -            break;
   5.524 -        case FLOATLITERAL: {
   5.525 -            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   5.526 -            Float n;
   5.527 -            try {
   5.528 -                n = Float.valueOf(proper);
   5.529 -            } catch (NumberFormatException ex) {
   5.530 -                // error already repoted in scanner
   5.531 -                n = Float.NaN;
   5.532 -            }
   5.533 -            if (n.floatValue() == 0.0f && !isZero(proper))
   5.534 -                log.error(S.pos(), "fp.number.too.small");
   5.535 -            else if (n.floatValue() == Float.POSITIVE_INFINITY)
   5.536 -                log.error(S.pos(), "fp.number.too.large");
   5.537 -            else
   5.538 -                t = F.at(pos).Literal(TypeTags.FLOAT, n);
   5.539 -            break;
   5.540 -        }
   5.541 -        case DOUBLELITERAL: {
   5.542 -            String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
   5.543 -            Double n;
   5.544 -            try {
   5.545 -                n = Double.valueOf(proper);
   5.546 -            } catch (NumberFormatException ex) {
   5.547 -                // error already reported in scanner
   5.548 -                n = Double.NaN;
   5.549 -            }
   5.550 -            if (n.doubleValue() == 0.0d && !isZero(proper))
   5.551 -                log.error(S.pos(), "fp.number.too.small");
   5.552 -            else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   5.553 -                log.error(S.pos(), "fp.number.too.large");
   5.554 -            else
   5.555 -                t = F.at(pos).Literal(TypeTags.DOUBLE, n);
   5.556 -            break;
   5.557 -        }
   5.558 -        case CHARLITERAL:
   5.559 -            t = F.at(pos).Literal(
   5.560 -                TypeTags.CHAR,
   5.561 -                S.stringVal().charAt(0) + 0);
   5.562 -            break;
   5.563 -        case STRINGLITERAL:
   5.564 -            t = F.at(pos).Literal(
   5.565 -                TypeTags.CLASS,
   5.566 -                S.stringVal());
   5.567 -            break;
   5.568 -        case TRUE: case FALSE:
   5.569 -            t = F.at(pos).Literal(
   5.570 -                TypeTags.BOOLEAN,
   5.571 -                (S.token() == TRUE ? 1 : 0));
   5.572 -            break;
   5.573 -        case NULL:
   5.574 -            t = F.at(pos).Literal(
   5.575 -                TypeTags.BOT,
   5.576 -                null);
   5.577 -            break;
   5.578 -        default:
   5.579 -            assert false;
   5.580 -        }
   5.581 -        if (t == errorTree)
   5.582 -            t = F.at(pos).Erroneous();
   5.583 -        storeEnd(t, S.endPos());
   5.584 -        S.nextToken();
   5.585 -        return t;
   5.586 -    }
   5.587 -//where
   5.588 -        boolean isZero(String s) {
   5.589 -            char[] cs = s.toCharArray();
   5.590 -            int base = ((Character.toLowerCase(s.charAt(1)) == 'x') ? 16 : 10);
   5.591 -            int i = ((base==16) ? 2 : 0);
   5.592 -            while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   5.593 -            return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   5.594 -        }
   5.595 -
   5.596 -        String strval(Name prefix) {
   5.597 -            String s = S.stringVal();
   5.598 -            return (prefix.len == 0) ? s : prefix + s;
   5.599 -        }
   5.600 -
   5.601 -    /** terms can be either expressions or types.
   5.602 -     */
   5.603 -    public JCExpression expression() {
   5.604 -        return term(EXPR);
   5.605 -    }
   5.606 -
   5.607 -    public JCExpression type() {
   5.608 -        return term(TYPE);
   5.609 -    }
   5.610 -
   5.611 -    JCExpression term(int newmode) {
   5.612 -        int prevmode = mode;
   5.613 -        mode = newmode;
   5.614 -        JCExpression t = term();
   5.615 -        lastmode = mode;
   5.616 -        mode = prevmode;
   5.617 -        return t;
   5.618 -    }
   5.619 -
   5.620 -    /**
   5.621 -     *  Expression = Expression1 [ExpressionRest]
   5.622 -     *  ExpressionRest = [AssignmentOperator Expression1]
   5.623 -     *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   5.624 -     *                       "&=" | "|=" | "^=" |
   5.625 -     *                       "%=" | "<<=" | ">>=" | ">>>="
   5.626 -     *  Type = Type1
   5.627 -     *  TypeNoParams = TypeNoParams1
   5.628 -     *  StatementExpression = Expression
   5.629 -     *  ConstantExpression = Expression
   5.630 -     */
   5.631 -    JCExpression term() {
   5.632 -        JCExpression t = term1();
   5.633 -        if ((mode & EXPR) != 0 &&
   5.634 -            S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
   5.635 -            return termRest(t);
   5.636 -        else
   5.637 -            return t;
   5.638 -    }
   5.639 -
   5.640 -    JCExpression termRest(JCExpression t) {
   5.641 -        switch (S.token()) {
   5.642 -        case EQ: {
   5.643 -            int pos = S.pos();
   5.644 -            S.nextToken();
   5.645 -            mode = EXPR;
   5.646 -            JCExpression t1 = term();
   5.647 -            return toP(F.at(pos).Assign(t, t1));
   5.648 -        }
   5.649 -        case PLUSEQ:
   5.650 -        case SUBEQ:
   5.651 -        case STAREQ:
   5.652 -        case SLASHEQ:
   5.653 -        case PERCENTEQ:
   5.654 -        case AMPEQ:
   5.655 -        case BAREQ:
   5.656 -        case CARETEQ:
   5.657 -        case LTLTEQ:
   5.658 -        case GTGTEQ:
   5.659 -        case GTGTGTEQ:
   5.660 -            int pos = S.pos();
   5.661 -            Token token = S.token();
   5.662 -            S.nextToken();
   5.663 -            mode = EXPR;
   5.664 -            JCExpression t1 = term();
   5.665 -            return F.at(pos).Assignop(optag(token), t, t1);
   5.666 -        default:
   5.667 -            return t;
   5.668 -        }
   5.669 -    }
   5.670 -
   5.671 -    /** Expression1   = Expression2 [Expression1Rest]
   5.672 -     *  Type1         = Type2
   5.673 -     *  TypeNoParams1 = TypeNoParams2
   5.674 -     */
   5.675 -    JCExpression term1() {
   5.676 -        JCExpression t = term2();
   5.677 -        if ((mode & EXPR) != 0 && S.token() == QUES) {
   5.678 -            mode = EXPR;
   5.679 -            return term1Rest(t);
   5.680 -        } else {
   5.681 -            return t;
   5.682 -        }
   5.683 -    }
   5.684 -
   5.685 -    /** Expression1Rest = ["?" Expression ":" Expression1]
   5.686 -     */
   5.687 -    JCExpression term1Rest(JCExpression t) {
   5.688 -        if (S.token() == QUES) {
   5.689 -            int pos = S.pos();
   5.690 -            S.nextToken();
   5.691 -            JCExpression t1 = term();
   5.692 -            accept(COLON);
   5.693 -            JCExpression t2 = term1();
   5.694 -            return F.at(pos).Conditional(t, t1, t2);
   5.695 -        } else {
   5.696 -            return t;
   5.697 -        }
   5.698 -    }
   5.699 -
   5.700 -    /** Expression2   = Expression3 [Expression2Rest]
   5.701 -     *  Type2         = Type3
   5.702 -     *  TypeNoParams2 = TypeNoParams3
   5.703 -     */
   5.704 -    JCExpression term2() {
   5.705 -        JCExpression t = term3();
   5.706 -        if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
   5.707 -            mode = EXPR;
   5.708 -            return term2Rest(t, TreeInfo.orPrec);
   5.709 -        } else {
   5.710 -            return t;
   5.711 -        }
   5.712 -    }
   5.713 -
   5.714 -    /*  Expression2Rest = {infixop Expression3}
   5.715 -     *                  | Expression3 instanceof Type
   5.716 -     *  infixop         = "||"
   5.717 -     *                  | "&&"
   5.718 -     *                  | "|"
   5.719 -     *                  | "^"
   5.720 -     *                  | "&"
   5.721 -     *                  | "==" | "!="
   5.722 -     *                  | "<" | ">" | "<=" | ">="
   5.723 -     *                  | "<<" | ">>" | ">>>"
   5.724 -     *                  | "+" | "-"
   5.725 -     *                  | "*" | "/" | "%"
   5.726 -     */
   5.727 -    JCExpression term2Rest(JCExpression t, int minprec) {
   5.728 -        List<JCExpression[]> savedOd = odStackSupply.elems;
   5.729 -        JCExpression[] odStack = newOdStack();
   5.730 -        List<Token[]> savedOp = opStackSupply.elems;
   5.731 -        Token[] opStack = newOpStack();
   5.732 -        // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   5.733 -        int top = 0;
   5.734 -        odStack[0] = t;
   5.735 -        int startPos = S.pos();
   5.736 -        Token topOp = ERROR;
   5.737 -        while (prec(S.token()) >= minprec) {
   5.738 -            opStack[top] = topOp;
   5.739 -            top++;
   5.740 -            topOp = S.token();
   5.741 -            int pos = S.pos();
   5.742 -            S.nextToken();
   5.743 -            odStack[top] = topOp == INSTANCEOF ? type() : term3();
   5.744 -            while (top > 0 && prec(topOp) >= prec(S.token())) {
   5.745 -                odStack[top-1] = makeOp(pos, topOp, odStack[top-1],
   5.746 -                                        odStack[top]);
   5.747 -                top--;
   5.748 -                topOp = opStack[top];
   5.749 -            }
   5.750 -        }
   5.751 -        assert top == 0;
   5.752 -        t = odStack[0];
   5.753 -
   5.754 -        if (t.getTag() == JCTree.PLUS) {
   5.755 -            StringBuffer buf = foldStrings(t);
   5.756 -            if (buf != null) {
   5.757 -                t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
   5.758 -            }
   5.759 -        }
   5.760 -
   5.761 -        odStackSupply.elems = savedOd; // optimization
   5.762 -        opStackSupply.elems = savedOp; // optimization
   5.763 -        return t;
   5.764 -    }
   5.765 -//where
   5.766 -        /** Construct a binary or type test node.
   5.767 -         */
   5.768 -        private JCExpression makeOp(int pos,
   5.769 -                                    Token topOp,
   5.770 -                                    JCExpression od1,
   5.771 -                                    JCExpression od2)
   5.772 -        {
   5.773 -            if (topOp == INSTANCEOF) {
   5.774 -                return F.at(pos).TypeTest(od1, od2);
   5.775 -            } else {
   5.776 -                return F.at(pos).Binary(optag(topOp), od1, od2);
   5.777 -            }
   5.778 -        }
   5.779 -        /** If tree is a concatenation of string literals, replace it
   5.780 -         *  by a single literal representing the concatenated string.
   5.781 -         */
   5.782 -        protected StringBuffer foldStrings(JCTree tree) {
   5.783 -            List<String> buf = List.nil();
   5.784 -            while (true) {
   5.785 -                if (tree.getTag() == JCTree.LITERAL) {
   5.786 -                    JCLiteral lit = (JCLiteral) tree;
   5.787 -                    if (lit.typetag == TypeTags.CLASS) {
   5.788 -                        StringBuffer sbuf =
   5.789 -                            new StringBuffer((String)lit.value);
   5.790 -                        while (buf.nonEmpty()) {
   5.791 -                            sbuf.append(buf.head);
   5.792 -                            buf = buf.tail;
   5.793 -                        }
   5.794 -                        return sbuf;
   5.795 -                    }
   5.796 -                } else if (tree.getTag() == JCTree.PLUS) {
   5.797 -                    JCBinary op = (JCBinary)tree;
   5.798 -                    if (op.rhs.getTag() == JCTree.LITERAL) {
   5.799 -                        JCLiteral lit = (JCLiteral) op.rhs;
   5.800 -                        if (lit.typetag == TypeTags.CLASS) {
   5.801 -                            buf = buf.prepend((String) lit.value);
   5.802 -                            tree = op.lhs;
   5.803 -                            continue;
   5.804 -                        }
   5.805 -                    }
   5.806 -                }
   5.807 -                return null;
   5.808 -            }
   5.809 -        }
   5.810 -
   5.811 -        /** optimization: To save allocating a new operand/operator stack
   5.812 -         *  for every binary operation, we use supplys.
   5.813 -         */
   5.814 -        ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
   5.815 -        ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
   5.816 -
   5.817 -        private JCExpression[] newOdStack() {
   5.818 -            if (odStackSupply.elems == odStackSupply.last)
   5.819 -                odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
   5.820 -            JCExpression[] odStack = odStackSupply.elems.head;
   5.821 -            odStackSupply.elems = odStackSupply.elems.tail;
   5.822 -            return odStack;
   5.823 -        }
   5.824 -
   5.825 -        private Token[] newOpStack() {
   5.826 -            if (opStackSupply.elems == opStackSupply.last)
   5.827 -                opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
   5.828 -            Token[] opStack = opStackSupply.elems.head;
   5.829 -            opStackSupply.elems = opStackSupply.elems.tail;
   5.830 -            return opStack;
   5.831 -        }
   5.832 -
   5.833 -    /** Expression3    = PrefixOp Expression3
   5.834 -     *                 | "(" Expr | TypeNoParams ")" Expression3
   5.835 -     *                 | Primary {Selector} {PostfixOp}
   5.836 -     *  Primary        = "(" Expression ")"
   5.837 -     *                 | Literal
   5.838 -     *                 | [TypeArguments] THIS [Arguments]
   5.839 -     *                 | [TypeArguments] SUPER SuperSuffix
   5.840 -     *                 | NEW [TypeArguments] Creator
   5.841 -     *                 | Ident { "." Ident }
   5.842 -     *                   [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   5.843 -     *                   | Arguments
   5.844 -     *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
   5.845 -     *                   ]
   5.846 -     *                 | BasicType BracketsOpt "." CLASS
   5.847 -     *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
   5.848 -     *  PostfixOp      = "++" | "--"
   5.849 -     *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
   5.850 -     *                 | BasicType
   5.851 -     *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
   5.852 -     *  Selector       = "." [TypeArguments] Ident [Arguments]
   5.853 -     *                 | "." THIS
   5.854 -     *                 | "." [TypeArguments] SUPER SuperSuffix
   5.855 -     *                 | "." NEW [TypeArguments] InnerCreator
   5.856 -     *                 | "[" Expression "]"
   5.857 -     *  TypeSelector   = "." Ident [TypeArguments]
   5.858 -     *  SuperSuffix    = Arguments | "." Ident [Arguments]
   5.859 -     */
   5.860 -    protected JCExpression term3() {
   5.861 -        int pos = S.pos();
   5.862 -        JCExpression t;
   5.863 -        List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
   5.864 -        switch (S.token()) {
   5.865 -        case QUES:
   5.866 -            if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
   5.867 -                mode = TYPE;
   5.868 -                return typeArgument();
   5.869 -            } else
   5.870 -                return illegal();
   5.871 -        case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
   5.872 -            if (typeArgs == null && (mode & EXPR) != 0) {
   5.873 -                Token token = S.token();
   5.874 -                S.nextToken();
   5.875 -                mode = EXPR;
   5.876 -                if (token == SUB &&
   5.877 -                    (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
   5.878 -                    S.radix() == 10) {
   5.879 -                    mode = EXPR;
   5.880 -                    t = literal(names.hyphen);
   5.881 -                } else {
   5.882 -                    t = term3();
   5.883 -                    return F.at(pos).Unary(unoptag(token), t);
   5.884 -                }
   5.885 -            } else return illegal();
   5.886 -            break;
   5.887 -        case LPAREN:
   5.888 -            if (typeArgs == null && (mode & EXPR) != 0) {
   5.889 -                S.nextToken();
   5.890 -                mode = EXPR | TYPE | NOPARAMS;
   5.891 -                t = term3();
   5.892 -                if ((mode & TYPE) != 0 && S.token() == LT) {
   5.893 -                    // Could be a cast to a parameterized type
   5.894 -                    int op = JCTree.LT;
   5.895 -                    int pos1 = S.pos();
   5.896 -                    S.nextToken();
   5.897 -                    mode &= (EXPR | TYPE);
   5.898 -                    mode |= TYPEARG;
   5.899 -                    JCExpression t1 = term3();
   5.900 -                    if ((mode & TYPE) != 0 &&
   5.901 -                        (S.token() == COMMA || S.token() == GT)) {
   5.902 -                        mode = TYPE;
   5.903 -                        ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
   5.904 -                        args.append(t1);
   5.905 -                        while (S.token() == COMMA) {
   5.906 -                            S.nextToken();
   5.907 -                            args.append(typeArgument());
   5.908 -                        }
   5.909 -                        accept(GT);
   5.910 -                        t = F.at(pos1).TypeApply(t, args.toList());
   5.911 -                        checkGenerics();
   5.912 -                        t = bracketsOpt(toP(t));
   5.913 -                    } else if ((mode & EXPR) != 0) {
   5.914 -                        mode = EXPR;
   5.915 -                        t = F.at(pos1).Binary(op, t, term2Rest(t1, TreeInfo.shiftPrec));
   5.916 -                        t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   5.917 -                    } else {
   5.918 -                        accept(GT);
   5.919 -                    }
   5.920 -                } else {
   5.921 -                    t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
   5.922 -                }
   5.923 -                accept(RPAREN);
   5.924 -                lastmode = mode;
   5.925 -                mode = EXPR;
   5.926 -                if ((lastmode & EXPR) == 0) {
   5.927 -                    JCExpression t1 = term3();
   5.928 -                    return F.at(pos).TypeCast(t, t1);
   5.929 -                } else if ((lastmode & TYPE) != 0) {
   5.930 -                    switch (S.token()) {
   5.931 -                    /*case PLUSPLUS: case SUBSUB: */
   5.932 -                    case BANG: case TILDE:
   5.933 -                    case LPAREN: case THIS: case SUPER:
   5.934 -                    case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
   5.935 -                    case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
   5.936 -                    case TRUE: case FALSE: case NULL:
   5.937 -                    case NEW: case IDENTIFIER: case ASSERT: case ENUM:
   5.938 -                    case BYTE: case SHORT: case CHAR: case INT:
   5.939 -                    case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
   5.940 -                        JCExpression t1 = term3();
   5.941 -                        return F.at(pos).TypeCast(t, t1);
   5.942 -                    }
   5.943 -                }
   5.944 -            } else return illegal();
   5.945 -            t = toP(F.at(pos).Parens(t));
   5.946 -            break;
   5.947 -        case THIS:
   5.948 -            if ((mode & EXPR) != 0) {
   5.949 -                mode = EXPR;
   5.950 -                t = to(F.at(pos).Ident(names._this));
   5.951 -                S.nextToken();
   5.952 -                if (typeArgs == null)
   5.953 -                    t = argumentsOpt(null, t);
   5.954 -                else
   5.955 -                    t = arguments(typeArgs, t);
   5.956 -                typeArgs = null;
   5.957 -            } else return illegal();
   5.958 -            break;
   5.959 -        case SUPER:
   5.960 -            if ((mode & EXPR) != 0) {
   5.961 -                mode = EXPR;
   5.962 -                t = to(superSuffix(typeArgs, F.at(pos).Ident(names._super)));
   5.963 -                typeArgs = null;
   5.964 -            } else return illegal();
   5.965 -            break;
   5.966 -        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
   5.967 -        case CHARLITERAL: case STRINGLITERAL:
   5.968 -        case TRUE: case FALSE: case NULL:
   5.969 -            if (typeArgs == null && (mode & EXPR) != 0) {
   5.970 -                mode = EXPR;
   5.971 -                t = literal(names.empty);
   5.972 -            } else return illegal();
   5.973 -            break;
   5.974 -        case NEW:
   5.975 -            if (typeArgs != null) return illegal();
   5.976 -            if ((mode & EXPR) != 0) {
   5.977 -                mode = EXPR;
   5.978 -                S.nextToken();
   5.979 -                if (S.token() == LT) typeArgs = typeArguments();
   5.980 -                t = creator(pos, typeArgs);
   5.981 -                typeArgs = null;
   5.982 -            } else return illegal();
   5.983 -            break;
   5.984 -        case IDENTIFIER: case ASSERT: case ENUM:
   5.985 -            if (typeArgs != null) return illegal();
   5.986 -            t = toP(F.at(S.pos()).Ident(ident()));
   5.987 -            loop: while (true) {
   5.988 -                pos = S.pos();
   5.989 -                switch (S.token()) {
   5.990 -                case LBRACKET:
   5.991 -                    S.nextToken();
   5.992 -                    if (S.token() == RBRACKET) {
   5.993 -                        S.nextToken();
   5.994 -                        t = bracketsOpt(t);
   5.995 -                        t = toP(F.at(pos).TypeArray(t));
   5.996 -                        t = bracketsSuffix(t);
   5.997 -                    } else {
   5.998 -                        if ((mode & EXPR) != 0) {
   5.999 -                            mode = EXPR;
  5.1000 -                            JCExpression t1 = term();
  5.1001 -                            t = to(F.at(pos).Indexed(t, t1));
  5.1002 -                        }
  5.1003 -                        accept(RBRACKET);
  5.1004 -                    }
  5.1005 -                    break loop;
  5.1006 -                case LPAREN:
  5.1007 -                    if ((mode & EXPR) != 0) {
  5.1008 -                        mode = EXPR;
  5.1009 -                        t = arguments(typeArgs, t);
  5.1010 -                        typeArgs = null;
  5.1011 -                    }
  5.1012 -                    break loop;
  5.1013 -                case DOT:
  5.1014 -                    S.nextToken();
  5.1015 -                    int oldmode = mode;
  5.1016 -                    mode &= ~NOPARAMS;
  5.1017 -                    typeArgs = typeArgumentsOpt(EXPR);
  5.1018 -                    mode = oldmode;
  5.1019 -                    if ((mode & EXPR) != 0) {
  5.1020 -                        switch (S.token()) {
  5.1021 -                        case CLASS:
  5.1022 -                            if (typeArgs != null) return illegal();
  5.1023 -                            mode = EXPR;
  5.1024 -                            t = to(F.at(pos).Select(t, names._class));
  5.1025 -                            S.nextToken();
  5.1026 -                            break loop;
  5.1027 -                        case THIS:
  5.1028 -                            if (typeArgs != null) return illegal();
  5.1029 -                            mode = EXPR;
  5.1030 -                            t = to(F.at(pos).Select(t, names._this));
  5.1031 -                            S.nextToken();
  5.1032 -                            break loop;
  5.1033 -                        case SUPER:
  5.1034 -                            mode = EXPR;
  5.1035 -                            t = to(F.at(pos).Select(t, names._super));
  5.1036 -                            t = superSuffix(typeArgs, t);
  5.1037 -                            typeArgs = null;
  5.1038 -                            break loop;
  5.1039 -                        case NEW:
  5.1040 -                            if (typeArgs != null) return illegal();
  5.1041 -                            mode = EXPR;
  5.1042 -                            int pos1 = S.pos();
  5.1043 -                            S.nextToken();
  5.1044 -                            if (S.token() == LT) typeArgs = typeArguments();
  5.1045 -                            t = innerCreator(pos1, typeArgs, t);
  5.1046 -                            typeArgs = null;
  5.1047 -                            break loop;
  5.1048 -                        }
  5.1049 -                    }
  5.1050 -                    // typeArgs saved for next loop iteration.
  5.1051 -                    t = toP(F.at(pos).Select(t, ident()));
  5.1052 -                    break;
  5.1053 -                default:
  5.1054 -                    break loop;
  5.1055 -                }
  5.1056 -            }
  5.1057 -            if (typeArgs != null) illegal();
  5.1058 -            t = typeArgumentsOpt(t);
  5.1059 -            break;
  5.1060 -        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  5.1061 -        case DOUBLE: case BOOLEAN:
  5.1062 -            if (typeArgs != null) illegal();
  5.1063 -            t = bracketsSuffix(bracketsOpt(basicType()));
  5.1064 -            break;
  5.1065 -        case VOID:
  5.1066 -            if (typeArgs != null) illegal();
  5.1067 -            if ((mode & EXPR) != 0) {
  5.1068 -                S.nextToken();
  5.1069 -                if (S.token() == DOT) {
  5.1070 -                    JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
  5.1071 -                    t = bracketsSuffix(ti);
  5.1072 -                } else {
  5.1073 -                    return illegal(pos);
  5.1074 -                }
  5.1075 -            } else {
  5.1076 -                return illegal();
  5.1077 -            }
  5.1078 -            break;
  5.1079 -        default:
  5.1080 -            return illegal();
  5.1081 -        }
  5.1082 -        if (typeArgs != null) illegal();
  5.1083 -        while (true) {
  5.1084 -            int pos1 = S.pos();
  5.1085 -            if (S.token() == LBRACKET) {
  5.1086 -                S.nextToken();
  5.1087 -                if ((mode & TYPE) != 0) {
  5.1088 -                    int oldmode = mode;
  5.1089 -                    mode = TYPE;
  5.1090 -                    if (S.token() == RBRACKET) {
  5.1091 -                        S.nextToken();
  5.1092 -                        t = bracketsOpt(t);
  5.1093 -                        t = toP(F.at(pos1).TypeArray(t));
  5.1094 -                        return t;
  5.1095 -                    }
  5.1096 -                    mode = oldmode;
  5.1097 -                }
  5.1098 -                if ((mode & EXPR) != 0) {
  5.1099 -                    mode = EXPR;
  5.1100 -                    JCExpression t1 = term();
  5.1101 -                    t = to(F.at(pos1).Indexed(t, t1));
  5.1102 -                }
  5.1103 -                accept(RBRACKET);
  5.1104 -            } else if (S.token() == DOT) {
  5.1105 -                S.nextToken();
  5.1106 -                typeArgs = typeArgumentsOpt(EXPR);
  5.1107 -                if (S.token() == SUPER && (mode & EXPR) != 0) {
  5.1108 -                    mode = EXPR;
  5.1109 -                    t = to(F.at(pos1).Select(t, names._super));
  5.1110 -                    S.nextToken();
  5.1111 -                    t = arguments(typeArgs, t);
  5.1112 -                    typeArgs = null;
  5.1113 -                } else if (S.token() == NEW && (mode & EXPR) != 0) {
  5.1114 -                    if (typeArgs != null) return illegal();
  5.1115 -                    mode = EXPR;
  5.1116 -                    int pos2 = S.pos();
  5.1117 -                    S.nextToken();
  5.1118 -                    if (S.token() == LT) typeArgs = typeArguments();
  5.1119 -                    t = innerCreator(pos2, typeArgs, t);
  5.1120 -                    typeArgs = null;
  5.1121 -                } else {
  5.1122 -                    t = toP(F.at(pos1).Select(t, ident()));
  5.1123 -                    t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  5.1124 -                    typeArgs = null;
  5.1125 -                }
  5.1126 -            } else {
  5.1127 -                break;
  5.1128 -            }
  5.1129 -        }
  5.1130 -        while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
  5.1131 -            mode = EXPR;
  5.1132 -            t = to(F.at(S.pos()).Unary(
  5.1133 -                  S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
  5.1134 -            S.nextToken();
  5.1135 -        }
  5.1136 -        return toP(t);
  5.1137 -    }
  5.1138 -
  5.1139 -    /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  5.1140 -     */
  5.1141 -    JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  5.1142 -        S.nextToken();
  5.1143 -        if (S.token() == LPAREN || typeArgs != null) {
  5.1144 -            t = arguments(typeArgs, t);
  5.1145 -        } else {
  5.1146 -            int pos = S.pos();
  5.1147 -            accept(DOT);
  5.1148 -            typeArgs = (S.token() == LT) ? typeArguments() : null;
  5.1149 -            t = toP(F.at(pos).Select(t, ident()));
  5.1150 -            t = argumentsOpt(typeArgs, t);
  5.1151 -        }
  5.1152 -        return t;
  5.1153 -    }
  5.1154 -
  5.1155 -    /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  5.1156 -     */
  5.1157 -    JCPrimitiveTypeTree basicType() {
  5.1158 -        JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
  5.1159 -        S.nextToken();
  5.1160 -        return t;
  5.1161 -    }
  5.1162 -
  5.1163 -    /** ArgumentsOpt = [ Arguments ]
  5.1164 -     */
  5.1165 -    JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  5.1166 -        if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
  5.1167 -            mode = EXPR;
  5.1168 -            return arguments(typeArgs, t);
  5.1169 -        } else {
  5.1170 -            return t;
  5.1171 -        }
  5.1172 -    }
  5.1173 -
  5.1174 -    /** Arguments = "(" [Expression { COMMA Expression }] ")"
  5.1175 -     */
  5.1176 -    List<JCExpression> arguments() {
  5.1177 -        ListBuffer<JCExpression> args = lb();
  5.1178 -        if (S.token() == LPAREN) {
  5.1179 -            S.nextToken();
  5.1180 -            if (S.token() != RPAREN) {
  5.1181 -                args.append(expression());
  5.1182 -                while (S.token() == COMMA) {
  5.1183 -                    S.nextToken();
  5.1184 -                    args.append(expression());
  5.1185 -                }
  5.1186 -            }
  5.1187 -            accept(RPAREN);
  5.1188 -        } else {
  5.1189 -            syntaxError(S.pos(), "expected", LPAREN);
  5.1190 -        }
  5.1191 -        return args.toList();
  5.1192 -    }
  5.1193 -
  5.1194 -    JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  5.1195 -        int pos = S.pos();
  5.1196 -        List<JCExpression> args = arguments();
  5.1197 -        return toP(F.at(pos).Apply(typeArgs, t, args));
  5.1198 -    }
  5.1199 -
  5.1200 -    /**  TypeArgumentsOpt = [ TypeArguments ]
  5.1201 -     */
  5.1202 -    JCExpression typeArgumentsOpt(JCExpression t) {
  5.1203 -        if (S.token() == LT &&
  5.1204 -            (mode & TYPE) != 0 &&
  5.1205 -            (mode & NOPARAMS) == 0) {
  5.1206 -            mode = TYPE;
  5.1207 -            checkGenerics();
  5.1208 -            return typeArguments(t);
  5.1209 -        } else {
  5.1210 -            return t;
  5.1211 -        }
  5.1212 -    }
  5.1213 -    List<JCExpression> typeArgumentsOpt() {
  5.1214 -        return typeArgumentsOpt(TYPE);
  5.1215 -    }
  5.1216 -
  5.1217 -    List<JCExpression> typeArgumentsOpt(int useMode) {
  5.1218 -        if (S.token() == LT) {
  5.1219 -            checkGenerics();
  5.1220 -            if ((mode & useMode) == 0 ||
  5.1221 -                (mode & NOPARAMS) != 0) {
  5.1222 -                illegal();
  5.1223 -            }
  5.1224 -            mode = useMode;
  5.1225 -            return typeArguments();
  5.1226 -        }
  5.1227 -        return null;
  5.1228 -    }
  5.1229 -
  5.1230 -    /**  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  5.1231 -     */
  5.1232 -    List<JCExpression> typeArguments() {
  5.1233 -        ListBuffer<JCExpression> args = lb();
  5.1234 -        if (S.token() == LT) {
  5.1235 -            S.nextToken();
  5.1236 -            args.append(((mode & EXPR) == 0) ? typeArgument() : type());
  5.1237 -            while (S.token() == COMMA) {
  5.1238 -                S.nextToken();
  5.1239 -                args.append(((mode & EXPR) == 0) ? typeArgument() : type());
  5.1240 -            }
  5.1241 -            switch (S.token()) {
  5.1242 -            case GTGTGTEQ:
  5.1243 -                S.token(GTGTEQ);
  5.1244 -                break;
  5.1245 -            case GTGTEQ:
  5.1246 -                S.token(GTEQ);
  5.1247 -                break;
  5.1248 -            case GTEQ:
  5.1249 -                S.token(EQ);
  5.1250 -                break;
  5.1251 -            case GTGTGT:
  5.1252 -                S.token(GTGT);
  5.1253 -                break;
  5.1254 -            case GTGT:
  5.1255 -                S.token(GT);
  5.1256 -                break;
  5.1257 -            default:
  5.1258 -                accept(GT);
  5.1259 -                break;
  5.1260 -            }
  5.1261 -        } else {
  5.1262 -            syntaxError(S.pos(), "expected", LT);
  5.1263 -        }
  5.1264 -        return args.toList();
  5.1265 -    }
  5.1266 -
  5.1267 -    /** TypeArgument = Type
  5.1268 -     *               | "?"
  5.1269 -     *               | "?" EXTENDS Type {"&" Type}
  5.1270 -     *               | "?" SUPER Type
  5.1271 -     */
  5.1272 -    JCExpression typeArgument() {
  5.1273 -        if (S.token() != QUES) return type();
  5.1274 -        int pos = S.pos();
  5.1275 -        S.nextToken();
  5.1276 -        if (S.token() == EXTENDS) {
  5.1277 -            TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
  5.1278 -            S.nextToken();
  5.1279 -            return F.at(pos).Wildcard(t, type());
  5.1280 -        } else if (S.token() == SUPER) {
  5.1281 -            TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
  5.1282 -            S.nextToken();
  5.1283 -            return F.at(pos).Wildcard(t, type());
  5.1284 -        } else if (S.token() == IDENTIFIER) {
  5.1285 -            //error recovery
  5.1286 -            reportSyntaxError(S.prevEndPos(), "expected3",
  5.1287 -                    GT, EXTENDS, SUPER);
  5.1288 -            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  5.1289 -            JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  5.1290 -            JCIdent id = toP(F.at(S.pos()).Ident(ident()));
  5.1291 -            return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  5.1292 -        } else {
  5.1293 -            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  5.1294 -            return toP(F.at(pos).Wildcard(t, null));
  5.1295 -        }
  5.1296 -    }
  5.1297 -
  5.1298 -    JCTypeApply typeArguments(JCExpression t) {
  5.1299 -        int pos = S.pos();
  5.1300 -        List<JCExpression> args = typeArguments();
  5.1301 -        return toP(F.at(pos).TypeApply(t, args));
  5.1302 -    }
  5.1303 -
  5.1304 -    /** BracketsOpt = {"[" "]"}
  5.1305 -     */
  5.1306 -    private JCExpression bracketsOpt(JCExpression t) {
  5.1307 -        if (S.token() == LBRACKET) {
  5.1308 -            int pos = S.pos();
  5.1309 -            S.nextToken();
  5.1310 -            t = bracketsOptCont(t, pos);
  5.1311 -            F.at(pos);
  5.1312 -        }
  5.1313 -        return t;
  5.1314 -    }
  5.1315 -
  5.1316 -    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
  5.1317 -        accept(RBRACKET);
  5.1318 -        t = bracketsOpt(t);
  5.1319 -        return toP(F.at(pos).TypeArray(t));
  5.1320 -    }
  5.1321 -
  5.1322 -    /** BracketsSuffixExpr = "." CLASS
  5.1323 -     *  BracketsSuffixType =
  5.1324 -     */
  5.1325 -    JCExpression bracketsSuffix(JCExpression t) {
  5.1326 -        if ((mode & EXPR) != 0 && S.token() == DOT) {
  5.1327 -            mode = EXPR;
  5.1328 -            int pos = S.pos();
  5.1329 -            S.nextToken();
  5.1330 -            accept(CLASS);
  5.1331 -            if (S.pos() == errorEndPos) {
  5.1332 -                // error recovery
  5.1333 -                Name name = null;
  5.1334 -                if (S.token() == IDENTIFIER) {
  5.1335 -                    name = S.name();
  5.1336 -                    S.nextToken();
  5.1337 -                } else {
  5.1338 -                    name = names.error;
  5.1339 -                }
  5.1340 -                t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  5.1341 -            } else {
  5.1342 -                t = toP(F.at(pos).Select(t, names._class));
  5.1343 -            }
  5.1344 -        } else if ((mode & TYPE) != 0) {
  5.1345 -            mode = TYPE;
  5.1346 -        } else {
  5.1347 -            syntaxError(S.pos(), "dot.class.expected");
  5.1348 -        }
  5.1349 -        return t;
  5.1350 -    }
  5.1351 -
  5.1352 -    /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  5.1353 -     */
  5.1354 -    JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  5.1355 -        switch (S.token()) {
  5.1356 -        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  5.1357 -        case DOUBLE: case BOOLEAN:
  5.1358 -            if (typeArgs == null)
  5.1359 -                return arrayCreatorRest(newpos, basicType());
  5.1360 -            break;
  5.1361 -        default:
  5.1362 -        }
  5.1363 -        JCExpression t = qualident();
  5.1364 -        int oldmode = mode;
  5.1365 -        mode = TYPE;
  5.1366 -        if (S.token() == LT) {
  5.1367 -            checkGenerics();
  5.1368 -            t = typeArguments(t);
  5.1369 -        }
  5.1370 -        while (S.token() == DOT) {
  5.1371 -            int pos = S.pos();
  5.1372 -            S.nextToken();
  5.1373 -            t = toP(F.at(pos).Select(t, ident()));
  5.1374 -            if (S.token() == LT) {
  5.1375 -                checkGenerics();
  5.1376 -                t = typeArguments(t);
  5.1377 -            }
  5.1378 -        }
  5.1379 -        mode = oldmode;
  5.1380 -        if (S.token() == LBRACKET) {
  5.1381 -            JCExpression e = arrayCreatorRest(newpos, t);
  5.1382 -            if (typeArgs != null) {
  5.1383 -                int pos = newpos;
  5.1384 -                if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  5.1385 -                    // note: this should always happen but we should
  5.1386 -                    // not rely on this as the parser is continuously
  5.1387 -                    // modified to improve error recovery.
  5.1388 -                    pos = typeArgs.head.pos;
  5.1389 -                }
  5.1390 -                setErrorEndPos(S.prevEndPos());
  5.1391 -                reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
  5.1392 -                return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
  5.1393 -            }
  5.1394 -            return e;
  5.1395 -        } else if (S.token() == LPAREN) {
  5.1396 -            return classCreatorRest(newpos, null, typeArgs, t);
  5.1397 -        } else {
  5.1398 -            reportSyntaxError(S.pos(), "expected2",
  5.1399 -                               LPAREN, LBRACKET);
  5.1400 -            t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  5.1401 -            return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  5.1402 -        }
  5.1403 -    }
  5.1404 -
  5.1405 -    /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
  5.1406 -     */
  5.1407 -    JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  5.1408 -        JCExpression t = toP(F.at(S.pos()).Ident(ident()));
  5.1409 -        if (S.token() == LT) {
  5.1410 -            checkGenerics();
  5.1411 -            t = typeArguments(t);
  5.1412 -        }
  5.1413 -        return classCreatorRest(newpos, encl, typeArgs, t);
  5.1414 -    }
  5.1415 -
  5.1416 -    /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
  5.1417 -     *                         | Expression "]" {"[" Expression "]"} BracketsOpt )
  5.1418 -     */
  5.1419 -    JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  5.1420 -        accept(LBRACKET);
  5.1421 -        if (S.token() == RBRACKET) {
  5.1422 -            accept(RBRACKET);
  5.1423 -            elemtype = bracketsOpt(elemtype);
  5.1424 -            if (S.token() == LBRACE) {
  5.1425 -                return arrayInitializer(newpos, elemtype);
  5.1426 -            } else {
  5.1427 -                return syntaxError(S.pos(), "array.dimension.missing");
  5.1428 -            }
  5.1429 -        } else {
  5.1430 -            ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  5.1431 -            dims.append(expression());
  5.1432 -            accept(RBRACKET);
  5.1433 -            while (S.token() == LBRACKET) {
  5.1434 -                int pos = S.pos();
  5.1435 -                S.nextToken();
  5.1436 -                if (S.token() == RBRACKET) {
  5.1437 -                    elemtype = bracketsOptCont(elemtype, pos);
  5.1438 -                } else {
  5.1439 -                    dims.append(expression());
  5.1440 -                    accept(RBRACKET);
  5.1441 -                }
  5.1442 -            }
  5.1443 -            return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  5.1444 -        }
  5.1445 -    }
  5.1446 -
  5.1447 -    /** ClassCreatorRest = Arguments [ClassBody]
  5.1448 -     */
  5.1449 -    JCExpression classCreatorRest(int newpos,
  5.1450 -                                  JCExpression encl,
  5.1451 -                                  List<JCExpression> typeArgs,
  5.1452 -                                  JCExpression t)
  5.1453 -    {
  5.1454 -        List<JCExpression> args = arguments();
  5.1455 -        JCClassDecl body = null;
  5.1456 -        if (S.token() == LBRACE) {
  5.1457 -            int pos = S.pos();
  5.1458 -            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  5.1459 -            JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  5.1460 -            body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  5.1461 -        }
  5.1462 -        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  5.1463 -    }
  5.1464 -
  5.1465 -    /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  5.1466 -     */
  5.1467 -    JCExpression arrayInitializer(int newpos, JCExpression t) {
  5.1468 -        accept(LBRACE);
  5.1469 -        ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  5.1470 -        if (S.token() == COMMA) {
  5.1471 -            S.nextToken();
  5.1472 -        } else if (S.token() != RBRACE) {
  5.1473 -            elems.append(variableInitializer());
  5.1474 -            while (S.token() == COMMA) {
  5.1475 -                S.nextToken();
  5.1476 -                if (S.token() == RBRACE) break;
  5.1477 -                elems.append(variableInitializer());
  5.1478 -            }
  5.1479 -        }
  5.1480 -        accept(RBRACE);
  5.1481 -        return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  5.1482 -    }
  5.1483 -
  5.1484 -    /** VariableInitializer = ArrayInitializer | Expression
  5.1485 -     */
  5.1486 -    public JCExpression variableInitializer() {
  5.1487 -        return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : expression();
  5.1488 -    }
  5.1489 -
  5.1490 -    /** ParExpression = "(" Expression ")"
  5.1491 -     */
  5.1492 -    JCExpression parExpression() {
  5.1493 -        accept(LPAREN);
  5.1494 -        JCExpression t = expression();
  5.1495 -        accept(RPAREN);
  5.1496 -        return t;
  5.1497 -    }
  5.1498 -
  5.1499 -    /** Block = "{" BlockStatements "}"
  5.1500 -     */
  5.1501 -    JCBlock block(int pos, long flags) {
  5.1502 -        accept(LBRACE);
  5.1503 -        List<JCStatement> stats = blockStatements();
  5.1504 -        JCBlock t = F.at(pos).Block(flags, stats);
  5.1505 -        while (S.token() == CASE || S.token() == DEFAULT) {
  5.1506 -            syntaxError("orphaned", S.token());
  5.1507 -            switchBlockStatementGroups();
  5.1508 -        }
  5.1509 -        // the Block node has a field "endpos" for first char of last token, which is
  5.1510 -        // usually but not necessarily the last char of the last token.
  5.1511 -        t.endpos = S.pos();
  5.1512 -        accept(RBRACE);
  5.1513 -        return toP(t);
  5.1514 -    }
  5.1515 -
  5.1516 -    public JCBlock block() {
  5.1517 -        return block(S.pos(), 0);
  5.1518 -    }
  5.1519 -
  5.1520 -    /** BlockStatements = { BlockStatement }
  5.1521 -     *  BlockStatement  = LocalVariableDeclarationStatement
  5.1522 -     *                  | ClassOrInterfaceOrEnumDeclaration
  5.1523 -     *                  | [Ident ":"] Statement
  5.1524 -     *  LocalVariableDeclarationStatement
  5.1525 -     *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  5.1526 -     */
  5.1527 -    @SuppressWarnings("fallthrough")
  5.1528 -    List<JCStatement> blockStatements() {
  5.1529 -//todo: skip to anchor on error(?)
  5.1530 -        int lastErrPos = -1;
  5.1531 -        ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  5.1532 -        while (true) {
  5.1533 -            int pos = S.pos();
  5.1534 -            switch (S.token()) {
  5.1535 -            case RBRACE: case CASE: case DEFAULT: case EOF:
  5.1536 -                return stats.toList();
  5.1537 -            case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  5.1538 -            case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  5.1539 -            case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  5.1540 -                stats.append(statement());
  5.1541 -                break;
  5.1542 -            case MONKEYS_AT:
  5.1543 -            case FINAL: {
  5.1544 -                String dc = S.docComment();
  5.1545 -                JCModifiers mods = modifiersOpt();
  5.1546 -                if (S.token() == INTERFACE ||
  5.1547 -                    S.token() == CLASS ||
  5.1548 -                    allowEnums && S.token() == ENUM) {
  5.1549 -                    stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  5.1550 -                } else {
  5.1551 -                    JCExpression t = type();
  5.1552 -                    stats.appendList(variableDeclarators(mods, t,
  5.1553 -                                                         new ListBuffer<JCStatement>()));
  5.1554 -                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  5.1555 -                    storeEnd(stats.elems.last(), S.endPos());
  5.1556 -                    accept(SEMI);
  5.1557 -                }
  5.1558 -                break;
  5.1559 -            }
  5.1560 -            case ABSTRACT: case STRICTFP: {
  5.1561 -                String dc = S.docComment();
  5.1562 -                JCModifiers mods = modifiersOpt();
  5.1563 -                stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
  5.1564 -                break;
  5.1565 -            }
  5.1566 -            case INTERFACE:
  5.1567 -            case CLASS:
  5.1568 -                stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  5.1569 -                                                               S.docComment()));
  5.1570 -                break;
  5.1571 -            case ENUM:
  5.1572 -            case ASSERT:
  5.1573 -                if (allowEnums && S.token() == ENUM) {
  5.1574 -                    log.error(S.pos(), "local.enum");
  5.1575 -                    stats.
  5.1576 -                        append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
  5.1577 -                                                                 S.docComment()));
  5.1578 -                    break;
  5.1579 -                } else if (allowAsserts && S.token() == ASSERT) {
  5.1580 -                    stats.append(statement());
  5.1581 -                    break;
  5.1582 -                }
  5.1583 -                /* fall through to default */
  5.1584 -            default:
  5.1585 -                Name name = S.name();
  5.1586 -                JCExpression t = term(EXPR | TYPE);
  5.1587 -                if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
  5.1588 -                    S.nextToken();
  5.1589 -                    JCStatement stat = statement();
  5.1590 -                    stats.append(F.at(pos).Labelled(name, stat));
  5.1591 -                } else if ((lastmode & TYPE) != 0 &&
  5.1592 -                           (S.token() == IDENTIFIER ||
  5.1593 -                            S.token() == ASSERT ||
  5.1594 -                            S.token() == ENUM)) {
  5.1595 -                    pos = S.pos();
  5.1596 -                    JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  5.1597 -                    F.at(pos);
  5.1598 -                    stats.appendList(variableDeclarators(mods, t,
  5.1599 -                                                         new ListBuffer<JCStatement>()));
  5.1600 -                    // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  5.1601 -                    storeEnd(stats.elems.last(), S.endPos());
  5.1602 -                    accept(SEMI);
  5.1603 -                } else {
  5.1604 -                    // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  5.1605 -                    stats.append(to(F.at(pos).Exec(checkExprStat(t))));
  5.1606 -                    accept(SEMI);
  5.1607 -                }
  5.1608 -            }
  5.1609 -
  5.1610 -            // error recovery
  5.1611 -            if (S.pos() == lastErrPos)
  5.1612 -                return stats.toList();
  5.1613 -            if (S.pos() <= errorEndPos) {
  5.1614 -                skip(false, true, true, true);
  5.1615 -                lastErrPos = S.pos();
  5.1616 -            }
  5.1617 -
  5.1618 -            // ensure no dangling /** @deprecated */ active
  5.1619 -            S.resetDeprecatedFlag();
  5.1620 -        }
  5.1621 -    }
  5.1622 -
  5.1623 -    /** Statement =
  5.1624 -     *       Block
  5.1625 -     *     | IF ParExpression Statement [ELSE Statement]
  5.1626 -     *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  5.1627 -     *     | FOR "(" FormalParameter : Expression ")" Statement
  5.1628 -     *     | WHILE ParExpression Statement
  5.1629 -     *     | DO Statement WHILE ParExpression ";"
  5.1630 -     *     | TRY Block ( Catches | [Catches] FinallyPart )
  5.1631 -     *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  5.1632 -     *     | SYNCHRONIZED ParExpression Block
  5.1633 -     *     | RETURN [Expression] ";"
  5.1634 -     *     | THROW Expression ";"
  5.1635 -     *     | BREAK [Ident] ";"
  5.1636 -     *     | CONTINUE [Ident] ";"
  5.1637 -     *     | ASSERT Expression [ ":" Expression ] ";"
  5.1638 -     *     | ";"
  5.1639 -     *     | ExpressionStatement
  5.1640 -     *     | Ident ":" Statement
  5.1641 -     */
  5.1642 -    @SuppressWarnings("fallthrough")
  5.1643 -    public JCStatement statement() {
  5.1644 -        int pos = S.pos();
  5.1645 -        switch (S.token()) {
  5.1646 -        case LBRACE:
  5.1647 -            return block();
  5.1648 -        case IF: {
  5.1649 -            S.nextToken();
  5.1650 -            JCExpression cond = parExpression();
  5.1651 -            JCStatement thenpart = statement();
  5.1652 -            JCStatement elsepart = null;
  5.1653 -            if (S.token() == ELSE) {
  5.1654 -                S.nextToken();
  5.1655 -                elsepart = statement();
  5.1656 -            }
  5.1657 -            return F.at(pos).If(cond, thenpart, elsepart);
  5.1658 -        }
  5.1659 -        case FOR: {
  5.1660 -            S.nextToken();
  5.1661 -            accept(LPAREN);
  5.1662 -            List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
  5.1663 -            if (inits.length() == 1 &&
  5.1664 -                inits.head.getTag() == JCTree.VARDEF &&
  5.1665 -                ((JCVariableDecl) inits.head).init == null &&
  5.1666 -                S.token() == COLON) {
  5.1667 -                checkForeach();
  5.1668 -                JCVariableDecl var = (JCVariableDecl)inits.head;
  5.1669 -                accept(COLON);
  5.1670 -                JCExpression expr = expression();
  5.1671 -                accept(RPAREN);
  5.1672 -                JCStatement body = statement();
  5.1673 -                return F.at(pos).ForeachLoop(var, expr, body);
  5.1674 -            } else {
  5.1675 -                accept(SEMI);
  5.1676 -                JCExpression cond = S.token() == SEMI ? null : expression();
  5.1677 -                accept(SEMI);
  5.1678 -                List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  5.1679 -                accept(RPAREN);
  5.1680 -                JCStatement body = statement();
  5.1681 -                return F.at(pos).ForLoop(inits, cond, steps, body);
  5.1682 -            }
  5.1683 -        }
  5.1684 -        case WHILE: {
  5.1685 -            S.nextToken();
  5.1686 -            JCExpression cond = parExpression();
  5.1687 -            JCStatement body = statement();
  5.1688 -            return F.at(pos).WhileLoop(cond, body);
  5.1689 -        }
  5.1690 -        case DO: {
  5.1691 -            S.nextToken();
  5.1692 -            JCStatement body = statement();
  5.1693 -            accept(WHILE);
  5.1694 -            JCExpression cond = parExpression();
  5.1695 -            JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  5.1696 -            accept(SEMI);
  5.1697 -            return t;
  5.1698 -        }
  5.1699 -        case TRY: {
  5.1700 -            S.nextToken();
  5.1701 -            JCBlock body = block();
  5.1702 -            ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  5.1703 -            JCBlock finalizer = null;
  5.1704 -            if (S.token() == CATCH || S.token() == FINALLY) {
  5.1705 -                while (S.token() == CATCH) catchers.append(catchClause());
  5.1706 -                if (S.token() == FINALLY) {
  5.1707 -                    S.nextToken();
  5.1708 -                    finalizer = block();
  5.1709 -                }
  5.1710 -            } else {
  5.1711 -                log.error(pos, "try.without.catch.or.finally");
  5.1712 -            }
  5.1713 -            return F.at(pos).Try(body, catchers.toList(), finalizer);
  5.1714 -        }
  5.1715 -        case SWITCH: {
  5.1716 -            S.nextToken();
  5.1717 -            JCExpression selector = parExpression();
  5.1718 -            accept(LBRACE);
  5.1719 -            List<JCCase> cases = switchBlockStatementGroups();
  5.1720 -            JCSwitch t = to(F.at(pos).Switch(selector, cases));
  5.1721 -            accept(RBRACE);
  5.1722 -            return t;
  5.1723 -        }
  5.1724 -        case SYNCHRONIZED: {
  5.1725 -            S.nextToken();
  5.1726 -            JCExpression lock = parExpression();
  5.1727 -            JCBlock body = block();
  5.1728 -            return F.at(pos).Synchronized(lock, body);
  5.1729 -        }
  5.1730 -        case RETURN: {
  5.1731 -            S.nextToken();
  5.1732 -            JCExpression result = S.token() == SEMI ? null : expression();
  5.1733 -            JCReturn t = to(F.at(pos).Return(result));
  5.1734 -            accept(SEMI);
  5.1735 -            return t;
  5.1736 -        }
  5.1737 -        case THROW: {
  5.1738 -            S.nextToken();
  5.1739 -            JCExpression exc = expression();
  5.1740 -            JCThrow t = to(F.at(pos).Throw(exc));
  5.1741 -            accept(SEMI);
  5.1742 -            return t;
  5.1743 -        }
  5.1744 -        case BREAK: {
  5.1745 -            S.nextToken();
  5.1746 -            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  5.1747 -            JCBreak t = to(F.at(pos).Break(label));
  5.1748 -            accept(SEMI);
  5.1749 -            return t;
  5.1750 -        }
  5.1751 -        case CONTINUE: {
  5.1752 -            S.nextToken();
  5.1753 -            Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
  5.1754 -            JCContinue t =  to(F.at(pos).Continue(label));
  5.1755 -            accept(SEMI);
  5.1756 -            return t;
  5.1757 -        }
  5.1758 -        case SEMI:
  5.1759 -            S.nextToken();
  5.1760 -            return toP(F.at(pos).Skip());
  5.1761 -        case ELSE:
  5.1762 -            return toP(F.Exec(syntaxError("else.without.if")));
  5.1763 -        case FINALLY:
  5.1764 -            return toP(F.Exec(syntaxError("finally.without.try")));
  5.1765 -        case CATCH:
  5.1766 -            return toP(F.Exec(syntaxError("catch.without.try")));
  5.1767 -        case ASSERT: {
  5.1768 -            if (allowAsserts && S.token() == ASSERT) {
  5.1769 -                S.nextToken();
  5.1770 -                JCExpression assertion = expression();
  5.1771 -                JCExpression message = null;
  5.1772 -                if (S.token() == COLON) {
  5.1773 -                    S.nextToken();
  5.1774 -                    message = expression();
  5.1775 -                }
  5.1776 -                JCAssert t = to(F.at(pos).Assert(assertion, message));
  5.1777 -                accept(SEMI);
  5.1778 -                return t;
  5.1779 -            }
  5.1780 -            /* else fall through to default case */
  5.1781 -        }
  5.1782 -        case ENUM:
  5.1783 -        default:
  5.1784 -            Name name = S.name();
  5.1785 -            JCExpression expr = expression();
  5.1786 -            if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
  5.1787 -                S.nextToken();
  5.1788 -                JCStatement stat = statement();
  5.1789 -                return F.at(pos).Labelled(name, stat);
  5.1790 -            } else {
  5.1791 -                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  5.1792 -                JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  5.1793 -                accept(SEMI);
  5.1794 -                return stat;
  5.1795 -            }
  5.1796 -        }
  5.1797 -    }
  5.1798 -
  5.1799 -    /** CatchClause     = CATCH "(" FormalParameter ")" Block
  5.1800 -     */
  5.1801 -    JCCatch catchClause() {
  5.1802 -        int pos = S.pos();
  5.1803 -        accept(CATCH);
  5.1804 -        accept(LPAREN);
  5.1805 -        JCVariableDecl formal =
  5.1806 -            variableDeclaratorId(optFinal(Flags.PARAMETER),
  5.1807 -                                 qualident());
  5.1808 -        accept(RPAREN);
  5.1809 -        JCBlock body = block();
  5.1810 -        return F.at(pos).Catch(formal, body);
  5.1811 -    }
  5.1812 -
  5.1813 -    /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  5.1814 -     *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  5.1815 -     *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  5.1816 -     */
  5.1817 -    List<JCCase> switchBlockStatementGroups() {
  5.1818 -        ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  5.1819 -        while (true) {
  5.1820 -            int pos = S.pos();
  5.1821 -            switch (S.token()) {
  5.1822 -            case CASE: {
  5.1823 -                S.nextToken();
  5.1824 -                JCExpression pat = expression();
  5.1825 -                accept(COLON);
  5.1826 -                List<JCStatement> stats = blockStatements();
  5.1827 -                JCCase c = F.at(pos).Case(pat, stats);
  5.1828 -                if (stats.isEmpty())
  5.1829 -                    storeEnd(c, S.prevEndPos());
  5.1830 -                cases.append(c);
  5.1831 -                break;
  5.1832 -            }
  5.1833 -            case DEFAULT: {
  5.1834 -                S.nextToken();
  5.1835 -                accept(COLON);
  5.1836 -                List<JCStatement> stats = blockStatements();
  5.1837 -                JCCase c = F.at(pos).Case(null, stats);
  5.1838 -                if (stats.isEmpty())
  5.1839 -                    storeEnd(c, S.prevEndPos());
  5.1840 -                cases.append(c);
  5.1841 -                break;
  5.1842 -            }
  5.1843 -            case RBRACE: case EOF:
  5.1844 -                return cases.toList();
  5.1845 -            default:
  5.1846 -                S.nextToken(); // to ensure progress
  5.1847 -                syntaxError(pos, "expected3",
  5.1848 -                    CASE, DEFAULT, RBRACE);
  5.1849 -            }
  5.1850 -        }
  5.1851 -    }
  5.1852 -
  5.1853 -    /** MoreStatementExpressions = { COMMA StatementExpression }
  5.1854 -     */
  5.1855 -    <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  5.1856 -                                                                    JCExpression first,
  5.1857 -                                                                    T stats) {
  5.1858 -        // This Exec is a "StatementExpression"; it subsumes no terminating token
  5.1859 -        stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  5.1860 -        while (S.token() == COMMA) {
  5.1861 -            S.nextToken();
  5.1862 -            pos = S.pos();
  5.1863 -            JCExpression t = expression();
  5.1864 -            // This Exec is a "StatementExpression"; it subsumes no terminating token
  5.1865 -            stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  5.1866 -        }
  5.1867 -        return stats;
  5.1868 -    }
  5.1869 -
  5.1870 -    /** ForInit = StatementExpression MoreStatementExpressions
  5.1871 -     *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  5.1872 -     */
  5.1873 -    List<JCStatement> forInit() {
  5.1874 -        ListBuffer<JCStatement> stats = lb();
  5.1875 -        int pos = S.pos();
  5.1876 -        if (S.token() == FINAL || S.token() == MONKEYS_AT) {
  5.1877 -            return variableDeclarators(optFinal(0), type(), stats).toList();
  5.1878 -        } else {
  5.1879 -            JCExpression t = term(EXPR | TYPE);
  5.1880 -            if ((lastmode & TYPE) != 0 &&
  5.1881 -                (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
  5.1882 -                return variableDeclarators(modifiersOpt(), t, stats).toList();
  5.1883 -            else
  5.1884 -                return moreStatementExpressions(pos, t, stats).toList();
  5.1885 -        }
  5.1886 -    }
  5.1887 -
  5.1888 -    /** ForUpdate = StatementExpression MoreStatementExpressions
  5.1889 -     */
  5.1890 -    List<JCExpressionStatement> forUpdate() {
  5.1891 -        return moreStatementExpressions(S.pos(),
  5.1892 -                                        expression(),
  5.1893 -                                        new ListBuffer<JCExpressionStatement>()).toList();
  5.1894 -    }
  5.1895 -
  5.1896 -    /** AnnotationsOpt = { '@' Annotation }
  5.1897 -     */
  5.1898 -    List<JCAnnotation> annotationsOpt() {
  5.1899 -        if (S.token() != MONKEYS_AT) return List.nil(); // optimization
  5.1900 -        ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  5.1901 -        while (S.token() == MONKEYS_AT) {
  5.1902 -            int pos = S.pos();
  5.1903 -            S.nextToken();
  5.1904 -            buf.append(annotation(pos));
  5.1905 -        }
  5.1906 -        return buf.toList();
  5.1907 -    }
  5.1908 -
  5.1909 -    /** ModifiersOpt = { Modifier }
  5.1910 -     *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  5.1911 -     *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  5.1912 -     *           | "@" Annotation
  5.1913 -     */
  5.1914 -    JCModifiers modifiersOpt() {
  5.1915 -        return modifiersOpt(null);
  5.1916 -    }
  5.1917 -    JCModifiers modifiersOpt(JCModifiers partial) {
  5.1918 -        long flags = (partial == null) ? 0 : partial.flags;
  5.1919 -        if (S.deprecatedFlag()) {
  5.1920 -            flags |= Flags.DEPRECATED;
  5.1921 -            S.resetDeprecatedFlag();
  5.1922 -        }
  5.1923 -        ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  5.1924 -        if (partial != null) annotations.appendList(partial.annotations);
  5.1925 -        int pos = S.pos();
  5.1926 -        int lastPos = Position.NOPOS;
  5.1927 -    loop:
  5.1928 -        while (true) {
  5.1929 -            long flag;
  5.1930 -            switch (S.token()) {
  5.1931 -            case PRIVATE     : flag = Flags.PRIVATE; break;
  5.1932 -            case PROTECTED   : flag = Flags.PROTECTED; break;
  5.1933 -            case PUBLIC      : flag = Flags.PUBLIC; break;
  5.1934 -            case STATIC      : flag = Flags.STATIC; break;
  5.1935 -            case TRANSIENT   : flag = Flags.TRANSIENT; break;
  5.1936 -            case FINAL       : flag = Flags.FINAL; break;
  5.1937 -            case ABSTRACT    : flag = Flags.ABSTRACT; break;
  5.1938 -            case NATIVE      : flag = Flags.NATIVE; break;
  5.1939 -            case VOLATILE    : flag = Flags.VOLATILE; break;
  5.1940 -            case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  5.1941 -            case STRICTFP    : flag = Flags.STRICTFP; break;
  5.1942 -            case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  5.1943 -            default: break loop;
  5.1944 -            }
  5.1945 -            if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
  5.1946 -            lastPos = S.pos();
  5.1947 -            S.nextToken();
  5.1948 -            if (flag == Flags.ANNOTATION) {
  5.1949 -                checkAnnotations();
  5.1950 -                if (S.token() != INTERFACE) {
  5.1951 -                JCAnnotation ann = annotation(lastPos);
  5.1952 -                // if first modifier is an annotation, set pos to annotation's.
  5.1953 -                if (flags == 0 && annotations.isEmpty())
  5.1954 -                    pos = ann.pos;
  5.1955 -                annotations.append(ann);
  5.1956 -                lastPos = ann.pos;
  5.1957 -                    flag = 0;
  5.1958 -                }
  5.1959 -            }
  5.1960 -            flags |= flag;
  5.1961 -        }
  5.1962 -        switch (S.token()) {
  5.1963 -        case ENUM: flags |= Flags.ENUM; break;
  5.1964 -        case INTERFACE: flags |= Flags.INTERFACE; break;
  5.1965 -        default: break;
  5.1966 -        }
  5.1967 -
  5.1968 -        /* A modifiers tree with no modifier tokens or annotations
  5.1969 -         * has no text position. */
  5.1970 -        if (flags == 0 && annotations.isEmpty())
  5.1971 -            pos = Position.NOPOS;
  5.1972 -
  5.1973 -        JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  5.1974 -        if (pos != Position.NOPOS)
  5.1975 -            storeEnd(mods, S.prevEndPos());
  5.1976 -        return mods;
  5.1977 -    }
  5.1978 -
  5.1979 -    /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  5.1980 -     * @param pos position of "@" token
  5.1981 -     */
  5.1982 -    JCAnnotation annotation(int pos) {
  5.1983 -        // accept(AT); // AT consumed by caller
  5.1984 -        checkAnnotations();
  5.1985 -        JCTree ident = qualident();
  5.1986 -        List<JCExpression> fieldValues = annotationFieldValuesOpt();
  5.1987 -        JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
  5.1988 -        storeEnd(ann, S.prevEndPos());
  5.1989 -        return ann;
  5.1990 -    }
  5.1991 -
  5.1992 -    List<JCExpression> annotationFieldValuesOpt() {
  5.1993 -        return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  5.1994 -    }
  5.1995 -
  5.1996 -    /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  5.1997 -    List<JCExpression> annotationFieldValues() {
  5.1998 -        accept(LPAREN);
  5.1999 -        ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  5.2000 -        if (S.token() != RPAREN) {
  5.2001 -            buf.append(annotationFieldValue());
  5.2002 -            while (S.token() == COMMA) {
  5.2003 -                S.nextToken();
  5.2004 -                buf.append(annotationFieldValue());
  5.2005 -            }
  5.2006 -        }
  5.2007 -        accept(RPAREN);
  5.2008 -        return buf.toList();
  5.2009 -    }
  5.2010 -
  5.2011 -    /** AnnotationFieldValue    = AnnotationValue
  5.2012 -     *                          | Identifier "=" AnnotationValue
  5.2013 -     */
  5.2014 -    JCExpression annotationFieldValue() {
  5.2015 -        if (S.token() == IDENTIFIER) {
  5.2016 -            mode = EXPR;
  5.2017 -            JCExpression t1 = term1();
  5.2018 -            if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
  5.2019 -                int pos = S.pos();
  5.2020 -                accept(EQ);
  5.2021 -                return toP(F.at(pos).Assign(t1, annotationValue()));
  5.2022 -            } else {
  5.2023 -                return t1;
  5.2024 -            }
  5.2025 -        }
  5.2026 -        return annotationValue();
  5.2027 -    }
  5.2028 -
  5.2029 -    /* AnnotationValue          = ConditionalExpression
  5.2030 -     *                          | Annotation
  5.2031 -     *                          | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
  5.2032 -     */
  5.2033 -    JCExpression annotationValue() {
  5.2034 -        int pos;
  5.2035 -        switch (S.token()) {
  5.2036 -        case MONKEYS_AT:
  5.2037 -            pos = S.pos();
  5.2038 -            S.nextToken();
  5.2039 -            return annotation(pos);
  5.2040 -        case LBRACE:
  5.2041 -            pos = S.pos();
  5.2042 -            accept(LBRACE);
  5.2043 -            ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  5.2044 -            if (S.token() != RBRACE) {
  5.2045 -                buf.append(annotationValue());
  5.2046 -                while (S.token() == COMMA) {
  5.2047 -                    S.nextToken();
  5.2048 -                    if (S.token() == RPAREN) break;
  5.2049 -                    buf.append(annotationValue());
  5.2050 -                }
  5.2051 -            }
  5.2052 -            accept(RBRACE);
  5.2053 -            return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  5.2054 -        default:
  5.2055 -            mode = EXPR;
  5.2056 -            return term1();
  5.2057 -        }
  5.2058 -    }
  5.2059 -
  5.2060 -    /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  5.2061 -     */
  5.2062 -    public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  5.2063 -                                                                         JCExpression type,
  5.2064 -                                                                         T vdefs)
  5.2065 -    {
  5.2066 -        return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
  5.2067 -    }
  5.2068 -
  5.2069 -    /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  5.2070 -     *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  5.2071 -     *
  5.2072 -     *  @param reqInit  Is an initializer always required?
  5.2073 -     *  @param dc       The documentation comment for the variable declarations, or null.
  5.2074 -     */
  5.2075 -    <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  5.2076 -                                                                     JCModifiers mods,
  5.2077 -                                                                     JCExpression type,
  5.2078 -                                                                     Name name,
  5.2079 -                                                                     boolean reqInit,
  5.2080 -                                                                     String dc,
  5.2081 -                                                                     T vdefs)
  5.2082 -    {
  5.2083 -        vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  5.2084 -        while (S.token() == COMMA) {
  5.2085 -            // All but last of multiple declarators subsume a comma
  5.2086 -            storeEnd((JCTree)vdefs.elems.last(), S.endPos());
  5.2087 -            S.nextToken();
  5.2088 -            vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  5.2089 -        }
  5.2090 -        return vdefs;
  5.2091 -    }
  5.2092 -
  5.2093 -    /** VariableDeclarator = Ident VariableDeclaratorRest
  5.2094 -     *  ConstantDeclarator = Ident ConstantDeclaratorRest
  5.2095 -     */
  5.2096 -    JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
  5.2097 -        return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
  5.2098 -    }
  5.2099 -
  5.2100 -    /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  5.2101 -     *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  5.2102 -     *
  5.2103 -     *  @param reqInit  Is an initializer always required?
  5.2104 -     *  @param dc       The documentation comment for the variable declarations, or null.
  5.2105 -     */
  5.2106 -    JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  5.2107 -                                  boolean reqInit, String dc) {
  5.2108 -        type = bracketsOpt(type);
  5.2109 -        JCExpression init = null;
  5.2110 -        if (S.token() == EQ) {
  5.2111 -            S.nextToken();
  5.2112 -            init = variableInitializer();
  5.2113 -        }
  5.2114 -        else if (reqInit) syntaxError(S.pos(), "expected", EQ);
  5.2115 -        JCVariableDecl result =
  5.2116 -            toP(F.at(pos).VarDef(mods, name, type, init));
  5.2117 -        attach(result, dc);
  5.2118 -        return result;
  5.2119 -    }
  5.2120 -
  5.2121 -    /** VariableDeclaratorId = Ident BracketsOpt
  5.2122 -     */
  5.2123 -    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  5.2124 -        int pos = S.pos();
  5.2125 -        Name name = ident();
  5.2126 -        if ((mods.flags & Flags.VARARGS) == 0)
  5.2127 -            type = bracketsOpt(type);
  5.2128 -        return toP(F.at(pos).VarDef(mods, name, type, null));
  5.2129 -    }
  5.2130 -
  5.2131 -    /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  5.2132 -     */
  5.2133 -    public JCTree.JCCompilationUnit compilationUnit() {
  5.2134 -        int pos = S.pos();
  5.2135 -        JCExpression pid = null;
  5.2136 -        String dc = S.docComment();
  5.2137 -        JCModifiers mods = null;
  5.2138 -        List<JCAnnotation> packageAnnotations = List.nil();
  5.2139 -        if (S.token() == MONKEYS_AT)
  5.2140 -            mods = modifiersOpt();
  5.2141 -
  5.2142 -        if (S.token() == PACKAGE) {
  5.2143 -            if (mods != null) {
  5.2144 -                checkNoMods(mods.flags);
  5.2145 -                packageAnnotations = mods.annotations;
  5.2146 -                mods = null;
  5.2147 -            }
  5.2148 -            S.nextToken();
  5.2149 -            pid = qualident();
  5.2150 -            accept(SEMI);
  5.2151 -        }
  5.2152 -        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  5.2153 -       boolean checkForImports = true;
  5.2154 -        while (S.token() != EOF) {
  5.2155 -            if (S.pos() <= errorEndPos) {
  5.2156 -                // error recovery
  5.2157 -                skip(checkForImports, false, false, false);
  5.2158 -                if (S.token() == EOF)
  5.2159 -                    break;
  5.2160 -            }
  5.2161 -            if (checkForImports && mods == null && S.token() == IMPORT) {
  5.2162 -                defs.append(importDeclaration());
  5.2163 -            } else {
  5.2164 -                JCTree def = typeDeclaration(mods);
  5.2165 -                if (def instanceof JCExpressionStatement)
  5.2166 -                    def = ((JCExpressionStatement)def).expr;
  5.2167 -                defs.append(def);
  5.2168 -                if (def instanceof JCClassDecl)
  5.2169 -                    checkForImports = false;
  5.2170 -                mods = null;
  5.2171 -            }
  5.2172 -        }
  5.2173 -        JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
  5.2174 -        attach(toplevel, dc);
  5.2175 -        if (defs.elems.isEmpty())
  5.2176 -            storeEnd(toplevel, S.prevEndPos());
  5.2177 -        if (keepDocComments) toplevel.docComments = docComments;
  5.2178 -        return toplevel;
  5.2179 -    }
  5.2180 -
  5.2181 -    /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  5.2182 -     */
  5.2183 -    JCTree importDeclaration() {
  5.2184 -        int pos = S.pos();
  5.2185 -        S.nextToken();
  5.2186 -        boolean importStatic = false;
  5.2187 -        if (S.token() == STATIC) {
  5.2188 -            checkStaticImports();
  5.2189 -            importStatic = true;
  5.2190 -            S.nextToken();
  5.2191 -        }
  5.2192 -        JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
  5.2193 -        do {
  5.2194 -            int pos1 = S.pos();
  5.2195 -            accept(DOT);
  5.2196 -            if (S.token() == STAR) {
  5.2197 -                pid = to(F.at(pos1).Select(pid, names.asterisk));
  5.2198 -                S.nextToken();
  5.2199 -                break;
  5.2200 -            } else {
  5.2201 -                pid = toP(F.at(pos1).Select(pid, ident()));
  5.2202 -            }
  5.2203 -        } while (S.token() == DOT);
  5.2204 -        accept(SEMI);
  5.2205 -        return toP(F.at(pos).Import(pid, importStatic));
  5.2206 -    }
  5.2207 -
  5.2208 -    /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  5.2209 -     *                  | ";"
  5.2210 -     */
  5.2211 -    JCTree typeDeclaration(JCModifiers mods) {
  5.2212 -        int pos = S.pos();
  5.2213 -        if (mods == null && S.token() == SEMI) {
  5.2214 -            S.nextToken();
  5.2215 -            return toP(F.at(pos).Skip());
  5.2216 -        } else {
  5.2217 -            String dc = S.docComment();
  5.2218 -            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
  5.2219 -        }
  5.2220 -    }
  5.2221 -
  5.2222 -    /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  5.2223 -     *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  5.2224 -     *  @param mods     Any modifiers starting the class or interface declaration
  5.2225 -     *  @param dc       The documentation comment for the class, or null.
  5.2226 -     */
  5.2227 -    JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
  5.2228 -        if (S.token() == CLASS) {
  5.2229 -            return classDeclaration(mods, dc);
  5.2230 -        } else if (S.token() == INTERFACE) {
  5.2231 -            return interfaceDeclaration(mods, dc);
  5.2232 -        } else if (allowEnums) {
  5.2233 -            if (S.token() == ENUM) {
  5.2234 -                return enumDeclaration(mods, dc);
  5.2235 -            } else {
  5.2236 -                int pos = S.pos();
  5.2237 -                List<JCTree> errs;
  5.2238 -                if (S.token() == IDENTIFIER) {
  5.2239 -                    errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  5.2240 -                    setErrorEndPos(S.pos());
  5.2241 -                } else {
  5.2242 -                    errs = List.<JCTree>of(mods);
  5.2243 -                }
  5.2244 -                return toP(F.Exec(syntaxError(pos, errs, "expected3",
  5.2245 -                                              CLASS, INTERFACE, ENUM)));
  5.2246 -            }
  5.2247 -        } else {
  5.2248 -            if (S.token() == ENUM) {
  5.2249 -                log.error(S.pos(), "enums.not.supported.in.source", source.name);
  5.2250 -                allowEnums = true;
  5.2251 -                return enumDeclaration(mods, dc);
  5.2252 -            }
  5.2253 -            int pos = S.pos();
  5.2254 -            List<JCTree> errs;
  5.2255 -            if (S.token() == IDENTIFIER) {
  5.2256 -                errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  5.2257 -                setErrorEndPos(S.pos());
  5.2258 -            } else {
  5.2259 -                errs = List.<JCTree>of(mods);
  5.2260 -            }
  5.2261 -            return toP(F.Exec(syntaxError(pos, errs, "expected2",
  5.2262 -                                          CLASS, INTERFACE)));
  5.2263 -        }
  5.2264 -    }
  5.2265 -
  5.2266 -    /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  5.2267 -     *                     [IMPLEMENTS TypeList] ClassBody
  5.2268 -     *  @param mods    The modifiers starting the class declaration
  5.2269 -     *  @param dc       The documentation comment for the class, or null.
  5.2270 -     */
  5.2271 -    JCClassDecl classDeclaration(JCModifiers mods, String dc) {
  5.2272 -        int pos = S.pos();
  5.2273 -        accept(CLASS);
  5.2274 -        Name name = ident();
  5.2275 -
  5.2276 -        List<JCTypeParameter> typarams = typeParametersOpt();
  5.2277 -
  5.2278 -        JCTree extending = null;
  5.2279 -        if (S.token() == EXTENDS) {
  5.2280 -            S.nextToken();
  5.2281 -            extending = type();
  5.2282 -        }
  5.2283 -        List<JCExpression> implementing = List.nil();
  5.2284 -        if (S.token() == IMPLEMENTS) {
  5.2285 -            S.nextToken();
  5.2286 -            implementing = typeList();
  5.2287 -        }
  5.2288 -        List<JCTree> defs = classOrInterfaceBody(name, false);
  5.2289 -        JCClassDecl result = toP(F.at(pos).ClassDef(
  5.2290 -            mods, name, typarams, extending, implementing, defs));
  5.2291 -        attach(result, dc);
  5.2292 -        return result;
  5.2293 -    }
  5.2294 -
  5.2295 -    /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  5.2296 -     *                         [EXTENDS TypeList] InterfaceBody
  5.2297 -     *  @param mods    The modifiers starting the interface declaration
  5.2298 -     *  @param dc       The documentation comment for the interface, or null.
  5.2299 -     */
  5.2300 -    JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
  5.2301 -        int pos = S.pos();
  5.2302 -        accept(INTERFACE);
  5.2303 -        Name name = ident();
  5.2304 -
  5.2305 -        List<JCTypeParameter> typarams = typeParametersOpt();
  5.2306 -
  5.2307 -        List<JCExpression> extending = List.nil();
  5.2308 -        if (S.token() == EXTENDS) {
  5.2309 -            S.nextToken();
  5.2310 -            extending = typeList();
  5.2311 -        }
  5.2312 -        List<JCTree> defs = classOrInterfaceBody(name, true);
  5.2313 -        JCClassDecl result = toP(F.at(pos).ClassDef(
  5.2314 -            mods, name, typarams, null, extending, defs));
  5.2315 -        attach(result, dc);
  5.2316 -        return result;
  5.2317 -    }
  5.2318 -
  5.2319 -    /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  5.2320 -     *  @param mods    The modifiers starting the enum declaration
  5.2321 -     *  @param dc       The documentation comment for the enum, or null.
  5.2322 -     */
  5.2323 -    JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
  5.2324 -        int pos = S.pos();
  5.2325 -        accept(ENUM);
  5.2326 -        Name name = ident();
  5.2327 -
  5.2328 -        List<JCExpression> implementing = List.nil();
  5.2329 -        if (S.token() == IMPLEMENTS) {
  5.2330 -            S.nextToken();
  5.2331 -            implementing = typeList();
  5.2332 -        }
  5.2333 -
  5.2334 -        List<JCTree> defs = enumBody(name);
  5.2335 -        JCModifiers newMods =
  5.2336 -            F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations);
  5.2337 -        JCClassDecl result = toP(F.at(pos).
  5.2338 -            ClassDef(newMods, name, List.<JCTypeParameter>nil(),
  5.2339 -                null, implementing, defs));
  5.2340 -        attach(result, dc);
  5.2341 -        return result;
  5.2342 -    }
  5.2343 -
  5.2344 -    /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  5.2345 -     *                  [ ";" {ClassBodyDeclaration} ] "}"
  5.2346 -     */
  5.2347 -    List<JCTree> enumBody(Name enumName) {
  5.2348 -        accept(LBRACE);
  5.2349 -        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  5.2350 -        if (S.token() == COMMA) {
  5.2351 -            S.nextToken();
  5.2352 -        } else if (S.token() != RBRACE && S.token() != SEMI) {
  5.2353 -            defs.append(enumeratorDeclaration(enumName));
  5.2354 -            while (S.token() == COMMA) {
  5.2355 -                S.nextToken();
  5.2356 -                if (S.token() == RBRACE || S.token() == SEMI) break;
  5.2357 -                defs.append(enumeratorDeclaration(enumName));
  5.2358 -            }
  5.2359 -            if (S.token() != SEMI && S.token() != RBRACE) {
  5.2360 -                defs.append(syntaxError(S.pos(), "expected3",
  5.2361 -                                COMMA, RBRACE, SEMI));
  5.2362 -                S.nextToken();
  5.2363 -            }
  5.2364 -        }
  5.2365 -        if (S.token() == SEMI) {
  5.2366 -            S.nextToken();
  5.2367 -            while (S.token() != RBRACE && S.token() != EOF) {
  5.2368 -                defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  5.2369 -                                                                false));
  5.2370 -                if (S.pos() <= errorEndPos) {
  5.2371 -                    // error recovery
  5.2372 -                   skip(false, true, true, false);
  5.2373 -                }
  5.2374 -            }
  5.2375 -        }
  5.2376 -        accept(RBRACE);
  5.2377 -        return defs.toList();
  5.2378 -    }
  5.2379 -
  5.2380 -    /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  5.2381 -     */
  5.2382 -    JCTree enumeratorDeclaration(Name enumName) {
  5.2383 -        String dc = S.docComment();
  5.2384 -        int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  5.2385 -        if (S.deprecatedFlag()) {
  5.2386 -            flags |= Flags.DEPRECATED;
  5.2387 -            S.resetDeprecatedFlag();
  5.2388 -        }
  5.2389 -        int pos = S.pos();
  5.2390 -        List<JCAnnotation> annotations = annotationsOpt();
  5.2391 -        JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  5.2392 -        List<JCExpression> typeArgs = typeArgumentsOpt();
  5.2393 -        int identPos = S.pos();
  5.2394 -        Name name = ident();
  5.2395 -        int createPos = S.pos();
  5.2396 -        List<JCExpression> args = (S.token() == LPAREN)
  5.2397 -            ? arguments() : List.<JCExpression>nil();
  5.2398 -        JCClassDecl body = null;
  5.2399 -        if (S.token() == LBRACE) {
  5.2400 -            JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  5.2401 -            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  5.2402 -            body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  5.2403 -        }
  5.2404 -        if (args.isEmpty() && body == null)
  5.2405 -            createPos = Position.NOPOS;
  5.2406 -        JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
  5.2407 -        JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  5.2408 -        if (createPos != Position.NOPOS)
  5.2409 -            storeEnd(create, S.prevEndPos());
  5.2410 -        ident = F.at(Position.NOPOS).Ident(enumName);
  5.2411 -        JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  5.2412 -        attach(result, dc);
  5.2413 -        return result;
  5.2414 -    }
  5.2415 -
  5.2416 -    /** TypeList = Type {"," Type}
  5.2417 -     */
  5.2418 -    List<JCExpression> typeList() {
  5.2419 -        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  5.2420 -        ts.append(type());
  5.2421 -        while (S.token() == COMMA) {
  5.2422 -            S.nextToken();
  5.2423 -            ts.append(type());
  5.2424 -        }
  5.2425 -        return ts.toList();
  5.2426 -    }
  5.2427 -
  5.2428 -    /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  5.2429 -     *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  5.2430 -     */
  5.2431 -    List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  5.2432 -        accept(LBRACE);
  5.2433 -        if (S.pos() <= errorEndPos) {
  5.2434 -            // error recovery
  5.2435 -            skip(false, true, false, false);
  5.2436 -            if (S.token() == LBRACE)
  5.2437 -                S.nextToken();
  5.2438 -        }
  5.2439 -        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  5.2440 -        while (S.token() != RBRACE && S.token() != EOF) {
  5.2441 -            defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  5.2442 -            if (S.pos() <= errorEndPos) {
  5.2443 -               // error recovery
  5.2444 -               skip(false, true, true, false);
  5.2445 -           }
  5.2446 -        }
  5.2447 -        accept(RBRACE);
  5.2448 -        return defs.toList();
  5.2449 -    }
  5.2450 -
  5.2451 -    /** ClassBodyDeclaration =
  5.2452 -     *      ";"
  5.2453 -     *    | [STATIC] Block
  5.2454 -     *    | ModifiersOpt
  5.2455 -     *      ( Type Ident
  5.2456 -     *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  5.2457 -     *      | VOID Ident MethodDeclaratorRest
  5.2458 -     *      | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
  5.2459 -     *      | Ident ConstructorDeclaratorRest
  5.2460 -     *      | TypeParameters Ident ConstructorDeclaratorRest
  5.2461 -     *      | ClassOrInterfaceOrEnumDeclaration
  5.2462 -     *      )
  5.2463 -     *  InterfaceBodyDeclaration =
  5.2464 -     *      ";"
  5.2465 -     *    | ModifiersOpt Type Ident
  5.2466 -     *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
  5.2467 -     */
  5.2468 -    List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  5.2469 -        if (S.token() == SEMI) {
  5.2470 -            S.nextToken();
  5.2471 -            return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
  5.2472 -        } else {
  5.2473 -            String dc = S.docComment();
  5.2474 -            int pos = S.pos();
  5.2475 -            JCModifiers mods = modifiersOpt();
  5.2476 -            if (S.token() == CLASS ||
  5.2477 -                S.token() == INTERFACE ||
  5.2478 -                allowEnums && S.token() == ENUM) {
  5.2479 -                return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  5.2480 -            } else if (S.token() == LBRACE && !isInterface &&
  5.2481 -                       (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  5.2482 -                       mods.annotations.isEmpty()) {
  5.2483 -                return List.<JCTree>of(block(pos, mods.flags));
  5.2484 -            } else {
  5.2485 -                pos = S.pos();
  5.2486 -                List<JCTypeParameter> typarams = typeParametersOpt();
  5.2487 -                // Hack alert:  if there are type arguments but no Modifiers, the start
  5.2488 -                // position will be lost unless we set the Modifiers position.  There
  5.2489 -                // should be an AST node for type parameters (BugId 5005090).
  5.2490 -                if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
  5.2491 -                    mods.pos = pos;
  5.2492 -                }
  5.2493 -                Token token = S.token();
  5.2494 -                Name name = S.name();
  5.2495 -                pos = S.pos();
  5.2496 -                JCExpression type;
  5.2497 -                boolean isVoid = S.token() == VOID;
  5.2498 -                if (isVoid) {
  5.2499 -                    type = to(F.at(pos).TypeIdent(TypeTags.VOID));
  5.2500 -                    S.nextToken();
  5.2501 -                } else {
  5.2502 -                    type = type();
  5.2503 -                }
  5.2504 -                if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
  5.2505 -                    if (isInterface || name != className)
  5.2506 -                        log.error(pos, "invalid.meth.decl.ret.type.req");
  5.2507 -                    return List.of(methodDeclaratorRest(
  5.2508 -                        pos, mods, null, names.init, typarams,
  5.2509 -                        isInterface, true, dc));
  5.2510 -                } else {
  5.2511 -                    pos = S.pos();
  5.2512 -                    name = ident();
  5.2513 -                    if (S.token() == LPAREN) {
  5.2514 -                        return List.of(methodDeclaratorRest(
  5.2515 -                            pos, mods, type, name, typarams,
  5.2516 -                            isInterface, isVoid, dc));
  5.2517 -                    } else if (!isVoid && typarams.isEmpty()) {
  5.2518 -                        List<JCTree> defs =
  5.2519 -                            variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  5.2520 -                                                    new ListBuffer<JCTree>()).toList();
  5.2521 -                        storeEnd(defs.last(), S.endPos());
  5.2522 -                        accept(SEMI);
  5.2523 -                        return defs;
  5.2524 -                    } else {
  5.2525 -                        pos = S.pos();
  5.2526 -                        List<JCTree> err = isVoid
  5.2527 -                            ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  5.2528 -                                List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  5.2529 -                            : null;
  5.2530 -                        return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
  5.2531 -                    }
  5.2532 -                }
  5.2533 -            }
  5.2534 -        }
  5.2535 -    }
  5.2536 -
  5.2537 -    /** MethodDeclaratorRest =
  5.2538 -     *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  5.2539 -     *  VoidMethodDeclaratorRest =
  5.2540 -     *      FormalParameters [Throws TypeList] ( MethodBody | ";")
  5.2541 -     *  InterfaceMethodDeclaratorRest =
  5.2542 -     *      FormalParameters BracketsOpt [THROWS TypeList] ";"
  5.2543 -     *  VoidInterfaceMethodDeclaratorRest =
  5.2544 -     *      FormalParameters [THROWS TypeList] ";"
  5.2545 -     *  ConstructorDeclaratorRest =
  5.2546 -     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
  5.2547 -     */
  5.2548 -    JCTree methodDeclaratorRest(int pos,
  5.2549 -                              JCModifiers mods,
  5.2550 -                              JCExpression type,
  5.2551 -                              Name name,
  5.2552 -                              List<JCTypeParameter> typarams,
  5.2553 -                              boolean isInterface, boolean isVoid,
  5.2554 -                              String dc) {
  5.2555 -        List<JCVariableDecl> params = formalParameters();
  5.2556 -        if (!isVoid) type = bracketsOpt(type);
  5.2557 -        List<JCExpression> thrown = List.nil();
  5.2558 -        if (S.token() == THROWS) {
  5.2559 -            S.nextToken();
  5.2560 -            thrown = qualidentList();
  5.2561 -        }
  5.2562 -        JCBlock body = null;
  5.2563 -        JCExpression defaultValue;
  5.2564 -        if (S.token() == LBRACE) {
  5.2565 -            body = block();
  5.2566 -            defaultValue = null;
  5.2567 -        } else {
  5.2568 -            if (S.token() == DEFAULT) {
  5.2569 -                accept(DEFAULT);
  5.2570 -                defaultValue = annotationValue();
  5.2571 -            } else {
  5.2572 -                defaultValue = null;
  5.2573 -            }
  5.2574 -            accept(SEMI);
  5.2575 -            if (S.pos() <= errorEndPos) {
  5.2576 -                // error recovery
  5.2577 -                skip(false, true, false, false);
  5.2578 -                if (S.token() == LBRACE) {
  5.2579 -                    body = block();
  5.2580 -                }
  5.2581 -            }
  5.2582 -        }
  5.2583 -        JCMethodDecl result =
  5.2584 -            toP(F.at(pos).MethodDef(mods, name, type, typarams,
  5.2585 -                                    params, thrown,
  5.2586 -                                    body, defaultValue));
  5.2587 -        attach(result, dc);
  5.2588 -        return result;
  5.2589 -    }
  5.2590 -
  5.2591 -    /** QualidentList = Qualident {"," Qualident}
  5.2592 -     */
  5.2593 -    List<JCExpression> qualidentList() {
  5.2594 -        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  5.2595 -        ts.append(qualident());
  5.2596 -        while (S.token() == COMMA) {
  5.2597 -            S.nextToken();
  5.2598 -            ts.append(qualident());
  5.2599 -        }
  5.2600 -        return ts.toList();
  5.2601 -    }
  5.2602 -
  5.2603 -    /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  5.2604 -     */
  5.2605 -    List<JCTypeParameter> typeParametersOpt() {
  5.2606 -        if (S.token() == LT) {
  5.2607 -            checkGenerics();
  5.2608 -            ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  5.2609 -            S.nextToken();
  5.2610 -            typarams.append(typeParameter());
  5.2611 -            while (S.token() == COMMA) {
  5.2612 -                S.nextToken();
  5.2613 -                typarams.append(typeParameter());
  5.2614 -            }
  5.2615 -            accept(GT);
  5.2616 -            return typarams.toList();
  5.2617 -        } else {
  5.2618 -            return List.nil();
  5.2619 -        }
  5.2620 -    }
  5.2621 -
  5.2622 -    /** TypeParameter = TypeVariable [TypeParameterBound]
  5.2623 -     *  TypeParameterBound = EXTENDS Type {"&" Type}
  5.2624 -     *  TypeVariable = Ident
  5.2625 -     */
  5.2626 -    JCTypeParameter typeParameter() {
  5.2627 -        int pos = S.pos();
  5.2628 -        Name name = ident();
  5.2629 -        ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  5.2630 -        if (S.token() == EXTENDS) {
  5.2631 -            S.nextToken();
  5.2632 -            bounds.append(type());
  5.2633 -            while (S.token() == AMP) {
  5.2634 -                S.nextToken();
  5.2635 -                bounds.append(type());
  5.2636 -            }
  5.2637 -        }
  5.2638 -        return toP(F.at(pos).TypeParameter(name, bounds.toList()));
  5.2639 -    }
  5.2640 -
  5.2641 -    /** FormalParameters = "(" [ FormalParameterList ] ")"
  5.2642 -     *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  5.2643 -     *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  5.2644 -     */
  5.2645 -    List<JCVariableDecl> formalParameters() {
  5.2646 -        ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  5.2647 -        JCVariableDecl lastParam = null;
  5.2648 -        accept(LPAREN);
  5.2649 -        if (S.token() != RPAREN) {
  5.2650 -            params.append(lastParam = formalParameter());
  5.2651 -            while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
  5.2652 -                S.nextToken();
  5.2653 -                params.append(lastParam = formalParameter());
  5.2654 -            }
  5.2655 -        }
  5.2656 -        accept(RPAREN);
  5.2657 -        return params.toList();
  5.2658 -    }
  5.2659 -
  5.2660 -    JCModifiers optFinal(long flags) {
  5.2661 -        JCModifiers mods = modifiersOpt();
  5.2662 -        checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  5.2663 -        mods.flags |= flags;
  5.2664 -        return mods;
  5.2665 -    }
  5.2666 -
  5.2667 -    /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  5.2668 -     *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  5.2669 -     */
  5.2670 -    JCVariableDecl formalParameter() {
  5.2671 -        JCModifiers mods = optFinal(Flags.PARAMETER);
  5.2672 -        JCExpression type = type();
  5.2673 -        if (S.token() == ELLIPSIS) {
  5.2674 -            checkVarargs();
  5.2675 -            mods.flags |= Flags.VARARGS;
  5.2676 -            type = to(F.at(S.pos()).TypeArray(type));
  5.2677 -            S.nextToken();
  5.2678 -        }
  5.2679 -        return variableDeclaratorId(mods, type);
  5.2680 -    }
  5.2681 -
  5.2682 -/* ---------- auxiliary methods -------------- */
  5.2683 -
  5.2684 -    /** Check that given tree is a legal expression statement.
  5.2685 -     */
  5.2686 -    protected JCExpression checkExprStat(JCExpression t) {
  5.2687 -        switch(t.getTag()) {
  5.2688 -        case JCTree.PREINC: case JCTree.PREDEC:
  5.2689 -        case JCTree.POSTINC: case JCTree.POSTDEC:
  5.2690 -        case JCTree.ASSIGN:
  5.2691 -        case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
  5.2692 -        case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
  5.2693 -        case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
  5.2694 -        case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
  5.2695 -        case JCTree.APPLY: case JCTree.NEWCLASS:
  5.2696 -        case JCTree.ERRONEOUS:
  5.2697 -            return t;
  5.2698 -        default:
  5.2699 -            log.error(t.pos, "not.stmt");
  5.2700 -            return F.at(t.pos).Erroneous(List.<JCTree>of(t));
  5.2701 -        }
  5.2702 -    }
  5.2703 -
  5.2704 -    /** Return precedence of operator represented by token,
  5.2705 -     *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  5.2706 -     */
  5.2707 -    static int prec(Token token) {
  5.2708 -        int oc = optag(token);
  5.2709 -        return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
  5.2710 -    }
  5.2711 -
  5.2712 -    /** Return operation tag of binary operator represented by token,
  5.2713 -     *  -1 if token is not a binary operator.
  5.2714 -     */
  5.2715 -    static int optag(Token token) {
  5.2716 -        switch (token) {
  5.2717 -        case BARBAR:
  5.2718 -            return JCTree.OR;
  5.2719 -        case AMPAMP:
  5.2720 -            return JCTree.AND;
  5.2721 -        case BAR:
  5.2722 -            return JCTree.BITOR;
  5.2723 -        case BAREQ:
  5.2724 -            return JCTree.BITOR_ASG;
  5.2725 -        case CARET:
  5.2726 -            return JCTree.BITXOR;
  5.2727 -        case CARETEQ:
  5.2728 -            return JCTree.BITXOR_ASG;
  5.2729 -        case AMP:
  5.2730 -            return JCTree.BITAND;
  5.2731 -        case AMPEQ:
  5.2732 -            return JCTree.BITAND_ASG;
  5.2733 -        case EQEQ:
  5.2734 -            return JCTree.EQ;
  5.2735 -        case BANGEQ:
  5.2736 -            return JCTree.NE;
  5.2737 -        case LT:
  5.2738 -            return JCTree.LT;
  5.2739 -        case GT:
  5.2740 -            return JCTree.GT;
  5.2741 -        case LTEQ:
  5.2742 -            return JCTree.LE;
  5.2743 -        case GTEQ:
  5.2744 -            return JCTree.GE;
  5.2745 -        case LTLT:
  5.2746 -            return JCTree.SL;
  5.2747 -        case LTLTEQ:
  5.2748 -            return JCTree.SL_ASG;
  5.2749 -        case GTGT:
  5.2750 -            return JCTree.SR;
  5.2751 -        case GTGTEQ:
  5.2752 -            return JCTree.SR_ASG;
  5.2753 -        case GTGTGT:
  5.2754 -            return JCTree.USR;
  5.2755 -        case GTGTGTEQ:
  5.2756 -            return JCTree.USR_ASG;
  5.2757 -        case PLUS:
  5.2758 -            return JCTree.PLUS;
  5.2759 -        case PLUSEQ:
  5.2760 -            return JCTree.PLUS_ASG;
  5.2761 -        case SUB:
  5.2762 -            return JCTree.MINUS;
  5.2763 -        case SUBEQ:
  5.2764 -            return JCTree.MINUS_ASG;
  5.2765 -        case STAR:
  5.2766 -            return JCTree.MUL;
  5.2767 -        case STAREQ:
  5.2768 -            return JCTree.MUL_ASG;
  5.2769 -        case SLASH:
  5.2770 -            return JCTree.DIV;
  5.2771 -        case SLASHEQ:
  5.2772 -            return JCTree.DIV_ASG;
  5.2773 -        case PERCENT:
  5.2774 -            return JCTree.MOD;
  5.2775 -        case PERCENTEQ:
  5.2776 -            return JCTree.MOD_ASG;
  5.2777 -        case INSTANCEOF:
  5.2778 -            return JCTree.TYPETEST;
  5.2779 -        default:
  5.2780 -            return -1;
  5.2781 -        }
  5.2782 -    }
  5.2783 -
  5.2784 -    /** Return operation tag of unary operator represented by token,
  5.2785 -     *  -1 if token is not a binary operator.
  5.2786 -     */
  5.2787 -    static int unoptag(Token token) {
  5.2788 -        switch (token) {
  5.2789 -        case PLUS:
  5.2790 -            return JCTree.POS;
  5.2791 -        case SUB:
  5.2792 -            return JCTree.NEG;
  5.2793 -        case BANG:
  5.2794 -            return JCTree.NOT;
  5.2795 -        case TILDE:
  5.2796 -            return JCTree.COMPL;
  5.2797 -        case PLUSPLUS:
  5.2798 -            return JCTree.PREINC;
  5.2799 -        case SUBSUB:
  5.2800 -            return JCTree.PREDEC;
  5.2801 -        default:
  5.2802 -            return -1;
  5.2803 -        }
  5.2804 -    }
  5.2805 -
  5.2806 -    /** Return type tag of basic type represented by token,
  5.2807 -     *  -1 if token is not a basic type identifier.
  5.2808 -     */
  5.2809 -    static int typetag(Token token) {
  5.2810 -        switch (token) {
  5.2811 -        case BYTE:
  5.2812 -            return TypeTags.BYTE;
  5.2813 -        case CHAR:
  5.2814 -            return TypeTags.CHAR;
  5.2815 -        case SHORT:
  5.2816 -            return TypeTags.SHORT;
  5.2817 -        case INT:
  5.2818 -            return TypeTags.INT;
  5.2819 -        case LONG:
  5.2820 -            return TypeTags.LONG;
  5.2821 -        case FLOAT:
  5.2822 -            return TypeTags.FLOAT;
  5.2823 -        case DOUBLE:
  5.2824 -            return TypeTags.DOUBLE;
  5.2825 -        case BOOLEAN:
  5.2826 -            return TypeTags.BOOLEAN;
  5.2827 -        default:
  5.2828 -            return -1;
  5.2829 -        }
  5.2830 -    }
  5.2831 -
  5.2832 -    void checkGenerics() {
  5.2833 -        if (!allowGenerics) {
  5.2834 -            log.error(S.pos(), "generics.not.supported.in.source", source.name);
  5.2835 -            allowGenerics = true;
  5.2836 -        }
  5.2837 -    }
  5.2838 -    void checkVarargs() {
  5.2839 -        if (!allowVarargs) {
  5.2840 -            log.error(S.pos(), "varargs.not.supported.in.source", source.name);
  5.2841 -            allowVarargs = true;
  5.2842 -        }
  5.2843 -    }
  5.2844 -    void checkForeach() {
  5.2845 -        if (!allowForeach) {
  5.2846 -            log.error(S.pos(), "foreach.not.supported.in.source", source.name);
  5.2847 -            allowForeach = true;
  5.2848 -        }
  5.2849 -    }
  5.2850 -    void checkStaticImports() {
  5.2851 -        if (!allowStaticImport) {
  5.2852 -            log.error(S.pos(), "static.import.not.supported.in.source", source.name);
  5.2853 -            allowStaticImport = true;
  5.2854 -        }
  5.2855 -    }
  5.2856 -    void checkAnnotations() {
  5.2857 -        if (!allowAnnotations) {
  5.2858 -            log.error(S.pos(), "annotations.not.supported.in.source", source.name);
  5.2859 -            allowAnnotations = true;
  5.2860 -        }
  5.2861 -    }
  5.2862 -}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java	Tue Sep 09 10:40:50 2008 -0700
     6.3 @@ -0,0 +1,79 @@
     6.4 +/*
     6.5 + * Copyright 1999-2008 Sun Microsystems, Inc.  All Rights Reserved.
     6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.7 + *
     6.8 + * This code is free software; you can redistribute it and/or modify it
     6.9 + * under the terms of the GNU General Public License version 2 only, as
    6.10 + * published by the Free Software Foundation.  Sun designates this
    6.11 + * particular file as subject to the "Classpath" exception as provided
    6.12 + * by Sun in the LICENSE file that accompanied this code.
    6.13 + *
    6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    6.17 + * version 2 for more details (a copy is included in the LICENSE file that
    6.18 + * accompanied this code).
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License version
    6.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    6.23 + *
    6.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
    6.25 + * CA 95054 USA or visit www.sun.com if you need additional information or
    6.26 + * have any questions.
    6.27 + */
    6.28 +
    6.29 +package com.sun.tools.javac.parser;
    6.30 +
    6.31 +import com.sun.tools.javac.code.Source;
    6.32 +import com.sun.tools.javac.tree.TreeMaker;
    6.33 +import com.sun.tools.javac.util.Context;
    6.34 +import com.sun.tools.javac.util.Log;
    6.35 +import com.sun.tools.javac.util.Name;
    6.36 +import com.sun.tools.javac.util.Options;
    6.37 +
    6.38 +/**
    6.39 + * A factory for creating parsers.
    6.40 + */
    6.41 +public class ParserFactory {
    6.42 +
    6.43 +    /** The context key for the parser factory. */
    6.44 +    protected static final Context.Key<ParserFactory> parserFactoryKey = new Context.Key<ParserFactory>();
    6.45 +
    6.46 +    public static ParserFactory instance(Context context) {
    6.47 +        ParserFactory instance = context.get(parserFactoryKey);
    6.48 +        if (instance == null) {
    6.49 +            instance = new ParserFactory(context);
    6.50 +        }
    6.51 +        return instance;
    6.52 +    }
    6.53 +
    6.54 +    final TreeMaker F;
    6.55 +    final Log log;
    6.56 +    final Keywords keywords;
    6.57 +    final Source source;
    6.58 +    final Name.Table names;
    6.59 +    final Options options;
    6.60 +    final Scanner.Factory scannerFactory;
    6.61 +
    6.62 +    protected ParserFactory(Context context) {
    6.63 +        super();
    6.64 +        context.put(parserFactoryKey, this);
    6.65 +        this.F = TreeMaker.instance(context);
    6.66 +        this.log = Log.instance(context);
    6.67 +        this.names = Name.Table.instance(context);
    6.68 +        this.keywords = Keywords.instance(context);
    6.69 +        this.source = Source.instance(context);
    6.70 +        this.options = Options.instance(context);
    6.71 +        this.scannerFactory = Scanner.Factory.instance(context);
    6.72 +    }
    6.73 +
    6.74 +    public Parser newParser(CharSequence input, boolean keepDocComments, boolean keepEndPos, boolean keepLineMap) {
    6.75 +        Lexer lexer = scannerFactory.newScanner(input);
    6.76 +        if (keepEndPos) {
    6.77 +            return new EndPosParser(this, lexer, keepDocComments, keepLineMap);
    6.78 +        } else {
    6.79 +            return new JavacParser(this, lexer, keepDocComments, keepLineMap);
    6.80 +        }
    6.81 +    }
    6.82 +}
     7.1 --- a/test/tools/javac/6304921/TestLog.java	Tue Sep 09 10:28:21 2008 -0700
     7.2 +++ b/test/tools/javac/6304921/TestLog.java	Tue Sep 09 10:40:50 2008 -0700
     7.3 @@ -34,6 +34,7 @@
     7.4  import javax.tools.SimpleJavaFileObject;
     7.5  import com.sun.tools.javac.file.JavacFileManager;
     7.6  import com.sun.tools.javac.parser.Parser;
     7.7 +import com.sun.tools.javac.parser.ParserFactory;
     7.8  import com.sun.tools.javac.parser.Scanner;
     7.9  import com.sun.tools.javac.tree.JCTree;
    7.10  import com.sun.tools.javac.tree.TreeScanner;
    7.11 @@ -60,7 +61,7 @@
    7.12  
    7.13          JavacFileManager.preRegister(context);
    7.14          Scanner.Factory sfac = Scanner.Factory.instance(context);
    7.15 -        Parser.Factory pfac = Parser.Factory.instance(context);
    7.16 +        ParserFactory pfac = ParserFactory.instance(context);
    7.17  
    7.18          final String text =
    7.19                "public class Foo {\n"
    7.20 @@ -74,9 +75,9 @@
    7.21          JavaFileObject fo = new StringJavaFileObject("Foo", text);
    7.22          log.useSource(fo);
    7.23  
    7.24 -        Scanner s = sfac.newScanner(fo.getCharContent(true));
    7.25 -        Parser parser = pfac.newParser(s, false, genEndPos);
    7.26 -        JCTree.JCCompilationUnit tree = parser.compilationUnit();
    7.27 +        CharSequence cs = fo.getCharContent(true);
    7.28 +        Parser parser = pfac.newParser(cs, false, genEndPos, false);
    7.29 +        JCTree.JCCompilationUnit tree = parser.parseCompilationUnit();
    7.30          log.setEndPosTable(fo, tree.endPositions);
    7.31  
    7.32          TreeScanner ts = new LogTester(log, tree.endPositions);

mercurial