Thu, 04 Feb 2010 10:14:28 -0800
6923080: TreeScanner.visitNewClass should scan tree.typeargs
Reviewed-by: darcy
1 /*
2 * Copyright 1999-2009 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.javac.parser;
28 import java.util.*;
30 import com.sun.tools.javac.tree.*;
31 import com.sun.tools.javac.code.*;
32 import com.sun.tools.javac.util.*;
33 import com.sun.tools.javac.util.List;
34 import static com.sun.tools.javac.util.ListBuffer.lb;
36 import com.sun.tools.javac.tree.JCTree.*;
38 import static com.sun.tools.javac.parser.Token.*;
40 /** The parser maps a token sequence into an abstract syntax
41 * tree. It operates by recursive descent, with code derived
42 * systematically from an LL(1) grammar. For efficiency reasons, an
43 * operator precedence scheme is used for parsing binary operation
44 * expressions.
45 *
46 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
47 * you write code that depends on this, you do so at your own risk.
48 * This code and its internal interfaces are subject to change or
49 * deletion without notice.</b>
50 */
51 public class JavacParser implements Parser {
53 /** The number of precedence levels of infix operators.
54 */
55 private static final int infixPrecedenceLevels = 10;
57 /** The scanner used for lexical analysis.
58 */
59 private Lexer S;
61 /** The factory to be used for abstract syntax tree construction.
62 */
63 protected TreeMaker F;
65 /** The log to be used for error diagnostics.
66 */
67 private Log log;
69 /** The keyword table. */
70 private Keywords keywords;
72 /** The Source language setting. */
73 private Source source;
75 /** The name table. */
76 private Names names;
78 // Because of javac's limited lookahead, some contexts are ambiguous in
79 // the presence of type annotations even though they are not ambiguous
80 // in the absence of type annotations. Consider this code:
81 // void m(String [] m) { }
82 // void m(String ... m) { }
83 // After parsing "String", javac calls bracketsOpt which immediately
84 // returns if the next character is not '['. Similarly, javac can see
85 // if the next token is ... and in that case parse an ellipsis. But in
86 // the presence of type annotations:
87 // void m(String @A [] m) { }
88 // void m(String @A ... m) { }
89 // no finite lookahead is enough to determine whether to read array
90 // levels or an ellipsis. Furthermore, if you call bracketsOpt, then
91 // bracketsOpt first reads all the leading annotations and only then
92 // discovers that it needs to fail. bracketsOpt needs a way to push
93 // back the extra annotations that it read. (But, bracketsOpt should
94 // not *always* be allowed to push back extra annotations that it finds
95 // -- in most contexts, any such extra annotation is an error.
96 // Another similar case occurs with arrays and receiver annotations:
97 // String b() @Array [] @Receiver { }
98 // String b() @Receiver { }
99 //
100 // The following two variables permit type annotations that have
101 // already been read to be stored for later use. Alternate
102 // implementations are possible but would cause much larger changes to
103 // the parser.
104 /** Type annotations that have already been read but have not yet been used. **/
105 private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
106 /**
107 * If the parser notices extra annotations, then it either immediately
108 * issues an error (if this variable is false) or places the extra
109 * annotations in variable typeAnnotationsPushedBack (if this variable
110 * is true).
111 */
112 private boolean permitTypeAnnotationsPushBack = false;
114 /** Construct a parser from a given scanner, tree factory and log.
115 */
116 protected JavacParser(ParserFactory fac,
117 Lexer S,
118 boolean keepDocComments,
119 boolean keepLineMap) {
120 this.S = S;
121 S.nextToken(); // prime the pump
122 this.F = fac.F;
123 this.log = fac.log;
124 this.names = fac.names;
125 this.keywords = fac.keywords;
126 this.source = fac.source;
127 this.allowGenerics = source.allowGenerics();
128 this.allowVarargs = source.allowVarargs();
129 this.allowAsserts = source.allowAsserts();
130 this.allowEnums = source.allowEnums();
131 this.allowForeach = source.allowForeach();
132 this.allowStaticImport = source.allowStaticImport();
133 this.allowAnnotations = source.allowAnnotations();
134 this.allowDiamond = source.allowDiamond();
135 this.allowTypeAnnotations = source.allowTypeAnnotations();
136 this.keepDocComments = keepDocComments;
137 if (keepDocComments)
138 docComments = new HashMap<JCTree,String>();
139 this.keepLineMap = keepLineMap;
140 this.errorTree = F.Erroneous();
141 this.debugJSR308 = fac.options.get("TA:parser") != null;
142 }
144 /** Switch: debug output for type-annotations operations
145 */
146 boolean debugJSR308;
148 /** Switch: Should generics be recognized?
149 */
150 boolean allowGenerics;
152 /** Switch: Should diamond operator be recognized?
153 */
154 boolean allowDiamond;
156 /** Switch: Should varargs be recognized?
157 */
158 boolean allowVarargs;
160 /** Switch: should we recognize assert statements, or just give a warning?
161 */
162 boolean allowAsserts;
164 /** Switch: should we recognize enums, or just give a warning?
165 */
166 boolean allowEnums;
168 /** Switch: should we recognize foreach?
169 */
170 boolean allowForeach;
172 /** Switch: should we recognize foreach?
173 */
174 boolean allowStaticImport;
176 /** Switch: should we recognize annotations?
177 */
178 boolean allowAnnotations;
180 /** Switch: should we recognize type annotations?
181 */
182 boolean allowTypeAnnotations;
184 /** Switch: should we keep docComments?
185 */
186 boolean keepDocComments;
188 /** Switch: should we keep line table?
189 */
190 boolean keepLineMap;
192 /** When terms are parsed, the mode determines which is expected:
193 * mode = EXPR : an expression
194 * mode = TYPE : a type
195 * mode = NOPARAMS : no parameters allowed for type
196 * mode = TYPEARG : type argument
197 */
198 static final int EXPR = 1;
199 static final int TYPE = 2;
200 static final int NOPARAMS = 4;
201 static final int TYPEARG = 8;
202 static final int DIAMOND = 16;
204 /** The current mode.
205 */
206 private int mode = 0;
208 /** The mode of the term that was parsed last.
209 */
210 private int lastmode = 0;
212 /* ---------- error recovery -------------- */
214 private JCErroneous errorTree;
216 /** Skip forward until a suitable stop token is found.
217 */
218 private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) {
219 while (true) {
220 switch (S.token()) {
221 case SEMI:
222 S.nextToken();
223 return;
224 case PUBLIC:
225 case FINAL:
226 case ABSTRACT:
227 case MONKEYS_AT:
228 case EOF:
229 case CLASS:
230 case INTERFACE:
231 case ENUM:
232 return;
233 case IMPORT:
234 if (stopAtImport)
235 return;
236 break;
237 case LBRACE:
238 case RBRACE:
239 case PRIVATE:
240 case PROTECTED:
241 case STATIC:
242 case TRANSIENT:
243 case NATIVE:
244 case VOLATILE:
245 case SYNCHRONIZED:
246 case STRICTFP:
247 case LT:
248 case BYTE:
249 case SHORT:
250 case CHAR:
251 case INT:
252 case LONG:
253 case FLOAT:
254 case DOUBLE:
255 case BOOLEAN:
256 case VOID:
257 if (stopAtMemberDecl)
258 return;
259 break;
260 case IDENTIFIER:
261 if (stopAtIdentifier)
262 return;
263 break;
264 case CASE:
265 case DEFAULT:
266 case IF:
267 case FOR:
268 case WHILE:
269 case DO:
270 case TRY:
271 case SWITCH:
272 case RETURN:
273 case THROW:
274 case BREAK:
275 case CONTINUE:
276 case ELSE:
277 case FINALLY:
278 case CATCH:
279 if (stopAtStatement)
280 return;
281 break;
282 }
283 S.nextToken();
284 }
285 }
287 private JCErroneous syntaxError(int pos, String key, Token... args) {
288 return syntaxError(pos, null, key, args);
289 }
291 private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
292 setErrorEndPos(pos);
293 reportSyntaxError(pos, key, (Object[])args);
294 return toP(F.at(pos).Erroneous(errs));
295 }
297 private int errorPos = Position.NOPOS;
298 /**
299 * Report a syntax error at given position using the given
300 * argument unless one was already reported at the same position.
301 */
302 private void reportSyntaxError(int pos, String key, Object... args) {
303 if (pos > S.errPos() || pos == Position.NOPOS) {
304 if (S.token() == EOF)
305 log.error(pos, "premature.eof");
306 else
307 log.error(pos, key, args);
308 }
309 S.errPos(pos);
310 if (S.pos() == errorPos)
311 S.nextToken(); // guarantee progress
312 errorPos = S.pos();
313 }
316 /** Generate a syntax error at current position unless one was already
317 * reported at the same position.
318 */
319 private JCErroneous syntaxError(String key) {
320 return syntaxError(S.pos(), key);
321 }
323 /** Generate a syntax error at current position unless one was
324 * already reported at the same position.
325 */
326 private JCErroneous syntaxError(String key, Token arg) {
327 return syntaxError(S.pos(), key, arg);
328 }
330 /** If next input token matches given token, skip it, otherwise report
331 * an error.
332 */
333 public void accept(Token token) {
334 if (S.token() == token) {
335 S.nextToken();
336 } else {
337 setErrorEndPos(S.pos());
338 reportSyntaxError(S.prevEndPos(), "expected", token);
339 }
340 }
342 /** Report an illegal start of expression/type error at given position.
343 */
344 JCExpression illegal(int pos) {
345 setErrorEndPos(S.pos());
346 if ((mode & EXPR) != 0)
347 return syntaxError(pos, "illegal.start.of.expr");
348 else
349 return syntaxError(pos, "illegal.start.of.type");
351 }
353 /** Report an illegal start of expression/type error at current position.
354 */
355 JCExpression illegal() {
356 return illegal(S.pos());
357 }
359 /** Diagnose a modifier flag from the set, if any. */
360 void checkNoMods(long mods) {
361 if (mods != 0) {
362 long lowestMod = mods & -mods;
363 log.error(S.pos(), "mod.not.allowed.here",
364 Flags.asFlagSet(lowestMod));
365 }
366 }
368 /* ---------- doc comments --------- */
370 /** A hashtable to store all documentation comments
371 * indexed by the tree nodes they refer to.
372 * defined only if option flag keepDocComment is set.
373 */
374 Map<JCTree, String> docComments;
376 /** Make an entry into docComments hashtable,
377 * provided flag keepDocComments is set and given doc comment is non-null.
378 * @param tree The tree to be used as index in the hashtable
379 * @param dc The doc comment to associate with the tree, or null.
380 */
381 void attach(JCTree tree, String dc) {
382 if (keepDocComments && dc != null) {
383 // System.out.println("doc comment = ");System.out.println(dc);//DEBUG
384 docComments.put(tree, dc);
385 }
386 }
388 /* -------- source positions ------- */
390 private int errorEndPos = -1;
392 private void setErrorEndPos(int errPos) {
393 if (errPos > errorEndPos)
394 errorEndPos = errPos;
395 }
397 protected int getErrorEndPos() {
398 return errorEndPos;
399 }
401 /**
402 * Store ending position for a tree.
403 * @param tree The tree.
404 * @param endpos The ending position to associate with the tree.
405 */
406 protected void storeEnd(JCTree tree, int endpos) {}
408 /**
409 * Store ending position for a tree. The ending position should
410 * be the ending position of the current token.
411 * @param t The tree.
412 */
413 protected <T extends JCTree> T to(T t) { return t; }
415 /**
416 * Store ending position for a tree. The ending position should
417 * be greater of the ending position of the previous token and errorEndPos.
418 * @param t The tree.
419 */
420 protected <T extends JCTree> T toP(T t) { return t; }
422 /** Get the start position for a tree node. The start position is
423 * defined to be the position of the first character of the first
424 * token of the node's source text.
425 * @param tree The tree node
426 */
427 public int getStartPos(JCTree tree) {
428 return TreeInfo.getStartPos(tree);
429 }
431 /**
432 * Get the end position for a tree node. The end position is
433 * defined to be the position of the last character of the last
434 * token of the node's source text. Returns Position.NOPOS if end
435 * positions are not generated or the position is otherwise not
436 * found.
437 * @param tree The tree node
438 */
439 public int getEndPos(JCTree tree) {
440 return Position.NOPOS;
441 }
445 /* ---------- parsing -------------- */
447 /**
448 * Ident = IDENTIFIER
449 */
450 Name ident() {
451 if (S.token() == IDENTIFIER) {
452 Name name = S.name();
453 S.nextToken();
454 return name;
455 } else if (S.token() == ASSERT) {
456 if (allowAsserts) {
457 log.error(S.pos(), "assert.as.identifier");
458 S.nextToken();
459 return names.error;
460 } else {
461 log.warning(S.pos(), "assert.as.identifier");
462 Name name = S.name();
463 S.nextToken();
464 return name;
465 }
466 } else if (S.token() == ENUM) {
467 if (allowEnums) {
468 log.error(S.pos(), "enum.as.identifier");
469 S.nextToken();
470 return names.error;
471 } else {
472 log.warning(S.pos(), "enum.as.identifier");
473 Name name = S.name();
474 S.nextToken();
475 return name;
476 }
477 } else {
478 accept(IDENTIFIER);
479 return names.error;
480 }
481 }
483 /**
484 * Qualident = Ident { DOT Ident }
485 */
486 public JCExpression qualident() {
487 JCExpression t = toP(F.at(S.pos()).Ident(ident()));
488 while (S.token() == DOT) {
489 int pos = S.pos();
490 S.nextToken();
491 t = toP(F.at(pos).Select(t, ident()));
492 }
493 return t;
494 }
496 /**
497 * Literal =
498 * INTLITERAL
499 * | LONGLITERAL
500 * | FLOATLITERAL
501 * | DOUBLELITERAL
502 * | CHARLITERAL
503 * | STRINGLITERAL
504 * | TRUE
505 * | FALSE
506 * | NULL
507 */
508 JCExpression literal(Name prefix) {
509 int pos = S.pos();
510 JCExpression t = errorTree;
511 switch (S.token()) {
512 case INTLITERAL:
513 try {
514 t = F.at(pos).Literal(
515 TypeTags.INT,
516 Convert.string2int(strval(prefix), S.radix()));
517 } catch (NumberFormatException ex) {
518 log.error(S.pos(), "int.number.too.large", strval(prefix));
519 }
520 break;
521 case LONGLITERAL:
522 try {
523 t = F.at(pos).Literal(
524 TypeTags.LONG,
525 new Long(Convert.string2long(strval(prefix), S.radix())));
526 } catch (NumberFormatException ex) {
527 log.error(S.pos(), "int.number.too.large", strval(prefix));
528 }
529 break;
530 case FLOATLITERAL: {
531 String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
532 Float n;
533 try {
534 n = Float.valueOf(proper);
535 } catch (NumberFormatException ex) {
536 // error already repoted in scanner
537 n = Float.NaN;
538 }
539 if (n.floatValue() == 0.0f && !isZero(proper))
540 log.error(S.pos(), "fp.number.too.small");
541 else if (n.floatValue() == Float.POSITIVE_INFINITY)
542 log.error(S.pos(), "fp.number.too.large");
543 else
544 t = F.at(pos).Literal(TypeTags.FLOAT, n);
545 break;
546 }
547 case DOUBLELITERAL: {
548 String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal());
549 Double n;
550 try {
551 n = Double.valueOf(proper);
552 } catch (NumberFormatException ex) {
553 // error already reported in scanner
554 n = Double.NaN;
555 }
556 if (n.doubleValue() == 0.0d && !isZero(proper))
557 log.error(S.pos(), "fp.number.too.small");
558 else if (n.doubleValue() == Double.POSITIVE_INFINITY)
559 log.error(S.pos(), "fp.number.too.large");
560 else
561 t = F.at(pos).Literal(TypeTags.DOUBLE, n);
562 break;
563 }
564 case CHARLITERAL:
565 t = F.at(pos).Literal(
566 TypeTags.CHAR,
567 S.stringVal().charAt(0) + 0);
568 break;
569 case STRINGLITERAL:
570 t = F.at(pos).Literal(
571 TypeTags.CLASS,
572 S.stringVal());
573 break;
574 case TRUE: case FALSE:
575 t = F.at(pos).Literal(
576 TypeTags.BOOLEAN,
577 (S.token() == TRUE ? 1 : 0));
578 break;
579 case NULL:
580 t = F.at(pos).Literal(
581 TypeTags.BOT,
582 null);
583 break;
584 default:
585 assert false;
586 }
587 if (t == errorTree)
588 t = F.at(pos).Erroneous();
589 storeEnd(t, S.endPos());
590 S.nextToken();
591 return t;
592 }
593 //where
594 boolean isZero(String s) {
595 char[] cs = s.toCharArray();
596 int base = ((cs.length > 1 && Character.toLowerCase(cs[1]) == 'x') ? 16 : 10);
597 int i = ((base==16) ? 2 : 0);
598 while (i < cs.length && (cs[i] == '0' || cs[i] == '.')) i++;
599 return !(i < cs.length && (Character.digit(cs[i], base) > 0));
600 }
602 String strval(Name prefix) {
603 String s = S.stringVal();
604 return prefix.isEmpty() ? s : prefix + s;
605 }
607 /** terms can be either expressions or types.
608 */
609 public JCExpression parseExpression() {
610 return term(EXPR);
611 }
613 /**
614 * parses (optional) type annotations followed by a type. If the
615 * annotations are present before the type and are not consumed during array
616 * parsing, this method returns a {@link JCAnnotatedType} consisting of
617 * these annotations and the underlying type. Otherwise, it returns the
618 * underlying type.
619 *
620 * <p>
621 *
622 * Note that this method sets {@code mode} to {@code TYPE} first, before
623 * parsing annotations.
624 */
625 public JCExpression parseType() {
626 List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
627 return parseType(annotations);
628 }
630 public JCExpression parseType(List<JCTypeAnnotation> annotations) {
631 JCExpression result = unannotatedType();
633 if (!annotations.isEmpty())
634 result = F.AnnotatedType(annotations, result);
636 return result;
637 }
639 public JCExpression unannotatedType() {
640 return term(TYPE);
641 }
643 JCExpression term(int newmode) {
644 int prevmode = mode;
645 mode = newmode;
646 JCExpression t = term();
647 lastmode = mode;
648 mode = prevmode;
649 return t;
650 }
652 /**
653 * Expression = Expression1 [ExpressionRest]
654 * ExpressionRest = [AssignmentOperator Expression1]
655 * AssignmentOperator = "=" | "+=" | "-=" | "*=" | "/=" |
656 * "&=" | "|=" | "^=" |
657 * "%=" | "<<=" | ">>=" | ">>>="
658 * Type = Type1
659 * TypeNoParams = TypeNoParams1
660 * StatementExpression = Expression
661 * ConstantExpression = Expression
662 */
663 JCExpression term() {
664 JCExpression t = term1();
665 if ((mode & EXPR) != 0 &&
666 S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0)
667 return termRest(t);
668 else
669 return t;
670 }
672 JCExpression termRest(JCExpression t) {
673 switch (S.token()) {
674 case EQ: {
675 int pos = S.pos();
676 S.nextToken();
677 mode = EXPR;
678 JCExpression t1 = term();
679 return toP(F.at(pos).Assign(t, t1));
680 }
681 case PLUSEQ:
682 case SUBEQ:
683 case STAREQ:
684 case SLASHEQ:
685 case PERCENTEQ:
686 case AMPEQ:
687 case BAREQ:
688 case CARETEQ:
689 case LTLTEQ:
690 case GTGTEQ:
691 case GTGTGTEQ:
692 int pos = S.pos();
693 Token token = S.token();
694 S.nextToken();
695 mode = EXPR;
696 JCExpression t1 = term();
697 return F.at(pos).Assignop(optag(token), t, t1);
698 default:
699 return t;
700 }
701 }
703 /** Expression1 = Expression2 [Expression1Rest]
704 * Type1 = Type2
705 * TypeNoParams1 = TypeNoParams2
706 */
707 JCExpression term1() {
708 JCExpression t = term2();
709 if ((mode & EXPR) != 0 && S.token() == QUES) {
710 mode = EXPR;
711 return term1Rest(t);
712 } else {
713 return t;
714 }
715 }
717 /** Expression1Rest = ["?" Expression ":" Expression1]
718 */
719 JCExpression term1Rest(JCExpression t) {
720 if (S.token() == QUES) {
721 int pos = S.pos();
722 S.nextToken();
723 JCExpression t1 = term();
724 accept(COLON);
725 JCExpression t2 = term1();
726 return F.at(pos).Conditional(t, t1, t2);
727 } else {
728 return t;
729 }
730 }
732 /** Expression2 = Expression3 [Expression2Rest]
733 * Type2 = Type3
734 * TypeNoParams2 = TypeNoParams3
735 */
736 JCExpression term2() {
737 JCExpression t = term3();
738 if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) {
739 mode = EXPR;
740 return term2Rest(t, TreeInfo.orPrec);
741 } else {
742 return t;
743 }
744 }
746 /* Expression2Rest = {infixop Expression3}
747 * | Expression3 instanceof Type
748 * infixop = "||"
749 * | "&&"
750 * | "|"
751 * | "^"
752 * | "&"
753 * | "==" | "!="
754 * | "<" | ">" | "<=" | ">="
755 * | "<<" | ">>" | ">>>"
756 * | "+" | "-"
757 * | "*" | "/" | "%"
758 */
759 JCExpression term2Rest(JCExpression t, int minprec) {
760 List<JCExpression[]> savedOd = odStackSupply.elems;
761 JCExpression[] odStack = newOdStack();
762 List<Token[]> savedOp = opStackSupply.elems;
763 Token[] opStack = newOpStack();
764 List<int[]> savedPos = posStackSupply.elems;
765 int[] posStack = newPosStack();
766 // optimization, was odStack = new Tree[...]; opStack = new Tree[...];
767 int top = 0;
768 odStack[0] = t;
769 int startPos = S.pos();
770 Token topOp = ERROR;
771 int topOpPos = Position.NOPOS;
772 while (prec(S.token()) >= minprec) {
773 posStack[top] = topOpPos;
774 opStack[top] = topOp;
775 top++;
776 topOp = S.token();
777 topOpPos = S.pos();
778 S.nextToken();
779 odStack[top] = (topOp == INSTANCEOF) ? parseType() : term3();
780 while (top > 0 && prec(topOp) >= prec(S.token())) {
781 odStack[top-1] = makeOp(topOpPos, topOp, odStack[top-1],
782 odStack[top]);
783 top--;
784 topOp = opStack[top];
785 topOpPos = posStack[top];
786 }
787 }
788 assert top == 0;
789 t = odStack[0];
791 if (t.getTag() == JCTree.PLUS) {
792 StringBuffer buf = foldStrings(t);
793 if (buf != null) {
794 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
795 }
796 }
798 odStackSupply.elems = savedOd; // optimization
799 opStackSupply.elems = savedOp; // optimization
800 posStackSupply.elems = savedPos; // optimization
801 return t;
802 }
803 //where
804 /** Construct a binary or type test node.
805 */
806 private JCExpression makeOp(int pos,
807 Token topOp,
808 JCExpression od1,
809 JCExpression od2)
810 {
811 if (topOp == INSTANCEOF) {
812 return F.at(pos).TypeTest(od1, od2);
813 } else {
814 return F.at(pos).Binary(optag(topOp), od1, od2);
815 }
816 }
817 /** If tree is a concatenation of string literals, replace it
818 * by a single literal representing the concatenated string.
819 */
820 protected StringBuffer foldStrings(JCTree tree) {
821 List<String> buf = List.nil();
822 while (true) {
823 if (tree.getTag() == JCTree.LITERAL) {
824 JCLiteral lit = (JCLiteral) tree;
825 if (lit.typetag == TypeTags.CLASS) {
826 StringBuffer sbuf =
827 new StringBuffer((String)lit.value);
828 while (buf.nonEmpty()) {
829 sbuf.append(buf.head);
830 buf = buf.tail;
831 }
832 return sbuf;
833 }
834 } else if (tree.getTag() == JCTree.PLUS) {
835 JCBinary op = (JCBinary)tree;
836 if (op.rhs.getTag() == JCTree.LITERAL) {
837 JCLiteral lit = (JCLiteral) op.rhs;
838 if (lit.typetag == TypeTags.CLASS) {
839 buf = buf.prepend((String) lit.value);
840 tree = op.lhs;
841 continue;
842 }
843 }
844 }
845 return null;
846 }
847 }
849 /** optimization: To save allocating a new operand/operator stack
850 * for every binary operation, we use supplys.
851 */
852 ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
853 ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
854 ListBuffer<int[]> posStackSupply = new ListBuffer<int[]>();
856 private JCExpression[] newOdStack() {
857 if (odStackSupply.elems == odStackSupply.last)
858 odStackSupply.append(new JCExpression[infixPrecedenceLevels + 1]);
859 JCExpression[] odStack = odStackSupply.elems.head;
860 odStackSupply.elems = odStackSupply.elems.tail;
861 return odStack;
862 }
864 private Token[] newOpStack() {
865 if (opStackSupply.elems == opStackSupply.last)
866 opStackSupply.append(new Token[infixPrecedenceLevels + 1]);
867 Token[] opStack = opStackSupply.elems.head;
868 opStackSupply.elems = opStackSupply.elems.tail;
869 return opStack;
870 }
872 private int[] newPosStack() {
873 if (posStackSupply.elems == posStackSupply.last)
874 posStackSupply.append(new int[infixPrecedenceLevels + 1]);
875 int[] posStack = posStackSupply.elems.head;
876 posStackSupply.elems = posStackSupply.elems.tail;
877 return posStack;
878 }
880 /** Expression3 = PrefixOp Expression3
881 * | "(" Expr | TypeNoParams ")" Expression3
882 * | Primary {Selector} {PostfixOp}
883 * Primary = "(" Expression ")"
884 * | Literal
885 * | [TypeArguments] THIS [Arguments]
886 * | [TypeArguments] SUPER SuperSuffix
887 * | NEW [TypeArguments] Creator
888 * | [Annotations] Ident { "." Ident }
889 * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
890 * | Arguments
891 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
892 * ]
893 * | BasicType BracketsOpt "." CLASS
894 * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-"
895 * PostfixOp = "++" | "--"
896 * Type3 = Ident { "." Ident } [TypeArguments] {TypeSelector} BracketsOpt
897 * | BasicType
898 * TypeNoParams3 = Ident { "." Ident } BracketsOpt
899 * Selector = "." [TypeArguments] Ident [Arguments]
900 * | "." THIS
901 * | "." [TypeArguments] SUPER SuperSuffix
902 * | "." NEW [TypeArguments] InnerCreator
903 * | "[" Expression "]"
904 * TypeSelector = "." Ident [TypeArguments]
905 * SuperSuffix = Arguments | "." Ident [Arguments]
906 */
907 protected JCExpression term3() {
908 int pos = S.pos();
909 JCExpression t;
910 List<JCExpression> typeArgs = typeArgumentsOpt(EXPR);
911 switch (S.token()) {
912 case QUES:
913 if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) {
914 mode = TYPE;
915 return typeArgument();
916 } else
917 return illegal();
918 case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB:
919 if (typeArgs == null && (mode & EXPR) != 0) {
920 Token token = S.token();
921 S.nextToken();
922 mode = EXPR;
923 if (token == SUB &&
924 (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
925 S.radix() == 10) {
926 mode = EXPR;
927 t = literal(names.hyphen);
928 } else {
929 t = term3();
930 return F.at(pos).Unary(unoptag(token), t);
931 }
932 } else return illegal();
933 break;
934 case LPAREN:
935 if (typeArgs == null && (mode & EXPR) != 0) {
936 S.nextToken();
937 mode = EXPR | TYPE | NOPARAMS;
938 t = term3();
939 if ((mode & TYPE) != 0 && S.token() == LT) {
940 // Could be a cast to a parameterized type
941 int op = JCTree.LT;
942 int pos1 = S.pos();
943 S.nextToken();
944 mode &= (EXPR | TYPE);
945 mode |= TYPEARG;
946 JCExpression t1 = term3();
947 if ((mode & TYPE) != 0 &&
948 (S.token() == COMMA || S.token() == GT)) {
949 mode = TYPE;
950 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
951 args.append(t1);
952 while (S.token() == COMMA) {
953 S.nextToken();
954 args.append(typeArgument());
955 }
956 accept(GT);
957 t = toP(F.at(pos1).TypeApply(t, args.toList()));
958 checkGenerics();
959 while (S.token() == DOT) {
960 S.nextToken();
961 mode = TYPE;
962 t = toP(F.at(S.pos()).Select(t, ident()));
963 t = typeArgumentsOpt(t);
964 }
965 t = bracketsOpt(toP(t));
966 } else if ((mode & EXPR) != 0) {
967 mode = EXPR;
968 JCExpression e = term2Rest(t1, TreeInfo.shiftPrec);
969 t = F.at(pos1).Binary(op, t, e);
970 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
971 } else {
972 accept(GT);
973 }
974 }
975 else {
976 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
977 }
978 accept(RPAREN);
979 lastmode = mode;
980 mode = EXPR;
981 if ((lastmode & EXPR) == 0) {
982 JCExpression t1 = term3();
983 return F.at(pos).TypeCast(t, t1);
984 } else if ((lastmode & TYPE) != 0) {
985 switch (S.token()) {
986 /*case PLUSPLUS: case SUBSUB: */
987 case BANG: case TILDE:
988 case LPAREN: case THIS: case SUPER:
989 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
990 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
991 case TRUE: case FALSE: case NULL:
992 case NEW: case IDENTIFIER: case ASSERT: case ENUM:
993 case BYTE: case SHORT: case CHAR: case INT:
994 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
995 JCExpression t1 = term3();
996 return F.at(pos).TypeCast(t, t1);
997 }
998 }
999 } else return illegal();
1000 t = toP(F.at(pos).Parens(t));
1001 break;
1002 case THIS:
1003 if ((mode & EXPR) != 0) {
1004 mode = EXPR;
1005 t = to(F.at(pos).Ident(names._this));
1006 S.nextToken();
1007 if (typeArgs == null)
1008 t = argumentsOpt(null, t);
1009 else
1010 t = arguments(typeArgs, t);
1011 typeArgs = null;
1012 } else return illegal();
1013 break;
1014 case SUPER:
1015 if ((mode & EXPR) != 0) {
1016 mode = EXPR;
1017 t = to(F.at(pos).Ident(names._super));
1018 t = superSuffix(typeArgs, t);
1019 typeArgs = null;
1020 } else return illegal();
1021 break;
1022 case INTLITERAL: case LONGLITERAL: case FLOATLITERAL: case DOUBLELITERAL:
1023 case CHARLITERAL: case STRINGLITERAL:
1024 case TRUE: case FALSE: case NULL:
1025 if (typeArgs == null && (mode & EXPR) != 0) {
1026 mode = EXPR;
1027 t = literal(names.empty);
1028 } else return illegal();
1029 break;
1030 case NEW:
1031 if (typeArgs != null) return illegal();
1032 if ((mode & EXPR) != 0) {
1033 mode = EXPR;
1034 S.nextToken();
1035 if (S.token() == LT) typeArgs = typeArguments();
1036 t = creator(pos, typeArgs);
1037 typeArgs = null;
1038 } else return illegal();
1039 break;
1040 case MONKEYS_AT:
1042 // only annotated targetting class literals or cast types are valid
1043 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
1044 if (typeAnnos.isEmpty()) {
1045 // else there would be no '@'
1046 throw new AssertionError("type annos is empty");
1047 }
1049 JCExpression expr = term3();
1051 // Type annotations: If term3 just parsed a non-type, expect a
1052 // class literal (and issue a syntax error if there is no class
1053 // literal). Otherwise, create a JCAnnotatedType.
1054 if ((mode & TYPE) == 0) {
1055 if (expr.getTag() != JCTree.SELECT)
1056 return illegal(typeAnnos.head.pos);
1057 JCFieldAccess sel = (JCFieldAccess)expr;
1058 if (sel.name != names._class)
1059 return illegal();
1060 else {
1061 sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
1062 t = expr;
1063 }
1064 } else {
1065 // type annotation targeting a cast
1066 t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
1067 }
1068 break;
1069 case IDENTIFIER: case ASSERT: case ENUM:
1070 if (typeArgs != null) return illegal();
1071 t = toP(F.at(S.pos()).Ident(ident()));
1072 loop: while (true) {
1073 pos = S.pos();
1074 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1076 // need to report an error later if LBRACKET is for array
1077 // index access rather than array creation level
1078 if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
1079 return illegal(annos.head.pos);
1080 switch (S.token()) {
1081 case LBRACKET:
1082 S.nextToken();
1084 if (S.token() == RBRACKET) {
1086 S.nextToken();
1088 t = bracketsOpt(t, annos);
1089 t = toP(F.at(pos).TypeArray(t));
1090 t = bracketsSuffix(t);
1091 } else {
1092 if ((mode & EXPR) != 0) {
1093 mode = EXPR;
1094 JCExpression t1 = term();
1095 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1096 t = to(F.at(pos).Indexed(t, t1));
1097 }
1098 accept(RBRACKET);
1099 }
1100 break loop;
1101 case LPAREN:
1102 if ((mode & EXPR) != 0) {
1103 mode = EXPR;
1104 t = arguments(typeArgs, t);
1105 typeArgs = null;
1106 }
1107 break loop;
1108 case DOT:
1109 S.nextToken();
1110 int oldmode = mode;
1111 mode &= ~NOPARAMS;
1112 typeArgs = typeArgumentsOpt(EXPR);
1113 mode = oldmode;
1114 if ((mode & EXPR) != 0) {
1115 switch (S.token()) {
1116 case CLASS:
1117 if (typeArgs != null) return illegal();
1118 mode = EXPR;
1119 t = to(F.at(pos).Select(t, names._class));
1120 S.nextToken();
1121 break loop;
1122 case THIS:
1123 if (typeArgs != null) return illegal();
1124 mode = EXPR;
1125 t = to(F.at(pos).Select(t, names._this));
1126 S.nextToken();
1127 break loop;
1128 case SUPER:
1129 mode = EXPR;
1130 t = to(F.at(pos).Select(t, names._super));
1131 t = superSuffix(typeArgs, t);
1132 typeArgs = null;
1133 break loop;
1134 case NEW:
1135 if (typeArgs != null) return illegal();
1136 mode = EXPR;
1137 int pos1 = S.pos();
1138 S.nextToken();
1139 if (S.token() == LT) typeArgs = typeArguments();
1140 t = innerCreator(pos1, typeArgs, t);
1141 typeArgs = null;
1142 break loop;
1143 }
1144 }
1145 // typeArgs saved for next loop iteration.
1146 t = toP(F.at(pos).Select(t, ident()));
1147 break;
1148 case ELLIPSIS:
1149 assert this.permitTypeAnnotationsPushBack;
1150 typeAnnotationsPushedBack = annos;
1151 break loop;
1152 default:
1153 break loop;
1154 }
1155 }
1156 if (typeArgs != null) illegal();
1157 t = typeArgumentsOpt(t);
1158 break;
1159 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1160 case DOUBLE: case BOOLEAN:
1161 if (typeArgs != null) illegal();
1162 t = bracketsSuffix(bracketsOpt(basicType()));
1163 break;
1164 case VOID:
1165 if (typeArgs != null) illegal();
1166 if ((mode & EXPR) != 0) {
1167 S.nextToken();
1168 if (S.token() == DOT) {
1169 JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID));
1170 t = bracketsSuffix(ti);
1171 } else {
1172 return illegal(pos);
1173 }
1174 } else {
1175 // Support the corner case of myMethodHandle.<void>invoke() by passing
1176 // a void type (like other primitive types) to the next phase.
1177 // The error will be reported in Attr.attribTypes or Attr.visitApply.
1178 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID));
1179 S.nextToken();
1180 return ti;
1181 //return illegal();
1182 }
1183 break;
1184 default:
1185 return illegal();
1186 }
1187 if (typeArgs != null) illegal();
1188 while (true) {
1189 int pos1 = S.pos();
1191 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1193 if (S.token() == LBRACKET) {
1194 S.nextToken();
1196 if ((mode & TYPE) != 0) {
1197 int oldmode = mode;
1198 mode = TYPE;
1199 if (S.token() == RBRACKET) {
1200 S.nextToken();
1201 t = bracketsOpt(t, annos);
1202 t = toP(F.at(pos1).TypeArray(t));
1203 return t;
1204 }
1205 mode = oldmode;
1206 }
1207 if ((mode & EXPR) != 0) {
1208 mode = EXPR;
1209 JCExpression t1 = term();
1210 t = to(F.at(pos1).Indexed(t, t1));
1211 }
1212 accept(RBRACKET);
1213 } else if (S.token() == DOT) {
1214 S.nextToken();
1215 typeArgs = typeArgumentsOpt(EXPR);
1216 if (S.token() == SUPER && (mode & EXPR) != 0) {
1217 mode = EXPR;
1218 t = to(F.at(pos1).Select(t, names._super));
1219 S.nextToken();
1220 t = arguments(typeArgs, t);
1221 typeArgs = null;
1222 } else if (S.token() == NEW && (mode & EXPR) != 0) {
1223 if (typeArgs != null) return illegal();
1224 mode = EXPR;
1225 int pos2 = S.pos();
1226 S.nextToken();
1227 if (S.token() == LT) typeArgs = typeArguments();
1228 t = innerCreator(pos2, typeArgs, t);
1229 typeArgs = null;
1230 } else {
1231 t = toP(F.at(pos1).Select(t, ident()));
1232 t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1233 typeArgs = null;
1234 }
1235 } else {
1236 if (!annos.isEmpty()) {
1237 if (permitTypeAnnotationsPushBack)
1238 typeAnnotationsPushedBack = annos;
1239 else
1240 return illegal(annos.head.pos);
1241 }
1242 break;
1243 }
1244 }
1245 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
1246 mode = EXPR;
1247 t = to(F.at(S.pos()).Unary(
1248 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1249 S.nextToken();
1250 }
1252 return toP(t);
1253 }
1255 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1256 */
1257 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1258 S.nextToken();
1259 if (S.token() == LPAREN || typeArgs != null) {
1260 t = arguments(typeArgs, t);
1261 } else {
1262 int pos = S.pos();
1263 accept(DOT);
1264 typeArgs = (S.token() == LT) ? typeArguments() : null;
1265 t = toP(F.at(pos).Select(t, ident()));
1266 t = argumentsOpt(typeArgs, t);
1267 }
1268 return t;
1269 }
1271 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1272 */
1273 JCPrimitiveTypeTree basicType() {
1274 JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
1275 S.nextToken();
1276 return t;
1277 }
1279 /** ArgumentsOpt = [ Arguments ]
1280 */
1281 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1282 if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
1283 mode = EXPR;
1284 return arguments(typeArgs, t);
1285 } else {
1286 return t;
1287 }
1288 }
1290 /** Arguments = "(" [Expression { COMMA Expression }] ")"
1291 */
1292 List<JCExpression> arguments() {
1293 ListBuffer<JCExpression> args = lb();
1294 if (S.token() == LPAREN) {
1295 S.nextToken();
1296 if (S.token() != RPAREN) {
1297 args.append(parseExpression());
1298 while (S.token() == COMMA) {
1299 S.nextToken();
1300 args.append(parseExpression());
1301 }
1302 }
1303 accept(RPAREN);
1304 } else {
1305 syntaxError(S.pos(), "expected", LPAREN);
1306 }
1307 return args.toList();
1308 }
1310 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1311 int pos = S.pos();
1312 List<JCExpression> args = arguments();
1313 return toP(F.at(pos).Apply(typeArgs, t, args));
1314 }
1316 /** TypeArgumentsOpt = [ TypeArguments ]
1317 */
1318 JCExpression typeArgumentsOpt(JCExpression t) {
1319 if (S.token() == LT &&
1320 (mode & TYPE) != 0 &&
1321 (mode & NOPARAMS) == 0) {
1322 mode = TYPE;
1323 checkGenerics();
1324 return typeArguments(t);
1325 } else {
1326 return t;
1327 }
1328 }
1329 List<JCExpression> typeArgumentsOpt() {
1330 return typeArgumentsOpt(TYPE);
1331 }
1333 List<JCExpression> typeArgumentsOpt(int useMode) {
1334 if (S.token() == LT) {
1335 checkGenerics();
1336 if ((mode & useMode) == 0 ||
1337 (mode & NOPARAMS) != 0) {
1338 illegal();
1339 }
1340 mode = useMode;
1341 return typeArguments();
1342 }
1343 return null;
1344 }
1346 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">"
1347 */
1348 List<JCExpression> typeArguments() {
1349 ListBuffer<JCExpression> args = lb();
1350 if (S.token() == LT) {
1351 S.nextToken();
1352 if (S.token() == GT && (mode & DIAMOND) != 0) {
1353 checkDiamond();
1354 S.nextToken();
1355 return List.nil();
1356 }
1357 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1358 while (S.token() == COMMA) {
1359 S.nextToken();
1360 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1361 }
1362 switch (S.token()) {
1363 case GTGTGTEQ:
1364 S.token(GTGTEQ);
1365 break;
1366 case GTGTEQ:
1367 S.token(GTEQ);
1368 break;
1369 case GTEQ:
1370 S.token(EQ);
1371 break;
1372 case GTGTGT:
1373 S.token(GTGT);
1374 break;
1375 case GTGT:
1376 S.token(GT);
1377 break;
1378 default:
1379 accept(GT);
1380 break;
1381 }
1382 } else {
1383 syntaxError(S.pos(), "expected", LT);
1384 }
1385 return args.toList();
1386 }
1388 /** TypeArgument = Type
1389 * | [Annotations] "?"
1390 * | [Annotations] "?" EXTENDS Type {"&" Type}
1391 * | [Annotations] "?" SUPER Type
1392 */
1393 JCExpression typeArgument() {
1394 List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
1395 if (S.token() != QUES) return parseType(annotations);
1396 int pos = S.pos();
1397 S.nextToken();
1398 JCExpression result;
1399 if (S.token() == EXTENDS) {
1400 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS));
1401 S.nextToken();
1402 JCExpression bound = parseType();
1403 result = F.at(pos).Wildcard(t, bound);
1404 } else if (S.token() == SUPER) {
1405 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER));
1406 S.nextToken();
1407 JCExpression bound = parseType();
1408 result = F.at(pos).Wildcard(t, bound);
1409 } else if (S.token() == IDENTIFIER) {
1410 //error recovery
1411 reportSyntaxError(S.prevEndPos(), "expected3",
1412 GT, EXTENDS, SUPER);
1413 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1414 JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1415 JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1416 result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1417 } else {
1418 TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
1419 result = toP(F.at(pos).Wildcard(t, null));
1420 }
1421 if (!annotations.isEmpty())
1422 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1423 return result;
1424 }
1426 JCTypeApply typeArguments(JCExpression t) {
1427 int pos = S.pos();
1428 List<JCExpression> args = typeArguments();
1429 return toP(F.at(pos).TypeApply(t, args));
1430 }
1432 /**
1433 * BracketsOpt = { [Annotations] "[" "]" }
1434 *
1435 * <p>
1436 *
1437 * <code>annotations</code> is the list of annotations targeting
1438 * the expression <code>t</code>.
1439 */
1440 private JCExpression bracketsOpt(JCExpression t,
1441 List<JCTypeAnnotation> annotations) {
1442 List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1444 if (S.token() == LBRACKET) {
1445 int pos = S.pos();
1446 S.nextToken();
1448 JCExpression orig = t;
1449 t = bracketsOptCont(t, pos, nextLevelAnnotations);
1450 } else if (!nextLevelAnnotations.isEmpty()) {
1451 if (permitTypeAnnotationsPushBack) {
1452 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1453 } else
1454 return illegal(nextLevelAnnotations.head.pos);
1455 }
1457 int apos = S.pos();
1458 if (!annotations.isEmpty())
1459 t = F.at(apos).AnnotatedType(annotations, t);
1460 return t;
1461 }
1463 /** BracketsOpt = {"[" TypeAnnotations "]"}
1464 */
1465 private JCExpression bracketsOpt(JCExpression t) {
1466 return bracketsOpt(t, List.<JCTypeAnnotation>nil());
1467 }
1469 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
1470 List<JCTypeAnnotation> annotations) {
1471 accept(RBRACKET);
1472 t = bracketsOpt(t, annotations);
1473 return toP(F.at(pos).TypeArray(t));
1474 }
1476 /** BracketsSuffixExpr = "." CLASS
1477 * BracketsSuffixType =
1478 */
1479 JCExpression bracketsSuffix(JCExpression t) {
1480 if ((mode & EXPR) != 0 && S.token() == DOT) {
1481 mode = EXPR;
1482 int pos = S.pos();
1483 S.nextToken();
1484 accept(CLASS);
1485 if (S.pos() == errorEndPos) {
1486 // error recovery
1487 Name name = null;
1488 if (S.token() == IDENTIFIER) {
1489 name = S.name();
1490 S.nextToken();
1491 } else {
1492 name = names.error;
1493 }
1494 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
1495 } else {
1496 t = toP(F.at(pos).Select(t, names._class));
1497 }
1498 } else if ((mode & TYPE) != 0) {
1499 mode = TYPE;
1500 } else {
1501 syntaxError(S.pos(), "dot.class.expected");
1502 }
1503 return t;
1504 }
1506 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1507 */
1508 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1510 List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
1512 switch (S.token()) {
1513 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1514 case DOUBLE: case BOOLEAN:
1515 if (typeArgs == null) {
1516 if (newAnnotations.isEmpty())
1517 return arrayCreatorRest(newpos, basicType());
1518 else
1519 return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
1520 }
1521 break;
1522 default:
1523 }
1524 JCExpression t = qualident();
1525 // handle type annotations for non primitive arrays
1526 if (!newAnnotations.isEmpty())
1527 t = F.AnnotatedType(newAnnotations, t);
1529 int oldmode = mode;
1530 mode = TYPE | DIAMOND;
1531 if (S.token() == LT) {
1532 checkGenerics();
1533 t = typeArguments(t);
1534 }
1535 while (S.token() == DOT) {
1536 int pos = S.pos();
1537 S.nextToken();
1538 t = toP(F.at(pos).Select(t, ident()));
1539 if (S.token() == LT) {
1540 checkGenerics();
1541 t = typeArguments(t);
1542 }
1543 }
1544 mode = oldmode;
1545 if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
1546 JCExpression e = arrayCreatorRest(newpos, t);
1547 if (typeArgs != null) {
1548 int pos = newpos;
1549 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
1550 // note: this should always happen but we should
1551 // not rely on this as the parser is continuously
1552 // modified to improve error recovery.
1553 pos = typeArgs.head.pos;
1554 }
1555 setErrorEndPos(S.prevEndPos());
1556 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
1557 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1558 }
1559 return e;
1560 } else if (S.token() == LPAREN) {
1561 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
1562 if (newClass.def != null) {
1563 assert newClass.def.mods.annotations.isEmpty();
1564 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
1565 }
1566 return newClass;
1567 } else {
1568 reportSyntaxError(S.pos(), "expected2",
1569 LPAREN, LBRACKET);
1570 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
1571 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
1572 }
1573 }
1575 /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
1576 */
1577 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
1578 JCExpression t = toP(F.at(S.pos()).Ident(ident()));
1579 if (S.token() == LT) {
1580 int oldmode = mode;
1581 mode |= DIAMOND;
1582 checkGenerics();
1583 t = typeArguments(t);
1584 mode = oldmode;
1585 }
1586 return classCreatorRest(newpos, encl, typeArgs, t);
1587 }
1589 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
1590 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
1591 */
1592 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1594 List<JCTypeAnnotation> topAnnos = List.nil();
1595 if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
1596 JCAnnotatedType atype = (JCAnnotatedType) elemtype;
1597 topAnnos = atype.annotations;
1598 elemtype = atype.underlyingType;
1599 }
1601 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1603 accept(LBRACKET);
1605 if (S.token() == RBRACKET) {
1606 accept(RBRACKET);
1608 elemtype = bracketsOpt(elemtype, annos);
1610 if (S.token() == LBRACE) {
1611 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
1613 na.annotations = topAnnos;
1615 return na;
1616 } else {
1617 return syntaxError(S.pos(), "array.dimension.missing");
1618 }
1619 } else {
1620 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1622 // maintain array dimension type annotations
1623 ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
1624 dimAnnotations.append(annos);
1626 dims.append(parseExpression());
1627 accept(RBRACKET);
1628 while (S.token() == LBRACKET
1629 || (S.token() == MONKEYS_AT)) {
1630 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
1631 int pos = S.pos();
1632 S.nextToken();
1633 if (S.token() == RBRACKET) {
1634 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1635 } else {
1636 if (S.token() == RBRACKET) { // no dimension
1637 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1638 } else {
1639 dimAnnotations.append(maybeDimAnnos);
1640 dims.append(parseExpression());
1641 accept(RBRACKET);
1642 }
1643 }
1644 }
1646 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
1647 na.annotations = topAnnos;
1648 na.dimAnnotations = dimAnnotations.toList();
1649 return na;
1650 }
1651 }
1653 /** ClassCreatorRest = Arguments [ClassBody]
1654 */
1655 JCNewClass classCreatorRest(int newpos,
1656 JCExpression encl,
1657 List<JCExpression> typeArgs,
1658 JCExpression t)
1659 {
1660 List<JCExpression> args = arguments();
1661 JCClassDecl body = null;
1662 if (S.token() == LBRACE) {
1663 int pos = S.pos();
1664 List<JCTree> defs = classOrInterfaceBody(names.empty, false);
1665 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1666 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
1667 }
1668 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
1669 }
1671 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
1672 */
1673 JCExpression arrayInitializer(int newpos, JCExpression t) {
1674 accept(LBRACE);
1675 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
1676 if (S.token() == COMMA) {
1677 S.nextToken();
1678 } else if (S.token() != RBRACE) {
1679 elems.append(variableInitializer());
1680 while (S.token() == COMMA) {
1681 S.nextToken();
1682 if (S.token() == RBRACE) break;
1683 elems.append(variableInitializer());
1684 }
1685 }
1686 accept(RBRACE);
1687 return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
1688 }
1690 /** VariableInitializer = ArrayInitializer | Expression
1691 */
1692 public JCExpression variableInitializer() {
1693 return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
1694 }
1696 /** ParExpression = "(" Expression ")"
1697 */
1698 JCExpression parExpression() {
1699 accept(LPAREN);
1700 JCExpression t = parseExpression();
1701 accept(RPAREN);
1702 return t;
1703 }
1705 /** Block = "{" BlockStatements "}"
1706 */
1707 JCBlock block(int pos, long flags) {
1708 accept(LBRACE);
1709 List<JCStatement> stats = blockStatements();
1710 JCBlock t = F.at(pos).Block(flags, stats);
1711 while (S.token() == CASE || S.token() == DEFAULT) {
1712 syntaxError("orphaned", S.token());
1713 switchBlockStatementGroups();
1714 }
1715 // the Block node has a field "endpos" for first char of last token, which is
1716 // usually but not necessarily the last char of the last token.
1717 t.endpos = S.pos();
1718 accept(RBRACE);
1719 return toP(t);
1720 }
1722 public JCBlock block() {
1723 return block(S.pos(), 0);
1724 }
1726 /** BlockStatements = { BlockStatement }
1727 * BlockStatement = LocalVariableDeclarationStatement
1728 * | ClassOrInterfaceOrEnumDeclaration
1729 * | [Ident ":"] Statement
1730 * LocalVariableDeclarationStatement
1731 * = { FINAL | '@' Annotation } Type VariableDeclarators ";"
1732 */
1733 @SuppressWarnings("fallthrough")
1734 List<JCStatement> blockStatements() {
1735 //todo: skip to anchor on error(?)
1736 int lastErrPos = -1;
1737 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1738 while (true) {
1739 int pos = S.pos();
1740 switch (S.token()) {
1741 case RBRACE: case CASE: case DEFAULT: case EOF:
1742 return stats.toList();
1743 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
1744 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
1745 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
1746 stats.append(parseStatement());
1747 break;
1748 case MONKEYS_AT:
1749 case FINAL: {
1750 String dc = S.docComment();
1751 JCModifiers mods = modifiersOpt();
1752 if (S.token() == INTERFACE ||
1753 S.token() == CLASS ||
1754 allowEnums && S.token() == ENUM) {
1755 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1756 } else {
1757 JCExpression t = parseType();
1758 stats.appendList(variableDeclarators(mods, t,
1759 new ListBuffer<JCStatement>()));
1760 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1761 storeEnd(stats.elems.last(), S.endPos());
1762 accept(SEMI);
1763 }
1764 break;
1765 }
1766 case ABSTRACT: case STRICTFP: {
1767 String dc = S.docComment();
1768 JCModifiers mods = modifiersOpt();
1769 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1770 break;
1771 }
1772 case INTERFACE:
1773 case CLASS:
1774 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1775 S.docComment()));
1776 break;
1777 case ENUM:
1778 case ASSERT:
1779 if (allowEnums && S.token() == ENUM) {
1780 log.error(S.pos(), "local.enum");
1781 stats.
1782 append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1783 S.docComment()));
1784 break;
1785 } else if (allowAsserts && S.token() == ASSERT) {
1786 stats.append(parseStatement());
1787 break;
1788 }
1789 /* fall through to default */
1790 default:
1791 Name name = S.name();
1792 JCExpression t = term(EXPR | TYPE);
1793 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
1794 S.nextToken();
1795 JCStatement stat = parseStatement();
1796 stats.append(F.at(pos).Labelled(name, stat));
1797 } else if ((lastmode & TYPE) != 0 &&
1798 (S.token() == IDENTIFIER ||
1799 S.token() == ASSERT ||
1800 S.token() == ENUM)) {
1801 pos = S.pos();
1802 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1803 F.at(pos);
1804 stats.appendList(variableDeclarators(mods, t,
1805 new ListBuffer<JCStatement>()));
1806 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1807 storeEnd(stats.elems.last(), S.endPos());
1808 accept(SEMI);
1809 } else {
1810 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1811 stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1812 accept(SEMI);
1813 }
1814 }
1816 // error recovery
1817 if (S.pos() == lastErrPos)
1818 return stats.toList();
1819 if (S.pos() <= errorEndPos) {
1820 skip(false, true, true, true);
1821 lastErrPos = S.pos();
1822 }
1824 // ensure no dangling /** @deprecated */ active
1825 S.resetDeprecatedFlag();
1826 }
1827 }
1829 /** Statement =
1830 * Block
1831 * | IF ParExpression Statement [ELSE Statement]
1832 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1833 * | FOR "(" FormalParameter : Expression ")" Statement
1834 * | WHILE ParExpression Statement
1835 * | DO Statement WHILE ParExpression ";"
1836 * | TRY Block ( Catches | [Catches] FinallyPart )
1837 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1838 * | SYNCHRONIZED ParExpression Block
1839 * | RETURN [Expression] ";"
1840 * | THROW Expression ";"
1841 * | BREAK [Ident] ";"
1842 * | CONTINUE [Ident] ";"
1843 * | ASSERT Expression [ ":" Expression ] ";"
1844 * | ";"
1845 * | ExpressionStatement
1846 * | Ident ":" Statement
1847 */
1848 @SuppressWarnings("fallthrough")
1849 public JCStatement parseStatement() {
1850 int pos = S.pos();
1851 switch (S.token()) {
1852 case LBRACE:
1853 return block();
1854 case IF: {
1855 S.nextToken();
1856 JCExpression cond = parExpression();
1857 JCStatement thenpart = parseStatement();
1858 JCStatement elsepart = null;
1859 if (S.token() == ELSE) {
1860 S.nextToken();
1861 elsepart = parseStatement();
1862 }
1863 return F.at(pos).If(cond, thenpart, elsepart);
1864 }
1865 case FOR: {
1866 S.nextToken();
1867 accept(LPAREN);
1868 List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
1869 if (inits.length() == 1 &&
1870 inits.head.getTag() == JCTree.VARDEF &&
1871 ((JCVariableDecl) inits.head).init == null &&
1872 S.token() == COLON) {
1873 checkForeach();
1874 JCVariableDecl var = (JCVariableDecl)inits.head;
1875 accept(COLON);
1876 JCExpression expr = parseExpression();
1877 accept(RPAREN);
1878 JCStatement body = parseStatement();
1879 return F.at(pos).ForeachLoop(var, expr, body);
1880 } else {
1881 accept(SEMI);
1882 JCExpression cond = S.token() == SEMI ? null : parseExpression();
1883 accept(SEMI);
1884 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1885 accept(RPAREN);
1886 JCStatement body = parseStatement();
1887 return F.at(pos).ForLoop(inits, cond, steps, body);
1888 }
1889 }
1890 case WHILE: {
1891 S.nextToken();
1892 JCExpression cond = parExpression();
1893 JCStatement body = parseStatement();
1894 return F.at(pos).WhileLoop(cond, body);
1895 }
1896 case DO: {
1897 S.nextToken();
1898 JCStatement body = parseStatement();
1899 accept(WHILE);
1900 JCExpression cond = parExpression();
1901 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1902 accept(SEMI);
1903 return t;
1904 }
1905 case TRY: {
1906 S.nextToken();
1907 JCBlock body = block();
1908 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1909 JCBlock finalizer = null;
1910 if (S.token() == CATCH || S.token() == FINALLY) {
1911 while (S.token() == CATCH) catchers.append(catchClause());
1912 if (S.token() == FINALLY) {
1913 S.nextToken();
1914 finalizer = block();
1915 }
1916 } else {
1917 log.error(pos, "try.without.catch.or.finally");
1918 }
1919 return F.at(pos).Try(body, catchers.toList(), finalizer);
1920 }
1921 case SWITCH: {
1922 S.nextToken();
1923 JCExpression selector = parExpression();
1924 accept(LBRACE);
1925 List<JCCase> cases = switchBlockStatementGroups();
1926 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1927 accept(RBRACE);
1928 return t;
1929 }
1930 case SYNCHRONIZED: {
1931 S.nextToken();
1932 JCExpression lock = parExpression();
1933 JCBlock body = block();
1934 return F.at(pos).Synchronized(lock, body);
1935 }
1936 case RETURN: {
1937 S.nextToken();
1938 JCExpression result = S.token() == SEMI ? null : parseExpression();
1939 JCReturn t = to(F.at(pos).Return(result));
1940 accept(SEMI);
1941 return t;
1942 }
1943 case THROW: {
1944 S.nextToken();
1945 JCExpression exc = parseExpression();
1946 JCThrow t = to(F.at(pos).Throw(exc));
1947 accept(SEMI);
1948 return t;
1949 }
1950 case BREAK: {
1951 S.nextToken();
1952 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1953 JCBreak t = to(F.at(pos).Break(label));
1954 accept(SEMI);
1955 return t;
1956 }
1957 case CONTINUE: {
1958 S.nextToken();
1959 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1960 JCContinue t = to(F.at(pos).Continue(label));
1961 accept(SEMI);
1962 return t;
1963 }
1964 case SEMI:
1965 S.nextToken();
1966 return toP(F.at(pos).Skip());
1967 case ELSE:
1968 return toP(F.Exec(syntaxError("else.without.if")));
1969 case FINALLY:
1970 return toP(F.Exec(syntaxError("finally.without.try")));
1971 case CATCH:
1972 return toP(F.Exec(syntaxError("catch.without.try")));
1973 case ASSERT: {
1974 if (allowAsserts && S.token() == ASSERT) {
1975 S.nextToken();
1976 JCExpression assertion = parseExpression();
1977 JCExpression message = null;
1978 if (S.token() == COLON) {
1979 S.nextToken();
1980 message = parseExpression();
1981 }
1982 JCAssert t = to(F.at(pos).Assert(assertion, message));
1983 accept(SEMI);
1984 return t;
1985 }
1986 /* else fall through to default case */
1987 }
1988 case ENUM:
1989 default:
1990 Name name = S.name();
1991 JCExpression expr = parseExpression();
1992 if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
1993 S.nextToken();
1994 JCStatement stat = parseStatement();
1995 return F.at(pos).Labelled(name, stat);
1996 } else {
1997 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1998 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1999 accept(SEMI);
2000 return stat;
2001 }
2002 }
2003 }
2005 /** CatchClause = CATCH "(" FormalParameter ")" Block
2006 */
2007 JCCatch catchClause() {
2008 int pos = S.pos();
2009 accept(CATCH);
2010 accept(LPAREN);
2011 JCVariableDecl formal =
2012 variableDeclaratorId(optFinal(Flags.PARAMETER),
2013 qualident());
2014 accept(RPAREN);
2015 JCBlock body = block();
2016 return F.at(pos).Catch(formal, body);
2017 }
2019 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
2020 * SwitchBlockStatementGroup = SwitchLabel BlockStatements
2021 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
2022 */
2023 List<JCCase> switchBlockStatementGroups() {
2024 ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
2025 while (true) {
2026 int pos = S.pos();
2027 switch (S.token()) {
2028 case CASE: {
2029 S.nextToken();
2030 JCExpression pat = parseExpression();
2031 accept(COLON);
2032 List<JCStatement> stats = blockStatements();
2033 JCCase c = F.at(pos).Case(pat, stats);
2034 if (stats.isEmpty())
2035 storeEnd(c, S.prevEndPos());
2036 cases.append(c);
2037 break;
2038 }
2039 case DEFAULT: {
2040 S.nextToken();
2041 accept(COLON);
2042 List<JCStatement> stats = blockStatements();
2043 JCCase c = F.at(pos).Case(null, stats);
2044 if (stats.isEmpty())
2045 storeEnd(c, S.prevEndPos());
2046 cases.append(c);
2047 break;
2048 }
2049 case RBRACE: case EOF:
2050 return cases.toList();
2051 default:
2052 S.nextToken(); // to ensure progress
2053 syntaxError(pos, "expected3",
2054 CASE, DEFAULT, RBRACE);
2055 }
2056 }
2057 }
2059 /** MoreStatementExpressions = { COMMA StatementExpression }
2060 */
2061 <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2062 JCExpression first,
2063 T stats) {
2064 // This Exec is a "StatementExpression"; it subsumes no terminating token
2065 stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2066 while (S.token() == COMMA) {
2067 S.nextToken();
2068 pos = S.pos();
2069 JCExpression t = parseExpression();
2070 // This Exec is a "StatementExpression"; it subsumes no terminating token
2071 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2072 }
2073 return stats;
2074 }
2076 /** ForInit = StatementExpression MoreStatementExpressions
2077 * | { FINAL | '@' Annotation } Type VariableDeclarators
2078 */
2079 List<JCStatement> forInit() {
2080 ListBuffer<JCStatement> stats = lb();
2081 int pos = S.pos();
2082 if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2083 return variableDeclarators(optFinal(0), parseType(), stats).toList();
2084 } else {
2085 JCExpression t = term(EXPR | TYPE);
2086 if ((lastmode & TYPE) != 0 &&
2087 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
2088 return variableDeclarators(modifiersOpt(), t, stats).toList();
2089 else
2090 return moreStatementExpressions(pos, t, stats).toList();
2091 }
2092 }
2094 /** ForUpdate = StatementExpression MoreStatementExpressions
2095 */
2096 List<JCExpressionStatement> forUpdate() {
2097 return moreStatementExpressions(S.pos(),
2098 parseExpression(),
2099 new ListBuffer<JCExpressionStatement>()).toList();
2100 }
2102 enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
2104 /** AnnotationsOpt = { '@' Annotation }
2105 */
2106 List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
2107 if (S.token() != MONKEYS_AT) return List.nil(); // optimization
2108 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2109 int prevmode = mode;
2110 while (S.token() == MONKEYS_AT) {
2111 int pos = S.pos();
2112 S.nextToken();
2113 buf.append(annotation(pos, kind));
2114 }
2115 lastmode = mode;
2116 mode = prevmode;
2117 List<JCAnnotation> annotations = buf.toList();
2119 if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
2120 System.out.println("TA: parsing " + annotations
2121 + " in " + log.currentSourceFile());
2122 return annotations;
2123 }
2125 List<JCTypeAnnotation> typeAnnotationsOpt() {
2126 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
2127 return List.convert(JCTypeAnnotation.class, annotations);
2128 }
2130 /** ModifiersOpt = { Modifier }
2131 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2132 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2133 * | "@" Annotation
2134 */
2135 JCModifiers modifiersOpt() {
2136 return modifiersOpt(null);
2137 }
2138 JCModifiers modifiersOpt(JCModifiers partial) {
2139 long flags;
2140 ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2141 int pos;
2142 if (partial == null) {
2143 flags = 0;
2144 pos = S.pos();
2145 } else {
2146 flags = partial.flags;
2147 annotations.appendList(partial.annotations);
2148 pos = partial.pos;
2149 }
2150 if (S.deprecatedFlag()) {
2151 flags |= Flags.DEPRECATED;
2152 S.resetDeprecatedFlag();
2153 }
2154 int lastPos = Position.NOPOS;
2155 loop:
2156 while (true) {
2157 long flag;
2158 switch (S.token()) {
2159 case PRIVATE : flag = Flags.PRIVATE; break;
2160 case PROTECTED : flag = Flags.PROTECTED; break;
2161 case PUBLIC : flag = Flags.PUBLIC; break;
2162 case STATIC : flag = Flags.STATIC; break;
2163 case TRANSIENT : flag = Flags.TRANSIENT; break;
2164 case FINAL : flag = Flags.FINAL; break;
2165 case ABSTRACT : flag = Flags.ABSTRACT; break;
2166 case NATIVE : flag = Flags.NATIVE; break;
2167 case VOLATILE : flag = Flags.VOLATILE; break;
2168 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2169 case STRICTFP : flag = Flags.STRICTFP; break;
2170 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
2171 default: break loop;
2172 }
2173 if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
2174 lastPos = S.pos();
2175 S.nextToken();
2176 if (flag == Flags.ANNOTATION) {
2177 checkAnnotations();
2178 if (S.token() != INTERFACE) {
2179 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
2180 // if first modifier is an annotation, set pos to annotation's.
2181 if (flags == 0 && annotations.isEmpty())
2182 pos = ann.pos;
2183 annotations.append(ann);
2184 lastPos = ann.pos;
2185 flag = 0;
2186 }
2187 }
2188 flags |= flag;
2189 }
2190 switch (S.token()) {
2191 case ENUM: flags |= Flags.ENUM; break;
2192 case INTERFACE: flags |= Flags.INTERFACE; break;
2193 default: break;
2194 }
2196 /* A modifiers tree with no modifier tokens or annotations
2197 * has no text position. */
2198 if ((flags & Flags.ModifierFlags) == 0 && annotations.isEmpty())
2199 pos = Position.NOPOS;
2201 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2202 if (pos != Position.NOPOS)
2203 storeEnd(mods, S.prevEndPos());
2204 return mods;
2205 }
2207 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2208 * @param pos position of "@" token
2209 */
2210 JCAnnotation annotation(int pos, AnnotationKind kind) {
2211 // accept(AT); // AT consumed by caller
2212 checkAnnotations();
2213 if (kind == AnnotationKind.TYPE_ANNO)
2214 checkTypeAnnotations();
2215 JCTree ident = qualident();
2216 List<JCExpression> fieldValues = annotationFieldValuesOpt();
2217 JCAnnotation ann;
2218 if (kind == AnnotationKind.DEFAULT_ANNO)
2219 ann = F.at(pos).Annotation(ident, fieldValues);
2220 else
2221 ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2222 storeEnd(ann, S.prevEndPos());
2223 return ann;
2224 }
2226 List<JCExpression> annotationFieldValuesOpt() {
2227 return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2228 }
2230 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2231 List<JCExpression> annotationFieldValues() {
2232 accept(LPAREN);
2233 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2234 if (S.token() != RPAREN) {
2235 buf.append(annotationFieldValue());
2236 while (S.token() == COMMA) {
2237 S.nextToken();
2238 buf.append(annotationFieldValue());
2239 }
2240 }
2241 accept(RPAREN);
2242 return buf.toList();
2243 }
2245 /** AnnotationFieldValue = AnnotationValue
2246 * | Identifier "=" AnnotationValue
2247 */
2248 JCExpression annotationFieldValue() {
2249 if (S.token() == IDENTIFIER) {
2250 mode = EXPR;
2251 JCExpression t1 = term1();
2252 if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
2253 int pos = S.pos();
2254 accept(EQ);
2255 JCExpression v = annotationValue();
2256 return toP(F.at(pos).Assign(t1, v));
2257 } else {
2258 return t1;
2259 }
2260 }
2261 return annotationValue();
2262 }
2264 /* AnnotationValue = ConditionalExpression
2265 * | Annotation
2266 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2267 */
2268 JCExpression annotationValue() {
2269 int pos;
2270 switch (S.token()) {
2271 case MONKEYS_AT:
2272 pos = S.pos();
2273 S.nextToken();
2274 return annotation(pos, AnnotationKind.DEFAULT_ANNO);
2275 case LBRACE:
2276 pos = S.pos();
2277 accept(LBRACE);
2278 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2279 if (S.token() != RBRACE) {
2280 buf.append(annotationValue());
2281 while (S.token() == COMMA) {
2282 S.nextToken();
2283 if (S.token() == RBRACE) break;
2284 buf.append(annotationValue());
2285 }
2286 }
2287 accept(RBRACE);
2288 return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2289 default:
2290 mode = EXPR;
2291 return term1();
2292 }
2293 }
2295 /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2296 */
2297 public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2298 JCExpression type,
2299 T vdefs)
2300 {
2301 return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
2302 }
2304 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2305 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2306 *
2307 * @param reqInit Is an initializer always required?
2308 * @param dc The documentation comment for the variable declarations, or null.
2309 */
2310 <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2311 JCModifiers mods,
2312 JCExpression type,
2313 Name name,
2314 boolean reqInit,
2315 String dc,
2316 T vdefs)
2317 {
2318 vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2319 while (S.token() == COMMA) {
2320 // All but last of multiple declarators subsume a comma
2321 storeEnd((JCTree)vdefs.elems.last(), S.endPos());
2322 S.nextToken();
2323 vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2324 }
2325 return vdefs;
2326 }
2328 /** VariableDeclarator = Ident VariableDeclaratorRest
2329 * ConstantDeclarator = Ident ConstantDeclaratorRest
2330 */
2331 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
2332 return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
2333 }
2335 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2336 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2337 *
2338 * @param reqInit Is an initializer always required?
2339 * @param dc The documentation comment for the variable declarations, or null.
2340 */
2341 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2342 boolean reqInit, String dc) {
2343 type = bracketsOpt(type);
2344 JCExpression init = null;
2345 if (S.token() == EQ) {
2346 S.nextToken();
2347 init = variableInitializer();
2348 }
2349 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2350 JCVariableDecl result =
2351 toP(F.at(pos).VarDef(mods, name, type, init));
2352 attach(result, dc);
2353 return result;
2354 }
2356 /** VariableDeclaratorId = Ident BracketsOpt
2357 */
2358 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2359 int pos = S.pos();
2360 Name name = ident();
2361 if ((mods.flags & Flags.VARARGS) == 0)
2362 type = bracketsOpt(type);
2363 return toP(F.at(pos).VarDef(mods, name, type, null));
2364 }
2366 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2367 */
2368 public JCTree.JCCompilationUnit parseCompilationUnit() {
2369 int pos = S.pos();
2370 JCExpression pid = null;
2371 String dc = S.docComment();
2372 JCModifiers mods = null;
2373 List<JCAnnotation> packageAnnotations = List.nil();
2374 if (S.token() == MONKEYS_AT)
2375 mods = modifiersOpt();
2377 if (S.token() == PACKAGE) {
2378 if (mods != null) {
2379 checkNoMods(mods.flags);
2380 packageAnnotations = mods.annotations;
2381 mods = null;
2382 }
2383 S.nextToken();
2384 pid = qualident();
2385 accept(SEMI);
2386 }
2387 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2388 boolean checkForImports = true;
2389 while (S.token() != EOF) {
2390 if (S.pos() <= errorEndPos) {
2391 // error recovery
2392 skip(checkForImports, false, false, false);
2393 if (S.token() == EOF)
2394 break;
2395 }
2396 if (checkForImports && mods == null && S.token() == IMPORT) {
2397 defs.append(importDeclaration());
2398 } else {
2399 JCTree def = typeDeclaration(mods);
2400 if (def instanceof JCExpressionStatement)
2401 def = ((JCExpressionStatement)def).expr;
2402 defs.append(def);
2403 if (def instanceof JCClassDecl)
2404 checkForImports = false;
2405 mods = null;
2406 }
2407 }
2408 JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
2409 attach(toplevel, dc);
2410 if (defs.elems.isEmpty())
2411 storeEnd(toplevel, S.prevEndPos());
2412 if (keepDocComments)
2413 toplevel.docComments = docComments;
2414 if (keepLineMap)
2415 toplevel.lineMap = S.getLineMap();
2416 return toplevel;
2417 }
2419 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2420 */
2421 JCTree importDeclaration() {
2422 int pos = S.pos();
2423 S.nextToken();
2424 boolean importStatic = false;
2425 if (S.token() == STATIC) {
2426 checkStaticImports();
2427 importStatic = true;
2428 S.nextToken();
2429 }
2430 JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
2431 do {
2432 int pos1 = S.pos();
2433 accept(DOT);
2434 if (S.token() == STAR) {
2435 pid = to(F.at(pos1).Select(pid, names.asterisk));
2436 S.nextToken();
2437 break;
2438 } else {
2439 pid = toP(F.at(pos1).Select(pid, ident()));
2440 }
2441 } while (S.token() == DOT);
2442 accept(SEMI);
2443 return toP(F.at(pos).Import(pid, importStatic));
2444 }
2446 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
2447 * | ";"
2448 */
2449 JCTree typeDeclaration(JCModifiers mods) {
2450 int pos = S.pos();
2451 if (mods == null && S.token() == SEMI) {
2452 S.nextToken();
2453 return toP(F.at(pos).Skip());
2454 } else {
2455 String dc = S.docComment();
2456 return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
2457 }
2458 }
2460 /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
2461 * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
2462 * @param mods Any modifiers starting the class or interface declaration
2463 * @param dc The documentation comment for the class, or null.
2464 */
2465 JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
2466 if (S.token() == CLASS) {
2467 return classDeclaration(mods, dc);
2468 } else if (S.token() == INTERFACE) {
2469 return interfaceDeclaration(mods, dc);
2470 } else if (allowEnums) {
2471 if (S.token() == ENUM) {
2472 return enumDeclaration(mods, dc);
2473 } else {
2474 int pos = S.pos();
2475 List<JCTree> errs;
2476 if (S.token() == IDENTIFIER) {
2477 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2478 setErrorEndPos(S.pos());
2479 } else {
2480 errs = List.<JCTree>of(mods);
2481 }
2482 return toP(F.Exec(syntaxError(pos, errs, "expected3",
2483 CLASS, INTERFACE, ENUM)));
2484 }
2485 } else {
2486 if (S.token() == ENUM) {
2487 log.error(S.pos(), "enums.not.supported.in.source", source.name);
2488 allowEnums = true;
2489 return enumDeclaration(mods, dc);
2490 }
2491 int pos = S.pos();
2492 List<JCTree> errs;
2493 if (S.token() == IDENTIFIER) {
2494 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2495 setErrorEndPos(S.pos());
2496 } else {
2497 errs = List.<JCTree>of(mods);
2498 }
2499 return toP(F.Exec(syntaxError(pos, errs, "expected2",
2500 CLASS, INTERFACE)));
2501 }
2502 }
2504 /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
2505 * [IMPLEMENTS TypeList] ClassBody
2506 * @param mods The modifiers starting the class declaration
2507 * @param dc The documentation comment for the class, or null.
2508 */
2509 JCClassDecl classDeclaration(JCModifiers mods, String dc) {
2510 int pos = S.pos();
2511 accept(CLASS);
2512 Name name = ident();
2514 List<JCTypeParameter> typarams = typeParametersOpt();
2516 JCTree extending = null;
2517 if (S.token() == EXTENDS) {
2518 S.nextToken();
2519 extending = parseType();
2520 }
2521 List<JCExpression> implementing = List.nil();
2522 if (S.token() == IMPLEMENTS) {
2523 S.nextToken();
2524 implementing = typeList();
2525 }
2526 List<JCTree> defs = classOrInterfaceBody(name, false);
2527 JCClassDecl result = toP(F.at(pos).ClassDef(
2528 mods, name, typarams, extending, implementing, defs));
2529 attach(result, dc);
2530 return result;
2531 }
2533 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
2534 * [EXTENDS TypeList] InterfaceBody
2535 * @param mods The modifiers starting the interface declaration
2536 * @param dc The documentation comment for the interface, or null.
2537 */
2538 JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
2539 int pos = S.pos();
2540 accept(INTERFACE);
2541 Name name = ident();
2543 List<JCTypeParameter> typarams = typeParametersOpt();
2545 List<JCExpression> extending = List.nil();
2546 if (S.token() == EXTENDS) {
2547 S.nextToken();
2548 extending = typeList();
2549 }
2550 List<JCTree> defs = classOrInterfaceBody(name, true);
2551 JCClassDecl result = toP(F.at(pos).ClassDef(
2552 mods, name, typarams, null, extending, defs));
2553 attach(result, dc);
2554 return result;
2555 }
2557 /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
2558 * @param mods The modifiers starting the enum declaration
2559 * @param dc The documentation comment for the enum, or null.
2560 */
2561 JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
2562 int pos = S.pos();
2563 accept(ENUM);
2564 Name name = ident();
2566 List<JCExpression> implementing = List.nil();
2567 if (S.token() == IMPLEMENTS) {
2568 S.nextToken();
2569 implementing = typeList();
2570 }
2572 List<JCTree> defs = enumBody(name);
2573 mods.flags |= Flags.ENUM;
2574 JCClassDecl result = toP(F.at(pos).
2575 ClassDef(mods, name, List.<JCTypeParameter>nil(),
2576 null, implementing, defs));
2577 attach(result, dc);
2578 return result;
2579 }
2581 /** EnumBody = "{" { EnumeratorDeclarationList } [","]
2582 * [ ";" {ClassBodyDeclaration} ] "}"
2583 */
2584 List<JCTree> enumBody(Name enumName) {
2585 accept(LBRACE);
2586 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2587 if (S.token() == COMMA) {
2588 S.nextToken();
2589 } else if (S.token() != RBRACE && S.token() != SEMI) {
2590 defs.append(enumeratorDeclaration(enumName));
2591 while (S.token() == COMMA) {
2592 S.nextToken();
2593 if (S.token() == RBRACE || S.token() == SEMI) break;
2594 defs.append(enumeratorDeclaration(enumName));
2595 }
2596 if (S.token() != SEMI && S.token() != RBRACE) {
2597 defs.append(syntaxError(S.pos(), "expected3",
2598 COMMA, RBRACE, SEMI));
2599 S.nextToken();
2600 }
2601 }
2602 if (S.token() == SEMI) {
2603 S.nextToken();
2604 while (S.token() != RBRACE && S.token() != EOF) {
2605 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
2606 false));
2607 if (S.pos() <= errorEndPos) {
2608 // error recovery
2609 skip(false, true, true, false);
2610 }
2611 }
2612 }
2613 accept(RBRACE);
2614 return defs.toList();
2615 }
2617 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
2618 */
2619 JCTree enumeratorDeclaration(Name enumName) {
2620 String dc = S.docComment();
2621 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
2622 if (S.deprecatedFlag()) {
2623 flags |= Flags.DEPRECATED;
2624 S.resetDeprecatedFlag();
2625 }
2626 int pos = S.pos();
2627 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2628 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
2629 List<JCExpression> typeArgs = typeArgumentsOpt();
2630 int identPos = S.pos();
2631 Name name = ident();
2632 int createPos = S.pos();
2633 List<JCExpression> args = (S.token() == LPAREN)
2634 ? arguments() : List.<JCExpression>nil();
2635 JCClassDecl body = null;
2636 if (S.token() == LBRACE) {
2637 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
2638 List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2639 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
2640 }
2641 if (args.isEmpty() && body == null)
2642 createPos = identPos;
2643 JCIdent ident = F.at(identPos).Ident(enumName);
2644 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
2645 if (createPos != identPos)
2646 storeEnd(create, S.prevEndPos());
2647 ident = F.at(identPos).Ident(enumName);
2648 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
2649 attach(result, dc);
2650 return result;
2651 }
2653 /** TypeList = Type {"," Type}
2654 */
2655 List<JCExpression> typeList() {
2656 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2657 ts.append(parseType());
2658 while (S.token() == COMMA) {
2659 S.nextToken();
2660 ts.append(parseType());
2661 }
2662 return ts.toList();
2663 }
2665 /** ClassBody = "{" {ClassBodyDeclaration} "}"
2666 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2667 */
2668 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
2669 accept(LBRACE);
2670 if (S.pos() <= errorEndPos) {
2671 // error recovery
2672 skip(false, true, false, false);
2673 if (S.token() == LBRACE)
2674 S.nextToken();
2675 }
2676 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2677 while (S.token() != RBRACE && S.token() != EOF) {
2678 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
2679 if (S.pos() <= errorEndPos) {
2680 // error recovery
2681 skip(false, true, true, false);
2682 }
2683 }
2684 accept(RBRACE);
2685 return defs.toList();
2686 }
2688 /** ClassBodyDeclaration =
2689 * ";"
2690 * | [STATIC] Block
2691 * | ModifiersOpt
2692 * ( Type Ident
2693 * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
2694 * | VOID Ident MethodDeclaratorRest
2695 * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
2696 * | Ident ConstructorDeclaratorRest
2697 * | TypeParameters Ident ConstructorDeclaratorRest
2698 * | ClassOrInterfaceOrEnumDeclaration
2699 * )
2700 * InterfaceBodyDeclaration =
2701 * ";"
2702 * | ModifiersOpt Type Ident
2703 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
2704 */
2705 List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
2706 if (S.token() == SEMI) {
2707 S.nextToken();
2708 return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
2709 } else {
2710 String dc = S.docComment();
2711 int pos = S.pos();
2712 JCModifiers mods = modifiersOpt();
2713 if (S.token() == CLASS ||
2714 S.token() == INTERFACE ||
2715 allowEnums && S.token() == ENUM) {
2716 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
2717 } else if (S.token() == LBRACE && !isInterface &&
2718 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
2719 mods.annotations.isEmpty()) {
2720 return List.<JCTree>of(block(pos, mods.flags));
2721 } else {
2722 pos = S.pos();
2723 List<JCTypeParameter> typarams = typeParametersOpt();
2724 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2726 Name name = S.name();
2727 pos = S.pos();
2728 JCExpression type;
2729 boolean isVoid = S.token() == VOID;
2730 if (isVoid) {
2731 if (annosAfterParams.nonEmpty())
2732 illegal(annosAfterParams.head.pos);
2733 type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2734 S.nextToken();
2735 } else {
2736 if (annosAfterParams.nonEmpty()) {
2737 mods.annotations = mods.annotations.appendList(annosAfterParams);
2738 if (mods.pos == Position.NOPOS)
2739 mods.pos = mods.annotations.head.pos;
2740 }
2741 // method returns types are un-annotated types
2742 type = unannotatedType();
2743 }
2744 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2745 if (isInterface || name != className)
2746 log.error(pos, "invalid.meth.decl.ret.type.req");
2747 return List.of(methodDeclaratorRest(
2748 pos, mods, null, names.init, typarams,
2749 isInterface, true, dc));
2750 } else {
2751 pos = S.pos();
2752 name = ident();
2753 if (S.token() == LPAREN) {
2754 return List.of(methodDeclaratorRest(
2755 pos, mods, type, name, typarams,
2756 isInterface, isVoid, dc));
2757 } else if (!isVoid && typarams.isEmpty()) {
2758 List<JCTree> defs =
2759 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2760 new ListBuffer<JCTree>()).toList();
2761 storeEnd(defs.last(), S.endPos());
2762 accept(SEMI);
2763 return defs;
2764 } else {
2765 pos = S.pos();
2766 List<JCTree> err = isVoid
2767 ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
2768 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
2769 : null;
2770 return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
2771 }
2772 }
2773 }
2774 }
2775 }
2777 /** MethodDeclaratorRest =
2778 * FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2779 * VoidMethodDeclaratorRest =
2780 * FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
2781 * InterfaceMethodDeclaratorRest =
2782 * FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
2783 * VoidInterfaceMethodDeclaratorRest =
2784 * FormalParameters [Annotations] [THROWS TypeList] ";"
2785 * ConstructorDeclaratorRest =
2786 * "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
2787 */
2788 JCTree methodDeclaratorRest(int pos,
2789 JCModifiers mods,
2790 JCExpression type,
2791 Name name,
2792 List<JCTypeParameter> typarams,
2793 boolean isInterface, boolean isVoid,
2794 String dc) {
2795 List<JCVariableDecl> params = formalParameters();
2797 List<JCTypeAnnotation> receiverAnnotations;
2798 if (!isVoid) {
2799 // need to distinguish between receiver anno and array anno
2800 // look at typeAnnotationsPushedBack comment
2801 this.permitTypeAnnotationsPushBack = true;
2802 type = methodReturnArrayRest(type);
2803 this.permitTypeAnnotationsPushBack = false;
2804 if (typeAnnotationsPushedBack == null)
2805 receiverAnnotations = List.nil();
2806 else
2807 receiverAnnotations = typeAnnotationsPushedBack;
2808 typeAnnotationsPushedBack = null;
2809 } else
2810 receiverAnnotations = typeAnnotationsOpt();
2812 List<JCExpression> thrown = List.nil();
2813 if (S.token() == THROWS) {
2814 S.nextToken();
2815 thrown = qualidentList();
2816 }
2817 JCBlock body = null;
2818 JCExpression defaultValue;
2819 if (S.token() == LBRACE) {
2820 body = block();
2821 defaultValue = null;
2822 } else {
2823 if (S.token() == DEFAULT) {
2824 accept(DEFAULT);
2825 defaultValue = annotationValue();
2826 } else {
2827 defaultValue = null;
2828 }
2829 accept(SEMI);
2830 if (S.pos() <= errorEndPos) {
2831 // error recovery
2832 skip(false, true, false, false);
2833 if (S.token() == LBRACE) {
2834 body = block();
2835 }
2836 }
2837 }
2839 JCMethodDecl result =
2840 toP(F.at(pos).MethodDef(mods, name, type, typarams,
2841 params, receiverAnnotations, thrown,
2842 body, defaultValue));
2843 attach(result, dc);
2844 return result;
2845 }
2847 /** Parses the array levels after the format parameters list, and append
2848 * them to the return type, while preseving the order of type annotations
2849 */
2850 private JCExpression methodReturnArrayRest(JCExpression type) {
2851 if (type.getTag() != JCTree.TYPEARRAY)
2852 return bracketsOpt(type);
2854 JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
2855 while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
2856 baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
2858 if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
2859 JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
2860 at.underlyingType = bracketsOpt(at.underlyingType);
2861 } else {
2862 baseArray.elemtype = bracketsOpt(baseArray.elemtype);
2863 }
2865 return type;
2866 }
2868 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
2869 */
2870 List<JCExpression> qualidentList() {
2871 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2873 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
2874 if (!typeAnnos.isEmpty())
2875 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2876 else
2877 ts.append(qualident());
2878 while (S.token() == COMMA) {
2879 S.nextToken();
2881 typeAnnos = typeAnnotationsOpt();
2882 if (!typeAnnos.isEmpty())
2883 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2884 else
2885 ts.append(qualident());
2886 }
2887 return ts.toList();
2888 }
2890 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2891 */
2892 List<JCTypeParameter> typeParametersOpt() {
2893 if (S.token() == LT) {
2894 checkGenerics();
2895 ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
2896 S.nextToken();
2897 typarams.append(typeParameter());
2898 while (S.token() == COMMA) {
2899 S.nextToken();
2900 typarams.append(typeParameter());
2901 }
2902 accept(GT);
2903 return typarams.toList();
2904 } else {
2905 return List.nil();
2906 }
2907 }
2909 /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
2910 * TypeParameterBound = EXTENDS Type {"&" Type}
2911 * TypeVariable = Ident
2912 */
2913 JCTypeParameter typeParameter() {
2914 int pos = S.pos();
2915 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
2916 Name name = ident();
2917 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
2918 if (S.token() == EXTENDS) {
2919 S.nextToken();
2920 bounds.append(parseType());
2921 while (S.token() == AMP) {
2922 S.nextToken();
2923 bounds.append(parseType());
2924 }
2925 }
2926 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
2927 }
2929 /** FormalParameters = "(" [ FormalParameterList ] ")"
2930 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
2931 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
2932 */
2933 List<JCVariableDecl> formalParameters() {
2934 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
2935 JCVariableDecl lastParam = null;
2936 accept(LPAREN);
2937 if (S.token() != RPAREN) {
2938 params.append(lastParam = formalParameter());
2939 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
2940 S.nextToken();
2941 params.append(lastParam = formalParameter());
2942 }
2943 }
2944 accept(RPAREN);
2945 return params.toList();
2946 }
2948 JCModifiers optFinal(long flags) {
2949 JCModifiers mods = modifiersOpt();
2950 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
2951 mods.flags |= flags;
2952 return mods;
2953 }
2955 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
2956 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
2957 */
2958 JCVariableDecl formalParameter() {
2959 JCModifiers mods = optFinal(Flags.PARAMETER);
2960 // need to distinguish between vararg annos and array annos
2961 // look at typeAnnotaitonsPushedBack comment
2962 this.permitTypeAnnotationsPushBack = true;
2963 JCExpression type = parseType();
2964 this.permitTypeAnnotationsPushBack = false;
2966 if (S.token() == ELLIPSIS) {
2967 List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
2968 typeAnnotationsPushedBack = null;
2969 checkVarargs();
2970 mods.flags |= Flags.VARARGS;
2971 // insert var arg type annotations
2972 if (varargsAnnos != null && varargsAnnos.nonEmpty())
2973 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
2974 type = to(F.at(S.pos()).TypeArray(type));
2976 S.nextToken();
2977 } else {
2978 // if not a var arg, then typeAnnotationsPushedBack should be null
2979 if (typeAnnotationsPushedBack != null
2980 && !typeAnnotationsPushedBack.isEmpty()) {
2981 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
2982 "illegal.start.of.type");
2983 }
2984 typeAnnotationsPushedBack = null;
2985 }
2986 return variableDeclaratorId(mods, type);
2987 }
2989 /* ---------- auxiliary methods -------------- */
2991 /** Check that given tree is a legal expression statement.
2992 */
2993 protected JCExpression checkExprStat(JCExpression t) {
2994 switch(t.getTag()) {
2995 case JCTree.PREINC: case JCTree.PREDEC:
2996 case JCTree.POSTINC: case JCTree.POSTDEC:
2997 case JCTree.ASSIGN:
2998 case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
2999 case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
3000 case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
3001 case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
3002 case JCTree.APPLY: case JCTree.NEWCLASS:
3003 case JCTree.ERRONEOUS:
3004 return t;
3005 default:
3006 log.error(t.pos, "not.stmt");
3007 return F.at(t.pos).Erroneous(List.<JCTree>of(t));
3008 }
3009 }
3011 /** Return precedence of operator represented by token,
3012 * -1 if token is not a binary operator. @see TreeInfo.opPrec
3013 */
3014 static int prec(Token token) {
3015 int oc = optag(token);
3016 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
3017 }
3019 /** Return operation tag of binary operator represented by token,
3020 * -1 if token is not a binary operator.
3021 */
3022 static int optag(Token token) {
3023 switch (token) {
3024 case BARBAR:
3025 return JCTree.OR;
3026 case AMPAMP:
3027 return JCTree.AND;
3028 case BAR:
3029 return JCTree.BITOR;
3030 case BAREQ:
3031 return JCTree.BITOR_ASG;
3032 case CARET:
3033 return JCTree.BITXOR;
3034 case CARETEQ:
3035 return JCTree.BITXOR_ASG;
3036 case AMP:
3037 return JCTree.BITAND;
3038 case AMPEQ:
3039 return JCTree.BITAND_ASG;
3040 case EQEQ:
3041 return JCTree.EQ;
3042 case BANGEQ:
3043 return JCTree.NE;
3044 case LT:
3045 return JCTree.LT;
3046 case GT:
3047 return JCTree.GT;
3048 case LTEQ:
3049 return JCTree.LE;
3050 case GTEQ:
3051 return JCTree.GE;
3052 case LTLT:
3053 return JCTree.SL;
3054 case LTLTEQ:
3055 return JCTree.SL_ASG;
3056 case GTGT:
3057 return JCTree.SR;
3058 case GTGTEQ:
3059 return JCTree.SR_ASG;
3060 case GTGTGT:
3061 return JCTree.USR;
3062 case GTGTGTEQ:
3063 return JCTree.USR_ASG;
3064 case PLUS:
3065 return JCTree.PLUS;
3066 case PLUSEQ:
3067 return JCTree.PLUS_ASG;
3068 case SUB:
3069 return JCTree.MINUS;
3070 case SUBEQ:
3071 return JCTree.MINUS_ASG;
3072 case STAR:
3073 return JCTree.MUL;
3074 case STAREQ:
3075 return JCTree.MUL_ASG;
3076 case SLASH:
3077 return JCTree.DIV;
3078 case SLASHEQ:
3079 return JCTree.DIV_ASG;
3080 case PERCENT:
3081 return JCTree.MOD;
3082 case PERCENTEQ:
3083 return JCTree.MOD_ASG;
3084 case INSTANCEOF:
3085 return JCTree.TYPETEST;
3086 default:
3087 return -1;
3088 }
3089 }
3091 /** Return operation tag of unary operator represented by token,
3092 * -1 if token is not a binary operator.
3093 */
3094 static int unoptag(Token token) {
3095 switch (token) {
3096 case PLUS:
3097 return JCTree.POS;
3098 case SUB:
3099 return JCTree.NEG;
3100 case BANG:
3101 return JCTree.NOT;
3102 case TILDE:
3103 return JCTree.COMPL;
3104 case PLUSPLUS:
3105 return JCTree.PREINC;
3106 case SUBSUB:
3107 return JCTree.PREDEC;
3108 default:
3109 return -1;
3110 }
3111 }
3113 /** Return type tag of basic type represented by token,
3114 * -1 if token is not a basic type identifier.
3115 */
3116 static int typetag(Token token) {
3117 switch (token) {
3118 case BYTE:
3119 return TypeTags.BYTE;
3120 case CHAR:
3121 return TypeTags.CHAR;
3122 case SHORT:
3123 return TypeTags.SHORT;
3124 case INT:
3125 return TypeTags.INT;
3126 case LONG:
3127 return TypeTags.LONG;
3128 case FLOAT:
3129 return TypeTags.FLOAT;
3130 case DOUBLE:
3131 return TypeTags.DOUBLE;
3132 case BOOLEAN:
3133 return TypeTags.BOOLEAN;
3134 default:
3135 return -1;
3136 }
3137 }
3139 void checkDiamond() {
3140 if (!allowDiamond) {
3141 log.error(S.pos(), "diamond.not.supported.in.source", source.name);
3142 allowDiamond = true;
3143 }
3144 }
3145 void checkGenerics() {
3146 if (!allowGenerics) {
3147 log.error(S.pos(), "generics.not.supported.in.source", source.name);
3148 allowGenerics = true;
3149 }
3150 }
3151 void checkVarargs() {
3152 if (!allowVarargs) {
3153 log.error(S.pos(), "varargs.not.supported.in.source", source.name);
3154 allowVarargs = true;
3155 }
3156 }
3157 void checkForeach() {
3158 if (!allowForeach) {
3159 log.error(S.pos(), "foreach.not.supported.in.source", source.name);
3160 allowForeach = true;
3161 }
3162 }
3163 void checkStaticImports() {
3164 if (!allowStaticImport) {
3165 log.error(S.pos(), "static.import.not.supported.in.source", source.name);
3166 allowStaticImport = true;
3167 }
3168 }
3169 void checkAnnotations() {
3170 if (!allowAnnotations) {
3171 log.error(S.pos(), "annotations.not.supported.in.source", source.name);
3172 allowAnnotations = true;
3173 }
3174 }
3175 void checkTypeAnnotations() {
3176 if (!allowTypeAnnotations) {
3177 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3178 allowTypeAnnotations = true;
3179 }
3180 }
3181 }