21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.parser;
27
28 import java.util.*;
29
30 import com.sun.tools.javac.code.*;
31 import com.sun.tools.javac.parser.Tokens.*;
32 import com.sun.tools.javac.tree.*;
33 import com.sun.tools.javac.tree.JCTree.*;
34 import com.sun.tools.javac.util.*;
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
37 import com.sun.tools.javac.util.List;
38
39 import static com.sun.tools.javac.util.ListBuffer.lb;
40 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
41
42 /** The parser maps a token sequence into an abstract syntax
43 * tree. It operates by recursive descent, with code derived
44 * systematically from an LL(1) grammar. For efficiency reasons, an
45 * operator precedence scheme is used for parsing binary operation
46 * expressions.
47 *
48 * <p><b>This is NOT part of any supported API.
49 * If you write code that depends on this, you do so at your own risk.
50 * This code and its internal interfaces are subject to change or
51 * deletion without notice.</b>
52 */
53 public class JavacParser implements Parser {
54
55 /** The number of precedence levels of infix operators.
56 */
57 private static final int infixPrecedenceLevels = 10;
58
59 /** The scanner used for lexical analysis.
60 */
740 int top = 0;
741 odStack[0] = t;
742 int startPos = token.pos;
743 Token topOp = Tokens.DUMMY;
744 while (prec(token.kind) >= minprec) {
745 opStack[top] = topOp;
746 top++;
747 topOp = token;
748 nextToken();
749 odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
750 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
751 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
752 odStack[top]);
753 top--;
754 topOp = opStack[top];
755 }
756 }
757 Assert.check(top == 0);
758 t = odStack[0];
759
760 if (t.getTag() == JCTree.PLUS) {
761 StringBuffer buf = foldStrings(t);
762 if (buf != null) {
763 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
764 }
765 }
766
767 odStackSupply.elems = savedOd; // optimization
768 opStackSupply.elems = savedOp; // optimization
769 return t;
770 }
771 //where
772 /** Construct a binary or type test node.
773 */
774 private JCExpression makeOp(int pos,
775 TokenKind topOp,
776 JCExpression od1,
777 JCExpression od2)
778 {
779 if (topOp == INSTANCEOF) {
780 return F.at(pos).TypeTest(od1, od2);
781 } else {
782 return F.at(pos).Binary(optag(topOp), od1, od2);
783 }
784 }
785 /** If tree is a concatenation of string literals, replace it
786 * by a single literal representing the concatenated string.
787 */
788 protected StringBuffer foldStrings(JCTree tree) {
789 if (!allowStringFolding)
790 return null;
791 List<String> buf = List.nil();
792 while (true) {
793 if (tree.getTag() == JCTree.LITERAL) {
794 JCLiteral lit = (JCLiteral) tree;
795 if (lit.typetag == TypeTags.CLASS) {
796 StringBuffer sbuf =
797 new StringBuffer((String)lit.value);
798 while (buf.nonEmpty()) {
799 sbuf.append(buf.head);
800 buf = buf.tail;
801 }
802 return sbuf;
803 }
804 } else if (tree.getTag() == JCTree.PLUS) {
805 JCBinary op = (JCBinary)tree;
806 if (op.rhs.getTag() == JCTree.LITERAL) {
807 JCLiteral lit = (JCLiteral) op.rhs;
808 if (lit.typetag == TypeTags.CLASS) {
809 buf = buf.prepend((String) lit.value);
810 tree = op.lhs;
811 continue;
812 }
813 }
814 }
815 return null;
816 }
817 }
818
819 /** optimization: To save allocating a new operand/operator stack
820 * for every binary operation, we use supplys.
821 */
822 ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
823 ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
824
825 private JCExpression[] newOdStack() {
826 if (odStackSupply.elems == odStackSupply.last)
882 nextToken();
883 mode = EXPR;
884 if (tk == SUB &&
885 (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
886 token.radix() == 10) {
887 mode = EXPR;
888 t = literal(names.hyphen, pos);
889 } else {
890 t = term3();
891 return F.at(pos).Unary(unoptag(tk), t);
892 }
893 } else return illegal();
894 break;
895 case LPAREN:
896 if (typeArgs == null && (mode & EXPR) != 0) {
897 nextToken();
898 mode = EXPR | TYPE | NOPARAMS;
899 t = term3();
900 if ((mode & TYPE) != 0 && token.kind == LT) {
901 // Could be a cast to a parameterized type
902 int op = JCTree.LT;
903 int pos1 = token.pos;
904 nextToken();
905 mode &= (EXPR | TYPE);
906 mode |= TYPEARG;
907 JCExpression t1 = term3();
908 if ((mode & TYPE) != 0 &&
909 (token.kind == COMMA || token.kind == GT)) {
910 mode = TYPE;
911 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
912 args.append(t1);
913 while (token.kind == COMMA) {
914 nextToken();
915 args.append(typeArgument());
916 }
917 accept(GT);
918 t = toP(F.at(pos1).TypeApply(t, args.toList()));
919 checkGenerics();
920 while (token.kind == DOT) {
921 nextToken();
922 mode = TYPE;
1136 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1137 if (typeArgs != null) return illegal();
1138 mode = EXPR;
1139 int pos2 = token.pos;
1140 nextToken();
1141 if (token.kind == LT) typeArgs = typeArguments(false);
1142 t = innerCreator(pos2, typeArgs, t);
1143 typeArgs = null;
1144 } else {
1145 t = toP(F.at(pos1).Select(t, ident()));
1146 t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1147 typeArgs = null;
1148 }
1149 } else {
1150 break;
1151 }
1152 }
1153 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1154 mode = EXPR;
1155 t = to(F.at(token.pos).Unary(
1156 token.kind == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1157 nextToken();
1158 }
1159 return toP(t);
1160 }
1161
1162 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1163 */
1164 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1165 nextToken();
1166 if (token.kind == LPAREN || typeArgs != null) {
1167 t = arguments(typeArgs, t);
1168 } else {
1169 int pos = token.pos;
1170 accept(DOT);
1171 typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1172 t = toP(F.at(pos).Select(t, ident()));
1173 t = argumentsOpt(typeArgs, t);
1174 }
1175 return t;
1176 }
1609 case INTERFACE:
1610 case CLASS:
1611 String dc = token.docComment;
1612 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1613 break;
1614 case ENUM:
1615 case ASSERT:
1616 if (allowEnums && token.kind == ENUM) {
1617 error(token.pos, "local.enum");
1618 dc = token.docComment;
1619 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1620 break;
1621 } else if (allowAsserts && token.kind == ASSERT) {
1622 stats.append(parseStatement());
1623 break;
1624 }
1625 /* fall through to default */
1626 default:
1627 Token prevToken = token;
1628 JCExpression t = term(EXPR | TYPE);
1629 if (token.kind == COLON && t.getTag() == JCTree.IDENT) {
1630 nextToken();
1631 JCStatement stat = parseStatement();
1632 stats.append(F.at(pos).Labelled(prevToken.name(), stat));
1633 } else if ((lastmode & TYPE) != 0 &&
1634 (token.kind == IDENTIFIER ||
1635 token.kind == ASSERT ||
1636 token.kind == ENUM)) {
1637 pos = token.pos;
1638 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1639 F.at(pos);
1640 stats.appendList(variableDeclarators(mods, t,
1641 new ListBuffer<JCStatement>()));
1642 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1643 storeEnd(stats.elems.last(), token.endPos);
1644 accept(SEMI);
1645 } else {
1646 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1647 stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1648 accept(SEMI);
1649 }
1684 int pos = token.pos;
1685 switch (token.kind) {
1686 case LBRACE:
1687 return block();
1688 case IF: {
1689 nextToken();
1690 JCExpression cond = parExpression();
1691 JCStatement thenpart = parseStatement();
1692 JCStatement elsepart = null;
1693 if (token.kind == ELSE) {
1694 nextToken();
1695 elsepart = parseStatement();
1696 }
1697 return F.at(pos).If(cond, thenpart, elsepart);
1698 }
1699 case FOR: {
1700 nextToken();
1701 accept(LPAREN);
1702 List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
1703 if (inits.length() == 1 &&
1704 inits.head.getTag() == JCTree.VARDEF &&
1705 ((JCVariableDecl) inits.head).init == null &&
1706 token.kind == COLON) {
1707 checkForeach();
1708 JCVariableDecl var = (JCVariableDecl)inits.head;
1709 accept(COLON);
1710 JCExpression expr = parseExpression();
1711 accept(RPAREN);
1712 JCStatement body = parseStatement();
1713 return F.at(pos).ForeachLoop(var, expr, body);
1714 } else {
1715 accept(SEMI);
1716 JCExpression cond = token.kind == SEMI ? null : parseExpression();
1717 accept(SEMI);
1718 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1719 accept(RPAREN);
1720 JCStatement body = parseStatement();
1721 return F.at(pos).ForLoop(inits, cond, steps, body);
1722 }
1723 }
1724 case WHILE: {
1817 return toP(F.Exec(syntaxError("catch.without.try")));
1818 case ASSERT: {
1819 if (allowAsserts && token.kind == ASSERT) {
1820 nextToken();
1821 JCExpression assertion = parseExpression();
1822 JCExpression message = null;
1823 if (token.kind == COLON) {
1824 nextToken();
1825 message = parseExpression();
1826 }
1827 JCAssert t = to(F.at(pos).Assert(assertion, message));
1828 accept(SEMI);
1829 return t;
1830 }
1831 /* else fall through to default case */
1832 }
1833 case ENUM:
1834 default:
1835 Token prevToken = token;
1836 JCExpression expr = parseExpression();
1837 if (token.kind == COLON && expr.getTag() == JCTree.IDENT) {
1838 nextToken();
1839 JCStatement stat = parseStatement();
1840 return F.at(pos).Labelled(prevToken.name(), stat);
1841 } else {
1842 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1843 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1844 accept(SEMI);
1845 return stat;
1846 }
1847 }
1848 }
1849
1850 /** CatchClause = CATCH "(" FormalParameter ")" Block
1851 */
1852 protected JCCatch catchClause() {
1853 int pos = token.pos;
1854 accept(CATCH);
1855 accept(LPAREN);
1856 JCModifiers mods = optFinal(Flags.PARAMETER);
1857 List<JCExpression> catchTypes = catchTypes();
2070 accept(LPAREN);
2071 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2072 if (token.kind != RPAREN) {
2073 buf.append(annotationFieldValue());
2074 while (token.kind == COMMA) {
2075 nextToken();
2076 buf.append(annotationFieldValue());
2077 }
2078 }
2079 accept(RPAREN);
2080 return buf.toList();
2081 }
2082
2083 /** AnnotationFieldValue = AnnotationValue
2084 * | Identifier "=" AnnotationValue
2085 */
2086 JCExpression annotationFieldValue() {
2087 if (token.kind == IDENTIFIER) {
2088 mode = EXPR;
2089 JCExpression t1 = term1();
2090 if (t1.getTag() == JCTree.IDENT && token.kind == EQ) {
2091 int pos = token.pos;
2092 accept(EQ);
2093 JCExpression v = annotationValue();
2094 return toP(F.at(pos).Assign(t1, v));
2095 } else {
2096 return t1;
2097 }
2098 }
2099 return annotationValue();
2100 }
2101
2102 /* AnnotationValue = ConditionalExpression
2103 * | Annotation
2104 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2105 */
2106 JCExpression annotationValue() {
2107 int pos;
2108 switch (token.kind) {
2109 case MONKEYS_AT:
2110 pos = token.pos;
2600 return List.<JCTree>of(block(pos, mods.flags));
2601 } else {
2602 pos = token.pos;
2603 List<JCTypeParameter> typarams = typeParametersOpt();
2604 // if there are type parameters but no modifiers, save the start
2605 // position of the method in the modifiers.
2606 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
2607 mods.pos = pos;
2608 storeEnd(mods, pos);
2609 }
2610 Token tk = token;
2611 pos = token.pos;
2612 JCExpression type;
2613 boolean isVoid = token.kind == VOID;
2614 if (isVoid) {
2615 type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2616 nextToken();
2617 } else {
2618 type = parseType();
2619 }
2620 if (token.kind == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2621 if (isInterface || tk.name() != className)
2622 error(pos, "invalid.meth.decl.ret.type.req");
2623 return List.of(methodDeclaratorRest(
2624 pos, mods, null, names.init, typarams,
2625 isInterface, true, dc));
2626 } else {
2627 pos = token.pos;
2628 Name name = ident();
2629 if (token.kind == LPAREN) {
2630 return List.of(methodDeclaratorRest(
2631 pos, mods, type, name, typarams,
2632 isInterface, isVoid, dc));
2633 } else if (!isVoid && typarams.isEmpty()) {
2634 List<JCTree> defs =
2635 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2636 new ListBuffer<JCTree>()).toList();
2637 storeEnd(defs.last(), token.endPos);
2638 accept(SEMI);
2639 return defs;
2640 } else {
2797 }
2798
2799 /* ---------- auxiliary methods -------------- */
2800
2801 void error(int pos, String key, Object ... args) {
2802 log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2803 }
2804
2805 void error(DiagnosticPosition pos, String key, Object ... args) {
2806 log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2807 }
2808
2809 void warning(int pos, String key, Object ... args) {
2810 log.warning(pos, key, args);
2811 }
2812
2813 /** Check that given tree is a legal expression statement.
2814 */
2815 protected JCExpression checkExprStat(JCExpression t) {
2816 switch(t.getTag()) {
2817 case JCTree.PREINC: case JCTree.PREDEC:
2818 case JCTree.POSTINC: case JCTree.POSTDEC:
2819 case JCTree.ASSIGN:
2820 case JCTree.BITOR_ASG: case JCTree.BITXOR_ASG: case JCTree.BITAND_ASG:
2821 case JCTree.SL_ASG: case JCTree.SR_ASG: case JCTree.USR_ASG:
2822 case JCTree.PLUS_ASG: case JCTree.MINUS_ASG:
2823 case JCTree.MUL_ASG: case JCTree.DIV_ASG: case JCTree.MOD_ASG:
2824 case JCTree.APPLY: case JCTree.NEWCLASS:
2825 case JCTree.ERRONEOUS:
2826 return t;
2827 default:
2828 JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
2829 error(ret, "not.stmt");
2830 return ret;
2831 }
2832 }
2833
2834 /** Return precedence of operator represented by token,
2835 * -1 if token is not a binary operator. @see TreeInfo.opPrec
2836 */
2837 static int prec(TokenKind token) {
2838 int oc = optag(token);
2839 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1;
2840 }
2841
2842 /**
2843 * Return the lesser of two positions, making allowance for either one
2844 * being unset.
2845 */
2846 static int earlier(int pos1, int pos2) {
2847 if (pos1 == Position.NOPOS)
2848 return pos2;
2849 if (pos2 == Position.NOPOS)
2850 return pos1;
2851 return (pos1 < pos2 ? pos1 : pos2);
2852 }
2853
2854 /** Return operation tag of binary operator represented by token,
2855 * -1 if token is not a binary operator.
2856 */
2857 static int optag(TokenKind token) {
2858 switch (token) {
2859 case BARBAR:
2860 return JCTree.OR;
2861 case AMPAMP:
2862 return JCTree.AND;
2863 case BAR:
2864 return JCTree.BITOR;
2865 case BAREQ:
2866 return JCTree.BITOR_ASG;
2867 case CARET:
2868 return JCTree.BITXOR;
2869 case CARETEQ:
2870 return JCTree.BITXOR_ASG;
2871 case AMP:
2872 return JCTree.BITAND;
2873 case AMPEQ:
2874 return JCTree.BITAND_ASG;
2875 case EQEQ:
2876 return JCTree.EQ;
2877 case BANGEQ:
2878 return JCTree.NE;
2879 case LT:
2880 return JCTree.LT;
2881 case GT:
2882 return JCTree.GT;
2883 case LTEQ:
2884 return JCTree.LE;
2885 case GTEQ:
2886 return JCTree.GE;
2887 case LTLT:
2888 return JCTree.SL;
2889 case LTLTEQ:
2890 return JCTree.SL_ASG;
2891 case GTGT:
2892 return JCTree.SR;
2893 case GTGTEQ:
2894 return JCTree.SR_ASG;
2895 case GTGTGT:
2896 return JCTree.USR;
2897 case GTGTGTEQ:
2898 return JCTree.USR_ASG;
2899 case PLUS:
2900 return JCTree.PLUS;
2901 case PLUSEQ:
2902 return JCTree.PLUS_ASG;
2903 case SUB:
2904 return JCTree.MINUS;
2905 case SUBEQ:
2906 return JCTree.MINUS_ASG;
2907 case STAR:
2908 return JCTree.MUL;
2909 case STAREQ:
2910 return JCTree.MUL_ASG;
2911 case SLASH:
2912 return JCTree.DIV;
2913 case SLASHEQ:
2914 return JCTree.DIV_ASG;
2915 case PERCENT:
2916 return JCTree.MOD;
2917 case PERCENTEQ:
2918 return JCTree.MOD_ASG;
2919 case INSTANCEOF:
2920 return JCTree.TYPETEST;
2921 default:
2922 return -1;
2923 }
2924 }
2925
2926 /** Return operation tag of unary operator represented by token,
2927 * -1 if token is not a binary operator.
2928 */
2929 static int unoptag(TokenKind token) {
2930 switch (token) {
2931 case PLUS:
2932 return JCTree.POS;
2933 case SUB:
2934 return JCTree.NEG;
2935 case BANG:
2936 return JCTree.NOT;
2937 case TILDE:
2938 return JCTree.COMPL;
2939 case PLUSPLUS:
2940 return JCTree.PREINC;
2941 case SUBSUB:
2942 return JCTree.PREDEC;
2943 default:
2944 return -1;
2945 }
2946 }
2947
2948 /** Return type tag of basic type represented by token,
2949 * -1 if token is not a basic type identifier.
2950 */
2951 static int typetag(TokenKind token) {
2952 switch (token) {
2953 case BYTE:
2954 return TypeTags.BYTE;
2955 case CHAR:
2956 return TypeTags.CHAR;
2957 case SHORT:
2958 return TypeTags.SHORT;
2959 case INT:
2960 return TypeTags.INT;
2961 case LONG:
2962 return TypeTags.LONG;
2963 case FLOAT:
2964 return TypeTags.FLOAT;
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package com.sun.tools.javac.parser;
27
28 import java.util.*;
29
30 import com.sun.tools.javac.code.*;
31 import com.sun.tools.javac.parser.Tokens.*;
32 import com.sun.tools.javac.tree.*;
33 import com.sun.tools.javac.tree.JCTree.*;
34 import com.sun.tools.javac.util.*;
35 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
36 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
37 import com.sun.tools.javac.util.List;
38
39 import static com.sun.tools.javac.util.ListBuffer.lb;
40 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
41 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
42 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
43 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
44 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
45 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
46 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
47 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
48 import static com.sun.tools.javac.tree.JCTree.Tag.*;
49
50 /** The parser maps a token sequence into an abstract syntax
51 * tree. It operates by recursive descent, with code derived
52 * systematically from an LL(1) grammar. For efficiency reasons, an
53 * operator precedence scheme is used for parsing binary operation
54 * expressions.
55 *
56 * <p><b>This is NOT part of any supported API.
57 * If you write code that depends on this, you do so at your own risk.
58 * This code and its internal interfaces are subject to change or
59 * deletion without notice.</b>
60 */
61 public class JavacParser implements Parser {
62
63 /** The number of precedence levels of infix operators.
64 */
65 private static final int infixPrecedenceLevels = 10;
66
67 /** The scanner used for lexical analysis.
68 */
748 int top = 0;
749 odStack[0] = t;
750 int startPos = token.pos;
751 Token topOp = Tokens.DUMMY;
752 while (prec(token.kind) >= minprec) {
753 opStack[top] = topOp;
754 top++;
755 topOp = token;
756 nextToken();
757 odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3();
758 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
759 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
760 odStack[top]);
761 top--;
762 topOp = opStack[top];
763 }
764 }
765 Assert.check(top == 0);
766 t = odStack[0];
767
768 if (t.hasTag(JCTree.Tag.PLUS)) {
769 StringBuffer buf = foldStrings(t);
770 if (buf != null) {
771 t = toP(F.at(startPos).Literal(TypeTags.CLASS, buf.toString()));
772 }
773 }
774
775 odStackSupply.elems = savedOd; // optimization
776 opStackSupply.elems = savedOp; // optimization
777 return t;
778 }
779 //where
780 /** Construct a binary or type test node.
781 */
782 private JCExpression makeOp(int pos,
783 TokenKind topOp,
784 JCExpression od1,
785 JCExpression od2)
786 {
787 if (topOp == INSTANCEOF) {
788 return F.at(pos).TypeTest(od1, od2);
789 } else {
790 return F.at(pos).Binary(optag(topOp), od1, od2);
791 }
792 }
793 /** If tree is a concatenation of string literals, replace it
794 * by a single literal representing the concatenated string.
795 */
796 protected StringBuffer foldStrings(JCTree tree) {
797 if (!allowStringFolding)
798 return null;
799 List<String> buf = List.nil();
800 while (true) {
801 if (tree.hasTag(LITERAL)) {
802 JCLiteral lit = (JCLiteral) tree;
803 if (lit.typetag == TypeTags.CLASS) {
804 StringBuffer sbuf =
805 new StringBuffer((String)lit.value);
806 while (buf.nonEmpty()) {
807 sbuf.append(buf.head);
808 buf = buf.tail;
809 }
810 return sbuf;
811 }
812 } else if (tree.hasTag(JCTree.Tag.PLUS)) {
813 JCBinary op = (JCBinary)tree;
814 if (op.rhs.hasTag(LITERAL)) {
815 JCLiteral lit = (JCLiteral) op.rhs;
816 if (lit.typetag == TypeTags.CLASS) {
817 buf = buf.prepend((String) lit.value);
818 tree = op.lhs;
819 continue;
820 }
821 }
822 }
823 return null;
824 }
825 }
826
827 /** optimization: To save allocating a new operand/operator stack
828 * for every binary operation, we use supplys.
829 */
830 ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>();
831 ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>();
832
833 private JCExpression[] newOdStack() {
834 if (odStackSupply.elems == odStackSupply.last)
890 nextToken();
891 mode = EXPR;
892 if (tk == SUB &&
893 (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
894 token.radix() == 10) {
895 mode = EXPR;
896 t = literal(names.hyphen, pos);
897 } else {
898 t = term3();
899 return F.at(pos).Unary(unoptag(tk), t);
900 }
901 } else return illegal();
902 break;
903 case LPAREN:
904 if (typeArgs == null && (mode & EXPR) != 0) {
905 nextToken();
906 mode = EXPR | TYPE | NOPARAMS;
907 t = term3();
908 if ((mode & TYPE) != 0 && token.kind == LT) {
909 // Could be a cast to a parameterized type
910 JCTree.Tag op = JCTree.Tag.LT;
911 int pos1 = token.pos;
912 nextToken();
913 mode &= (EXPR | TYPE);
914 mode |= TYPEARG;
915 JCExpression t1 = term3();
916 if ((mode & TYPE) != 0 &&
917 (token.kind == COMMA || token.kind == GT)) {
918 mode = TYPE;
919 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
920 args.append(t1);
921 while (token.kind == COMMA) {
922 nextToken();
923 args.append(typeArgument());
924 }
925 accept(GT);
926 t = toP(F.at(pos1).TypeApply(t, args.toList()));
927 checkGenerics();
928 while (token.kind == DOT) {
929 nextToken();
930 mode = TYPE;
1144 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1145 if (typeArgs != null) return illegal();
1146 mode = EXPR;
1147 int pos2 = token.pos;
1148 nextToken();
1149 if (token.kind == LT) typeArgs = typeArguments(false);
1150 t = innerCreator(pos2, typeArgs, t);
1151 typeArgs = null;
1152 } else {
1153 t = toP(F.at(pos1).Select(t, ident()));
1154 t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1155 typeArgs = null;
1156 }
1157 } else {
1158 break;
1159 }
1160 }
1161 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1162 mode = EXPR;
1163 t = to(F.at(token.pos).Unary(
1164 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1165 nextToken();
1166 }
1167 return toP(t);
1168 }
1169
1170 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1171 */
1172 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1173 nextToken();
1174 if (token.kind == LPAREN || typeArgs != null) {
1175 t = arguments(typeArgs, t);
1176 } else {
1177 int pos = token.pos;
1178 accept(DOT);
1179 typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1180 t = toP(F.at(pos).Select(t, ident()));
1181 t = argumentsOpt(typeArgs, t);
1182 }
1183 return t;
1184 }
1617 case INTERFACE:
1618 case CLASS:
1619 String dc = token.docComment;
1620 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1621 break;
1622 case ENUM:
1623 case ASSERT:
1624 if (allowEnums && token.kind == ENUM) {
1625 error(token.pos, "local.enum");
1626 dc = token.docComment;
1627 stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
1628 break;
1629 } else if (allowAsserts && token.kind == ASSERT) {
1630 stats.append(parseStatement());
1631 break;
1632 }
1633 /* fall through to default */
1634 default:
1635 Token prevToken = token;
1636 JCExpression t = term(EXPR | TYPE);
1637 if (token.kind == COLON && t.hasTag(IDENT)) {
1638 nextToken();
1639 JCStatement stat = parseStatement();
1640 stats.append(F.at(pos).Labelled(prevToken.name(), stat));
1641 } else if ((lastmode & TYPE) != 0 &&
1642 (token.kind == IDENTIFIER ||
1643 token.kind == ASSERT ||
1644 token.kind == ENUM)) {
1645 pos = token.pos;
1646 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
1647 F.at(pos);
1648 stats.appendList(variableDeclarators(mods, t,
1649 new ListBuffer<JCStatement>()));
1650 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon
1651 storeEnd(stats.elems.last(), token.endPos);
1652 accept(SEMI);
1653 } else {
1654 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1655 stats.append(to(F.at(pos).Exec(checkExprStat(t))));
1656 accept(SEMI);
1657 }
1692 int pos = token.pos;
1693 switch (token.kind) {
1694 case LBRACE:
1695 return block();
1696 case IF: {
1697 nextToken();
1698 JCExpression cond = parExpression();
1699 JCStatement thenpart = parseStatement();
1700 JCStatement elsepart = null;
1701 if (token.kind == ELSE) {
1702 nextToken();
1703 elsepart = parseStatement();
1704 }
1705 return F.at(pos).If(cond, thenpart, elsepart);
1706 }
1707 case FOR: {
1708 nextToken();
1709 accept(LPAREN);
1710 List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit();
1711 if (inits.length() == 1 &&
1712 inits.head.hasTag(VARDEF) &&
1713 ((JCVariableDecl) inits.head).init == null &&
1714 token.kind == COLON) {
1715 checkForeach();
1716 JCVariableDecl var = (JCVariableDecl)inits.head;
1717 accept(COLON);
1718 JCExpression expr = parseExpression();
1719 accept(RPAREN);
1720 JCStatement body = parseStatement();
1721 return F.at(pos).ForeachLoop(var, expr, body);
1722 } else {
1723 accept(SEMI);
1724 JCExpression cond = token.kind == SEMI ? null : parseExpression();
1725 accept(SEMI);
1726 List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate();
1727 accept(RPAREN);
1728 JCStatement body = parseStatement();
1729 return F.at(pos).ForLoop(inits, cond, steps, body);
1730 }
1731 }
1732 case WHILE: {
1825 return toP(F.Exec(syntaxError("catch.without.try")));
1826 case ASSERT: {
1827 if (allowAsserts && token.kind == ASSERT) {
1828 nextToken();
1829 JCExpression assertion = parseExpression();
1830 JCExpression message = null;
1831 if (token.kind == COLON) {
1832 nextToken();
1833 message = parseExpression();
1834 }
1835 JCAssert t = to(F.at(pos).Assert(assertion, message));
1836 accept(SEMI);
1837 return t;
1838 }
1839 /* else fall through to default case */
1840 }
1841 case ENUM:
1842 default:
1843 Token prevToken = token;
1844 JCExpression expr = parseExpression();
1845 if (token.kind == COLON && expr.hasTag(IDENT)) {
1846 nextToken();
1847 JCStatement stat = parseStatement();
1848 return F.at(pos).Labelled(prevToken.name(), stat);
1849 } else {
1850 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
1851 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr)));
1852 accept(SEMI);
1853 return stat;
1854 }
1855 }
1856 }
1857
1858 /** CatchClause = CATCH "(" FormalParameter ")" Block
1859 */
1860 protected JCCatch catchClause() {
1861 int pos = token.pos;
1862 accept(CATCH);
1863 accept(LPAREN);
1864 JCModifiers mods = optFinal(Flags.PARAMETER);
1865 List<JCExpression> catchTypes = catchTypes();
2078 accept(LPAREN);
2079 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2080 if (token.kind != RPAREN) {
2081 buf.append(annotationFieldValue());
2082 while (token.kind == COMMA) {
2083 nextToken();
2084 buf.append(annotationFieldValue());
2085 }
2086 }
2087 accept(RPAREN);
2088 return buf.toList();
2089 }
2090
2091 /** AnnotationFieldValue = AnnotationValue
2092 * | Identifier "=" AnnotationValue
2093 */
2094 JCExpression annotationFieldValue() {
2095 if (token.kind == IDENTIFIER) {
2096 mode = EXPR;
2097 JCExpression t1 = term1();
2098 if (t1.hasTag(IDENT) && token.kind == EQ) {
2099 int pos = token.pos;
2100 accept(EQ);
2101 JCExpression v = annotationValue();
2102 return toP(F.at(pos).Assign(t1, v));
2103 } else {
2104 return t1;
2105 }
2106 }
2107 return annotationValue();
2108 }
2109
2110 /* AnnotationValue = ConditionalExpression
2111 * | Annotation
2112 * | "{" [ AnnotationValue { "," AnnotationValue } ] [","] "}"
2113 */
2114 JCExpression annotationValue() {
2115 int pos;
2116 switch (token.kind) {
2117 case MONKEYS_AT:
2118 pos = token.pos;
2608 return List.<JCTree>of(block(pos, mods.flags));
2609 } else {
2610 pos = token.pos;
2611 List<JCTypeParameter> typarams = typeParametersOpt();
2612 // if there are type parameters but no modifiers, save the start
2613 // position of the method in the modifiers.
2614 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
2615 mods.pos = pos;
2616 storeEnd(mods, pos);
2617 }
2618 Token tk = token;
2619 pos = token.pos;
2620 JCExpression type;
2621 boolean isVoid = token.kind == VOID;
2622 if (isVoid) {
2623 type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2624 nextToken();
2625 } else {
2626 type = parseType();
2627 }
2628 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
2629 if (isInterface || tk.name() != className)
2630 error(pos, "invalid.meth.decl.ret.type.req");
2631 return List.of(methodDeclaratorRest(
2632 pos, mods, null, names.init, typarams,
2633 isInterface, true, dc));
2634 } else {
2635 pos = token.pos;
2636 Name name = ident();
2637 if (token.kind == LPAREN) {
2638 return List.of(methodDeclaratorRest(
2639 pos, mods, type, name, typarams,
2640 isInterface, isVoid, dc));
2641 } else if (!isVoid && typarams.isEmpty()) {
2642 List<JCTree> defs =
2643 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
2644 new ListBuffer<JCTree>()).toList();
2645 storeEnd(defs.last(), token.endPos);
2646 accept(SEMI);
2647 return defs;
2648 } else {
2805 }
2806
2807 /* ---------- auxiliary methods -------------- */
2808
2809 void error(int pos, String key, Object ... args) {
2810 log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2811 }
2812
2813 void error(DiagnosticPosition pos, String key, Object ... args) {
2814 log.error(DiagnosticFlag.SYNTAX, pos, key, args);
2815 }
2816
2817 void warning(int pos, String key, Object ... args) {
2818 log.warning(pos, key, args);
2819 }
2820
2821 /** Check that given tree is a legal expression statement.
2822 */
2823 protected JCExpression checkExprStat(JCExpression t) {
2824 switch(t.getTag()) {
2825 case PREINC: case PREDEC:
2826 case POSTINC: case POSTDEC:
2827 case ASSIGN:
2828 case BITOR_ASG: case BITXOR_ASG: case BITAND_ASG:
2829 case SL_ASG: case SR_ASG: case USR_ASG:
2830 case PLUS_ASG: case MINUS_ASG:
2831 case MUL_ASG: case DIV_ASG: case MOD_ASG:
2832 case APPLY: case NEWCLASS:
2833 case ERRONEOUS:
2834 return t;
2835 default:
2836 JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
2837 error(ret, "not.stmt");
2838 return ret;
2839 }
2840 }
2841
2842 /** Return precedence of operator represented by token,
2843 * -1 if token is not a binary operator. @see TreeInfo.opPrec
2844 */
2845 static int prec(TokenKind token) {
2846 JCTree.Tag oc = optag(token);
2847 return (oc.ordinal() > NO_TAG.ordinal()) ? TreeInfo.opPrec(oc) : -1;
2848 }
2849
2850 /**
2851 * Return the lesser of two positions, making allowance for either one
2852 * being unset.
2853 */
2854 static int earlier(int pos1, int pos2) {
2855 if (pos1 == Position.NOPOS)
2856 return pos2;
2857 if (pos2 == Position.NOPOS)
2858 return pos1;
2859 return (pos1 < pos2 ? pos1 : pos2);
2860 }
2861
2862 /** Return operation tag of binary operator represented by token,
2863 * No_TAG if token is not a binary operator.
2864 */
2865 static JCTree.Tag optag(TokenKind token) {
2866 switch (token) {
2867 case BARBAR:
2868 return OR;
2869 case AMPAMP:
2870 return AND;
2871 case BAR:
2872 return BITOR;
2873 case BAREQ:
2874 return BITOR_ASG;
2875 case CARET:
2876 return BITXOR;
2877 case CARETEQ:
2878 return BITXOR_ASG;
2879 case AMP:
2880 return BITAND;
2881 case AMPEQ:
2882 return BITAND_ASG;
2883 case EQEQ:
2884 return JCTree.Tag.EQ;
2885 case BANGEQ:
2886 return NE;
2887 case LT:
2888 return JCTree.Tag.LT;
2889 case GT:
2890 return JCTree.Tag.GT;
2891 case LTEQ:
2892 return LE;
2893 case GTEQ:
2894 return GE;
2895 case LTLT:
2896 return SL;
2897 case LTLTEQ:
2898 return SL_ASG;
2899 case GTGT:
2900 return SR;
2901 case GTGTEQ:
2902 return SR_ASG;
2903 case GTGTGT:
2904 return USR;
2905 case GTGTGTEQ:
2906 return USR_ASG;
2907 case PLUS:
2908 return JCTree.Tag.PLUS;
2909 case PLUSEQ:
2910 return PLUS_ASG;
2911 case SUB:
2912 return MINUS;
2913 case SUBEQ:
2914 return MINUS_ASG;
2915 case STAR:
2916 return MUL;
2917 case STAREQ:
2918 return MUL_ASG;
2919 case SLASH:
2920 return DIV;
2921 case SLASHEQ:
2922 return DIV_ASG;
2923 case PERCENT:
2924 return MOD;
2925 case PERCENTEQ:
2926 return MOD_ASG;
2927 case INSTANCEOF:
2928 return TYPETEST;
2929 default:
2930 return NO_TAG;
2931 }
2932 }
2933
2934 /** Return operation tag of unary operator represented by token,
2935 * No_TAG if token is not a binary operator.
2936 */
2937 static JCTree.Tag unoptag(TokenKind token) {
2938 switch (token) {
2939 case PLUS:
2940 return POS;
2941 case SUB:
2942 return NEG;
2943 case BANG:
2944 return NOT;
2945 case TILDE:
2946 return COMPL;
2947 case PLUSPLUS:
2948 return PREINC;
2949 case SUBSUB:
2950 return PREDEC;
2951 default:
2952 return NO_TAG;
2953 }
2954 }
2955
2956 /** Return type tag of basic type represented by token,
2957 * -1 if token is not a basic type identifier.
2958 */
2959 static int typetag(TokenKind token) {
2960 switch (token) {
2961 case BYTE:
2962 return TypeTags.BYTE;
2963 case CHAR:
2964 return TypeTags.CHAR;
2965 case SHORT:
2966 return TypeTags.SHORT;
2967 case INT:
2968 return TypeTags.INT;
2969 case LONG:
2970 return TypeTags.LONG;
2971 case FLOAT:
2972 return TypeTags.FLOAT;
|