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