Mon, 27 Jul 2009 19:52:42 -0700
6865399: some javac files are missing Sun internal API comment
Reviewed-by: darcy
1 /*
2 * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
26 package com.sun.tools.javac.parser;
28 import java.util.*;
30 import com.sun.tools.javac.tree.*;
31 import com.sun.tools.javac.code.*;
32 import com.sun.tools.javac.util.*;
33 import com.sun.tools.javac.util.List;
34 import static com.sun.tools.javac.util.ListBuffer.lb;
36 import com.sun.tools.javac.tree.JCTree.*;
38 import static com.sun.tools.javac.parser.Token.*;
40 /** The parser maps a token sequence into an abstract syntax
41 * tree. It operates by recursive descent, with code derived
42 * systematically from an LL(1) grammar. For efficiency reasons, an
43 * operator precedence scheme is used for parsing binary operation
44 * expressions.
45 *
46 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
47 * you write code that depends on this, you do so at your own risk.
48 * This code and its internal interfaces are subject to change or
49 * deletion without notice.</b>
50 */
51 public class JavacParser implements Parser {
53 /** The number of precedence levels of infix operators.
54 */
55 private static final int infixPrecedenceLevels = 10;
57 /** The scanner used for lexical analysis.
58 */
59 private Lexer S;
61 /** The factory to be used for abstract syntax tree construction.
62 */
63 protected TreeMaker F;
65 /** The log to be used for error diagnostics.
66 */
67 private Log log;
69 /** The keyword table. */
70 private Keywords keywords;
72 /** The Source language setting. */
73 private Source source;
75 /** The name table. */
76 private Names names;
78 // Because of javac's limited lookahead, some contexts are ambiguous in
79 // the presence of type annotations even though they are not ambiguous
80 // in the absence of type annotations. Consider this code:
81 // void m(String [] m) { }
82 // void m(String ... m) { }
83 // After parsing "String", javac calls bracketsOpt which immediately
84 // returns if the next character is not '['. Similarly, javac can see
85 // if the next token is ... and in that case parse an ellipsis. But in
86 // the presence of type annotations:
87 // void m(String @A [] m) { }
88 // void m(String @A ... m) { }
89 // no finite lookahead is enough to determine whether to read array
90 // levels or an ellipsis. Furthermore, if you call bracketsOpt, then
91 // bracketsOpt first reads all the leading annotations and only then
92 // discovers that it needs to fail. bracketsOpt needs a way to push
93 // back the extra annotations that it read. (But, bracketsOpt should
94 // not *always* be allowed to push back extra annotations that it finds
95 // -- in most contexts, any such extra annotation is an error.
96 // Another similar case occurs with arrays and receiver annotations:
97 // String b() @Array [] @Receiver { }
98 // String b() @Receiver { }
99 //
100 // The following two variables permit type annotations that have
101 // already been read to be stored for later use. Alternate
102 // implementations are possible but would cause much larger changes to
103 // the parser.
104 /** Type annotations that have already been read but have not yet been used. **/
105 private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
106 /**
107 * If the parser notices extra annotations, then it either immediately
108 * issues an error (if this variable is false) or places the extra
109 * annotations in variable typeAnnotationsPushedBack (if this variable
110 * is true).
111 */
112 private boolean permitTypeAnnotationsPushBack = false;
114 /** Construct a parser from a given scanner, tree factory and log.
115 */
116 protected JavacParser(ParserFactory fac,
117 Lexer S,
118 boolean keepDocComments,
119 boolean keepLineMap) {
120 this.S = S;
121 S.nextToken(); // prime the pump
122 this.F = fac.F;
123 this.log = fac.log;
124 this.names = fac.names;
125 this.keywords = fac.keywords;
126 this.source = fac.source;
127 this.allowGenerics = source.allowGenerics();
128 this.allowVarargs = source.allowVarargs();
129 this.allowAsserts = source.allowAsserts();
130 this.allowEnums = source.allowEnums();
131 this.allowForeach = source.allowForeach();
132 this.allowStaticImport = source.allowStaticImport();
133 this.allowAnnotations = source.allowAnnotations();
134 this.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 if (permitTypeAnnotationsPushBack)
1215 typeAnnotationsPushedBack = annos;
1216 else
1217 return illegal(annos.head.pos);
1218 }
1219 break;
1220 }
1221 }
1222 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
1223 mode = EXPR;
1224 t = to(F.at(S.pos()).Unary(
1225 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1226 S.nextToken();
1227 }
1229 return toP(t);
1230 }
1232 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1233 */
1234 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1235 S.nextToken();
1236 if (S.token() == LPAREN || typeArgs != null) {
1237 t = arguments(typeArgs, t);
1238 } else {
1239 int pos = S.pos();
1240 accept(DOT);
1241 typeArgs = (S.token() == LT) ? typeArguments() : null;
1242 t = toP(F.at(pos).Select(t, ident()));
1243 t = argumentsOpt(typeArgs, t);
1244 }
1245 return t;
1246 }
1248 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN
1249 */
1250 JCPrimitiveTypeTree basicType() {
1251 JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token())));
1252 S.nextToken();
1253 return t;
1254 }
1256 /** ArgumentsOpt = [ Arguments ]
1257 */
1258 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) {
1259 if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) {
1260 mode = EXPR;
1261 return arguments(typeArgs, t);
1262 } else {
1263 return t;
1264 }
1265 }
1267 /** Arguments = "(" [Expression { COMMA Expression }] ")"
1268 */
1269 List<JCExpression> arguments() {
1270 ListBuffer<JCExpression> args = lb();
1271 if (S.token() == LPAREN) {
1272 S.nextToken();
1273 if (S.token() != RPAREN) {
1274 args.append(parseExpression());
1275 while (S.token() == COMMA) {
1276 S.nextToken();
1277 args.append(parseExpression());
1278 }
1279 }
1280 accept(RPAREN);
1281 } else {
1282 syntaxError(S.pos(), "expected", LPAREN);
1283 }
1284 return args.toList();
1285 }
1287 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) {
1288 int pos = S.pos();
1289 List<JCExpression> args = arguments();
1290 return toP(F.at(pos).Apply(typeArgs, t, args));
1291 }
1293 /** TypeArgumentsOpt = [ TypeArguments ]
1294 */
1295 JCExpression typeArgumentsOpt(JCExpression t) {
1296 if (S.token() == LT &&
1297 (mode & TYPE) != 0 &&
1298 (mode & NOPARAMS) == 0) {
1299 mode = TYPE;
1300 checkGenerics();
1301 return typeArguments(t);
1302 } else {
1303 return t;
1304 }
1305 }
1306 List<JCExpression> typeArgumentsOpt() {
1307 return typeArgumentsOpt(TYPE);
1308 }
1310 List<JCExpression> typeArgumentsOpt(int useMode) {
1311 if (S.token() == LT) {
1312 checkGenerics();
1313 if ((mode & useMode) == 0 ||
1314 (mode & NOPARAMS) != 0) {
1315 illegal();
1316 }
1317 mode = useMode;
1318 return typeArguments();
1319 }
1320 return null;
1321 }
1323 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">"
1324 */
1325 List<JCExpression> typeArguments() {
1326 ListBuffer<JCExpression> args = lb();
1327 if (S.token() == LT) {
1328 S.nextToken();
1329 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1330 while (S.token() == COMMA) {
1331 S.nextToken();
1332 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType());
1333 }
1334 switch (S.token()) {
1335 case GTGTGTEQ:
1336 S.token(GTGTEQ);
1337 break;
1338 case GTGTEQ:
1339 S.token(GTEQ);
1340 break;
1341 case GTEQ:
1342 S.token(EQ);
1343 break;
1344 case GTGTGT:
1345 S.token(GTGT);
1346 break;
1347 case GTGT:
1348 S.token(GT);
1349 break;
1350 default:
1351 accept(GT);
1352 break;
1353 }
1354 } else {
1355 syntaxError(S.pos(), "expected", LT);
1356 }
1357 return args.toList();
1358 }
1360 /** TypeArgument = Type
1361 * | [Annotations] "?"
1362 * | [Annotations] "?" EXTENDS Type {"&" Type}
1363 * | [Annotations] "?" SUPER Type
1364 */
1365 JCExpression typeArgument() {
1366 List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
1367 if (S.token() != QUES) return parseType(annotations);
1368 int pos = S.pos();
1369 S.nextToken();
1370 JCExpression result;
1371 if (S.token() == EXTENDS) {
1372 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
1373 S.nextToken();
1374 result = F.at(pos).Wildcard(t, parseType());
1375 } else if (S.token() == SUPER) {
1376 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
1377 S.nextToken();
1378 result = F.at(pos).Wildcard(t, parseType());
1379 } else if (S.token() == IDENTIFIER) {
1380 //error recovery
1381 reportSyntaxError(S.prevEndPos(), "expected3",
1382 GT, EXTENDS, SUPER);
1383 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1384 JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1385 JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1386 result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1387 } else {
1388 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1389 result = toP(F.at(pos).Wildcard(t, null));
1390 }
1391 if (!annotations.isEmpty())
1392 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1393 return result;
1394 }
1396 JCTypeApply typeArguments(JCExpression t) {
1397 int pos = S.pos();
1398 List<JCExpression> args = typeArguments();
1399 return toP(F.at(pos).TypeApply(t, args));
1400 }
1402 /**
1403 * BracketsOpt = { [Annotations] "[" "]" }
1404 *
1405 * <p>
1406 *
1407 * <code>annotations</code> is the list of annotations targeting
1408 * the expression <code>t</code>.
1409 */
1410 private JCExpression bracketsOpt(JCExpression t,
1411 List<JCTypeAnnotation> annotations) {
1412 List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1414 if (S.token() == LBRACKET) {
1415 int pos = S.pos();
1416 S.nextToken();
1418 JCExpression orig = t;
1419 t = bracketsOptCont(t, pos, nextLevelAnnotations);
1420 } else if (!nextLevelAnnotations.isEmpty()) {
1421 if (permitTypeAnnotationsPushBack) {
1422 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1423 } else
1424 return illegal(nextLevelAnnotations.head.pos);
1425 }
1427 int apos = S.pos();
1428 if (!annotations.isEmpty())
1429 t = F.at(apos).AnnotatedType(annotations, t);
1430 return t;
1431 }
1433 /** BracketsOpt = {"[" TypeAnnotations "]"}
1434 */
1435 private JCExpression bracketsOpt(JCExpression t) {
1436 return bracketsOpt(t, List.<JCTypeAnnotation>nil());
1437 }
1439 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
1440 List<JCTypeAnnotation> annotations) {
1441 accept(RBRACKET);
1442 t = bracketsOpt(t, annotations);
1443 return toP(F.at(pos).TypeArray(t));
1444 }
1446 /** BracketsSuffixExpr = "." CLASS
1447 * BracketsSuffixType =
1448 */
1449 JCExpression bracketsSuffix(JCExpression t) {
1450 if ((mode & EXPR) != 0 && S.token() == DOT) {
1451 mode = EXPR;
1452 int pos = S.pos();
1453 S.nextToken();
1454 accept(CLASS);
1455 if (S.pos() == errorEndPos) {
1456 // error recovery
1457 Name name = null;
1458 if (S.token() == IDENTIFIER) {
1459 name = S.name();
1460 S.nextToken();
1461 } else {
1462 name = names.error;
1463 }
1464 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
1465 } else {
1466 t = toP(F.at(pos).Select(t, names._class));
1467 }
1468 } else if ((mode & TYPE) != 0) {
1469 mode = TYPE;
1470 } else {
1471 syntaxError(S.pos(), "dot.class.expected");
1472 }
1473 return t;
1474 }
1476 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1477 */
1478 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1480 List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
1482 switch (S.token()) {
1483 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1484 case DOUBLE: case BOOLEAN:
1485 if (typeArgs == null) {
1486 if (newAnnotations.isEmpty())
1487 return arrayCreatorRest(newpos, basicType());
1488 else
1489 return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
1490 }
1491 break;
1492 default:
1493 }
1494 JCExpression t = qualident();
1495 // handle type annotations for non primitive arrays
1496 if (!newAnnotations.isEmpty())
1497 t = F.AnnotatedType(newAnnotations, t);
1499 int oldmode = mode;
1500 mode = TYPE;
1501 if (S.token() == LT) {
1502 checkGenerics();
1503 t = typeArguments(t);
1504 }
1505 while (S.token() == DOT) {
1506 int pos = S.pos();
1507 S.nextToken();
1508 t = toP(F.at(pos).Select(t, ident()));
1509 if (S.token() == LT) {
1510 checkGenerics();
1511 t = typeArguments(t);
1512 }
1513 }
1514 mode = oldmode;
1515 if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
1516 JCExpression e = arrayCreatorRest(newpos, t);
1517 if (typeArgs != null) {
1518 int pos = newpos;
1519 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
1520 // note: this should always happen but we should
1521 // not rely on this as the parser is continuously
1522 // modified to improve error recovery.
1523 pos = typeArgs.head.pos;
1524 }
1525 setErrorEndPos(S.prevEndPos());
1526 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
1527 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1528 }
1529 return e;
1530 } else if (S.token() == LPAREN) {
1531 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
1532 if (newClass.def != null) {
1533 assert newClass.def.mods.annotations.isEmpty();
1534 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
1535 }
1536 return newClass;
1537 } else {
1538 reportSyntaxError(S.pos(), "expected2",
1539 LPAREN, LBRACKET);
1540 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
1541 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
1542 }
1543 }
1545 /** InnerCreator = Ident [TypeArguments] ClassCreatorRest
1546 */
1547 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
1548 JCExpression t = toP(F.at(S.pos()).Ident(ident()));
1549 if (S.token() == LT) {
1550 checkGenerics();
1551 t = typeArguments(t);
1552 }
1553 return classCreatorRest(newpos, encl, typeArgs, t);
1554 }
1556 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
1557 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
1558 */
1559 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1561 List<JCTypeAnnotation> topAnnos = List.nil();
1562 if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
1563 JCAnnotatedType atype = (JCAnnotatedType) elemtype;
1564 topAnnos = atype.annotations;
1565 elemtype = atype.underlyingType;
1566 }
1568 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1570 accept(LBRACKET);
1572 if (S.token() == RBRACKET) {
1573 accept(RBRACKET);
1575 elemtype = bracketsOpt(elemtype, annos);
1577 if (S.token() == LBRACE) {
1578 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
1580 na.annotations = topAnnos;
1582 return na;
1583 } else {
1584 return syntaxError(S.pos(), "array.dimension.missing");
1585 }
1586 } else {
1587 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1589 // maintain array dimension type annotations
1590 ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
1591 dimAnnotations.append(annos);
1593 dims.append(parseExpression());
1594 accept(RBRACKET);
1595 while (S.token() == LBRACKET
1596 || (S.token() == MONKEYS_AT)) {
1597 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
1598 int pos = S.pos();
1599 S.nextToken();
1600 if (S.token() == RBRACKET) {
1601 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1602 } else {
1603 if (S.token() == RBRACKET) { // no dimension
1604 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1605 } else {
1606 dimAnnotations.append(maybeDimAnnos);
1607 dims.append(parseExpression());
1608 accept(RBRACKET);
1609 }
1610 }
1611 }
1613 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
1614 na.annotations = topAnnos;
1615 na.dimAnnotations = dimAnnotations.toList();
1616 return na;
1617 }
1618 }
1620 /** ClassCreatorRest = Arguments [ClassBody]
1621 */
1622 JCNewClass classCreatorRest(int newpos,
1623 JCExpression encl,
1624 List<JCExpression> typeArgs,
1625 JCExpression t)
1626 {
1627 List<JCExpression> args = arguments();
1628 JCClassDecl body = null;
1629 if (S.token() == LBRACE) {
1630 int pos = S.pos();
1631 List<JCTree> defs = classOrInterfaceBody(names.empty, false);
1632 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1633 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
1634 }
1635 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
1636 }
1638 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
1639 */
1640 JCExpression arrayInitializer(int newpos, JCExpression t) {
1641 accept(LBRACE);
1642 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>();
1643 if (S.token() == COMMA) {
1644 S.nextToken();
1645 } else if (S.token() != RBRACE) {
1646 elems.append(variableInitializer());
1647 while (S.token() == COMMA) {
1648 S.nextToken();
1649 if (S.token() == RBRACE) break;
1650 elems.append(variableInitializer());
1651 }
1652 }
1653 accept(RBRACE);
1654 return toP(F.at(newpos).NewArray(t, List.<JCExpression>nil(), elems.toList()));
1655 }
1657 /** VariableInitializer = ArrayInitializer | Expression
1658 */
1659 public JCExpression variableInitializer() {
1660 return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression();
1661 }
1663 /** ParExpression = "(" Expression ")"
1664 */
1665 JCExpression parExpression() {
1666 accept(LPAREN);
1667 JCExpression t = parseExpression();
1668 accept(RPAREN);
1669 return t;
1670 }
1672 /** Block = "{" BlockStatements "}"
1673 */
1674 JCBlock block(int pos, long flags) {
1675 accept(LBRACE);
1676 List<JCStatement> stats = blockStatements();
1677 JCBlock t = F.at(pos).Block(flags, stats);
1678 while (S.token() == CASE || S.token() == DEFAULT) {
1679 syntaxError("orphaned", S.token());
1680 switchBlockStatementGroups();
1681 }
1682 // the Block node has a field "endpos" for first char of last token, which is
1683 // usually but not necessarily the last char of the last token.
1684 t.endpos = S.pos();
1685 accept(RBRACE);
1686 return toP(t);
1687 }
1689 public JCBlock block() {
1690 return block(S.pos(), 0);
1691 }
1693 /** BlockStatements = { BlockStatement }
1694 * BlockStatement = LocalVariableDeclarationStatement
1695 * | ClassOrInterfaceOrEnumDeclaration
1696 * | [Ident ":"] Statement
1697 * LocalVariableDeclarationStatement
1698 * = { FINAL | '@' Annotation } Type VariableDeclarators ";"
1699 */
1700 @SuppressWarnings("fallthrough")
1701 List<JCStatement> blockStatements() {
1702 //todo: skip to anchor on error(?)
1703 int lastErrPos = -1;
1704 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>();
1705 while (true) {
1706 int pos = S.pos();
1707 switch (S.token()) {
1708 case RBRACE: case CASE: case DEFAULT: case EOF:
1709 return stats.toList();
1710 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
1711 case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
1712 case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
1713 stats.append(parseStatement());
1714 break;
1715 case MONKEYS_AT:
1716 case FINAL: {
1717 String dc = S.docComment();
1718 JCModifiers mods = modifiersOpt();
1719 if (S.token() == INTERFACE ||
1720 S.token() == CLASS ||
1721 allowEnums && S.token() == ENUM) {
1722 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1723 } else {
1724 JCExpression t = parseType();
1725 stats.appendList(variableDeclarators(mods, t,
1726 new ListBuffer<JCStatement>()));
1727 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1728 storeEnd(stats.elems.last(), S.endPos());
1729 accept(SEMI);
1730 }
1731 break;
1732 }
1733 case ABSTRACT: case STRICTFP: {
1734 String dc = S.docComment();
1735 JCModifiers mods = modifiersOpt();
1736 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc));
1737 break;
1738 }
1739 case INTERFACE:
1740 case CLASS:
1741 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1742 S.docComment()));
1743 break;
1744 case ENUM:
1745 case ASSERT:
1746 if (allowEnums && S.token() == ENUM) {
1747 log.error(S.pos(), "local.enum");
1748 stats.
1749 append(classOrInterfaceOrEnumDeclaration(modifiersOpt(),
1750 S.docComment()));
1751 break;
1752 } else if (allowAsserts && S.token() == ASSERT) {
1753 stats.append(parseStatement());
1754 break;
1755 }
1756 /* fall through to default */
1757 default:
1758 Name name = S.name();
1759 JCExpression t = term(EXPR | TYPE);
1760 if (S.token() == COLON && t.getTag() == JCTree.IDENT) {
1761 S.nextToken();
1762 JCStatement stat = parseStatement();
1763 stats.append(F.at(pos).Labelled(name, stat));
1764 } else if ((lastmode & TYPE) != 0 &&
1765 (S.token() == IDENTIFIER ||
1766 S.token() == ASSERT ||
1767 S.token() == ENUM)) {
1768 pos = S.pos();
1769 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1770 F.at(pos);
1771 stats.appendList(variableDeclarators(mods, t,
1772 new ListBuffer<JCStatement>()));
1773 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1774 storeEnd(stats.elems.last(), S.endPos());
1775 accept(SEMI);
1776 } else {
1777 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1778 stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1779 accept(SEMI);
1780 }
1781 }
1783 // error recovery
1784 if (S.pos() == lastErrPos)
1785 return stats.toList();
1786 if (S.pos() <= errorEndPos) {
1787 skip(false, true, true, true);
1788 lastErrPos = S.pos();
1789 }
1791 // ensure no dangling /** @deprecated */ active
1792 S.resetDeprecatedFlag();
1793 }
1794 }
1796 /** Statement =
1797 * Block
1798 * | IF ParExpression Statement [ELSE Statement]
1799 * | FOR "(" ForInitOpt ";" [Expression] ";" ForUpdateOpt ")" Statement
1800 * | FOR "(" FormalParameter : Expression ")" Statement
1801 * | WHILE ParExpression Statement
1802 * | DO Statement WHILE ParExpression ";"
1803 * | TRY Block ( Catches | [Catches] FinallyPart )
1804 * | SWITCH ParExpression "{" SwitchBlockStatementGroups "}"
1805 * | SYNCHRONIZED ParExpression Block
1806 * | RETURN [Expression] ";"
1807 * | THROW Expression ";"
1808 * | BREAK [Ident] ";"
1809 * | CONTINUE [Ident] ";"
1810 * | ASSERT Expression [ ":" Expression ] ";"
1811 * | ";"
1812 * | ExpressionStatement
1813 * | Ident ":" Statement
1814 */
1815 @SuppressWarnings("fallthrough")
1816 public JCStatement parseStatement() {
1817 int pos = S.pos();
1818 switch (S.token()) {
1819 case LBRACE:
1820 return block();
1821 case IF: {
1822 S.nextToken();
1823 JCExpression cond = parExpression();
1824 JCStatement thenpart = parseStatement();
1825 JCStatement elsepart = null;
1826 if (S.token() == ELSE) {
1827 S.nextToken();
1828 elsepart = parseStatement();
1829 }
1830 return F.at(pos).If(cond, thenpart, elsepart);
1831 }
1832 case FOR: {
1833 S.nextToken();
1834 accept(LPAREN);
1835 List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit();
1836 if (inits.length() == 1 &&
1837 inits.head.getTag() == JCTree.VARDEF &&
1838 ((JCVariableDecl) inits.head).init == null &&
1839 S.token() == COLON) {
1840 checkForeach();
1841 JCVariableDecl var = (JCVariableDecl)inits.head;
1842 accept(COLON);
1843 JCExpression expr = parseExpression();
1844 accept(RPAREN);
1845 JCStatement body = parseStatement();
1846 return F.at(pos).ForeachLoop(var, expr, body);
1847 } else {
1848 accept(SEMI);
1849 JCExpression cond = S.token() == SEMI ? null : parseExpression();
1850 accept(SEMI);
1851 List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1852 accept(RPAREN);
1853 JCStatement body = parseStatement();
1854 return F.at(pos).ForLoop(inits, cond, steps, body);
1855 }
1856 }
1857 case WHILE: {
1858 S.nextToken();
1859 JCExpression cond = parExpression();
1860 JCStatement body = parseStatement();
1861 return F.at(pos).WhileLoop(cond, body);
1862 }
1863 case DO: {
1864 S.nextToken();
1865 JCStatement body = parseStatement();
1866 accept(WHILE);
1867 JCExpression cond = parExpression();
1868 JCDoWhileLoop t = to(F.at(pos).DoLoop(body, cond));
1869 accept(SEMI);
1870 return t;
1871 }
1872 case TRY: {
1873 S.nextToken();
1874 JCBlock body = block();
1875 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>();
1876 JCBlock finalizer = null;
1877 if (S.token() == CATCH || S.token() == FINALLY) {
1878 while (S.token() == CATCH) catchers.append(catchClause());
1879 if (S.token() == FINALLY) {
1880 S.nextToken();
1881 finalizer = block();
1882 }
1883 } else {
1884 log.error(pos, "try.without.catch.or.finally");
1885 }
1886 return F.at(pos).Try(body, catchers.toList(), finalizer);
1887 }
1888 case SWITCH: {
1889 S.nextToken();
1890 JCExpression selector = parExpression();
1891 accept(LBRACE);
1892 List<JCCase> cases = switchBlockStatementGroups();
1893 JCSwitch t = to(F.at(pos).Switch(selector, cases));
1894 accept(RBRACE);
1895 return t;
1896 }
1897 case SYNCHRONIZED: {
1898 S.nextToken();
1899 JCExpression lock = parExpression();
1900 JCBlock body = block();
1901 return F.at(pos).Synchronized(lock, body);
1902 }
1903 case RETURN: {
1904 S.nextToken();
1905 JCExpression result = S.token() == SEMI ? null : parseExpression();
1906 JCReturn t = to(F.at(pos).Return(result));
1907 accept(SEMI);
1908 return t;
1909 }
1910 case THROW: {
1911 S.nextToken();
1912 JCExpression exc = parseExpression();
1913 JCThrow t = to(F.at(pos).Throw(exc));
1914 accept(SEMI);
1915 return t;
1916 }
1917 case BREAK: {
1918 S.nextToken();
1919 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1920 JCBreak t = to(F.at(pos).Break(label));
1921 accept(SEMI);
1922 return t;
1923 }
1924 case CONTINUE: {
1925 S.nextToken();
1926 Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null;
1927 JCContinue t = to(F.at(pos).Continue(label));
1928 accept(SEMI);
1929 return t;
1930 }
1931 case SEMI:
1932 S.nextToken();
1933 return toP(F.at(pos).Skip());
1934 case ELSE:
1935 return toP(F.Exec(syntaxError("else.without.if")));
1936 case FINALLY:
1937 return toP(F.Exec(syntaxError("finally.without.try")));
1938 case CATCH:
1939 return toP(F.Exec(syntaxError("catch.without.try")));
1940 case ASSERT: {
1941 if (allowAsserts && S.token() == ASSERT) {
1942 S.nextToken();
1943 JCExpression assertion = parseExpression();
1944 JCExpression message = null;
1945 if (S.token() == COLON) {
1946 S.nextToken();
1947 message = parseExpression();
1948 }
1949 JCAssert t = to(F.at(pos).Assert(assertion, message));
1950 accept(SEMI);
1951 return t;
1952 }
1953 /* else fall through to default case */
1954 }
1955 case ENUM:
1956 default:
1957 Name name = S.name();
1958 JCExpression expr = parseExpression();
1959 if (S.token() == COLON && expr.getTag() == JCTree.IDENT) {
1960 S.nextToken();
1961 JCStatement stat = parseStatement();
1962 return F.at(pos).Labelled(name, stat);
1963 } else {
1964 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1965 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1966 accept(SEMI);
1967 return stat;
1968 }
1969 }
1970 }
1972 /** CatchClause = CATCH "(" FormalParameter ")" Block
1973 */
1974 JCCatch catchClause() {
1975 int pos = S.pos();
1976 accept(CATCH);
1977 accept(LPAREN);
1978 JCVariableDecl formal =
1979 variableDeclaratorId(optFinal(Flags.PARAMETER),
1980 qualident());
1981 accept(RPAREN);
1982 JCBlock body = block();
1983 return F.at(pos).Catch(formal, body);
1984 }
1986 /** SwitchBlockStatementGroups = { SwitchBlockStatementGroup }
1987 * SwitchBlockStatementGroup = SwitchLabel BlockStatements
1988 * SwitchLabel = CASE ConstantExpression ":" | DEFAULT ":"
1989 */
1990 List<JCCase> switchBlockStatementGroups() {
1991 ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
1992 while (true) {
1993 int pos = S.pos();
1994 switch (S.token()) {
1995 case CASE: {
1996 S.nextToken();
1997 JCExpression pat = parseExpression();
1998 accept(COLON);
1999 List<JCStatement> stats = blockStatements();
2000 JCCase c = F.at(pos).Case(pat, stats);
2001 if (stats.isEmpty())
2002 storeEnd(c, S.prevEndPos());
2003 cases.append(c);
2004 break;
2005 }
2006 case DEFAULT: {
2007 S.nextToken();
2008 accept(COLON);
2009 List<JCStatement> stats = blockStatements();
2010 JCCase c = F.at(pos).Case(null, stats);
2011 if (stats.isEmpty())
2012 storeEnd(c, S.prevEndPos());
2013 cases.append(c);
2014 break;
2015 }
2016 case RBRACE: case EOF:
2017 return cases.toList();
2018 default:
2019 S.nextToken(); // to ensure progress
2020 syntaxError(pos, "expected3",
2021 CASE, DEFAULT, RBRACE);
2022 }
2023 }
2024 }
2026 /** MoreStatementExpressions = { COMMA StatementExpression }
2027 */
2028 <T extends ListBuffer<? super JCExpressionStatement>> T moreStatementExpressions(int pos,
2029 JCExpression first,
2030 T stats) {
2031 // This Exec is a "StatementExpression"; it subsumes no terminating token
2032 stats.append(toP(F.at(pos).Exec(checkExprStat(first))));
2033 while (S.token() == COMMA) {
2034 S.nextToken();
2035 pos = S.pos();
2036 JCExpression t = parseExpression();
2037 // This Exec is a "StatementExpression"; it subsumes no terminating token
2038 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
2039 }
2040 return stats;
2041 }
2043 /** ForInit = StatementExpression MoreStatementExpressions
2044 * | { FINAL | '@' Annotation } Type VariableDeclarators
2045 */
2046 List<JCStatement> forInit() {
2047 ListBuffer<JCStatement> stats = lb();
2048 int pos = S.pos();
2049 if (S.token() == FINAL || S.token() == MONKEYS_AT) {
2050 return variableDeclarators(optFinal(0), parseType(), stats).toList();
2051 } else {
2052 JCExpression t = term(EXPR | TYPE);
2053 if ((lastmode & TYPE) != 0 &&
2054 (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM))
2055 return variableDeclarators(modifiersOpt(), t, stats).toList();
2056 else
2057 return moreStatementExpressions(pos, t, stats).toList();
2058 }
2059 }
2061 /** ForUpdate = StatementExpression MoreStatementExpressions
2062 */
2063 List<JCExpressionStatement> forUpdate() {
2064 return moreStatementExpressions(S.pos(),
2065 parseExpression(),
2066 new ListBuffer<JCExpressionStatement>()).toList();
2067 }
2069 enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
2071 /** AnnotationsOpt = { '@' Annotation }
2072 */
2073 List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
2074 if (S.token() != MONKEYS_AT) return List.nil(); // optimization
2075 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2076 int prevmode = mode;
2077 while (S.token() == MONKEYS_AT) {
2078 int pos = S.pos();
2079 S.nextToken();
2080 buf.append(annotation(pos, kind));
2081 }
2082 lastmode = mode;
2083 mode = prevmode;
2084 List<JCAnnotation> annotations = buf.toList();
2086 if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
2087 System.out.println("TA: parsing " + annotations
2088 + " in " + log.currentSourceFile());
2089 return annotations;
2090 }
2092 List<JCTypeAnnotation> typeAnnotationsOpt() {
2093 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
2094 return List.convert(JCTypeAnnotation.class, annotations);
2095 }
2097 /** ModifiersOpt = { Modifier }
2098 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
2099 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
2100 * | "@" Annotation
2101 */
2102 JCModifiers modifiersOpt() {
2103 return modifiersOpt(null);
2104 }
2105 JCModifiers modifiersOpt(JCModifiers partial) {
2106 long flags = (partial == null) ? 0 : partial.flags;
2107 if (S.deprecatedFlag()) {
2108 flags |= Flags.DEPRECATED;
2109 S.resetDeprecatedFlag();
2110 }
2111 ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
2112 if (partial != null) annotations.appendList(partial.annotations);
2113 int pos = S.pos();
2114 int lastPos = Position.NOPOS;
2115 loop:
2116 while (true) {
2117 long flag;
2118 switch (S.token()) {
2119 case PRIVATE : flag = Flags.PRIVATE; break;
2120 case PROTECTED : flag = Flags.PROTECTED; break;
2121 case PUBLIC : flag = Flags.PUBLIC; break;
2122 case STATIC : flag = Flags.STATIC; break;
2123 case TRANSIENT : flag = Flags.TRANSIENT; break;
2124 case FINAL : flag = Flags.FINAL; break;
2125 case ABSTRACT : flag = Flags.ABSTRACT; break;
2126 case NATIVE : flag = Flags.NATIVE; break;
2127 case VOLATILE : flag = Flags.VOLATILE; break;
2128 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
2129 case STRICTFP : flag = Flags.STRICTFP; break;
2130 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
2131 default: break loop;
2132 }
2133 if ((flags & flag) != 0) log.error(S.pos(), "repeated.modifier");
2134 lastPos = S.pos();
2135 S.nextToken();
2136 if (flag == Flags.ANNOTATION) {
2137 checkAnnotations();
2138 if (S.token() != INTERFACE) {
2139 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
2140 // if first modifier is an annotation, set pos to annotation's.
2141 if (flags == 0 && annotations.isEmpty())
2142 pos = ann.pos;
2143 annotations.append(ann);
2144 lastPos = ann.pos;
2145 flag = 0;
2146 }
2147 }
2148 flags |= flag;
2149 }
2150 switch (S.token()) {
2151 case ENUM: flags |= Flags.ENUM; break;
2152 case INTERFACE: flags |= Flags.INTERFACE; break;
2153 default: break;
2154 }
2156 /* A modifiers tree with no modifier tokens or annotations
2157 * has no text position. */
2158 if (flags == 0 && annotations.isEmpty())
2159 pos = Position.NOPOS;
2161 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList());
2162 if (pos != Position.NOPOS)
2163 storeEnd(mods, S.prevEndPos());
2164 return mods;
2165 }
2167 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ]
2168 * @param pos position of "@" token
2169 */
2170 JCAnnotation annotation(int pos, AnnotationKind kind) {
2171 // accept(AT); // AT consumed by caller
2172 checkAnnotations();
2173 if (kind == AnnotationKind.TYPE_ANNO)
2174 checkTypeAnnotations();
2175 JCTree ident = qualident();
2176 List<JCExpression> fieldValues = annotationFieldValuesOpt();
2177 JCAnnotation ann;
2178 if (kind == AnnotationKind.DEFAULT_ANNO)
2179 ann = F.at(pos).Annotation(ident, fieldValues);
2180 else
2181 ann = F.at(pos).TypeAnnotation(ident, fieldValues);
2182 storeEnd(ann, S.prevEndPos());
2183 return ann;
2184 }
2186 List<JCExpression> annotationFieldValuesOpt() {
2187 return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil();
2188 }
2190 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */
2191 List<JCExpression> annotationFieldValues() {
2192 accept(LPAREN);
2193 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2194 if (S.token() != RPAREN) {
2195 buf.append(annotationFieldValue());
2196 while (S.token() == COMMA) {
2197 S.nextToken();
2198 buf.append(annotationFieldValue());
2199 }
2200 }
2201 accept(RPAREN);
2202 return buf.toList();
2203 }
2205 /** AnnotationFieldValue = AnnotationValue
2206 * | Identifier "=" AnnotationValue
2207 */
2208 JCExpression annotationFieldValue() {
2209 if (S.token() == IDENTIFIER) {
2210 mode = EXPR;
2211 JCExpression t1 = term1();
2212 if (t1.getTag() == JCTree.IDENT && S.token() == EQ) {
2213 int pos = S.pos();
2214 accept(EQ);
2215 return toP(F.at(pos).Assign(t1, annotationValue()));
2216 } else {
2217 return t1;
2218 }
2219 }
2220 return annotationValue();
2221 }
2223 /* AnnotationValue = ConditionalExpression
2224 * | Annotation
2225 * | "{" [ AnnotationValue { "," AnnotationValue } ] "}"
2226 */
2227 JCExpression annotationValue() {
2228 int pos;
2229 switch (S.token()) {
2230 case MONKEYS_AT:
2231 pos = S.pos();
2232 S.nextToken();
2233 return annotation(pos, AnnotationKind.DEFAULT_ANNO);
2234 case LBRACE:
2235 pos = S.pos();
2236 accept(LBRACE);
2237 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2238 if (S.token() != RBRACE) {
2239 buf.append(annotationValue());
2240 while (S.token() == COMMA) {
2241 S.nextToken();
2242 if (S.token() == RPAREN) break;
2243 buf.append(annotationValue());
2244 }
2245 }
2246 accept(RBRACE);
2247 return toP(F.at(pos).NewArray(null, List.<JCExpression>nil(), buf.toList()));
2248 default:
2249 mode = EXPR;
2250 return term1();
2251 }
2252 }
2254 /** VariableDeclarators = VariableDeclarator { "," VariableDeclarator }
2255 */
2256 public <T extends ListBuffer<? super JCVariableDecl>> T variableDeclarators(JCModifiers mods,
2257 JCExpression type,
2258 T vdefs)
2259 {
2260 return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs);
2261 }
2263 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator }
2264 * ConstantDeclaratorsRest = ConstantDeclaratorRest { "," ConstantDeclarator }
2265 *
2266 * @param reqInit Is an initializer always required?
2267 * @param dc The documentation comment for the variable declarations, or null.
2268 */
2269 <T extends ListBuffer<? super JCVariableDecl>> T variableDeclaratorsRest(int pos,
2270 JCModifiers mods,
2271 JCExpression type,
2272 Name name,
2273 boolean reqInit,
2274 String dc,
2275 T vdefs)
2276 {
2277 vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc));
2278 while (S.token() == COMMA) {
2279 // All but last of multiple declarators subsume a comma
2280 storeEnd((JCTree)vdefs.elems.last(), S.endPos());
2281 S.nextToken();
2282 vdefs.append(variableDeclarator(mods, type, reqInit, dc));
2283 }
2284 return vdefs;
2285 }
2287 /** VariableDeclarator = Ident VariableDeclaratorRest
2288 * ConstantDeclarator = Ident ConstantDeclaratorRest
2289 */
2290 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) {
2291 return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc);
2292 }
2294 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer]
2295 * ConstantDeclaratorRest = BracketsOpt "=" VariableInitializer
2296 *
2297 * @param reqInit Is an initializer always required?
2298 * @param dc The documentation comment for the variable declarations, or null.
2299 */
2300 JCVariableDecl variableDeclaratorRest(int pos, JCModifiers mods, JCExpression type, Name name,
2301 boolean reqInit, String dc) {
2302 type = bracketsOpt(type);
2303 JCExpression init = null;
2304 if (S.token() == EQ) {
2305 S.nextToken();
2306 init = variableInitializer();
2307 }
2308 else if (reqInit) syntaxError(S.pos(), "expected", EQ);
2309 JCVariableDecl result =
2310 toP(F.at(pos).VarDef(mods, name, type, init));
2311 attach(result, dc);
2312 return result;
2313 }
2315 /** VariableDeclaratorId = Ident BracketsOpt
2316 */
2317 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
2318 int pos = S.pos();
2319 Name name = ident();
2320 if ((mods.flags & Flags.VARARGS) == 0)
2321 type = bracketsOpt(type);
2322 return toP(F.at(pos).VarDef(mods, name, type, null));
2323 }
2325 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
2326 */
2327 public JCTree.JCCompilationUnit parseCompilationUnit() {
2328 int pos = S.pos();
2329 JCExpression pid = null;
2330 String dc = S.docComment();
2331 JCModifiers mods = null;
2332 List<JCAnnotation> packageAnnotations = List.nil();
2333 if (S.token() == MONKEYS_AT)
2334 mods = modifiersOpt();
2336 if (S.token() == PACKAGE) {
2337 if (mods != null) {
2338 checkNoMods(mods.flags);
2339 packageAnnotations = mods.annotations;
2340 mods = null;
2341 }
2342 S.nextToken();
2343 pid = qualident();
2344 accept(SEMI);
2345 }
2346 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2347 boolean checkForImports = true;
2348 while (S.token() != EOF) {
2349 if (S.pos() <= errorEndPos) {
2350 // error recovery
2351 skip(checkForImports, false, false, false);
2352 if (S.token() == EOF)
2353 break;
2354 }
2355 if (checkForImports && mods == null && S.token() == IMPORT) {
2356 defs.append(importDeclaration());
2357 } else {
2358 JCTree def = typeDeclaration(mods);
2359 if (def instanceof JCExpressionStatement)
2360 def = ((JCExpressionStatement)def).expr;
2361 defs.append(def);
2362 if (def instanceof JCClassDecl)
2363 checkForImports = false;
2364 mods = null;
2365 }
2366 }
2367 JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList());
2368 attach(toplevel, dc);
2369 if (defs.elems.isEmpty())
2370 storeEnd(toplevel, S.prevEndPos());
2371 if (keepDocComments)
2372 toplevel.docComments = docComments;
2373 if (keepLineMap)
2374 toplevel.lineMap = S.getLineMap();
2375 return toplevel;
2376 }
2378 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";"
2379 */
2380 JCTree importDeclaration() {
2381 int pos = S.pos();
2382 S.nextToken();
2383 boolean importStatic = false;
2384 if (S.token() == STATIC) {
2385 checkStaticImports();
2386 importStatic = true;
2387 S.nextToken();
2388 }
2389 JCExpression pid = toP(F.at(S.pos()).Ident(ident()));
2390 do {
2391 int pos1 = S.pos();
2392 accept(DOT);
2393 if (S.token() == STAR) {
2394 pid = to(F.at(pos1).Select(pid, names.asterisk));
2395 S.nextToken();
2396 break;
2397 } else {
2398 pid = toP(F.at(pos1).Select(pid, ident()));
2399 }
2400 } while (S.token() == DOT);
2401 accept(SEMI);
2402 return toP(F.at(pos).Import(pid, importStatic));
2403 }
2405 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
2406 * | ";"
2407 */
2408 JCTree typeDeclaration(JCModifiers mods) {
2409 int pos = S.pos();
2410 if (mods == null && S.token() == SEMI) {
2411 S.nextToken();
2412 return toP(F.at(pos).Skip());
2413 } else {
2414 String dc = S.docComment();
2415 return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc);
2416 }
2417 }
2419 /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
2420 * (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
2421 * @param mods Any modifiers starting the class or interface declaration
2422 * @param dc The documentation comment for the class, or null.
2423 */
2424 JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) {
2425 if (S.token() == CLASS) {
2426 return classDeclaration(mods, dc);
2427 } else if (S.token() == INTERFACE) {
2428 return interfaceDeclaration(mods, dc);
2429 } else if (allowEnums) {
2430 if (S.token() == ENUM) {
2431 return enumDeclaration(mods, dc);
2432 } else {
2433 int pos = S.pos();
2434 List<JCTree> errs;
2435 if (S.token() == IDENTIFIER) {
2436 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2437 setErrorEndPos(S.pos());
2438 } else {
2439 errs = List.<JCTree>of(mods);
2440 }
2441 return toP(F.Exec(syntaxError(pos, errs, "expected3",
2442 CLASS, INTERFACE, ENUM)));
2443 }
2444 } else {
2445 if (S.token() == ENUM) {
2446 log.error(S.pos(), "enums.not.supported.in.source", source.name);
2447 allowEnums = true;
2448 return enumDeclaration(mods, dc);
2449 }
2450 int pos = S.pos();
2451 List<JCTree> errs;
2452 if (S.token() == IDENTIFIER) {
2453 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident())));
2454 setErrorEndPos(S.pos());
2455 } else {
2456 errs = List.<JCTree>of(mods);
2457 }
2458 return toP(F.Exec(syntaxError(pos, errs, "expected2",
2459 CLASS, INTERFACE)));
2460 }
2461 }
2463 /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
2464 * [IMPLEMENTS TypeList] ClassBody
2465 * @param mods The modifiers starting the class declaration
2466 * @param dc The documentation comment for the class, or null.
2467 */
2468 JCClassDecl classDeclaration(JCModifiers mods, String dc) {
2469 int pos = S.pos();
2470 accept(CLASS);
2471 Name name = ident();
2473 List<JCTypeParameter> typarams = typeParametersOpt();
2475 JCTree extending = null;
2476 if (S.token() == EXTENDS) {
2477 S.nextToken();
2478 extending = parseType();
2479 }
2480 List<JCExpression> implementing = List.nil();
2481 if (S.token() == IMPLEMENTS) {
2482 S.nextToken();
2483 implementing = typeList();
2484 }
2485 List<JCTree> defs = classOrInterfaceBody(name, false);
2486 JCClassDecl result = toP(F.at(pos).ClassDef(
2487 mods, name, typarams, extending, implementing, defs));
2488 attach(result, dc);
2489 return result;
2490 }
2492 /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
2493 * [EXTENDS TypeList] InterfaceBody
2494 * @param mods The modifiers starting the interface declaration
2495 * @param dc The documentation comment for the interface, or null.
2496 */
2497 JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) {
2498 int pos = S.pos();
2499 accept(INTERFACE);
2500 Name name = ident();
2502 List<JCTypeParameter> typarams = typeParametersOpt();
2504 List<JCExpression> extending = List.nil();
2505 if (S.token() == EXTENDS) {
2506 S.nextToken();
2507 extending = typeList();
2508 }
2509 List<JCTree> defs = classOrInterfaceBody(name, true);
2510 JCClassDecl result = toP(F.at(pos).ClassDef(
2511 mods, name, typarams, null, extending, defs));
2512 attach(result, dc);
2513 return result;
2514 }
2516 /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
2517 * @param mods The modifiers starting the enum declaration
2518 * @param dc The documentation comment for the enum, or null.
2519 */
2520 JCClassDecl enumDeclaration(JCModifiers mods, String dc) {
2521 int pos = S.pos();
2522 accept(ENUM);
2523 Name name = ident();
2525 List<JCExpression> implementing = List.nil();
2526 if (S.token() == IMPLEMENTS) {
2527 S.nextToken();
2528 implementing = typeList();
2529 }
2531 List<JCTree> defs = enumBody(name);
2532 JCModifiers newMods =
2533 F.at(mods.pos).Modifiers(mods.flags|Flags.ENUM, mods.annotations);
2534 JCClassDecl result = toP(F.at(pos).
2535 ClassDef(newMods, name, List.<JCTypeParameter>nil(),
2536 null, implementing, defs));
2537 attach(result, dc);
2538 return result;
2539 }
2541 /** EnumBody = "{" { EnumeratorDeclarationList } [","]
2542 * [ ";" {ClassBodyDeclaration} ] "}"
2543 */
2544 List<JCTree> enumBody(Name enumName) {
2545 accept(LBRACE);
2546 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2547 if (S.token() == COMMA) {
2548 S.nextToken();
2549 } else if (S.token() != RBRACE && S.token() != SEMI) {
2550 defs.append(enumeratorDeclaration(enumName));
2551 while (S.token() == COMMA) {
2552 S.nextToken();
2553 if (S.token() == RBRACE || S.token() == SEMI) break;
2554 defs.append(enumeratorDeclaration(enumName));
2555 }
2556 if (S.token() != SEMI && S.token() != RBRACE) {
2557 defs.append(syntaxError(S.pos(), "expected3",
2558 COMMA, RBRACE, SEMI));
2559 S.nextToken();
2560 }
2561 }
2562 if (S.token() == SEMI) {
2563 S.nextToken();
2564 while (S.token() != RBRACE && S.token() != EOF) {
2565 defs.appendList(classOrInterfaceBodyDeclaration(enumName,
2566 false));
2567 if (S.pos() <= errorEndPos) {
2568 // error recovery
2569 skip(false, true, true, false);
2570 }
2571 }
2572 }
2573 accept(RBRACE);
2574 return defs.toList();
2575 }
2577 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
2578 */
2579 JCTree enumeratorDeclaration(Name enumName) {
2580 String dc = S.docComment();
2581 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
2582 if (S.deprecatedFlag()) {
2583 flags |= Flags.DEPRECATED;
2584 S.resetDeprecatedFlag();
2585 }
2586 int pos = S.pos();
2587 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2588 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
2589 List<JCExpression> typeArgs = typeArgumentsOpt();
2590 int identPos = S.pos();
2591 Name name = ident();
2592 int createPos = S.pos();
2593 List<JCExpression> args = (S.token() == LPAREN)
2594 ? arguments() : List.<JCExpression>nil();
2595 JCClassDecl body = null;
2596 if (S.token() == LBRACE) {
2597 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC);
2598 List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2599 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
2600 }
2601 if (args.isEmpty() && body == null)
2602 createPos = Position.NOPOS;
2603 JCIdent ident = F.at(Position.NOPOS).Ident(enumName);
2604 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
2605 if (createPos != Position.NOPOS)
2606 storeEnd(create, S.prevEndPos());
2607 ident = F.at(Position.NOPOS).Ident(enumName);
2608 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
2609 attach(result, dc);
2610 return result;
2611 }
2613 /** TypeList = Type {"," Type}
2614 */
2615 List<JCExpression> typeList() {
2616 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2617 ts.append(parseType());
2618 while (S.token() == COMMA) {
2619 S.nextToken();
2620 ts.append(parseType());
2621 }
2622 return ts.toList();
2623 }
2625 /** ClassBody = "{" {ClassBodyDeclaration} "}"
2626 * InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
2627 */
2628 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
2629 accept(LBRACE);
2630 if (S.pos() <= errorEndPos) {
2631 // error recovery
2632 skip(false, true, false, false);
2633 if (S.token() == LBRACE)
2634 S.nextToken();
2635 }
2636 ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
2637 while (S.token() != RBRACE && S.token() != EOF) {
2638 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
2639 if (S.pos() <= errorEndPos) {
2640 // error recovery
2641 skip(false, true, true, false);
2642 }
2643 }
2644 accept(RBRACE);
2645 return defs.toList();
2646 }
2648 /** ClassBodyDeclaration =
2649 * ";"
2650 * | [STATIC] Block
2651 * | ModifiersOpt
2652 * ( Type Ident
2653 * ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
2654 * | VOID Ident MethodDeclaratorRest
2655 * | TypeParameters (Type | VOID) Ident MethodDeclaratorRest
2656 * | Ident ConstructorDeclaratorRest
2657 * | TypeParameters Ident ConstructorDeclaratorRest
2658 * | ClassOrInterfaceOrEnumDeclaration
2659 * )
2660 * InterfaceBodyDeclaration =
2661 * ";"
2662 * | ModifiersOpt Type Ident
2663 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
2664 */
2665 List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
2666 if (S.token() == SEMI) {
2667 S.nextToken();
2668 return List.<JCTree>of(F.at(Position.NOPOS).Block(0, List.<JCStatement>nil()));
2669 } else {
2670 String dc = S.docComment();
2671 int pos = S.pos();
2672 JCModifiers mods = modifiersOpt();
2673 if (S.token() == CLASS ||
2674 S.token() == INTERFACE ||
2675 allowEnums && S.token() == ENUM) {
2676 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc));
2677 } else if (S.token() == LBRACE && !isInterface &&
2678 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
2679 mods.annotations.isEmpty()) {
2680 return List.<JCTree>of(block(pos, mods.flags));
2681 } else {
2682 pos = S.pos();
2683 List<JCTypeParameter> typarams = typeParametersOpt();
2684 // Hack alert: if there are type arguments but no Modifiers, the start
2685 // position will be lost unless we set the Modifiers position. There
2686 // should be an AST node for type parameters (BugId 5005090).
2687 if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
2688 mods.pos = pos;
2689 }
2691 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2693 Token token = S.token();
2694 Name name = S.name();
2695 pos = S.pos();
2696 JCExpression type;
2697 boolean isVoid = S.token() == VOID;
2698 if (isVoid) {
2699 if (annosAfterParams.nonEmpty())
2700 illegal(annosAfterParams.head.pos);
2701 type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2702 S.nextToken();
2703 } else {
2704 mods.annotations = mods.annotations.appendList(annosAfterParams);
2705 // method returns types are un-annotated types
2706 type = unannotatedType();
2707 }
2708 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2709 if (isInterface || name != className)
2710 log.error(pos, "invalid.meth.decl.ret.type.req");
2711 return List.of(methodDeclaratorRest(
2712 pos, mods, null, names.init, typarams,
2713 isInterface, true, dc));
2714 } else {
2715 pos = S.pos();
2716 name = ident();
2717 if (S.token() == LPAREN) {
2718 return List.of(methodDeclaratorRest(
2719 pos, mods, type, name, typarams,
2720 isInterface, isVoid, dc));
2721 } else if (!isVoid && typarams.isEmpty()) {
2722 List<JCTree> defs =
2723 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2724 new ListBuffer<JCTree>()).toList();
2725 storeEnd(defs.last(), S.endPos());
2726 accept(SEMI);
2727 return defs;
2728 } else {
2729 pos = S.pos();
2730 List<JCTree> err = isVoid
2731 ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
2732 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null)))
2733 : null;
2734 return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN));
2735 }
2736 }
2737 }
2738 }
2739 }
2741 /** MethodDeclaratorRest =
2742 * FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2743 * VoidMethodDeclaratorRest =
2744 * FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
2745 * InterfaceMethodDeclaratorRest =
2746 * FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
2747 * VoidInterfaceMethodDeclaratorRest =
2748 * FormalParameters [Annotations] [THROWS TypeList] ";"
2749 * ConstructorDeclaratorRest =
2750 * "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
2751 */
2752 JCTree methodDeclaratorRest(int pos,
2753 JCModifiers mods,
2754 JCExpression type,
2755 Name name,
2756 List<JCTypeParameter> typarams,
2757 boolean isInterface, boolean isVoid,
2758 String dc) {
2759 List<JCVariableDecl> params = formalParameters();
2761 List<JCTypeAnnotation> receiverAnnotations;
2762 if (!isVoid) {
2763 // need to distinguish between receiver anno and array anno
2764 // look at typeAnnotationsPushedBack comment
2765 this.permitTypeAnnotationsPushBack = true;
2766 type = methodReturnArrayRest(type);
2767 this.permitTypeAnnotationsPushBack = false;
2768 if (typeAnnotationsPushedBack == null)
2769 receiverAnnotations = List.nil();
2770 else
2771 receiverAnnotations = typeAnnotationsPushedBack;
2772 typeAnnotationsPushedBack = null;
2773 } else
2774 receiverAnnotations = typeAnnotationsOpt();
2776 List<JCExpression> thrown = List.nil();
2777 if (S.token() == THROWS) {
2778 S.nextToken();
2779 thrown = qualidentList();
2780 }
2781 JCBlock body = null;
2782 JCExpression defaultValue;
2783 if (S.token() == LBRACE) {
2784 body = block();
2785 defaultValue = null;
2786 } else {
2787 if (S.token() == DEFAULT) {
2788 accept(DEFAULT);
2789 defaultValue = annotationValue();
2790 } else {
2791 defaultValue = null;
2792 }
2793 accept(SEMI);
2794 if (S.pos() <= errorEndPos) {
2795 // error recovery
2796 skip(false, true, false, false);
2797 if (S.token() == LBRACE) {
2798 body = block();
2799 }
2800 }
2801 }
2802 JCMethodDecl result =
2803 toP(F.at(pos).MethodDef(mods, name, type, typarams,
2804 params, receiverAnnotations, thrown,
2805 body, defaultValue));
2806 attach(result, dc);
2807 return result;
2808 }
2810 /** Parses the array levels after the format parameters list, and append
2811 * them to the return type, while preseving the order of type annotations
2812 */
2813 private JCExpression methodReturnArrayRest(JCExpression type) {
2814 if (type.getTag() != JCTree.TYPEARRAY)
2815 return bracketsOpt(type);
2817 JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
2818 while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
2819 baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
2821 if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
2822 JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
2823 at.underlyingType = bracketsOpt(at.underlyingType);
2824 } else {
2825 baseArray.elemtype = bracketsOpt(baseArray.elemtype);
2826 }
2828 return type;
2829 }
2831 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
2832 */
2833 List<JCExpression> qualidentList() {
2834 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2836 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
2837 if (!typeAnnos.isEmpty())
2838 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2839 else
2840 ts.append(qualident());
2841 while (S.token() == COMMA) {
2842 S.nextToken();
2844 typeAnnos = typeAnnotationsOpt();
2845 if (!typeAnnos.isEmpty())
2846 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2847 else
2848 ts.append(qualident());
2849 }
2850 return ts.toList();
2851 }
2853 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2854 */
2855 List<JCTypeParameter> typeParametersOpt() {
2856 if (S.token() == LT) {
2857 checkGenerics();
2858 ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>();
2859 S.nextToken();
2860 typarams.append(typeParameter());
2861 while (S.token() == COMMA) {
2862 S.nextToken();
2863 typarams.append(typeParameter());
2864 }
2865 accept(GT);
2866 return typarams.toList();
2867 } else {
2868 return List.nil();
2869 }
2870 }
2872 /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
2873 * TypeParameterBound = EXTENDS Type {"&" Type}
2874 * TypeVariable = Ident
2875 */
2876 JCTypeParameter typeParameter() {
2877 int pos = S.pos();
2878 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
2879 Name name = ident();
2880 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
2881 if (S.token() == EXTENDS) {
2882 S.nextToken();
2883 bounds.append(parseType());
2884 while (S.token() == AMP) {
2885 S.nextToken();
2886 bounds.append(parseType());
2887 }
2888 }
2889 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
2890 }
2892 /** FormalParameters = "(" [ FormalParameterList ] ")"
2893 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
2894 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
2895 */
2896 List<JCVariableDecl> formalParameters() {
2897 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
2898 JCVariableDecl lastParam = null;
2899 accept(LPAREN);
2900 if (S.token() != RPAREN) {
2901 params.append(lastParam = formalParameter());
2902 while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) {
2903 S.nextToken();
2904 params.append(lastParam = formalParameter());
2905 }
2906 }
2907 accept(RPAREN);
2908 return params.toList();
2909 }
2911 JCModifiers optFinal(long flags) {
2912 JCModifiers mods = modifiersOpt();
2913 checkNoMods(mods.flags & ~(Flags.FINAL | Flags.DEPRECATED));
2914 mods.flags |= flags;
2915 return mods;
2916 }
2918 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
2919 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
2920 */
2921 JCVariableDecl formalParameter() {
2922 JCModifiers mods = optFinal(Flags.PARAMETER);
2923 // need to distinguish between vararg annos and array annos
2924 // look at typeAnnotaitonsPushedBack comment
2925 this.permitTypeAnnotationsPushBack = true;
2926 JCExpression type = parseType();
2927 this.permitTypeAnnotationsPushBack = false;
2929 if (S.token() == ELLIPSIS) {
2930 List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
2931 typeAnnotationsPushedBack = null;
2932 checkVarargs();
2933 mods.flags |= Flags.VARARGS;
2934 // insert var arg type annotations
2935 if (varargsAnnos != null && varargsAnnos.nonEmpty())
2936 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
2937 type = to(F.at(S.pos()).TypeArray(type));
2939 S.nextToken();
2940 } else {
2941 // if not a var arg, then typeAnnotationsPushedBack should be null
2942 if (typeAnnotationsPushedBack != null
2943 && !typeAnnotationsPushedBack.isEmpty()) {
2944 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
2945 "illegal.start.of.type");
2946 }
2947 typeAnnotationsPushedBack = null;
2948 }
2949 return variableDeclaratorId(mods, type);
2950 }
2952 /* ---------- auxiliary methods -------------- */
2954 /** Check that given tree is a legal expression statement.
2955 */
2956 protected JCExpression checkExprStat(JCExpression t) {
2957 switch(t.getTag()) {
2958 case JCTree.PREINC: case JCTree.PREDEC:
2959 case JCTree.POSTINC: case JCTree.POSTDEC:
2960 case JCTree.ASSIGN:
2961 case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
2962 case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
2963 case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
2964 case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
2965 case JCTree.APPLY: case JCTree.NEWCLASS:
2966 case JCTree.ERRONEOUS:
2967 return t;
2968 default:
2969 log.error(t.pos, "not.stmt");
2970 return F.at(t.pos).Erroneous(List.<JCTree>of(t));
2971 }
2972 }
2974 /** Return precedence of operator represented by token,
2975 * -1 if token is not a binary operator. @see TreeInfo.opPrec
2976 */
2977 static int prec(Token token) {
2978 int oc = optag(token);
2979 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
2980 }
2982 /** Return operation tag of binary operator represented by token,
2983 * -1 if token is not a binary operator.
2984 */
2985 static int optag(Token token) {
2986 switch (token) {
2987 case BARBAR:
2988 return JCTree.OR;
2989 case AMPAMP:
2990 return JCTree.AND;
2991 case BAR:
2992 return JCTree.BITOR;
2993 case BAREQ:
2994 return JCTree.BITOR_ASG;
2995 case CARET:
2996 return JCTree.BITXOR;
2997 case CARETEQ:
2998 return JCTree.BITXOR_ASG;
2999 case AMP:
3000 return JCTree.BITAND;
3001 case AMPEQ:
3002 return JCTree.BITAND_ASG;
3003 case EQEQ:
3004 return JCTree.EQ;
3005 case BANGEQ:
3006 return JCTree.NE;
3007 case LT:
3008 return JCTree.LT;
3009 case GT:
3010 return JCTree.GT;
3011 case LTEQ:
3012 return JCTree.LE;
3013 case GTEQ:
3014 return JCTree.GE;
3015 case LTLT:
3016 return JCTree.SL;
3017 case LTLTEQ:
3018 return JCTree.SL_ASG;
3019 case GTGT:
3020 return JCTree.SR;
3021 case GTGTEQ:
3022 return JCTree.SR_ASG;
3023 case GTGTGT:
3024 return JCTree.USR;
3025 case GTGTGTEQ:
3026 return JCTree.USR_ASG;
3027 case PLUS:
3028 return JCTree.PLUS;
3029 case PLUSEQ:
3030 return JCTree.PLUS_ASG;
3031 case SUB:
3032 return JCTree.MINUS;
3033 case SUBEQ:
3034 return JCTree.MINUS_ASG;
3035 case STAR:
3036 return JCTree.MUL;
3037 case STAREQ:
3038 return JCTree.MUL_ASG;
3039 case SLASH:
3040 return JCTree.DIV;
3041 case SLASHEQ:
3042 return JCTree.DIV_ASG;
3043 case PERCENT:
3044 return JCTree.MOD;
3045 case PERCENTEQ:
3046 return JCTree.MOD_ASG;
3047 case INSTANCEOF:
3048 return JCTree.TYPETEST;
3049 default:
3050 return -1;
3051 }
3052 }
3054 /** Return operation tag of unary operator represented by token,
3055 * -1 if token is not a binary operator.
3056 */
3057 static int unoptag(Token token) {
3058 switch (token) {
3059 case PLUS:
3060 return JCTree.POS;
3061 case SUB:
3062 return JCTree.NEG;
3063 case BANG:
3064 return JCTree.NOT;
3065 case TILDE:
3066 return JCTree.COMPL;
3067 case PLUSPLUS:
3068 return JCTree.PREINC;
3069 case SUBSUB:
3070 return JCTree.PREDEC;
3071 default:
3072 return -1;
3073 }
3074 }
3076 /** Return type tag of basic type represented by token,
3077 * -1 if token is not a basic type identifier.
3078 */
3079 static int typetag(Token token) {
3080 switch (token) {
3081 case BYTE:
3082 return TypeTags.BYTE;
3083 case CHAR:
3084 return TypeTags.CHAR;
3085 case SHORT:
3086 return TypeTags.SHORT;
3087 case INT:
3088 return TypeTags.INT;
3089 case LONG:
3090 return TypeTags.LONG;
3091 case FLOAT:
3092 return TypeTags.FLOAT;
3093 case DOUBLE:
3094 return TypeTags.DOUBLE;
3095 case BOOLEAN:
3096 return TypeTags.BOOLEAN;
3097 default:
3098 return -1;
3099 }
3100 }
3102 void checkGenerics() {
3103 if (!allowGenerics) {
3104 log.error(S.pos(), "generics.not.supported.in.source", source.name);
3105 allowGenerics = true;
3106 }
3107 }
3108 void checkVarargs() {
3109 if (!allowVarargs) {
3110 log.error(S.pos(), "varargs.not.supported.in.source", source.name);
3111 allowVarargs = true;
3112 }
3113 }
3114 void checkForeach() {
3115 if (!allowForeach) {
3116 log.error(S.pos(), "foreach.not.supported.in.source", source.name);
3117 allowForeach = true;
3118 }
3119 }
3120 void checkStaticImports() {
3121 if (!allowStaticImport) {
3122 log.error(S.pos(), "static.import.not.supported.in.source", source.name);
3123 allowStaticImport = true;
3124 }
3125 }
3126 void checkAnnotations() {
3127 if (!allowAnnotations) {
3128 log.error(S.pos(), "annotations.not.supported.in.source", source.name);
3129 allowAnnotations = true;
3130 }
3131 }
3132 void checkTypeAnnotations() {
3133 if (!allowTypeAnnotations) {
3134 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3135 allowTypeAnnotations = true;
3136 }
3137 }
3138 }