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

changeset 0
959103a6100f
child 2525
2eb010b6cb22
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Apr 27 01:34:52 2016 +0800
     1.3 @@ -0,0 +1,4184 @@
     1.4 +/*
     1.5 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package com.sun.tools.javac.parser;
    1.30 +
    1.31 +import java.util.*;
    1.32 +
    1.33 +import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
    1.34 +
    1.35 +import com.sun.tools.javac.code.*;
    1.36 +import com.sun.tools.javac.parser.Tokens.*;
    1.37 +import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
    1.38 +import com.sun.tools.javac.tree.*;
    1.39 +import com.sun.tools.javac.tree.JCTree.*;
    1.40 +import com.sun.tools.javac.util.*;
    1.41 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    1.42 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.43 +import com.sun.tools.javac.util.List;
    1.44 +
    1.45 +import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
    1.46 +import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
    1.47 +import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
    1.48 +import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
    1.49 +import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
    1.50 +import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
    1.51 +import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
    1.52 +import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
    1.53 +import static com.sun.tools.javac.tree.JCTree.Tag.*;
    1.54 +
    1.55 +/** The parser maps a token sequence into an abstract syntax
    1.56 + *  tree. It operates by recursive descent, with code derived
    1.57 + *  systematically from an LL(1) grammar. For efficiency reasons, an
    1.58 + *  operator precedence scheme is used for parsing binary operation
    1.59 + *  expressions.
    1.60 + *
    1.61 + *  <p><b>This is NOT part of any supported API.
    1.62 + *  If you write code that depends on this, you do so at your own risk.
    1.63 + *  This code and its internal interfaces are subject to change or
    1.64 + *  deletion without notice.</b>
    1.65 + */
    1.66 +public class JavacParser implements Parser {
    1.67 +
    1.68 +    /** The number of precedence levels of infix operators.
    1.69 +     */
    1.70 +    private static final int infixPrecedenceLevels = 10;
    1.71 +
    1.72 +    /** The scanner used for lexical analysis.
    1.73 +     */
    1.74 +    protected Lexer S;
    1.75 +
    1.76 +    /** The factory to be used for abstract syntax tree construction.
    1.77 +     */
    1.78 +    protected TreeMaker F;
    1.79 +
    1.80 +    /** The log to be used for error diagnostics.
    1.81 +     */
    1.82 +    private Log log;
    1.83 +
    1.84 +    /** The Source language setting. */
    1.85 +    private Source source;
    1.86 +
    1.87 +    /** The name table. */
    1.88 +    private Names names;
    1.89 +
    1.90 +    /** End position mappings container */
    1.91 +    private final AbstractEndPosTable endPosTable;
    1.92 +
    1.93 +    // Because of javac's limited lookahead, some contexts are ambiguous in
    1.94 +    // the presence of type annotations even though they are not ambiguous
    1.95 +    // in the absence of type annotations.  Consider this code:
    1.96 +    //   void m(String [] m) { }
    1.97 +    //   void m(String ... m) { }
    1.98 +    // After parsing "String", javac calls bracketsOpt which immediately
    1.99 +    // returns if the next character is not '['.  Similarly, javac can see
   1.100 +    // if the next token is ... and in that case parse an ellipsis.  But in
   1.101 +    // the presence of type annotations:
   1.102 +    //   void m(String @A [] m) { }
   1.103 +    //   void m(String @A ... m) { }
   1.104 +    // no finite lookahead is enough to determine whether to read array
   1.105 +    // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
   1.106 +    // bracketsOpt first reads all the leading annotations and only then
   1.107 +    // discovers that it needs to fail.  bracketsOpt needs a way to push
   1.108 +    // back the extra annotations that it read.  (But, bracketsOpt should
   1.109 +    // not *always* be allowed to push back extra annotations that it finds
   1.110 +    // -- in most contexts, any such extra annotation is an error.
   1.111 +    //
   1.112 +    // The following two variables permit type annotations that have
   1.113 +    // already been read to be stored for later use.  Alternate
   1.114 +    // implementations are possible but would cause much larger changes to
   1.115 +    // the parser.
   1.116 +
   1.117 +    /** Type annotations that have already been read but have not yet been used. **/
   1.118 +    private List<JCAnnotation> typeAnnotationsPushedBack = List.nil();
   1.119 +
   1.120 +    /**
   1.121 +     * If the parser notices extra annotations, then it either immediately
   1.122 +     * issues an error (if this variable is false) or places the extra
   1.123 +     * annotations in variable typeAnnotationsPushedBack (if this variable
   1.124 +     * is true).
   1.125 +     */
   1.126 +    private boolean permitTypeAnnotationsPushBack = false;
   1.127 +
   1.128 +    interface ErrorRecoveryAction {
   1.129 +        JCTree doRecover(JavacParser parser);
   1.130 +    }
   1.131 +
   1.132 +    enum BasicErrorRecoveryAction implements ErrorRecoveryAction {
   1.133 +        BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }},
   1.134 +        CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }}
   1.135 +    }
   1.136 +
   1.137 +    /** Construct a parser from a given scanner, tree factory and log.
   1.138 +     */
   1.139 +    protected JavacParser(ParserFactory fac,
   1.140 +                     Lexer S,
   1.141 +                     boolean keepDocComments,
   1.142 +                     boolean keepLineMap,
   1.143 +                     boolean keepEndPositions) {
   1.144 +        this.S = S;
   1.145 +        nextToken(); // prime the pump
   1.146 +        this.F = fac.F;
   1.147 +        this.log = fac.log;
   1.148 +        this.names = fac.names;
   1.149 +        this.source = fac.source;
   1.150 +        this.allowGenerics = source.allowGenerics();
   1.151 +        this.allowVarargs = source.allowVarargs();
   1.152 +        this.allowAsserts = source.allowAsserts();
   1.153 +        this.allowEnums = source.allowEnums();
   1.154 +        this.allowForeach = source.allowForeach();
   1.155 +        this.allowStaticImport = source.allowStaticImport();
   1.156 +        this.allowAnnotations = source.allowAnnotations();
   1.157 +        this.allowTWR = source.allowTryWithResources();
   1.158 +        this.allowDiamond = source.allowDiamond();
   1.159 +        this.allowMulticatch = source.allowMulticatch();
   1.160 +        this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
   1.161 +        this.allowLambda = source.allowLambda();
   1.162 +        this.allowMethodReferences = source.allowMethodReferences();
   1.163 +        this.allowDefaultMethods = source.allowDefaultMethods();
   1.164 +        this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
   1.165 +        this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
   1.166 +        this.allowTypeAnnotations = source.allowTypeAnnotations();
   1.167 +        this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
   1.168 +        this.keepDocComments = keepDocComments;
   1.169 +        docComments = newDocCommentTable(keepDocComments, fac);
   1.170 +        this.keepLineMap = keepLineMap;
   1.171 +        this.errorTree = F.Erroneous();
   1.172 +        endPosTable = newEndPosTable(keepEndPositions);
   1.173 +    }
   1.174 +
   1.175 +    protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
   1.176 +        return  keepEndPositions
   1.177 +                ? new SimpleEndPosTable(this)
   1.178 +                : new EmptyEndPosTable(this);
   1.179 +    }
   1.180 +
   1.181 +    protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
   1.182 +        return keepDocComments ? new LazyDocCommentTable(fac) : null;
   1.183 +    }
   1.184 +
   1.185 +    /** Switch: Should generics be recognized?
   1.186 +     */
   1.187 +    boolean allowGenerics;
   1.188 +
   1.189 +    /** Switch: Should diamond operator be recognized?
   1.190 +     */
   1.191 +    boolean allowDiamond;
   1.192 +
   1.193 +    /** Switch: Should multicatch clause be accepted?
   1.194 +     */
   1.195 +    boolean allowMulticatch;
   1.196 +
   1.197 +    /** Switch: Should varargs be recognized?
   1.198 +     */
   1.199 +    boolean allowVarargs;
   1.200 +
   1.201 +    /** Switch: should we recognize assert statements, or just give a warning?
   1.202 +     */
   1.203 +    boolean allowAsserts;
   1.204 +
   1.205 +    /** Switch: should we recognize enums, or just give a warning?
   1.206 +     */
   1.207 +    boolean allowEnums;
   1.208 +
   1.209 +    /** Switch: should we recognize foreach?
   1.210 +     */
   1.211 +    boolean allowForeach;
   1.212 +
   1.213 +    /** Switch: should we recognize foreach?
   1.214 +     */
   1.215 +    boolean allowStaticImport;
   1.216 +
   1.217 +    /** Switch: should we recognize annotations?
   1.218 +     */
   1.219 +    boolean allowAnnotations;
   1.220 +
   1.221 +    /** Switch: should we recognize try-with-resources?
   1.222 +     */
   1.223 +    boolean allowTWR;
   1.224 +
   1.225 +    /** Switch: should we fold strings?
   1.226 +     */
   1.227 +    boolean allowStringFolding;
   1.228 +
   1.229 +    /** Switch: should we recognize lambda expressions?
   1.230 +     */
   1.231 +    boolean allowLambda;
   1.232 +
   1.233 +    /** Switch: should we allow method/constructor references?
   1.234 +     */
   1.235 +    boolean allowMethodReferences;
   1.236 +
   1.237 +    /** Switch: should we allow default methods in interfaces?
   1.238 +     */
   1.239 +    boolean allowDefaultMethods;
   1.240 +
   1.241 +    /** Switch: should we allow static methods in interfaces?
   1.242 +     */
   1.243 +    boolean allowStaticInterfaceMethods;
   1.244 +
   1.245 +    /** Switch: should we allow intersection types in cast?
   1.246 +     */
   1.247 +    boolean allowIntersectionTypesInCast;
   1.248 +
   1.249 +    /** Switch: should we keep docComments?
   1.250 +     */
   1.251 +    boolean keepDocComments;
   1.252 +
   1.253 +    /** Switch: should we keep line table?
   1.254 +     */
   1.255 +    boolean keepLineMap;
   1.256 +
   1.257 +    /** Switch: should we recognize type annotations?
   1.258 +     */
   1.259 +    boolean allowTypeAnnotations;
   1.260 +
   1.261 +    /** Switch: should we allow annotations after the method type parameters?
   1.262 +     */
   1.263 +    boolean allowAnnotationsAfterTypeParams;
   1.264 +
   1.265 +    /** Switch: is "this" allowed as an identifier?
   1.266 +     * This is needed to parse receiver types.
   1.267 +     */
   1.268 +    boolean allowThisIdent;
   1.269 +
   1.270 +    /** The type of the method receiver, as specified by a first "this" parameter.
   1.271 +     */
   1.272 +    JCVariableDecl receiverParam;
   1.273 +
   1.274 +
   1.275 +    /** When terms are parsed, the mode determines which is expected:
   1.276 +     *     mode = EXPR        : an expression
   1.277 +     *     mode = TYPE        : a type
   1.278 +     *     mode = NOPARAMS    : no parameters allowed for type
   1.279 +     *     mode = TYPEARG     : type argument
   1.280 +     */
   1.281 +    static final int EXPR = 0x1;
   1.282 +    static final int TYPE = 0x2;
   1.283 +    static final int NOPARAMS = 0x4;
   1.284 +    static final int TYPEARG = 0x8;
   1.285 +    static final int DIAMOND = 0x10;
   1.286 +
   1.287 +    /** The current mode.
   1.288 +     */
   1.289 +    private int mode = 0;
   1.290 +
   1.291 +    /** The mode of the term that was parsed last.
   1.292 +     */
   1.293 +    private int lastmode = 0;
   1.294 +
   1.295 +    /* ---------- token management -------------- */
   1.296 +
   1.297 +    protected Token token;
   1.298 +
   1.299 +    public Token token() {
   1.300 +        return token;
   1.301 +    }
   1.302 +
   1.303 +    public void nextToken() {
   1.304 +        S.nextToken();
   1.305 +        token = S.token();
   1.306 +    }
   1.307 +
   1.308 +    protected boolean peekToken(Filter<TokenKind> tk) {
   1.309 +        return peekToken(0, tk);
   1.310 +    }
   1.311 +
   1.312 +    protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
   1.313 +        return tk.accepts(S.token(lookahead + 1).kind);
   1.314 +    }
   1.315 +
   1.316 +    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
   1.317 +        return peekToken(0, tk1, tk2);
   1.318 +    }
   1.319 +
   1.320 +    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
   1.321 +        return tk1.accepts(S.token(lookahead + 1).kind) &&
   1.322 +                tk2.accepts(S.token(lookahead + 2).kind);
   1.323 +    }
   1.324 +
   1.325 +    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
   1.326 +        return peekToken(0, tk1, tk2, tk3);
   1.327 +    }
   1.328 +
   1.329 +    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
   1.330 +        return tk1.accepts(S.token(lookahead + 1).kind) &&
   1.331 +                tk2.accepts(S.token(lookahead + 2).kind) &&
   1.332 +                tk3.accepts(S.token(lookahead + 3).kind);
   1.333 +    }
   1.334 +
   1.335 +    @SuppressWarnings("unchecked")
   1.336 +    protected boolean peekToken(Filter<TokenKind>... kinds) {
   1.337 +        return peekToken(0, kinds);
   1.338 +    }
   1.339 +
   1.340 +    @SuppressWarnings("unchecked")
   1.341 +    protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
   1.342 +        for (; lookahead < kinds.length ; lookahead++) {
   1.343 +            if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
   1.344 +                return false;
   1.345 +            }
   1.346 +        }
   1.347 +        return true;
   1.348 +    }
   1.349 +
   1.350 +    /* ---------- error recovery -------------- */
   1.351 +
   1.352 +    private JCErroneous errorTree;
   1.353 +
   1.354 +    /** Skip forward until a suitable stop token is found.
   1.355 +     */
   1.356 +    private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
   1.357 +         while (true) {
   1.358 +             switch (token.kind) {
   1.359 +                case SEMI:
   1.360 +                    nextToken();
   1.361 +                    return;
   1.362 +                case PUBLIC:
   1.363 +                case FINAL:
   1.364 +                case ABSTRACT:
   1.365 +                case MONKEYS_AT:
   1.366 +                case EOF:
   1.367 +                case CLASS:
   1.368 +                case INTERFACE:
   1.369 +                case ENUM:
   1.370 +                    return;
   1.371 +                case IMPORT:
   1.372 +                    if (stopAtImport)
   1.373 +                        return;
   1.374 +                    break;
   1.375 +                case LBRACE:
   1.376 +                case RBRACE:
   1.377 +                case PRIVATE:
   1.378 +                case PROTECTED:
   1.379 +                case STATIC:
   1.380 +                case TRANSIENT:
   1.381 +                case NATIVE:
   1.382 +                case VOLATILE:
   1.383 +                case SYNCHRONIZED:
   1.384 +                case STRICTFP:
   1.385 +                case LT:
   1.386 +                case BYTE:
   1.387 +                case SHORT:
   1.388 +                case CHAR:
   1.389 +                case INT:
   1.390 +                case LONG:
   1.391 +                case FLOAT:
   1.392 +                case DOUBLE:
   1.393 +                case BOOLEAN:
   1.394 +                case VOID:
   1.395 +                    if (stopAtMemberDecl)
   1.396 +                        return;
   1.397 +                    break;
   1.398 +                case UNDERSCORE:
   1.399 +                case IDENTIFIER:
   1.400 +                   if (stopAtIdentifier)
   1.401 +                        return;
   1.402 +                    break;
   1.403 +                case CASE:
   1.404 +                case DEFAULT:
   1.405 +                case IF:
   1.406 +                case FOR:
   1.407 +                case WHILE:
   1.408 +                case DO:
   1.409 +                case TRY:
   1.410 +                case SWITCH:
   1.411 +                case RETURN:
   1.412 +                case THROW:
   1.413 +                case BREAK:
   1.414 +                case CONTINUE:
   1.415 +                case ELSE:
   1.416 +                case FINALLY:
   1.417 +                case CATCH:
   1.418 +                    if (stopAtStatement)
   1.419 +                        return;
   1.420 +                    break;
   1.421 +            }
   1.422 +            nextToken();
   1.423 +        }
   1.424 +    }
   1.425 +
   1.426 +    private JCErroneous syntaxError(int pos, String key, TokenKind... args) {
   1.427 +        return syntaxError(pos, List.<JCTree>nil(), key, args);
   1.428 +    }
   1.429 +
   1.430 +    private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
   1.431 +        setErrorEndPos(pos);
   1.432 +        JCErroneous err = F.at(pos).Erroneous(errs);
   1.433 +        reportSyntaxError(err, key, (Object[])args);
   1.434 +        if (errs != null) {
   1.435 +            JCTree last = errs.last();
   1.436 +            if (last != null)
   1.437 +                storeEnd(last, pos);
   1.438 +        }
   1.439 +        return toP(err);
   1.440 +    }
   1.441 +
   1.442 +    private int errorPos = Position.NOPOS;
   1.443 +
   1.444 +    /**
   1.445 +     * Report a syntax using the given the position parameter and arguments,
   1.446 +     * unless one was already reported at the same position.
   1.447 +     */
   1.448 +    private void reportSyntaxError(int pos, String key, Object... args) {
   1.449 +        JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
   1.450 +        reportSyntaxError(diag, key, args);
   1.451 +    }
   1.452 +
   1.453 +    /**
   1.454 +     * Report a syntax error using the given DiagnosticPosition object and
   1.455 +     * arguments, unless one was already reported at the same position.
   1.456 +     */
   1.457 +    private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
   1.458 +        int pos = diagPos.getPreferredPosition();
   1.459 +        if (pos > S.errPos() || pos == Position.NOPOS) {
   1.460 +            if (token.kind == EOF) {
   1.461 +                error(diagPos, "premature.eof");
   1.462 +            } else {
   1.463 +                error(diagPos, key, args);
   1.464 +            }
   1.465 +        }
   1.466 +        S.errPos(pos);
   1.467 +        if (token.pos == errorPos)
   1.468 +            nextToken(); // guarantee progress
   1.469 +        errorPos = token.pos;
   1.470 +    }
   1.471 +
   1.472 +
   1.473 +    /** Generate a syntax error at current position unless one was already
   1.474 +     *  reported at the same position.
   1.475 +     */
   1.476 +    private JCErroneous syntaxError(String key) {
   1.477 +        return syntaxError(token.pos, key);
   1.478 +    }
   1.479 +
   1.480 +    /** Generate a syntax error at current position unless one was
   1.481 +     *  already reported at the same position.
   1.482 +     */
   1.483 +    private JCErroneous syntaxError(String key, TokenKind arg) {
   1.484 +        return syntaxError(token.pos, key, arg);
   1.485 +    }
   1.486 +
   1.487 +    /** If next input token matches given token, skip it, otherwise report
   1.488 +     *  an error.
   1.489 +     */
   1.490 +    public void accept(TokenKind tk) {
   1.491 +        if (token.kind == tk) {
   1.492 +            nextToken();
   1.493 +        } else {
   1.494 +            setErrorEndPos(token.pos);
   1.495 +            reportSyntaxError(S.prevToken().endPos, "expected", tk);
   1.496 +        }
   1.497 +    }
   1.498 +
   1.499 +    /** Report an illegal start of expression/type error at given position.
   1.500 +     */
   1.501 +    JCExpression illegal(int pos) {
   1.502 +        setErrorEndPos(pos);
   1.503 +        if ((mode & EXPR) != 0)
   1.504 +            return syntaxError(pos, "illegal.start.of.expr");
   1.505 +        else
   1.506 +            return syntaxError(pos, "illegal.start.of.type");
   1.507 +
   1.508 +    }
   1.509 +
   1.510 +    /** Report an illegal start of expression/type error at current position.
   1.511 +     */
   1.512 +    JCExpression illegal() {
   1.513 +        return illegal(token.pos);
   1.514 +    }
   1.515 +
   1.516 +    /** Diagnose a modifier flag from the set, if any. */
   1.517 +    void checkNoMods(long mods) {
   1.518 +        if (mods != 0) {
   1.519 +            long lowestMod = mods & -mods;
   1.520 +            error(token.pos, "mod.not.allowed.here",
   1.521 +                      Flags.asFlagSet(lowestMod));
   1.522 +        }
   1.523 +    }
   1.524 +
   1.525 +/* ---------- doc comments --------- */
   1.526 +
   1.527 +    /** A table to store all documentation comments
   1.528 +     *  indexed by the tree nodes they refer to.
   1.529 +     *  defined only if option flag keepDocComment is set.
   1.530 +     */
   1.531 +    private final DocCommentTable docComments;
   1.532 +
   1.533 +    /** Make an entry into docComments hashtable,
   1.534 +     *  provided flag keepDocComments is set and given doc comment is non-null.
   1.535 +     *  @param tree   The tree to be used as index in the hashtable
   1.536 +     *  @param dc     The doc comment to associate with the tree, or null.
   1.537 +     */
   1.538 +    void attach(JCTree tree, Comment dc) {
   1.539 +        if (keepDocComments && dc != null) {
   1.540 +//          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
   1.541 +            docComments.putComment(tree, dc);
   1.542 +        }
   1.543 +    }
   1.544 +
   1.545 +/* -------- source positions ------- */
   1.546 +
   1.547 +    private void setErrorEndPos(int errPos) {
   1.548 +        endPosTable.setErrorEndPos(errPos);
   1.549 +    }
   1.550 +
   1.551 +    private void storeEnd(JCTree tree, int endpos) {
   1.552 +        endPosTable.storeEnd(tree, endpos);
   1.553 +    }
   1.554 +
   1.555 +    private <T extends JCTree> T to(T t) {
   1.556 +        return endPosTable.to(t);
   1.557 +    }
   1.558 +
   1.559 +    private <T extends JCTree> T toP(T t) {
   1.560 +        return endPosTable.toP(t);
   1.561 +    }
   1.562 +
   1.563 +    /** Get the start position for a tree node.  The start position is
   1.564 +     * defined to be the position of the first character of the first
   1.565 +     * token of the node's source text.
   1.566 +     * @param tree  The tree node
   1.567 +     */
   1.568 +    public int getStartPos(JCTree tree) {
   1.569 +        return TreeInfo.getStartPos(tree);
   1.570 +    }
   1.571 +
   1.572 +    /**
   1.573 +     * Get the end position for a tree node.  The end position is
   1.574 +     * defined to be the position of the last character of the last
   1.575 +     * token of the node's source text.  Returns Position.NOPOS if end
   1.576 +     * positions are not generated or the position is otherwise not
   1.577 +     * found.
   1.578 +     * @param tree  The tree node
   1.579 +     */
   1.580 +    public int getEndPos(JCTree tree) {
   1.581 +        return endPosTable.getEndPos(tree);
   1.582 +    }
   1.583 +
   1.584 +
   1.585 +
   1.586 +/* ---------- parsing -------------- */
   1.587 +
   1.588 +    /**
   1.589 +     * Ident = IDENTIFIER
   1.590 +     */
   1.591 +    Name ident() {
   1.592 +        if (token.kind == IDENTIFIER) {
   1.593 +            Name name = token.name();
   1.594 +            nextToken();
   1.595 +            return name;
   1.596 +        } else if (token.kind == ASSERT) {
   1.597 +            if (allowAsserts) {
   1.598 +                error(token.pos, "assert.as.identifier");
   1.599 +                nextToken();
   1.600 +                return names.error;
   1.601 +            } else {
   1.602 +                warning(token.pos, "assert.as.identifier");
   1.603 +                Name name = token.name();
   1.604 +                nextToken();
   1.605 +                return name;
   1.606 +            }
   1.607 +        } else if (token.kind == ENUM) {
   1.608 +            if (allowEnums) {
   1.609 +                error(token.pos, "enum.as.identifier");
   1.610 +                nextToken();
   1.611 +                return names.error;
   1.612 +            } else {
   1.613 +                warning(token.pos, "enum.as.identifier");
   1.614 +                Name name = token.name();
   1.615 +                nextToken();
   1.616 +                return name;
   1.617 +            }
   1.618 +        } else if (token.kind == THIS) {
   1.619 +            if (allowThisIdent) {
   1.620 +                // Make sure we're using a supported source version.
   1.621 +                checkTypeAnnotations();
   1.622 +                Name name = token.name();
   1.623 +                nextToken();
   1.624 +                return name;
   1.625 +            } else {
   1.626 +                error(token.pos, "this.as.identifier");
   1.627 +                nextToken();
   1.628 +                return names.error;
   1.629 +            }
   1.630 +        } else if (token.kind == UNDERSCORE) {
   1.631 +            warning(token.pos, "underscore.as.identifier");
   1.632 +            Name name = token.name();
   1.633 +            nextToken();
   1.634 +            return name;
   1.635 +        } else {
   1.636 +            accept(IDENTIFIER);
   1.637 +            return names.error;
   1.638 +        }
   1.639 +    }
   1.640 +
   1.641 +    /**
   1.642 +     * Qualident = Ident { DOT [Annotations] Ident }
   1.643 +     */
   1.644 +    public JCExpression qualident(boolean allowAnnos) {
   1.645 +        JCExpression t = toP(F.at(token.pos).Ident(ident()));
   1.646 +        while (token.kind == DOT) {
   1.647 +            int pos = token.pos;
   1.648 +            nextToken();
   1.649 +            List<JCAnnotation> tyannos = null;
   1.650 +            if (allowAnnos) {
   1.651 +                tyannos = typeAnnotationsOpt();
   1.652 +            }
   1.653 +            t = toP(F.at(pos).Select(t, ident()));
   1.654 +            if (tyannos != null && tyannos.nonEmpty()) {
   1.655 +                t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
   1.656 +            }
   1.657 +        }
   1.658 +        return t;
   1.659 +    }
   1.660 +
   1.661 +    JCExpression literal(Name prefix) {
   1.662 +        return literal(prefix, token.pos);
   1.663 +    }
   1.664 +
   1.665 +    /**
   1.666 +     * Literal =
   1.667 +     *     INTLITERAL
   1.668 +     *   | LONGLITERAL
   1.669 +     *   | FLOATLITERAL
   1.670 +     *   | DOUBLELITERAL
   1.671 +     *   | CHARLITERAL
   1.672 +     *   | STRINGLITERAL
   1.673 +     *   | TRUE
   1.674 +     *   | FALSE
   1.675 +     *   | NULL
   1.676 +     */
   1.677 +    JCExpression literal(Name prefix, int pos) {
   1.678 +        JCExpression t = errorTree;
   1.679 +        switch (token.kind) {
   1.680 +        case INTLITERAL:
   1.681 +            try {
   1.682 +                t = F.at(pos).Literal(
   1.683 +                    TypeTag.INT,
   1.684 +                    Convert.string2int(strval(prefix), token.radix()));
   1.685 +            } catch (NumberFormatException ex) {
   1.686 +                error(token.pos, "int.number.too.large", strval(prefix));
   1.687 +            }
   1.688 +            break;
   1.689 +        case LONGLITERAL:
   1.690 +            try {
   1.691 +                t = F.at(pos).Literal(
   1.692 +                    TypeTag.LONG,
   1.693 +                    new Long(Convert.string2long(strval(prefix), token.radix())));
   1.694 +            } catch (NumberFormatException ex) {
   1.695 +                error(token.pos, "int.number.too.large", strval(prefix));
   1.696 +            }
   1.697 +            break;
   1.698 +        case FLOATLITERAL: {
   1.699 +            String proper = token.radix() == 16 ?
   1.700 +                    ("0x"+ token.stringVal()) :
   1.701 +                    token.stringVal();
   1.702 +            Float n;
   1.703 +            try {
   1.704 +                n = Float.valueOf(proper);
   1.705 +            } catch (NumberFormatException ex) {
   1.706 +                // error already reported in scanner
   1.707 +                n = Float.NaN;
   1.708 +            }
   1.709 +            if (n.floatValue() == 0.0f && !isZero(proper))
   1.710 +                error(token.pos, "fp.number.too.small");
   1.711 +            else if (n.floatValue() == Float.POSITIVE_INFINITY)
   1.712 +                error(token.pos, "fp.number.too.large");
   1.713 +            else
   1.714 +                t = F.at(pos).Literal(TypeTag.FLOAT, n);
   1.715 +            break;
   1.716 +        }
   1.717 +        case DOUBLELITERAL: {
   1.718 +            String proper = token.radix() == 16 ?
   1.719 +                    ("0x"+ token.stringVal()) :
   1.720 +                    token.stringVal();
   1.721 +            Double n;
   1.722 +            try {
   1.723 +                n = Double.valueOf(proper);
   1.724 +            } catch (NumberFormatException ex) {
   1.725 +                // error already reported in scanner
   1.726 +                n = Double.NaN;
   1.727 +            }
   1.728 +            if (n.doubleValue() == 0.0d && !isZero(proper))
   1.729 +                error(token.pos, "fp.number.too.small");
   1.730 +            else if (n.doubleValue() == Double.POSITIVE_INFINITY)
   1.731 +                error(token.pos, "fp.number.too.large");
   1.732 +            else
   1.733 +                t = F.at(pos).Literal(TypeTag.DOUBLE, n);
   1.734 +            break;
   1.735 +        }
   1.736 +        case CHARLITERAL:
   1.737 +            t = F.at(pos).Literal(
   1.738 +                TypeTag.CHAR,
   1.739 +                token.stringVal().charAt(0) + 0);
   1.740 +            break;
   1.741 +        case STRINGLITERAL:
   1.742 +            t = F.at(pos).Literal(
   1.743 +                TypeTag.CLASS,
   1.744 +                token.stringVal());
   1.745 +            break;
   1.746 +        case TRUE: case FALSE:
   1.747 +            t = F.at(pos).Literal(
   1.748 +                TypeTag.BOOLEAN,
   1.749 +                (token.kind == TRUE ? 1 : 0));
   1.750 +            break;
   1.751 +        case NULL:
   1.752 +            t = F.at(pos).Literal(
   1.753 +                TypeTag.BOT,
   1.754 +                null);
   1.755 +            break;
   1.756 +        default:
   1.757 +            Assert.error();
   1.758 +        }
   1.759 +        if (t == errorTree)
   1.760 +            t = F.at(pos).Erroneous();
   1.761 +        storeEnd(t, token.endPos);
   1.762 +        nextToken();
   1.763 +        return t;
   1.764 +    }
   1.765 +    //where
   1.766 +        boolean isZero(String s) {
   1.767 +            char[] cs = s.toCharArray();
   1.768 +            int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
   1.769 +            int i = ((base==16) ? 2 : 0);
   1.770 +            while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
   1.771 +            return !(i < cs.length && (Character.digit(cs[i], base) > 0));
   1.772 +        }
   1.773 +
   1.774 +        String strval(Name prefix) {
   1.775 +            String s = token.stringVal();
   1.776 +            return prefix.isEmpty() ? s : prefix + s;
   1.777 +        }
   1.778 +
   1.779 +    /** terms can be either expressions or types.
   1.780 +     */
   1.781 +    public JCExpression parseExpression() {
   1.782 +        return term(EXPR);
   1.783 +    }
   1.784 +
   1.785 +    /**
   1.786 +     * parses (optional) type annotations followed by a type. If the
   1.787 +     * annotations are present before the type and are not consumed during array
   1.788 +     * parsing, this method returns a {@link JCAnnotatedType} consisting of
   1.789 +     * these annotations and the underlying type. Otherwise, it returns the
   1.790 +     * underlying type.
   1.791 +     *
   1.792 +     * <p>
   1.793 +     *
   1.794 +     * Note that this method sets {@code mode} to {@code TYPE} first, before
   1.795 +     * parsing annotations.
   1.796 +     */
   1.797 +    public JCExpression parseType() {
   1.798 +        List<JCAnnotation> annotations = typeAnnotationsOpt();
   1.799 +        return parseType(annotations);
   1.800 +    }
   1.801 +
   1.802 +    public JCExpression parseType(List<JCAnnotation> annotations) {
   1.803 +        JCExpression result = unannotatedType();
   1.804 +
   1.805 +        if (annotations.nonEmpty()) {
   1.806 +            result = insertAnnotationsToMostInner(result, annotations, false);
   1.807 +        }
   1.808 +
   1.809 +        return result;
   1.810 +    }
   1.811 +
   1.812 +    public JCExpression unannotatedType() {
   1.813 +        return term(TYPE);
   1.814 +    }
   1.815 +
   1.816 +    JCExpression term(int newmode) {
   1.817 +        int prevmode = mode;
   1.818 +        mode = newmode;
   1.819 +        JCExpression t = term();
   1.820 +        lastmode = mode;
   1.821 +        mode = prevmode;
   1.822 +        return t;
   1.823 +    }
   1.824 +
   1.825 +    /**
   1.826 +     *  {@literal
   1.827 +     *  Expression = Expression1 [ExpressionRest]
   1.828 +     *  ExpressionRest = [AssignmentOperator Expression1]
   1.829 +     *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
   1.830 +     *                       "&=" | "|=" | "^=" |
   1.831 +     *                       "%=" | "<<=" | ">>=" | ">>>="
   1.832 +     *  Type = Type1
   1.833 +     *  TypeNoParams = TypeNoParams1
   1.834 +     *  StatementExpression = Expression
   1.835 +     *  ConstantExpression = Expression
   1.836 +     *  }
   1.837 +     */
   1.838 +    JCExpression term() {
   1.839 +        JCExpression t = term1();
   1.840 +        if ((mode & EXPR) != 0 &&
   1.841 +            token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0)
   1.842 +            return termRest(t);
   1.843 +        else
   1.844 +            return t;
   1.845 +    }
   1.846 +
   1.847 +    JCExpression termRest(JCExpression t) {
   1.848 +        switch (token.kind) {
   1.849 +        case EQ: {
   1.850 +            int pos = token.pos;
   1.851 +            nextToken();
   1.852 +            mode = EXPR;
   1.853 +            JCExpression t1 = term();
   1.854 +            return toP(F.at(pos).Assign(t, t1));
   1.855 +        }
   1.856 +        case PLUSEQ:
   1.857 +        case SUBEQ:
   1.858 +        case STAREQ:
   1.859 +        case SLASHEQ:
   1.860 +        case PERCENTEQ:
   1.861 +        case AMPEQ:
   1.862 +        case BAREQ:
   1.863 +        case CARETEQ:
   1.864 +        case LTLTEQ:
   1.865 +        case GTGTEQ:
   1.866 +        case GTGTGTEQ:
   1.867 +            int pos = token.pos;
   1.868 +            TokenKind tk = token.kind;
   1.869 +            nextToken();
   1.870 +            mode = EXPR;
   1.871 +            JCExpression t1 = term();
   1.872 +            return F.at(pos).Assignop(optag(tk), t, t1);
   1.873 +        default:
   1.874 +            return t;
   1.875 +        }
   1.876 +    }
   1.877 +
   1.878 +    /** Expression1   = Expression2 [Expression1Rest]
   1.879 +     *  Type1         = Type2
   1.880 +     *  TypeNoParams1 = TypeNoParams2
   1.881 +     */
   1.882 +    JCExpression term1() {
   1.883 +        JCExpression t = term2();
   1.884 +        if ((mode & EXPR) != 0 && token.kind == QUES) {
   1.885 +            mode = EXPR;
   1.886 +            return term1Rest(t);
   1.887 +        } else {
   1.888 +            return t;
   1.889 +        }
   1.890 +    }
   1.891 +
   1.892 +    /** Expression1Rest = ["?" Expression ":" Expression1]
   1.893 +     */
   1.894 +    JCExpression term1Rest(JCExpression t) {
   1.895 +        if (token.kind == QUES) {
   1.896 +            int pos = token.pos;
   1.897 +            nextToken();
   1.898 +            JCExpression t1 = term();
   1.899 +            accept(COLON);
   1.900 +            JCExpression t2 = term1();
   1.901 +            return F.at(pos).Conditional(t, t1, t2);
   1.902 +        } else {
   1.903 +            return t;
   1.904 +        }
   1.905 +    }
   1.906 +
   1.907 +    /** Expression2   = Expression3 [Expression2Rest]
   1.908 +     *  Type2         = Type3
   1.909 +     *  TypeNoParams2 = TypeNoParams3
   1.910 +     */
   1.911 +    JCExpression term2() {
   1.912 +        JCExpression t = term3();
   1.913 +        if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) {
   1.914 +            mode = EXPR;
   1.915 +            return term2Rest(t, TreeInfo.orPrec);
   1.916 +        } else {
   1.917 +            return t;
   1.918 +        }
   1.919 +    }
   1.920 +
   1.921 +    /*  Expression2Rest = {infixop Expression3}
   1.922 +     *                  | Expression3 instanceof Type
   1.923 +     *  infixop         = "||"
   1.924 +     *                  | "&&"
   1.925 +     *                  | "|"
   1.926 +     *                  | "^"
   1.927 +     *                  | "&"
   1.928 +     *                  | "==" | "!="
   1.929 +     *                  | "<" | ">" | "<=" | ">="
   1.930 +     *                  | "<<" | ">>" | ">>>"
   1.931 +     *                  | "+" | "-"
   1.932 +     *                  | "*" | "/" | "%"
   1.933 +     */
   1.934 +    JCExpression term2Rest(JCExpression t, int minprec) {
   1.935 +        JCExpression[] odStack = newOdStack();
   1.936 +        Token[] opStack = newOpStack();
   1.937 +
   1.938 +        // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
   1.939 +        int top = 0;
   1.940 +        odStack[0] = t;
   1.941 +        int startPos = token.pos;
   1.942 +        Token topOp = Tokens.DUMMY;
   1.943 +        while (prec(token.kind) >= minprec) {
   1.944 +            opStack[top] = topOp;
   1.945 +            top++;
   1.946 +            topOp = token;
   1.947 +            nextToken();
   1.948 +            odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
   1.949 +            while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
   1.950 +                odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
   1.951 +                                        odStack[top]);
   1.952 +                top--;
   1.953 +                topOp = opStack[top];
   1.954 +            }
   1.955 +        }
   1.956 +        Assert.check(top == 0);
   1.957 +        t = odStack[0];
   1.958 +
   1.959 +        if (t.hasTag(JCTree.Tag.PLUS)) {
   1.960 +            StringBuilder buf = foldStrings(t);
   1.961 +            if (buf != null) {
   1.962 +                t = toP(F.at(startPos).Literal(TypeTag.CLASS, buf.toString()));
   1.963 +            }
   1.964 +        }
   1.965 +
   1.966 +        odStackSupply.add(odStack);
   1.967 +        opStackSupply.add(opStack);
   1.968 +        return t;
   1.969 +    }
   1.970 +    //where
   1.971 +        /** Construct a binary or type test node.
   1.972 +         */
   1.973 +        private JCExpression makeOp(int pos,
   1.974 +                                    TokenKind topOp,
   1.975 +                                    JCExpression od1,
   1.976 +                                    JCExpression od2)
   1.977 +        {
   1.978 +            if (topOp == INSTANCEOF) {
   1.979 +                return F.at(pos).TypeTest(od1, od2);
   1.980 +            } else {
   1.981 +                return F.at(pos).Binary(optag(topOp), od1, od2);
   1.982 +            }
   1.983 +        }
   1.984 +        /** If tree is a concatenation of string literals, replace it
   1.985 +         *  by a single literal representing the concatenated string.
   1.986 +         */
   1.987 +        protected StringBuilder foldStrings(JCTree tree) {
   1.988 +            if (!allowStringFolding)
   1.989 +                return null;
   1.990 +            List<String> buf = List.nil();
   1.991 +            while (true) {
   1.992 +                if (tree.hasTag(LITERAL)) {
   1.993 +                    JCLiteral lit = (JCLiteral) tree;
   1.994 +                    if (lit.typetag == TypeTag.CLASS) {
   1.995 +                        StringBuilder sbuf =
   1.996 +                            new StringBuilder((String)lit.value);
   1.997 +                        while (buf.nonEmpty()) {
   1.998 +                            sbuf.append(buf.head);
   1.999 +                            buf = buf.tail;
  1.1000 +                        }
  1.1001 +                        return sbuf;
  1.1002 +                    }
  1.1003 +                } else if (tree.hasTag(JCTree.Tag.PLUS)) {
  1.1004 +                    JCBinary op = (JCBinary)tree;
  1.1005 +                    if (op.rhs.hasTag(LITERAL)) {
  1.1006 +                        JCLiteral lit = (JCLiteral) op.rhs;
  1.1007 +                        if (lit.typetag == TypeTag.CLASS) {
  1.1008 +                            buf = buf.prepend((String) lit.value);
  1.1009 +                            tree = op.lhs;
  1.1010 +                            continue;
  1.1011 +                        }
  1.1012 +                    }
  1.1013 +                }
  1.1014 +                return null;
  1.1015 +            }
  1.1016 +        }
  1.1017 +
  1.1018 +        /** optimization: To save allocating a new operand/operator stack
  1.1019 +         *  for every binary operation, we use supplys.
  1.1020 +         */
  1.1021 +        ArrayList<JCExpression[]> odStackSupply = new ArrayList<JCExpression[]>();
  1.1022 +        ArrayList<Token[]> opStackSupply = new ArrayList<Token[]>();
  1.1023 +
  1.1024 +        private JCExpression[] newOdStack() {
  1.1025 +            if (odStackSupply.isEmpty())
  1.1026 +                return new JCExpression[infixPrecedenceLevels + 1];
  1.1027 +            return odStackSupply.remove(odStackSupply.size() - 1);
  1.1028 +        }
  1.1029 +
  1.1030 +        private Token[] newOpStack() {
  1.1031 +            if (opStackSupply.isEmpty())
  1.1032 +                return new Token[infixPrecedenceLevels + 1];
  1.1033 +            return opStackSupply.remove(opStackSupply.size() - 1);
  1.1034 +        }
  1.1035 +
  1.1036 +    /**
  1.1037 +     *  Expression3    = PrefixOp Expression3
  1.1038 +     *                 | "(" Expr | TypeNoParams ")" Expression3
  1.1039 +     *                 | Primary {Selector} {PostfixOp}
  1.1040 +     *
  1.1041 +     *  {@literal
  1.1042 +     *  Primary        = "(" Expression ")"
  1.1043 +     *                 | Literal
  1.1044 +     *                 | [TypeArguments] THIS [Arguments]
  1.1045 +     *                 | [TypeArguments] SUPER SuperSuffix
  1.1046 +     *                 | NEW [TypeArguments] Creator
  1.1047 +     *                 | "(" Arguments ")" "->" ( Expression | Block )
  1.1048 +     *                 | Ident "->" ( Expression | Block )
  1.1049 +     *                 | [Annotations] Ident { "." [Annotations] Ident }
  1.1050 +     *                 | Expression3 MemberReferenceSuffix
  1.1051 +     *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
  1.1052 +     *                   | Arguments
  1.1053 +     *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
  1.1054 +     *                   ]
  1.1055 +     *                 | BasicType BracketsOpt "." CLASS
  1.1056 +     *  }
  1.1057 +     *
  1.1058 +     *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
  1.1059 +     *  PostfixOp      = "++" | "--"
  1.1060 +     *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
  1.1061 +     *                 | BasicType
  1.1062 +     *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
  1.1063 +     *  Selector       = "." [TypeArguments] Ident [Arguments]
  1.1064 +     *                 | "." THIS
  1.1065 +     *                 | "." [TypeArguments] SUPER SuperSuffix
  1.1066 +     *                 | "." NEW [TypeArguments] InnerCreator
  1.1067 +     *                 | "[" Expression "]"
  1.1068 +     *  TypeSelector   = "." Ident [TypeArguments]
  1.1069 +     *  SuperSuffix    = Arguments | "." Ident [Arguments]
  1.1070 +     */
  1.1071 +    protected JCExpression term3() {
  1.1072 +        int pos = token.pos;
  1.1073 +        JCExpression t;
  1.1074 +        List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
  1.1075 +        switch (token.kind) {
  1.1076 +        case QUES:
  1.1077 +            if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
  1.1078 +                mode = TYPE;
  1.1079 +                return typeArgument();
  1.1080 +            } else
  1.1081 +                return illegal();
  1.1082 +        case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
  1.1083 +            if (typeArgs == null && (mode & EXPR) != 0) {
  1.1084 +                TokenKind tk = token.kind;
  1.1085 +                nextToken();
  1.1086 +                mode = EXPR;
  1.1087 +                if (tk == SUB &&
  1.1088 +                    (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
  1.1089 +                    token.radix() == 10) {
  1.1090 +                    mode = EXPR;
  1.1091 +                    t = literal(names.hyphen, pos);
  1.1092 +                } else {
  1.1093 +                    t = term3();
  1.1094 +                    return F.at(pos).Unary(unoptag(tk), t);
  1.1095 +                }
  1.1096 +            } else return illegal();
  1.1097 +            break;
  1.1098 +        case LPAREN:
  1.1099 +            if (typeArgs == null && (mode & EXPR) != 0) {
  1.1100 +                ParensResult pres = analyzeParens();
  1.1101 +                switch (pres) {
  1.1102 +                    case CAST:
  1.1103 +                       accept(LPAREN);
  1.1104 +                       mode = TYPE;
  1.1105 +                       int pos1 = pos;
  1.1106 +                       List<JCExpression> targets = List.of(t = term3());
  1.1107 +                       while (token.kind == AMP) {
  1.1108 +                           checkIntersectionTypesInCast();
  1.1109 +                           accept(AMP);
  1.1110 +                           targets = targets.prepend(term3());
  1.1111 +                       }
  1.1112 +                       if (targets.length() > 1) {
  1.1113 +                           t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
  1.1114 +                       }
  1.1115 +                       accept(RPAREN);
  1.1116 +                       mode = EXPR;
  1.1117 +                       JCExpression t1 = term3();
  1.1118 +                       return F.at(pos).TypeCast(t, t1);
  1.1119 +                    case IMPLICIT_LAMBDA:
  1.1120 +                    case EXPLICIT_LAMBDA:
  1.1121 +                        t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
  1.1122 +                        break;
  1.1123 +                    default: //PARENS
  1.1124 +                        accept(LPAREN);
  1.1125 +                        mode = EXPR;
  1.1126 +                        t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec)));
  1.1127 +                        accept(RPAREN);
  1.1128 +                        t = toP(F.at(pos).Parens(t));
  1.1129 +                        break;
  1.1130 +                }
  1.1131 +            } else {
  1.1132 +                return illegal();
  1.1133 +            }
  1.1134 +            break;
  1.1135 +        case THIS:
  1.1136 +            if ((mode & EXPR) != 0) {
  1.1137 +                mode = EXPR;
  1.1138 +                t = to(F.at(pos).Ident(names._this));
  1.1139 +                nextToken();
  1.1140 +                if (typeArgs == null)
  1.1141 +                    t = argumentsOpt(null, t);
  1.1142 +                else
  1.1143 +                    t = arguments(typeArgs, t);
  1.1144 +                typeArgs = null;
  1.1145 +            } else return illegal();
  1.1146 +            break;
  1.1147 +        case SUPER:
  1.1148 +            if ((mode & EXPR) != 0) {
  1.1149 +                mode = EXPR;
  1.1150 +                t = to(F.at(pos).Ident(names._super));
  1.1151 +                t = superSuffix(typeArgs, t);
  1.1152 +                typeArgs = null;
  1.1153 +            } else return illegal();
  1.1154 +            break;
  1.1155 +        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
  1.1156 +        case CHARLITERAL: case STRINGLITERAL:
  1.1157 +        case TRUE: case FALSE: case NULL:
  1.1158 +            if (typeArgs == null && (mode & EXPR) != 0) {
  1.1159 +                mode = EXPR;
  1.1160 +                t = literal(names.empty);
  1.1161 +            } else return illegal();
  1.1162 +            break;
  1.1163 +        case NEW:
  1.1164 +            if (typeArgs != null) return illegal();
  1.1165 +            if ((mode & EXPR) != 0) {
  1.1166 +                mode = EXPR;
  1.1167 +                nextToken();
  1.1168 +                if (token.kind == LT) typeArgs = typeArguments(false);
  1.1169 +                t = creator(pos, typeArgs);
  1.1170 +                typeArgs = null;
  1.1171 +            } else return illegal();
  1.1172 +            break;
  1.1173 +        case MONKEYS_AT:
  1.1174 +            // Only annotated cast types and method references are valid
  1.1175 +            List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  1.1176 +            if (typeAnnos.isEmpty()) {
  1.1177 +                // else there would be no '@'
  1.1178 +                throw new AssertionError("Expected type annotations, but found none!");
  1.1179 +            }
  1.1180 +
  1.1181 +            JCExpression expr = term3();
  1.1182 +
  1.1183 +            if ((mode & TYPE) == 0) {
  1.1184 +                // Type annotations on class literals no longer legal
  1.1185 +                switch (expr.getTag()) {
  1.1186 +                case REFERENCE: {
  1.1187 +                    JCMemberReference mref = (JCMemberReference) expr;
  1.1188 +                    mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
  1.1189 +                    t = mref;
  1.1190 +                    break;
  1.1191 +                }
  1.1192 +                case SELECT: {
  1.1193 +                    JCFieldAccess sel = (JCFieldAccess) expr;
  1.1194 +
  1.1195 +                    if (sel.name != names._class) {
  1.1196 +                        return illegal();
  1.1197 +                    } else {
  1.1198 +                        log.error(token.pos, "no.annotations.on.dot.class");
  1.1199 +                        return expr;
  1.1200 +                    }
  1.1201 +                }
  1.1202 +                default:
  1.1203 +                    return illegal(typeAnnos.head.pos);
  1.1204 +                }
  1.1205 +
  1.1206 +            } else {
  1.1207 +                // Type annotations targeting a cast
  1.1208 +                t = insertAnnotationsToMostInner(expr, typeAnnos, false);
  1.1209 +            }
  1.1210 +            break;
  1.1211 +        case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
  1.1212 +            if (typeArgs != null) return illegal();
  1.1213 +            if ((mode & EXPR) != 0 && peekToken(ARROW)) {
  1.1214 +                t = lambdaExpressionOrStatement(false, false, pos);
  1.1215 +            } else {
  1.1216 +                t = toP(F.at(token.pos).Ident(ident()));
  1.1217 +                loop: while (true) {
  1.1218 +                    pos = token.pos;
  1.1219 +                    final List<JCAnnotation> annos = typeAnnotationsOpt();
  1.1220 +
  1.1221 +                    // need to report an error later if LBRACKET is for array
  1.1222 +                    // index access rather than array creation level
  1.1223 +                    if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
  1.1224 +                        return illegal(annos.head.pos);
  1.1225 +
  1.1226 +                    switch (token.kind) {
  1.1227 +                    case LBRACKET:
  1.1228 +                        nextToken();
  1.1229 +                        if (token.kind == RBRACKET) {
  1.1230 +                            nextToken();
  1.1231 +                            t = bracketsOpt(t);
  1.1232 +                            t = toP(F.at(pos).TypeArray(t));
  1.1233 +                            if (annos.nonEmpty()) {
  1.1234 +                                t = toP(F.at(pos).AnnotatedType(annos, t));
  1.1235 +                            }
  1.1236 +                            // .class is only allowed if there were no annotations
  1.1237 +                            JCExpression nt = bracketsSuffix(t);
  1.1238 +                            if (nt != t && (annos.nonEmpty() || TreeInfo.containsTypeAnnotation(t))) {
  1.1239 +                                // t and nt are different if bracketsSuffix parsed a .class.
  1.1240 +                                // The check for nonEmpty covers the case when the whole array is annotated.
  1.1241 +                                // Helper method isAnnotated looks for annos deeply within t.
  1.1242 +                                syntaxError("no.annotations.on.dot.class");
  1.1243 +                            }
  1.1244 +                            t = nt;
  1.1245 +                        } else {
  1.1246 +                            if ((mode & EXPR) != 0) {
  1.1247 +                                mode = EXPR;
  1.1248 +                                JCExpression t1 = term();
  1.1249 +                                if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1.1250 +                                t = to(F.at(pos).Indexed(t, t1));
  1.1251 +                            }
  1.1252 +                            accept(RBRACKET);
  1.1253 +                        }
  1.1254 +                        break loop;
  1.1255 +                    case LPAREN:
  1.1256 +                        if ((mode & EXPR) != 0) {
  1.1257 +                            mode = EXPR;
  1.1258 +                            t = arguments(typeArgs, t);
  1.1259 +                            if (!annos.isEmpty()) t = illegal(annos.head.pos);
  1.1260 +                            typeArgs = null;
  1.1261 +                        }
  1.1262 +                        break loop;
  1.1263 +                    case DOT:
  1.1264 +                        nextToken();
  1.1265 +                        int oldmode = mode;
  1.1266 +                        mode &= ~NOPARAMS;
  1.1267 +                        typeArgs = typeArgumentsOpt(EXPR);
  1.1268 +                        mode = oldmode;
  1.1269 +                        if ((mode & EXPR) != 0) {
  1.1270 +                            switch (token.kind) {
  1.1271 +                            case CLASS:
  1.1272 +                                if (typeArgs != null) return illegal();
  1.1273 +                                mode = EXPR;
  1.1274 +                                t = to(F.at(pos).Select(t, names._class));
  1.1275 +                                nextToken();
  1.1276 +                                break loop;
  1.1277 +                            case THIS:
  1.1278 +                                if (typeArgs != null) return illegal();
  1.1279 +                                mode = EXPR;
  1.1280 +                                t = to(F.at(pos).Select(t, names._this));
  1.1281 +                                nextToken();
  1.1282 +                                break loop;
  1.1283 +                            case SUPER:
  1.1284 +                                mode = EXPR;
  1.1285 +                                t = to(F.at(pos).Select(t, names._super));
  1.1286 +                                t = superSuffix(typeArgs, t);
  1.1287 +                                typeArgs = null;
  1.1288 +                                break loop;
  1.1289 +                            case NEW:
  1.1290 +                                if (typeArgs != null) return illegal();
  1.1291 +                                mode = EXPR;
  1.1292 +                                int pos1 = token.pos;
  1.1293 +                                nextToken();
  1.1294 +                                if (token.kind == LT) typeArgs = typeArguments(false);
  1.1295 +                                t = innerCreator(pos1, typeArgs, t);
  1.1296 +                                typeArgs = null;
  1.1297 +                                break loop;
  1.1298 +                            }
  1.1299 +                        }
  1.1300 +
  1.1301 +                        List<JCAnnotation> tyannos = null;
  1.1302 +                        if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
  1.1303 +                            tyannos = typeAnnotationsOpt();
  1.1304 +                        }
  1.1305 +                        // typeArgs saved for next loop iteration.
  1.1306 +                        t = toP(F.at(pos).Select(t, ident()));
  1.1307 +                        if (tyannos != null && tyannos.nonEmpty()) {
  1.1308 +                            t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  1.1309 +                        }
  1.1310 +                        break;
  1.1311 +                    case ELLIPSIS:
  1.1312 +                        if (this.permitTypeAnnotationsPushBack) {
  1.1313 +                            this.typeAnnotationsPushedBack = annos;
  1.1314 +                        } else if (annos.nonEmpty()) {
  1.1315 +                            // Don't return here -- error recovery attempt
  1.1316 +                            illegal(annos.head.pos);
  1.1317 +                        }
  1.1318 +                        break loop;
  1.1319 +                    case LT:
  1.1320 +                        if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
  1.1321 +                            //this is an unbound method reference whose qualifier
  1.1322 +                            //is a generic type i.e. A<S>::m
  1.1323 +                            int pos1 = token.pos;
  1.1324 +                            accept(LT);
  1.1325 +                            ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
  1.1326 +                            args.append(typeArgument());
  1.1327 +                            while (token.kind == COMMA) {
  1.1328 +                                nextToken();
  1.1329 +                                args.append(typeArgument());
  1.1330 +                            }
  1.1331 +                            accept(GT);
  1.1332 +                            t = toP(F.at(pos1).TypeApply(t, args.toList()));
  1.1333 +                            checkGenerics();
  1.1334 +                            while (token.kind == DOT) {
  1.1335 +                                nextToken();
  1.1336 +                                mode = TYPE;
  1.1337 +                                t = toP(F.at(token.pos).Select(t, ident()));
  1.1338 +                                t = typeArgumentsOpt(t);
  1.1339 +                            }
  1.1340 +                            t = bracketsOpt(t);
  1.1341 +                            if (token.kind != COLCOL) {
  1.1342 +                                //method reference expected here
  1.1343 +                                t = illegal();
  1.1344 +                            }
  1.1345 +                            mode = EXPR;
  1.1346 +                            return term3Rest(t, typeArgs);
  1.1347 +                        }
  1.1348 +                        break loop;
  1.1349 +                    default:
  1.1350 +                        break loop;
  1.1351 +                    }
  1.1352 +                }
  1.1353 +            }
  1.1354 +            if (typeArgs != null) illegal();
  1.1355 +            t = typeArgumentsOpt(t);
  1.1356 +            break;
  1.1357 +        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1.1358 +        case DOUBLE: case BOOLEAN:
  1.1359 +            if (typeArgs != null) illegal();
  1.1360 +            t = bracketsSuffix(bracketsOpt(basicType()));
  1.1361 +            break;
  1.1362 +        case VOID:
  1.1363 +            if (typeArgs != null) illegal();
  1.1364 +            if ((mode & EXPR) != 0) {
  1.1365 +                nextToken();
  1.1366 +                if (token.kind == DOT) {
  1.1367 +                    JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
  1.1368 +                    t = bracketsSuffix(ti);
  1.1369 +                } else {
  1.1370 +                    return illegal(pos);
  1.1371 +                }
  1.1372 +            } else {
  1.1373 +                // Support the corner case of myMethodHandle.<void>invoke() by passing
  1.1374 +                // a void type (like other primitive types) to the next phase.
  1.1375 +                // The error will be reported in Attr.attribTypes or Attr.visitApply.
  1.1376 +                JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
  1.1377 +                nextToken();
  1.1378 +                return ti;
  1.1379 +                //return illegal();
  1.1380 +            }
  1.1381 +            break;
  1.1382 +        default:
  1.1383 +            return illegal();
  1.1384 +        }
  1.1385 +        return term3Rest(t, typeArgs);
  1.1386 +    }
  1.1387 +
  1.1388 +    JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
  1.1389 +        if (typeArgs != null) illegal();
  1.1390 +        while (true) {
  1.1391 +            int pos1 = token.pos;
  1.1392 +            final List<JCAnnotation> annos = typeAnnotationsOpt();
  1.1393 +
  1.1394 +            if (token.kind == LBRACKET) {
  1.1395 +                nextToken();
  1.1396 +                if ((mode & TYPE) != 0) {
  1.1397 +                    int oldmode = mode;
  1.1398 +                    mode = TYPE;
  1.1399 +                    if (token.kind == RBRACKET) {
  1.1400 +                        nextToken();
  1.1401 +                        t = bracketsOpt(t);
  1.1402 +                        t = toP(F.at(pos1).TypeArray(t));
  1.1403 +                        if (token.kind == COLCOL) {
  1.1404 +                            mode = EXPR;
  1.1405 +                            continue;
  1.1406 +                        }
  1.1407 +                        if (annos.nonEmpty()) {
  1.1408 +                            t = toP(F.at(pos1).AnnotatedType(annos, t));
  1.1409 +                        }
  1.1410 +                        return t;
  1.1411 +                    }
  1.1412 +                    mode = oldmode;
  1.1413 +                }
  1.1414 +                if ((mode & EXPR) != 0) {
  1.1415 +                    mode = EXPR;
  1.1416 +                    JCExpression t1 = term();
  1.1417 +                    t = to(F.at(pos1).Indexed(t, t1));
  1.1418 +                }
  1.1419 +                accept(RBRACKET);
  1.1420 +            } else if (token.kind == DOT) {
  1.1421 +                nextToken();
  1.1422 +                typeArgs = typeArgumentsOpt(EXPR);
  1.1423 +                if (token.kind == SUPER && (mode & EXPR) != 0) {
  1.1424 +                    mode = EXPR;
  1.1425 +                    t = to(F.at(pos1).Select(t, names._super));
  1.1426 +                    nextToken();
  1.1427 +                    t = arguments(typeArgs, t);
  1.1428 +                    typeArgs = null;
  1.1429 +                } else if (token.kind == NEW && (mode & EXPR) != 0) {
  1.1430 +                    if (typeArgs != null) return illegal();
  1.1431 +                    mode = EXPR;
  1.1432 +                    int pos2 = token.pos;
  1.1433 +                    nextToken();
  1.1434 +                    if (token.kind == LT) typeArgs = typeArguments(false);
  1.1435 +                    t = innerCreator(pos2, typeArgs, t);
  1.1436 +                    typeArgs = null;
  1.1437 +                } else {
  1.1438 +                    List<JCAnnotation> tyannos = null;
  1.1439 +                    if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
  1.1440 +                        // is the mode check needed?
  1.1441 +                        tyannos = typeAnnotationsOpt();
  1.1442 +                    }
  1.1443 +                    t = toP(F.at(pos1).Select(t, ident()));
  1.1444 +                    if (tyannos != null && tyannos.nonEmpty()) {
  1.1445 +                        t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  1.1446 +                    }
  1.1447 +                    t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
  1.1448 +                    typeArgs = null;
  1.1449 +                }
  1.1450 +            } else if ((mode & EXPR) != 0 && token.kind == COLCOL) {
  1.1451 +                mode = EXPR;
  1.1452 +                if (typeArgs != null) return illegal();
  1.1453 +                accept(COLCOL);
  1.1454 +                t = memberReferenceSuffix(pos1, t);
  1.1455 +            } else {
  1.1456 +                if (!annos.isEmpty()) {
  1.1457 +                    if (permitTypeAnnotationsPushBack)
  1.1458 +                        typeAnnotationsPushedBack = annos;
  1.1459 +                    else
  1.1460 +                        return illegal(annos.head.pos);
  1.1461 +                }
  1.1462 +                break;
  1.1463 +            }
  1.1464 +        }
  1.1465 +        while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
  1.1466 +            mode = EXPR;
  1.1467 +            t = to(F.at(token.pos).Unary(
  1.1468 +                  token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
  1.1469 +            nextToken();
  1.1470 +        }
  1.1471 +        return toP(t);
  1.1472 +    }
  1.1473 +
  1.1474 +    /**
  1.1475 +     * If we see an identifier followed by a '&lt;' it could be an unbound
  1.1476 +     * method reference or a binary expression. To disambiguate, look for a
  1.1477 +     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
  1.1478 +     */
  1.1479 +    @SuppressWarnings("fallthrough")
  1.1480 +    boolean isUnboundMemberRef() {
  1.1481 +        int pos = 0, depth = 0;
  1.1482 +        outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
  1.1483 +            switch (t.kind) {
  1.1484 +                case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
  1.1485 +                case DOT: case RBRACKET: case LBRACKET: case COMMA:
  1.1486 +                case BYTE: case SHORT: case INT: case LONG: case FLOAT:
  1.1487 +                case DOUBLE: case BOOLEAN: case CHAR:
  1.1488 +                case MONKEYS_AT:
  1.1489 +                    break;
  1.1490 +
  1.1491 +                case LPAREN:
  1.1492 +                    // skip annotation values
  1.1493 +                    int nesting = 0;
  1.1494 +                    for (; ; pos++) {
  1.1495 +                        TokenKind tk2 = S.token(pos).kind;
  1.1496 +                        switch (tk2) {
  1.1497 +                            case EOF:
  1.1498 +                                return false;
  1.1499 +                            case LPAREN:
  1.1500 +                                nesting++;
  1.1501 +                                break;
  1.1502 +                            case RPAREN:
  1.1503 +                                nesting--;
  1.1504 +                                if (nesting == 0) {
  1.1505 +                                    continue outer;
  1.1506 +                                }
  1.1507 +                                break;
  1.1508 +                        }
  1.1509 +                    }
  1.1510 +
  1.1511 +                case LT:
  1.1512 +                    depth++; break;
  1.1513 +                case GTGTGT:
  1.1514 +                    depth--;
  1.1515 +                case GTGT:
  1.1516 +                    depth--;
  1.1517 +                case GT:
  1.1518 +                    depth--;
  1.1519 +                    if (depth == 0) {
  1.1520 +                        TokenKind nextKind = S.token(pos + 1).kind;
  1.1521 +                        return
  1.1522 +                            nextKind == TokenKind.DOT ||
  1.1523 +                            nextKind == TokenKind.LBRACKET ||
  1.1524 +                            nextKind == TokenKind.COLCOL;
  1.1525 +                    }
  1.1526 +                    break;
  1.1527 +                default:
  1.1528 +                    return false;
  1.1529 +            }
  1.1530 +        }
  1.1531 +    }
  1.1532 +
  1.1533 +    /**
  1.1534 +     * If we see an identifier followed by a '&lt;' it could be an unbound
  1.1535 +     * method reference or a binary expression. To disambiguate, look for a
  1.1536 +     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
  1.1537 +     */
  1.1538 +    @SuppressWarnings("fallthrough")
  1.1539 +    ParensResult analyzeParens() {
  1.1540 +        int depth = 0;
  1.1541 +        boolean type = false;
  1.1542 +        outer: for (int lookahead = 0 ; ; lookahead++) {
  1.1543 +            TokenKind tk = S.token(lookahead).kind;
  1.1544 +            switch (tk) {
  1.1545 +                case COMMA:
  1.1546 +                    type = true;
  1.1547 +                case EXTENDS: case SUPER: case DOT: case AMP:
  1.1548 +                    //skip
  1.1549 +                    break;
  1.1550 +                case QUES:
  1.1551 +                    if (peekToken(lookahead, EXTENDS) ||
  1.1552 +                            peekToken(lookahead, SUPER)) {
  1.1553 +                        //wildcards
  1.1554 +                        type = true;
  1.1555 +                    }
  1.1556 +                    break;
  1.1557 +                case BYTE: case SHORT: case INT: case LONG: case FLOAT:
  1.1558 +                case DOUBLE: case BOOLEAN: case CHAR:
  1.1559 +                    if (peekToken(lookahead, RPAREN)) {
  1.1560 +                        //Type, ')' -> cast
  1.1561 +                        return ParensResult.CAST;
  1.1562 +                    } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
  1.1563 +                        //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
  1.1564 +                        return ParensResult.EXPLICIT_LAMBDA;
  1.1565 +                    }
  1.1566 +                    break;
  1.1567 +                case LPAREN:
  1.1568 +                    if (lookahead != 0) {
  1.1569 +                        // '(' in a non-starting position -> parens
  1.1570 +                        return ParensResult.PARENS;
  1.1571 +                    } else if (peekToken(lookahead, RPAREN)) {
  1.1572 +                        // '(', ')' -> explicit lambda
  1.1573 +                        return ParensResult.EXPLICIT_LAMBDA;
  1.1574 +                    }
  1.1575 +                    break;
  1.1576 +                case RPAREN:
  1.1577 +                    // if we have seen something that looks like a type,
  1.1578 +                    // then it's a cast expression
  1.1579 +                    if (type) return ParensResult.CAST;
  1.1580 +                    // otherwise, disambiguate cast vs. parenthesized expression
  1.1581 +                    // based on subsequent token.
  1.1582 +                    switch (S.token(lookahead + 1).kind) {
  1.1583 +                        /*case PLUSPLUS: case SUBSUB: */
  1.1584 +                        case BANG: case TILDE:
  1.1585 +                        case LPAREN: case THIS: case SUPER:
  1.1586 +                        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
  1.1587 +                        case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
  1.1588 +                        case TRUE: case FALSE: case NULL:
  1.1589 +                        case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
  1.1590 +                        case BYTE: case SHORT: case CHAR: case INT:
  1.1591 +                        case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
  1.1592 +                            return ParensResult.CAST;
  1.1593 +                        default:
  1.1594 +                            return ParensResult.PARENS;
  1.1595 +                    }
  1.1596 +                case UNDERSCORE:
  1.1597 +                case ASSERT:
  1.1598 +                case ENUM:
  1.1599 +                case IDENTIFIER:
  1.1600 +                    if (peekToken(lookahead, LAX_IDENTIFIER)) {
  1.1601 +                        // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
  1.1602 +                        return ParensResult.EXPLICIT_LAMBDA;
  1.1603 +                    } else if (peekToken(lookahead, RPAREN, ARROW)) {
  1.1604 +                        // Identifier, ')' '->' -> implicit lambda
  1.1605 +                        return ParensResult.IMPLICIT_LAMBDA;
  1.1606 +                    }
  1.1607 +                    type = false;
  1.1608 +                    break;
  1.1609 +                case FINAL:
  1.1610 +                case ELLIPSIS:
  1.1611 +                    //those can only appear in explicit lambdas
  1.1612 +                    return ParensResult.EXPLICIT_LAMBDA;
  1.1613 +                case MONKEYS_AT:
  1.1614 +                    type = true;
  1.1615 +                    lookahead += 1; //skip '@'
  1.1616 +                    while (peekToken(lookahead, DOT)) {
  1.1617 +                        lookahead += 2;
  1.1618 +                    }
  1.1619 +                    if (peekToken(lookahead, LPAREN)) {
  1.1620 +                        lookahead++;
  1.1621 +                        //skip annotation values
  1.1622 +                        int nesting = 0;
  1.1623 +                        for (; ; lookahead++) {
  1.1624 +                            TokenKind tk2 = S.token(lookahead).kind;
  1.1625 +                            switch (tk2) {
  1.1626 +                                case EOF:
  1.1627 +                                    return ParensResult.PARENS;
  1.1628 +                                case LPAREN:
  1.1629 +                                    nesting++;
  1.1630 +                                    break;
  1.1631 +                                case RPAREN:
  1.1632 +                                    nesting--;
  1.1633 +                                    if (nesting == 0) {
  1.1634 +                                        continue outer;
  1.1635 +                                    }
  1.1636 +                                break;
  1.1637 +                            }
  1.1638 +                        }
  1.1639 +                    }
  1.1640 +                    break;
  1.1641 +                case LBRACKET:
  1.1642 +                    if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
  1.1643 +                        // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
  1.1644 +                        return ParensResult.EXPLICIT_LAMBDA;
  1.1645 +                    } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
  1.1646 +                            peekToken(lookahead, RBRACKET, AMP)) {
  1.1647 +                        // '[', ']', ')' -> cast
  1.1648 +                        // '[', ']', '&' -> cast (intersection type)
  1.1649 +                        return ParensResult.CAST;
  1.1650 +                    } else if (peekToken(lookahead, RBRACKET)) {
  1.1651 +                        //consume the ']' and skip
  1.1652 +                        type = true;
  1.1653 +                        lookahead++;
  1.1654 +                        break;
  1.1655 +                    } else {
  1.1656 +                        return ParensResult.PARENS;
  1.1657 +                    }
  1.1658 +                case LT:
  1.1659 +                    depth++; break;
  1.1660 +                case GTGTGT:
  1.1661 +                    depth--;
  1.1662 +                case GTGT:
  1.1663 +                    depth--;
  1.1664 +                case GT:
  1.1665 +                    depth--;
  1.1666 +                    if (depth == 0) {
  1.1667 +                        if (peekToken(lookahead, RPAREN) ||
  1.1668 +                                peekToken(lookahead, AMP)) {
  1.1669 +                            // '>', ')' -> cast
  1.1670 +                            // '>', '&' -> cast
  1.1671 +                            return ParensResult.CAST;
  1.1672 +                        } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
  1.1673 +                                peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
  1.1674 +                                peekToken(lookahead, ELLIPSIS)) {
  1.1675 +                            // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
  1.1676 +                            // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
  1.1677 +                            // '>', '...' -> explicit lambda
  1.1678 +                            return ParensResult.EXPLICIT_LAMBDA;
  1.1679 +                        }
  1.1680 +                        //it looks a type, but could still be (i) a cast to generic type,
  1.1681 +                        //(ii) an unbound method reference or (iii) an explicit lambda
  1.1682 +                        type = true;
  1.1683 +                        break;
  1.1684 +                    } else if (depth < 0) {
  1.1685 +                        //unbalanced '<', '>' - not a generic type
  1.1686 +                        return ParensResult.PARENS;
  1.1687 +                    }
  1.1688 +                    break;
  1.1689 +                default:
  1.1690 +                    //this includes EOF
  1.1691 +                    return ParensResult.PARENS;
  1.1692 +            }
  1.1693 +        }
  1.1694 +    }
  1.1695 +
  1.1696 +    /** Accepts all identifier-like tokens */
  1.1697 +    Filter<TokenKind> LAX_IDENTIFIER = new Filter<TokenKind>() {
  1.1698 +        public boolean accepts(TokenKind t) {
  1.1699 +            return t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
  1.1700 +        }
  1.1701 +    };
  1.1702 +
  1.1703 +    enum ParensResult {
  1.1704 +        CAST,
  1.1705 +        EXPLICIT_LAMBDA,
  1.1706 +        IMPLICIT_LAMBDA,
  1.1707 +        PARENS;
  1.1708 +    }
  1.1709 +
  1.1710 +    JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
  1.1711 +        List<JCVariableDecl> params = explicitParams ?
  1.1712 +                formalParameters(true) :
  1.1713 +                implicitParameters(hasParens);
  1.1714 +
  1.1715 +        return lambdaExpressionOrStatementRest(params, pos);
  1.1716 +    }
  1.1717 +
  1.1718 +    JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
  1.1719 +        checkLambda();
  1.1720 +        accept(ARROW);
  1.1721 +
  1.1722 +        return token.kind == LBRACE ?
  1.1723 +            lambdaStatement(args, pos, pos) :
  1.1724 +            lambdaExpression(args, pos);
  1.1725 +    }
  1.1726 +
  1.1727 +    JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) {
  1.1728 +        JCBlock block = block(pos2, 0);
  1.1729 +        return toP(F.at(pos).Lambda(args, block));
  1.1730 +    }
  1.1731 +
  1.1732 +    JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
  1.1733 +        JCTree expr = parseExpression();
  1.1734 +        return toP(F.at(pos).Lambda(args, expr));
  1.1735 +    }
  1.1736 +
  1.1737 +    /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
  1.1738 +     */
  1.1739 +    JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
  1.1740 +        nextToken();
  1.1741 +        if (token.kind == LPAREN || typeArgs != null) {
  1.1742 +            t = arguments(typeArgs, t);
  1.1743 +        } else if (token.kind == COLCOL) {
  1.1744 +            if (typeArgs != null) return illegal();
  1.1745 +            t = memberReferenceSuffix(t);
  1.1746 +        } else {
  1.1747 +            int pos = token.pos;
  1.1748 +            accept(DOT);
  1.1749 +            typeArgs = (token.kind == LT) ? typeArguments(false) : null;
  1.1750 +            t = toP(F.at(pos).Select(t, ident()));
  1.1751 +            t = argumentsOpt(typeArgs, t);
  1.1752 +        }
  1.1753 +        return t;
  1.1754 +    }
  1.1755 +
  1.1756 +    /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
  1.1757 +     */
  1.1758 +    JCPrimitiveTypeTree basicType() {
  1.1759 +        JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
  1.1760 +        nextToken();
  1.1761 +        return t;
  1.1762 +    }
  1.1763 +
  1.1764 +    /** ArgumentsOpt = [ Arguments ]
  1.1765 +     */
  1.1766 +    JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
  1.1767 +        if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
  1.1768 +            mode = EXPR;
  1.1769 +            return arguments(typeArgs, t);
  1.1770 +        } else {
  1.1771 +            return t;
  1.1772 +        }
  1.1773 +    }
  1.1774 +
  1.1775 +    /** Arguments = "(" [Expression { COMMA Expression }] ")"
  1.1776 +     */
  1.1777 +    List<JCExpression> arguments() {
  1.1778 +        ListBuffer<JCExpression> args = new ListBuffer<>();
  1.1779 +        if (token.kind == LPAREN) {
  1.1780 +            nextToken();
  1.1781 +            if (token.kind != RPAREN) {
  1.1782 +                args.append(parseExpression());
  1.1783 +                while (token.kind == COMMA) {
  1.1784 +                    nextToken();
  1.1785 +                    args.append(parseExpression());
  1.1786 +                }
  1.1787 +            }
  1.1788 +            accept(RPAREN);
  1.1789 +        } else {
  1.1790 +            syntaxError(token.pos, "expected", LPAREN);
  1.1791 +        }
  1.1792 +        return args.toList();
  1.1793 +    }
  1.1794 +
  1.1795 +    JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
  1.1796 +        int pos = token.pos;
  1.1797 +        List<JCExpression> args = arguments();
  1.1798 +        return toP(F.at(pos).Apply(typeArgs, t, args));
  1.1799 +    }
  1.1800 +
  1.1801 +    /**  TypeArgumentsOpt = [ TypeArguments ]
  1.1802 +     */
  1.1803 +    JCExpression typeArgumentsOpt(JCExpression t) {
  1.1804 +        if (token.kind == LT &&
  1.1805 +            (mode & TYPE) != 0 &&
  1.1806 +            (mode & NOPARAMS) == 0) {
  1.1807 +            mode = TYPE;
  1.1808 +            checkGenerics();
  1.1809 +            return typeArguments(t, false);
  1.1810 +        } else {
  1.1811 +            return t;
  1.1812 +        }
  1.1813 +    }
  1.1814 +    List<JCExpression> typeArgumentsOpt() {
  1.1815 +        return typeArgumentsOpt(TYPE);
  1.1816 +    }
  1.1817 +
  1.1818 +    List<JCExpression> typeArgumentsOpt(int useMode) {
  1.1819 +        if (token.kind == LT) {
  1.1820 +            checkGenerics();
  1.1821 +            if ((mode & useMode) == 0 ||
  1.1822 +                (mode & NOPARAMS) != 0) {
  1.1823 +                illegal();
  1.1824 +            }
  1.1825 +            mode = useMode;
  1.1826 +            return typeArguments(false);
  1.1827 +        }
  1.1828 +        return null;
  1.1829 +    }
  1.1830 +
  1.1831 +    /**
  1.1832 +     *  {@literal
  1.1833 +     *  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
  1.1834 +     *  }
  1.1835 +     */
  1.1836 +    List<JCExpression> typeArguments(boolean diamondAllowed) {
  1.1837 +        if (token.kind == LT) {
  1.1838 +            nextToken();
  1.1839 +            if (token.kind == GT && diamondAllowed) {
  1.1840 +                checkDiamond();
  1.1841 +                mode |= DIAMOND;
  1.1842 +                nextToken();
  1.1843 +                return List.nil();
  1.1844 +            } else {
  1.1845 +                ListBuffer<JCExpression> args = new ListBuffer<>();
  1.1846 +                args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1.1847 +                while (token.kind == COMMA) {
  1.1848 +                    nextToken();
  1.1849 +                    args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
  1.1850 +                }
  1.1851 +                switch (token.kind) {
  1.1852 +
  1.1853 +                case GTGTGTEQ: case GTGTEQ: case GTEQ:
  1.1854 +                case GTGTGT: case GTGT:
  1.1855 +                    token = S.split();
  1.1856 +                    break;
  1.1857 +                case GT:
  1.1858 +                    nextToken();
  1.1859 +                    break;
  1.1860 +                default:
  1.1861 +                    args.append(syntaxError(token.pos, "expected", GT));
  1.1862 +                    break;
  1.1863 +                }
  1.1864 +                return args.toList();
  1.1865 +            }
  1.1866 +        } else {
  1.1867 +            return List.<JCExpression>of(syntaxError(token.pos, "expected", LT));
  1.1868 +        }
  1.1869 +    }
  1.1870 +
  1.1871 +    /**
  1.1872 +     *  {@literal
  1.1873 +     *  TypeArgument = Type
  1.1874 +     *               | [Annotations] "?"
  1.1875 +     *               | [Annotations] "?" EXTENDS Type {"&" Type}
  1.1876 +     *               | [Annotations] "?" SUPER Type
  1.1877 +     *  }
  1.1878 +     */
  1.1879 +    JCExpression typeArgument() {
  1.1880 +        List<JCAnnotation> annotations = typeAnnotationsOpt();
  1.1881 +        if (token.kind != QUES) return parseType(annotations);
  1.1882 +        int pos = token.pos;
  1.1883 +        nextToken();
  1.1884 +        JCExpression result;
  1.1885 +        if (token.kind == EXTENDS) {
  1.1886 +            TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
  1.1887 +            nextToken();
  1.1888 +            JCExpression bound = parseType();
  1.1889 +            result = F.at(pos).Wildcard(t, bound);
  1.1890 +        } else if (token.kind == SUPER) {
  1.1891 +            TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
  1.1892 +            nextToken();
  1.1893 +            JCExpression bound = parseType();
  1.1894 +            result = F.at(pos).Wildcard(t, bound);
  1.1895 +        } else if (LAX_IDENTIFIER.accepts(token.kind)) {
  1.1896 +            //error recovery
  1.1897 +            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
  1.1898 +            JCExpression wc = toP(F.at(pos).Wildcard(t, null));
  1.1899 +            JCIdent id = toP(F.at(token.pos).Ident(ident()));
  1.1900 +            JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
  1.1901 +            reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
  1.1902 +            result = err;
  1.1903 +        } else {
  1.1904 +            TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
  1.1905 +            result = toP(F.at(pos).Wildcard(t, null));
  1.1906 +        }
  1.1907 +        if (!annotations.isEmpty()) {
  1.1908 +            result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
  1.1909 +        }
  1.1910 +        return result;
  1.1911 +    }
  1.1912 +
  1.1913 +    JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
  1.1914 +        int pos = token.pos;
  1.1915 +        List<JCExpression> args = typeArguments(diamondAllowed);
  1.1916 +        return toP(F.at(pos).TypeApply(t, args));
  1.1917 +    }
  1.1918 +
  1.1919 +    /**
  1.1920 +     * BracketsOpt = { [Annotations] "[" "]" }*
  1.1921 +     *
  1.1922 +     * <p>
  1.1923 +     *
  1.1924 +     * <code>annotations</code> is the list of annotations targeting
  1.1925 +     * the expression <code>t</code>.
  1.1926 +     */
  1.1927 +    private JCExpression bracketsOpt(JCExpression t,
  1.1928 +            List<JCAnnotation> annotations) {
  1.1929 +        List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
  1.1930 +
  1.1931 +        if (token.kind == LBRACKET) {
  1.1932 +            int pos = token.pos;
  1.1933 +            nextToken();
  1.1934 +            t = bracketsOptCont(t, pos, nextLevelAnnotations);
  1.1935 +        } else if (!nextLevelAnnotations.isEmpty()) {
  1.1936 +            if (permitTypeAnnotationsPushBack) {
  1.1937 +                this.typeAnnotationsPushedBack = nextLevelAnnotations;
  1.1938 +            } else {
  1.1939 +                return illegal(nextLevelAnnotations.head.pos);
  1.1940 +            }
  1.1941 +        }
  1.1942 +
  1.1943 +        if (!annotations.isEmpty()) {
  1.1944 +            t = toP(F.at(token.pos).AnnotatedType(annotations, t));
  1.1945 +        }
  1.1946 +        return t;
  1.1947 +    }
  1.1948 +
  1.1949 +    /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ]
  1.1950 +     */
  1.1951 +    private JCExpression bracketsOpt(JCExpression t) {
  1.1952 +        return bracketsOpt(t, List.<JCAnnotation>nil());
  1.1953 +    }
  1.1954 +
  1.1955 +    private JCExpression bracketsOptCont(JCExpression t, int pos,
  1.1956 +            List<JCAnnotation> annotations) {
  1.1957 +        accept(RBRACKET);
  1.1958 +        t = bracketsOpt(t);
  1.1959 +        t = toP(F.at(pos).TypeArray(t));
  1.1960 +        if (annotations.nonEmpty()) {
  1.1961 +            t = toP(F.at(pos).AnnotatedType(annotations, t));
  1.1962 +        }
  1.1963 +        return t;
  1.1964 +    }
  1.1965 +
  1.1966 +    /** BracketsSuffixExpr = "." CLASS
  1.1967 +     *  BracketsSuffixType =
  1.1968 +     */
  1.1969 +    JCExpression bracketsSuffix(JCExpression t) {
  1.1970 +        if ((mode & EXPR) != 0 && token.kind == DOT) {
  1.1971 +            mode = EXPR;
  1.1972 +            int pos = token.pos;
  1.1973 +            nextToken();
  1.1974 +            accept(CLASS);
  1.1975 +            if (token.pos == endPosTable.errorEndPos) {
  1.1976 +                // error recovery
  1.1977 +                Name name;
  1.1978 +                if (LAX_IDENTIFIER.accepts(token.kind)) {
  1.1979 +                    name = token.name();
  1.1980 +                    nextToken();
  1.1981 +                } else {
  1.1982 +                    name = names.error;
  1.1983 +                }
  1.1984 +                t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
  1.1985 +            } else {
  1.1986 +                t = toP(F.at(pos).Select(t, names._class));
  1.1987 +            }
  1.1988 +        } else if ((mode & TYPE) != 0) {
  1.1989 +            if (token.kind != COLCOL) {
  1.1990 +                mode = TYPE;
  1.1991 +            }
  1.1992 +        } else if (token.kind != COLCOL) {
  1.1993 +            syntaxError(token.pos, "dot.class.expected");
  1.1994 +        }
  1.1995 +        return t;
  1.1996 +    }
  1.1997 +
  1.1998 +    /**
  1.1999 +     * MemberReferenceSuffix = "::" [TypeArguments] Ident
  1.2000 +     *                       | "::" [TypeArguments] "new"
  1.2001 +     */
  1.2002 +    JCExpression memberReferenceSuffix(JCExpression t) {
  1.2003 +        int pos1 = token.pos;
  1.2004 +        accept(COLCOL);
  1.2005 +        return memberReferenceSuffix(pos1, t);
  1.2006 +    }
  1.2007 +
  1.2008 +    JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
  1.2009 +        checkMethodReferences();
  1.2010 +        mode = EXPR;
  1.2011 +        List<JCExpression> typeArgs = null;
  1.2012 +        if (token.kind == LT) {
  1.2013 +            typeArgs = typeArguments(false);
  1.2014 +        }
  1.2015 +        Name refName;
  1.2016 +        ReferenceMode refMode;
  1.2017 +        if (token.kind == NEW) {
  1.2018 +            refMode = ReferenceMode.NEW;
  1.2019 +            refName = names.init;
  1.2020 +            nextToken();
  1.2021 +        } else {
  1.2022 +            refMode = ReferenceMode.INVOKE;
  1.2023 +            refName = ident();
  1.2024 +        }
  1.2025 +        return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
  1.2026 +    }
  1.2027 +
  1.2028 +    /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
  1.2029 +     */
  1.2030 +    JCExpression creator(int newpos, List<JCExpression> typeArgs) {
  1.2031 +        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
  1.2032 +
  1.2033 +        switch (token.kind) {
  1.2034 +        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
  1.2035 +        case DOUBLE: case BOOLEAN:
  1.2036 +            if (typeArgs == null) {
  1.2037 +                if (newAnnotations.isEmpty()) {
  1.2038 +                    return arrayCreatorRest(newpos, basicType());
  1.2039 +                } else {
  1.2040 +                    return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
  1.2041 +                }
  1.2042 +            }
  1.2043 +            break;
  1.2044 +        default:
  1.2045 +        }
  1.2046 +        JCExpression t = qualident(true);
  1.2047 +
  1.2048 +        int oldmode = mode;
  1.2049 +        mode = TYPE;
  1.2050 +        boolean diamondFound = false;
  1.2051 +        int lastTypeargsPos = -1;
  1.2052 +        if (token.kind == LT) {
  1.2053 +            checkGenerics();
  1.2054 +            lastTypeargsPos = token.pos;
  1.2055 +            t = typeArguments(t, true);
  1.2056 +            diamondFound = (mode & DIAMOND) != 0;
  1.2057 +        }
  1.2058 +        while (token.kind == DOT) {
  1.2059 +            if (diamondFound) {
  1.2060 +                //cannot select after a diamond
  1.2061 +                illegal();
  1.2062 +            }
  1.2063 +            int pos = token.pos;
  1.2064 +            nextToken();
  1.2065 +            List<JCAnnotation> tyannos = typeAnnotationsOpt();
  1.2066 +            t = toP(F.at(pos).Select(t, ident()));
  1.2067 +
  1.2068 +            if (tyannos != null && tyannos.nonEmpty()) {
  1.2069 +                t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
  1.2070 +            }
  1.2071 +
  1.2072 +            if (token.kind == LT) {
  1.2073 +                lastTypeargsPos = token.pos;
  1.2074 +                checkGenerics();
  1.2075 +                t = typeArguments(t, true);
  1.2076 +                diamondFound = (mode & DIAMOND) != 0;
  1.2077 +            }
  1.2078 +        }
  1.2079 +        mode = oldmode;
  1.2080 +        if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
  1.2081 +            // handle type annotations for non primitive arrays
  1.2082 +            if (newAnnotations.nonEmpty()) {
  1.2083 +                t = insertAnnotationsToMostInner(t, newAnnotations, false);
  1.2084 +            }
  1.2085 +
  1.2086 +            JCExpression e = arrayCreatorRest(newpos, t);
  1.2087 +            if (diamondFound) {
  1.2088 +                reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
  1.2089 +                return toP(F.at(newpos).Erroneous(List.of(e)));
  1.2090 +            }
  1.2091 +            else if (typeArgs != null) {
  1.2092 +                int pos = newpos;
  1.2093 +                if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
  1.2094 +                    // note: this should always happen but we should
  1.2095 +                    // not rely on this as the parser is continuously
  1.2096 +                    // modified to improve error recovery.
  1.2097 +                    pos = typeArgs.head.pos;
  1.2098 +                }
  1.2099 +                setErrorEndPos(S.prevToken().endPos);
  1.2100 +                JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
  1.2101 +                reportSyntaxError(err, "cannot.create.array.with.type.arguments");
  1.2102 +                return toP(err);
  1.2103 +            }
  1.2104 +            return e;
  1.2105 +        } else if (token.kind == LPAREN) {
  1.2106 +            JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
  1.2107 +            if (newClass.def != null) {
  1.2108 +                assert newClass.def.mods.annotations.isEmpty();
  1.2109 +                if (newAnnotations.nonEmpty()) {
  1.2110 +                    // Add type and declaration annotations to the new class;
  1.2111 +                    // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
  1.2112 +                    // will later remove all type annotations and only leave the
  1.2113 +                    // declaration annotations.
  1.2114 +                    newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
  1.2115 +                    newClass.def.mods.annotations = newAnnotations;
  1.2116 +                }
  1.2117 +            } else {
  1.2118 +                // handle type annotations for instantiations
  1.2119 +                if (newAnnotations.nonEmpty()) {
  1.2120 +                    t = insertAnnotationsToMostInner(t, newAnnotations, false);
  1.2121 +                    newClass.clazz = t;
  1.2122 +                }
  1.2123 +            }
  1.2124 +            return newClass;
  1.2125 +        } else {
  1.2126 +            setErrorEndPos(token.pos);
  1.2127 +            reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET);
  1.2128 +            t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
  1.2129 +            return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
  1.2130 +        }
  1.2131 +    }
  1.2132 +
  1.2133 +    /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
  1.2134 +     */
  1.2135 +    JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
  1.2136 +        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
  1.2137 +
  1.2138 +        JCExpression t = toP(F.at(token.pos).Ident(ident()));
  1.2139 +
  1.2140 +        if (newAnnotations.nonEmpty()) {
  1.2141 +            t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
  1.2142 +        }
  1.2143 +
  1.2144 +        if (token.kind == LT) {
  1.2145 +            int oldmode = mode;
  1.2146 +            checkGenerics();
  1.2147 +            t = typeArguments(t, true);
  1.2148 +            mode = oldmode;
  1.2149 +        }
  1.2150 +        return classCreatorRest(newpos, encl, typeArgs, t);
  1.2151 +    }
  1.2152 +
  1.2153 +    /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
  1.2154 +     *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
  1.2155 +     */
  1.2156 +    JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
  1.2157 +        List<JCAnnotation> annos = typeAnnotationsOpt();
  1.2158 +
  1.2159 +        accept(LBRACKET);
  1.2160 +        if (token.kind == RBRACKET) {
  1.2161 +            accept(RBRACKET);
  1.2162 +            elemtype = bracketsOpt(elemtype, annos);
  1.2163 +            if (token.kind == LBRACE) {
  1.2164 +                JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
  1.2165 +                if (annos.nonEmpty()) {
  1.2166 +                    // when an array initializer is present then
  1.2167 +                    // the parsed annotations should target the
  1.2168 +                    // new array tree
  1.2169 +                    // bracketsOpt inserts the annotation in
  1.2170 +                    // elemtype, and it needs to be corrected
  1.2171 +                    //
  1.2172 +                    JCAnnotatedType annotated = (JCAnnotatedType)elemtype;
  1.2173 +                    assert annotated.annotations == annos;
  1.2174 +                    na.annotations = annotated.annotations;
  1.2175 +                    na.elemtype = annotated.underlyingType;
  1.2176 +                }
  1.2177 +                return na;
  1.2178 +            } else {
  1.2179 +                JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
  1.2180 +                return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
  1.2181 +            }
  1.2182 +        } else {
  1.2183 +            ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
  1.2184 +
  1.2185 +            // maintain array dimension type annotations
  1.2186 +            ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
  1.2187 +            dimAnnotations.append(annos);
  1.2188 +
  1.2189 +            dims.append(parseExpression());
  1.2190 +            accept(RBRACKET);
  1.2191 +            while (token.kind == LBRACKET
  1.2192 +                    || token.kind == MONKEYS_AT) {
  1.2193 +                List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt();
  1.2194 +                int pos = token.pos;
  1.2195 +                nextToken();
  1.2196 +                if (token.kind == RBRACKET) {
  1.2197 +                    elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1.2198 +                } else {
  1.2199 +                    if (token.kind == RBRACKET) { // no dimension
  1.2200 +                        elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
  1.2201 +                    } else {
  1.2202 +                        dimAnnotations.append(maybeDimAnnos);
  1.2203 +                        dims.append(parseExpression());
  1.2204 +                        accept(RBRACKET);
  1.2205 +                    }
  1.2206 +                }
  1.2207 +            }
  1.2208 +
  1.2209 +            JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
  1.2210 +            na.dimAnnotations = dimAnnotations.toList();
  1.2211 +            return na;
  1.2212 +        }
  1.2213 +    }
  1.2214 +
  1.2215 +    /** ClassCreatorRest = Arguments [ClassBody]
  1.2216 +     */
  1.2217 +    JCNewClass classCreatorRest(int newpos,
  1.2218 +                                  JCExpression encl,
  1.2219 +                                  List<JCExpression> typeArgs,
  1.2220 +                                  JCExpression t)
  1.2221 +    {
  1.2222 +        List<JCExpression> args = arguments();
  1.2223 +        JCClassDecl body = null;
  1.2224 +        if (token.kind == LBRACE) {
  1.2225 +            int pos = token.pos;
  1.2226 +            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  1.2227 +            JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1.2228 +            body = toP(F.at(pos).AnonymousClassDef(mods, defs));
  1.2229 +        }
  1.2230 +        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
  1.2231 +    }
  1.2232 +
  1.2233 +    /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
  1.2234 +     */
  1.2235 +    JCExpression arrayInitializer(int newpos, JCExpression t) {
  1.2236 +        accept(LBRACE);
  1.2237 +        ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
  1.2238 +        if (token.kind == COMMA) {
  1.2239 +            nextToken();
  1.2240 +        } else if (token.kind != RBRACE) {
  1.2241 +            elems.append(variableInitializer());
  1.2242 +            while (token.kind == COMMA) {
  1.2243 +                nextToken();
  1.2244 +                if (token.kind == RBRACE) break;
  1.2245 +                elems.append(variableInitializer());
  1.2246 +            }
  1.2247 +        }
  1.2248 +        accept(RBRACE);
  1.2249 +        return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
  1.2250 +    }
  1.2251 +
  1.2252 +    /** VariableInitializer = ArrayInitializer | Expression
  1.2253 +     */
  1.2254 +    public JCExpression variableInitializer() {
  1.2255 +        return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
  1.2256 +    }
  1.2257 +
  1.2258 +    /** ParExpression = "(" Expression ")"
  1.2259 +     */
  1.2260 +    JCExpression parExpression() {
  1.2261 +        int pos = token.pos;
  1.2262 +        accept(LPAREN);
  1.2263 +        JCExpression t = parseExpression();
  1.2264 +        accept(RPAREN);
  1.2265 +        return toP(F.at(pos).Parens(t));
  1.2266 +    }
  1.2267 +
  1.2268 +    /** Block = "{" BlockStatements "}"
  1.2269 +     */
  1.2270 +    JCBlock block(int pos, long flags) {
  1.2271 +        accept(LBRACE);
  1.2272 +        List<JCStatement> stats = blockStatements();
  1.2273 +        JCBlock t = F.at(pos).Block(flags, stats);
  1.2274 +        while (token.kind == CASE || token.kind == DEFAULT) {
  1.2275 +            syntaxError("orphaned", token.kind);
  1.2276 +            switchBlockStatementGroups();
  1.2277 +        }
  1.2278 +        // the Block node has a field "endpos" for first char of last token, which is
  1.2279 +        // usually but not necessarily the last char of the last token.
  1.2280 +        t.endpos = token.pos;
  1.2281 +        accept(RBRACE);
  1.2282 +        return toP(t);
  1.2283 +    }
  1.2284 +
  1.2285 +    public JCBlock block() {
  1.2286 +        return block(token.pos, 0);
  1.2287 +    }
  1.2288 +
  1.2289 +    /** BlockStatements = { BlockStatement }
  1.2290 +     *  BlockStatement  = LocalVariableDeclarationStatement
  1.2291 +     *                  | ClassOrInterfaceOrEnumDeclaration
  1.2292 +     *                  | [Ident ":"] Statement
  1.2293 +     *  LocalVariableDeclarationStatement
  1.2294 +     *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
  1.2295 +     */
  1.2296 +    @SuppressWarnings("fallthrough")
  1.2297 +    List<JCStatement> blockStatements() {
  1.2298 +        //todo: skip to anchor on error(?)
  1.2299 +        ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
  1.2300 +        while (true) {
  1.2301 +            List<JCStatement> stat = blockStatement();
  1.2302 +            if (stat.isEmpty()) {
  1.2303 +                return stats.toList();
  1.2304 +            } else {
  1.2305 +                if (token.pos <= endPosTable.errorEndPos) {
  1.2306 +                    skip(false, true, true, true);
  1.2307 +                }
  1.2308 +                stats.addAll(stat);
  1.2309 +            }
  1.2310 +        }
  1.2311 +    }
  1.2312 +
  1.2313 +    /*
  1.2314 +     * This method parses a statement treating it as a block, relaxing the
  1.2315 +     * JLS restrictions, allows us to parse more faulty code, doing so
  1.2316 +     * enables us to provide better and accurate diagnostics to the user.
  1.2317 +     */
  1.2318 +    JCStatement parseStatementAsBlock() {
  1.2319 +        int pos = token.pos;
  1.2320 +        List<JCStatement> stats = blockStatement();
  1.2321 +        if (stats.isEmpty()) {
  1.2322 +            JCErroneous e = F.at(pos).Erroneous();
  1.2323 +            error(e, "illegal.start.of.stmt");
  1.2324 +            return F.at(pos).Exec(e);
  1.2325 +        } else {
  1.2326 +            JCStatement first = stats.head;
  1.2327 +            String error = null;
  1.2328 +            switch (first.getTag()) {
  1.2329 +            case CLASSDEF:
  1.2330 +                error = "class.not.allowed";
  1.2331 +                break;
  1.2332 +            case VARDEF:
  1.2333 +                error = "variable.not.allowed";
  1.2334 +                break;
  1.2335 +            }
  1.2336 +            if (error != null) {
  1.2337 +                error(first, error);
  1.2338 +                List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
  1.2339 +                return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
  1.2340 +            }
  1.2341 +            return first;
  1.2342 +        }
  1.2343 +    }
  1.2344 +
  1.2345 +    @SuppressWarnings("fallthrough")
  1.2346 +    List<JCStatement> blockStatement() {
  1.2347 +        //todo: skip to anchor on error(?)
  1.2348 +        int pos = token.pos;
  1.2349 +        switch (token.kind) {
  1.2350 +        case RBRACE: case CASE: case DEFAULT: case EOF:
  1.2351 +            return List.nil();
  1.2352 +        case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
  1.2353 +        case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
  1.2354 +        case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
  1.2355 +            return List.of(parseStatement());
  1.2356 +        case MONKEYS_AT:
  1.2357 +        case FINAL: {
  1.2358 +            Comment dc = token.comment(CommentStyle.JAVADOC);
  1.2359 +            JCModifiers mods = modifiersOpt();
  1.2360 +            if (token.kind == INTERFACE ||
  1.2361 +                token.kind == CLASS ||
  1.2362 +                allowEnums && token.kind == ENUM) {
  1.2363 +                return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  1.2364 +            } else {
  1.2365 +                JCExpression t = parseType();
  1.2366 +                ListBuffer<JCStatement> stats =
  1.2367 +                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  1.2368 +                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1.2369 +                storeEnd(stats.last(), token.endPos);
  1.2370 +                accept(SEMI);
  1.2371 +                return stats.toList();
  1.2372 +            }
  1.2373 +        }
  1.2374 +        case ABSTRACT: case STRICTFP: {
  1.2375 +            Comment dc = token.comment(CommentStyle.JAVADOC);
  1.2376 +            JCModifiers mods = modifiersOpt();
  1.2377 +            return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
  1.2378 +        }
  1.2379 +        case INTERFACE:
  1.2380 +        case CLASS:
  1.2381 +            Comment dc = token.comment(CommentStyle.JAVADOC);
  1.2382 +            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  1.2383 +        case ENUM:
  1.2384 +        case ASSERT:
  1.2385 +            if (allowEnums && token.kind == ENUM) {
  1.2386 +                error(token.pos, "local.enum");
  1.2387 +                dc = token.comment(CommentStyle.JAVADOC);
  1.2388 +                return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
  1.2389 +            } else if (allowAsserts && token.kind == ASSERT) {
  1.2390 +                return List.of(parseStatement());
  1.2391 +            }
  1.2392 +            /* fall through to default */
  1.2393 +        default:
  1.2394 +            Token prevToken = token;
  1.2395 +            JCExpression t = term(EXPR | TYPE);
  1.2396 +            if (token.kind == COLON && t.hasTag(IDENT)) {
  1.2397 +                nextToken();
  1.2398 +                JCStatement stat = parseStatement();
  1.2399 +                return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
  1.2400 +            } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  1.2401 +                pos = token.pos;
  1.2402 +                JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
  1.2403 +                F.at(pos);
  1.2404 +                ListBuffer<JCStatement> stats =
  1.2405 +                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
  1.2406 +                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
  1.2407 +                storeEnd(stats.last(), token.endPos);
  1.2408 +                accept(SEMI);
  1.2409 +                return stats.toList();
  1.2410 +            } else {
  1.2411 +                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  1.2412 +                JCExpressionStatement expr = to(F.at(pos).Exec(checkExprStat(t)));
  1.2413 +                accept(SEMI);
  1.2414 +                return List.<JCStatement>of(expr);
  1.2415 +            }
  1.2416 +        }
  1.2417 +    }
  1.2418 +
  1.2419 +    /** Statement =
  1.2420 +     *       Block
  1.2421 +     *     | IF ParExpression Statement [ELSE Statement]
  1.2422 +     *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
  1.2423 +     *     | FOR "(" FormalParameter : Expression ")" Statement
  1.2424 +     *     | WHILE ParExpression Statement
  1.2425 +     *     | DO Statement WHILE ParExpression ";"
  1.2426 +     *     | TRY Block ( Catches | [Catches] FinallyPart )
  1.2427 +     *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
  1.2428 +     *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
  1.2429 +     *     | SYNCHRONIZED ParExpression Block
  1.2430 +     *     | RETURN [Expression] ";"
  1.2431 +     *     | THROW Expression ";"
  1.2432 +     *     | BREAK [Ident] ";"
  1.2433 +     *     | CONTINUE [Ident] ";"
  1.2434 +     *     | ASSERT Expression [ ":" Expression ] ";"
  1.2435 +     *     | ";"
  1.2436 +     *     | ExpressionStatement
  1.2437 +     *     | Ident ":" Statement
  1.2438 +     */
  1.2439 +    @SuppressWarnings("fallthrough")
  1.2440 +    public JCStatement parseStatement() {
  1.2441 +        int pos = token.pos;
  1.2442 +        switch (token.kind) {
  1.2443 +        case LBRACE:
  1.2444 +            return block();
  1.2445 +        case IF: {
  1.2446 +            nextToken();
  1.2447 +            JCExpression cond = parExpression();
  1.2448 +            JCStatement thenpart = parseStatementAsBlock();
  1.2449 +            JCStatement elsepart = null;
  1.2450 +            if (token.kind == ELSE) {
  1.2451 +                nextToken();
  1.2452 +                elsepart = parseStatementAsBlock();
  1.2453 +            }
  1.2454 +            return F.at(pos).If(cond, thenpart, elsepart);
  1.2455 +        }
  1.2456 +        case FOR: {
  1.2457 +            nextToken();
  1.2458 +            accept(LPAREN);
  1.2459 +            List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
  1.2460 +            if (inits.length() == 1 &&
  1.2461 +                inits.head.hasTag(VARDEF) &&
  1.2462 +                ((JCVariableDecl) inits.head).init == null &&
  1.2463 +                token.kind == COLON) {
  1.2464 +                checkForeach();
  1.2465 +                JCVariableDecl var = (JCVariableDecl)inits.head;
  1.2466 +                accept(COLON);
  1.2467 +                JCExpression expr = parseExpression();
  1.2468 +                accept(RPAREN);
  1.2469 +                JCStatement body = parseStatementAsBlock();
  1.2470 +                return F.at(pos).ForeachLoop(var, expr, body);
  1.2471 +            } else {
  1.2472 +                accept(SEMI);
  1.2473 +                JCExpression cond = token.kind == SEMI ? null : parseExpression();
  1.2474 +                accept(SEMI);
  1.2475 +                List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
  1.2476 +                accept(RPAREN);
  1.2477 +                JCStatement body = parseStatementAsBlock();
  1.2478 +                return F.at(pos).ForLoop(inits, cond, steps, body);
  1.2479 +            }
  1.2480 +        }
  1.2481 +        case WHILE: {
  1.2482 +            nextToken();
  1.2483 +            JCExpression cond = parExpression();
  1.2484 +            JCStatement body = parseStatementAsBlock();
  1.2485 +            return F.at(pos).WhileLoop(cond, body);
  1.2486 +        }
  1.2487 +        case DO: {
  1.2488 +            nextToken();
  1.2489 +            JCStatement body = parseStatementAsBlock();
  1.2490 +            accept(WHILE);
  1.2491 +            JCExpression cond = parExpression();
  1.2492 +            JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
  1.2493 +            accept(SEMI);
  1.2494 +            return t;
  1.2495 +        }
  1.2496 +        case TRY: {
  1.2497 +            nextToken();
  1.2498 +            List<JCTree> resources = List.<JCTree>nil();
  1.2499 +            if (token.kind == LPAREN) {
  1.2500 +                checkTryWithResources();
  1.2501 +                nextToken();
  1.2502 +                resources = resources();
  1.2503 +                accept(RPAREN);
  1.2504 +            }
  1.2505 +            JCBlock body = block();
  1.2506 +            ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
  1.2507 +            JCBlock finalizer = null;
  1.2508 +            if (token.kind == CATCH || token.kind == FINALLY) {
  1.2509 +                while (token.kind == CATCH) catchers.append(catchClause());
  1.2510 +                if (token.kind == FINALLY) {
  1.2511 +                    nextToken();
  1.2512 +                    finalizer = block();
  1.2513 +                }
  1.2514 +            } else {
  1.2515 +                if (allowTWR) {
  1.2516 +                    if (resources.isEmpty())
  1.2517 +                        error(pos, "try.without.catch.finally.or.resource.decls");
  1.2518 +                } else
  1.2519 +                    error(pos, "try.without.catch.or.finally");
  1.2520 +            }
  1.2521 +            return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
  1.2522 +        }
  1.2523 +        case SWITCH: {
  1.2524 +            nextToken();
  1.2525 +            JCExpression selector = parExpression();
  1.2526 +            accept(LBRACE);
  1.2527 +            List<JCCase> cases = switchBlockStatementGroups();
  1.2528 +            JCSwitch t = to(F.at(pos).Switch(selector, cases));
  1.2529 +            accept(RBRACE);
  1.2530 +            return t;
  1.2531 +        }
  1.2532 +        case SYNCHRONIZED: {
  1.2533 +            nextToken();
  1.2534 +            JCExpression lock = parExpression();
  1.2535 +            JCBlock body = block();
  1.2536 +            return F.at(pos).Synchronized(lock, body);
  1.2537 +        }
  1.2538 +        case RETURN: {
  1.2539 +            nextToken();
  1.2540 +            JCExpression result = token.kind == SEMI ? null : parseExpression();
  1.2541 +            JCReturn t = to(F.at(pos).Return(result));
  1.2542 +            accept(SEMI);
  1.2543 +            return t;
  1.2544 +        }
  1.2545 +        case THROW: {
  1.2546 +            nextToken();
  1.2547 +            JCExpression exc = parseExpression();
  1.2548 +            JCThrow t = to(F.at(pos).Throw(exc));
  1.2549 +            accept(SEMI);
  1.2550 +            return t;
  1.2551 +        }
  1.2552 +        case BREAK: {
  1.2553 +            nextToken();
  1.2554 +            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
  1.2555 +            JCBreak t = to(F.at(pos).Break(label));
  1.2556 +            accept(SEMI);
  1.2557 +            return t;
  1.2558 +        }
  1.2559 +        case CONTINUE: {
  1.2560 +            nextToken();
  1.2561 +            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
  1.2562 +            JCContinue t =  to(F.at(pos).Continue(label));
  1.2563 +            accept(SEMI);
  1.2564 +            return t;
  1.2565 +        }
  1.2566 +        case SEMI:
  1.2567 +            nextToken();
  1.2568 +            return toP(F.at(pos).Skip());
  1.2569 +        case ELSE:
  1.2570 +            int elsePos = token.pos;
  1.2571 +            nextToken();
  1.2572 +            return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
  1.2573 +        case FINALLY:
  1.2574 +            int finallyPos = token.pos;
  1.2575 +            nextToken();
  1.2576 +            return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
  1.2577 +        case CATCH:
  1.2578 +            return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
  1.2579 +        case ASSERT: {
  1.2580 +            if (allowAsserts && token.kind == ASSERT) {
  1.2581 +                nextToken();
  1.2582 +                JCExpression assertion = parseExpression();
  1.2583 +                JCExpression message = null;
  1.2584 +                if (token.kind == COLON) {
  1.2585 +                    nextToken();
  1.2586 +                    message = parseExpression();
  1.2587 +                }
  1.2588 +                JCAssert t = to(F.at(pos).Assert(assertion, message));
  1.2589 +                accept(SEMI);
  1.2590 +                return t;
  1.2591 +            }
  1.2592 +            /* else fall through to default case */
  1.2593 +        }
  1.2594 +        case ENUM:
  1.2595 +        default:
  1.2596 +            Token prevToken = token;
  1.2597 +            JCExpression expr = parseExpression();
  1.2598 +            if (token.kind == COLON && expr.hasTag(IDENT)) {
  1.2599 +                nextToken();
  1.2600 +                JCStatement stat = parseStatement();
  1.2601 +                return F.at(pos).Labelled(prevToken.name(), stat);
  1.2602 +            } else {
  1.2603 +                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
  1.2604 +                JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
  1.2605 +                accept(SEMI);
  1.2606 +                return stat;
  1.2607 +            }
  1.2608 +        }
  1.2609 +    }
  1.2610 +
  1.2611 +    private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
  1.2612 +        int errPos = S.errPos();
  1.2613 +        JCTree stm = action.doRecover(this);
  1.2614 +        S.errPos(errPos);
  1.2615 +        return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
  1.2616 +    }
  1.2617 +
  1.2618 +    /** CatchClause     = CATCH "(" FormalParameter ")" Block
  1.2619 +     * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
  1.2620 +     */
  1.2621 +    protected JCCatch catchClause() {
  1.2622 +        int pos = token.pos;
  1.2623 +        accept(CATCH);
  1.2624 +        accept(LPAREN);
  1.2625 +        JCModifiers mods = optFinal(Flags.PARAMETER);
  1.2626 +        List<JCExpression> catchTypes = catchTypes();
  1.2627 +        JCExpression paramType = catchTypes.size() > 1 ?
  1.2628 +                toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
  1.2629 +                catchTypes.head;
  1.2630 +        JCVariableDecl formal = variableDeclaratorId(mods, paramType);
  1.2631 +        accept(RPAREN);
  1.2632 +        JCBlock body = block();
  1.2633 +        return F.at(pos).Catch(formal, body);
  1.2634 +    }
  1.2635 +
  1.2636 +    List<JCExpression> catchTypes() {
  1.2637 +        ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
  1.2638 +        catchTypes.add(parseType());
  1.2639 +        while (token.kind == BAR) {
  1.2640 +            checkMulticatch();
  1.2641 +            nextToken();
  1.2642 +            // Instead of qualident this is now parseType.
  1.2643 +            // But would that allow too much, e.g. arrays or generics?
  1.2644 +            catchTypes.add(parseType());
  1.2645 +        }
  1.2646 +        return catchTypes.toList();
  1.2647 +    }
  1.2648 +
  1.2649 +    /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
  1.2650 +     *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
  1.2651 +     *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
  1.2652 +     */
  1.2653 +    List<JCCase> switchBlockStatementGroups() {
  1.2654 +        ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
  1.2655 +        while (true) {
  1.2656 +            int pos = token.pos;
  1.2657 +            switch (token.kind) {
  1.2658 +            case CASE:
  1.2659 +            case DEFAULT:
  1.2660 +                cases.append(switchBlockStatementGroup());
  1.2661 +                break;
  1.2662 +            case RBRACE: case EOF:
  1.2663 +                return cases.toList();
  1.2664 +            default:
  1.2665 +                nextToken(); // to ensure progress
  1.2666 +                syntaxError(pos, "expected3",
  1.2667 +                    CASE, DEFAULT, RBRACE);
  1.2668 +            }
  1.2669 +        }
  1.2670 +    }
  1.2671 +
  1.2672 +    protected JCCase switchBlockStatementGroup() {
  1.2673 +        int pos = token.pos;
  1.2674 +        List<JCStatement> stats;
  1.2675 +        JCCase c;
  1.2676 +        switch (token.kind) {
  1.2677 +        case CASE:
  1.2678 +            nextToken();
  1.2679 +            JCExpression pat = parseExpression();
  1.2680 +            accept(COLON);
  1.2681 +            stats = blockStatements();
  1.2682 +            c = F.at(pos).Case(pat, stats);
  1.2683 +            if (stats.isEmpty())
  1.2684 +                storeEnd(c, S.prevToken().endPos);
  1.2685 +            return c;
  1.2686 +        case DEFAULT:
  1.2687 +            nextToken();
  1.2688 +            accept(COLON);
  1.2689 +            stats = blockStatements();
  1.2690 +            c = F.at(pos).Case(null, stats);
  1.2691 +            if (stats.isEmpty())
  1.2692 +                storeEnd(c, S.prevToken().endPos);
  1.2693 +            return c;
  1.2694 +        }
  1.2695 +        throw new AssertionError("should not reach here");
  1.2696 +    }
  1.2697 +
  1.2698 +    /** MoreStatementExpressions = { COMMA StatementExpression }
  1.2699 +     */
  1.2700 +    <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
  1.2701 +                                                                    JCExpression first,
  1.2702 +                                                                    T stats) {
  1.2703 +        // This Exec is a "StatementExpression"; it subsumes no terminating token
  1.2704 +        stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
  1.2705 +        while (token.kind == COMMA) {
  1.2706 +            nextToken();
  1.2707 +            pos = token.pos;
  1.2708 +            JCExpression t = parseExpression();
  1.2709 +            // This Exec is a "StatementExpression"; it subsumes no terminating token
  1.2710 +            stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
  1.2711 +        }
  1.2712 +        return stats;
  1.2713 +    }
  1.2714 +
  1.2715 +    /** ForInit = StatementExpression MoreStatementExpressions
  1.2716 +     *           |  { FINAL | '@' Annotation } Type VariableDeclarators
  1.2717 +     */
  1.2718 +    List<JCStatement> forInit() {
  1.2719 +        ListBuffer<JCStatement> stats = new ListBuffer<>();
  1.2720 +        int pos = token.pos;
  1.2721 +        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
  1.2722 +            return variableDeclarators(optFinal(0), parseType(), stats).toList();
  1.2723 +        } else {
  1.2724 +            JCExpression t = term(EXPR | TYPE);
  1.2725 +            if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
  1.2726 +                return variableDeclarators(modifiersOpt(), t, stats).toList();
  1.2727 +            } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
  1.2728 +                error(pos, "bad.initializer", "for-loop");
  1.2729 +                return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
  1.2730 +            } else {
  1.2731 +                return moreStatementExpressions(pos, t, stats).toList();
  1.2732 +            }
  1.2733 +        }
  1.2734 +    }
  1.2735 +
  1.2736 +    /** ForUpdate = StatementExpression MoreStatementExpressions
  1.2737 +     */
  1.2738 +    List<JCExpressionStatement> forUpdate() {
  1.2739 +        return moreStatementExpressions(token.pos,
  1.2740 +                                        parseExpression(),
  1.2741 +                                        new ListBuffer<JCExpressionStatement>()).toList();
  1.2742 +    }
  1.2743 +
  1.2744 +    /** AnnotationsOpt = { '@' Annotation }
  1.2745 +     *
  1.2746 +     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  1.2747 +     */
  1.2748 +    List<JCAnnotation> annotationsOpt(Tag kind) {
  1.2749 +        if (token.kind != MONKEYS_AT) return List.nil(); // optimization
  1.2750 +        ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
  1.2751 +        int prevmode = mode;
  1.2752 +        while (token.kind == MONKEYS_AT) {
  1.2753 +            int pos = token.pos;
  1.2754 +            nextToken();
  1.2755 +            buf.append(annotation(pos, kind));
  1.2756 +        }
  1.2757 +        lastmode = mode;
  1.2758 +        mode = prevmode;
  1.2759 +        List<JCAnnotation> annotations = buf.toList();
  1.2760 +
  1.2761 +        return annotations;
  1.2762 +    }
  1.2763 +
  1.2764 +    List<JCAnnotation> typeAnnotationsOpt() {
  1.2765 +        List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
  1.2766 +        return annotations;
  1.2767 +    }
  1.2768 +
  1.2769 +    /** ModifiersOpt = { Modifier }
  1.2770 +     *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
  1.2771 +     *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
  1.2772 +     *           | "@" Annotation
  1.2773 +     */
  1.2774 +    JCModifiers modifiersOpt() {
  1.2775 +        return modifiersOpt(null);
  1.2776 +    }
  1.2777 +    protected JCModifiers modifiersOpt(JCModifiers partial) {
  1.2778 +        long flags;
  1.2779 +        ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
  1.2780 +        int pos;
  1.2781 +        if (partial == null) {
  1.2782 +            flags = 0;
  1.2783 +            pos = token.pos;
  1.2784 +        } else {
  1.2785 +            flags = partial.flags;
  1.2786 +            annotations.appendList(partial.annotations);
  1.2787 +            pos = partial.pos;
  1.2788 +        }
  1.2789 +        if (token.deprecatedFlag()) {
  1.2790 +            flags |= Flags.DEPRECATED;
  1.2791 +        }
  1.2792 +        int lastPos;
  1.2793 +    loop:
  1.2794 +        while (true) {
  1.2795 +            long flag;
  1.2796 +            switch (token.kind) {
  1.2797 +            case PRIVATE     : flag = Flags.PRIVATE; break;
  1.2798 +            case PROTECTED   : flag = Flags.PROTECTED; break;
  1.2799 +            case PUBLIC      : flag = Flags.PUBLIC; break;
  1.2800 +            case STATIC      : flag = Flags.STATIC; break;
  1.2801 +            case TRANSIENT   : flag = Flags.TRANSIENT; break;
  1.2802 +            case FINAL       : flag = Flags.FINAL; break;
  1.2803 +            case ABSTRACT    : flag = Flags.ABSTRACT; break;
  1.2804 +            case NATIVE      : flag = Flags.NATIVE; break;
  1.2805 +            case VOLATILE    : flag = Flags.VOLATILE; break;
  1.2806 +            case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
  1.2807 +            case STRICTFP    : flag = Flags.STRICTFP; break;
  1.2808 +            case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
  1.2809 +            case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
  1.2810 +            case ERROR       : flag = 0; nextToken(); break;
  1.2811 +            default: break loop;
  1.2812 +            }
  1.2813 +            if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
  1.2814 +            lastPos = token.pos;
  1.2815 +            nextToken();
  1.2816 +            if (flag == Flags.ANNOTATION) {
  1.2817 +                checkAnnotations();
  1.2818 +                if (token.kind != INTERFACE) {
  1.2819 +                    JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
  1.2820 +                    // if first modifier is an annotation, set pos to annotation's.
  1.2821 +                    if (flags == 0 && annotations.isEmpty())
  1.2822 +                        pos = ann.pos;
  1.2823 +                    annotations.append(ann);
  1.2824 +                    flag = 0;
  1.2825 +                }
  1.2826 +            }
  1.2827 +            flags |= flag;
  1.2828 +        }
  1.2829 +        switch (token.kind) {
  1.2830 +        case ENUM: flags |= Flags.ENUM; break;
  1.2831 +        case INTERFACE: flags |= Flags.INTERFACE; break;
  1.2832 +        default: break;
  1.2833 +        }
  1.2834 +
  1.2835 +        /* A modifiers tree with no modifier tokens or annotations
  1.2836 +         * has no text position. */
  1.2837 +        if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
  1.2838 +            pos = Position.NOPOS;
  1.2839 +
  1.2840 +        JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
  1.2841 +        if (pos != Position.NOPOS)
  1.2842 +            storeEnd(mods, S.prevToken().endPos);
  1.2843 +        return mods;
  1.2844 +    }
  1.2845 +
  1.2846 +    /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
  1.2847 +     *
  1.2848 +     * @param pos position of "@" token
  1.2849 +     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
  1.2850 +     */
  1.2851 +    JCAnnotation annotation(int pos, Tag kind) {
  1.2852 +        // accept(AT); // AT consumed by caller
  1.2853 +        checkAnnotations();
  1.2854 +        if (kind == Tag.TYPE_ANNOTATION) {
  1.2855 +            checkTypeAnnotations();
  1.2856 +        }
  1.2857 +        JCTree ident = qualident(false);
  1.2858 +        List<JCExpression> fieldValues = annotationFieldValuesOpt();
  1.2859 +        JCAnnotation ann;
  1.2860 +        if (kind == Tag.ANNOTATION) {
  1.2861 +            ann = F.at(pos).Annotation(ident, fieldValues);
  1.2862 +        } else if (kind == Tag.TYPE_ANNOTATION) {
  1.2863 +            ann = F.at(pos).TypeAnnotation(ident, fieldValues);
  1.2864 +        } else {
  1.2865 +            throw new AssertionError("Unhandled annotation kind: " + kind);
  1.2866 +        }
  1.2867 +
  1.2868 +        storeEnd(ann, S.prevToken().endPos);
  1.2869 +        return ann;
  1.2870 +    }
  1.2871 +
  1.2872 +    List<JCExpression> annotationFieldValuesOpt() {
  1.2873 +        return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
  1.2874 +    }
  1.2875 +
  1.2876 +    /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
  1.2877 +    List<JCExpression> annotationFieldValues() {
  1.2878 +        accept(LPAREN);
  1.2879 +        ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  1.2880 +        if (token.kind != RPAREN) {
  1.2881 +            buf.append(annotationFieldValue());
  1.2882 +            while (token.kind == COMMA) {
  1.2883 +                nextToken();
  1.2884 +                buf.append(annotationFieldValue());
  1.2885 +            }
  1.2886 +        }
  1.2887 +        accept(RPAREN);
  1.2888 +        return buf.toList();
  1.2889 +    }
  1.2890 +
  1.2891 +    /** AnnotationFieldValue    = AnnotationValue
  1.2892 +     *                          | Identifier "=" AnnotationValue
  1.2893 +     */
  1.2894 +    JCExpression annotationFieldValue() {
  1.2895 +        if (LAX_IDENTIFIER.accepts(token.kind)) {
  1.2896 +            mode = EXPR;
  1.2897 +            JCExpression t1 = term1();
  1.2898 +            if (t1.hasTag(IDENT) && token.kind == EQ) {
  1.2899 +                int pos = token.pos;
  1.2900 +                accept(EQ);
  1.2901 +                JCExpression v = annotationValue();
  1.2902 +                return toP(F.at(pos).Assign(t1, v));
  1.2903 +            } else {
  1.2904 +                return t1;
  1.2905 +            }
  1.2906 +        }
  1.2907 +        return annotationValue();
  1.2908 +    }
  1.2909 +
  1.2910 +    /* AnnotationValue          = ConditionalExpression
  1.2911 +     *                          | Annotation
  1.2912 +     *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
  1.2913 +     */
  1.2914 +    JCExpression annotationValue() {
  1.2915 +        int pos;
  1.2916 +        switch (token.kind) {
  1.2917 +        case MONKEYS_AT:
  1.2918 +            pos = token.pos;
  1.2919 +            nextToken();
  1.2920 +            return annotation(pos, Tag.ANNOTATION);
  1.2921 +        case LBRACE:
  1.2922 +            pos = token.pos;
  1.2923 +            accept(LBRACE);
  1.2924 +            ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
  1.2925 +            if (token.kind == COMMA) {
  1.2926 +                nextToken();
  1.2927 +            } else if (token.kind != RBRACE) {
  1.2928 +                buf.append(annotationValue());
  1.2929 +                while (token.kind == COMMA) {
  1.2930 +                    nextToken();
  1.2931 +                    if (token.kind == RBRACE) break;
  1.2932 +                    buf.append(annotationValue());
  1.2933 +                }
  1.2934 +            }
  1.2935 +            accept(RBRACE);
  1.2936 +            return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
  1.2937 +        default:
  1.2938 +            mode = EXPR;
  1.2939 +            return term1();
  1.2940 +        }
  1.2941 +    }
  1.2942 +
  1.2943 +    /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
  1.2944 +     */
  1.2945 +    public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
  1.2946 +                                                                         JCExpression type,
  1.2947 +                                                                         T vdefs)
  1.2948 +    {
  1.2949 +        return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
  1.2950 +    }
  1.2951 +
  1.2952 +    /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
  1.2953 +     *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
  1.2954 +     *
  1.2955 +     *  @param reqInit  Is an initializer always required?
  1.2956 +     *  @param dc       The documentation comment for the variable declarations, or null.
  1.2957 +     */
  1.2958 +    <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
  1.2959 +                                                                     JCModifiers mods,
  1.2960 +                                                                     JCExpression type,
  1.2961 +                                                                     Name name,
  1.2962 +                                                                     boolean reqInit,
  1.2963 +                                                                     Comment dc,
  1.2964 +                                                                     T vdefs)
  1.2965 +    {
  1.2966 +        vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
  1.2967 +        while (token.kind == COMMA) {
  1.2968 +            // All but last of multiple declarators subsume a comma
  1.2969 +            storeEnd((JCTree)vdefs.last(), token.endPos);
  1.2970 +            nextToken();
  1.2971 +            vdefs.append(variableDeclarator(mods, type, reqInit, dc));
  1.2972 +        }
  1.2973 +        return vdefs;
  1.2974 +    }
  1.2975 +
  1.2976 +    /** VariableDeclarator = Ident VariableDeclaratorRest
  1.2977 +     *  ConstantDeclarator = Ident ConstantDeclaratorRest
  1.2978 +     */
  1.2979 +    JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
  1.2980 +        return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
  1.2981 +    }
  1.2982 +
  1.2983 +    /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
  1.2984 +     *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
  1.2985 +     *
  1.2986 +     *  @param reqInit  Is an initializer always required?
  1.2987 +     *  @param dc       The documentation comment for the variable declarations, or null.
  1.2988 +     */
  1.2989 +    JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
  1.2990 +                                  boolean reqInit, Comment dc) {
  1.2991 +        type = bracketsOpt(type);
  1.2992 +        JCExpression init = null;
  1.2993 +        if (token.kind == EQ) {
  1.2994 +            nextToken();
  1.2995 +            init = variableInitializer();
  1.2996 +        }
  1.2997 +        else if (reqInit) syntaxError(token.pos, "expected", EQ);
  1.2998 +        JCVariableDecl result =
  1.2999 +            toP(F.at(pos).VarDef(mods, name, type, init));
  1.3000 +        attach(result, dc);
  1.3001 +        return result;
  1.3002 +    }
  1.3003 +
  1.3004 +    /** VariableDeclaratorId = Ident BracketsOpt
  1.3005 +     */
  1.3006 +    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
  1.3007 +        return variableDeclaratorId(mods, type, false);
  1.3008 +    }
  1.3009 +    //where
  1.3010 +    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
  1.3011 +        int pos = token.pos;
  1.3012 +        Name name;
  1.3013 +        if (lambdaParameter && token.kind == UNDERSCORE) {
  1.3014 +            log.error(pos, "underscore.as.identifier.in.lambda");
  1.3015 +            name = token.name();
  1.3016 +            nextToken();
  1.3017 +        } else {
  1.3018 +            if (allowThisIdent) {
  1.3019 +                JCExpression pn = qualident(false);
  1.3020 +                if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
  1.3021 +                    name = ((JCIdent)pn).name;
  1.3022 +                } else {
  1.3023 +                    if ((mods.flags & Flags.VARARGS) != 0) {
  1.3024 +                        log.error(token.pos, "varargs.and.receiver");
  1.3025 +                    }
  1.3026 +                    if (token.kind == LBRACKET) {
  1.3027 +                        log.error(token.pos, "array.and.receiver");
  1.3028 +                    }
  1.3029 +                    return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
  1.3030 +                }
  1.3031 +            } else {
  1.3032 +                name = ident();
  1.3033 +            }
  1.3034 +        }
  1.3035 +        if ((mods.flags & Flags.VARARGS) != 0 &&
  1.3036 +                token.kind == LBRACKET) {
  1.3037 +            log.error(token.pos, "varargs.and.old.array.syntax");
  1.3038 +        }
  1.3039 +        type = bracketsOpt(type);
  1.3040 +        return toP(F.at(pos).VarDef(mods, name, type, null));
  1.3041 +    }
  1.3042 +
  1.3043 +    /** Resources = Resource { ";" Resources }
  1.3044 +     */
  1.3045 +    List<JCTree> resources() {
  1.3046 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  1.3047 +        defs.append(resource());
  1.3048 +        while (token.kind == SEMI) {
  1.3049 +            // All but last of multiple declarators must subsume a semicolon
  1.3050 +            storeEnd(defs.last(), token.endPos);
  1.3051 +            int semiColonPos = token.pos;
  1.3052 +            nextToken();
  1.3053 +            if (token.kind == RPAREN) { // Optional trailing semicolon
  1.3054 +                                       // after last resource
  1.3055 +                break;
  1.3056 +            }
  1.3057 +            defs.append(resource());
  1.3058 +        }
  1.3059 +        return defs.toList();
  1.3060 +    }
  1.3061 +
  1.3062 +    /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
  1.3063 +     */
  1.3064 +    protected JCTree resource() {
  1.3065 +        JCModifiers optFinal = optFinal(Flags.FINAL);
  1.3066 +        JCExpression type = parseType();
  1.3067 +        int pos = token.pos;
  1.3068 +        Name ident = ident();
  1.3069 +        return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
  1.3070 +    }
  1.3071 +
  1.3072 +    /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
  1.3073 +     */
  1.3074 +    public JCTree.JCCompilationUnit parseCompilationUnit() {
  1.3075 +        Token firstToken = token;
  1.3076 +        JCExpression pid = null;
  1.3077 +        JCModifiers mods = null;
  1.3078 +        boolean consumedToplevelDoc = false;
  1.3079 +        boolean seenImport = false;
  1.3080 +        boolean seenPackage = false;
  1.3081 +        List<JCAnnotation> packageAnnotations = List.nil();
  1.3082 +        if (token.kind == MONKEYS_AT)
  1.3083 +            mods = modifiersOpt();
  1.3084 +
  1.3085 +        if (token.kind == PACKAGE) {
  1.3086 +            seenPackage = true;
  1.3087 +            if (mods != null) {
  1.3088 +                checkNoMods(mods.flags);
  1.3089 +                packageAnnotations = mods.annotations;
  1.3090 +                mods = null;
  1.3091 +            }
  1.3092 +            nextToken();
  1.3093 +            pid = qualident(false);
  1.3094 +            accept(SEMI);
  1.3095 +        }
  1.3096 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  1.3097 +        boolean checkForImports = true;
  1.3098 +        boolean firstTypeDecl = true;
  1.3099 +        while (token.kind != EOF) {
  1.3100 +            if (token.pos > 0 && token.pos <= endPosTable.errorEndPos) {
  1.3101 +                // error recovery
  1.3102 +                skip(checkForImports, false, false, false);
  1.3103 +                if (token.kind == EOF)
  1.3104 +                    break;
  1.3105 +            }
  1.3106 +            if (checkForImports && mods == null && token.kind == IMPORT) {
  1.3107 +                seenImport = true;
  1.3108 +                defs.append(importDeclaration());
  1.3109 +            } else {
  1.3110 +                Comment docComment = token.comment(CommentStyle.JAVADOC);
  1.3111 +                if (firstTypeDecl && !seenImport && !seenPackage) {
  1.3112 +                    docComment = firstToken.comment(CommentStyle.JAVADOC);
  1.3113 +                    consumedToplevelDoc = true;
  1.3114 +                }
  1.3115 +                JCTree def = typeDeclaration(mods, docComment);
  1.3116 +                if (def instanceof JCExpressionStatement)
  1.3117 +                    def = ((JCExpressionStatement)def).expr;
  1.3118 +                defs.append(def);
  1.3119 +                if (def instanceof JCClassDecl)
  1.3120 +                    checkForImports = false;
  1.3121 +                mods = null;
  1.3122 +                firstTypeDecl = false;
  1.3123 +            }
  1.3124 +        }
  1.3125 +        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList());
  1.3126 +        if (!consumedToplevelDoc)
  1.3127 +            attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
  1.3128 +        if (defs.isEmpty())
  1.3129 +            storeEnd(toplevel, S.prevToken().endPos);
  1.3130 +        if (keepDocComments)
  1.3131 +            toplevel.docComments = docComments;
  1.3132 +        if (keepLineMap)
  1.3133 +            toplevel.lineMap = S.getLineMap();
  1.3134 +        this.endPosTable.setParser(null); // remove reference to parser
  1.3135 +        toplevel.endPositions = this.endPosTable;
  1.3136 +        return toplevel;
  1.3137 +    }
  1.3138 +
  1.3139 +    /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
  1.3140 +     */
  1.3141 +    JCTree importDeclaration() {
  1.3142 +        int pos = token.pos;
  1.3143 +        nextToken();
  1.3144 +        boolean importStatic = false;
  1.3145 +        if (token.kind == STATIC) {
  1.3146 +            checkStaticImports();
  1.3147 +            importStatic = true;
  1.3148 +            nextToken();
  1.3149 +        }
  1.3150 +        JCExpression pid = toP(F.at(token.pos).Ident(ident()));
  1.3151 +        do {
  1.3152 +            int pos1 = token.pos;
  1.3153 +            accept(DOT);
  1.3154 +            if (token.kind == STAR) {
  1.3155 +                pid = to(F.at(pos1).Select(pid, names.asterisk));
  1.3156 +                nextToken();
  1.3157 +                break;
  1.3158 +            } else {
  1.3159 +                pid = toP(F.at(pos1).Select(pid, ident()));
  1.3160 +            }
  1.3161 +        } while (token.kind == DOT);
  1.3162 +        accept(SEMI);
  1.3163 +        return toP(F.at(pos).Import(pid, importStatic));
  1.3164 +    }
  1.3165 +
  1.3166 +    /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
  1.3167 +     *                  | ";"
  1.3168 +     */
  1.3169 +    JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
  1.3170 +        int pos = token.pos;
  1.3171 +        if (mods == null && token.kind == SEMI) {
  1.3172 +            nextToken();
  1.3173 +            return toP(F.at(pos).Skip());
  1.3174 +        } else {
  1.3175 +            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
  1.3176 +        }
  1.3177 +    }
  1.3178 +
  1.3179 +    /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
  1.3180 +     *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
  1.3181 +     *  @param mods     Any modifiers starting the class or interface declaration
  1.3182 +     *  @param dc       The documentation comment for the class, or null.
  1.3183 +     */
  1.3184 +    JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
  1.3185 +        if (token.kind == CLASS) {
  1.3186 +            return classDeclaration(mods, dc);
  1.3187 +        } else if (token.kind == INTERFACE) {
  1.3188 +            return interfaceDeclaration(mods, dc);
  1.3189 +        } else if (allowEnums) {
  1.3190 +            if (token.kind == ENUM) {
  1.3191 +                return enumDeclaration(mods, dc);
  1.3192 +            } else {
  1.3193 +                int pos = token.pos;
  1.3194 +                List<JCTree> errs;
  1.3195 +                if (LAX_IDENTIFIER.accepts(token.kind)) {
  1.3196 +                    errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  1.3197 +                    setErrorEndPos(token.pos);
  1.3198 +                } else {
  1.3199 +                    errs = List.<JCTree>of(mods);
  1.3200 +                }
  1.3201 +                return toP(F.Exec(syntaxError(pos, errs, "expected3",
  1.3202 +                                              CLASS, INTERFACE, ENUM)));
  1.3203 +            }
  1.3204 +        } else {
  1.3205 +            if (token.kind == ENUM) {
  1.3206 +                error(token.pos, "enums.not.supported.in.source", source.name);
  1.3207 +                allowEnums = true;
  1.3208 +                return enumDeclaration(mods, dc);
  1.3209 +            }
  1.3210 +            int pos = token.pos;
  1.3211 +            List<JCTree> errs;
  1.3212 +            if (LAX_IDENTIFIER.accepts(token.kind)) {
  1.3213 +                errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
  1.3214 +                setErrorEndPos(token.pos);
  1.3215 +            } else {
  1.3216 +                errs = List.<JCTree>of(mods);
  1.3217 +            }
  1.3218 +            return toP(F.Exec(syntaxError(pos, errs, "expected2",
  1.3219 +                                          CLASS, INTERFACE)));
  1.3220 +        }
  1.3221 +    }
  1.3222 +
  1.3223 +    /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
  1.3224 +     *                     [IMPLEMENTS TypeList] ClassBody
  1.3225 +     *  @param mods    The modifiers starting the class declaration
  1.3226 +     *  @param dc       The documentation comment for the class, or null.
  1.3227 +     */
  1.3228 +    protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
  1.3229 +        int pos = token.pos;
  1.3230 +        accept(CLASS);
  1.3231 +        Name name = ident();
  1.3232 +
  1.3233 +        List<JCTypeParameter> typarams = typeParametersOpt();
  1.3234 +
  1.3235 +        JCExpression extending = null;
  1.3236 +        if (token.kind == EXTENDS) {
  1.3237 +            nextToken();
  1.3238 +            extending = parseType();
  1.3239 +        }
  1.3240 +        List<JCExpression> implementing = List.nil();
  1.3241 +        if (token.kind == IMPLEMENTS) {
  1.3242 +            nextToken();
  1.3243 +            implementing = typeList();
  1.3244 +        }
  1.3245 +        List<JCTree> defs = classOrInterfaceBody(name, false);
  1.3246 +        JCClassDecl result = toP(F.at(pos).ClassDef(
  1.3247 +            mods, name, typarams, extending, implementing, defs));
  1.3248 +        attach(result, dc);
  1.3249 +        return result;
  1.3250 +    }
  1.3251 +
  1.3252 +    /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
  1.3253 +     *                         [EXTENDS TypeList] InterfaceBody
  1.3254 +     *  @param mods    The modifiers starting the interface declaration
  1.3255 +     *  @param dc       The documentation comment for the interface, or null.
  1.3256 +     */
  1.3257 +    protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
  1.3258 +        int pos = token.pos;
  1.3259 +        accept(INTERFACE);
  1.3260 +        Name name = ident();
  1.3261 +
  1.3262 +        List<JCTypeParameter> typarams = typeParametersOpt();
  1.3263 +
  1.3264 +        List<JCExpression> extending = List.nil();
  1.3265 +        if (token.kind == EXTENDS) {
  1.3266 +            nextToken();
  1.3267 +            extending = typeList();
  1.3268 +        }
  1.3269 +        List<JCTree> defs = classOrInterfaceBody(name, true);
  1.3270 +        JCClassDecl result = toP(F.at(pos).ClassDef(
  1.3271 +            mods, name, typarams, null, extending, defs));
  1.3272 +        attach(result, dc);
  1.3273 +        return result;
  1.3274 +    }
  1.3275 +
  1.3276 +    /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
  1.3277 +     *  @param mods    The modifiers starting the enum declaration
  1.3278 +     *  @param dc       The documentation comment for the enum, or null.
  1.3279 +     */
  1.3280 +    protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
  1.3281 +        int pos = token.pos;
  1.3282 +        accept(ENUM);
  1.3283 +        Name name = ident();
  1.3284 +
  1.3285 +        List<JCExpression> implementing = List.nil();
  1.3286 +        if (token.kind == IMPLEMENTS) {
  1.3287 +            nextToken();
  1.3288 +            implementing = typeList();
  1.3289 +        }
  1.3290 +
  1.3291 +        List<JCTree> defs = enumBody(name);
  1.3292 +        mods.flags |= Flags.ENUM;
  1.3293 +        JCClassDecl result = toP(F.at(pos).
  1.3294 +            ClassDef(mods, name, List.<JCTypeParameter>nil(),
  1.3295 +                null, implementing, defs));
  1.3296 +        attach(result, dc);
  1.3297 +        return result;
  1.3298 +    }
  1.3299 +
  1.3300 +    /** EnumBody = "{" { EnumeratorDeclarationList } [","]
  1.3301 +     *                  [ ";" {ClassBodyDeclaration} ] "}"
  1.3302 +     */
  1.3303 +    List<JCTree> enumBody(Name enumName) {
  1.3304 +        accept(LBRACE);
  1.3305 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  1.3306 +        if (token.kind == COMMA) {
  1.3307 +            nextToken();
  1.3308 +        } else if (token.kind != RBRACE && token.kind != SEMI) {
  1.3309 +            defs.append(enumeratorDeclaration(enumName));
  1.3310 +            while (token.kind == COMMA) {
  1.3311 +                nextToken();
  1.3312 +                if (token.kind == RBRACE || token.kind == SEMI) break;
  1.3313 +                defs.append(enumeratorDeclaration(enumName));
  1.3314 +            }
  1.3315 +            if (token.kind != SEMI && token.kind != RBRACE) {
  1.3316 +                defs.append(syntaxError(token.pos, "expected3",
  1.3317 +                                COMMA, RBRACE, SEMI));
  1.3318 +                nextToken();
  1.3319 +            }
  1.3320 +        }
  1.3321 +        if (token.kind == SEMI) {
  1.3322 +            nextToken();
  1.3323 +            while (token.kind != RBRACE && token.kind != EOF) {
  1.3324 +                defs.appendList(classOrInterfaceBodyDeclaration(enumName,
  1.3325 +                                                                false));
  1.3326 +                if (token.pos <= endPosTable.errorEndPos) {
  1.3327 +                    // error recovery
  1.3328 +                   skip(false, true, true, false);
  1.3329 +                }
  1.3330 +            }
  1.3331 +        }
  1.3332 +        accept(RBRACE);
  1.3333 +        return defs.toList();
  1.3334 +    }
  1.3335 +
  1.3336 +    /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
  1.3337 +     */
  1.3338 +    JCTree enumeratorDeclaration(Name enumName) {
  1.3339 +        Comment dc = token.comment(CommentStyle.JAVADOC);
  1.3340 +        int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
  1.3341 +        if (token.deprecatedFlag()) {
  1.3342 +            flags |= Flags.DEPRECATED;
  1.3343 +        }
  1.3344 +        int pos = token.pos;
  1.3345 +        List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
  1.3346 +        JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
  1.3347 +        List<JCExpression> typeArgs = typeArgumentsOpt();
  1.3348 +        int identPos = token.pos;
  1.3349 +        Name name = ident();
  1.3350 +        int createPos = token.pos;
  1.3351 +        List<JCExpression> args = (token.kind == LPAREN)
  1.3352 +            ? arguments() : List.<JCExpression>nil();
  1.3353 +        JCClassDecl body = null;
  1.3354 +        if (token.kind == LBRACE) {
  1.3355 +            JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
  1.3356 +            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
  1.3357 +            body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
  1.3358 +        }
  1.3359 +        if (args.isEmpty() && body == null)
  1.3360 +            createPos = identPos;
  1.3361 +        JCIdent ident = F.at(identPos).Ident(enumName);
  1.3362 +        JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
  1.3363 +        if (createPos != identPos)
  1.3364 +            storeEnd(create, S.prevToken().endPos);
  1.3365 +        ident = F.at(identPos).Ident(enumName);
  1.3366 +        JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
  1.3367 +        attach(result, dc);
  1.3368 +        return result;
  1.3369 +    }
  1.3370 +
  1.3371 +    /** TypeList = Type {"," Type}
  1.3372 +     */
  1.3373 +    List<JCExpression> typeList() {
  1.3374 +        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  1.3375 +        ts.append(parseType());
  1.3376 +        while (token.kind == COMMA) {
  1.3377 +            nextToken();
  1.3378 +            ts.append(parseType());
  1.3379 +        }
  1.3380 +        return ts.toList();
  1.3381 +    }
  1.3382 +
  1.3383 +    /** ClassBody     = "{" {ClassBodyDeclaration} "}"
  1.3384 +     *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
  1.3385 +     */
  1.3386 +    List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
  1.3387 +        accept(LBRACE);
  1.3388 +        if (token.pos <= endPosTable.errorEndPos) {
  1.3389 +            // error recovery
  1.3390 +            skip(false, true, false, false);
  1.3391 +            if (token.kind == LBRACE)
  1.3392 +                nextToken();
  1.3393 +        }
  1.3394 +        ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
  1.3395 +        while (token.kind != RBRACE && token.kind != EOF) {
  1.3396 +            defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
  1.3397 +            if (token.pos <= endPosTable.errorEndPos) {
  1.3398 +               // error recovery
  1.3399 +               skip(false, true, true, false);
  1.3400 +           }
  1.3401 +        }
  1.3402 +        accept(RBRACE);
  1.3403 +        return defs.toList();
  1.3404 +    }
  1.3405 +
  1.3406 +    /** ClassBodyDeclaration =
  1.3407 +     *      ";"
  1.3408 +     *    | [STATIC] Block
  1.3409 +     *    | ModifiersOpt
  1.3410 +     *      ( Type Ident
  1.3411 +     *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
  1.3412 +     *      | VOID Ident VoidMethodDeclaratorRest
  1.3413 +     *      | TypeParameters [Annotations]
  1.3414 +     *        ( Type Ident MethodDeclaratorRest
  1.3415 +     *        | VOID Ident VoidMethodDeclaratorRest
  1.3416 +     *        )
  1.3417 +     *      | Ident ConstructorDeclaratorRest
  1.3418 +     *      | TypeParameters Ident ConstructorDeclaratorRest
  1.3419 +     *      | ClassOrInterfaceOrEnumDeclaration
  1.3420 +     *      )
  1.3421 +     *  InterfaceBodyDeclaration =
  1.3422 +     *      ";"
  1.3423 +     *    | ModifiersOpt
  1.3424 +     *      ( Type Ident
  1.3425 +     *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
  1.3426 +     *      | VOID Ident MethodDeclaratorRest
  1.3427 +     *      | TypeParameters [Annotations]
  1.3428 +     *        ( Type Ident MethodDeclaratorRest
  1.3429 +     *        | VOID Ident VoidMethodDeclaratorRest
  1.3430 +     *        )
  1.3431 +     *      | ClassOrInterfaceOrEnumDeclaration
  1.3432 +     *      )
  1.3433 +     *
  1.3434 +     */
  1.3435 +    protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
  1.3436 +        if (token.kind == SEMI) {
  1.3437 +            nextToken();
  1.3438 +            return List.<JCTree>nil();
  1.3439 +        } else {
  1.3440 +            Comment dc = token.comment(CommentStyle.JAVADOC);
  1.3441 +            int pos = token.pos;
  1.3442 +            JCModifiers mods = modifiersOpt();
  1.3443 +            if (token.kind == CLASS ||
  1.3444 +                token.kind == INTERFACE ||
  1.3445 +                allowEnums && token.kind == ENUM) {
  1.3446 +                return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
  1.3447 +            } else if (token.kind == LBRACE && !isInterface &&
  1.3448 +                       (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
  1.3449 +                       mods.annotations.isEmpty()) {
  1.3450 +                return List.<JCTree>of(block(pos, mods.flags));
  1.3451 +            } else {
  1.3452 +                pos = token.pos;
  1.3453 +                List<JCTypeParameter> typarams = typeParametersOpt();
  1.3454 +                // if there are type parameters but no modifiers, save the start
  1.3455 +                // position of the method in the modifiers.
  1.3456 +                if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
  1.3457 +                    mods.pos = pos;
  1.3458 +                    storeEnd(mods, pos);
  1.3459 +                }
  1.3460 +                List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
  1.3461 +
  1.3462 +                if (annosAfterParams.nonEmpty()) {
  1.3463 +                    checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
  1.3464 +                    mods.annotations = mods.annotations.appendList(annosAfterParams);
  1.3465 +                    if (mods.pos == Position.NOPOS)
  1.3466 +                        mods.pos = mods.annotations.head.pos;
  1.3467 +                }
  1.3468 +
  1.3469 +                Token tk = token;
  1.3470 +                pos = token.pos;
  1.3471 +                JCExpression type;
  1.3472 +                boolean isVoid = token.kind == VOID;
  1.3473 +                if (isVoid) {
  1.3474 +                    type = to(F.at(pos).TypeIdent(TypeTag.VOID));
  1.3475 +                    nextToken();
  1.3476 +                } else {
  1.3477 +                    // method returns types are un-annotated types
  1.3478 +                    type = unannotatedType();
  1.3479 +                }
  1.3480 +                if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
  1.3481 +                    if (isInterface || tk.name() != className)
  1.3482 +                        error(pos, "invalid.meth.decl.ret.type.req");
  1.3483 +                    else if (annosAfterParams.nonEmpty())
  1.3484 +                        illegal(annosAfterParams.head.pos);
  1.3485 +                    return List.of(methodDeclaratorRest(
  1.3486 +                        pos, mods, null, names.init, typarams,
  1.3487 +                        isInterface, true, dc));
  1.3488 +                } else {
  1.3489 +                    pos = token.pos;
  1.3490 +                    Name name = ident();
  1.3491 +                    if (token.kind == LPAREN) {
  1.3492 +                        return List.of(methodDeclaratorRest(
  1.3493 +                            pos, mods, type, name, typarams,
  1.3494 +                            isInterface, isVoid, dc));
  1.3495 +                    } else if (!isVoid && typarams.isEmpty()) {
  1.3496 +                        List<JCTree> defs =
  1.3497 +                            variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
  1.3498 +                                                    new ListBuffer<JCTree>()).toList();
  1.3499 +                        storeEnd(defs.last(), token.endPos);
  1.3500 +                        accept(SEMI);
  1.3501 +                        return defs;
  1.3502 +                    } else {
  1.3503 +                        pos = token.pos;
  1.3504 +                        List<JCTree> err = isVoid
  1.3505 +                            ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
  1.3506 +                                List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
  1.3507 +                            : null;
  1.3508 +                        return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
  1.3509 +                    }
  1.3510 +                }
  1.3511 +            }
  1.3512 +        }
  1.3513 +    }
  1.3514 +
  1.3515 +    /** MethodDeclaratorRest =
  1.3516 +     *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
  1.3517 +     *  VoidMethodDeclaratorRest =
  1.3518 +     *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
  1.3519 +     *  ConstructorDeclaratorRest =
  1.3520 +     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
  1.3521 +     */
  1.3522 +    protected JCTree methodDeclaratorRest(int pos,
  1.3523 +                              JCModifiers mods,
  1.3524 +                              JCExpression type,
  1.3525 +                              Name name,
  1.3526 +                              List<JCTypeParameter> typarams,
  1.3527 +                              boolean isInterface, boolean isVoid,
  1.3528 +                              Comment dc) {
  1.3529 +        if (isInterface && (mods.flags & Flags.STATIC) != 0) {
  1.3530 +            checkStaticInterfaceMethods();
  1.3531 +        }
  1.3532 +        JCVariableDecl prevReceiverParam = this.receiverParam;
  1.3533 +        try {
  1.3534 +            this.receiverParam = null;
  1.3535 +            // Parsing formalParameters sets the receiverParam, if present
  1.3536 +            List<JCVariableDecl> params = formalParameters();
  1.3537 +            if (!isVoid) type = bracketsOpt(type);
  1.3538 +            List<JCExpression> thrown = List.nil();
  1.3539 +            if (token.kind == THROWS) {
  1.3540 +                nextToken();
  1.3541 +                thrown = qualidentList();
  1.3542 +            }
  1.3543 +            JCBlock body = null;
  1.3544 +            JCExpression defaultValue;
  1.3545 +            if (token.kind == LBRACE) {
  1.3546 +                body = block();
  1.3547 +                defaultValue = null;
  1.3548 +            } else {
  1.3549 +                if (token.kind == DEFAULT) {
  1.3550 +                    accept(DEFAULT);
  1.3551 +                    defaultValue = annotationValue();
  1.3552 +                } else {
  1.3553 +                    defaultValue = null;
  1.3554 +                }
  1.3555 +                accept(SEMI);
  1.3556 +                if (token.pos <= endPosTable.errorEndPos) {
  1.3557 +                    // error recovery
  1.3558 +                    skip(false, true, false, false);
  1.3559 +                    if (token.kind == LBRACE) {
  1.3560 +                        body = block();
  1.3561 +                    }
  1.3562 +                }
  1.3563 +            }
  1.3564 +
  1.3565 +            JCMethodDecl result =
  1.3566 +                    toP(F.at(pos).MethodDef(mods, name, type, typarams,
  1.3567 +                                            receiverParam, params, thrown,
  1.3568 +                                            body, defaultValue));
  1.3569 +            attach(result, dc);
  1.3570 +            return result;
  1.3571 +        } finally {
  1.3572 +            this.receiverParam = prevReceiverParam;
  1.3573 +        }
  1.3574 +    }
  1.3575 +
  1.3576 +    /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
  1.3577 +     */
  1.3578 +    List<JCExpression> qualidentList() {
  1.3579 +        ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
  1.3580 +
  1.3581 +        List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
  1.3582 +        JCExpression qi = qualident(true);
  1.3583 +        if (!typeAnnos.isEmpty()) {
  1.3584 +            JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  1.3585 +            ts.append(at);
  1.3586 +        } else {
  1.3587 +            ts.append(qi);
  1.3588 +        }
  1.3589 +        while (token.kind == COMMA) {
  1.3590 +            nextToken();
  1.3591 +
  1.3592 +            typeAnnos = typeAnnotationsOpt();
  1.3593 +            qi = qualident(true);
  1.3594 +            if (!typeAnnos.isEmpty()) {
  1.3595 +                JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
  1.3596 +                ts.append(at);
  1.3597 +            } else {
  1.3598 +                ts.append(qi);
  1.3599 +            }
  1.3600 +        }
  1.3601 +        return ts.toList();
  1.3602 +    }
  1.3603 +
  1.3604 +    /**
  1.3605 +     *  {@literal
  1.3606 +     *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
  1.3607 +     *  }
  1.3608 +     */
  1.3609 +    List<JCTypeParameter> typeParametersOpt() {
  1.3610 +        if (token.kind == LT) {
  1.3611 +            checkGenerics();
  1.3612 +            ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
  1.3613 +            nextToken();
  1.3614 +            typarams.append(typeParameter());
  1.3615 +            while (token.kind == COMMA) {
  1.3616 +                nextToken();
  1.3617 +                typarams.append(typeParameter());
  1.3618 +            }
  1.3619 +            accept(GT);
  1.3620 +            return typarams.toList();
  1.3621 +        } else {
  1.3622 +            return List.nil();
  1.3623 +        }
  1.3624 +    }
  1.3625 +
  1.3626 +    /**
  1.3627 +     *  {@literal
  1.3628 +     *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
  1.3629 +     *  TypeParameterBound = EXTENDS Type {"&" Type}
  1.3630 +     *  TypeVariable = Ident
  1.3631 +     *  }
  1.3632 +     */
  1.3633 +    JCTypeParameter typeParameter() {
  1.3634 +        int pos = token.pos;
  1.3635 +        List<JCAnnotation> annos = typeAnnotationsOpt();
  1.3636 +        Name name = ident();
  1.3637 +        ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
  1.3638 +        if (token.kind == EXTENDS) {
  1.3639 +            nextToken();
  1.3640 +            bounds.append(parseType());
  1.3641 +            while (token.kind == AMP) {
  1.3642 +                nextToken();
  1.3643 +                bounds.append(parseType());
  1.3644 +            }
  1.3645 +        }
  1.3646 +        return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
  1.3647 +    }
  1.3648 +
  1.3649 +    /** FormalParameters = "(" [ FormalParameterList ] ")"
  1.3650 +     *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
  1.3651 +     *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
  1.3652 +     */
  1.3653 +    List<JCVariableDecl> formalParameters() {
  1.3654 +        return formalParameters(false);
  1.3655 +    }
  1.3656 +    List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
  1.3657 +        ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  1.3658 +        JCVariableDecl lastParam;
  1.3659 +        accept(LPAREN);
  1.3660 +        if (token.kind != RPAREN) {
  1.3661 +            this.allowThisIdent = true;
  1.3662 +            lastParam = formalParameter(lambdaParameters);
  1.3663 +            if (lastParam.nameexpr != null) {
  1.3664 +                this.receiverParam = lastParam;
  1.3665 +            } else {
  1.3666 +                params.append(lastParam);
  1.3667 +            }
  1.3668 +            this.allowThisIdent = false;
  1.3669 +            while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) {
  1.3670 +                nextToken();
  1.3671 +                params.append(lastParam = formalParameter(lambdaParameters));
  1.3672 +            }
  1.3673 +        }
  1.3674 +        accept(RPAREN);
  1.3675 +        return params.toList();
  1.3676 +    }
  1.3677 +
  1.3678 +    List<JCVariableDecl> implicitParameters(boolean hasParens) {
  1.3679 +        if (hasParens) {
  1.3680 +            accept(LPAREN);
  1.3681 +        }
  1.3682 +        ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
  1.3683 +        if (token.kind != RPAREN && token.kind != ARROW) {
  1.3684 +            params.append(implicitParameter());
  1.3685 +            while (token.kind == COMMA) {
  1.3686 +                nextToken();
  1.3687 +                params.append(implicitParameter());
  1.3688 +            }
  1.3689 +        }
  1.3690 +        if (hasParens) {
  1.3691 +            accept(RPAREN);
  1.3692 +        }
  1.3693 +        return params.toList();
  1.3694 +    }
  1.3695 +
  1.3696 +    JCModifiers optFinal(long flags) {
  1.3697 +        JCModifiers mods = modifiersOpt();
  1.3698 +        checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
  1.3699 +        mods.flags |= flags;
  1.3700 +        return mods;
  1.3701 +    }
  1.3702 +
  1.3703 +    /**
  1.3704 +     * Inserts the annotations (and possibly a new array level)
  1.3705 +     * to the left-most type in an array or nested type.
  1.3706 +     *
  1.3707 +     * When parsing a type like {@code @B Outer.Inner @A []}, the
  1.3708 +     * {@code @A} annotation should target the array itself, while
  1.3709 +     * {@code @B} targets the nested type {@code Outer}.
  1.3710 +     *
  1.3711 +     * Currently the parser parses the annotation first, then
  1.3712 +     * the array, and then inserts the annotation to the left-most
  1.3713 +     * nested type.
  1.3714 +     *
  1.3715 +     * When {@code createNewLevel} is true, then a new array
  1.3716 +     * level is inserted as the most inner type, and have the
  1.3717 +     * annotations target it.  This is useful in the case of
  1.3718 +     * varargs, e.g. {@code String @A [] @B ...}, as the parser
  1.3719 +     * first parses the type {@code String @A []} then inserts
  1.3720 +     * a new array level with {@code @B} annotation.
  1.3721 +     */
  1.3722 +    private JCExpression insertAnnotationsToMostInner(
  1.3723 +            JCExpression type, List<JCAnnotation> annos,
  1.3724 +            boolean createNewLevel) {
  1.3725 +        int origEndPos = getEndPos(type);
  1.3726 +        JCExpression mostInnerType = type;
  1.3727 +        JCArrayTypeTree mostInnerArrayType = null;
  1.3728 +        while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
  1.3729 +            mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
  1.3730 +            mostInnerType = mostInnerArrayType.elemtype;
  1.3731 +        }
  1.3732 +
  1.3733 +        if (createNewLevel) {
  1.3734 +            mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
  1.3735 +        }
  1.3736 +
  1.3737 +        JCExpression mostInnerTypeToReturn = mostInnerType;
  1.3738 +        if (annos.nonEmpty()) {
  1.3739 +            JCExpression lastToModify = mostInnerType;
  1.3740 +
  1.3741 +            while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
  1.3742 +                    TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
  1.3743 +                while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
  1.3744 +                    lastToModify = mostInnerType;
  1.3745 +                    mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
  1.3746 +                }
  1.3747 +                while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
  1.3748 +                    lastToModify = mostInnerType;
  1.3749 +                    mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
  1.3750 +                }
  1.3751 +            }
  1.3752 +
  1.3753 +            mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
  1.3754 +
  1.3755 +            if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
  1.3756 +                ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
  1.3757 +            } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
  1.3758 +                ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
  1.3759 +            } else {
  1.3760 +                // We never saw a SELECT or TYPEAPPLY, return the annotated type.
  1.3761 +                mostInnerTypeToReturn = mostInnerType;
  1.3762 +            }
  1.3763 +        }
  1.3764 +
  1.3765 +        if (mostInnerArrayType == null) {
  1.3766 +            return mostInnerTypeToReturn;
  1.3767 +        } else {
  1.3768 +            mostInnerArrayType.elemtype = mostInnerTypeToReturn;
  1.3769 +            storeEnd(type, origEndPos);
  1.3770 +            return type;
  1.3771 +        }
  1.3772 +    }
  1.3773 +
  1.3774 +    /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
  1.3775 +     *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
  1.3776 +     */
  1.3777 +    protected JCVariableDecl formalParameter() {
  1.3778 +        return formalParameter(false);
  1.3779 +    }
  1.3780 +    protected JCVariableDecl formalParameter(boolean lambdaParameter) {
  1.3781 +        JCModifiers mods = optFinal(Flags.PARAMETER);
  1.3782 +        // need to distinguish between vararg annos and array annos
  1.3783 +        // look at typeAnnotationsPushedBack comment
  1.3784 +        this.permitTypeAnnotationsPushBack = true;
  1.3785 +        JCExpression type = parseType();
  1.3786 +        this.permitTypeAnnotationsPushBack = false;
  1.3787 +
  1.3788 +        if (token.kind == ELLIPSIS) {
  1.3789 +            List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
  1.3790 +            typeAnnotationsPushedBack = List.nil();
  1.3791 +            checkVarargs();
  1.3792 +            mods.flags |= Flags.VARARGS;
  1.3793 +            // insert var arg type annotations
  1.3794 +            type = insertAnnotationsToMostInner(type, varargsAnnos, true);
  1.3795 +            nextToken();
  1.3796 +        } else {
  1.3797 +            // if not a var arg, then typeAnnotationsPushedBack should be null
  1.3798 +            if (typeAnnotationsPushedBack.nonEmpty()) {
  1.3799 +                reportSyntaxError(typeAnnotationsPushedBack.head.pos,
  1.3800 +                        "illegal.start.of.type");
  1.3801 +            }
  1.3802 +            typeAnnotationsPushedBack = List.nil();
  1.3803 +        }
  1.3804 +        return variableDeclaratorId(mods, type, lambdaParameter);
  1.3805 +    }
  1.3806 +
  1.3807 +    protected JCVariableDecl implicitParameter() {
  1.3808 +        JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
  1.3809 +        return variableDeclaratorId(mods, null, true);
  1.3810 +    }
  1.3811 +
  1.3812 +/* ---------- auxiliary methods -------------- */
  1.3813 +
  1.3814 +    void error(int pos, String key, Object ... args) {
  1.3815 +        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
  1.3816 +    }
  1.3817 +
  1.3818 +    void error(DiagnosticPosition pos, String key, Object ... args) {
  1.3819 +        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
  1.3820 +    }
  1.3821 +
  1.3822 +    void warning(int pos, String key, Object ... args) {
  1.3823 +        log.warning(pos, key, args);
  1.3824 +    }
  1.3825 +
  1.3826 +    /** Check that given tree is a legal expression statement.
  1.3827 +     */
  1.3828 +    protected JCExpression checkExprStat(JCExpression t) {
  1.3829 +        if (!TreeInfo.isExpressionStatement(t)) {
  1.3830 +            JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
  1.3831 +            error(ret, "not.stmt");
  1.3832 +            return ret;
  1.3833 +        } else {
  1.3834 +            return t;
  1.3835 +        }
  1.3836 +    }
  1.3837 +
  1.3838 +    /** Return precedence of operator represented by token,
  1.3839 +     *  -1 if token is not a binary operator. @see TreeInfo.opPrec
  1.3840 +     */
  1.3841 +    static int prec(TokenKind token) {
  1.3842 +        JCTree.Tag oc = optag(token);
  1.3843 +        return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
  1.3844 +    }
  1.3845 +
  1.3846 +    /**
  1.3847 +     * Return the lesser of two positions, making allowance for either one
  1.3848 +     * being unset.
  1.3849 +     */
  1.3850 +    static int earlier(int pos1, int pos2) {
  1.3851 +        if (pos1 == Position.NOPOS)
  1.3852 +            return pos2;
  1.3853 +        if (pos2 == Position.NOPOS)
  1.3854 +            return pos1;
  1.3855 +        return (pos1 < pos2 ? pos1 : pos2);
  1.3856 +    }
  1.3857 +
  1.3858 +    /** Return operation tag of binary operator represented by token,
  1.3859 +     *  No_TAG if token is not a binary operator.
  1.3860 +     */
  1.3861 +    static JCTree.Tag optag(TokenKind token) {
  1.3862 +        switch (token) {
  1.3863 +        case BARBAR:
  1.3864 +            return OR;
  1.3865 +        case AMPAMP:
  1.3866 +            return AND;
  1.3867 +        case BAR:
  1.3868 +            return BITOR;
  1.3869 +        case BAREQ:
  1.3870 +            return BITOR_ASG;
  1.3871 +        case CARET:
  1.3872 +            return BITXOR;
  1.3873 +        case CARETEQ:
  1.3874 +            return BITXOR_ASG;
  1.3875 +        case AMP:
  1.3876 +            return BITAND;
  1.3877 +        case AMPEQ:
  1.3878 +            return BITAND_ASG;
  1.3879 +        case EQEQ:
  1.3880 +            return JCTree.Tag.EQ;
  1.3881 +        case BANGEQ:
  1.3882 +            return NE;
  1.3883 +        case LT:
  1.3884 +            return JCTree.Tag.LT;
  1.3885 +        case GT:
  1.3886 +            return JCTree.Tag.GT;
  1.3887 +        case LTEQ:
  1.3888 +            return LE;
  1.3889 +        case GTEQ:
  1.3890 +            return GE;
  1.3891 +        case LTLT:
  1.3892 +            return SL;
  1.3893 +        case LTLTEQ:
  1.3894 +            return SL_ASG;
  1.3895 +        case GTGT:
  1.3896 +            return SR;
  1.3897 +        case GTGTEQ:
  1.3898 +            return SR_ASG;
  1.3899 +        case GTGTGT:
  1.3900 +            return USR;
  1.3901 +        case GTGTGTEQ:
  1.3902 +            return USR_ASG;
  1.3903 +        case PLUS:
  1.3904 +            return JCTree.Tag.PLUS;
  1.3905 +        case PLUSEQ:
  1.3906 +            return PLUS_ASG;
  1.3907 +        case SUB:
  1.3908 +            return MINUS;
  1.3909 +        case SUBEQ:
  1.3910 +            return MINUS_ASG;
  1.3911 +        case STAR:
  1.3912 +            return MUL;
  1.3913 +        case STAREQ:
  1.3914 +            return MUL_ASG;
  1.3915 +        case SLASH:
  1.3916 +            return DIV;
  1.3917 +        case SLASHEQ:
  1.3918 +            return DIV_ASG;
  1.3919 +        case PERCENT:
  1.3920 +            return MOD;
  1.3921 +        case PERCENTEQ:
  1.3922 +            return MOD_ASG;
  1.3923 +        case INSTANCEOF:
  1.3924 +            return TYPETEST;
  1.3925 +        default:
  1.3926 +            return NO_TAG;
  1.3927 +        }
  1.3928 +    }
  1.3929 +
  1.3930 +    /** Return operation tag of unary operator represented by token,
  1.3931 +     *  No_TAG if token is not a binary operator.
  1.3932 +     */
  1.3933 +    static JCTree.Tag unoptag(TokenKind token) {
  1.3934 +        switch (token) {
  1.3935 +        case PLUS:
  1.3936 +            return POS;
  1.3937 +        case SUB:
  1.3938 +            return NEG;
  1.3939 +        case BANG:
  1.3940 +            return NOT;
  1.3941 +        case TILDE:
  1.3942 +            return COMPL;
  1.3943 +        case PLUSPLUS:
  1.3944 +            return PREINC;
  1.3945 +        case SUBSUB:
  1.3946 +            return PREDEC;
  1.3947 +        default:
  1.3948 +            return NO_TAG;
  1.3949 +        }
  1.3950 +    }
  1.3951 +
  1.3952 +    /** Return type tag of basic type represented by token,
  1.3953 +     *  NONE if token is not a basic type identifier.
  1.3954 +     */
  1.3955 +    static TypeTag typetag(TokenKind token) {
  1.3956 +        switch (token) {
  1.3957 +        case BYTE:
  1.3958 +            return TypeTag.BYTE;
  1.3959 +        case CHAR:
  1.3960 +            return TypeTag.CHAR;
  1.3961 +        case SHORT:
  1.3962 +            return TypeTag.SHORT;
  1.3963 +        case INT:
  1.3964 +            return TypeTag.INT;
  1.3965 +        case LONG:
  1.3966 +            return TypeTag.LONG;
  1.3967 +        case FLOAT:
  1.3968 +            return TypeTag.FLOAT;
  1.3969 +        case DOUBLE:
  1.3970 +            return TypeTag.DOUBLE;
  1.3971 +        case BOOLEAN:
  1.3972 +            return TypeTag.BOOLEAN;
  1.3973 +        default:
  1.3974 +            return TypeTag.NONE;
  1.3975 +        }
  1.3976 +    }
  1.3977 +
  1.3978 +    void checkGenerics() {
  1.3979 +        if (!allowGenerics) {
  1.3980 +            error(token.pos, "generics.not.supported.in.source", source.name);
  1.3981 +            allowGenerics = true;
  1.3982 +        }
  1.3983 +    }
  1.3984 +    void checkVarargs() {
  1.3985 +        if (!allowVarargs) {
  1.3986 +            error(token.pos, "varargs.not.supported.in.source", source.name);
  1.3987 +            allowVarargs = true;
  1.3988 +        }
  1.3989 +    }
  1.3990 +    void checkForeach() {
  1.3991 +        if (!allowForeach) {
  1.3992 +            error(token.pos, "foreach.not.supported.in.source", source.name);
  1.3993 +            allowForeach = true;
  1.3994 +        }
  1.3995 +    }
  1.3996 +    void checkStaticImports() {
  1.3997 +        if (!allowStaticImport) {
  1.3998 +            error(token.pos, "static.import.not.supported.in.source", source.name);
  1.3999 +            allowStaticImport = true;
  1.4000 +        }
  1.4001 +    }
  1.4002 +    void checkAnnotations() {
  1.4003 +        if (!allowAnnotations) {
  1.4004 +            error(token.pos, "annotations.not.supported.in.source", source.name);
  1.4005 +            allowAnnotations = true;
  1.4006 +        }
  1.4007 +    }
  1.4008 +    void checkDiamond() {
  1.4009 +        if (!allowDiamond) {
  1.4010 +            error(token.pos, "diamond.not.supported.in.source", source.name);
  1.4011 +            allowDiamond = true;
  1.4012 +        }
  1.4013 +    }
  1.4014 +    void checkMulticatch() {
  1.4015 +        if (!allowMulticatch) {
  1.4016 +            error(token.pos, "multicatch.not.supported.in.source", source.name);
  1.4017 +            allowMulticatch = true;
  1.4018 +        }
  1.4019 +    }
  1.4020 +    void checkTryWithResources() {
  1.4021 +        if (!allowTWR) {
  1.4022 +            error(token.pos, "try.with.resources.not.supported.in.source", source.name);
  1.4023 +            allowTWR = true;
  1.4024 +        }
  1.4025 +    }
  1.4026 +    void checkLambda() {
  1.4027 +        if (!allowLambda) {
  1.4028 +            log.error(token.pos, "lambda.not.supported.in.source", source.name);
  1.4029 +            allowLambda = true;
  1.4030 +        }
  1.4031 +    }
  1.4032 +    void checkMethodReferences() {
  1.4033 +        if (!allowMethodReferences) {
  1.4034 +            log.error(token.pos, "method.references.not.supported.in.source", source.name);
  1.4035 +            allowMethodReferences = true;
  1.4036 +        }
  1.4037 +    }
  1.4038 +    void checkDefaultMethods() {
  1.4039 +        if (!allowDefaultMethods) {
  1.4040 +            log.error(token.pos, "default.methods.not.supported.in.source", source.name);
  1.4041 +            allowDefaultMethods = true;
  1.4042 +        }
  1.4043 +    }
  1.4044 +    void checkIntersectionTypesInCast() {
  1.4045 +        if (!allowIntersectionTypesInCast) {
  1.4046 +            log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
  1.4047 +            allowIntersectionTypesInCast = true;
  1.4048 +        }
  1.4049 +    }
  1.4050 +    void checkStaticInterfaceMethods() {
  1.4051 +        if (!allowStaticInterfaceMethods) {
  1.4052 +            log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
  1.4053 +            allowStaticInterfaceMethods = true;
  1.4054 +        }
  1.4055 +    }
  1.4056 +    void checkTypeAnnotations() {
  1.4057 +        if (!allowTypeAnnotations) {
  1.4058 +            log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
  1.4059 +            allowTypeAnnotations = true;
  1.4060 +        }
  1.4061 +    }
  1.4062 +    void checkAnnotationsAfterTypeParams(int pos) {
  1.4063 +        if (!allowAnnotationsAfterTypeParams) {
  1.4064 +            log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);
  1.4065 +            allowAnnotationsAfterTypeParams = true;
  1.4066 +        }
  1.4067 +    }
  1.4068 +
  1.4069 +    /*
  1.4070 +     * a functional source tree and end position mappings
  1.4071 +     */
  1.4072 +    protected static class SimpleEndPosTable extends AbstractEndPosTable {
  1.4073 +
  1.4074 +        private final IntHashTable endPosMap;
  1.4075 +
  1.4076 +        SimpleEndPosTable(JavacParser parser) {
  1.4077 +            super(parser);
  1.4078 +            endPosMap = new IntHashTable();
  1.4079 +        }
  1.4080 +
  1.4081 +        public void storeEnd(JCTree tree, int endpos) {
  1.4082 +            endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos,
  1.4083 +                                 endPosMap.lookup(tree));
  1.4084 +        }
  1.4085 +
  1.4086 +        protected <T extends JCTree> T to(T t) {
  1.4087 +            storeEnd(t, parser.token.endPos);
  1.4088 +            return t;
  1.4089 +        }
  1.4090 +
  1.4091 +        protected <T extends JCTree> T toP(T t) {
  1.4092 +            storeEnd(t, parser.S.prevToken().endPos);
  1.4093 +            return t;
  1.4094 +        }
  1.4095 +
  1.4096 +        public int getEndPos(JCTree tree) {
  1.4097 +            int value = endPosMap.getFromIndex(endPosMap.lookup(tree));
  1.4098 +            // As long as Position.NOPOS==-1, this just returns value.
  1.4099 +            return (value == -1) ? Position.NOPOS : value;
  1.4100 +        }
  1.4101 +
  1.4102 +        public int replaceTree(JCTree oldTree, JCTree newTree) {
  1.4103 +            int pos = endPosMap.remove(oldTree);
  1.4104 +            if (pos != -1) {
  1.4105 +                storeEnd(newTree, pos);
  1.4106 +                return pos;
  1.4107 +            }
  1.4108 +            return Position.NOPOS;
  1.4109 +        }
  1.4110 +    }
  1.4111 +
  1.4112 +    /*
  1.4113 +     * a default skeletal implementation without any mapping overhead.
  1.4114 +     */
  1.4115 +    protected static class EmptyEndPosTable extends AbstractEndPosTable {
  1.4116 +
  1.4117 +        EmptyEndPosTable(JavacParser parser) {
  1.4118 +            super(parser);
  1.4119 +        }
  1.4120 +
  1.4121 +        public void storeEnd(JCTree tree, int endpos) { /* empty */ }
  1.4122 +
  1.4123 +        protected <T extends JCTree> T to(T t) {
  1.4124 +            return t;
  1.4125 +        }
  1.4126 +
  1.4127 +        protected <T extends JCTree> T toP(T t) {
  1.4128 +            return t;
  1.4129 +        }
  1.4130 +
  1.4131 +        public int getEndPos(JCTree tree) {
  1.4132 +            return Position.NOPOS;
  1.4133 +        }
  1.4134 +
  1.4135 +        public int replaceTree(JCTree oldTree, JCTree newTree) {
  1.4136 +            return Position.NOPOS;
  1.4137 +        }
  1.4138 +
  1.4139 +    }
  1.4140 +
  1.4141 +    protected static abstract class AbstractEndPosTable implements EndPosTable {
  1.4142 +        /**
  1.4143 +         * The current parser.
  1.4144 +         */
  1.4145 +        protected JavacParser parser;
  1.4146 +
  1.4147 +        /**
  1.4148 +         * Store the last error position.
  1.4149 +         */
  1.4150 +        protected int errorEndPos;
  1.4151 +
  1.4152 +        public AbstractEndPosTable(JavacParser parser) {
  1.4153 +            this.parser = parser;
  1.4154 +        }
  1.4155 +
  1.4156 +        /**
  1.4157 +         * Store current token's ending position for a tree, the value of which
  1.4158 +         * will be the greater of last error position and the ending position of
  1.4159 +         * the current token.
  1.4160 +         * @param t The tree.
  1.4161 +         */
  1.4162 +        protected abstract <T extends JCTree> T to(T t);
  1.4163 +
  1.4164 +        /**
  1.4165 +         * Store current token's ending position for a tree, the value of which
  1.4166 +         * will be the greater of last error position and the ending position of
  1.4167 +         * the previous token.
  1.4168 +         * @param t The tree.
  1.4169 +         */
  1.4170 +        protected abstract <T extends JCTree> T toP(T t);
  1.4171 +
  1.4172 +        /**
  1.4173 +         * Set the error position during the parsing phases, the value of which
  1.4174 +         * will be set only if it is greater than the last stored error position.
  1.4175 +         * @param errPos The error position
  1.4176 +         */
  1.4177 +        protected void setErrorEndPos(int errPos) {
  1.4178 +            if (errPos > errorEndPos) {
  1.4179 +                errorEndPos = errPos;
  1.4180 +            }
  1.4181 +        }
  1.4182 +
  1.4183 +        protected void setParser(JavacParser parser) {
  1.4184 +            this.parser = parser;
  1.4185 +        }
  1.4186 +    }
  1.4187 +}

mercurial