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