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

changeset 308
03944ee4fac4
parent 267
e2722bd43f3a
child 310
7c154fdc3547
equal deleted inserted replaced
307:ca063536e4a6 308:03944ee4fac4
73 private Source source; 73 private Source source;
74 74
75 /** The name table. */ 75 /** The name table. */
76 private Names names; 76 private Names names;
77 77
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;
113
78 /** Construct a parser from a given scanner, tree factory and log. 114 /** Construct a parser from a given scanner, tree factory and log.
79 */ 115 */
80 protected JavacParser(ParserFactory fac, 116 protected JavacParser(ParserFactory fac,
81 Lexer S, 117 Lexer S,
82 boolean keepDocComments, 118 boolean keepDocComments,
93 this.allowAsserts = source.allowAsserts(); 129 this.allowAsserts = source.allowAsserts();
94 this.allowEnums = source.allowEnums(); 130 this.allowEnums = source.allowEnums();
95 this.allowForeach = source.allowForeach(); 131 this.allowForeach = source.allowForeach();
96 this.allowStaticImport = source.allowStaticImport(); 132 this.allowStaticImport = source.allowStaticImport();
97 this.allowAnnotations = source.allowAnnotations(); 133 this.allowAnnotations = source.allowAnnotations();
134 this.allowTypeAnnotations = source.allowTypeAnnotations();
98 this.keepDocComments = keepDocComments; 135 this.keepDocComments = keepDocComments;
99 if (keepDocComments) 136 if (keepDocComments)
100 docComments = new HashMap<JCTree,String>(); 137 docComments = new HashMap<JCTree,String>();
101 this.keepLineMap = keepLineMap; 138 this.keepLineMap = keepLineMap;
102 this.errorTree = F.Erroneous(); 139 this.errorTree = F.Erroneous();
103 } 140 this.debugJSR308 = fac.options.get("TA:parser") != null;
141 }
142
143 /** Switch: debug output for type-annotations operations
144 */
145 boolean debugJSR308;
104 146
105 /** Switch: Should generics be recognized? 147 /** Switch: Should generics be recognized?
106 */ 148 */
107 boolean allowGenerics; 149 boolean allowGenerics;
108 150
127 boolean allowStaticImport; 169 boolean allowStaticImport;
128 170
129 /** Switch: should we recognize annotations? 171 /** Switch: should we recognize annotations?
130 */ 172 */
131 boolean allowAnnotations; 173 boolean allowAnnotations;
174
175 /** Switch: should we recognize type annotations?
176 */
177 boolean allowTypeAnnotations;
132 178
133 /** Switch: should we keep docComments? 179 /** Switch: should we keep docComments?
134 */ 180 */
135 boolean keepDocComments; 181 boolean keepDocComments;
136 182
556 */ 602 */
557 public JCExpression parseExpression() { 603 public JCExpression parseExpression() {
558 return term(EXPR); 604 return term(EXPR);
559 } 605 }
560 606
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 */
561 public JCExpression parseType() { 619 public JCExpression parseType() {
620 List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
621 return parseType(annotations);
622 }
623
624 public JCExpression parseType(List<JCTypeAnnotation> annotations) {
625 JCExpression result = unannotatedType();
626
627 if (!annotations.isEmpty())
628 result = F.AnnotatedType(annotations, result);
629
630 return result;
631 }
632
633 public JCExpression unannotatedType() {
562 return term(TYPE); 634 return term(TYPE);
563 } 635 }
564 636
565 JCExpression term(int newmode) { 637 JCExpression term(int newmode) {
566 int prevmode = mode; 638 int prevmode = mode;
790 * Primary = "(" Expression ")" 862 * Primary = "(" Expression ")"
791 * | Literal 863 * | Literal
792 * | [TypeArguments] THIS [Arguments] 864 * | [TypeArguments] THIS [Arguments]
793 * | [TypeArguments] SUPER SuperSuffix 865 * | [TypeArguments] SUPER SuperSuffix
794 * | NEW [TypeArguments] Creator 866 * | NEW [TypeArguments] Creator
795 * | Ident { "." Ident } 867 * | [Annotations] Ident { "." Ident }
796 * [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" ) 868 * [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
797 * | Arguments 869 * | Arguments
798 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator ) 870 * | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
799 * ] 871 * ]
800 * | BasicType BracketsOpt "." CLASS 872 * | BasicType BracketsOpt "." CLASS
801 * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-" 873 * PrefixOp = "++" | "--" | "!" | "~" | "+" | "-"
940 if (S.token() == LT) typeArgs = typeArguments(); 1012 if (S.token() == LT) typeArgs = typeArguments();
941 t = creator(pos, typeArgs); 1013 t = creator(pos, typeArgs);
942 typeArgs = null; 1014 typeArgs = null;
943 } else return illegal(); 1015 } else return illegal();
944 break; 1016 break;
1017 case MONKEYS_AT:
1018
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 }
1025
1026 JCExpression expr = term3();
1027
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;
945 case IDENTIFIER: case ASSERT: case ENUM: 1046 case IDENTIFIER: case ASSERT: case ENUM:
946 if (typeArgs != null) return illegal(); 1047 if (typeArgs != null) return illegal();
947 t = toP(F.at(S.pos()).Ident(ident())); 1048 t = toP(F.at(S.pos()).Ident(ident()));
948 loop: while (true) { 1049 loop: while (true) {
949 pos = S.pos(); 1050 pos = S.pos();
1051 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1052
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);
950 switch (S.token()) { 1057 switch (S.token()) {
951 case LBRACKET: 1058 case LBRACKET:
952 S.nextToken(); 1059 S.nextToken();
1060
953 if (S.token() == RBRACKET) { 1061 if (S.token() == RBRACKET) {
1062
954 S.nextToken(); 1063 S.nextToken();
955 t = bracketsOpt(t); 1064
1065 t = bracketsOpt(t, annos);
956 t = toP(F.at(pos).TypeArray(t)); 1066 t = toP(F.at(pos).TypeArray(t));
957 t = bracketsSuffix(t); 1067 t = bracketsSuffix(t);
958 } else { 1068 } else {
959 if ((mode & EXPR) != 0) { 1069 if ((mode & EXPR) != 0) {
960 mode = EXPR; 1070 mode = EXPR;
961 JCExpression t1 = term(); 1071 JCExpression t1 = term();
1072 if (!annos.isEmpty()) t = illegal(annos.head.pos);
962 t = to(F.at(pos).Indexed(t, t1)); 1073 t = to(F.at(pos).Indexed(t, t1));
963 } 1074 }
964 accept(RBRACKET); 1075 accept(RBRACKET);
965 } 1076 }
966 break loop; 1077 break loop;
1009 } 1120 }
1010 } 1121 }
1011 // typeArgs saved for next loop iteration. 1122 // typeArgs saved for next loop iteration.
1012 t = toP(F.at(pos).Select(t, ident())); 1123 t = toP(F.at(pos).Select(t, ident()));
1013 break; 1124 break;
1125 case ELLIPSIS:
1126 assert this.permitTypeAnnotationsPushBack;
1127 typeAnnotationsPushedBack = annos;
1128 break loop;
1014 default: 1129 default:
1015 break loop; 1130 break loop;
1016 } 1131 }
1017 } 1132 }
1018 if (typeArgs != null) illegal(); 1133 if (typeArgs != null) illegal();
1047 return illegal(); 1162 return illegal();
1048 } 1163 }
1049 if (typeArgs != null) illegal(); 1164 if (typeArgs != null) illegal();
1050 while (true) { 1165 while (true) {
1051 int pos1 = S.pos(); 1166 int pos1 = S.pos();
1167
1168 final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1169
1052 if (S.token() == LBRACKET) { 1170 if (S.token() == LBRACKET) {
1053 S.nextToken(); 1171 S.nextToken();
1172
1054 if ((mode & TYPE) != 0) { 1173 if ((mode & TYPE) != 0) {
1055 int oldmode = mode; 1174 int oldmode = mode;
1056 mode = TYPE; 1175 mode = TYPE;
1057 if (S.token() == RBRACKET) { 1176 if (S.token() == RBRACKET) {
1058 S.nextToken(); 1177 S.nextToken();
1059 t = bracketsOpt(t); 1178 t = bracketsOpt(t, annos);
1060 t = toP(F.at(pos1).TypeArray(t)); 1179 t = toP(F.at(pos1).TypeArray(t));
1061 return t; 1180 return t;
1062 } 1181 }
1063 mode = oldmode; 1182 mode = oldmode;
1064 } 1183 }
1089 t = toP(F.at(pos1).Select(t, ident())); 1208 t = toP(F.at(pos1).Select(t, ident()));
1090 t = argumentsOpt(typeArgs, typeArgumentsOpt(t)); 1209 t = argumentsOpt(typeArgs, typeArgumentsOpt(t));
1091 typeArgs = null; 1210 typeArgs = null;
1092 } 1211 }
1093 } else { 1212 } else {
1213 if (!annos.isEmpty()) {
1214 illegal(0);
1215 if (permitTypeAnnotationsPushBack)
1216 typeAnnotationsPushedBack = annos;
1217 else
1218 return illegal(annos.head.pos);
1219 }
1094 break; 1220 break;
1095 } 1221 }
1096 } 1222 }
1097 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 1223 while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) {
1098 mode = EXPR; 1224 mode = EXPR;
1099 t = to(F.at(S.pos()).Unary( 1225 t = to(F.at(S.pos()).Unary(
1100 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 1226 S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
1101 S.nextToken(); 1227 S.nextToken();
1102 } 1228 }
1229
1103 return toP(t); 1230 return toP(t);
1104 } 1231 }
1105 1232
1106 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 1233 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments]
1107 */ 1234 */
1230 } 1357 }
1231 return args.toList(); 1358 return args.toList();
1232 } 1359 }
1233 1360
1234 /** TypeArgument = Type 1361 /** TypeArgument = Type
1235 * | "?" 1362 * | [Annotations] "?"
1236 * | "?" EXTENDS Type {"&" Type} 1363 * | [Annotations] "?" EXTENDS Type {"&" Type}
1237 * | "?" SUPER Type 1364 * | [Annotations] "?" SUPER Type
1238 */ 1365 */
1239 JCExpression typeArgument() { 1366 JCExpression typeArgument() {
1240 if (S.token() != QUES) return parseType(); 1367 List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
1368 if (S.token() != QUES) return parseType(annotations);
1241 int pos = S.pos(); 1369 int pos = S.pos();
1242 S.nextToken(); 1370 S.nextToken();
1371 JCExpression result;
1243 if (S.token() == EXTENDS) { 1372 if (S.token() == EXTENDS) {
1244 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS)); 1373 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
1245 S.nextToken(); 1374 S.nextToken();
1246 return F.at(pos).Wildcard(t, parseType()); 1375 result = F.at(pos).Wildcard(t, parseType());
1247 } else if (S.token() == SUPER) { 1376 } else if (S.token() == SUPER) {
1248 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER)); 1377 TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
1249 S.nextToken(); 1378 S.nextToken();
1250 return F.at(pos).Wildcard(t, parseType()); 1379 result = F.at(pos).Wildcard(t, parseType());
1251 } else if (S.token() == IDENTIFIER) { 1380 } else if (S.token() == IDENTIFIER) {
1252 //error recovery 1381 //error recovery
1253 reportSyntaxError(S.prevEndPos(), "expected3", 1382 reportSyntaxError(S.prevEndPos(), "expected3",
1254 GT, EXTENDS, SUPER); 1383 GT, EXTENDS, SUPER);
1255 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1384 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1256 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 1385 JCExpression wc = toP(F.at(pos).Wildcard(t, null));
1257 JCIdent id = toP(F.at(S.pos()).Ident(ident())); 1386 JCIdent id = toP(F.at(S.pos()).Ident(ident()));
1258 return F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 1387 result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
1259 } else { 1388 } else {
1260 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 1389 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
1261 return toP(F.at(pos).Wildcard(t, null)); 1390 result = toP(F.at(pos).Wildcard(t, null));
1262 } 1391 }
1392 if (!annotations.isEmpty())
1393 result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
1394 return result;
1263 } 1395 }
1264 1396
1265 JCTypeApply typeArguments(JCExpression t) { 1397 JCTypeApply typeArguments(JCExpression t) {
1266 int pos = S.pos(); 1398 int pos = S.pos();
1267 List<JCExpression> args = typeArguments(); 1399 List<JCExpression> args = typeArguments();
1268 return toP(F.at(pos).TypeApply(t, args)); 1400 return toP(F.at(pos).TypeApply(t, args));
1269 } 1401 }
1270 1402
1271 /** BracketsOpt = {"[" "]"} 1403 /**
1272 */ 1404 * BracketsOpt = { [Annotations] "[" "]" }
1273 private JCExpression bracketsOpt(JCExpression t) { 1405 *
1406 * <p>
1407 *
1408 * <code>annotations</code> is the list of annotations targeting
1409 * the expression <code>t</code>.
1410 */
1411 private JCExpression bracketsOpt(JCExpression t,
1412 List<JCTypeAnnotation> annotations) {
1413 List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
1414
1274 if (S.token() == LBRACKET) { 1415 if (S.token() == LBRACKET) {
1275 int pos = S.pos(); 1416 int pos = S.pos();
1276 S.nextToken(); 1417 S.nextToken();
1277 t = bracketsOptCont(t, pos); 1418
1278 F.at(pos); 1419 JCExpression orig = t;
1279 } 1420 t = bracketsOptCont(t, pos, nextLevelAnnotations);
1421 } else if (!nextLevelAnnotations.isEmpty()) {
1422 if (permitTypeAnnotationsPushBack) {
1423 this.typeAnnotationsPushedBack = nextLevelAnnotations;
1424 } else
1425 return illegal(nextLevelAnnotations.head.pos);
1426 }
1427
1428 int apos = S.pos();
1429 if (!annotations.isEmpty())
1430 t = F.at(apos).AnnotatedType(annotations, t);
1280 return t; 1431 return t;
1281 } 1432 }
1282 1433
1283 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) { 1434 /** BracketsOpt = {"[" TypeAnnotations "]"}
1435 */
1436 private JCExpression bracketsOpt(JCExpression t) {
1437 return bracketsOpt(t, List.<JCTypeAnnotation>nil());
1438 }
1439
1440 private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
1441 List<JCTypeAnnotation> annotations) {
1284 accept(RBRACKET); 1442 accept(RBRACKET);
1285 t = bracketsOpt(t); 1443 t = bracketsOpt(t, annotations);
1286 return toP(F.at(pos).TypeArray(t)); 1444 return toP(F.at(pos).TypeArray(t));
1287 } 1445 }
1288 1446
1289 /** BracketsSuffixExpr = "." CLASS 1447 /** BracketsSuffixExpr = "." CLASS
1290 * BracketsSuffixType = 1448 * BracketsSuffixType =
1314 syntaxError(S.pos(), "dot.class.expected"); 1472 syntaxError(S.pos(), "dot.class.expected");
1315 } 1473 }
1316 return t; 1474 return t;
1317 } 1475 }
1318 1476
1319 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 1477 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
1320 */ 1478 */
1321 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 1479 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
1480
1481 List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
1482
1322 switch (S.token()) { 1483 switch (S.token()) {
1323 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 1484 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
1324 case DOUBLE: case BOOLEAN: 1485 case DOUBLE: case BOOLEAN:
1325 if (typeArgs == null) 1486 if (typeArgs == null) {
1326 return arrayCreatorRest(newpos, basicType()); 1487 if (newAnnotations.isEmpty())
1488 return arrayCreatorRest(newpos, basicType());
1489 else
1490 return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
1491 }
1327 break; 1492 break;
1328 default: 1493 default:
1329 } 1494 }
1330 JCExpression t = qualident(); 1495 JCExpression t = qualident();
1496 // handle type annotations for non primitive arrays
1497 if (!newAnnotations.isEmpty())
1498 t = F.AnnotatedType(newAnnotations, t);
1499
1331 int oldmode = mode; 1500 int oldmode = mode;
1332 mode = TYPE; 1501 mode = TYPE;
1333 if (S.token() == LT) { 1502 if (S.token() == LT) {
1334 checkGenerics(); 1503 checkGenerics();
1335 t = typeArguments(t); 1504 t = typeArguments(t);
1342 checkGenerics(); 1511 checkGenerics();
1343 t = typeArguments(t); 1512 t = typeArguments(t);
1344 } 1513 }
1345 } 1514 }
1346 mode = oldmode; 1515 mode = oldmode;
1347 if (S.token() == LBRACKET) { 1516 if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
1348 JCExpression e = arrayCreatorRest(newpos, t); 1517 JCExpression e = arrayCreatorRest(newpos, t);
1349 if (typeArgs != null) { 1518 if (typeArgs != null) {
1350 int pos = newpos; 1519 int pos = newpos;
1351 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) { 1520 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
1352 // note: this should always happen but we should 1521 // note: this should always happen but we should
1358 reportSyntaxError(pos, "cannot.create.array.with.type.arguments"); 1527 reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
1359 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e))); 1528 return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
1360 } 1529 }
1361 return e; 1530 return e;
1362 } else if (S.token() == LPAREN) { 1531 } else if (S.token() == LPAREN) {
1363 return classCreatorRest(newpos, null, typeArgs, t); 1532 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
1533 if (newClass.def != null) {
1534 assert newClass.def.mods.annotations.isEmpty();
1535 newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
1536 }
1537 return newClass;
1364 } else { 1538 } else {
1365 reportSyntaxError(S.pos(), "expected2", 1539 reportSyntaxError(S.pos(), "expected2",
1366 LPAREN, LBRACKET); 1540 LPAREN, LBRACKET);
1367 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 1541 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
1368 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 1542 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
1378 t = typeArguments(t); 1552 t = typeArguments(t);
1379 } 1553 }
1380 return classCreatorRest(newpos, encl, typeArgs, t); 1554 return classCreatorRest(newpos, encl, typeArgs, t);
1381 } 1555 }
1382 1556
1383 /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer 1557 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
1384 * | Expression "]" {"[" Expression "]"} BracketsOpt ) 1558 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
1385 */ 1559 */
1386 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 1560 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
1561
1562 List<JCTypeAnnotation> topAnnos = List.nil();
1563 if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
1564 JCAnnotatedType atype = (JCAnnotatedType) elemtype;
1565 topAnnos = atype.annotations;
1566 elemtype = atype.underlyingType;
1567 }
1568
1569 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
1570
1387 accept(LBRACKET); 1571 accept(LBRACKET);
1572
1388 if (S.token() == RBRACKET) { 1573 if (S.token() == RBRACKET) {
1389 accept(RBRACKET); 1574 accept(RBRACKET);
1390 elemtype = bracketsOpt(elemtype); 1575
1576 elemtype = bracketsOpt(elemtype, annos);
1577
1391 if (S.token() == LBRACE) { 1578 if (S.token() == LBRACE) {
1392 return arrayInitializer(newpos, elemtype); 1579 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
1580
1581 na.annotations = topAnnos;
1582
1583 return na;
1393 } else { 1584 } else {
1394 return syntaxError(S.pos(), "array.dimension.missing"); 1585 return syntaxError(S.pos(), "array.dimension.missing");
1395 } 1586 }
1396 } else { 1587 } else {
1397 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 1588 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
1589
1590 // maintain array dimension type annotations
1591 ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
1592 dimAnnotations.append(annos);
1593
1398 dims.append(parseExpression()); 1594 dims.append(parseExpression());
1399 accept(RBRACKET); 1595 accept(RBRACKET);
1400 while (S.token() == LBRACKET) { 1596 while (S.token() == LBRACKET
1597 || (S.token() == MONKEYS_AT)) {
1598 List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
1401 int pos = S.pos(); 1599 int pos = S.pos();
1402 S.nextToken(); 1600 S.nextToken();
1403 if (S.token() == RBRACKET) { 1601 if (S.token() == RBRACKET) {
1404 elemtype = bracketsOptCont(elemtype, pos); 1602 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1405 } else { 1603 } else {
1406 dims.append(parseExpression()); 1604 if (S.token() == RBRACKET) { // no dimension
1407 accept(RBRACKET); 1605 elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
1606 } else {
1607 dimAnnotations.append(maybeDimAnnos);
1608 dims.append(parseExpression());
1609 accept(RBRACKET);
1610 }
1408 } 1611 }
1409 } 1612 }
1410 return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null)); 1613
1614 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
1615 na.annotations = topAnnos;
1616 na.dimAnnotations = dimAnnotations.toList();
1617 return na;
1411 } 1618 }
1412 } 1619 }
1413 1620
1414 /** ClassCreatorRest = Arguments [ClassBody] 1621 /** ClassCreatorRest = Arguments [ClassBody]
1415 */ 1622 */
1416 JCExpression classCreatorRest(int newpos, 1623 JCNewClass classCreatorRest(int newpos,
1417 JCExpression encl, 1624 JCExpression encl,
1418 List<JCExpression> typeArgs, 1625 List<JCExpression> typeArgs,
1419 JCExpression t) 1626 JCExpression t)
1420 { 1627 {
1421 List<JCExpression> args = arguments(); 1628 List<JCExpression> args = arguments();
1858 return moreStatementExpressions(S.pos(), 2065 return moreStatementExpressions(S.pos(),
1859 parseExpression(), 2066 parseExpression(),
1860 new ListBuffer<JCExpressionStatement>()).toList(); 2067 new ListBuffer<JCExpressionStatement>()).toList();
1861 } 2068 }
1862 2069
2070 enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
2071
1863 /** AnnotationsOpt = { '@' Annotation } 2072 /** AnnotationsOpt = { '@' Annotation }
1864 */ 2073 */
1865 List<JCAnnotation> annotationsOpt() { 2074 List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
1866 if (S.token() != MONKEYS_AT) return List.nil(); // optimization 2075 if (S.token() != MONKEYS_AT) return List.nil(); // optimization
1867 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 2076 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
2077 int prevmode = mode;
1868 while (S.token() == MONKEYS_AT) { 2078 while (S.token() == MONKEYS_AT) {
1869 int pos = S.pos(); 2079 int pos = S.pos();
1870 S.nextToken(); 2080 S.nextToken();
1871 buf.append(annotation(pos)); 2081 buf.append(annotation(pos, kind));
1872 } 2082 }
1873 return buf.toList(); 2083 lastmode = mode;
2084 mode = prevmode;
2085 List<JCAnnotation> annotations = buf.toList();
2086
2087 if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
2088 System.out.println("TA: parsing " + annotations
2089 + " in " + log.currentSourceFile());
2090 return annotations;
2091 }
2092
2093 List<JCTypeAnnotation> typeAnnotationsOpt() {
2094 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
2095 return List.convert(JCTypeAnnotation.class, annotations);
1874 } 2096 }
1875 2097
1876 /** ModifiersOpt = { Modifier } 2098 /** ModifiersOpt = { Modifier }
1877 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL 2099 * Modifier = PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL
1878 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@" 2100 * | NATIVE | SYNCHRONIZED | TRANSIENT | VOLATILE | "@"
1913 lastPos = S.pos(); 2135 lastPos = S.pos();
1914 S.nextToken(); 2136 S.nextToken();
1915 if (flag == Flags.ANNOTATION) { 2137 if (flag == Flags.ANNOTATION) {
1916 checkAnnotations(); 2138 checkAnnotations();
1917 if (S.token() != INTERFACE) { 2139 if (S.token() != INTERFACE) {
1918 JCAnnotation ann = annotation(lastPos); 2140 JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
1919 // if first modifier is an annotation, set pos to annotation's. 2141 // if first modifier is an annotation, set pos to annotation's.
1920 if (flags == 0 && annotations.isEmpty()) 2142 if (flags == 0 && annotations.isEmpty())
1921 pos = ann.pos; 2143 pos = ann.pos;
1922 annotations.append(ann); 2144 annotations.append(ann);
1923 lastPos = ann.pos; 2145 lastPos = ann.pos;
1944 } 2166 }
1945 2167
1946 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ] 2168 /** Annotation = "@" Qualident [ "(" AnnotationFieldValues ")" ]
1947 * @param pos position of "@" token 2169 * @param pos position of "@" token
1948 */ 2170 */
1949 JCAnnotation annotation(int pos) { 2171 JCAnnotation annotation(int pos, AnnotationKind kind) {
1950 // accept(AT); // AT consumed by caller 2172 // accept(AT); // AT consumed by caller
1951 checkAnnotations(); 2173 checkAnnotations();
2174 if (kind == AnnotationKind.TYPE_ANNO)
2175 checkTypeAnnotations();
1952 JCTree ident = qualident(); 2176 JCTree ident = qualident();
1953 List<JCExpression> fieldValues = annotationFieldValuesOpt(); 2177 List<JCExpression> fieldValues = annotationFieldValuesOpt();
1954 JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); 2178 JCAnnotation ann;
2179 if (kind == AnnotationKind.DEFAULT_ANNO)
2180 ann = F.at(pos).Annotation(ident, fieldValues);
2181 else
2182 ann = F.at(pos).TypeAnnotation(ident, fieldValues);
1955 storeEnd(ann, S.prevEndPos()); 2183 storeEnd(ann, S.prevEndPos());
1956 return ann; 2184 return ann;
1957 } 2185 }
1958 2186
1959 List<JCExpression> annotationFieldValuesOpt() { 2187 List<JCExpression> annotationFieldValuesOpt() {
2001 int pos; 2229 int pos;
2002 switch (S.token()) { 2230 switch (S.token()) {
2003 case MONKEYS_AT: 2231 case MONKEYS_AT:
2004 pos = S.pos(); 2232 pos = S.pos();
2005 S.nextToken(); 2233 S.nextToken();
2006 return annotation(pos); 2234 return annotation(pos, AnnotationKind.DEFAULT_ANNO);
2007 case LBRACE: 2235 case LBRACE:
2008 pos = S.pos(); 2236 pos = S.pos();
2009 accept(LBRACE); 2237 accept(LBRACE);
2010 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 2238 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>();
2011 if (S.token() != RBRACE) { 2239 if (S.token() != RBRACE) {
2355 if (S.deprecatedFlag()) { 2583 if (S.deprecatedFlag()) {
2356 flags |= Flags.DEPRECATED; 2584 flags |= Flags.DEPRECATED;
2357 S.resetDeprecatedFlag(); 2585 S.resetDeprecatedFlag();
2358 } 2586 }
2359 int pos = S.pos(); 2587 int pos = S.pos();
2360 List<JCAnnotation> annotations = annotationsOpt(); 2588 List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2361 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 2589 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
2362 List<JCExpression> typeArgs = typeArgumentsOpt(); 2590 List<JCExpression> typeArgs = typeArgumentsOpt();
2363 int identPos = S.pos(); 2591 int identPos = S.pos();
2364 Name name = ident(); 2592 Name name = ident();
2365 int createPos = S.pos(); 2593 int createPos = S.pos();
2458 // position will be lost unless we set the Modifiers position. There 2686 // position will be lost unless we set the Modifiers position. There
2459 // should be an AST node for type parameters (BugId 5005090). 2687 // should be an AST node for type parameters (BugId 5005090).
2460 if (typarams.length() > 0 && mods.pos == Position.NOPOS) { 2688 if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
2461 mods.pos = pos; 2689 mods.pos = pos;
2462 } 2690 }
2691
2692 List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
2693
2463 Token token = S.token(); 2694 Token token = S.token();
2464 Name name = S.name(); 2695 Name name = S.name();
2465 pos = S.pos(); 2696 pos = S.pos();
2466 JCExpression type; 2697 JCExpression type;
2467 boolean isVoid = S.token() == VOID; 2698 boolean isVoid = S.token() == VOID;
2468 if (isVoid) { 2699 if (isVoid) {
2700 if (annosAfterParams.nonEmpty())
2701 illegal(annosAfterParams.head.pos);
2469 type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 2702 type = to(F.at(pos).TypeIdent(TypeTags.VOID));
2470 S.nextToken(); 2703 S.nextToken();
2471 } else { 2704 } else {
2472 type = parseType(); 2705 mods.annotations = mods.annotations.appendList(annosAfterParams);
2706 // method returns types are un-annotated types
2707 type = unannotatedType();
2473 } 2708 }
2474 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 2709 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
2475 if (isInterface || name != className) 2710 if (isInterface || name != className)
2476 log.error(pos, "invalid.meth.decl.ret.type.req"); 2711 log.error(pos, "invalid.meth.decl.ret.type.req");
2477 return List.of(methodDeclaratorRest( 2712 return List.of(methodDeclaratorRest(
2503 } 2738 }
2504 } 2739 }
2505 } 2740 }
2506 2741
2507 /** MethodDeclaratorRest = 2742 /** MethodDeclaratorRest =
2508 * FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";") 2743 * FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
2509 * VoidMethodDeclaratorRest = 2744 * VoidMethodDeclaratorRest =
2510 * FormalParameters [Throws TypeList] ( MethodBody | ";") 2745 * FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
2511 * InterfaceMethodDeclaratorRest = 2746 * InterfaceMethodDeclaratorRest =
2512 * FormalParameters BracketsOpt [THROWS TypeList] ";" 2747 * FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
2513 * VoidInterfaceMethodDeclaratorRest = 2748 * VoidInterfaceMethodDeclaratorRest =
2514 * FormalParameters [THROWS TypeList] ";" 2749 * FormalParameters [Annotations] [THROWS TypeList] ";"
2515 * ConstructorDeclaratorRest = 2750 * ConstructorDeclaratorRest =
2516 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody 2751 * "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
2517 */ 2752 */
2518 JCTree methodDeclaratorRest(int pos, 2753 JCTree methodDeclaratorRest(int pos,
2519 JCModifiers mods, 2754 JCModifiers mods,
2520 JCExpression type, 2755 JCExpression type,
2521 Name name, 2756 Name name,
2522 List<JCTypeParameter> typarams, 2757 List<JCTypeParameter> typarams,
2523 boolean isInterface, boolean isVoid, 2758 boolean isInterface, boolean isVoid,
2524 String dc) { 2759 String dc) {
2525 List<JCVariableDecl> params = formalParameters(); 2760 List<JCVariableDecl> params = formalParameters();
2526 if (!isVoid) type = bracketsOpt(type); 2761
2762 List<JCTypeAnnotation> receiverAnnotations;
2763 if (!isVoid) {
2764 // need to distinguish between receiver anno and array anno
2765 // look at typeAnnotationsPushedBack comment
2766 this.permitTypeAnnotationsPushBack = true;
2767 type = methodReturnArrayRest(type);
2768 this.permitTypeAnnotationsPushBack = false;
2769 if (typeAnnotationsPushedBack == null)
2770 receiverAnnotations = List.nil();
2771 else
2772 receiverAnnotations = typeAnnotationsPushedBack;
2773 typeAnnotationsPushedBack = null;
2774 } else
2775 receiverAnnotations = typeAnnotationsOpt();
2776
2527 List<JCExpression> thrown = List.nil(); 2777 List<JCExpression> thrown = List.nil();
2528 if (S.token() == THROWS) { 2778 if (S.token() == THROWS) {
2529 S.nextToken(); 2779 S.nextToken();
2530 thrown = qualidentList(); 2780 thrown = qualidentList();
2531 } 2781 }
2550 } 2800 }
2551 } 2801 }
2552 } 2802 }
2553 JCMethodDecl result = 2803 JCMethodDecl result =
2554 toP(F.at(pos).MethodDef(mods, name, type, typarams, 2804 toP(F.at(pos).MethodDef(mods, name, type, typarams,
2555 params, thrown, 2805 params, receiverAnnotations, thrown,
2556 body, defaultValue)); 2806 body, defaultValue));
2557 attach(result, dc); 2807 attach(result, dc);
2558 return result; 2808 return result;
2559 } 2809 }
2560 2810
2561 /** QualidentList = Qualident {"," Qualident} 2811 /** Parses the array levels after the format parameters list, and append
2812 * them to the return type, while preseving the order of type annotations
2813 */
2814 private JCExpression methodReturnArrayRest(JCExpression type) {
2815 if (type.getTag() != JCTree.TYPEARRAY)
2816 return bracketsOpt(type);
2817
2818 JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
2819 while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
2820 baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
2821
2822 if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
2823 JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
2824 at.underlyingType = bracketsOpt(at.underlyingType);
2825 } else {
2826 baseArray.elemtype = bracketsOpt(baseArray.elemtype);
2827 }
2828
2829 return type;
2830 }
2831
2832 /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
2562 */ 2833 */
2563 List<JCExpression> qualidentList() { 2834 List<JCExpression> qualidentList() {
2564 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 2835 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
2565 ts.append(qualident()); 2836
2837 List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
2838 if (!typeAnnos.isEmpty())
2839 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2840 else
2841 ts.append(qualident());
2566 while (S.token() == COMMA) { 2842 while (S.token() == COMMA) {
2567 S.nextToken(); 2843 S.nextToken();
2568 ts.append(qualident()); 2844
2845 typeAnnos = typeAnnotationsOpt();
2846 if (!typeAnnos.isEmpty())
2847 ts.append(F.AnnotatedType(typeAnnos, qualident()));
2848 else
2849 ts.append(qualident());
2569 } 2850 }
2570 return ts.toList(); 2851 return ts.toList();
2571 } 2852 }
2572 2853
2573 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 2854 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"]
2587 } else { 2868 } else {
2588 return List.nil(); 2869 return List.nil();
2589 } 2870 }
2590 } 2871 }
2591 2872
2592 /** TypeParameter = TypeVariable [TypeParameterBound] 2873 /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
2593 * TypeParameterBound = EXTENDS Type {"&" Type} 2874 * TypeParameterBound = EXTENDS Type {"&" Type}
2594 * TypeVariable = Ident 2875 * TypeVariable = Ident
2595 */ 2876 */
2596 JCTypeParameter typeParameter() { 2877 JCTypeParameter typeParameter() {
2597 int pos = S.pos(); 2878 int pos = S.pos();
2879 List<JCTypeAnnotation> annos = typeAnnotationsOpt();
2598 Name name = ident(); 2880 Name name = ident();
2599 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 2881 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
2600 if (S.token() == EXTENDS) { 2882 if (S.token() == EXTENDS) {
2601 S.nextToken(); 2883 S.nextToken();
2602 bounds.append(parseType()); 2884 bounds.append(parseType());
2603 while (S.token() == AMP) { 2885 while (S.token() == AMP) {
2604 S.nextToken(); 2886 S.nextToken();
2605 bounds.append(parseType()); 2887 bounds.append(parseType());
2606 } 2888 }
2607 } 2889 }
2608 return toP(F.at(pos).TypeParameter(name, bounds.toList())); 2890 return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
2609 } 2891 }
2610 2892
2611 /** FormalParameters = "(" [ FormalParameterList ] ")" 2893 /** FormalParameters = "(" [ FormalParameterList ] ")"
2612 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter 2894 * FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
2613 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter 2895 * FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
2637 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId 2919 /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
2638 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter 2920 * LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
2639 */ 2921 */
2640 JCVariableDecl formalParameter() { 2922 JCVariableDecl formalParameter() {
2641 JCModifiers mods = optFinal(Flags.PARAMETER); 2923 JCModifiers mods = optFinal(Flags.PARAMETER);
2924 // need to distinguish between vararg annos and array annos
2925 // look at typeAnnotaitonsPushedBack comment
2926 this.permitTypeAnnotationsPushBack = true;
2642 JCExpression type = parseType(); 2927 JCExpression type = parseType();
2928 this.permitTypeAnnotationsPushBack = false;
2929
2643 if (S.token() == ELLIPSIS) { 2930 if (S.token() == ELLIPSIS) {
2931 List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
2932 typeAnnotationsPushedBack = null;
2644 checkVarargs(); 2933 checkVarargs();
2645 mods.flags |= Flags.VARARGS; 2934 mods.flags |= Flags.VARARGS;
2935 // insert var arg type annotations
2936 if (varargsAnnos != null && varargsAnnos.nonEmpty())
2937 type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
2646 type = to(F.at(S.pos()).TypeArray(type)); 2938 type = to(F.at(S.pos()).TypeArray(type));
2647 S.nextToken(); 2939
2940 S.nextToken();
2941 } else {
2942 // if not a var arg, then typeAnnotationsPushedBack should be null
2943 if (typeAnnotationsPushedBack != null
2944 && !typeAnnotationsPushedBack.isEmpty()) {
2945 reportSyntaxError(typeAnnotationsPushedBack.head.pos,
2946 "illegal.start.of.type");
2947 }
2948 typeAnnotationsPushedBack = null;
2648 } 2949 }
2649 return variableDeclaratorId(mods, type); 2950 return variableDeclaratorId(mods, type);
2650 } 2951 }
2651 2952
2652 /* ---------- auxiliary methods -------------- */ 2953 /* ---------- auxiliary methods -------------- */
2827 if (!allowAnnotations) { 3128 if (!allowAnnotations) {
2828 log.error(S.pos(), "annotations.not.supported.in.source", source.name); 3129 log.error(S.pos(), "annotations.not.supported.in.source", source.name);
2829 allowAnnotations = true; 3130 allowAnnotations = true;
2830 } 3131 }
2831 } 3132 }
3133 void checkTypeAnnotations() {
3134 if (!allowTypeAnnotations) {
3135 log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
3136 allowTypeAnnotations = true;
3137 }
3138 }
2832 } 3139 }

mercurial