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