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