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