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