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