JavacParser.java revision 4202:2bd34895dda2
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            JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
2247            na.dimAnnotations = dimAnnotations.toList();
2248            return na;
2249        }
2250    }
2251
2252    /** ClassCreatorRest = Arguments [ClassBody]
2253     */
2254    JCNewClass classCreatorRest(int newpos,
2255                                  JCExpression encl,
2256                                  List<JCExpression> typeArgs,
2257                                  JCExpression t)
2258    {
2259        List<JCExpression> args = arguments();
2260        JCClassDecl body = null;
2261        if (token.kind == LBRACE) {
2262            int pos = token.pos;
2263            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2264            JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2265            body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2266        }
2267        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2268    }
2269
2270    /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2271     */
2272    JCExpression arrayInitializer(int newpos, JCExpression t) {
2273        accept(LBRACE);
2274        ListBuffer<JCExpression> elems = new ListBuffer<>();
2275        if (token.kind == COMMA) {
2276            nextToken();
2277        } else if (token.kind != RBRACE) {
2278            elems.append(variableInitializer());
2279            while (token.kind == COMMA) {
2280                nextToken();
2281                if (token.kind == RBRACE) break;
2282                elems.append(variableInitializer());
2283            }
2284        }
2285        accept(RBRACE);
2286        return toP(F.at(newpos).NewArray(t, List.nil(), elems.toList()));
2287    }
2288
2289    /** VariableInitializer = ArrayInitializer | Expression
2290     */
2291    public JCExpression variableInitializer() {
2292        return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression();
2293    }
2294
2295    /** ParExpression = "(" Expression ")"
2296     */
2297    JCExpression parExpression() {
2298        int pos = token.pos;
2299        accept(LPAREN);
2300        JCExpression t = parseExpression();
2301        accept(RPAREN);
2302        return toP(F.at(pos).Parens(t));
2303    }
2304
2305    /** Block = "{" BlockStatements "}"
2306     */
2307    JCBlock block(int pos, long flags) {
2308        accept(LBRACE);
2309        List<JCStatement> stats = blockStatements();
2310        JCBlock t = F.at(pos).Block(flags, stats);
2311        while (token.kind == CASE || token.kind == DEFAULT) {
2312            syntaxError("orphaned", token.kind);
2313            switchBlockStatementGroups();
2314        }
2315        // the Block node has a field "endpos" for first char of last token, which is
2316        // usually but not necessarily the last char of the last token.
2317        t.endpos = token.pos;
2318        accept(RBRACE);
2319        return toP(t);
2320    }
2321
2322    public JCBlock block() {
2323        return block(token.pos, 0);
2324    }
2325
2326    /** BlockStatements = { BlockStatement }
2327     *  BlockStatement  = LocalVariableDeclarationStatement
2328     *                  | ClassOrInterfaceOrEnumDeclaration
2329     *                  | [Ident ":"] Statement
2330     *  LocalVariableDeclarationStatement
2331     *                  = { FINAL | '@' Annotation } Type VariableDeclarators ";"
2332     */
2333    @SuppressWarnings("fallthrough")
2334    List<JCStatement> blockStatements() {
2335        //todo: skip to anchor on error(?)
2336        int lastErrPos = -1;
2337        ListBuffer<JCStatement> stats = new ListBuffer<>();
2338        while (true) {
2339            List<JCStatement> stat = blockStatement();
2340            if (stat.isEmpty()) {
2341                return stats.toList();
2342            } else {
2343                // error recovery
2344                if (token.pos == lastErrPos)
2345                    return stats.toList();
2346                if (token.pos <= endPosTable.errorEndPos) {
2347                    skip(false, true, true, true);
2348                    lastErrPos = token.pos;
2349                }
2350                stats.addAll(stat);
2351            }
2352        }
2353    }
2354
2355    /*
2356     * Parse a Statement (JLS 14.5). As an enhancement to improve error recovery,
2357     * this method will also recognize variable and class declarations (which are
2358     * not legal for a Statement) by delegating the parsing to BlockStatement (JLS 14.2).
2359     * If any illegal declarations are found, they will be wrapped in an erroneous tree,
2360     * and an error will be produced by this method.
2361     */
2362    JCStatement parseStatementAsBlock() {
2363        int pos = token.pos;
2364        List<JCStatement> stats = blockStatement();
2365        if (stats.isEmpty()) {
2366            JCErroneous e = F.at(pos).Erroneous();
2367            error(e, "illegal.start.of.stmt");
2368            return F.at(pos).Exec(e);
2369        } else {
2370            JCStatement first = stats.head;
2371            String error = null;
2372            switch (first.getTag()) {
2373            case CLASSDEF:
2374                error = "class.not.allowed";
2375                break;
2376            case VARDEF:
2377                error = "variable.not.allowed";
2378                break;
2379            }
2380            if (error != null) {
2381                error(first, error);
2382                List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2383                return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2384            }
2385            return first;
2386        }
2387    }
2388
2389    /**This method parses a statement appearing inside a block.
2390     */
2391    List<JCStatement> blockStatement() {
2392        //todo: skip to anchor on error(?)
2393        int pos = token.pos;
2394        switch (token.kind) {
2395        case RBRACE: case CASE: case DEFAULT: case EOF:
2396            return List.nil();
2397        case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2398        case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2399        case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2400        case ASSERT:
2401            return List.of(parseSimpleStatement());
2402        case MONKEYS_AT:
2403        case FINAL: {
2404            Comment dc = token.comment(CommentStyle.JAVADOC);
2405            JCModifiers mods = modifiersOpt();
2406            if (token.kind == INTERFACE ||
2407                token.kind == CLASS ||
2408                token.kind == ENUM) {
2409                return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2410            } else {
2411                JCExpression t = parseType();
2412                ListBuffer<JCStatement> stats =
2413                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2414                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2415                accept(SEMI);
2416                storeEnd(stats.last(), S.prevToken().endPos);
2417                return stats.toList();
2418            }
2419        }
2420        case ABSTRACT: case STRICTFP: {
2421            Comment dc = token.comment(CommentStyle.JAVADOC);
2422            JCModifiers mods = modifiersOpt();
2423            return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2424        }
2425        case INTERFACE:
2426        case CLASS:
2427            Comment dc = token.comment(CommentStyle.JAVADOC);
2428            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2429        case ENUM:
2430            error(token.pos, "local.enum");
2431            dc = token.comment(CommentStyle.JAVADOC);
2432            return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2433        default:
2434            Token prevToken = token;
2435            JCExpression t = term(EXPR | TYPE);
2436            if (token.kind == COLON && t.hasTag(IDENT)) {
2437                nextToken();
2438                JCStatement stat = parseStatementAsBlock();
2439                return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2440            } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2441                pos = token.pos;
2442                JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2443                F.at(pos);
2444                ListBuffer<JCStatement> stats =
2445                        variableDeclarators(mods, t, new ListBuffer<JCStatement>());
2446                // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
2447                accept(SEMI);
2448                storeEnd(stats.last(), S.prevToken().endPos);
2449                return stats.toList();
2450            } else {
2451                // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2452                t = checkExprStat(t);
2453                accept(SEMI);
2454                JCExpressionStatement expr = toP(F.at(pos).Exec(t));
2455                return List.of(expr);
2456            }
2457        }
2458    }
2459
2460    /** Statement =
2461     *       Block
2462     *     | IF ParExpression Statement [ELSE Statement]
2463     *     | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
2464     *     | FOR "(" FormalParameter : Expression ")" Statement
2465     *     | WHILE ParExpression Statement
2466     *     | DO Statement WHILE ParExpression ";"
2467     *     | TRY Block ( Catches | [Catches] FinallyPart )
2468     *     | TRY "(" ResourceSpecification ";"opt ")" Block [Catches] [FinallyPart]
2469     *     | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
2470     *     | SYNCHRONIZED ParExpression Block
2471     *     | RETURN [Expression] ";"
2472     *     | THROW Expression ";"
2473     *     | BREAK [Ident] ";"
2474     *     | CONTINUE [Ident] ";"
2475     *     | ASSERT Expression [ ":" Expression ] ";"
2476     *     | ";"
2477     */
2478    public JCStatement parseSimpleStatement() {
2479        int pos = token.pos;
2480        switch (token.kind) {
2481        case LBRACE:
2482            return block();
2483        case IF: {
2484            nextToken();
2485            JCExpression cond = parExpression();
2486            JCStatement thenpart = parseStatementAsBlock();
2487            JCStatement elsepart = null;
2488            if (token.kind == ELSE) {
2489                nextToken();
2490                elsepart = parseStatementAsBlock();
2491            }
2492            return F.at(pos).If(cond, thenpart, elsepart);
2493        }
2494        case FOR: {
2495            nextToken();
2496            accept(LPAREN);
2497            List<JCStatement> inits = token.kind == SEMI ? List.nil() : forInit();
2498            if (inits.length() == 1 &&
2499                inits.head.hasTag(VARDEF) &&
2500                ((JCVariableDecl) inits.head).init == null &&
2501                token.kind == COLON) {
2502                JCVariableDecl var = (JCVariableDecl)inits.head;
2503                accept(COLON);
2504                JCExpression expr = parseExpression();
2505                accept(RPAREN);
2506                JCStatement body = parseStatementAsBlock();
2507                return F.at(pos).ForeachLoop(var, expr, body);
2508            } else {
2509                accept(SEMI);
2510                JCExpression cond = token.kind == SEMI ? null : parseExpression();
2511                accept(SEMI);
2512                List<JCExpressionStatement> steps = token.kind == RPAREN ? List.nil() : forUpdate();
2513                accept(RPAREN);
2514                JCStatement body = parseStatementAsBlock();
2515                return F.at(pos).ForLoop(inits, cond, steps, body);
2516            }
2517        }
2518        case WHILE: {
2519            nextToken();
2520            JCExpression cond = parExpression();
2521            JCStatement body = parseStatementAsBlock();
2522            return F.at(pos).WhileLoop(cond, body);
2523        }
2524        case DO: {
2525            nextToken();
2526            JCStatement body = parseStatementAsBlock();
2527            accept(WHILE);
2528            JCExpression cond = parExpression();
2529            accept(SEMI);
2530            JCDoWhileLoop t = toP(F.at(pos).DoLoop(body, cond));
2531            return t;
2532        }
2533        case TRY: {
2534            nextToken();
2535            List<JCTree> resources = List.nil();
2536            if (token.kind == LPAREN) {
2537                checkTryWithResources();
2538                nextToken();
2539                resources = resources();
2540                accept(RPAREN);
2541            }
2542            JCBlock body = block();
2543            ListBuffer<JCCatch> catchers = new ListBuffer<>();
2544            JCBlock finalizer = null;
2545            if (token.kind == CATCH || token.kind == FINALLY) {
2546                while (token.kind == CATCH) catchers.append(catchClause());
2547                if (token.kind == FINALLY) {
2548                    nextToken();
2549                    finalizer = block();
2550                }
2551            } else {
2552                if (resources.isEmpty()) {
2553                    if (allowTWR) {
2554                        error(pos, "try.without.catch.finally.or.resource.decls");
2555                    } else {
2556                        error(pos, "try.without.catch.or.finally");
2557                    }
2558                }
2559            }
2560            return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
2561        }
2562        case SWITCH: {
2563            nextToken();
2564            JCExpression selector = parExpression();
2565            accept(LBRACE);
2566            List<JCCase> cases = switchBlockStatementGroups();
2567            JCSwitch t = to(F.at(pos).Switch(selector, cases));
2568            accept(RBRACE);
2569            return t;
2570        }
2571        case SYNCHRONIZED: {
2572            nextToken();
2573            JCExpression lock = parExpression();
2574            JCBlock body = block();
2575            return F.at(pos).Synchronized(lock, body);
2576        }
2577        case RETURN: {
2578            nextToken();
2579            JCExpression result = token.kind == SEMI ? null : parseExpression();
2580            accept(SEMI);
2581            JCReturn t = toP(F.at(pos).Return(result));
2582            return t;
2583        }
2584        case THROW: {
2585            nextToken();
2586            JCExpression exc = parseExpression();
2587            accept(SEMI);
2588            JCThrow t = toP(F.at(pos).Throw(exc));
2589            return t;
2590        }
2591        case BREAK: {
2592            nextToken();
2593            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2594            accept(SEMI);
2595            JCBreak t = toP(F.at(pos).Break(label));
2596            return t;
2597        }
2598        case CONTINUE: {
2599            nextToken();
2600            Name label = LAX_IDENTIFIER.accepts(token.kind) ? ident() : null;
2601            accept(SEMI);
2602            JCContinue t =  toP(F.at(pos).Continue(label));
2603            return t;
2604        }
2605        case SEMI:
2606            nextToken();
2607            return toP(F.at(pos).Skip());
2608        case ELSE:
2609            int elsePos = token.pos;
2610            nextToken();
2611            return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
2612        case FINALLY:
2613            int finallyPos = token.pos;
2614            nextToken();
2615            return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
2616        case CATCH:
2617            return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
2618        case ASSERT: {
2619            nextToken();
2620            JCExpression assertion = parseExpression();
2621            JCExpression message = null;
2622            if (token.kind == COLON) {
2623                nextToken();
2624                message = parseExpression();
2625            }
2626            accept(SEMI);
2627            JCAssert t = toP(F.at(pos).Assert(assertion, message));
2628            return t;
2629        }
2630        default:
2631            Assert.error();
2632            return null;
2633        }
2634    }
2635
2636    @Override
2637    public JCStatement parseStatement() {
2638        return parseStatementAsBlock();
2639    }
2640
2641    private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
2642        int errPos = S.errPos();
2643        JCTree stm = action.doRecover(this);
2644        S.errPos(errPos);
2645        return toP(F.Exec(syntaxError(startPos, List.of(stm), key)));
2646    }
2647
2648    /** CatchClause     = CATCH "(" FormalParameter ")" Block
2649     * TODO: the "FormalParameter" is not correct, it uses the special "catchTypes" rule below.
2650     */
2651    protected JCCatch catchClause() {
2652        int pos = token.pos;
2653        accept(CATCH);
2654        accept(LPAREN);
2655        JCModifiers mods = optFinal(Flags.PARAMETER);
2656        List<JCExpression> catchTypes = catchTypes();
2657        JCExpression paramType = catchTypes.size() > 1 ?
2658                toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
2659                catchTypes.head;
2660        JCVariableDecl formal = variableDeclaratorId(mods, paramType);
2661        accept(RPAREN);
2662        JCBlock body = block();
2663        return F.at(pos).Catch(formal, body);
2664    }
2665
2666    List<JCExpression> catchTypes() {
2667        ListBuffer<JCExpression> catchTypes = new ListBuffer<>();
2668        catchTypes.add(parseType());
2669        while (token.kind == BAR) {
2670            checkMulticatch();
2671            nextToken();
2672            // Instead of qualident this is now parseType.
2673            // But would that allow too much, e.g. arrays or generics?
2674            catchTypes.add(parseType());
2675        }
2676        return catchTypes.toList();
2677    }
2678
2679    /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2680     *  SwitchBlockStatementGroup = SwitchLabel BlockStatements
2681     *  SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2682     */
2683    List<JCCase> switchBlockStatementGroups() {
2684        ListBuffer<JCCase> cases = new ListBuffer<>();
2685        while (true) {
2686            int pos = token.pos;
2687            switch (token.kind) {
2688            case CASE:
2689            case DEFAULT:
2690                cases.append(switchBlockStatementGroup());
2691                break;
2692            case RBRACE: case EOF:
2693                return cases.toList();
2694            default:
2695                nextToken(); // to ensure progress
2696                syntaxError(pos, "expected3",
2697                    CASE, DEFAULT, RBRACE);
2698            }
2699        }
2700    }
2701
2702    protected JCCase switchBlockStatementGroup() {
2703        int pos = token.pos;
2704        List<JCStatement> stats;
2705        JCCase c;
2706        switch (token.kind) {
2707        case CASE:
2708            nextToken();
2709            JCExpression pat = parseExpression();
2710            accept(COLON);
2711            stats = blockStatements();
2712            c = F.at(pos).Case(pat, stats);
2713            if (stats.isEmpty())
2714                storeEnd(c, S.prevToken().endPos);
2715            return c;
2716        case DEFAULT:
2717            nextToken();
2718            accept(COLON);
2719            stats = blockStatements();
2720            c = F.at(pos).Case(null, stats);
2721            if (stats.isEmpty())
2722                storeEnd(c, S.prevToken().endPos);
2723            return c;
2724        }
2725        throw new AssertionError("should not reach here");
2726    }
2727
2728    /** MoreStatementExpressions = { COMMA StatementExpression }
2729     */
2730    <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2731                                                                    JCExpression first,
2732                                                                    T stats) {
2733        // This Exec is a "StatementExpression"; it subsumes no terminating token
2734        stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2735        while (token.kind == COMMA) {
2736            nextToken();
2737            pos = token.pos;
2738            JCExpression t = parseExpression();
2739            // This Exec is a "StatementExpression"; it subsumes no terminating token
2740            stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2741        }
2742        return stats;
2743    }
2744
2745    /** ForInit = StatementExpression MoreStatementExpressions
2746     *           |  { FINAL | '@' Annotation } Type VariableDeclarators
2747     */
2748    List<JCStatement> forInit() {
2749        ListBuffer<JCStatement> stats = new ListBuffer<>();
2750        int pos = token.pos;
2751        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
2752            return variableDeclarators(optFinal(0), parseType(), stats).toList();
2753        } else {
2754            JCExpression t = term(EXPR | TYPE);
2755            if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2756                return variableDeclarators(modifiersOpt(), t, stats).toList();
2757            } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
2758                error(pos, "bad.initializer", "for-loop");
2759                return List.of((JCStatement)F.at(pos).VarDef(null, null, t, null));
2760            } else {
2761                return moreStatementExpressions(pos, t, stats).toList();
2762            }
2763        }
2764    }
2765
2766    /** ForUpdate = StatementExpression MoreStatementExpressions
2767     */
2768    List<JCExpressionStatement> forUpdate() {
2769        return moreStatementExpressions(token.pos,
2770                                        parseExpression(),
2771                                        new ListBuffer<JCExpressionStatement>()).toList();
2772    }
2773
2774    /** AnnotationsOpt = { '@' Annotation }
2775     *
2776     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2777     */
2778    protected List<JCAnnotation> annotationsOpt(Tag kind) {
2779        if (token.kind != MONKEYS_AT) return List.nil(); // optimization
2780        ListBuffer<JCAnnotation> buf = new ListBuffer<>();
2781        int prevmode = mode;
2782        while (token.kind == MONKEYS_AT) {
2783            int pos = token.pos;
2784            nextToken();
2785            buf.append(annotation(pos, kind));
2786        }
2787        lastmode = mode;
2788        mode = prevmode;
2789        List<JCAnnotation> annotations = buf.toList();
2790
2791        return annotations;
2792    }
2793
2794    List<JCAnnotation> typeAnnotationsOpt() {
2795        List<JCAnnotation> annotations = annotationsOpt(Tag.TYPE_ANNOTATION);
2796        return annotations;
2797    }
2798
2799    /** ModifiersOpt = { Modifier }
2800     *  Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2801     *           | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2802     *           | "@" Annotation
2803     */
2804    protected JCModifiers modifiersOpt() {
2805        return modifiersOpt(null);
2806    }
2807    protected JCModifiers modifiersOpt(JCModifiers partial) {
2808        long flags;
2809        ListBuffer<JCAnnotation> annotations = new ListBuffer<>();
2810        int pos;
2811        if (partial == null) {
2812            flags = 0;
2813            pos = token.pos;
2814        } else {
2815            flags = partial.flags;
2816            annotations.appendList(partial.annotations);
2817            pos = partial.pos;
2818        }
2819        if (token.deprecatedFlag()) {
2820            flags |= Flags.DEPRECATED;
2821        }
2822        int lastPos;
2823    loop:
2824        while (true) {
2825            long flag;
2826            switch (token.kind) {
2827            case PRIVATE     : flag = Flags.PRIVATE; break;
2828            case PROTECTED   : flag = Flags.PROTECTED; break;
2829            case PUBLIC      : flag = Flags.PUBLIC; break;
2830            case STATIC      : flag = Flags.STATIC; break;
2831            case TRANSIENT   : flag = Flags.TRANSIENT; break;
2832            case FINAL       : flag = Flags.FINAL; break;
2833            case ABSTRACT    : flag = Flags.ABSTRACT; break;
2834            case NATIVE      : flag = Flags.NATIVE; break;
2835            case VOLATILE    : flag = Flags.VOLATILE; break;
2836            case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2837            case STRICTFP    : flag = Flags.STRICTFP; break;
2838            case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
2839            case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
2840            case ERROR       : flag = 0; nextToken(); break;
2841            default: break loop;
2842            }
2843            if ((flags & flag) != 0) error(token.pos, "repeated.modifier");
2844            lastPos = token.pos;
2845            nextToken();
2846            if (flag == Flags.ANNOTATION) {
2847                if (token.kind != INTERFACE) {
2848                    JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
2849                    // if first modifier is an annotation, set pos to annotation's.
2850                    if (flags == 0 && annotations.isEmpty())
2851                        pos = ann.pos;
2852                    annotations.append(ann);
2853                    flag = 0;
2854                }
2855            }
2856            flags |= flag;
2857        }
2858        switch (token.kind) {
2859        case ENUM: flags |= Flags.ENUM; break;
2860        case INTERFACE: flags |= Flags.INTERFACE; break;
2861        default: break;
2862        }
2863
2864        /* A modifiers tree with no modifier tokens or annotations
2865         * has no text position. */
2866        if ((flags & (Flags.ModifierFlags | Flags.ANNOTATION)) == 0 && annotations.isEmpty())
2867            pos = Position.NOPOS;
2868
2869        JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2870        if (pos != Position.NOPOS)
2871            storeEnd(mods, S.prevToken().endPos);
2872        return mods;
2873    }
2874
2875    /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2876     *
2877     * @param pos position of "@" token
2878     * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
2879     */
2880    JCAnnotation annotation(int pos, Tag kind) {
2881        // accept(AT); // AT consumed by caller
2882        if (kind == Tag.TYPE_ANNOTATION) {
2883            checkTypeAnnotations();
2884        }
2885        JCTree ident = qualident(false);
2886        List<JCExpression> fieldValues = annotationFieldValuesOpt();
2887        JCAnnotation ann;
2888        if (kind == Tag.ANNOTATION) {
2889            ann = F.at(pos).Annotation(ident, fieldValues);
2890        } else if (kind == Tag.TYPE_ANNOTATION) {
2891            ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2892        } else {
2893            throw new AssertionError("Unhandled annotation kind: " + kind);
2894        }
2895
2896        storeEnd(ann, S.prevToken().endPos);
2897        return ann;
2898    }
2899
2900    List<JCExpression> annotationFieldValuesOpt() {
2901        return (token.kind == LPAREN) ? annotationFieldValues() : List.nil();
2902    }
2903
2904    /** AnnotationFieldValues   = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2905    List<JCExpression> annotationFieldValues() {
2906        accept(LPAREN);
2907        ListBuffer<JCExpression> buf = new ListBuffer<>();
2908        if (token.kind != RPAREN) {
2909            buf.append(annotationFieldValue());
2910            while (token.kind == COMMA) {
2911                nextToken();
2912                buf.append(annotationFieldValue());
2913            }
2914        }
2915        accept(RPAREN);
2916        return buf.toList();
2917    }
2918
2919    /** AnnotationFieldValue    = AnnotationValue
2920     *                          | Identifier "=" AnnotationValue
2921     */
2922    JCExpression annotationFieldValue() {
2923        if (LAX_IDENTIFIER.accepts(token.kind)) {
2924            mode = EXPR;
2925            JCExpression t1 = term1();
2926            if (t1.hasTag(IDENT) && token.kind == EQ) {
2927                int pos = token.pos;
2928                accept(EQ);
2929                JCExpression v = annotationValue();
2930                return toP(F.at(pos).Assign(t1, v));
2931            } else {
2932                return t1;
2933            }
2934        }
2935        return annotationValue();
2936    }
2937
2938    /* AnnotationValue          = ConditionalExpression
2939     *                          | Annotation
2940     *                          | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2941     */
2942    JCExpression annotationValue() {
2943        int pos;
2944        switch (token.kind) {
2945        case MONKEYS_AT:
2946            pos = token.pos;
2947            nextToken();
2948            return annotation(pos, Tag.ANNOTATION);
2949        case LBRACE:
2950            pos = token.pos;
2951            accept(LBRACE);
2952            ListBuffer<JCExpression> buf = new ListBuffer<>();
2953            if (token.kind == COMMA) {
2954                nextToken();
2955            } else if (token.kind != RBRACE) {
2956                buf.append(annotationValue());
2957                while (token.kind == COMMA) {
2958                    nextToken();
2959                    if (token.kind == RBRACE) break;
2960                    buf.append(annotationValue());
2961                }
2962            }
2963            accept(RBRACE);
2964            return toP(F.at(pos).NewArray(null, List.nil(), buf.toList()));
2965        default:
2966            mode = EXPR;
2967            return term1();
2968        }
2969    }
2970
2971    /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2972     */
2973    public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2974                                                                         JCExpression type,
2975                                                                         T vdefs)
2976    {
2977        return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs);
2978    }
2979
2980    /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2981     *  ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2982     *
2983     *  @param reqInit  Is an initializer always required?
2984     *  @param dc       The documentation comment for the variable declarations, or null.
2985     */
2986    protected <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2987                                                                     JCModifiers mods,
2988                                                                     JCExpression type,
2989                                                                     Name name,
2990                                                                     boolean reqInit,
2991                                                                     Comment dc,
2992                                                                     T vdefs)
2993    {
2994        vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2995        while (token.kind == COMMA) {
2996            // All but last of multiple declarators subsume a comma
2997            storeEnd((JCTree)vdefs.last(), token.endPos);
2998            nextToken();
2999            vdefs.append(variableDeclarator(mods, type, reqInit, dc));
3000        }
3001        return vdefs;
3002    }
3003
3004    /** VariableDeclarator = Ident VariableDeclaratorRest
3005     *  ConstantDeclarator = Ident ConstantDeclaratorRest
3006     */
3007    JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, Comment dc) {
3008        return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc);
3009    }
3010
3011    /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
3012     *  ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
3013     *
3014     *  @param reqInit  Is an initializer always required?
3015     *  @param dc       The documentation comment for the variable declarations, or null.
3016     */
3017    JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
3018                                  boolean reqInit, Comment dc) {
3019        type = bracketsOpt(type);
3020        JCExpression init = null;
3021        if (token.kind == EQ) {
3022            nextToken();
3023            init = variableInitializer();
3024        }
3025        else if (reqInit) syntaxError(token.pos, "expected", EQ);
3026        JCVariableDecl result =
3027            toP(F.at(pos).VarDef(mods, name, type, init));
3028        attach(result, dc);
3029        return result;
3030    }
3031
3032    /** VariableDeclaratorId = Ident BracketsOpt
3033     */
3034    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3035        return variableDeclaratorId(mods, type, false);
3036    }
3037    //where
3038    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3039        int pos = token.pos;
3040        Name name;
3041        if (lambdaParameter && token.kind == UNDERSCORE) {
3042            log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3043            name = token.name();
3044            nextToken();
3045        } else {
3046            if (allowThisIdent && !lambdaParameter) {
3047                JCExpression pn = qualident(false);
3048                if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
3049                    name = ((JCIdent)pn).name;
3050                } else {
3051                    if ((mods.flags & Flags.VARARGS) != 0) {
3052                        log.error(token.pos, Errors.VarargsAndReceiver);
3053                    }
3054                    if (token.kind == LBRACKET) {
3055                        log.error(token.pos, Errors.ArrayAndReceiver);
3056                    }
3057                    return toP(F.at(pos).ReceiverVarDef(mods, pn, type));
3058                }
3059            } else {
3060                name = ident();
3061            }
3062        }
3063        if ((mods.flags & Flags.VARARGS) != 0 &&
3064                token.kind == LBRACKET) {
3065            log.error(token.pos, Errors.VarargsAndOldArraySyntax);
3066        }
3067        type = bracketsOpt(type);
3068        return toP(F.at(pos).VarDef(mods, name, type, null));
3069    }
3070
3071    /** Resources = Resource { ";" Resources }
3072     */
3073    List<JCTree> resources() {
3074        ListBuffer<JCTree> defs = new ListBuffer<>();
3075        defs.append(resource());
3076        while (token.kind == SEMI) {
3077            // All but last of multiple declarators must subsume a semicolon
3078            storeEnd(defs.last(), token.endPos);
3079            int semiColonPos = token.pos;
3080            nextToken();
3081            if (token.kind == RPAREN) { // Optional trailing semicolon
3082                                       // after last resource
3083                break;
3084            }
3085            defs.append(resource());
3086        }
3087        return defs.toList();
3088    }
3089
3090    /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
3091     *           | Expression
3092     */
3093    protected JCTree resource() {
3094        int startPos = token.pos;
3095        if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3096            JCModifiers mods = optFinal(Flags.FINAL);
3097            JCExpression t = parseType();
3098            return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
3099        }
3100        JCExpression t = term(EXPR | TYPE);
3101        if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
3102            JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
3103            return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
3104        } else {
3105            checkVariableInTryWithResources(startPos);
3106            if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
3107                log.error(t.pos(), Errors.TryWithResourcesExprNeedsVar);
3108            }
3109
3110            return t;
3111        }
3112    }
3113
3114    /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
3115     */
3116    public JCTree.JCCompilationUnit parseCompilationUnit() {
3117        Token firstToken = token;
3118        JCModifiers mods = null;
3119        boolean consumedToplevelDoc = false;
3120        boolean seenImport = false;
3121        boolean seenPackage = false;
3122        ListBuffer<JCTree> defs = new ListBuffer<>();
3123        if (token.kind == MONKEYS_AT)
3124            mods = modifiersOpt();
3125
3126        if (token.kind == PACKAGE) {
3127            int packagePos = token.pos;
3128            List<JCAnnotation> annotations = List.nil();
3129            seenPackage = true;
3130            if (mods != null) {
3131                checkNoMods(mods.flags);
3132                annotations = mods.annotations;
3133                mods = null;
3134            }
3135            nextToken();
3136            JCExpression pid = qualident(false);
3137            accept(SEMI);
3138            JCPackageDecl pd = F.at(packagePos).PackageDecl(annotations, pid);
3139            attach(pd, firstToken.comment(CommentStyle.JAVADOC));
3140            consumedToplevelDoc = true;
3141            storeEnd(pd, token.pos);
3142            defs.append(pd);
3143        }
3144
3145        boolean checkForImports = true;
3146        boolean firstTypeDecl = true;
3147        while (token.kind != EOF) {
3148            if (token.pos <= endPosTable.errorEndPos) {
3149                // error recovery
3150                skip(checkForImports, false, false, false);
3151                if (token.kind == EOF)
3152                    break;
3153            }
3154            if (checkForImports && mods == null && token.kind == IMPORT) {
3155                seenImport = true;
3156                defs.append(importDeclaration());
3157            } else {
3158                Comment docComment = token.comment(CommentStyle.JAVADOC);
3159                if (firstTypeDecl && !seenImport && !seenPackage) {
3160                    docComment = firstToken.comment(CommentStyle.JAVADOC);
3161                    consumedToplevelDoc = true;
3162                }
3163                if (mods != null || token.kind != SEMI)
3164                    mods = modifiersOpt(mods);
3165                if (firstTypeDecl && token.kind == IDENTIFIER) {
3166                    ModuleKind kind = ModuleKind.STRONG;
3167                    if (token.name() == names.open) {
3168                        kind = ModuleKind.OPEN;
3169                        nextToken();
3170                    }
3171                    if (token.kind == IDENTIFIER && token.name() == names.module) {
3172                        if (mods != null) {
3173                            checkNoMods(mods.flags & ~Flags.DEPRECATED);
3174                        }
3175                        defs.append(moduleDecl(mods, kind, docComment));
3176                        consumedToplevelDoc = true;
3177                        break;
3178                    } else if (kind != ModuleKind.STRONG) {
3179                        reportSyntaxError(token.pos, "expected.module");
3180                    }
3181                }
3182                JCTree def = typeDeclaration(mods, docComment);
3183                if (def instanceof JCExpressionStatement)
3184                    def = ((JCExpressionStatement)def).expr;
3185                defs.append(def);
3186                if (def instanceof JCClassDecl)
3187                    checkForImports = false;
3188                mods = null;
3189                firstTypeDecl = false;
3190            }
3191        }
3192        JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(defs.toList());
3193        if (!consumedToplevelDoc)
3194            attach(toplevel, firstToken.comment(CommentStyle.JAVADOC));
3195        if (defs.isEmpty())
3196            storeEnd(toplevel, S.prevToken().endPos);
3197        if (keepDocComments)
3198            toplevel.docComments = docComments;
3199        if (keepLineMap)
3200            toplevel.lineMap = S.getLineMap();
3201        this.endPosTable.setParser(null); // remove reference to parser
3202        toplevel.endPositions = this.endPosTable;
3203        return toplevel;
3204    }
3205
3206    JCModuleDecl moduleDecl(JCModifiers mods, ModuleKind kind, Comment dc) {
3207        int pos = token.pos;
3208        if (!allowModules) {
3209            log.error(pos, Errors.ModulesNotSupportedInSource(source.name));
3210            allowModules = true;
3211        }
3212
3213        nextToken();
3214        JCExpression name = qualident(false);
3215        List<JCDirective> directives = null;
3216
3217        accept(LBRACE);
3218        directives = moduleDirectiveList();
3219        accept(RBRACE);
3220        accept(EOF);
3221
3222        JCModuleDecl result = toP(F.at(pos).ModuleDef(mods, kind, name, directives));
3223        attach(result, dc);
3224        return result;
3225    }
3226
3227    List<JCDirective> moduleDirectiveList() {
3228        ListBuffer<JCDirective> defs = new ListBuffer<>();
3229        while (token.kind == IDENTIFIER) {
3230            int pos = token.pos;
3231            if (token.name() == names.requires) {
3232                nextToken();
3233                boolean isTransitive = false;
3234                boolean isStaticPhase = false;
3235            loop:
3236                while (true) {
3237                    switch (token.kind) {
3238                        case IDENTIFIER:
3239                            if (token.name() == names.transitive && !isTransitive) {
3240                                Token t1 = S.token(1);
3241                                if (t1.kind == SEMI || t1.kind == DOT) {
3242                                    break loop;
3243                                }
3244                                isTransitive = true;
3245                                break;
3246                            } else {
3247                                break loop;
3248                            }
3249                        case STATIC:
3250                            if (isStaticPhase) {
3251                                error(token.pos, "repeated.modifier");
3252                            }
3253                            isStaticPhase = true;
3254                            break;
3255                        default:
3256                            break loop;
3257                    }
3258                    nextToken();
3259                }
3260                JCExpression moduleName = qualident(false);
3261                accept(SEMI);
3262                defs.append(toP(F.at(pos).Requires(isTransitive, isStaticPhase, moduleName)));
3263            } else if (token.name() == names.exports || token.name() == names.opens) {
3264                boolean exports = token.name() == names.exports;
3265                nextToken();
3266                JCExpression pkgName = qualident(false);
3267                List<JCExpression> moduleNames = null;
3268                if (token.kind == IDENTIFIER && token.name() == names.to) {
3269                    nextToken();
3270                    moduleNames = qualidentList(false);
3271                }
3272                accept(SEMI);
3273                JCDirective d;
3274                if (exports) {
3275                    d = F.at(pos).Exports(pkgName, moduleNames);
3276                } else {
3277                    d = F.at(pos).Opens(pkgName, moduleNames);
3278                }
3279                defs.append(toP(d));
3280            } else if (token.name() == names.provides) {
3281                nextToken();
3282                JCExpression serviceName = qualident(false);
3283                if (token.kind == IDENTIFIER && token.name() == names.with) {
3284                    nextToken();
3285                    List<JCExpression> implNames = qualidentList(false);
3286                    accept(SEMI);
3287                    defs.append(toP(F.at(pos).Provides(serviceName, implNames)));
3288                } else {
3289                    error(token.pos, "expected", "'" + names.with + "'");
3290                    skip(false, false, false, false);
3291                }
3292            } else if (token.name() == names.uses) {
3293                nextToken();
3294                JCExpression service = qualident(false);
3295                accept(SEMI);
3296                defs.append(toP(F.at(pos).Uses(service)));
3297            } else {
3298                setErrorEndPos(pos);
3299                reportSyntaxError(pos, "invalid.module.directive");
3300                break;
3301            }
3302        }
3303        return defs.toList();
3304    }
3305
3306    /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
3307     */
3308    protected JCTree importDeclaration() {
3309        int pos = token.pos;
3310        nextToken();
3311        boolean importStatic = false;
3312        if (token.kind == STATIC) {
3313            importStatic = true;
3314            nextToken();
3315        }
3316        JCExpression pid = toP(F.at(token.pos).Ident(ident()));
3317        do {
3318            int pos1 = token.pos;
3319            accept(DOT);
3320            if (token.kind == STAR) {
3321                pid = to(F.at(pos1).Select(pid, names.asterisk));
3322                nextToken();
3323                break;
3324            } else {
3325                pid = toP(F.at(pos1).Select(pid, ident()));
3326            }
3327        } while (token.kind == DOT);
3328        accept(SEMI);
3329        return toP(F.at(pos).Import(pid, importStatic));
3330    }
3331
3332    /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3333     *                  | ";"
3334     */
3335    JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3336        int pos = token.pos;
3337        if (mods == null && token.kind == SEMI) {
3338            nextToken();
3339            return toP(F.at(pos).Skip());
3340        } else {
3341            return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3342        }
3343    }
3344
3345    /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3346     *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3347     *  @param mods     Any modifiers starting the class or interface declaration
3348     *  @param dc       The documentation comment for the class, or null.
3349     */
3350    protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3351        if (token.kind == CLASS) {
3352            return classDeclaration(mods, dc);
3353        } else if (token.kind == INTERFACE) {
3354            return interfaceDeclaration(mods, dc);
3355        } else if (token.kind == ENUM) {
3356            return enumDeclaration(mods, dc);
3357        } else {
3358            int pos = token.pos;
3359            List<JCTree> errs;
3360            if (LAX_IDENTIFIER.accepts(token.kind)) {
3361                errs = List.of(mods, toP(F.at(pos).Ident(ident())));
3362                setErrorEndPos(token.pos);
3363            } else {
3364                errs = List.of(mods);
3365            }
3366            final JCErroneous erroneousTree;
3367            if (parseModuleInfo) {
3368                erroneousTree = syntaxError(pos, errs, "expected.module.or.open");
3369            } else {
3370                erroneousTree = syntaxError(pos, errs, "expected3", CLASS, INTERFACE, ENUM);
3371            }
3372            return toP(F.Exec(erroneousTree));
3373        }
3374    }
3375
3376    /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3377     *                     [IMPLEMENTS TypeList] ClassBody
3378     *  @param mods    The modifiers starting the class declaration
3379     *  @param dc       The documentation comment for the class, or null.
3380     */
3381    protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3382        int pos = token.pos;
3383        accept(CLASS);
3384        Name name = ident();
3385
3386        List<JCTypeParameter> typarams = typeParametersOpt();
3387
3388        JCExpression extending = null;
3389        if (token.kind == EXTENDS) {
3390            nextToken();
3391            extending = parseType();
3392        }
3393        List<JCExpression> implementing = List.nil();
3394        if (token.kind == IMPLEMENTS) {
3395            nextToken();
3396            implementing = typeList();
3397        }
3398        List<JCTree> defs = classOrInterfaceBody(name, false);
3399        JCClassDecl result = toP(F.at(pos).ClassDef(
3400            mods, name, typarams, extending, implementing, defs));
3401        attach(result, dc);
3402        return result;
3403    }
3404
3405    /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3406     *                         [EXTENDS TypeList] InterfaceBody
3407     *  @param mods    The modifiers starting the interface declaration
3408     *  @param dc       The documentation comment for the interface, or null.
3409     */
3410    protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3411        int pos = token.pos;
3412        accept(INTERFACE);
3413        Name name = ident();
3414
3415        List<JCTypeParameter> typarams = typeParametersOpt();
3416
3417        List<JCExpression> extending = List.nil();
3418        if (token.kind == EXTENDS) {
3419            nextToken();
3420            extending = typeList();
3421        }
3422        List<JCTree> defs = classOrInterfaceBody(name, true);
3423        JCClassDecl result = toP(F.at(pos).ClassDef(
3424            mods, name, typarams, null, extending, defs));
3425        attach(result, dc);
3426        return result;
3427    }
3428
3429    /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3430     *  @param mods    The modifiers starting the enum declaration
3431     *  @param dc       The documentation comment for the enum, or null.
3432     */
3433    protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3434        int pos = token.pos;
3435        accept(ENUM);
3436        Name name = ident();
3437
3438        List<JCExpression> implementing = List.nil();
3439        if (token.kind == IMPLEMENTS) {
3440            nextToken();
3441            implementing = typeList();
3442        }
3443
3444        List<JCTree> defs = enumBody(name);
3445        mods.flags |= Flags.ENUM;
3446        JCClassDecl result = toP(F.at(pos).
3447            ClassDef(mods, name, List.nil(),
3448                     null, implementing, defs));
3449        attach(result, dc);
3450        return result;
3451    }
3452
3453    /** EnumBody = "{" { EnumeratorDeclarationList } [","]
3454     *                  [ ";" {ClassBodyDeclaration} ] "}"
3455     */
3456    List<JCTree> enumBody(Name enumName) {
3457        accept(LBRACE);
3458        ListBuffer<JCTree> defs = new ListBuffer<>();
3459        if (token.kind == COMMA) {
3460            nextToken();
3461        } else if (token.kind != RBRACE && token.kind != SEMI) {
3462            defs.append(enumeratorDeclaration(enumName));
3463            while (token.kind == COMMA) {
3464                nextToken();
3465                if (token.kind == RBRACE || token.kind == SEMI) break;
3466                defs.append(enumeratorDeclaration(enumName));
3467            }
3468            if (token.kind != SEMI && token.kind != RBRACE) {
3469                defs.append(syntaxError(token.pos, "expected3",
3470                                COMMA, RBRACE, SEMI));
3471                nextToken();
3472            }
3473        }
3474        if (token.kind == SEMI) {
3475            nextToken();
3476            while (token.kind != RBRACE && token.kind != EOF) {
3477                defs.appendList(classOrInterfaceBodyDeclaration(enumName,
3478                                                                false));
3479                if (token.pos <= endPosTable.errorEndPos) {
3480                    // error recovery
3481                   skip(false, true, true, false);
3482                }
3483            }
3484        }
3485        accept(RBRACE);
3486        return defs.toList();
3487    }
3488
3489    /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3490     */
3491    JCTree enumeratorDeclaration(Name enumName) {
3492        Comment dc = token.comment(CommentStyle.JAVADOC);
3493        int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3494        if (token.deprecatedFlag()) {
3495            flags |= Flags.DEPRECATED;
3496        }
3497        int pos = token.pos;
3498        List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3499        JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3500        List<JCExpression> typeArgs = typeArgumentsOpt();
3501        int identPos = token.pos;
3502        Name name = ident();
3503        int createPos = token.pos;
3504        List<JCExpression> args = (token.kind == LPAREN)
3505            ? arguments() : List.nil();
3506        JCClassDecl body = null;
3507        if (token.kind == LBRACE) {
3508            JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3509            List<JCTree> defs = classOrInterfaceBody(names.empty, false);
3510            body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3511        }
3512        if (args.isEmpty() && body == null)
3513            createPos = identPos;
3514        JCIdent ident = F.at(identPos).Ident(enumName);
3515        JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3516        if (createPos != identPos)
3517            storeEnd(create, S.prevToken().endPos);
3518        ident = F.at(identPos).Ident(enumName);
3519        JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3520        attach(result, dc);
3521        return result;
3522    }
3523
3524    /** TypeList = Type {"," Type}
3525     */
3526    List<JCExpression> typeList() {
3527        ListBuffer<JCExpression> ts = new ListBuffer<>();
3528        ts.append(parseType());
3529        while (token.kind == COMMA) {
3530            nextToken();
3531            ts.append(parseType());
3532        }
3533        return ts.toList();
3534    }
3535
3536    /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3537     *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3538     */
3539    List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
3540        accept(LBRACE);
3541        if (token.pos <= endPosTable.errorEndPos) {
3542            // error recovery
3543            skip(false, true, false, false);
3544            if (token.kind == LBRACE)
3545                nextToken();
3546        }
3547        ListBuffer<JCTree> defs = new ListBuffer<>();
3548        while (token.kind != RBRACE && token.kind != EOF) {
3549            defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
3550            if (token.pos <= endPosTable.errorEndPos) {
3551               // error recovery
3552               skip(false, true, true, false);
3553           }
3554        }
3555        accept(RBRACE);
3556        return defs.toList();
3557    }
3558
3559    /** ClassBodyDeclaration =
3560     *      ";"
3561     *    | [STATIC] Block
3562     *    | ModifiersOpt
3563     *      ( Type Ident
3564     *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3565     *      | VOID Ident VoidMethodDeclaratorRest
3566     *      | TypeParameters [Annotations]
3567     *        ( Type Ident MethodDeclaratorRest
3568     *        | VOID Ident VoidMethodDeclaratorRest
3569     *        )
3570     *      | Ident ConstructorDeclaratorRest
3571     *      | TypeParameters Ident ConstructorDeclaratorRest
3572     *      | ClassOrInterfaceOrEnumDeclaration
3573     *      )
3574     *  InterfaceBodyDeclaration =
3575     *      ";"
3576     *    | ModifiersOpt
3577     *      ( Type Ident
3578     *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3579     *      | VOID Ident MethodDeclaratorRest
3580     *      | TypeParameters [Annotations]
3581     *        ( Type Ident MethodDeclaratorRest
3582     *        | VOID Ident VoidMethodDeclaratorRest
3583     *        )
3584     *      | ClassOrInterfaceOrEnumDeclaration
3585     *      )
3586     *
3587     */
3588    protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3589        if (token.kind == SEMI) {
3590            nextToken();
3591            return List.nil();
3592        } else {
3593            Comment dc = token.comment(CommentStyle.JAVADOC);
3594            int pos = token.pos;
3595            JCModifiers mods = modifiersOpt();
3596            if (token.kind == CLASS ||
3597                token.kind == INTERFACE ||
3598                token.kind == ENUM) {
3599                return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
3600            } else if (token.kind == LBRACE &&
3601                       (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3602                       mods.annotations.isEmpty()) {
3603                if (isInterface) {
3604                    error(token.pos, "initializer.not.allowed");
3605                }
3606                return List.of(block(pos, mods.flags));
3607            } else {
3608                pos = token.pos;
3609                List<JCTypeParameter> typarams = typeParametersOpt();
3610                // if there are type parameters but no modifiers, save the start
3611                // position of the method in the modifiers.
3612                if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3613                    mods.pos = pos;
3614                    storeEnd(mods, pos);
3615                }
3616                List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3617
3618                if (annosAfterParams.nonEmpty()) {
3619                    checkAnnotationsAfterTypeParams(annosAfterParams.head.pos);
3620                    mods.annotations = mods.annotations.appendList(annosAfterParams);
3621                    if (mods.pos == Position.NOPOS)
3622                        mods.pos = mods.annotations.head.pos;
3623                }
3624
3625                Token tk = token;
3626                pos = token.pos;
3627                JCExpression type;
3628                boolean isVoid = token.kind == VOID;
3629                if (isVoid) {
3630                    type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3631                    nextToken();
3632                } else {
3633                    // method returns types are un-annotated types
3634                    type = unannotatedType();
3635                }
3636                if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3637                    if (isInterface || tk.name() != className)
3638                        error(pos, "invalid.meth.decl.ret.type.req");
3639                    else if (annosAfterParams.nonEmpty())
3640                        illegal(annosAfterParams.head.pos);
3641                    return List.of(methodDeclaratorRest(
3642                        pos, mods, null, names.init, typarams,
3643                        isInterface, true, dc));
3644                } else {
3645                    pos = token.pos;
3646                    Name name = ident();
3647                    if (token.kind == LPAREN) {
3648                        return List.of(methodDeclaratorRest(
3649                            pos, mods, type, name, typarams,
3650                            isInterface, isVoid, dc));
3651                    } else if (!isVoid && typarams.isEmpty()) {
3652                        List<JCTree> defs =
3653                            variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3654                                                    new ListBuffer<JCTree>()).toList();
3655                        accept(SEMI);
3656                        storeEnd(defs.last(), S.prevToken().endPos);
3657                        return defs;
3658                    } else {
3659                        pos = token.pos;
3660                        List<JCTree> err = isVoid
3661                            ? List.of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
3662                                List.nil(), List.nil(), null, null)))
3663                            : null;
3664                        return List.of(syntaxError(token.pos, err, "expected", LPAREN));
3665                    }
3666                }
3667            }
3668        }
3669    }
3670
3671    /** MethodDeclaratorRest =
3672     *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
3673     *  VoidMethodDeclaratorRest =
3674     *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
3675     *  ConstructorDeclaratorRest =
3676     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
3677     */
3678    protected JCTree methodDeclaratorRest(int pos,
3679                              JCModifiers mods,
3680                              JCExpression type,
3681                              Name name,
3682                              List<JCTypeParameter> typarams,
3683                              boolean isInterface, boolean isVoid,
3684                              Comment dc) {
3685        if (isInterface) {
3686            if ((mods.flags & Flags.STATIC) != 0) {
3687                checkStaticInterfaceMethods();
3688            }
3689            if ((mods.flags & Flags.PRIVATE) != 0) {
3690                checkPrivateInterfaceMethods();
3691            }
3692        }
3693        JCVariableDecl prevReceiverParam = this.receiverParam;
3694        try {
3695            this.receiverParam = null;
3696            // Parsing formalParameters sets the receiverParam, if present
3697            List<JCVariableDecl> params = formalParameters();
3698            if (!isVoid) type = bracketsOpt(type);
3699            List<JCExpression> thrown = List.nil();
3700            if (token.kind == THROWS) {
3701                nextToken();
3702                thrown = qualidentList(true);
3703            }
3704            JCBlock body = null;
3705            JCExpression defaultValue;
3706            if (token.kind == LBRACE) {
3707                body = block();
3708                defaultValue = null;
3709            } else {
3710                if (token.kind == DEFAULT) {
3711                    accept(DEFAULT);
3712                    defaultValue = annotationValue();
3713                } else {
3714                    defaultValue = null;
3715                }
3716                accept(SEMI);
3717                if (token.pos <= endPosTable.errorEndPos) {
3718                    // error recovery
3719                    skip(false, true, false, false);
3720                    if (token.kind == LBRACE) {
3721                        body = block();
3722                    }
3723                }
3724            }
3725
3726            JCMethodDecl result =
3727                    toP(F.at(pos).MethodDef(mods, name, type, typarams,
3728                                            receiverParam, params, thrown,
3729                                            body, defaultValue));
3730            attach(result, dc);
3731            return result;
3732        } finally {
3733            this.receiverParam = prevReceiverParam;
3734        }
3735    }
3736
3737    /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
3738     */
3739    List<JCExpression> qualidentList(boolean allowAnnos) {
3740        ListBuffer<JCExpression> ts = new ListBuffer<>();
3741
3742        List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3743        JCExpression qi = qualident(allowAnnos);
3744        if (!typeAnnos.isEmpty()) {
3745            JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3746            ts.append(at);
3747        } else {
3748            ts.append(qi);
3749        }
3750        while (token.kind == COMMA) {
3751            nextToken();
3752
3753            typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3754            qi = qualident(allowAnnos);
3755            if (!typeAnnos.isEmpty()) {
3756                JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);
3757                ts.append(at);
3758            } else {
3759                ts.append(qi);
3760            }
3761        }
3762        return ts.toList();
3763    }
3764
3765    /**
3766     *  {@literal
3767     *  TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
3768     *  }
3769     */
3770    protected List<JCTypeParameter> typeParametersOpt() {
3771        if (token.kind == LT) {
3772            ListBuffer<JCTypeParameter> typarams = new ListBuffer<>();
3773            nextToken();
3774            typarams.append(typeParameter());
3775            while (token.kind == COMMA) {
3776                nextToken();
3777                typarams.append(typeParameter());
3778            }
3779            accept(GT);
3780            return typarams.toList();
3781        } else {
3782            return List.nil();
3783        }
3784    }
3785
3786    /**
3787     *  {@literal
3788     *  TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
3789     *  TypeParameterBound = EXTENDS Type {"&" Type}
3790     *  TypeVariable = Ident
3791     *  }
3792     */
3793    JCTypeParameter typeParameter() {
3794        int pos = token.pos;
3795        List<JCAnnotation> annos = typeAnnotationsOpt();
3796        Name name = ident();
3797        ListBuffer<JCExpression> bounds = new ListBuffer<>();
3798        if (token.kind == EXTENDS) {
3799            nextToken();
3800            bounds.append(parseType());
3801            while (token.kind == AMP) {
3802                nextToken();
3803                bounds.append(parseType());
3804            }
3805        }
3806        return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
3807    }
3808
3809    /** FormalParameters = "(" [ FormalParameterList ] ")"
3810     *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
3811     *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
3812     */
3813    List<JCVariableDecl> formalParameters() {
3814        return formalParameters(false);
3815    }
3816    List<JCVariableDecl> formalParameters(boolean lambdaParameters) {
3817        ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3818        JCVariableDecl lastParam;
3819        accept(LPAREN);
3820        if (token.kind != RPAREN) {
3821            this.allowThisIdent = true;
3822            lastParam = formalParameter(lambdaParameters);
3823            if (lastParam.nameexpr != null) {
3824                this.receiverParam = lastParam;
3825            } else {
3826                params.append(lastParam);
3827            }
3828            this.allowThisIdent = false;
3829            while (token.kind == COMMA) {
3830                if ((lastParam.mods.flags & Flags.VARARGS) != 0) {
3831                    error(lastParam, "varargs.must.be.last");
3832                }
3833                nextToken();
3834                params.append(lastParam = formalParameter(lambdaParameters));
3835            }
3836        }
3837        if (token.kind == RPAREN) {
3838            nextToken();
3839        } else {
3840            setErrorEndPos(token.pos);
3841            reportSyntaxError(S.prevToken().endPos, "expected3", COMMA, RPAREN, LBRACKET);
3842        }
3843        return params.toList();
3844    }
3845
3846    List<JCVariableDecl> implicitParameters(boolean hasParens) {
3847        if (hasParens) {
3848            accept(LPAREN);
3849        }
3850        ListBuffer<JCVariableDecl> params = new ListBuffer<>();
3851        if (token.kind != RPAREN && token.kind != ARROW) {
3852            params.append(implicitParameter());
3853            while (token.kind == COMMA) {
3854                nextToken();
3855                params.append(implicitParameter());
3856            }
3857        }
3858        if (hasParens) {
3859            accept(RPAREN);
3860        }
3861        return params.toList();
3862    }
3863
3864    JCModifiers optFinal(long flags) {
3865        JCModifiers mods = modifiersOpt();
3866        checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
3867        mods.flags |= flags;
3868        return mods;
3869    }
3870
3871    /**
3872     * Inserts the annotations (and possibly a new array level)
3873     * to the left-most type in an array or nested type.
3874     *
3875     * When parsing a type like {@code @B Outer.Inner @A []}, the
3876     * {@code @A} annotation should target the array itself, while
3877     * {@code @B} targets the nested type {@code Outer}.
3878     *
3879     * Currently the parser parses the annotation first, then
3880     * the array, and then inserts the annotation to the left-most
3881     * nested type.
3882     *
3883     * When {@code createNewLevel} is true, then a new array
3884     * level is inserted as the most inner type, and have the
3885     * annotations target it.  This is useful in the case of
3886     * varargs, e.g. {@code String @A [] @B ...}, as the parser
3887     * first parses the type {@code String @A []} then inserts
3888     * a new array level with {@code @B} annotation.
3889     */
3890    private JCExpression insertAnnotationsToMostInner(
3891            JCExpression type, List<JCAnnotation> annos,
3892            boolean createNewLevel) {
3893        int origEndPos = getEndPos(type);
3894        JCExpression mostInnerType = type;
3895        JCArrayTypeTree mostInnerArrayType = null;
3896        while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEARRAY)) {
3897            mostInnerArrayType = (JCArrayTypeTree) TreeInfo.typeIn(mostInnerType);
3898            mostInnerType = mostInnerArrayType.elemtype;
3899        }
3900
3901        if (createNewLevel) {
3902            mostInnerType = to(F.at(token.pos).TypeArray(mostInnerType));
3903        }
3904
3905        JCExpression mostInnerTypeToReturn = mostInnerType;
3906        if (annos.nonEmpty()) {
3907            JCExpression lastToModify = mostInnerType;
3908
3909            while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT) ||
3910                    TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3911                while (TreeInfo.typeIn(mostInnerType).hasTag(SELECT)) {
3912                    lastToModify = mostInnerType;
3913                    mostInnerType = ((JCFieldAccess) TreeInfo.typeIn(mostInnerType)).getExpression();
3914                }
3915                while (TreeInfo.typeIn(mostInnerType).hasTag(TYPEAPPLY)) {
3916                    lastToModify = mostInnerType;
3917                    mostInnerType = ((JCTypeApply) TreeInfo.typeIn(mostInnerType)).clazz;
3918                }
3919            }
3920
3921            mostInnerType = F.at(annos.head.pos).AnnotatedType(annos, mostInnerType);
3922
3923            if (TreeInfo.typeIn(lastToModify).hasTag(TYPEAPPLY)) {
3924                ((JCTypeApply) TreeInfo.typeIn(lastToModify)).clazz = mostInnerType;
3925            } else if (TreeInfo.typeIn(lastToModify).hasTag(SELECT)) {
3926                ((JCFieldAccess) TreeInfo.typeIn(lastToModify)).selected = mostInnerType;
3927            } else {
3928                // We never saw a SELECT or TYPEAPPLY, return the annotated type.
3929                mostInnerTypeToReturn = mostInnerType;
3930            }
3931        }
3932
3933        if (mostInnerArrayType == null) {
3934            return mostInnerTypeToReturn;
3935        } else {
3936            mostInnerArrayType.elemtype = mostInnerTypeToReturn;
3937            storeEnd(type, origEndPos);
3938            return type;
3939        }
3940    }
3941
3942    /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
3943     *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
3944     */
3945    protected JCVariableDecl formalParameter() {
3946        return formalParameter(false);
3947    }
3948    protected JCVariableDecl formalParameter(boolean lambdaParameter) {
3949        JCModifiers mods = optFinal(Flags.PARAMETER);
3950        // need to distinguish between vararg annos and array annos
3951        // look at typeAnnotationsPushedBack comment
3952        this.permitTypeAnnotationsPushBack = true;
3953        JCExpression type = parseType();
3954        this.permitTypeAnnotationsPushBack = false;
3955
3956        if (token.kind == ELLIPSIS) {
3957            List<JCAnnotation> varargsAnnos = typeAnnotationsPushedBack;
3958            typeAnnotationsPushedBack = List.nil();
3959            mods.flags |= Flags.VARARGS;
3960            // insert var arg type annotations
3961            type = insertAnnotationsToMostInner(type, varargsAnnos, true);
3962            nextToken();
3963        } else {
3964            // if not a var arg, then typeAnnotationsPushedBack should be null
3965            if (typeAnnotationsPushedBack.nonEmpty()) {
3966                reportSyntaxError(typeAnnotationsPushedBack.head.pos,
3967                        "illegal.start.of.type");
3968            }
3969            typeAnnotationsPushedBack = List.nil();
3970        }
3971        return variableDeclaratorId(mods, type, lambdaParameter);
3972    }
3973
3974    protected JCVariableDecl implicitParameter() {
3975        JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
3976        return variableDeclaratorId(mods, null, true);
3977    }
3978
3979/* ---------- auxiliary methods -------------- */
3980
3981    void error(int pos, String key, Object ... args) {
3982        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3983    }
3984
3985    void error(DiagnosticPosition pos, String key, Object ... args) {
3986        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
3987    }
3988
3989    void warning(int pos, String key, Object ... args) {
3990        log.warning(pos, key, args);
3991    }
3992
3993    /** Check that given tree is a legal expression statement.
3994     */
3995    protected JCExpression checkExprStat(JCExpression t) {
3996        if (!TreeInfo.isExpressionStatement(t)) {
3997            JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
3998            error(ret, "not.stmt");
3999            return ret;
4000        } else {
4001            return t;
4002        }
4003    }
4004
4005    /** Return precedence of operator represented by token,
4006     *  -1 if token is not a binary operator. @see TreeInfo.opPrec
4007     */
4008    static int prec(TokenKind token) {
4009        JCTree.Tag oc = optag(token);
4010        return (oc != NO_TAG) ? TreeInfo.opPrec(oc) : -1;
4011    }
4012
4013    /**
4014     * Return the lesser of two positions, making allowance for either one
4015     * being unset.
4016     */
4017    static int earlier(int pos1, int pos2) {
4018        if (pos1 == Position.NOPOS)
4019            return pos2;
4020        if (pos2 == Position.NOPOS)
4021            return pos1;
4022        return (pos1 < pos2 ? pos1 : pos2);
4023    }
4024
4025    /** Return operation tag of binary operator represented by token,
4026     *  No_TAG if token is not a binary operator.
4027     */
4028    static JCTree.Tag optag(TokenKind token) {
4029        switch (token) {
4030        case BARBAR:
4031            return OR;
4032        case AMPAMP:
4033            return AND;
4034        case BAR:
4035            return BITOR;
4036        case BAREQ:
4037            return BITOR_ASG;
4038        case CARET:
4039            return BITXOR;
4040        case CARETEQ:
4041            return BITXOR_ASG;
4042        case AMP:
4043            return BITAND;
4044        case AMPEQ:
4045            return BITAND_ASG;
4046        case EQEQ:
4047            return JCTree.Tag.EQ;
4048        case BANGEQ:
4049            return NE;
4050        case LT:
4051            return JCTree.Tag.LT;
4052        case GT:
4053            return JCTree.Tag.GT;
4054        case LTEQ:
4055            return LE;
4056        case GTEQ:
4057            return GE;
4058        case LTLT:
4059            return SL;
4060        case LTLTEQ:
4061            return SL_ASG;
4062        case GTGT:
4063            return SR;
4064        case GTGTEQ:
4065            return SR_ASG;
4066        case GTGTGT:
4067            return USR;
4068        case GTGTGTEQ:
4069            return USR_ASG;
4070        case PLUS:
4071            return JCTree.Tag.PLUS;
4072        case PLUSEQ:
4073            return PLUS_ASG;
4074        case SUB:
4075            return MINUS;
4076        case SUBEQ:
4077            return MINUS_ASG;
4078        case STAR:
4079            return MUL;
4080        case STAREQ:
4081            return MUL_ASG;
4082        case SLASH:
4083            return DIV;
4084        case SLASHEQ:
4085            return DIV_ASG;
4086        case PERCENT:
4087            return MOD;
4088        case PERCENTEQ:
4089            return MOD_ASG;
4090        case INSTANCEOF:
4091            return TYPETEST;
4092        default:
4093            return NO_TAG;
4094        }
4095    }
4096
4097    /** Return operation tag of unary operator represented by token,
4098     *  No_TAG if token is not a binary operator.
4099     */
4100    static JCTree.Tag unoptag(TokenKind token) {
4101        switch (token) {
4102        case PLUS:
4103            return POS;
4104        case SUB:
4105            return NEG;
4106        case BANG:
4107            return NOT;
4108        case TILDE:
4109            return COMPL;
4110        case PLUSPLUS:
4111            return PREINC;
4112        case SUBSUB:
4113            return PREDEC;
4114        default:
4115            return NO_TAG;
4116        }
4117    }
4118
4119    /** Return type tag of basic type represented by token,
4120     *  NONE if token is not a basic type identifier.
4121     */
4122    static TypeTag typetag(TokenKind token) {
4123        switch (token) {
4124        case BYTE:
4125            return TypeTag.BYTE;
4126        case CHAR:
4127            return TypeTag.CHAR;
4128        case SHORT:
4129            return TypeTag.SHORT;
4130        case INT:
4131            return TypeTag.INT;
4132        case LONG:
4133            return TypeTag.LONG;
4134        case FLOAT:
4135            return TypeTag.FLOAT;
4136        case DOUBLE:
4137            return TypeTag.DOUBLE;
4138        case BOOLEAN:
4139            return TypeTag.BOOLEAN;
4140        default:
4141            return TypeTag.NONE;
4142        }
4143    }
4144
4145    void checkDiamond() {
4146        if (!allowDiamond) {
4147            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DiamondNotSupportedInSource(source.name));
4148        }
4149    }
4150    void checkMulticatch() {
4151        if (!allowMulticatch) {
4152            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MulticatchNotSupportedInSource(source.name));
4153        }
4154    }
4155    void checkTryWithResources() {
4156        if (!allowTWR) {
4157            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TryWithResourcesNotSupportedInSource(source.name));
4158        }
4159    }
4160    void checkVariableInTryWithResources(int startPos) {
4161        if (!allowEffectivelyFinalVariablesInTWR) {
4162            log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, Errors.VarInTryWithResourcesNotSupportedInSource(source.name));
4163        }
4164    }
4165    void checkLambda() {
4166        if (!allowLambda) {
4167            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.LambdaNotSupportedInSource(source.name));
4168        }
4169    }
4170    void checkMethodReferences() {
4171        if (!allowMethodReferences) {
4172            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.MethodReferencesNotSupportedInSource(source.name));
4173        }
4174    }
4175    void checkDefaultMethods() {
4176        if (!allowDefaultMethods) {
4177            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DefaultMethodsNotSupportedInSource(source.name));
4178        }
4179    }
4180    void checkIntersectionTypesInCast() {
4181        if (!allowIntersectionTypesInCast) {
4182            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name));
4183        }
4184    }
4185    void checkStaticInterfaceMethods() {
4186        if (!allowStaticInterfaceMethods) {
4187            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.StaticIntfMethodsNotSupportedInSource(source.name));
4188        }
4189    }
4190    void checkTypeAnnotations() {
4191        if (!allowTypeAnnotations) {
4192            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.TypeAnnotationsNotSupportedInSource(source.name));
4193        }
4194    }
4195    void checkPrivateInterfaceMethods() {
4196        if (!allowPrivateInterfaceMethods) {
4197            log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
4198        }
4199    }
4200    protected void checkAnnotationsAfterTypeParams(int pos) {
4201        if (!allowAnnotationsAfterTypeParams) {
4202            log.error(DiagnosticFlag.SOURCE_LEVEL, pos, Errors.AnnotationsAfterTypeParamsNotSupportedInSource(source.name));
4203        }
4204    }
4205
4206    /*
4207     * a functional source tree and end position mappings
4208     */
4209    protected static class SimpleEndPosTable extends AbstractEndPosTable {
4210
4211        private final IntHashTable endPosMap;
4212
4213        SimpleEndPosTable(JavacParser parser) {
4214            super(parser);
4215            endPosMap = new IntHashTable();
4216        }
4217
4218        public void storeEnd(JCTree tree, int endpos) {
4219            endPosMap.putAtIndex(tree, errorEndPos > endpos ? errorEndPos : endpos,
4220                                 endPosMap.lookup(tree));
4221        }
4222
4223        protected <T extends JCTree> T to(T t) {
4224            storeEnd(t, parser.token.endPos);
4225            return t;
4226        }
4227
4228        protected <T extends JCTree> T toP(T t) {
4229            storeEnd(t, parser.S.prevToken().endPos);
4230            return t;
4231        }
4232
4233        public int getEndPos(JCTree tree) {
4234            int value = endPosMap.getFromIndex(endPosMap.lookup(tree));
4235            // As long as Position.NOPOS==-1, this just returns value.
4236            return (value == -1) ? Position.NOPOS : value;
4237        }
4238
4239        public int replaceTree(JCTree oldTree, JCTree newTree) {
4240            int pos = endPosMap.remove(oldTree);
4241            if (pos != -1) {
4242                storeEnd(newTree, pos);
4243                return pos;
4244            }
4245            return Position.NOPOS;
4246        }
4247    }
4248
4249    /*
4250     * a default skeletal implementation without any mapping overhead.
4251     */
4252    protected static class EmptyEndPosTable extends AbstractEndPosTable {
4253
4254        EmptyEndPosTable(JavacParser parser) {
4255            super(parser);
4256        }
4257
4258        public void storeEnd(JCTree tree, int endpos) { /* empty */ }
4259
4260        protected <T extends JCTree> T to(T t) {
4261            return t;
4262        }
4263
4264        protected <T extends JCTree> T toP(T t) {
4265            return t;
4266        }
4267
4268        public int getEndPos(JCTree tree) {
4269            return Position.NOPOS;
4270        }
4271
4272        public int replaceTree(JCTree oldTree, JCTree newTree) {
4273            return Position.NOPOS;
4274        }
4275
4276    }
4277
4278    protected static abstract class AbstractEndPosTable implements EndPosTable {
4279        /**
4280         * The current parser.
4281         */
4282        protected JavacParser parser;
4283
4284        /**
4285         * Store the last error position.
4286         */
4287        public int errorEndPos = Position.NOPOS;
4288
4289        public AbstractEndPosTable(JavacParser parser) {
4290            this.parser = parser;
4291        }
4292
4293        /**
4294         * Store current token's ending position for a tree, the value of which
4295         * will be the greater of last error position and the ending position of
4296         * the current token.
4297         * @param t The tree.
4298         */
4299        protected abstract <T extends JCTree> T to(T t);
4300
4301        /**
4302         * Store current token's ending position for a tree, the value of which
4303         * will be the greater of last error position and the ending position of
4304         * the previous token.
4305         * @param t The tree.
4306         */
4307        protected abstract <T extends JCTree> T toP(T t);
4308
4309        /**
4310         * Set the error position during the parsing phases, the value of which
4311         * will be set only if it is greater than the last stored error position.
4312         * @param errPos The error position
4313         */
4314        public void setErrorEndPos(int errPos) {
4315            if (errPos > errorEndPos) {
4316                errorEndPos = errPos;
4317            }
4318        }
4319
4320        public void setParser(JavacParser parser) {
4321            this.parser = parser;
4322        }
4323    }
4324}
4325