JavacParser.java revision 3827:44bdefe64114
1/*
2 * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.tools.javac.parser;
27
28import java.util.*;
29import java.util.stream.Collectors;
30
31import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
32import com.sun.source.tree.ModuleTree.ModuleKind;
33
34import com.sun.tools.javac.code.*;
35import com.sun.tools.javac.parser.Tokens.*;
36import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
37import com.sun.tools.javac.resources.CompilerProperties;
38import com.sun.tools.javac.resources.CompilerProperties.Errors;
39import com.sun.tools.javac.tree.*;
40import com.sun.tools.javac.tree.JCTree.*;
41import com.sun.tools.javac.util.*;
42import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
43import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
44import com.sun.tools.javac.util.List;
45
46import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
47import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
48import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
49import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
50import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
51import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
52import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
53import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
54import static com.sun.tools.javac.tree.JCTree.Tag.*;
55
56/** The parser maps a token sequence into an abstract syntax
57 *  tree. It operates by recursive descent, with code derived
58 *  systematically from an LL(1) grammar. For efficiency reasons, an
59 *  operator precedence scheme is used for parsing binary operation
60 *  expressions.
61 *
62 *  <p><b>This is NOT part of any supported API.
63 *  If you write code that depends on this, you do so at your own risk.
64 *  This code and its internal interfaces are subject to change or
65 *  deletion without notice.</b>
66 */
67public class JavacParser implements Parser {
68
69    /** The number of precedence levels of infix operators.
70     */
71    private static final int infixPrecedenceLevels = 10;
72
73    /** The scanner used for lexical analysis.
74     */
75    protected Lexer S;
76
77    /** The factory to be used for abstract syntax tree construction.
78     */
79    protected TreeMaker F;
80
81    /** The log to be used for error diagnostics.
82     */
83    private Log log;
84
85    /** The Source language setting. */
86    private Source source;
87
88    /** The name table. */
89    private Names names;
90
91    /** End position mappings container */
92    protected final AbstractEndPosTable endPosTable;
93
94    // Because of javac's limited lookahead, some contexts are ambiguous in
95    // the presence of type annotations even though they are not ambiguous
96    // in the absence of type annotations.  Consider this code:
97    //   void m(String [] m) { }
98    //   void m(String ... m) { }
99    // After parsing "String", javac calls bracketsOpt which immediately
100    // returns if the next character is not '['.  Similarly, javac can see
101    // if the next token is ... and in that case parse an ellipsis.  But in
102    // the presence of type annotations:
103    //   void m(String @A [] m) { }
104    //   void m(String @A ... m) { }
105    // no finite lookahead is enough to determine whether to read array
106    // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
107    // bracketsOpt first reads all the leading annotations and only then
108    // discovers that it needs to fail.  bracketsOpt needs a way to push
109    // back the extra annotations that it read.  (But, bracketsOpt should
110    // not *always* be allowed to push back extra annotations that it finds
111    // -- in most contexts, any such extra annotation is an error.
112    //
113    // The following two variables permit type annotations that have
114    // already been read to be stored for later use.  Alternate
115    // implementations are possible but would cause much larger changes to
116    // the parser.
117
118    /** Type annotations that have already been read but have not yet been used. **/
119    private List<JCAnnotation> typeAnnotationsPushedBack = List.nil();
120
121    /**
122     * If the parser notices extra annotations, then it either immediately
123     * issues an error (if this variable is false) or places the extra
124     * annotations in variable typeAnnotationsPushedBack (if this variable
125     * is true).
126     */
127    private boolean permitTypeAnnotationsPushBack = false;
128
129    interface ErrorRecoveryAction {
130        JCTree doRecover(JavacParser parser);
131    }
132
133    enum BasicErrorRecoveryAction implements ErrorRecoveryAction {
134        BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }},
135        CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }}
136    }
137
138    /** Construct a parser from a given scanner, tree factory and log.
139     */
140    protected JavacParser(ParserFactory fac,
141                     Lexer S,
142                     boolean keepDocComments,
143                     boolean keepLineMap,
144                     boolean keepEndPositions) {
145        this.S = S;
146        nextToken(); // prime the pump
147        this.F = fac.F;
148        this.log = fac.log;
149        this.names = fac.names;
150        this.source = fac.source;
151        this.allowTWR = source.allowTryWithResources();
152        this.allowEffectivelyFinalVariablesInTWR =
153                source.allowEffectivelyFinalVariablesInTryWithResources();
154        this.allowDiamond = source.allowDiamond();
155        this.allowMulticatch = source.allowMulticatch();
156        this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
157        this.allowLambda = source.allowLambda();
158        this.allowMethodReferences = source.allowMethodReferences();
159        this.allowDefaultMethods = source.allowDefaultMethods();
160        this.allowStaticInterfaceMethods = source.allowStaticInterfaceMethods();
161        this.allowIntersectionTypesInCast = source.allowIntersectionTypesInCast();
162        this.allowTypeAnnotations = source.allowTypeAnnotations();
163        this.allowModules = source.allowModules();
164        this.allowAnnotationsAfterTypeParams = source.allowAnnotationsAfterTypeParams();
165        this.allowUnderscoreIdentifier = source.allowUnderscoreIdentifier();
166        this.allowPrivateInterfaceMethods = source.allowPrivateInterfaceMethods();
167        this.keepDocComments = keepDocComments;
168        docComments = newDocCommentTable(keepDocComments, fac);
169        this.keepLineMap = keepLineMap;
170        this.errorTree = F.Erroneous();
171        endPosTable = newEndPosTable(keepEndPositions);
172    }
173
174    protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
175        return  keepEndPositions
176                ? new SimpleEndPosTable(this)
177                : new EmptyEndPosTable(this);
178    }
179
180    protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
181        return keepDocComments ? new LazyDocCommentTable(fac) : null;
182    }
183
184    /** Switch: Should diamond operator be recognized?
185     */
186    boolean allowDiamond;
187
188    /** Switch: Should multicatch clause be accepted?
189     */
190    boolean allowMulticatch;
191
192    /** Switch: should we recognize try-with-resources?
193     */
194    boolean allowTWR;
195
196    /** Switch: should we allow (effectively) final variables as resources in try-with-resources?
197     */
198    boolean allowEffectivelyFinalVariablesInTWR;
199
200    /** Switch: should we fold strings?
201     */
202    boolean allowStringFolding;
203
204    /** Switch: should we recognize lambda expressions?
205     */
206    boolean allowLambda;
207
208    /** Switch: should we allow method/constructor references?
209     */
210    boolean allowMethodReferences;
211
212    /** Switch: should we recognize modules?
213     */
214    boolean allowModules;
215
216    /** Switch: should we allow default methods in interfaces?
217     */
218    boolean allowDefaultMethods;
219
220    /** Switch: should we allow static methods in interfaces?
221     */
222    boolean allowStaticInterfaceMethods;
223
224    /** Switch: should we allow private (instance) methods in interfaces?
225     */
226    boolean allowPrivateInterfaceMethods;
227
228    /** Switch: should we allow intersection types in cast?
229     */
230    boolean allowIntersectionTypesInCast;
231
232    /** Switch: should we keep docComments?
233     */
234    boolean keepDocComments;
235
236    /** Switch: should we keep line table?
237     */
238    boolean keepLineMap;
239
240    /** Switch: should we recognize type annotations?
241     */
242    boolean allowTypeAnnotations;
243
244    /** Switch: should we allow annotations after the method type parameters?
245     */
246    boolean allowAnnotationsAfterTypeParams;
247
248    /** Switch: should we allow '_' as an identifier?
249     */
250    boolean allowUnderscoreIdentifier;
251
252    /** Switch: is "this" allowed as an identifier?
253     * This is needed to parse receiver types.
254     */
255    boolean allowThisIdent;
256
257    /** The type of the method receiver, as specified by a first "this" parameter.
258     */
259    JCVariableDecl receiverParam;
260
261
262    /** When terms are parsed, the mode determines which is expected:
263     *     mode = EXPR        : an expression
264     *     mode = TYPE        : a type
265     *     mode = NOPARAMS    : no parameters allowed for type
266     *     mode = TYPEARG     : type argument
267     */
268    protected static final int EXPR = 0x1;
269    protected static final int TYPE = 0x2;
270    protected static final int NOPARAMS = 0x4;
271    protected static final int TYPEARG = 0x8;
272    protected static final int DIAMOND = 0x10;
273
274    /** The current mode.
275     */
276    protected int mode = 0;
277
278    /** The mode of the term that was parsed last.
279     */
280    protected int lastmode = 0;
281
282    /* ---------- token management -------------- */
283
284    protected Token token;
285
286    public Token token() {
287        return token;
288    }
289
290    public void nextToken() {
291        S.nextToken();
292        token = S.token();
293    }
294
295    protected boolean peekToken(Filter<TokenKind> tk) {
296        return peekToken(0, tk);
297    }
298
299    protected boolean peekToken(int lookahead, Filter<TokenKind> tk) {
300        return tk.accepts(S.token(lookahead + 1).kind);
301    }
302
303    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
304        return peekToken(0, tk1, tk2);
305    }
306
307    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2) {
308        return tk1.accepts(S.token(lookahead + 1).kind) &&
309                tk2.accepts(S.token(lookahead + 2).kind);
310    }
311
312    protected boolean peekToken(Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
313        return peekToken(0, tk1, tk2, tk3);
314    }
315
316    protected boolean peekToken(int lookahead, Filter<TokenKind> tk1, Filter<TokenKind> tk2, Filter<TokenKind> tk3) {
317        return tk1.accepts(S.token(lookahead + 1).kind) &&
318                tk2.accepts(S.token(lookahead + 2).kind) &&
319                tk3.accepts(S.token(lookahead + 3).kind);
320    }
321
322    @SuppressWarnings("unchecked")
323    protected boolean peekToken(Filter<TokenKind>... kinds) {
324        return peekToken(0, kinds);
325    }
326
327    @SuppressWarnings("unchecked")
328    protected boolean peekToken(int lookahead, Filter<TokenKind>... kinds) {
329        for (; lookahead < kinds.length ; lookahead++) {
330            if (!kinds[lookahead].accepts(S.token(lookahead + 1).kind)) {
331                return false;
332            }
333        }
334        return true;
335    }
336
337    /* ---------- error recovery -------------- */
338
339    private JCErroneous errorTree;
340
341    /** Skip forward until a suitable stop token is found.
342     */
343    protected void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
344         while (true) {
345             switch (token.kind) {
346                case SEMI:
347                    nextToken();
348                    return;
349                case PUBLIC:
350                case FINAL:
351                case ABSTRACT:
352                case MONKEYS_AT:
353                case EOF:
354                case CLASS:
355                case INTERFACE:
356                case ENUM:
357                    return;
358                case IMPORT:
359                    if (stopAtImport)
360                        return;
361                    break;
362                case LBRACE:
363                case RBRACE:
364                case PRIVATE:
365                case PROTECTED:
366                case STATIC:
367                case TRANSIENT:
368                case NATIVE:
369                case VOLATILE:
370                case SYNCHRONIZED:
371                case STRICTFP:
372                case LT:
373                case BYTE:
374                case SHORT:
375                case CHAR:
376                case INT:
377                case LONG:
378                case FLOAT:
379                case DOUBLE:
380                case BOOLEAN:
381                case VOID:
382                    if (stopAtMemberDecl)
383                        return;
384                    break;
385                case UNDERSCORE:
386                case IDENTIFIER:
387                   if (stopAtIdentifier)
388                        return;
389                    break;
390                case CASE:
391                case DEFAULT:
392                case IF:
393                case FOR:
394                case WHILE:
395                case DO:
396                case TRY:
397                case SWITCH:
398                case RETURN:
399                case THROW:
400                case BREAK:
401                case CONTINUE:
402                case ELSE:
403                case FINALLY:
404                case CATCH:
405                case THIS:
406                case SUPER:
407                case NEW:
408                    if (stopAtStatement)
409                        return;
410                    break;
411                case ASSERT:
412                    if (stopAtStatement)
413                        return;
414                    break;
415            }
416            nextToken();
417        }
418    }
419
420    protected JCErroneous syntaxError(int pos, String key, TokenKind... args) {
421        return syntaxError(pos, List.<JCTree>nil(), key, args);
422    }
423
424    protected JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) {
425        setErrorEndPos(pos);
426        JCErroneous err = F.at(pos).Erroneous(errs);
427        reportSyntaxError(err, key, (Object[])args);
428        if (errs != null) {
429            JCTree last = errs.last();
430            if (last != null)
431                storeEnd(last, pos);
432        }
433        return toP(err);
434    }
435
436    private static final int RECOVERY_THRESHOLD = 50;
437    private int errorPos = Position.NOPOS;
438    private int count = 0;
439
440    /**
441     * Report a syntax using the given the position parameter and arguments,
442     * unless one was already reported at the same position.
443     */
444    protected void reportSyntaxError(int pos, String key, Object... args) {
445        JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
446        reportSyntaxError(diag, key, args);
447    }
448
449    /**
450     * Report a syntax error using the given DiagnosticPosition object and
451     * arguments, unless one was already reported at the same position.
452     */
453    protected void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
454        int pos = diagPos.getPreferredPosition();
455        if (pos > S.errPos() || pos == Position.NOPOS) {
456            if (token.kind == EOF) {
457                error(diagPos, "premature.eof");
458            } else {
459                error(diagPos, key, args);
460            }
461        }
462        S.errPos(pos);
463        if (token.pos == errorPos) {
464            //check for a possible infinite loop in parsing:
465            Assert.check(count++ < RECOVERY_THRESHOLD);
466        } else {
467            count = 0;
468            errorPos = token.pos;
469        }
470    }
471
472
473    /** Generate a syntax error at current position unless one was already
474     *  reported at the same position.
475     */
476    protected JCErroneous syntaxError(String key) {
477        return syntaxError(token.pos, key);
478    }
479
480    /** Generate a syntax error at current position unless one was
481     *  already reported at the same position.
482     */
483    protected JCErroneous syntaxError(String key, TokenKind arg) {
484        return syntaxError(token.pos, key, arg);
485    }
486
487    /** If next input token matches given token, skip it, otherwise report
488     *  an error.
489     */
490    public void accept(TokenKind tk) {
491        if (token.kind == tk) {
492            nextToken();
493        } else {
494            setErrorEndPos(token.pos);
495            reportSyntaxError(S.prevToken().endPos, "expected", tk);
496        }
497    }
498
499    /** Report an illegal start of expression/type error at given position.
500     */
501    JCExpression illegal(int pos) {
502        setErrorEndPos(pos);
503        if ((mode & EXPR) != 0)
504            return syntaxError(pos, "illegal.start.of.expr");
505        else
506            return syntaxError(pos, "illegal.start.of.type");
507
508    }
509
510    /** Report an illegal start of expression/type error at current position.
511     */
512    JCExpression illegal() {
513        return illegal(token.pos);
514    }
515
516    /** Diagnose a modifier flag from the set, if any. */
517    protected void checkNoMods(long mods) {
518        if (mods != 0) {
519            long lowestMod = mods & -mods;
520            error(token.pos, "mod.not.allowed.here",
521                    Flags.asFlagSet(lowestMod));
522        }
523    }
524
525/* ---------- doc comments --------- */
526
527    /** A table to store all documentation comments
528     *  indexed by the tree nodes they refer to.
529     *  defined only if option flag keepDocComment is set.
530     */
531    private final DocCommentTable docComments;
532
533    /** Make an entry into docComments hashtable,
534     *  provided flag keepDocComments is set and given doc comment is non-null.
535     *  @param tree   The tree to be used as index in the hashtable
536     *  @param dc     The doc comment to associate with the tree, or null.
537     */
538    protected void attach(JCTree tree, Comment dc) {
539        if (keepDocComments && dc != null) {
540//          System.out.println("doc comment = ");System.out.println(dc);//DEBUG
541            docComments.putComment(tree, dc);
542        }
543    }
544
545/* -------- source positions ------- */
546
547    protected void setErrorEndPos(int errPos) {
548        endPosTable.setErrorEndPos(errPos);
549    }
550
551    protected void storeEnd(JCTree tree, int endpos) {
552        endPosTable.storeEnd(tree, endpos);
553    }
554
555    protected <T extends JCTree> T to(T t) {
556        return endPosTable.to(t);
557    }
558
559    protected <T extends JCTree> T toP(T t) {
560        return endPosTable.toP(t);
561    }
562
563    /** Get the start position for a tree node.  The start position is
564     * defined to be the position of the first character of the first
565     * token of the node's source text.
566     * @param tree  The tree node
567     */
568    public int getStartPos(JCTree tree) {
569        return TreeInfo.getStartPos(tree);
570    }
571
572    /**
573     * Get the end position for a tree node.  The end position is
574     * defined to be the position of the last character of the last
575     * token of the node's source text.  Returns Position.NOPOS if end
576     * positions are not generated or the position is otherwise not
577     * found.
578     * @param tree  The tree node
579     */
580    public int getEndPos(JCTree tree) {
581        return endPosTable.getEndPos(tree);
582    }
583
584
585
586/* ---------- parsing -------------- */
587
588    /**
589     * Ident = IDENTIFIER
590     */
591    protected Name ident() {
592        return ident(false);
593    }
594
595    protected Name ident(boolean advanceOnErrors) {
596        if (token.kind == IDENTIFIER) {
597            Name name = token.name();
598            nextToken();
599            return name;
600        } else if (token.kind == ASSERT) {
601            error(token.pos, "assert.as.identifier");
602            nextToken();
603            return names.error;
604        } else if (token.kind == ENUM) {
605            error(token.pos, "enum.as.identifier");
606            nextToken();
607            return names.error;
608        } else if (token.kind == THIS) {
609            if (allowThisIdent) {
610                // Make sure we're using a supported source version.
611                checkTypeAnnotations();
612                Name name = token.name();
613                nextToken();
614                return name;
615            } else {
616                error(token.pos, "this.as.identifier");
617                nextToken();
618                return names.error;
619            }
620        } else if (token.kind == UNDERSCORE) {
621            if (allowUnderscoreIdentifier) {
622                warning(token.pos, "underscore.as.identifier");
623            } else {
624                error(token.pos, "underscore.as.identifier");
625            }
626            Name name = token.name();
627            nextToken();
628            return name;
629        } else {
630            accept(IDENTIFIER);
631            if (advanceOnErrors) {
632                nextToken();
633            }
634            return names.error;
635        }
636    }
637
638    /**
639     * Qualident = Ident { DOT [Annotations] Ident }
640     */
641    public JCExpression qualident(boolean allowAnnos) {
642        JCExpression t = toP(F.at(token.pos).Ident(ident()));
643        while (token.kind == DOT) {
644            int pos = token.pos;
645            nextToken();
646            List<JCAnnotation> tyannos = null;
647            if (allowAnnos) {
648                tyannos = typeAnnotationsOpt();
649            }
650            t = toP(F.at(pos).Select(t, ident()));
651            if (tyannos != null && tyannos.nonEmpty()) {
652                t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
653            }
654        }
655        return t;
656    }
657
658    JCExpression literal(Name prefix) {
659        return literal(prefix, token.pos);
660    }
661
662    /**
663     * Literal =
664     *     INTLITERAL
665     *   | LONGLITERAL
666     *   | FLOATLITERAL
667     *   | DOUBLELITERAL
668     *   | CHARLITERAL
669     *   | STRINGLITERAL
670     *   | TRUE
671     *   | FALSE
672     *   | NULL
673     */
674    JCExpression literal(Name prefix, int pos) {
675        JCExpression t = errorTree;
676        switch (token.kind) {
677        case INTLITERAL:
678            try {
679                t = F.at(pos).Literal(
680                    TypeTag.INT,
681                    Convert.string2int(strval(prefix), token.radix()));
682            } catch (NumberFormatException ex) {
683                error(token.pos, "int.number.too.large", strval(prefix));
684            }
685            break;
686        case LONGLITERAL:
687            try {
688                t = F.at(pos).Literal(
689                    TypeTag.LONG,
690                    Long.valueOf(Convert.string2long(strval(prefix), token.radix())));
691            } catch (NumberFormatException ex) {
692                error(token.pos, "int.number.too.large", strval(prefix));
693            }
694            break;
695        case FLOATLITERAL: {
696            String proper = token.radix() == 16 ?
697                    ("0x"+ token.stringVal()) :
698                    token.stringVal();
699            Float n;
700            try {
701                n = Float.valueOf(proper);
702            } catch (NumberFormatException ex) {
703                // error already reported in scanner
704                n = Float.NaN;
705            }
706            if (n.floatValue() == 0.0f && !isZero(proper))
707                error(token.pos, "fp.number.too.small");
708            else if (n.floatValue() == Float.POSITIVE_INFINITY)
709                error(token.pos, "fp.number.too.large");
710            else
711                t = F.at(pos).Literal(TypeTag.FLOAT, n);
712            break;
713        }
714        case DOUBLELITERAL: {
715            String proper = token.radix() == 16 ?
716                    ("0x"+ token.stringVal()) :
717                    token.stringVal();
718            Double n;
719            try {
720                n = Double.valueOf(proper);
721            } catch (NumberFormatException ex) {
722                // error already reported in scanner
723                n = Double.NaN;
724            }
725            if (n.doubleValue() == 0.0d && !isZero(proper))
726                error(token.pos, "fp.number.too.small");
727            else if (n.doubleValue() == Double.POSITIVE_INFINITY)
728                error(token.pos, "fp.number.too.large");
729            else
730                t = F.at(pos).Literal(TypeTag.DOUBLE, n);
731            break;
732        }
733        case CHARLITERAL:
734            t = F.at(pos).Literal(
735                TypeTag.CHAR,
736                token.stringVal().charAt(0) + 0);
737            break;
738        case STRINGLITERAL:
739            t = F.at(pos).Literal(
740                TypeTag.CLASS,
741                token.stringVal());
742            break;
743        case TRUE: case FALSE:
744            t = F.at(pos).Literal(
745                TypeTag.BOOLEAN,
746                (token.kind == TRUE ? 1 : 0));
747            break;
748        case NULL:
749            t = F.at(pos).Literal(
750                TypeTag.BOT,
751                null);
752            break;
753        default:
754            Assert.error();
755        }
756        if (t == errorTree)
757            t = F.at(pos).Erroneous();
758        storeEnd(t, token.endPos);
759        nextToken();
760        return t;
761    }
762    //where
763        boolean isZero(String s) {
764            char[] cs = s.toCharArray();
765            int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
766            int i = ((base==16) ? 2 : 0);
767            while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
768            return !(i < cs.length && (Character.digit(cs[i], base) > 0));
769        }
770
771        String strval(Name prefix) {
772            String s = token.stringVal();
773            return prefix.isEmpty() ? s : prefix + s;
774        }
775
776    /** terms can be either expressions or types.
777     */
778    public JCExpression parseExpression() {
779        return term(EXPR);
780    }
781
782    /**
783     * parses (optional) type annotations followed by a type. If the
784     * annotations are present before the type and are not consumed during array
785     * parsing, this method returns a {@link JCAnnotatedType} consisting of
786     * these annotations and the underlying type. Otherwise, it returns the
787     * underlying type.
788     *
789     * <p>
790     *
791     * Note that this method sets {@code mode} to {@code TYPE} first, before
792     * parsing annotations.
793     */
794    public JCExpression parseType() {
795        List<JCAnnotation> annotations = typeAnnotationsOpt();
796        return parseType(annotations);
797    }
798
799    public JCExpression parseType(List<JCAnnotation> annotations) {
800        JCExpression result = unannotatedType();
801
802        if (annotations.nonEmpty()) {
803            result = insertAnnotationsToMostInner(result, annotations, false);
804        }
805
806        return result;
807    }
808
809    public JCExpression unannotatedType() {
810        return term(TYPE);
811    }
812
813    protected JCExpression term(int newmode) {
814        int prevmode = mode;
815        mode = newmode;
816        JCExpression t = term();
817        lastmode = mode;
818        mode = prevmode;
819        return t;
820    }
821
822    /**
823     *  {@literal
824     *  Expression = Expression1 [ExpressionRest]
825     *  ExpressionRest = [AssignmentOperator Expression1]
826     *  AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
827     *                       "&=" | "|=" | "^=" |
828     *                       "%=" | "<<=" | ">>=" | ">>>="
829     *  Type = Type1
830     *  TypeNoParams = TypeNoParams1
831     *  StatementExpression = Expression
832     *  ConstantExpression = Expression
833     *  }
834     */
835    JCExpression term() {
836        JCExpression t = term1();
837        if ((mode & EXPR) != 0 &&
838            token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0)
839            return termRest(t);
840        else
841            return t;
842    }
843
844    JCExpression termRest(JCExpression t) {
845        switch (token.kind) {
846        case EQ: {
847            int pos = token.pos;
848            nextToken();
849            mode = EXPR;
850            JCExpression t1 = term();
851            return toP(F.at(pos).Assign(t, t1));
852        }
853        case PLUSEQ:
854        case SUBEQ:
855        case STAREQ:
856        case SLASHEQ:
857        case PERCENTEQ:
858        case AMPEQ:
859        case BAREQ:
860        case CARETEQ:
861        case LTLTEQ:
862        case GTGTEQ:
863        case GTGTGTEQ:
864            int pos = token.pos;
865            TokenKind tk = token.kind;
866            nextToken();
867            mode = EXPR;
868            JCExpression t1 = term();
869            return F.at(pos).Assignop(optag(tk), t, t1);
870        default:
871            return t;
872        }
873    }
874
875    /** Expression1   = Expression2 [Expression1Rest]
876     *  Type1         = Type2
877     *  TypeNoParams1 = TypeNoParams2
878     */
879    JCExpression term1() {
880        JCExpression t = term2();
881        if ((mode & EXPR) != 0 && token.kind == QUES) {
882            mode = EXPR;
883            return term1Rest(t);
884        } else {
885            return t;
886        }
887    }
888
889    /** Expression1Rest = ["?" Expression ":" Expression1]
890     */
891    JCExpression term1Rest(JCExpression t) {
892        if (token.kind == QUES) {
893            int pos = token.pos;
894            nextToken();
895            JCExpression t1 = term();
896            accept(COLON);
897            JCExpression t2 = term1();
898            return F.at(pos).Conditional(t, t1, t2);
899        } else {
900            return t;
901        }
902    }
903
904    /** Expression2   = Expression3 [Expression2Rest]
905     *  Type2         = Type3
906     *  TypeNoParams2 = TypeNoParams3
907     */
908    JCExpression term2() {
909        JCExpression t = term3();
910        if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) {
911            mode = EXPR;
912            return term2Rest(t, TreeInfo.orPrec);
913        } else {
914            return t;
915        }
916    }
917
918    /*  Expression2Rest = {infixop Expression3}
919     *                  | Expression3 instanceof Type
920     *  infixop         = "||"
921     *                  | "&&"
922     *                  | "|"
923     *                  | "^"
924     *                  | "&"
925     *                  | "==" | "!="
926     *                  | "<" | ">" | "<=" | ">="
927     *                  | "<<" | ">>" | ">>>"
928     *                  | "+" | "-"
929     *                  | "*" | "/" | "%"
930     */
931    JCExpression term2Rest(JCExpression t, int minprec) {
932        JCExpression[] odStack = newOdStack();
933        Token[] opStack = newOpStack();
934
935        // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
936        int top = 0;
937        odStack[0] = t;
938        int startPos = token.pos;
939        Token topOp = Tokens.DUMMY;
940        while (prec(token.kind) >= minprec) {
941            opStack[top] = topOp;
942            top++;
943            topOp = token;
944            nextToken();
945            odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
946            while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
947                odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
948                                        odStack[top]);
949                top--;
950                topOp = opStack[top];
951            }
952        }
953        Assert.check(top == 0);
954        t = odStack[0];
955
956        if (t.hasTag(JCTree.Tag.PLUS)) {
957            t = foldStrings(t);
958        }
959
960        odStackSupply.add(odStack);
961        opStackSupply.add(opStack);
962        return t;
963    }
964    //where
965        /** Construct a binary or type test node.
966         */
967        private JCExpression makeOp(int pos,
968                                    TokenKind topOp,
969                                    JCExpression od1,
970                                    JCExpression od2)
971        {
972            if (topOp == INSTANCEOF) {
973                return F.at(pos).TypeTest(od1, od2);
974            } else {
975                return F.at(pos).Binary(optag(topOp), od1, od2);
976            }
977        }
978        /** If tree is a concatenation of string literals, replace it
979         *  by a single literal representing the concatenated string.
980         */
981        protected JCExpression foldStrings(JCExpression tree) {
982            if (!allowStringFolding)
983                return tree;
984            ListBuffer<JCExpression> opStack = new ListBuffer<>();
985            ListBuffer<JCLiteral> litBuf = new ListBuffer<>();
986            boolean needsFolding = false;
987            JCExpression curr = tree;
988            while (true) {
989                if (curr.hasTag(JCTree.Tag.PLUS)) {
990                    JCBinary op = (JCBinary)curr;
991                    needsFolding |= foldIfNeeded(op.rhs, litBuf, opStack, false);
992                    curr = op.lhs;
993                } else {
994                    needsFolding |= foldIfNeeded(curr, litBuf, opStack, true);
995                    break; //last one!
996                }
997            }
998            if (needsFolding) {
999                List<JCExpression> ops = opStack.toList();
1000                JCExpression res = ops.head;
1001                for (JCExpression op : ops.tail) {
1002                    res = F.at(op.getStartPosition()).Binary(optag(TokenKind.PLUS), res, op);
1003                    storeEnd(res, getEndPos(op));
1004                }
1005                return res;
1006            } else {
1007                return tree;
1008            }
1009        }
1010
1011        private boolean foldIfNeeded(JCExpression tree, ListBuffer<JCLiteral> litBuf,
1012                                                ListBuffer<JCExpression> opStack, boolean last) {
1013            JCLiteral str = stringLiteral(tree);
1014            if (str != null) {
1015                litBuf.prepend(str);
1016                return last && merge(litBuf, opStack);
1017            } else {
1018                boolean res = merge(litBuf, opStack);
1019                litBuf.clear();
1020                opStack.prepend(tree);
1021                return res;
1022            }
1023        }
1024
1025        boolean merge(ListBuffer<JCLiteral> litBuf, ListBuffer<JCExpression> opStack) {
1026            if (litBuf.isEmpty()) {
1027                return false;
1028            } else if (litBuf.size() == 1) {
1029                opStack.prepend(litBuf.first());
1030                return false;
1031            } else {
1032                JCExpression t = F.at(litBuf.first().getStartPosition()).Literal(TypeTag.CLASS,
1033                        litBuf.stream().map(lit -> (String)lit.getValue()).collect(Collectors.joining()));
1034                storeEnd(t, litBuf.last().getEndPosition(endPosTable));
1035                opStack.prepend(t);
1036                return true;
1037            }
1038        }
1039
1040        private JCLiteral stringLiteral(JCTree tree) {
1041            if (tree.hasTag(LITERAL)) {
1042                JCLiteral lit = (JCLiteral)tree;
1043                if (lit.typetag == TypeTag.CLASS) {
1044                    return lit;
1045                }
1046            }
1047            return null;
1048        }
1049
1050
1051        /** optimization: To save allocating a new operand/operator stack
1052         *  for every binary operation, we use supplys.
1053         */
1054        ArrayList<JCExpression[]> odStackSupply = new ArrayList<>();
1055        ArrayList<Token[]> opStackSupply = new ArrayList<>();
1056
1057        private JCExpression[] newOdStack() {
1058            if (odStackSupply.isEmpty())
1059                return new JCExpression[infixPrecedenceLevels + 1];
1060            return odStackSupply.remove(odStackSupply.size() - 1);
1061        }
1062
1063        private Token[] newOpStack() {
1064            if (opStackSupply.isEmpty())
1065                return new Token[infixPrecedenceLevels + 1];
1066            return opStackSupply.remove(opStackSupply.size() - 1);
1067        }
1068
1069    /**
1070     *  Expression3    = PrefixOp Expression3
1071     *                 | "(" Expr | TypeNoParams ")" Expression3
1072     *                 | Primary {Selector} {PostfixOp}
1073     *
1074     *  {@literal
1075     *  Primary        = "(" Expression ")"
1076     *                 | Literal
1077     *                 | [TypeArguments] THIS [Arguments]
1078     *                 | [TypeArguments] SUPER SuperSuffix
1079     *                 | NEW [TypeArguments] Creator
1080     *                 | "(" Arguments ")" "->" ( Expression | Block )
1081     *                 | Ident "->" ( Expression | Block )
1082     *                 | [Annotations] Ident { "." [Annotations] Ident }
1083     *                 | Expression3 MemberReferenceSuffix
1084     *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
1085     *                   | Arguments
1086     *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
1087     *                   ]
1088     *                 | BasicType BracketsOpt "." CLASS
1089     *  }
1090     *
1091     *  PrefixOp       = "++" | "--" | "!" | "~" | "+" | "-"
1092     *  PostfixOp      = "++" | "--"
1093     *  Type3          = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
1094     *                 | BasicType
1095     *  TypeNoParams3  = Ident { "." Ident } BracketsOpt
1096     *  Selector       = "." [TypeArguments] Ident [Arguments]
1097     *                 | "." THIS
1098     *                 | "." [TypeArguments] SUPER SuperSuffix
1099     *                 | "." NEW [TypeArguments] InnerCreator
1100     *                 | "[" Expression "]"
1101     *  TypeSelector   = "." Ident [TypeArguments]
1102     *  SuperSuffix    = Arguments | "." Ident [Arguments]
1103     */
1104    protected JCExpression term3() {
1105        int pos = token.pos;
1106        JCExpression t;
1107        List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
1108        switch (token.kind) {
1109        case QUES:
1110            if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
1111                mode = TYPE;
1112                return typeArgument();
1113            } else
1114                return illegal();
1115        case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
1116            if (typeArgs == null && (mode & EXPR) != 0) {
1117                TokenKind tk = token.kind;
1118                nextToken();
1119                mode = EXPR;
1120                if (tk == SUB &&
1121                    (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
1122                    token.radix() == 10) {
1123                    mode = EXPR;
1124                    t = literal(names.hyphen, pos);
1125                } else {
1126                    t = term3();
1127                    return F.at(pos).Unary(unoptag(tk), t);
1128                }
1129            } else return illegal();
1130            break;
1131        case LPAREN:
1132            if (typeArgs == null && (mode & EXPR) != 0) {
1133                ParensResult pres = analyzeParens();
1134                switch (pres) {
1135                    case CAST:
1136                       accept(LPAREN);
1137                       mode = TYPE;
1138                       int pos1 = pos;
1139                       List<JCExpression> targets = List.of(t = term3());
1140                       while (token.kind == AMP) {
1141                           checkIntersectionTypesInCast();
1142                           accept(AMP);
1143                           targets = targets.prepend(term3());
1144                       }
1145                       if (targets.length() > 1) {
1146                           t = toP(F.at(pos1).TypeIntersection(targets.reverse()));
1147                       }
1148                       accept(RPAREN);
1149                       mode = EXPR;
1150                       JCExpression t1 = term3();
1151                       return F.at(pos).TypeCast(t, t1);
1152                    case IMPLICIT_LAMBDA:
1153                    case EXPLICIT_LAMBDA:
1154                        t = lambdaExpressionOrStatement(true, pres == ParensResult.EXPLICIT_LAMBDA, pos);
1155                        break;
1156                    default: //PARENS
1157                        accept(LPAREN);
1158                        mode = EXPR;
1159                        t = termRest(term1Rest(term2Rest(term3(), TreeInfo.orPrec)));
1160                        accept(RPAREN);
1161                        t = toP(F.at(pos).Parens(t));
1162                        break;
1163                }
1164            } else {
1165                return illegal();
1166            }
1167            break;
1168        case THIS:
1169            if ((mode & EXPR) != 0) {
1170                mode = EXPR;
1171                t = to(F.at(pos).Ident(names._this));
1172                nextToken();
1173                if (typeArgs == null)
1174                    t = argumentsOpt(null, t);
1175                else
1176                    t = arguments(typeArgs, t);
1177                typeArgs = null;
1178            } else return illegal();
1179            break;
1180        case SUPER:
1181            if ((mode & EXPR) != 0) {
1182                mode = EXPR;
1183                t = to(F.at(pos).Ident(names._super));
1184                t = superSuffix(typeArgs, t);
1185                typeArgs = null;
1186            } else return illegal();
1187            break;
1188        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
1189        case CHARLITERAL: case STRINGLITERAL:
1190        case TRUE: case FALSE: case NULL:
1191            if (typeArgs == null && (mode & EXPR) != 0) {
1192                mode = EXPR;
1193                t = literal(names.empty);
1194            } else return illegal();
1195            break;
1196        case NEW:
1197            if (typeArgs != null) return illegal();
1198            if ((mode & EXPR) != 0) {
1199                mode = EXPR;
1200                nextToken();
1201                if (token.kind == LT) typeArgs = typeArguments(false);
1202                t = creator(pos, typeArgs);
1203                typeArgs = null;
1204            } else return illegal();
1205            break;
1206        case MONKEYS_AT:
1207            // Only annotated cast types and method references are valid
1208            List<JCAnnotation> typeAnnos = typeAnnotationsOpt();
1209            if (typeAnnos.isEmpty()) {
1210                // else there would be no '@'
1211                throw new AssertionError("Expected type annotations, but found none!");
1212            }
1213
1214            JCExpression expr = term3();
1215
1216            if ((mode & TYPE) == 0) {
1217                // Type annotations on class literals no longer legal
1218                switch (expr.getTag()) {
1219                case REFERENCE: {
1220                    JCMemberReference mref = (JCMemberReference) expr;
1221                    mref.expr = toP(F.at(pos).AnnotatedType(typeAnnos, mref.expr));
1222                    t = mref;
1223                    break;
1224                }
1225                case SELECT: {
1226                    JCFieldAccess sel = (JCFieldAccess) expr;
1227
1228                    if (sel.name != names._class) {
1229                        return illegal();
1230                    } else {
1231                        log.error(token.pos, "no.annotations.on.dot.class");
1232                        return expr;
1233                    }
1234                }
1235                default:
1236                    return illegal(typeAnnos.head.pos);
1237                }
1238
1239            } else {
1240                // Type annotations targeting a cast
1241                t = insertAnnotationsToMostInner(expr, typeAnnos, false);
1242            }
1243            break;
1244        case UNDERSCORE: case IDENTIFIER: case ASSERT: case ENUM:
1245            if (typeArgs != null) return illegal();
1246            if ((mode & EXPR) != 0 && peekToken(ARROW)) {
1247                t = lambdaExpressionOrStatement(false, false, pos);
1248            } else {
1249                t = toP(F.at(token.pos).Ident(ident()));
1250                loop: while (true) {
1251                    pos = token.pos;
1252                    final List<JCAnnotation> annos = typeAnnotationsOpt();
1253
1254                    // need to report an error later if LBRACKET is for array
1255                    // index access rather than array creation level
1256                    if (!annos.isEmpty() && token.kind != LBRACKET && token.kind != ELLIPSIS)
1257                        return illegal(annos.head.pos);
1258
1259                    switch (token.kind) {
1260                    case LBRACKET:
1261                        nextToken();
1262                        if (token.kind == RBRACKET) {
1263                            nextToken();
1264                            t = bracketsOpt(t);
1265                            t = toP(F.at(pos).TypeArray(t));
1266                            if (annos.nonEmpty()) {
1267                                t = toP(F.at(pos).AnnotatedType(annos, t));
1268                            }
1269                            t = bracketsSuffix(t);
1270                        } else {
1271                            if ((mode & EXPR) != 0) {
1272                                mode = EXPR;
1273                                JCExpression t1 = term();
1274                                if (!annos.isEmpty()) t = illegal(annos.head.pos);
1275                                t = to(F.at(pos).Indexed(t, t1));
1276                            }
1277                            accept(RBRACKET);
1278                        }
1279                        break loop;
1280                    case LPAREN:
1281                        if ((mode & EXPR) != 0) {
1282                            mode = EXPR;
1283                            t = arguments(typeArgs, t);
1284                            if (!annos.isEmpty()) t = illegal(annos.head.pos);
1285                            typeArgs = null;
1286                        }
1287                        break loop;
1288                    case DOT:
1289                        nextToken();
1290                        int oldmode = mode;
1291                        mode &= ~NOPARAMS;
1292                        typeArgs = typeArgumentsOpt(EXPR);
1293                        mode = oldmode;
1294                        if ((mode & EXPR) != 0) {
1295                            switch (token.kind) {
1296                            case CLASS:
1297                                if (typeArgs != null) return illegal();
1298                                mode = EXPR;
1299                                t = to(F.at(pos).Select(t, names._class));
1300                                nextToken();
1301                                break loop;
1302                            case THIS:
1303                                if (typeArgs != null) return illegal();
1304                                mode = EXPR;
1305                                t = to(F.at(pos).Select(t, names._this));
1306                                nextToken();
1307                                break loop;
1308                            case SUPER:
1309                                mode = EXPR;
1310                                t = to(F.at(pos).Select(t, names._super));
1311                                t = superSuffix(typeArgs, t);
1312                                typeArgs = null;
1313                                break loop;
1314                            case NEW:
1315                                if (typeArgs != null) return illegal();
1316                                mode = EXPR;
1317                                int pos1 = token.pos;
1318                                nextToken();
1319                                if (token.kind == LT) typeArgs = typeArguments(false);
1320                                t = innerCreator(pos1, typeArgs, t);
1321                                typeArgs = null;
1322                                break loop;
1323                            }
1324                        }
1325
1326                        List<JCAnnotation> tyannos = null;
1327                        if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1328                            tyannos = typeAnnotationsOpt();
1329                        }
1330                        // typeArgs saved for next loop iteration.
1331                        t = toP(F.at(pos).Select(t, ident()));
1332                        if (tyannos != null && tyannos.nonEmpty()) {
1333                            t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1334                        }
1335                        break;
1336                    case ELLIPSIS:
1337                        if (this.permitTypeAnnotationsPushBack) {
1338                            this.typeAnnotationsPushedBack = annos;
1339                        } else if (annos.nonEmpty()) {
1340                            // Don't return here -- error recovery attempt
1341                            illegal(annos.head.pos);
1342                        }
1343                        break loop;
1344                    case LT:
1345                        if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1346                            //this is an unbound method reference whose qualifier
1347                            //is a generic type i.e. A<S>::m
1348                            int pos1 = token.pos;
1349                            accept(LT);
1350                            ListBuffer<JCExpression> args = new ListBuffer<>();
1351                            args.append(typeArgument());
1352                            while (token.kind == COMMA) {
1353                                nextToken();
1354                                args.append(typeArgument());
1355                            }
1356                            accept(GT);
1357                            t = toP(F.at(pos1).TypeApply(t, args.toList()));
1358                            while (token.kind == DOT) {
1359                                nextToken();
1360                                mode = TYPE;
1361                                t = toP(F.at(token.pos).Select(t, ident()));
1362                                t = typeArgumentsOpt(t);
1363                            }
1364                            t = bracketsOpt(t);
1365                            if (token.kind != COLCOL) {
1366                                //method reference expected here
1367                                t = illegal();
1368                            }
1369                            mode = EXPR;
1370                            return term3Rest(t, typeArgs);
1371                        }
1372                        break loop;
1373                    default:
1374                        break loop;
1375                    }
1376                }
1377            }
1378            if (typeArgs != null) illegal();
1379            t = typeArgumentsOpt(t);
1380            break;
1381        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1382        case DOUBLE: case BOOLEAN:
1383            if (typeArgs != null) illegal();
1384            t = bracketsSuffix(bracketsOpt(basicType()));
1385            break;
1386        case VOID:
1387            if (typeArgs != null) illegal();
1388            if ((mode & EXPR) != 0) {
1389                nextToken();
1390                if (token.kind == DOT) {
1391                    JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTag.VOID));
1392                    t = bracketsSuffix(ti);
1393                } else {
1394                    return illegal(pos);
1395                }
1396            } else {
1397                // Support the corner case of myMethodHandle.<void>invoke() by passing
1398                // a void type (like other primitive types) to the next phase.
1399                // The error will be reported in Attr.attribTypes or Attr.visitApply.
1400                JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTag.VOID));
1401                nextToken();
1402                return ti;
1403                //return illegal();
1404            }
1405            break;
1406        default:
1407            return illegal();
1408        }
1409        return term3Rest(t, typeArgs);
1410    }
1411
1412    JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1413        if (typeArgs != null) illegal();
1414        while (true) {
1415            int pos1 = token.pos;
1416            final List<JCAnnotation> annos = typeAnnotationsOpt();
1417
1418            if (token.kind == LBRACKET) {
1419                nextToken();
1420                if ((mode & TYPE) != 0) {
1421                    int oldmode = mode;
1422                    mode = TYPE;
1423                    if (token.kind == RBRACKET) {
1424                        nextToken();
1425                        t = bracketsOpt(t);
1426                        t = toP(F.at(pos1).TypeArray(t));
1427                        if (token.kind == COLCOL) {
1428                            mode = EXPR;
1429                            continue;
1430                        }
1431                        if (annos.nonEmpty()) {
1432                            t = toP(F.at(pos1).AnnotatedType(annos, t));
1433                        }
1434                        return t;
1435                    }
1436                    mode = oldmode;
1437                }
1438                if ((mode & EXPR) != 0) {
1439                    mode = EXPR;
1440                    JCExpression t1 = term();
1441                    t = to(F.at(pos1).Indexed(t, t1));
1442                }
1443                accept(RBRACKET);
1444            } else if (token.kind == DOT) {
1445                nextToken();
1446                typeArgs = typeArgumentsOpt(EXPR);
1447                if (token.kind == SUPER && (mode & EXPR) != 0) {
1448                    mode = EXPR;
1449                    t = to(F.at(pos1).Select(t, names._super));
1450                    nextToken();
1451                    t = arguments(typeArgs, t);
1452                    typeArgs = null;
1453                } else if (token.kind == NEW && (mode & EXPR) != 0) {
1454                    if (typeArgs != null) return illegal();
1455                    mode = EXPR;
1456                    int pos2 = token.pos;
1457                    nextToken();
1458                    if (token.kind == LT) typeArgs = typeArguments(false);
1459                    t = innerCreator(pos2, typeArgs, t);
1460                    typeArgs = null;
1461                } else {
1462                    List<JCAnnotation> tyannos = null;
1463                    if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1464                        // is the mode check needed?
1465                        tyannos = typeAnnotationsOpt();
1466                    }
1467                    t = toP(F.at(pos1).Select(t, ident(true)));
1468                    if (tyannos != null && tyannos.nonEmpty()) {
1469                        t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1470                    }
1471                    t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1472                    typeArgs = null;
1473                }
1474            } else if ((mode & EXPR) != 0 && token.kind == COLCOL) {
1475                mode = EXPR;
1476                if (typeArgs != null) return illegal();
1477                accept(COLCOL);
1478                t = memberReferenceSuffix(pos1, t);
1479            } else {
1480                if (!annos.isEmpty()) {
1481                    if (permitTypeAnnotationsPushBack)
1482                        typeAnnotationsPushedBack = annos;
1483                    else
1484                        return illegal(annos.head.pos);
1485                }
1486                break;
1487            }
1488        }
1489        while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1490            mode = EXPR;
1491            t = to(F.at(token.pos).Unary(
1492                  token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1493            nextToken();
1494        }
1495        return toP(t);
1496    }
1497
1498    /**
1499     * If we see an identifier followed by a '&lt;' it could be an unbound
1500     * method reference or a binary expression. To disambiguate, look for a
1501     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1502     */
1503    @SuppressWarnings("fallthrough")
1504    boolean isUnboundMemberRef() {
1505        int pos = 0, depth = 0;
1506        outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1507            switch (t.kind) {
1508                case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1509                case DOT: case RBRACKET: case LBRACKET: case COMMA:
1510                case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1511                case DOUBLE: case BOOLEAN: case CHAR:
1512                case MONKEYS_AT:
1513                    break;
1514
1515                case LPAREN:
1516                    // skip annotation values
1517                    int nesting = 0;
1518                    for (; ; pos++) {
1519                        TokenKind tk2 = S.token(pos).kind;
1520                        switch (tk2) {
1521                            case EOF:
1522                                return false;
1523                            case LPAREN:
1524                                nesting++;
1525                                break;
1526                            case RPAREN:
1527                                nesting--;
1528                                if (nesting == 0) {
1529                                    continue outer;
1530                                }
1531                                break;
1532                        }
1533                    }
1534
1535                case LT:
1536                    depth++; break;
1537                case GTGTGT:
1538                    depth--;
1539                case GTGT:
1540                    depth--;
1541                case GT:
1542                    depth--;
1543                    if (depth == 0) {
1544                        TokenKind nextKind = S.token(pos + 1).kind;
1545                        return
1546                            nextKind == TokenKind.DOT ||
1547                            nextKind == TokenKind.LBRACKET ||
1548                            nextKind == TokenKind.COLCOL;
1549                    }
1550                    break;
1551                default:
1552                    return false;
1553            }
1554        }
1555    }
1556
1557    /**
1558     * If we see an identifier followed by a '&lt;' it could be an unbound
1559     * method reference or a binary expression. To disambiguate, look for a
1560     * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1561     */
1562    @SuppressWarnings("fallthrough")
1563    ParensResult analyzeParens() {
1564        int depth = 0;
1565        boolean type = false;
1566        outer: for (int lookahead = 0 ; ; lookahead++) {
1567            TokenKind tk = S.token(lookahead).kind;
1568            switch (tk) {
1569                case COMMA:
1570                    type = true;
1571                case EXTENDS: case SUPER: case DOT: case AMP:
1572                    //skip
1573                    break;
1574                case QUES:
1575                    if (peekToken(lookahead, EXTENDS) ||
1576                            peekToken(lookahead, SUPER)) {
1577                        //wildcards
1578                        type = true;
1579                    }
1580                    break;
1581                case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1582                case DOUBLE: case BOOLEAN: case CHAR: case VOID:
1583                    if (peekToken(lookahead, RPAREN)) {
1584                        //Type, ')' -> cast
1585                        return ParensResult.CAST;
1586                    } else if (peekToken(lookahead, LAX_IDENTIFIER)) {
1587                        //Type, Identifier/'_'/'assert'/'enum' -> explicit lambda
1588                        return ParensResult.EXPLICIT_LAMBDA;
1589                    }
1590                    break;
1591                case LPAREN:
1592                    if (lookahead != 0) {
1593                        // '(' in a non-starting position -> parens
1594                        return ParensResult.PARENS;
1595                    } else if (peekToken(lookahead, RPAREN)) {
1596                        // '(', ')' -> explicit lambda
1597                        return ParensResult.EXPLICIT_LAMBDA;
1598                    }
1599                    break;
1600                case RPAREN:
1601                    // if we have seen something that looks like a type,
1602                    // then it's a cast expression
1603                    if (type) return ParensResult.CAST;
1604                    // otherwise, disambiguate cast vs. parenthesized expression
1605                    // based on subsequent token.
1606                    switch (S.token(lookahead + 1).kind) {
1607                        /*case PLUSPLUS: case SUBSUB: */
1608                        case BANG: case TILDE:
1609                        case LPAREN: case THIS: case SUPER:
1610                        case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
1611                        case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1612                        case TRUE: case FALSE: case NULL:
1613                        case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
1614                        case BYTE: case SHORT: case CHAR: case INT:
1615                        case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1616                            return ParensResult.CAST;
1617                        default:
1618                            return ParensResult.PARENS;
1619                    }
1620                case UNDERSCORE:
1621                case ASSERT:
1622                case ENUM:
1623                case IDENTIFIER:
1624                    if (peekToken(lookahead, LAX_IDENTIFIER)) {
1625                        // Identifier, Identifier/'_'/'assert'/'enum' -> explicit lambda
1626                        return ParensResult.EXPLICIT_LAMBDA;
1627                    } else if (peekToken(lookahead, RPAREN, ARROW)) {
1628                        // Identifier, ')' '->' -> implicit lambda
1629                        return ParensResult.IMPLICIT_LAMBDA;
1630                    }
1631                    type = false;
1632                    break;
1633                case FINAL:
1634                case ELLIPSIS:
1635                    //those can only appear in explicit lambdas
1636                    return ParensResult.EXPLICIT_LAMBDA;
1637                case MONKEYS_AT:
1638                    type = true;
1639                    lookahead += 1; //skip '@'
1640                    while (peekToken(lookahead, DOT)) {
1641                        lookahead += 2;
1642                    }
1643                    if (peekToken(lookahead, LPAREN)) {
1644                        lookahead++;
1645                        //skip annotation values
1646                        int nesting = 0;
1647                        for (; ; lookahead++) {
1648                            TokenKind tk2 = S.token(lookahead).kind;
1649                            switch (tk2) {
1650                                case EOF:
1651                                    return ParensResult.PARENS;
1652                                case LPAREN:
1653                                    nesting++;
1654                                    break;
1655                                case RPAREN:
1656                                    nesting--;
1657                                    if (nesting == 0) {
1658                                        continue outer;
1659                                    }
1660                                break;
1661                            }
1662                        }
1663                    }
1664                    break;
1665                case LBRACKET:
1666                    if (peekToken(lookahead, RBRACKET, LAX_IDENTIFIER)) {
1667                        // '[', ']', Identifier/'_'/'assert'/'enum' -> explicit lambda
1668                        return ParensResult.EXPLICIT_LAMBDA;
1669                    } else if (peekToken(lookahead, RBRACKET, RPAREN) ||
1670                            peekToken(lookahead, RBRACKET, AMP)) {
1671                        // '[', ']', ')' -> cast
1672                        // '[', ']', '&' -> cast (intersection type)
1673                        return ParensResult.CAST;
1674                    } else if (peekToken(lookahead, RBRACKET)) {
1675                        //consume the ']' and skip
1676                        type = true;
1677                        lookahead++;
1678                        break;
1679                    } else {
1680                        return ParensResult.PARENS;
1681                    }
1682                case LT:
1683                    depth++; break;
1684                case GTGTGT:
1685                    depth--;
1686                case GTGT:
1687                    depth--;
1688                case GT:
1689                    depth--;
1690                    if (depth == 0) {
1691                        if (peekToken(lookahead, RPAREN) ||
1692                                peekToken(lookahead, AMP)) {
1693                            // '>', ')' -> cast
1694                            // '>', '&' -> cast
1695                            return ParensResult.CAST;
1696                        } else if (peekToken(lookahead, LAX_IDENTIFIER, COMMA) ||
1697                                peekToken(lookahead, LAX_IDENTIFIER, RPAREN, ARROW) ||
1698                                peekToken(lookahead, ELLIPSIS)) {
1699                            // '>', Identifier/'_'/'assert'/'enum', ',' -> explicit lambda
1700                            // '>', Identifier/'_'/'assert'/'enum', ')', '->' -> explicit lambda
1701                            // '>', '...' -> explicit lambda
1702                            return ParensResult.EXPLICIT_LAMBDA;
1703                        }
1704                        //it looks a type, but could still be (i) a cast to generic type,
1705                        //(ii) an unbound method reference or (iii) an explicit lambda
1706                        type = true;
1707                        break;
1708                    } else if (depth < 0) {
1709                        //unbalanced '<', '>' - not a generic type
1710                        return ParensResult.PARENS;
1711                    }
1712                    break;
1713                default:
1714                    //this includes EOF
1715                    return ParensResult.PARENS;
1716            }
1717        }
1718    }
1719
1720    /** Accepts all identifier-like tokens */
1721    protected Filter<TokenKind> LAX_IDENTIFIER = t -> t == IDENTIFIER || t == UNDERSCORE || t == ASSERT || t == ENUM;
1722
1723    enum ParensResult {
1724        CAST,
1725        EXPLICIT_LAMBDA,
1726        IMPLICIT_LAMBDA,
1727        PARENS
1728    }
1729
1730    JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
1731        List<JCVariableDecl> params = explicitParams ?
1732                formalParameters(true) :
1733                implicitParameters(hasParens);
1734
1735        return lambdaExpressionOrStatementRest(params, pos);
1736    }
1737
1738    JCExpression lambdaExpressionOrStatementRest(List<JCVariableDecl> args, int pos) {
1739        checkLambda();
1740        accept(ARROW);
1741
1742        return token.kind == LBRACE ?
1743            lambdaStatement(args, pos, pos) :
1744            lambdaExpression(args, pos);
1745    }
1746
1747    JCExpression lambdaStatement(List<JCVariableDecl> args, int pos, int pos2) {
1748        JCBlock block = block(pos2, 0);
1749        return toP(F.at(pos).Lambda(args, block));
1750    }
1751
1752    JCExpression lambdaExpression(List<JCVariableDecl> args, int pos) {
1753        JCTree expr = parseExpression();
1754        return toP(F.at(pos).Lambda(args, expr));
1755    }
1756
1757    /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1758     */
1759    JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1760        nextToken();
1761        if (token.kind == LPAREN || typeArgs != null) {
1762            t = arguments(typeArgs, t);
1763        } else if (token.kind == COLCOL) {
1764            if (typeArgs != null) return illegal();
1765            t = memberReferenceSuffix(t);
1766        } else {
1767            int pos = token.pos;
1768            accept(DOT);
1769            typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1770            t = toP(F.at(pos).Select(t, ident()));
1771            t = argumentsOpt(typeArgs, t);
1772        }
1773        return t;
1774    }
1775
1776    /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1777     */
1778    JCPrimitiveTypeTree basicType() {
1779        JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind)));
1780        nextToken();
1781        return t;
1782    }
1783
1784    /** ArgumentsOpt = [ Arguments ]
1785     */
1786    JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1787        if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) {
1788            mode = EXPR;
1789            return arguments(typeArgs, t);
1790        } else {
1791            return t;
1792        }
1793    }
1794
1795    /** Arguments = "(" [Expression { COMMA Expression }] ")"
1796     */
1797    List<JCExpression> arguments() {
1798        ListBuffer<JCExpression> args = new ListBuffer<>();
1799        if (token.kind == LPAREN) {
1800            nextToken();
1801            if (token.kind != RPAREN) {
1802                args.append(parseExpression());
1803                while (token.kind == COMMA) {
1804                    nextToken();
1805                    args.append(parseExpression());
1806                }
1807            }
1808            accept(RPAREN);
1809        } else {
1810            syntaxError(token.pos, "expected", LPAREN);
1811        }
1812        return args.toList();
1813    }
1814
1815    JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1816        int pos = token.pos;
1817        List<JCExpression> args = arguments();
1818        return toP(F.at(pos).Apply(typeArgs, t, args));
1819    }
1820
1821    /**  TypeArgumentsOpt = [ TypeArguments ]
1822     */
1823    JCExpression typeArgumentsOpt(JCExpression t) {
1824        if (token.kind == LT &&
1825            (mode & TYPE) != 0 &&
1826            (mode & NOPARAMS) == 0) {
1827            mode = TYPE;
1828            return typeArguments(t, false);
1829        } else {
1830            return t;
1831        }
1832    }
1833    List<JCExpression> typeArgumentsOpt() {
1834        return typeArgumentsOpt(TYPE);
1835    }
1836
1837    List<JCExpression> typeArgumentsOpt(int useMode) {
1838        if (token.kind == LT) {
1839            if ((mode & useMode) == 0 ||
1840                (mode & NOPARAMS) != 0) {
1841                illegal();
1842            }
1843            mode = useMode;
1844            return typeArguments(false);
1845        }
1846        return null;
1847    }
1848
1849    /**
1850     *  {@literal
1851     *  TypeArguments  = "<" TypeArgument {"," TypeArgument} ">"
1852     *  }
1853     */
1854    List<JCExpression> typeArguments(boolean diamondAllowed) {
1855        if (token.kind == LT) {
1856            nextToken();
1857            if (token.kind == GT && diamondAllowed) {
1858                checkDiamond();
1859                mode |= DIAMOND;
1860                nextToken();
1861                return List.nil();
1862            } else {
1863                ListBuffer<JCExpression> args = new ListBuffer<>();
1864                args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1865                while (token.kind == COMMA) {
1866                    nextToken();
1867                    args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1868                }
1869                switch (token.kind) {
1870
1871                case GTGTGTEQ: case GTGTEQ: case GTEQ:
1872                case GTGTGT: case GTGT:
1873                    token = S.split();
1874                    break;
1875                case GT:
1876                    nextToken();
1877                    break;
1878                default:
1879                    args.append(syntaxError(token.pos, "expected", GT));
1880                    break;
1881                }
1882                return args.toList();
1883            }
1884        } else {
1885            return List.<JCExpression>of(syntaxError(token.pos, "expected", LT));
1886        }
1887    }
1888
1889    /**
1890     *  {@literal
1891     *  TypeArgument = Type
1892     *               | [Annotations] "?"
1893     *               | [Annotations] "?" EXTENDS Type {"&" Type}
1894     *               | [Annotations] "?" SUPER Type
1895     *  }
1896     */
1897    JCExpression typeArgument() {
1898        List<JCAnnotation> annotations = typeAnnotationsOpt();
1899        if (token.kind != QUES) return parseType(annotations);
1900        int pos = token.pos;
1901        nextToken();
1902        JCExpression result;
1903        if (token.kind == EXTENDS) {
1904            TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
1905            nextToken();
1906            JCExpression bound = parseType();
1907            result = F.at(pos).Wildcard(t, bound);
1908        } else if (token.kind == SUPER) {
1909            TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
1910            nextToken();
1911            JCExpression bound = parseType();
1912            result = F.at(pos).Wildcard(t, bound);
1913        } else if (LAX_IDENTIFIER.accepts(token.kind)) {
1914            //error recovery
1915            TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1916            JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1917            JCIdent id = toP(F.at(token.pos).Ident(ident()));
1918            JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1919            reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
1920            result = err;
1921        } else {
1922            TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
1923            result = toP(F.at(pos).Wildcard(t, null));
1924        }
1925        if (!annotations.isEmpty()) {
1926            result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1927        }
1928        return result;
1929    }
1930
1931    JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) {
1932        int pos = token.pos;
1933        List<JCExpression> args = typeArguments(diamondAllowed);
1934        return toP(F.at(pos).TypeApply(t, args));
1935    }
1936
1937    /**
1938     * BracketsOpt = { [Annotations] "[" "]" }*
1939     *
1940     * <p>
1941     *
1942     * <code>annotations</code> is the list of annotations targeting
1943     * the expression <code>t</code>.
1944     */
1945    private JCExpression bracketsOpt(JCExpression t,
1946            List<JCAnnotation> annotations) {
1947        List<JCAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1948
1949        if (token.kind == LBRACKET) {
1950            int pos = token.pos;
1951            nextToken();
1952            t = bracketsOptCont(t, pos, nextLevelAnnotations);
1953        } else if (!nextLevelAnnotations.isEmpty()) {
1954            if (permitTypeAnnotationsPushBack) {
1955                this.typeAnnotationsPushedBack = nextLevelAnnotations;
1956            } else {
1957                return illegal(nextLevelAnnotations.head.pos);
1958            }
1959        }
1960
1961        if (!annotations.isEmpty()) {
1962            t = toP(F.at(token.pos).AnnotatedType(annotations, t));
1963        }
1964        return t;
1965    }
1966
1967    /** BracketsOpt = [ "[" "]" { [Annotations] "[" "]"} ]
1968     */
1969    private JCExpression bracketsOpt(JCExpression t) {
1970        return bracketsOpt(t, List.<JCAnnotation>nil());
1971    }
1972
1973    private JCExpression bracketsOptCont(JCExpression t, int pos,
1974            List<JCAnnotation> annotations) {
1975        accept(RBRACKET);
1976        t = bracketsOpt(t);
1977        t = toP(F.at(pos).TypeArray(t));
1978        if (annotations.nonEmpty()) {
1979            t = toP(F.at(pos).AnnotatedType(annotations, t));
1980        }
1981        return t;
1982    }
1983
1984    /** BracketsSuffixExpr = "." CLASS
1985     *  BracketsSuffixType =
1986     */
1987    JCExpression bracketsSuffix(JCExpression t) {
1988        if ((mode & EXPR) != 0 && token.kind == DOT) {
1989            mode = EXPR;
1990            int pos = token.pos;
1991            nextToken();
1992            accept(CLASS);
1993            if (token.pos == endPosTable.errorEndPos) {
1994                // error recovery
1995                Name name;
1996                if (LAX_IDENTIFIER.accepts(token.kind)) {
1997                    name = token.name();
1998                    nextToken();
1999                } else {
2000                    name = names.error;
2001                }
2002                t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2003            } else {
2004                Tag tag = t.getTag();
2005                // Type annotations are illegal on class literals. Annotated non array class literals
2006                // are complained about directly in term3(), Here check for type annotations on dimensions
2007                // taking care to handle some interior dimension(s) being annotated.
2008                if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2009                    syntaxError("no.annotations.on.dot.class");
2010                t = toP(F.at(pos).Select(t, names._class));
2011            }
2012        } else if ((mode & TYPE) != 0) {
2013            if (token.kind != COLCOL) {
2014                mode = TYPE;
2015            }
2016        } else if (token.kind != COLCOL) {
2017            syntaxError(token.pos, "dot.class.expected");
2018        }
2019        return t;
2020    }
2021
2022    /**
2023     * MemberReferenceSuffix = "::" [TypeArguments] Ident
2024     *                       | "::" [TypeArguments] "new"
2025     */
2026    JCExpression memberReferenceSuffix(JCExpression t) {
2027        int pos1 = token.pos;
2028        accept(COLCOL);
2029        return memberReferenceSuffix(pos1, t);
2030    }
2031
2032    JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2033        checkMethodReferences();
2034        mode = EXPR;
2035        List<JCExpression> typeArgs = null;
2036        if (token.kind == LT) {
2037            typeArgs = typeArguments(false);
2038        }
2039        Name refName;
2040        ReferenceMode refMode;
2041        if (token.kind == NEW) {
2042            refMode = ReferenceMode.NEW;
2043            refName = names.init;
2044            nextToken();
2045        } else {
2046            refMode = ReferenceMode.INVOKE;
2047            refName = ident();
2048        }
2049        return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2050    }
2051
2052    /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2053     */
2054    JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2055        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2056
2057        switch (token.kind) {
2058        case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2059        case DOUBLE: case BOOLEAN:
2060            if (typeArgs == null) {
2061                if (newAnnotations.isEmpty()) {
2062                    return arrayCreatorRest(newpos, basicType());
2063                } else {
2064                    return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2065                }
2066            }
2067            break;
2068        default:
2069        }
2070        JCExpression t = qualident(true);
2071
2072        int oldmode = mode;
2073        mode = TYPE;
2074        boolean diamondFound = false;
2075        int lastTypeargsPos = -1;
2076        if (token.kind == LT) {
2077            lastTypeargsPos = token.pos;
2078            t = typeArguments(t, true);
2079            diamondFound = (mode & DIAMOND) != 0;
2080        }
2081        while (token.kind == DOT) {
2082            if (diamondFound) {
2083                //cannot select after a diamond
2084                illegal();
2085            }
2086            int pos = token.pos;
2087            nextToken();
2088            List<JCAnnotation> tyannos = typeAnnotationsOpt();
2089            t = toP(F.at(pos).Select(t, ident()));
2090
2091            if (tyannos != null && tyannos.nonEmpty()) {
2092                t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
2093            }
2094
2095            if (token.kind == LT) {
2096                lastTypeargsPos = token.pos;
2097                t = typeArguments(t, true);
2098                diamondFound = (mode & DIAMOND) != 0;
2099            }
2100        }
2101        mode = oldmode;
2102        if (token.kind == LBRACKET || token.kind == MONKEYS_AT) {
2103            // handle type annotations for non primitive arrays
2104            if (newAnnotations.nonEmpty()) {
2105                t = insertAnnotationsToMostInner(t, newAnnotations, false);
2106            }
2107
2108            JCExpression e = arrayCreatorRest(newpos, t);
2109            if (diamondFound) {
2110                reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond");
2111                return toP(F.at(newpos).Erroneous(List.of(e)));
2112            }
2113            else if (typeArgs != null) {
2114                int pos = newpos;
2115                if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2116                    // note: this should always happen but we should
2117                    // not rely on this as the parser is continuously
2118                    // modified to improve error recovery.
2119                    pos = typeArgs.head.pos;
2120                }
2121                setErrorEndPos(S.prevToken().endPos);
2122                JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2123                reportSyntaxError(err, "cannot.create.array.with.type.arguments");
2124                return toP(err);
2125            }
2126            return e;
2127        } else if (token.kind == LPAREN) {
2128            JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
2129            if (newClass.def != null) {
2130                assert newClass.def.mods.annotations.isEmpty();
2131                if (newAnnotations.nonEmpty()) {
2132                    // Add type and declaration annotations to the new class;
2133                    // com.sun.tools.javac.code.TypeAnnotations.TypeAnnotationPositions.visitNewClass(JCNewClass)
2134                    // will later remove all type annotations and only leave the
2135                    // declaration annotations.
2136                    newClass.def.mods.pos = earlier(newClass.def.mods.pos, newAnnotations.head.pos);
2137                    newClass.def.mods.annotations = newAnnotations;
2138                }
2139            } else {
2140                // handle type annotations for instantiations
2141                if (newAnnotations.nonEmpty()) {
2142                    t = insertAnnotationsToMostInner(t, newAnnotations, false);
2143                    newClass.clazz = t;
2144                }
2145            }
2146            return newClass;
2147        } else {
2148            setErrorEndPos(token.pos);
2149            reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET);
2150            t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
2151            return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2152        }
2153    }
2154
2155    /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2156     */
2157    JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2158        List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2159
2160        JCExpression t = toP(F.at(token.pos).Ident(ident()));
2161
2162        if (newAnnotations.nonEmpty()) {
2163            t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2164        }
2165
2166        if (token.kind == LT) {
2167            int oldmode = mode;
2168            t = typeArguments(t, true);
2169            mode = oldmode;
2170        }
2171        return classCreatorRest(newpos, encl, typeArgs, t);
2172    }
2173
2174    /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2175     *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2176     */
2177    JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2178        List<JCAnnotation> annos = typeAnnotationsOpt();
2179
2180        accept(LBRACKET);
2181        if (token.kind == RBRACKET) {
2182            accept(RBRACKET);
2183            elemtype = bracketsOpt(elemtype, annos);
2184            if (token.kind == LBRACE) {
2185                JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2186                if (annos.nonEmpty()) {
2187                    // when an array initializer is present then
2188                    // the parsed annotations should target the
2189                    // new array tree
2190                    // bracketsOpt inserts the annotation in
2191                    // elemtype, and it needs to be corrected
2192                    //
2193                    JCAnnotatedType annotated = (JCAnnotatedType)elemtype;
2194                    assert annotated.annotations == annos;
2195                    na.annotations = annotated.annotations;
2196                    na.elemtype = annotated.underlyingType;
2197                }
2198                return na;
2199            } else {
2200                JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
2201                return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing");
2202            }
2203        } else {
2204            ListBuffer<JCExpression> dims = new ListBuffer<>();
2205
2206            // maintain array dimension type annotations
2207            ListBuffer<List<JCAnnotation>> dimAnnotations = new ListBuffer<>();
2208            dimAnnotations.append(annos);
2209
2210            dims.append(parseExpression());
2211            accept(RBRACKET);
2212            while (token.kind == LBRACKET
2213                    || token.kind == MONKEYS_AT) {
2214                List<JCAnnotation> maybeDimAnnos = typeAnnotationsOpt();
2215                int pos = token.pos;
2216                nextToken();
2217                if (token.kind == RBRACKET) {
2218                    elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2219                } else {
2220                    if (token.kind == RBRACKET) { // no dimension
2221                        elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
2222                    } else {
2223                        dimAnnotations.append(maybeDimAnnos);
2224                        dims.append(parseExpression());
2225                        accept(RBRACKET);
2226                    }
2227                }
2228            }
2229
2230            JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
2231            na.dimAnnotations = dimAnnotations.toList();
2232            return na;
2233        }
2234    }
2235
2236    /** ClassCreatorRest = Arguments [ClassBody]
2237     */
2238    JCNewClass classCreatorRest(int newpos,
2239                                  JCExpression encl,
2240                                  List<JCExpression> typeArgs,
2241                                  JCExpression t)
2242    {
2243        List<JCExpression> args = arguments();
2244        JCClassDecl body = null;
2245        if (token.kind == LBRACE) {
2246            int pos = token.pos;
2247            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2248            JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2249            body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2250        }
2251        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2252    }
2253
2254    /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2255     */
2256    JCExpression arrayInitializer(int newpos, JCExpression t) {
2257        accept(LBRACE);
2258        ListBuffer<JCExpression> elems = new ListBuffer<>();
2259        if (token.kind == COMMA) {
2260            nextToken();
2261        } else if (token.kind != RBRACE) {
2262            elems.append(variableInitializer());
2263            while (token.kind == COMMA) {
2264                nextToken();
2265                if (token.kind == RBRACE) break;
2266                elems.append(variableInitializer());
2267            }
2268        }
2269        accept(RBRACE);
2270        return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
2271    }
2272
2273    /** VariableInitializer = ArrayInitializer | Expression
2274     */
2275    public JCExpression variableInitializer() {
2276        return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
2277    }
2278
2279    /** ParExpression = "(" Expression ")"
2280     */
2281    JCExpression parExpression() {
2282        int pos = token.pos;
2283        accept(LPAREN);
2284        JCExpression t = parseExpression();
2285        accept(RPAREN);
2286        return toP(F.at(pos).Parens(t));
2287    }
2288
2289    /** Block = "{" BlockStatements "}"
2290     */
2291    JCBlock block(int pos, long flags) {
2292        accept(LBRACE);
2293        List<JCStatement> stats = blockStatements();
2294        JCBlock t = F.at(pos).Block(flags, stats);
2295        while (token.kind == CASE || token.kind == DEFAULT) {
2296            syntaxError("orphaned", token.kind);
2297            switchBlockStatementGroups();
2298        }
2299        // the Block node has a field "endpos" for first char of last token, which is
2300        // usually but not necessarily the last char of the last token.
2301        t.endpos = token.pos;
2302        accept(RBRACE);
2303        return toP(t);
2304    }
2305
2306    public JCBlock block() {
2307        return block(token.pos, 0);
2308    }
2309
2310    /** BlockStatements = { BlockStatement }
2311     *  BlockStatement  = LocalVariableDeclarationStatement
2312     *                  | ClassOrInterfaceOrEnumDeclaration
2313     *                  | [Ident ":"] Statement
2314     *  LocalVariableDeclarationStatement
2315     *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
2316     */
2317    @SuppressWarnings("fallthrough")
2318    List<JCStatement> blockStatements() {
2319        //todo: skip to anchor on error(?)
2320        int lastErrPos = -1;
2321        ListBuffer<JCStatement> stats = new ListBuffer<>();
2322        while (true) {
2323            List<JCStatement> stat = blockStatement();
2324            if (stat.isEmpty()) {
2325                return stats.toList();
2326            } else {
2327                // error recovery
2328                if (token.pos == lastErrPos)
2329                    return stats.toList();
2330                if (token.pos <= endPosTable.errorEndPos) {
2331                    skip(false, true, true, true);
2332                    lastErrPos = token.pos;
2333                }
2334                stats.addAll(stat);
2335            }
2336        }
2337    }
2338
2339    /*
2340     * Parse a Statement (JLS 14.5). As an enhancement to improve error recovery,
2341     * this method will also recognize variable and class declarations (which are
2342     * not legal for a Statement) by delegating the parsing to BlockStatement (JLS 14.2).
2343     * If any illegal declarations are found, they will be wrapped in an erroneous tree,
2344     * and an error will be produced by this method.
2345     */
2346    JCStatement parseStatementAsBlock() {
2347        int pos = token.pos;
2348        List<JCStatement> stats = blockStatement();
2349        if (stats.isEmpty()) {
2350            JCErroneous e = F.at(pos).Erroneous();
2351            error(e, "illegal.start.of.stmt");
2352            return F.at(pos).Exec(e);
2353        } else {
2354            JCStatement first = stats.head;
2355            String error = null;
2356            switch (first.getTag()) {
2357            case CLASSDEF:
2358                error = "class.not.allowed";
2359                break;
2360            case VARDEF:
2361                error = "variable.not.allowed";
2362                break;
2363            }
2364            if (error != null) {
2365                error(first, error);
2366                List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2367                return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2368            }
2369            return first;
2370        }
2371    }
2372
2373    /**This method parses a statement appearing inside a block.
2374     */
2375    List<JCStatement> blockStatement() {
2376        //todo: skip to anchor on error(?)
2377        int pos = token.pos;
2378        switch (token.kind) {
2379        case RBRACE: case CASE: case DEFAULT: case EOF:
2380            return List.nil();
2381        case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2382        case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2383        case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2384        case ASSERT:
2385            return List.of(parseSimpleStatement());
2386        case MONKEYS_AT:
2387        case FINAL: {
2388            Comment dc = token.comment(CommentStyle.JAVADOC);
2389            JCModifiers mods = modifiersOpt();
2390            if (token.kind == INTERFACE ||
2391                token.kind == CLASS ||
2392                token.kind == ENUM) {
2393                return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2394            } else {
2395                JCExpression t = parseType();
2396                ListBuffer<JCStatement> stats =
2397                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2398                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2399                accept(SEMI);
2400                storeEnd(stats.last(), S.prevToken().endPos);
2401                return stats.toList();
2402            }
2403        }
2404        case ABSTRACT: case STRICTFP: {
2405            Comment dc = token.comment(CommentStyle.JAVADOC);
2406            JCModifiers mods = modifiersOpt();
2407            return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2408        }
2409        case INTERFACE:
2410        case CLASS:
2411            Comment dc = token.comment(CommentStyle.JAVADOC);
2412            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2413        case ENUM:
2414            error(token.pos, "local.enum");
2415            dc = token.comment(CommentStyle.JAVADOC);
2416            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2417        default:
2418            Token prevToken = token;
2419            JCExpression t = term(EXPR | TYPE);
2420            if (token.kind == COLON && t.hasTag(IDENT)) {
2421                nextToken();
2422                JCStatement stat = parseStatementAsBlock();
2423                return List.<JCStatement>of(F.at(pos).Labelled(prevToken.name(), stat));
2424            } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2425                pos = token.pos;
2426                JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2427                F.at(pos);
2428                ListBuffer<JCStatement> stats =
2429                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2430                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2431                accept(SEMI);
2432                storeEnd(stats.last(), S.prevToken().endPos);
2433                return stats.toList();
2434            } else {
2435                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2436                t = checkExprStat(t);
2437                accept(SEMI);
2438                JCExpressionStatement expr = toP(F.at(pos).Exec(t));
2439                return List.<JCStatement>of(expr);
2440            }
2441        }
2442    }
2443
2444    /** Statement =
2445     *       Block
2446     *     | IF ParExpression Statement [ELSE Statement]
2447     *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
2448     *     | FOR "(" FormalParameter : Expression ")" Statement
2449     *     | WHILE ParExpression Statement
2450     *     | DO Statement WHILE ParExpression ";"
2451     *     | TRY Block ( Catches | [Catches] FinallyPart )
2452     *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
2453     *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
2454     *     | SYNCHRONIZED ParExpression Block
2455     *     | RETURN [Expression] ";"
2456     *     | THROW Expression ";"
2457     *     | BREAK [Ident] ";"
2458     *     | CONTINUE [Ident] ";"
2459     *     | ASSERT Expression [ ":" Expression ] ";"
2460     *     | ";"
2461     */
2462    public JCStatement parseSimpleStatement() {
2463        int pos = token.pos;
2464        switch (token.kind) {
2465        case LBRACE:
2466            return block();
2467        case IF: {
2468            nextToken();
2469            JCExpression cond = parExpression();
2470            JCStatement thenpart = parseStatementAsBlock();
2471            JCStatement elsepart = null;
2472            if (token.kind == ELSE) {
2473                nextToken();
2474                elsepart = parseStatementAsBlock();
2475            }
2476            return F.at(pos).If(cond, thenpart, elsepart);
2477        }
2478        case FOR: {
2479            nextToken();
2480            accept(LPAREN);
2481            List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
2482            if (inits.length() == 1 &&
2483                inits.head.hasTag(VARDEF) &&
2484                ((JCVariableDecl) inits.head).init == null &&
2485                token.kind == COLON) {
2486                JCVariableDecl var = (JCVariableDecl)inits.head;
2487                accept(COLON);
2488                JCExpression expr = parseExpression();
2489                accept(RPAREN);
2490                JCStatement body = parseStatementAsBlock();
2491                return F.at(pos).ForeachLoop(var, expr, body);
2492            } else {
2493                accept(SEMI);
2494                JCExpression cond = token.kind == SEMI ? null : parseExpression();
2495                accept(SEMI);
2496                List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
2497                accept(RPAREN);
2498                JCStatement body = parseStatementAsBlock();
2499                return F.at(pos).ForLoop(inits, cond, steps, body);
2500            }
2501        }
2502        case WHILE: {
2503            nextToken();
2504            JCExpression cond = parExpression();
2505            JCStatement body = parseStatementAsBlock();
2506            return F.at(pos).WhileLoop(cond, body);
2507        }
2508        case DO: {
2509            nextToken();
2510            JCStatement body = parseStatementAsBlock();
2511            accept(WHILE);
2512            JCExpression cond = parExpression();
2513            accept(SEMI);
2514            JCDoWhileLoop t = toP(F.at(pos).DoLoop(body, cond));
2515            return t;
2516        }
2517        case TRY: {
2518            nextToken();
2519            List<JCTree> resources = List.<JCTree>nil();
2520            if (token.kind == LPAREN) {
2521                checkTryWithResources();
2522                nextToken();
2523                resources = resources();
2524                accept(RPAREN);
2525            }
2526            JCBlock body = block();
2527            ListBuffer<JCCatch> catchers = new ListBuffer<>();
2528            JCBlock finalizer = null;
2529            if (token.kind == CATCH || token.kind == FINALLY) {
2530                while (token.kind == CATCH) catchers.append(catchClause());
2531                if (token.kind == FINALLY) {
2532                    nextToken();
2533                    finalizer = block();
2534                }
2535            } else {
2536                if (resources.isEmpty()) {
2537                    if (allowTWR) {
2538                        error(pos, "try.without.catch.finally.or.resource.decls");
2539                    } else {
2540                        error(pos, "try.without.catch.or.finally");
2541                    }
2542                }
2543            }
2544            return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
2545        }
2546        case SWITCH: {
2547            nextToken();
2548            JCExpression selector = parExpression();
2549            accept(LBRACE);
2550            List<JCCase> cases = switchBlockStatementGroups();
2551            JCSwitch t = to(F.at(pos).Switch(selector, cases));
2552            accept(RBRACE);
2553            return t;
2554        }
2555        case SYNCHRONIZED: {
2556            nextToken();
2557            JCExpression lock = parExpression();
2558            JCBlock body = block();
2559            return F.at(pos).Synchronized(lock, body);
2560        }
2561        case RETURN: {
2562            nextToken();
2563            JCExpression result = token.kind == SEMI ? null : parseExpression();
2564            accept(SEMI);
2565            JCReturn t = toP(F.at(pos).Return(result));
2566            return t;
2567        }
2568        case THROW: {
2569            nextToken();
2570            JCExpression exc = parseExpression();
2571            accept(SEMI);
2572            JCThrow t = toP(F.at(pos).Throw(exc));
2573            return t;
2574        }
2575        case BREAK: {
2576            nextToken();
2577            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2578            accept(SEMI);
2579            JCBreak t = toP(F.at(pos).Break(label));
2580            return t;
2581        }
2582        case CONTINUE: {
2583            nextToken();
2584            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2585            accept(SEMI);
2586            JCContinue t =  toP(F.at(pos).Continue(label));
2587            return t;
2588        }
2589        case SEMI:
2590            nextToken();
2591            return toP(F.at(pos).Skip());
2592        case ELSE:
2593            int elsePos = token.pos;
2594            nextToken();
2595            return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
2596        case FINALLY:
2597            int finallyPos = token.pos;
2598            nextToken();
2599            return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
2600        case CATCH:
2601            return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
2602        case ASSERT: {
2603            nextToken();
2604            JCExpression assertion = parseExpression();
2605            JCExpression message = null;
2606            if (token.kind == COLON) {
2607                nextToken();
2608                message = parseExpression();
2609            }
2610            accept(SEMI);
2611            JCAssert t = toP(F.at(pos).Assert(assertion, message));
2612            return t;
2613        }
2614        default:
2615            Assert.error();
2616            return null;
2617        }
2618    }
2619
2620    @Override
2621    public JCStatement parseStatement() {
2622        return parseStatementAsBlock();
2623    }
2624
2625    private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
2626        int errPos = S.errPos();
2627        JCTree stm = action.doRecover(this);
2628        S.errPos(errPos);
2629        return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
2630    }
2631
2632    /** CatchClause     = CATCH "(" FormalParameter ")" Block
2633     * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
2634     */
2635    protected JCCatch catchClause() {
2636        int pos = token.pos;
2637        accept(CATCH);
2638        accept(LPAREN);
2639        JCModifiers mods = optFinal(Flags.PARAMETER);
2640        List<JCExpression> catchTypes = catchTypes();
2641        JCExpression paramType = catchTypes.size() > 1 ?
2642                toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
2643                catchTypes.head;
2644        JCVariableDecl formal = variableDeclaratorId(mods, paramType);
2645        accept(RPAREN);
2646        JCBlock body = block();
2647        return F.at(pos).Catch(formal, body);
2648    }
2649
2650    List<JCExpression> catchTypes() {
2651        ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
2652        catchTypes.add(parseType());
2653        while (token.kind == BAR) {
2654            checkMulticatch();
2655            nextToken();
2656            // Instead of qualident this is now parseType.
2657            // But would that allow too much, e.g. arrays or generics?
2658            catchTypes.add(parseType());
2659        }
2660        return catchTypes.toList();
2661    }
2662
2663    /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2664     *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2665     *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2666     */
2667    List<JCCase> switchBlockStatementGroups() {
2668        ListBuffer<JCCase> cases = new ListBuffer<>();
2669        while (true) {
2670            int pos = token.pos;
2671            switch (token.kind) {
2672            case CASE:
2673            case DEFAULT:
2674                cases.append(switchBlockStatementGroup());
2675                break;
2676            case RBRACE: case EOF:
2677                return cases.toList();
2678            default:
2679                nextToken(); // to ensure progress
2680                syntaxError(pos, "expected3",
2681                    CASE, DEFAULT, RBRACE);
2682            }
2683        }
2684    }
2685
2686    protected JCCase switchBlockStatementGroup() {
2687        int pos = token.pos;
2688        List<JCStatement> stats;
2689        JCCase c;
2690        switch (token.kind) {
2691        case CASE:
2692            nextToken();
2693            JCExpression pat = parseExpression();
2694            accept(COLON);
2695            stats = blockStatements();
2696            c = F.at(pos).Case(pat, stats);
2697            if (stats.isEmpty())
2698                storeEnd(c, S.prevToken().endPos);
2699            return c;
2700        case DEFAULT:
2701            nextToken();
2702            accept(COLON);
2703            stats = blockStatements();
2704            c = F.at(pos).Case(null, stats);
2705            if (stats.isEmpty())
2706                storeEnd(c, S.prevToken().endPos);
2707            return c;
2708        }
2709        throw new AssertionError("should not reach here");
2710    }
2711
2712    /** MoreStatementExpressions = { COMMA StatementExpression }
2713     */
2714    <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2715                                                                    JCExpression first,
2716                                                                    T stats) {
2717        // This Exec is a "StatementExpression"; it subsumes no terminating token
2718        stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2719        while (token.kind == COMMA) {
2720            nextToken();
2721            pos = token.pos;
2722            JCExpression t = parseExpression();
2723            // This Exec is a "StatementExpression"; it subsumes no terminating token
2724            stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2725        }
2726        return stats;
2727    }
2728
2729    /** ForInit = StatementExpression MoreStatementExpressions
2730     *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2731     */
2732    List<JCStatement> forInit() {
2733        ListBuffer<JCStatement> stats = new ListBuffer<>();
2734        int pos = token.pos;
2735        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
2736            return variableDeclarators(optFinal(0), parseType(), stats).toList();
2737        } else {
2738            JCExpression t = term(EXPR | TYPE);
2739            if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2740                return variableDeclarators(modifiersOpt(), t, stats).toList();
2741            } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
2742                error(pos, "bad.initializer", "for-loop");
2743                return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
2744            } else {
2745                return moreStatementExpressions(pos, t, stats).toList();
2746            }
2747        }
2748    }
2749
2750    /** ForUpdate = StatementExpression MoreStatementExpressions
2751     */
2752    List<JCExpressionStatement> forUpdate() {
2753        return moreStatementExpressions(token.pos,
2754                                        parseExpression(),
2755                                        new ListBuffer<JCExpressionStatement>()).toList();
2756    }
2757
2758    /** AnnotationsOpt = { '@' Annotation }
2759     *
2760     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2761     */
2762    protected List<JCAnnotation> annotationsOpt(Tag kind) {
2763        if (token.kind != MONKEYS_AT) return List.nil(); // optimization
2764        ListBuffer<JCAnnotation> buf = new ListBuffer<>();
2765        int prevmode = mode;
2766        while (token.kind == MONKEYS_AT) {
2767            int pos = token.pos;
2768            nextToken();
2769            buf.append(annotation(pos, kind));
2770        }
2771        lastmode = mode;
2772        mode = prevmode;
2773        List<JCAnnotation> annotations = buf.toList();
2774
2775        return annotations;
2776    }
2777
2778    List<JCAnnotation> typeAnnotationsOpt() {
2779        List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
2780        return annotations;
2781    }
2782
2783    /** ModifiersOpt = { Modifier }
2784     *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2785     *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2786     *           | "@" Annotation
2787     */
2788    protected JCModifiers modifiersOpt() {
2789        return modifiersOpt(null);
2790    }
2791    protected JCModifiers modifiersOpt(JCModifiers partial) {
2792        long flags;
2793        ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
2794        int pos;
2795        if (partial == null) {
2796            flags = 0;
2797            pos = token.pos;
2798        } else {
2799            flags = partial.flags;
2800            annotations.appendList(partial.annotations);
2801            pos = partial.pos;
2802        }
2803        if (token.deprecatedFlag()) {
2804            flags |= Flags.DEPRECATED;
2805        }
2806        int lastPos;
2807    loop:
2808        while (true) {
2809            long flag;
2810            switch (token.kind) {
2811            case PRIVATE     : flag = Flags.PRIVATE; break;
2812            case PROTECTED   : flag = Flags.PROTECTED; break;
2813            case PUBLIC      : flag = Flags.PUBLIC; break;
2814            case STATIC      : flag = Flags.STATIC; break;
2815            case TRANSIENT   : flag = Flags.TRANSIENT; break;
2816            case FINAL       : flag = Flags.FINAL; break;
2817            case ABSTRACT    : flag = Flags.ABSTRACT; break;
2818            case NATIVE      : flag = Flags.NATIVE; break;
2819            case VOLATILE    : flag = Flags.VOLATILE; break;
2820            case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2821            case STRICTFP    : flag = Flags.STRICTFP; break;
2822            case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2823            case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
2824            case ERROR       : flag = 0; nextToken(); break;
2825            default: break loop;
2826            }
2827            if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
2828            lastPos = token.pos;
2829            nextToken();
2830            if (flag == Flags.ANNOTATION) {
2831                if (token.kind != INTERFACE) {
2832                    JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
2833                    // if first modifier is an annotation, set pos to annotation's.
2834                    if (flags == 0 && annotations.isEmpty())
2835                        pos = ann.pos;
2836                    annotations.append(ann);
2837                    flag = 0;
2838                }
2839            }
2840            flags |= flag;
2841        }
2842        switch (token.kind) {
2843        case ENUM: flags |= Flags.ENUM; break;
2844        case INTERFACE: flags |= Flags.INTERFACE; break;
2845        default: break;
2846        }
2847
2848        /* A modifiers tree with no modifier tokens or annotations
2849         * has no text position. */
2850        if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
2851            pos = Position.NOPOS;
2852
2853        JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2854        if (pos != Position.NOPOS)
2855            storeEnd(mods, S.prevToken().endPos);
2856        return mods;
2857    }
2858
2859    /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2860     *
2861     * @param pos position of "@" token
2862     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2863     */
2864    JCAnnotation annotation(int pos, Tag kind) {
2865        // accept(AT); // AT consumed by caller
2866        if (kind == Tag.TYPE_ANNOTATION) {
2867            checkTypeAnnotations();
2868        }
2869        JCTree ident = qualident(false);
2870        List<JCExpression> fieldValues = annotationFieldValuesOpt();
2871        JCAnnotation ann;
2872        if (kind == Tag.ANNOTATION) {
2873            ann = F.at(pos).Annotation(ident, fieldValues);
2874        } else if (kind == Tag.TYPE_ANNOTATION) {
2875            ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2876        } else {
2877            throw new AssertionError("Unhandled annotation kind: " + kind);
2878        }
2879
2880        storeEnd(ann, S.prevToken().endPos);
2881        return ann;
2882    }
2883
2884    List<JCExpression> annotationFieldValuesOpt() {
2885        return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2886    }
2887
2888    /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2889    List<JCExpression> annotationFieldValues() {
2890        accept(LPAREN);
2891        ListBuffer<JCExpression> buf = new ListBuffer<>();
2892        if (token.kind != RPAREN) {
2893            buf.append(annotationFieldValue());
2894            while (token.kind == COMMA) {
2895                nextToken();
2896                buf.append(annotationFieldValue());
2897            }
2898        }
2899        accept(RPAREN);
2900        return buf.toList();
2901    }
2902
2903    /** AnnotationFieldValue    = AnnotationValue
2904     *                          | Identifier "=" AnnotationValue
2905     */
2906    JCExpression annotationFieldValue() {
2907        if (LAX_IDENTIFIER.accepts(token.kind)) {
2908            mode = EXPR;
2909            JCExpression t1 = term1();
2910            if (t1.hasTag(IDENT) && token.kind == EQ) {
2911                int pos = token.pos;
2912                accept(EQ);
2913                JCExpression v = annotationValue();
2914                return toP(F.at(pos).Assign(t1, v));
2915            } else {
2916                return t1;
2917            }
2918        }
2919        return annotationValue();
2920    }
2921
2922    /* AnnotationValue          = ConditionalExpression
2923     *                          | Annotation
2924     *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2925     */
2926    JCExpression annotationValue() {
2927        int pos;
2928        switch (token.kind) {
2929        case MONKEYS_AT:
2930            pos = token.pos;
2931            nextToken();
2932            return annotation(pos, Tag.ANNOTATION);
2933        case LBRACE:
2934            pos = token.pos;
2935            accept(LBRACE);
2936            ListBuffer<JCExpression> buf = new ListBuffer<>();
2937            if (token.kind == COMMA) {
2938                nextToken();
2939            } else if (token.kind != RBRACE) {
2940                buf.append(annotationValue());
2941                while (token.kind == COMMA) {
2942                    nextToken();
2943                    if (token.kind == RBRACE) break;
2944                    buf.append(annotationValue());
2945                }
2946            }
2947            accept(RBRACE);
2948            return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2949        default:
2950            mode = EXPR;
2951            return term1();
2952        }
2953    }
2954
2955    /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2956     */
2957    public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2958                                                                         JCExpression type,
2959                                                                         T vdefs)
2960    {
2961        return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
2962    }
2963
2964    /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2965     *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2966     *
2967     *  @param reqInit  Is an initializer always required?
2968     *  @param dc       The documentation comment for the variable declarations, or null.
2969     */
2970    protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2971                                                                     JCModifiers mods,
2972                                                                     JCExpression type,
2973                                                                     Name name,
2974                                                                     boolean reqInit,
2975                                                                     Comment dc,
2976                                                                     T vdefs)
2977    {
2978        vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2979        while (token.kind == COMMA) {
2980            // All but last of multiple declarators subsume a comma
2981            storeEnd((JCTree)vdefs.last(), token.endPos);
2982            nextToken();
2983            vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2984        }
2985        return vdefs;
2986    }
2987
2988    /** VariableDeclarator = Ident VariableDeclaratorRest
2989     *  ConstantDeclarator = Ident ConstantDeclaratorRest
2990     */
2991    JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
2992        return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
2993    }
2994
2995    /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2996     *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2997     *
2998     *  @param reqInit  Is an initializer always required?
2999     *  @param dc       The documentation comment for the variable declarations, or null.
3000     */
3001    JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
3002                                  boolean reqInit, Comment dc) {
3003        type = bracketsOpt(type);
3004        JCExpression init = null;
3005        if (token.kind == EQ) {
3006            nextToken();
3007            init = variableInitializer();
3008        }
3009        else if (reqInit) syntaxError(token.pos, "expected", EQ);
3010        JCVariableDecl result =
3011            toP(F.at(pos).VarDef(mods, name, type, init));
3012        attach(result, dc);
3013        return result;
3014    }
3015
3016    /** VariableDeclaratorId = Ident BracketsOpt
3017     */
3018    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3019        return variableDeclaratorId(mods, type, false);
3020    }
3021    //where
3022    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3023        int pos = token.pos;
3024        Name name;
3025        if (lambdaParameter && token.kind == UNDERSCORE) {
3026            log.error(pos, "underscore.as.identifier.in.lambda");
3027            name = token.name();
3028            nextToken();
3029        } else {
3030            if (allowThisIdent && !lambdaParameter) {
3031                JCExpression pn = qualident(false);
3032                if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3033                    name = ((JCIdent)pn).name;
3034                } else {
3035                    if ((mods.flags & Flags.VARARGS) != 0) {
3036                        log.error(token.pos, "varargs.and.receiver");
3037                    }
3038                    if (token.kind == LBRACKET) {
3039                        log.error(token.pos, "array.and.receiver");
3040                    }
3041                    return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
3042                }
3043            } else {
3044                name = ident();
3045            }
3046        }
3047        if ((mods.flags & Flags.VARARGS) != 0 &&
3048                token.kind == LBRACKET) {
3049            log.error(token.pos, "varargs.and.old.array.syntax");
3050        }
3051        type = bracketsOpt(type);
3052        return toP(F.at(pos).VarDef(mods, name, type, null));
3053    }
3054
3055    /** Resources = Resource { ";" Resources }
3056     */
3057    List<JCTree> resources() {
3058        ListBuffer<JCTree> defs = new ListBuffer<>();
3059        defs.append(resource());
3060        while (token.kind == SEMI) {
3061            // All but last of multiple declarators must subsume a semicolon
3062            storeEnd(defs.last(), token.endPos);
3063            int semiColonPos = token.pos;
3064            nextToken();
3065            if (token.kind == RPAREN) { // Optional trailing semicolon
3066                                       // after last resource
3067                break;
3068            }
3069            defs.append(resource());
3070        }
3071        return defs.toList();
3072    }
3073
3074    /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
3075     *           | Expression
3076     */
3077    protected JCTree resource() {
3078        int startPos = token.pos;
3079        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3080            JCModifiers mods = optFinal(Flags.FINAL);
3081            JCExpression t = parseType();
3082            return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
3083        }
3084        JCExpression t = term(EXPR | TYPE);
3085        if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
3086            JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
3087            return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
3088        } else {
3089            checkVariableInTryWithResources(startPos);
3090            if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
3091                log.error(t.pos(), "try.with.resources.expr.needs.var");
3092            }
3093
3094            return t;
3095        }
3096    }
3097
3098    /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
3099     */
3100    public JCTree.JCCompilationUnit parseCompilationUnit() {
3101        Token firstToken = token;
3102        JCModifiers mods = null;
3103        boolean consumedToplevelDoc = false;
3104        boolean seenImport = false;
3105        boolean seenPackage = false;
3106        ListBuffer<JCTree> defs = new ListBuffer<>();
3107        if (token.kind == MONKEYS_AT)
3108            mods = modifiersOpt();
3109
3110        if (token.kind == PACKAGE) {
3111            int packagePos = token.pos;
3112            List<JCAnnotation> annotations = List.nil();
3113            seenPackage = true;
3114            if (mods != null) {
3115                checkNoMods(mods.flags);
3116                annotations = mods.annotations;
3117                mods = null;
3118            }
3119            nextToken();
3120            JCExpression pid = qualident(false);
3121            accept(SEMI);
3122            JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
3123            attach(pd, firstToken.comment(CommentStyle.JAVADOC));
3124            consumedToplevelDoc = true;
3125            storeEnd(pd, token.pos);
3126            defs.append(pd);
3127        }
3128
3129        boolean checkForImports = true;
3130        boolean firstTypeDecl = true;
3131        while (token.kind != EOF) {
3132            if (token.pos <= endPosTable.errorEndPos) {
3133                // error recovery
3134                skip(checkForImports, false, false, false);
3135                if (token.kind == EOF)
3136                    break;
3137            }
3138            if (checkForImports && mods == null && token.kind == IMPORT) {
3139                seenImport = true;
3140                defs.append(importDeclaration());
3141            } else {
3142                Comment docComment = token.comment(CommentStyle.JAVADOC);
3143                if (firstTypeDecl && !seenImport && !seenPackage) {
3144                    docComment = firstToken.comment(CommentStyle.JAVADOC);
3145                    consumedToplevelDoc = true;
3146                }
3147                if (mods != null || token.kind != SEMI)
3148                    mods = modifiersOpt(mods);
3149                if (firstTypeDecl && token.kind == IDENTIFIER) {
3150                    ModuleKind kind = ModuleKind.STRONG;
3151                    if (token.name() == names.open) {
3152                        kind = ModuleKind.OPEN;
3153                        nextToken();
3154                    }
3155                    if (token.kind == IDENTIFIER && token.name() == names.module) {
3156                        if (mods != null) {
3157                            checkNoMods(mods.flags & ~Flags.DEPRECATED);
3158                        }
3159                        defs.append(moduleDecl(mods, kind, docComment));
3160                        consumedToplevelDoc = true;
3161                        break;
3162                    } else if (kind != ModuleKind.STRONG) {
3163                        reportSyntaxError(token.pos, "expected.module");
3164                    }
3165                }
3166                JCTree def = typeDeclaration(mods, docComment);
3167                if (def instanceof JCExpressionStatement)
3168                    def = ((JCExpressionStatement)def).expr;
3169                defs.append(def);
3170                if (def instanceof JCClassDecl)
3171                    checkForImports = false;
3172                mods = null;
3173                firstTypeDecl = false;
3174            }
3175        }
3176        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
3177        if (!consumedToplevelDoc)
3178            attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
3179        if (defs.isEmpty())
3180            storeEnd(toplevel, S.prevToken().endPos);
3181        if (keepDocComments)
3182            toplevel.docComments = docComments;
3183        if (keepLineMap)
3184            toplevel.lineMap = S.getLineMap();
3185        this.endPosTable.setParser(null); // remove reference to parser
3186        toplevel.endPositions = this.endPosTable;
3187        return toplevel;
3188    }
3189
3190    JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
3191        int pos = token.pos;
3192        if (!allowModules) {
3193            log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
3194            allowModules = true;
3195        }
3196
3197        nextToken();
3198        JCExpression name = qualident(false);
3199        List<JCDirective> directives = null;
3200
3201        accept(LBRACE);
3202        directives = moduleDirectiveList();
3203        accept(RBRACE);
3204        accept(EOF);
3205
3206        JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives));
3207        attach(result, dc);
3208        return result;
3209    }
3210
3211    List<JCDirective> moduleDirectiveList() {
3212        ListBuffer<JCDirective> defs = new ListBuffer<>();
3213        while (token.kind == IDENTIFIER) {
3214            int pos = token.pos;
3215            if (token.name() == names.requires) {
3216                nextToken();
3217                boolean isTransitive = false;
3218                boolean isStaticPhase = false;
3219            loop:
3220                while (true) {
3221                    switch (token.kind) {
3222                        case IDENTIFIER:
3223                            if (token.name() == names.transitive && !isTransitive) {
3224                                Token t1 = S.token(1);
3225                                if (t1.kind == SEMI || t1.kind == DOT) {
3226                                    break loop;
3227                                }
3228                                isTransitive = true;
3229                                break;
3230                            } else {
3231                                break loop;
3232                            }
3233                        case STATIC:
3234                            if (isStaticPhase) {
3235                                error(token.pos, "repeated.modifier");
3236                            }
3237                            isStaticPhase = true;
3238                            break;
3239                        default:
3240                            break loop;
3241                    }
3242                    nextToken();
3243                }
3244                JCExpression moduleName = qualident(false);
3245                accept(SEMI);
3246                defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName)));
3247            } else if (token.name() == names.exports || token.name() == names.opens) {
3248                boolean exports = token.name() == names.exports;
3249                nextToken();
3250                JCExpression pkgName = qualident(false);
3251                List<JCExpression> moduleNames = null;
3252                if (token.kind == IDENTIFIER && token.name() == names.to) {
3253                    nextToken();
3254                    moduleNames = qualidentList(false);
3255                }
3256                accept(SEMI);
3257                JCDirective d;
3258                if (exports) {
3259                    d = F.at(pos).Exports(pkgName, moduleNames);
3260                } else {
3261                    d = F.at(pos).Opens(pkgName, moduleNames);
3262                }
3263                defs.append(toP(d));
3264            } else if (token.name() == names.provides) {
3265                nextToken();
3266                JCExpression serviceName = qualident(false);
3267                if (token.kind == IDENTIFIER && token.name() == names.with) {
3268                    nextToken();
3269                    List<JCExpression> implNames = qualidentList(false);
3270                    accept(SEMI);
3271                    defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
3272                } else {
3273                    error(token.pos, "expected", "'" + names.with + "'");
3274                    skip(false, false, false, false);
3275                }
3276            } else if (token.name() == names.uses) {
3277                nextToken();
3278                JCExpression service = qualident(false);
3279                accept(SEMI);
3280                defs.append(toP(F.at(pos).Uses(service)));
3281            } else {
3282                setErrorEndPos(pos);
3283                reportSyntaxError(pos, "invalid.module.directive");
3284                break;
3285            }
3286        }
3287        return defs.toList();
3288    }
3289
3290    /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
3291     */
3292    protected JCTree importDeclaration() {
3293        int pos = token.pos;
3294        nextToken();
3295        boolean importStatic = false;
3296        if (token.kind == STATIC) {
3297            importStatic = true;
3298            nextToken();
3299        }
3300        JCExpression pid = toP(F.at(token.pos).Ident(ident()));
3301        do {
3302            int pos1 = token.pos;
3303            accept(DOT);
3304            if (token.kind == STAR) {
3305                pid = to(F.at(pos1).Select(pid, names.asterisk));
3306                nextToken();
3307                break;
3308            } else {
3309                pid = toP(F.at(pos1).Select(pid, ident()));
3310            }
3311        } while (token.kind == DOT);
3312        accept(SEMI);
3313        return toP(F.at(pos).Import(pid, importStatic));
3314    }
3315
3316    /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3317     *                  | ";"
3318     */
3319    JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3320        int pos = token.pos;
3321        if (mods == null && token.kind == SEMI) {
3322            nextToken();
3323            return toP(F.at(pos).Skip());
3324        } else {
3325            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3326        }
3327    }
3328
3329    /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3330     *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3331     *  @param mods     Any modifiers starting the class or interface declaration
3332     *  @param dc       The documentation comment for the class, or null.
3333     */
3334    protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3335        if (token.kind == CLASS) {
3336            return classDeclaration(mods, dc);
3337        } else if (token.kind == INTERFACE) {
3338            return interfaceDeclaration(mods, dc);
3339        } else if (token.kind == ENUM) {
3340            return enumDeclaration(mods, dc);
3341        } else {
3342            int pos = token.pos;
3343            List<JCTree> errs;
3344            if (LAX_IDENTIFIER.accepts(token.kind)) {
3345                errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
3346                setErrorEndPos(token.pos);
3347            } else {
3348                errs = List.<JCTree>of(mods);
3349            }
3350            return toP(F.Exec(syntaxError(pos, errs, "expected3",
3351                                          CLASS, INTERFACE, ENUM)));
3352        }
3353    }
3354
3355    /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3356     *                     [IMPLEMENTS TypeList] ClassBody
3357     *  @param mods    The modifiers starting the class declaration
3358     *  @param dc       The documentation comment for the class, or null.
3359     */
3360    protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3361        int pos = token.pos;
3362        accept(CLASS);
3363        Name name = ident();
3364
3365        List<JCTypeParameter> typarams = typeParametersOpt();
3366
3367        JCExpression extending = null;
3368        if (token.kind == EXTENDS) {
3369            nextToken();
3370            extending = parseType();
3371        }
3372        List<JCExpression> implementing = List.nil();
3373        if (token.kind == IMPLEMENTS) {
3374            nextToken();
3375            implementing = typeList();
3376        }
3377        List<JCTree> defs = classOrInterfaceBody(name, false);
3378        JCClassDecl result = toP(F.at(pos).ClassDef(
3379            mods, name, typarams, extending, implementing, defs));
3380        attach(result, dc);
3381        return result;
3382    }
3383
3384    /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3385     *                         [EXTENDS TypeList] InterfaceBody
3386     *  @param mods    The modifiers starting the interface declaration
3387     *  @param dc       The documentation comment for the interface, or null.
3388     */
3389    protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3390        int pos = token.pos;
3391        accept(INTERFACE);
3392        Name name = ident();
3393
3394        List<JCTypeParameter> typarams = typeParametersOpt();
3395
3396        List<JCExpression> extending = List.nil();
3397        if (token.kind == EXTENDS) {
3398            nextToken();
3399            extending = typeList();
3400        }
3401        List<JCTree> defs = classOrInterfaceBody(name, true);
3402        JCClassDecl result = toP(F.at(pos).ClassDef(
3403            mods, name, typarams, null, extending, defs));
3404        attach(result, dc);
3405        return result;
3406    }
3407
3408    /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3409     *  @param mods    The modifiers starting the enum declaration
3410     *  @param dc       The documentation comment for the enum, or null.
3411     */
3412    protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3413        int pos = token.pos;
3414        accept(ENUM);
3415        Name name = ident();
3416
3417        List<JCExpression> implementing = List.nil();
3418        if (token.kind == IMPLEMENTS) {
3419            nextToken();
3420            implementing = typeList();
3421        }
3422
3423        List<JCTree> defs = enumBody(name);
3424        mods.flags |= Flags.ENUM;
3425        JCClassDecl result = toP(F.at(pos).
3426            ClassDef(mods, name, List.<JCTypeParameter>nil(),
3427                     null, implementing, defs));
3428        attach(result, dc);
3429        return result;
3430    }
3431
3432    /** EnumBody = "{" { EnumeratorDeclarationList } [","]
3433     *                  [ ";" {ClassBodyDeclaration} ] "}"
3434     */
3435    List<JCTree> enumBody(Name enumName) {
3436        accept(LBRACE);
3437        ListBuffer<JCTree> defs = new ListBuffer<>();
3438        if (token.kind == COMMA) {
3439            nextToken();
3440        } else if (token.kind != RBRACE && token.kind != SEMI) {
3441            defs.append(enumeratorDeclaration(enumName));
3442            while (token.kind == COMMA) {
3443                nextToken();
3444                if (token.kind == RBRACE || token.kind == SEMI) break;
3445                defs.append(enumeratorDeclaration(enumName));
3446            }
3447            if (token.kind != SEMI && token.kind != RBRACE) {
3448                defs.append(syntaxError(token.pos, "expected3",
3449                                COMMA, RBRACE, SEMI));
3450                nextToken();
3451            }
3452        }
3453        if (token.kind == SEMI) {
3454            nextToken();
3455            while (token.kind != RBRACE && token.kind != EOF) {
3456                defs.appendList(classOrInterfaceBodyDeclaration(enumName,
3457                                                                false));
3458                if (token.pos <= endPosTable.errorEndPos) {
3459                    // error recovery
3460                   skip(false, true, true, false);
3461                }
3462            }
3463        }
3464        accept(RBRACE);
3465        return defs.toList();
3466    }
3467
3468    /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3469     */
3470    JCTree enumeratorDeclaration(Name enumName) {
3471        Comment dc = token.comment(CommentStyle.JAVADOC);
3472        int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3473        if (token.deprecatedFlag()) {
3474            flags |= Flags.DEPRECATED;
3475        }
3476        int pos = token.pos;
3477        List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3478        JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3479        List<JCExpression> typeArgs = typeArgumentsOpt();
3480        int identPos = token.pos;
3481        Name name = ident();
3482        int createPos = token.pos;
3483        List<JCExpression> args = (token.kind == LPAREN)
3484            ? arguments() : List.<JCExpression>nil();
3485        JCClassDecl body = null;
3486        if (token.kind == LBRACE) {
3487            JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3488            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
3489            body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3490        }
3491        if (args.isEmpty() && body == null)
3492            createPos = identPos;
3493        JCIdent ident = F.at(identPos).Ident(enumName);
3494        JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3495        if (createPos != identPos)
3496            storeEnd(create, S.prevToken().endPos);
3497        ident = F.at(identPos).Ident(enumName);
3498        JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3499        attach(result, dc);
3500        return result;
3501    }
3502
3503    /** TypeList = Type {"," Type}
3504     */
3505    List<JCExpression> typeList() {
3506        ListBuffer<JCExpression> ts = new ListBuffer<>();
3507        ts.append(parseType());
3508        while (token.kind == COMMA) {
3509            nextToken();
3510            ts.append(parseType());
3511        }
3512        return ts.toList();
3513    }
3514
3515    /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3516     *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3517     */
3518    List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
3519        accept(LBRACE);
3520        if (token.pos <= endPosTable.errorEndPos) {
3521            // error recovery
3522            skip(false, true, false, false);
3523            if (token.kind == LBRACE)
3524                nextToken();
3525        }
3526        ListBuffer<JCTree> defs = new ListBuffer<>();
3527        while (token.kind != RBRACE && token.kind != EOF) {
3528            defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
3529            if (token.pos <= endPosTable.errorEndPos) {
3530               // error recovery
3531               skip(false, true, true, false);
3532           }
3533        }
3534        accept(RBRACE);
3535        return defs.toList();
3536    }
3537
3538    /** ClassBodyDeclaration =
3539     *      ";"
3540     *    | [STATIC] Block
3541     *    | ModifiersOpt
3542     *      ( Type Ident
3543     *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3544     *      | VOID Ident VoidMethodDeclaratorRest
3545     *      | TypeParameters [Annotations]
3546     *        ( Type Ident MethodDeclaratorRest
3547     *        | VOID Ident VoidMethodDeclaratorRest
3548     *        )
3549     *      | Ident ConstructorDeclaratorRest
3550     *      | TypeParameters Ident ConstructorDeclaratorRest
3551     *      | ClassOrInterfaceOrEnumDeclaration
3552     *      )
3553     *  InterfaceBodyDeclaration =
3554     *      ";"
3555     *    | ModifiersOpt
3556     *      ( Type Ident
3557     *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3558     *      | VOID Ident MethodDeclaratorRest
3559     *      | TypeParameters [Annotations]
3560     *        ( Type Ident MethodDeclaratorRest
3561     *        | VOID Ident VoidMethodDeclaratorRest
3562     *        )
3563     *      | ClassOrInterfaceOrEnumDeclaration
3564     *      )
3565     *
3566     */
3567    protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3568        if (token.kind == SEMI) {
3569            nextToken();
3570            return List.<JCTree>nil();
3571        } else {
3572            Comment dc = token.comment(CommentStyle.JAVADOC);
3573            int pos = token.pos;
3574            JCModifiers mods = modifiersOpt();
3575            if (token.kind == CLASS ||
3576                token.kind == INTERFACE ||
3577                token.kind == ENUM) {
3578                return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
3579            } else if (token.kind == LBRACE &&
3580                       (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3581                       mods.annotations.isEmpty()) {
3582                if (isInterface) {
3583                    error(token.pos, "initializer.not.allowed");
3584                }
3585                return List.<JCTree>of(block(pos, mods.flags));
3586            } else {
3587                pos = token.pos;
3588                List<JCTypeParameter> typarams = typeParametersOpt();
3589                // if there are type parameters but no modifiers, save the start
3590                // position of the method in the modifiers.
3591                if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3592                    mods.pos = pos;
3593                    storeEnd(mods, pos);
3594                }
3595                List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3596
3597                if (annosAfterParams.nonEmpty()) {
3598                    checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
3599                    mods.annotations = mods.annotations.appendList(annosAfterParams);
3600                    if (mods.pos == Position.NOPOS)
3601                        mods.pos = mods.annotations.head.pos;
3602                }
3603
3604                Token tk = token;
3605                pos = token.pos;
3606                JCExpression type;
3607                boolean isVoid = token.kind == VOID;
3608                if (isVoid) {
3609                    type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3610                    nextToken();
3611                } else {
3612                    // method returns types are un-annotated types
3613                    type = unannotatedType();
3614                }
3615                if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3616                    if (isInterface || tk.name() != className)
3617                        error(pos, "invalid.meth.decl.ret.type.req");
3618                    else if (annosAfterParams.nonEmpty())
3619                        illegal(annosAfterParams.head.pos);
3620                    return List.of(methodDeclaratorRest(
3621                        pos, mods, null, names.init, typarams,
3622                        isInterface, true, dc));
3623                } else {
3624                    pos = token.pos;
3625                    Name name = ident();
3626                    if (token.kind == LPAREN) {
3627                        return List.of(methodDeclaratorRest(
3628                            pos, mods, type, name, typarams,
3629                            isInterface, isVoid, dc));
3630                    } else if (!isVoid && typarams.isEmpty()) {
3631                        List<JCTree> defs =
3632                            variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3633                                                    new ListBuffer<JCTree>()).toList();
3634                        accept(SEMI);
3635                        storeEnd(defs.last(), S.prevToken().endPos);
3636                        return defs;
3637                    } else {
3638                        pos = token.pos;
3639                        List<JCTree> err = isVoid
3640                            ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
3641                                List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
3642                            : null;
3643                        return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN));
3644                    }
3645                }
3646            }
3647        }
3648    }
3649
3650    /** MethodDeclaratorRest =
3651     *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
3652     *  VoidMethodDeclaratorRest =
3653     *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
3654     *  ConstructorDeclaratorRest =
3655     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
3656     */
3657    protected JCTree methodDeclaratorRest(int pos,
3658                              JCModifiers mods,
3659                              JCExpression type,
3660                              Name name,
3661                              List<JCTypeParameter> typarams,
3662                              boolean isInterface, boolean isVoid,
3663                              Comment dc) {
3664        if (isInterface) {
3665            if ((mods.flags & Flags.STATIC) != 0) {
3666                checkStaticInterfaceMethods();
3667            }
3668            if ((mods.flags & Flags.PRIVATE) != 0) {
3669                checkPrivateInterfaceMethods();
3670            }
3671        }
3672        JCVariableDecl prevReceiverParam = this.receiverParam;
3673        try {
3674            this.receiverParam = null;
3675            // Parsing formalParameters sets the receiverParam, if present
3676            List<JCVariableDecl> params = formalParameters();
3677            if (!isVoid) type = bracketsOpt(type);
3678            List<JCExpression> thrown = List.nil();
3679            if (token.kind == THROWS) {
3680                nextToken();
3681                thrown = qualidentList(true);
3682            }
3683            JCBlock body = null;
3684            JCExpression defaultValue;
3685            if (token.kind == LBRACE) {
3686                body = block();
3687                defaultValue = null;
3688            } else {
3689                if (token.kind == DEFAULT) {
3690                    accept(DEFAULT);
3691                    defaultValue = annotationValue();
3692                } else {
3693                    defaultValue = null;
3694                }
3695                accept(SEMI);
3696                if (token.pos <= endPosTable.errorEndPos) {
3697                    // error recovery
3698                    skip(false, true, false, false);
3699                    if (token.kind == LBRACE) {
3700                        body = block();
3701                    }
3702                }
3703            }
3704
3705            JCMethodDecl result =
3706                    toP(F.at(pos).MethodDef(mods, name, type, typarams,
3707                                            receiverParam, params, thrown,
3708                                            body, defaultValue));
3709            attach(result, dc);
3710            return result;
3711        } finally {
3712            this.receiverParam = prevReceiverParam;
3713        }
3714    }
3715
3716    /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
3717     */
3718    List<JCExpression> qualidentList(boolean allowAnnos) {
3719        ListBuffer<JCExpression> ts = new ListBuffer<>();
3720
3721        List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3722        JCExpression qi = qualident(allowAnnos);
3723        if (!typeAnnos.isEmpty()) {
3724            JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3725            ts.append(at);
3726        } else {
3727            ts.append(qi);
3728        }
3729        while (token.kind == COMMA) {
3730            nextToken();
3731
3732            typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3733            qi = qualident(allowAnnos);
3734            if (!typeAnnos.isEmpty()) {
3735                JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3736                ts.append(at);
3737            } else {
3738                ts.append(qi);
3739            }
3740        }
3741        return ts.toList();
3742    }
3743
3744    /**
3745     *  {@literal
3746     *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
3747     *  }
3748     */
3749    protected List<JCTypeParameter> typeParametersOpt() {
3750        if (token.kind == LT) {
3751            ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
3752            nextToken();
3753            typarams.append(typeParameter());
3754            while (token.kind == COMMA) {
3755                nextToken();
3756                typarams.append(typeParameter());
3757            }
3758            accept(GT);
3759            return typarams.toList();
3760        } else {
3761            return List.nil();
3762        }
3763    }
3764
3765    /**
3766     *  {@literal
3767     *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
3768     *  TypeParameterBound = EXTENDS Type {"&" Type}
3769     *  TypeVariable = Ident
3770     *  }
3771     */
3772    JCTypeParameter typeParameter() {
3773        int pos = token.pos;
3774        List<JCAnnotation> annos = typeAnnotationsOpt();
3775        Name name = ident();
3776        ListBuffer<JCExpression> bounds = new ListBuffer<>();
3777        if (token.kind == EXTENDS) {
3778            nextToken();
3779            bounds.append(parseType());
3780            while (token.kind == AMP) {
3781                nextToken();
3782                bounds.append(parseType());
3783            }
3784        }
3785        return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
3786    }
3787
3788    /** FormalParameters = "(" [ FormalParameterList ] ")"
3789     *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3790     *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3791     */
3792    List<JCVariableDecl> formalParameters() {
3793        return formalParameters(false);
3794    }
3795    List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
3796        ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3797        JCVariableDecl lastParam;
3798        accept(LPAREN);
3799        if (token.kind != RPAREN) {
3800            this.allowThisIdent = true;
3801            lastParam = formalParameter(lambdaParameters);
3802            if (lastParam.nameexpr != null) {
3803                this.receiverParam = lastParam;
3804            } else {
3805                params.append(lastParam);
3806            }
3807            this.allowThisIdent = false;
3808            while (token.kind == COMMA) {
3809                if ((lastParam.mods.flags & Flags.VARARGS) != 0) {
3810                    error(lastParam, "varargs.must.be.last");
3811                }
3812                nextToken();
3813                params.append(lastParam = formalParameter(lambdaParameters));
3814            }
3815        }
3816        if (token.kind == RPAREN) {
3817            nextToken();
3818        } else {
3819            setErrorEndPos(token.pos);
3820            reportSyntaxError(S.prevToken().endPos, "expected3", COMMA, RPAREN, LBRACKET);
3821        }
3822        return params.toList();
3823    }
3824
3825    List<JCVariableDecl> implicitParameters(boolean hasParens) {
3826        if (hasParens) {
3827            accept(LPAREN);
3828        }
3829        ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3830        if (token.kind != RPAREN && token.kind != ARROW) {
3831            params.append(implicitParameter());
3832            while (token.kind == COMMA) {
3833                nextToken();
3834                params.append(implicitParameter());
3835            }
3836        }
3837        if (hasParens) {
3838            accept(RPAREN);
3839        }
3840        return params.toList();
3841    }
3842
3843    JCModifiers optFinal(long flags) {
3844        JCModifiers mods = modifiersOpt();
3845        checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
3846        mods.flags |= flags;
3847        return mods;
3848    }
3849
3850    /**
3851     * Inserts the annotations (and possibly a new array level)
3852     * to the left-most type in an array or nested type.
3853     *
3854     * When parsing a type like {@code @B Outer.Inner @A []}, the
3855     * {@code @A} annotation should target the array itself, while
3856     * {@code @B} targets the nested type {@code Outer}.
3857     *
3858     * Currently the parser parses the annotation first, then
3859     * the array, and then inserts the annotation to the left-most
3860     * nested type.
3861     *
3862     * When {@code createNewLevel} is true, then a new array
3863     * level is inserted as the most inner type, and have the
3864     * annotations target it.  This is useful in the case of
3865     * varargs, e.g. {@code String @A [] @B ...}, as the parser
3866     * first parses the type {@code String @A []} then inserts
3867     * a new array level with {@code @B} annotation.
3868     */
3869    private JCExpression insertAnnotationsToMostInner(
3870            JCExpression type, List<JCAnnotation> annos,
3871            boolean createNewLevel) {
3872        int origEndPos = getEndPos(type);
3873        JCExpression mostInnerType = type;
3874        JCArrayTypeTree mostInnerArrayType = null;
3875        while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
3876            mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
3877            mostInnerType = mostInnerArrayType.elemtype;
3878        }
3879
3880        if (createNewLevel) {
3881            mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
3882        }
3883
3884        JCExpression mostInnerTypeToReturn = mostInnerType;
3885        if (annos.nonEmpty()) {
3886            JCExpression lastToModify = mostInnerType;
3887
3888            while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
3889                    TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3890                while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
3891                    lastToModify = mostInnerType;
3892                    mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
3893                }
3894                while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3895                    lastToModify = mostInnerType;
3896                    mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
3897                }
3898            }
3899
3900            mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
3901
3902            if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
3903                ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
3904            } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
3905                ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
3906            } else {
3907                // We never saw a SELECT or TYPEAPPLY, return the annotated type.
3908                mostInnerTypeToReturn = mostInnerType;
3909            }
3910        }
3911
3912        if (mostInnerArrayType == null) {
3913            return mostInnerTypeToReturn;
3914        } else {
3915            mostInnerArrayType.elemtype = mostInnerTypeToReturn;
3916            storeEnd(type, origEndPos);
3917            return type;
3918        }
3919    }
3920
3921    /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3922     *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3923     */
3924    protected JCVariableDecl formalParameter() {
3925        return formalParameter(false);
3926    }
3927    protected JCVariableDecl formalParameter(boolean lambdaParameter) {
3928        JCModifiers mods = optFinal(Flags.PARAMETER);
3929        // need to distinguish between vararg annos and array annos
3930        // look at typeAnnotationsPushedBack comment
3931        this.permitTypeAnnotationsPushBack = true;
3932        JCExpression type = parseType();
3933        this.permitTypeAnnotationsPushBack = false;
3934
3935        if (token.kind == ELLIPSIS) {
3936            List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
3937            typeAnnotationsPushedBack = List.nil();
3938            mods.flags |= Flags.VARARGS;
3939            // insert var arg type annotations
3940            type = insertAnnotationsToMostInner(type, varargsAnnos, true);
3941            nextToken();
3942        } else {
3943            // if not a var arg, then typeAnnotationsPushedBack should be null
3944            if (typeAnnotationsPushedBack.nonEmpty()) {
3945                reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3946                        "illegal.start.of.type");
3947            }
3948            typeAnnotationsPushedBack = List.nil();
3949        }
3950        return variableDeclaratorId(mods, type, lambdaParameter);
3951    }
3952
3953    protected JCVariableDecl implicitParameter() {
3954        JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
3955        return variableDeclaratorId(mods, null, true);
3956    }
3957
3958/* ---------- auxiliary methods -------------- */
3959
3960    void error(int pos, String key, Object ... args) {
3961        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3962    }
3963
3964    void error(DiagnosticPosition pos, String key, Object ... args) {
3965        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3966    }
3967
3968    void warning(int pos, String key, Object ... args) {
3969        log.warning(pos, key, args);
3970    }
3971
3972    /** Check that given tree is a legal expression statement.
3973     */
3974    protected JCExpression checkExprStat(JCExpression t) {
3975        if (!TreeInfo.isExpressionStatement(t)) {
3976            JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
3977            error(ret, "not.stmt");
3978            return ret;
3979        } else {
3980            return t;
3981        }
3982    }
3983
3984    /** Return precedence of operator represented by token,
3985     *  -1 if token is not a binary operator. @see TreeInfo.opPrec
3986     */
3987    static int prec(TokenKind token) {
3988        JCTree.Tag oc = optag(token);
3989        return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
3990    }
3991
3992    /**
3993     * Return the lesser of two positions, making allowance for either one
3994     * being unset.
3995     */
3996    static int earlier(int pos1, int pos2) {
3997        if (pos1 == Position.NOPOS)
3998            return pos2;
3999        if (pos2 == Position.NOPOS)
4000            return pos1;
4001        return (pos1 < pos2 ? pos1 : pos2);
4002    }
4003
4004    /** Return operation tag of binary operator represented by token,
4005     *  No_TAG if token is not a binary operator.
4006     */
4007    static JCTree.Tag optag(TokenKind token) {
4008        switch (token) {
4009        case BARBAR:
4010            return OR;
4011        case AMPAMP:
4012            return AND;
4013        case BAR:
4014            return BITOR;
4015        case BAREQ:
4016            return BITOR_ASG;
4017        case CARET:
4018            return BITXOR;
4019        case CARETEQ:
4020            return BITXOR_ASG;
4021        case AMP:
4022            return BITAND;
4023        case AMPEQ:
4024            return BITAND_ASG;
4025        case EQEQ:
4026            return JCTree.Tag.EQ;
4027        case BANGEQ:
4028            return NE;
4029        case LT:
4030            return JCTree.Tag.LT;
4031        case GT:
4032            return JCTree.Tag.GT;
4033        case LTEQ:
4034            return LE;
4035        case GTEQ:
4036            return GE;
4037        case LTLT:
4038            return SL;
4039        case LTLTEQ:
4040            return SL_ASG;
4041        case GTGT:
4042            return SR;
4043        case GTGTEQ:
4044            return SR_ASG;
4045        case GTGTGT:
4046            return USR;
4047        case GTGTGTEQ:
4048            return USR_ASG;
4049        case PLUS:
4050            return JCTree.Tag.PLUS;
4051        case PLUSEQ:
4052            return PLUS_ASG;
4053        case SUB:
4054            return MINUS;
4055        case SUBEQ:
4056            return MINUS_ASG;
4057        case STAR:
4058            return MUL;
4059        case STAREQ:
4060            return MUL_ASG;
4061        case SLASH:
4062            return DIV;
4063        case SLASHEQ:
4064            return DIV_ASG;
4065        case PERCENT:
4066            return MOD;
4067        case PERCENTEQ:
4068            return MOD_ASG;
4069        case INSTANCEOF:
4070            return TYPETEST;
4071        default:
4072            return NO_TAG;
4073        }
4074    }
4075
4076    /** Return operation tag of unary operator represented by token,
4077     *  No_TAG if token is not a binary operator.
4078     */
4079    static JCTree.Tag unoptag(TokenKind token) {
4080        switch (token) {
4081        case PLUS:
4082            return POS;
4083        case SUB:
4084            return NEG;
4085        case BANG:
4086            return NOT;
4087        case TILDE:
4088            return COMPL;
4089        case PLUSPLUS:
4090            return PREINC;
4091        case SUBSUB:
4092            return PREDEC;
4093        default:
4094            return NO_TAG;
4095        }
4096    }
4097
4098    /** Return type tag of basic type represented by token,
4099     *  NONE if token is not a basic type identifier.
4100     */
4101    static TypeTag typetag(TokenKind token) {
4102        switch (token) {
4103        case BYTE:
4104            return TypeTag.BYTE;
4105        case CHAR:
4106            return TypeTag.CHAR;
4107        case SHORT:
4108            return TypeTag.SHORT;
4109        case INT:
4110            return TypeTag.INT;
4111        case LONG:
4112            return TypeTag.LONG;
4113        case FLOAT:
4114            return TypeTag.FLOAT;
4115        case DOUBLE:
4116            return TypeTag.DOUBLE;
4117        case BOOLEAN:
4118            return TypeTag.BOOLEAN;
4119        default:
4120            return TypeTag.NONE;
4121        }
4122    }
4123
4124    void checkDiamond() {
4125        if (!allowDiamond) {
4126            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "diamond.not.supported.in.source", source.name);
4127        }
4128    }
4129    void checkMulticatch() {
4130        if (!allowMulticatch) {
4131            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "multicatch.not.supported.in.source", source.name);
4132        }
4133    }
4134    void checkTryWithResources() {
4135        if (!allowTWR) {
4136            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "try.with.resources.not.supported.in.source", source.name);
4137        }
4138    }
4139    void checkVariableInTryWithResources(int startPos) {
4140        if (!allowEffectivelyFinalVariablesInTWR) {
4141            log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
4142        }
4143    }
4144    void checkLambda() {
4145        if (!allowLambda) {
4146            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "lambda.not.supported.in.source", source.name);
4147        }
4148    }
4149    void checkMethodReferences() {
4150        if (!allowMethodReferences) {
4151            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "method.references.not.supported.in.source", source.name);
4152        }
4153    }
4154    void checkDefaultMethods() {
4155        if (!allowDefaultMethods) {
4156            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "default.methods.not.supported.in.source", source.name);
4157        }
4158    }
4159    void checkIntersectionTypesInCast() {
4160        if (!allowIntersectionTypesInCast) {
4161            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
4162        }
4163    }
4164    void checkStaticInterfaceMethods() {
4165        if (!allowStaticInterfaceMethods) {
4166            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "static.intf.methods.not.supported.in.source", source.name);
4167        }
4168    }
4169    void checkTypeAnnotations() {
4170        if (!allowTypeAnnotations) {
4171            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "type.annotations.not.supported.in.source", source.name);
4172        }
4173    }
4174    void checkPrivateInterfaceMethods() {
4175        if (!allowPrivateInterfaceMethods) {
4176            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
4177        }
4178    }
4179    protected void checkAnnotationsAfterTypeParams(int pos) {
4180        if (!allowAnnotationsAfterTypeParams) {
4181            log.error(DiagnosticFlag.SOURCE_LEVEL, pos, "annotations.after.type.params.not.supported.in.source", source.name);
4182        }
4183    }
4184
4185    /*
4186     * a functional source tree and end position mappings
4187     */
4188    protected static class SimpleEndPosTable extends AbstractEndPosTable {
4189
4190        private final IntHashTable endPosMap;
4191
4192        SimpleEndPosTable(JavacParser parser) {
4193            super(parser);
4194            endPosMap = new IntHashTable();
4195        }
4196
4197        public void storeEnd(JCTree tree, int endpos) {
4198            endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos,
4199                                 endPosMap.lookup(tree));
4200        }
4201
4202        protected <T extends JCTree> T to(T t) {
4203            storeEnd(t, parser.token.endPos);
4204            return t;
4205        }
4206
4207        protected <T extends JCTree> T toP(T t) {
4208            storeEnd(t, parser.S.prevToken().endPos);
4209            return t;
4210        }
4211
4212        public int getEndPos(JCTree tree) {
4213            int value = endPosMap.getFromIndex(endPosMap.lookup(tree));
4214            // As long as Position.NOPOS==-1, this just returns value.
4215            return (value == -1) ? Position.NOPOS : value;
4216        }
4217
4218        public int replaceTree(JCTree oldTree, JCTree newTree) {
4219            int pos = endPosMap.remove(oldTree);
4220            if (pos != -1) {
4221                storeEnd(newTree, pos);
4222                return pos;
4223            }
4224            return Position.NOPOS;
4225        }
4226    }
4227
4228    /*
4229     * a default skeletal implementation without any mapping overhead.
4230     */
4231    protected static class EmptyEndPosTable extends AbstractEndPosTable {
4232
4233        EmptyEndPosTable(JavacParser parser) {
4234            super(parser);
4235        }
4236
4237        public void storeEnd(JCTree tree, int endpos) { /* empty */ }
4238
4239        protected <T extends JCTree> T to(T t) {
4240            return t;
4241        }
4242
4243        protected <T extends JCTree> T toP(T t) {
4244            return t;
4245        }
4246
4247        public int getEndPos(JCTree tree) {
4248            return Position.NOPOS;
4249        }
4250
4251        public int replaceTree(JCTree oldTree, JCTree newTree) {
4252            return Position.NOPOS;
4253        }
4254
4255    }
4256
4257    protected static abstract class AbstractEndPosTable implements EndPosTable {
4258        /**
4259         * The current parser.
4260         */
4261        protected JavacParser parser;
4262
4263        /**
4264         * Store the last error position.
4265         */
4266        public int errorEndPos = Position.NOPOS;
4267
4268        public AbstractEndPosTable(JavacParser parser) {
4269            this.parser = parser;
4270        }
4271
4272        /**
4273         * Store current token's ending position for a tree, the value of which
4274         * will be the greater of last error position and the ending position of
4275         * the current token.
4276         * @param t The tree.
4277         */
4278        protected abstract <T extends JCTree> T to(T t);
4279
4280        /**
4281         * Store current token's ending position for a tree, the value of which
4282         * will be the greater of last error position and the ending position of
4283         * the previous token.
4284         * @param t The tree.
4285         */
4286        protected abstract <T extends JCTree> T toP(T t);
4287
4288        /**
4289         * Set the error position during the parsing phases, the value of which
4290         * will be set only if it is greater than the last stored error position.
4291         * @param errPos The error position
4292         */
4293        public void setErrorEndPos(int errPos) {
4294            if (errPos > errorEndPos) {
4295                errorEndPos = errPos;
4296            }
4297        }
4298
4299        public void setParser(JavacParser parser) {
4300            this.parser = parser;
4301        }
4302    }
4303}
4304