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