src/share/classes/com/sun/tools/javac/parser/JavacParser.java

changeset 1145
3343b22e2761
parent 1144
9448fe783fd2
child 1148
9350d0498d21
equal deleted inserted replaced
1144:9448fe783fd2 1145:3343b22e2761
25 25
26 package com.sun.tools.javac.parser; 26 package com.sun.tools.javac.parser;
27 27
28 import java.util.*; 28 import java.util.*;
29 29
30 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
31
30 import com.sun.tools.javac.code.*; 32 import com.sun.tools.javac.code.*;
31 import com.sun.tools.javac.parser.Tokens.*; 33 import com.sun.tools.javac.parser.Tokens.*;
32 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle; 34 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
33 import com.sun.tools.javac.tree.*; 35 import com.sun.tools.javac.tree.*;
34 import com.sun.tools.javac.tree.JCTree.*; 36 import com.sun.tools.javac.tree.JCTree.*;
110 this.allowDiamond = source.allowDiamond(); 112 this.allowDiamond = source.allowDiamond();
111 this.allowMulticatch = source.allowMulticatch(); 113 this.allowMulticatch = source.allowMulticatch();
112 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true); 114 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
113 this.allowLambda = source.allowLambda() && 115 this.allowLambda = source.allowLambda() &&
114 fac.options.isSet("allowLambda"); 116 fac.options.isSet("allowLambda");
117 this.allowMethodReferences = source.allowMethodReferences() &&
118 fac.options.isSet("allowMethodReferences");
115 this.keepDocComments = keepDocComments; 119 this.keepDocComments = keepDocComments;
116 docComments = keepDocComments ? new HashMap<JCTree,String>() : null; 120 docComments = keepDocComments ? new HashMap<JCTree,String>() : null;
117 this.keepLineMap = keepLineMap; 121 this.keepLineMap = keepLineMap;
118 this.errorTree = F.Erroneous(); 122 this.errorTree = F.Erroneous();
119 endPosTable = newEndPosTable(keepEndPositions); 123 endPosTable = newEndPosTable(keepEndPositions);
169 boolean allowStringFolding; 173 boolean allowStringFolding;
170 174
171 /** Switch: should we recognize lambda expressions? 175 /** Switch: should we recognize lambda expressions?
172 */ 176 */
173 boolean allowLambda; 177 boolean allowLambda;
178
179 /** Switch: should we allow method/constructor references?
180 */
181 boolean allowMethodReferences;
174 182
175 /** Switch: should we keep docComments? 183 /** Switch: should we keep docComments?
176 */ 184 */
177 boolean keepDocComments; 185 boolean keepDocComments;
178 186
777 while (prec(token.kind) >= minprec) { 785 while (prec(token.kind) >= minprec) {
778 opStack[top] = topOp; 786 opStack[top] = topOp;
779 top++; 787 top++;
780 topOp = token; 788 topOp = token;
781 nextToken(); 789 nextToken();
782 odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); 790 odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3NoParams();
783 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { 791 while (top > 0 && prec(topOp.kind) >= prec(token.kind)) {
784 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], 792 odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1],
785 odStack[top]); 793 odStack[top]);
786 top--; 794 top--;
787 topOp = opStack[top]; 795 topOp = opStack[top];
880 * | [TypeArguments] SUPER SuperSuffix 888 * | [TypeArguments] SUPER SuperSuffix
881 * | NEW [TypeArguments] Creator 889 * | NEW [TypeArguments] Creator
882 * | "(" Arguments ")" "->" ( Expression | Block ) 890 * | "(" Arguments ")" "->" ( Expression | Block )
883 * | Ident "->" ( Expression | Block ) 891 * | Ident "->" ( Expression | Block )
884 * | Ident { "." Ident } 892 * | Ident { "." Ident }
893 * | Expression3 MemberReferenceSuffix
885 * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 894 * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
886 * | Arguments 895 * | Arguments
887 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 896 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
888 * ] 897 * ]
889 * | BasicType BracketsOpt "." CLASS 898 * | BasicType BracketsOpt "." CLASS
920 (token.kind == INTLITERAL || token.kind == LONGLITERAL) && 929 (token.kind == INTLITERAL || token.kind == LONGLITERAL) &&
921 token.radix() == 10) { 930 token.radix() == 10) {
922 mode = EXPR; 931 mode = EXPR;
923 t = literal(names.hyphen, pos); 932 t = literal(names.hyphen, pos);
924 } else { 933 } else {
925 t = term3(); 934 t = term3NoParams();
926 return F.at(pos).Unary(unoptag(tk), t); 935 return F.at(pos).Unary(unoptag(tk), t);
927 } 936 }
928 } else return illegal(); 937 } else return illegal();
929 break; 938 break;
930 case LPAREN: 939 case LPAREN:
936 //implicit n-ary lambda 945 //implicit n-ary lambda
937 t = lambdaExpressionOrStatement(true, peekToken(FINAL), pos); 946 t = lambdaExpressionOrStatement(true, peekToken(FINAL), pos);
938 break; 947 break;
939 } else { 948 } else {
940 nextToken(); 949 nextToken();
941 mode = EXPR | TYPE | NOPARAMS; 950 mode = EXPR | TYPE;
942 t = term3(); 951 t = term3NoParams();
943 if ((mode & TYPE) != 0 && token.kind == LT) { 952 if ((mode & TYPE) != 0 && token.kind == LT) {
944 // Could be a cast to a parameterized type 953 // Could be a cast to a parameterized type
945 JCTree.Tag op = JCTree.Tag.LT; 954 JCTree.Tag op = JCTree.Tag.LT;
946 int pos1 = token.pos; 955 int pos1 = token.pos;
947 nextToken(); 956 nextToken();
1000 1009
1001 accept(RPAREN); 1010 accept(RPAREN);
1002 lastmode = mode; 1011 lastmode = mode;
1003 mode = EXPR; 1012 mode = EXPR;
1004 if ((lastmode & EXPR) == 0) { 1013 if ((lastmode & EXPR) == 0) {
1005 JCExpression t1 = term3(); 1014 JCExpression t1 = term3NoParams();
1006 return F.at(pos).TypeCast(t, t1); 1015 return F.at(pos).TypeCast(t, t1);
1007 } else if ((lastmode & TYPE) != 0) { 1016 } else if ((lastmode & TYPE) != 0) {
1008 switch (token.kind) { 1017 switch (token.kind) {
1009 /*case PLUSPLUS: case SUBSUB: */ 1018 /*case PLUSPLUS: case SUBSUB: */
1010 case BANG: case TILDE: 1019 case BANG: case TILDE:
1013 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL: 1022 case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
1014 case TRUE: case FALSE: case NULL: 1023 case TRUE: case FALSE: case NULL:
1015 case NEW: case IDENTIFIER: case ASSERT: case ENUM: 1024 case NEW: case IDENTIFIER: case ASSERT: case ENUM:
1016 case BYTE: case SHORT: case CHAR: case INT: 1025 case BYTE: case SHORT: case CHAR: case INT:
1017 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: 1026 case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
1018 JCExpression t1 = term3(); 1027 JCExpression t1 = term3NoParams();
1019 return F.at(pos).TypeCast(t, t1); 1028 return F.at(pos).TypeCast(t, t1);
1020 } 1029 }
1021 } 1030 }
1022 } else { 1031 } else {
1023 return illegal(); 1032 return illegal();
1132 } 1141 }
1133 } 1142 }
1134 // typeArgs saved for next loop iteration. 1143 // typeArgs saved for next loop iteration.
1135 t = toP(F.at(pos).Select(t, ident())); 1144 t = toP(F.at(pos).Select(t, ident()));
1136 break; 1145 break;
1146 case LT:
1147 if ((mode & (TYPE | NOPARAMS)) == 0) {
1148 //could be an unbound method reference whose qualifier
1149 //is a generic type i.e. A<S>#m
1150 mode = EXPR | TYPE;
1151 JCTree.Tag op = JCTree.Tag.LT;
1152 int pos1 = token.pos;
1153 nextToken();
1154 mode |= EXPR | TYPE | TYPEARG;
1155 JCExpression t1 = term3();
1156 if ((mode & TYPE) != 0 &&
1157 (token.kind == COMMA || token.kind == GT)) {
1158 mode = TYPE;
1159 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
1160 args.append(t1);
1161 while (token.kind == COMMA) {
1162 nextToken();
1163 args.append(typeArgument());
1164 }
1165 accept(GT);
1166 t = toP(F.at(pos1).TypeApply(t, args.toList()));
1167 checkGenerics();
1168 while (token.kind == DOT) {
1169 nextToken();
1170 mode = TYPE;
1171 t = toP(F.at(token.pos).Select(t, ident()));
1172 t = typeArgumentsOpt(t);
1173 }
1174 if (token.kind != HASH) {
1175 //method reference expected here
1176 t = illegal();
1177 }
1178 mode = EXPR;
1179 break;
1180 } else if ((mode & EXPR) != 0) {
1181 //rollback - it was a binary expression
1182 mode = EXPR;
1183 JCExpression e = term2Rest(t1, TreeInfo.shiftPrec);
1184 t = F.at(pos1).Binary(op, t, e);
1185 t = termRest(term1Rest(term2Rest(t, TreeInfo.orPrec)));
1186 }
1187 }
1188 break loop;
1137 default: 1189 default:
1138 break loop; 1190 break loop;
1139 } 1191 }
1140 } 1192 }
1141 } 1193 }
1169 break; 1221 break;
1170 default: 1222 default:
1171 return illegal(); 1223 return illegal();
1172 } 1224 }
1173 return term3Rest(t, typeArgs); 1225 return term3Rest(t, typeArgs);
1226 }
1227
1228 JCExpression term3NoParams() {
1229 try {
1230 mode |= NOPARAMS;
1231 return term3();
1232 } finally {
1233 mode &= ~NOPARAMS;
1234 }
1174 } 1235 }
1175 1236
1176 JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) { 1237 JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
1177 if (typeArgs != null) illegal(); 1238 if (typeArgs != null) illegal();
1178 while (true) { 1239 while (true) {
1216 } else { 1277 } else {
1217 t = toP(F.at(pos1).Select(t, ident())); 1278 t = toP(F.at(pos1).Select(t, ident()));
1218 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 1279 t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1219 typeArgs = null; 1280 typeArgs = null;
1220 } 1281 }
1282 } else if ((mode & EXPR) != 0 && token.kind == HASH) {
1283 mode = EXPR;
1284 if (typeArgs != null) return illegal();
1285 accept(HASH);
1286 t = memberReferenceSuffix(pos1, t);
1221 } else { 1287 } else {
1222 break; 1288 break;
1223 } 1289 }
1224 } 1290 }
1225 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) { 1291 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1279 */ 1345 */
1280 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 1346 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) {
1281 nextToken(); 1347 nextToken();
1282 if (token.kind == LPAREN || typeArgs != null) { 1348 if (token.kind == LPAREN || typeArgs != null) {
1283 t = arguments(typeArgs, t); 1349 t = arguments(typeArgs, t);
1350 } else if (token.kind == HASH) {
1351 if (typeArgs != null) return illegal();
1352 t = memberReferenceSuffix(t);
1284 } else { 1353 } else {
1285 int pos = token.pos; 1354 int pos = token.pos;
1286 accept(DOT); 1355 accept(DOT);
1287 typeArgs = (token.kind == LT) ? typeArguments(false) : null; 1356 typeArgs = (token.kind == LT) ? typeArguments(false) : null;
1288 t = toP(F.at(pos).Select(t, ident())); 1357 t = toP(F.at(pos).Select(t, ident()));
1486 mode = TYPE; 1555 mode = TYPE;
1487 } else { 1556 } else {
1488 syntaxError(token.pos, "dot.class.expected"); 1557 syntaxError(token.pos, "dot.class.expected");
1489 } 1558 }
1490 return t; 1559 return t;
1560 }
1561
1562 /**
1563 * MemberReferenceSuffix = "#" [TypeArguments] Ident
1564 * | "#" [TypeArguments] "new"
1565 */
1566 JCExpression memberReferenceSuffix(JCExpression t) {
1567 int pos1 = token.pos;
1568 accept(HASH);
1569 return memberReferenceSuffix(pos1, t);
1570 }
1571
1572 JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
1573 checkMethodReferences();
1574 mode = EXPR;
1575 List<JCExpression> typeArgs = null;
1576 if (token.kind == LT) {
1577 typeArgs = typeArguments(false);
1578 }
1579 Name refName = null;
1580 ReferenceMode refMode = null;
1581 if (token.kind == NEW) {
1582 refMode = ReferenceMode.NEW;
1583 refName = names.init;
1584 nextToken();
1585 } else {
1586 refMode = ReferenceMode.INVOKE;
1587 refName = ident();
1588 }
1589 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
1491 } 1590 }
1492 1591
1493 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 1592 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1494 */ 1593 */
1495 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 1594 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
3164 if (!allowLambda) { 3263 if (!allowLambda) {
3165 log.error(token.pos, "lambda.not.supported.in.source", source.name); 3264 log.error(token.pos, "lambda.not.supported.in.source", source.name);
3166 allowLambda = true; 3265 allowLambda = true;
3167 } 3266 }
3168 } 3267 }
3268 void checkMethodReferences() {
3269 if (!allowMethodReferences) {
3270 log.error(token.pos, "method.references.not.supported.in.source", source.name);
3271 allowMethodReferences = true;
3272 }
3273 }
3169 3274
3170 /* 3275 /*
3171 * a functional source tree and end position mappings 3276 * a functional source tree and end position mappings
3172 */ 3277 */
3173 protected class SimpleEndPosTable extends AbstractEndPosTable { 3278 protected class SimpleEndPosTable extends AbstractEndPosTable {

mercurial