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