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 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 import java.util.function.Function;
30 import java.util.function.Predicate;
31 import java.util.stream.Collectors;
32
33 import com.sun.source.tree.CaseTree;
34 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
35 import com.sun.source.tree.ModuleTree.ModuleKind;
36
37 import com.sun.tools.javac.code.*;
38 import com.sun.tools.javac.code.Source.Feature;
39 import com.sun.tools.javac.parser.Tokens.*;
40 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
41 import com.sun.tools.javac.resources.CompilerProperties.Errors;
42 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
43 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
44 import com.sun.tools.javac.tree.*;
45 import com.sun.tools.javac.tree.JCTree.*;
46 import com.sun.tools.javac.util.*;
47 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
48 import com.sun.tools.javac.util.JCDiagnostic.Error;
49 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
50 import com.sun.tools.javac.util.List;
51
52 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
53 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
54 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
55 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
56 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
57 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
58 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
59 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
60 import static com.sun.tools.javac.tree.JCTree.Tag.*;
61 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
62 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
63 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
64 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
65 import java.util.function.BiFunction;
66
67 /**
68 * The parser maps a token sequence into an abstract syntax tree.
69 * The parser is a hand-written recursive-descent parser that
70 * implements the grammar described in the Java Language Specification.
71 * For efficiency reasons, an operator precedence scheme is used
72 * for parsing binary operation expressions.
73 *
74 * <p><b>This is NOT part of any supported API.
75 * If you write code that depends on this, you do so at your own risk.
76 * This code and its internal interfaces are subject to change or
77 * deletion without notice.</b>
78 */
79 public class JavacParser implements Parser {
172 boolean keepLineMap,
173 boolean keepEndPositions,
174 boolean parseModuleInfo) {
175 this.S = S;
176 nextToken(); // prime the pump
177 this.F = fac.F;
178 this.log = fac.log;
179 this.names = fac.names;
180 this.source = fac.source;
181 this.preview = fac.preview;
182 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
183 this.keepDocComments = keepDocComments;
184 this.parseModuleInfo = parseModuleInfo;
185 docComments = newDocCommentTable(keepDocComments, fac);
186 this.keepLineMap = keepLineMap;
187 this.errorTree = F.Erroneous();
188 endPosTable = newEndPosTable(keepEndPositions);
189 this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
190 this.allowRecords = Feature.RECORDS.allowedInSource(source);
191 this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
192 }
193
194 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
195 return keepEndPositions
196 ? new SimpleEndPosTable(this)
197 : new EmptyEndPosTable(this);
198 }
199
200 protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
201 return keepDocComments ? new LazyDocCommentTable(fac) : null;
202 }
203
204 /** Switch: should we fold strings?
205 */
206 boolean allowStringFolding;
207
208 /** Switch: should we keep docComments?
209 */
210 boolean keepDocComments;
211
212 /** Switch: should we keep line table?
213 */
214 boolean keepLineMap;
215
216 /** Switch: is "this" allowed as an identifier?
217 * This is needed to parse receiver types.
218 */
219 boolean allowThisIdent;
220
221 /** Switch: is yield statement allowed in this source level?
222 */
223 boolean allowYieldStatement;
224
225 /** Switch: are records allowed in this source level?
226 */
227 boolean allowRecords;
228
229 /** Switch: are sealed types allowed in this source level?
230 */
231 boolean allowSealedTypes;
232
233 /** The type of the method receiver, as specified by a first "this" parameter.
234 */
235 JCVariableDecl receiverParam;
236
237 /** When terms are parsed, the mode determines which is expected:
238 * mode = EXPR : an expression
239 * mode = TYPE : a type
240 * mode = NOPARAMS : no parameters allowed for type
241 * mode = TYPEARG : type argument
242 * mode |= NOLAMBDA : lambdas are not allowed
243 */
244 protected static final int EXPR = 0x1;
245 protected static final int TYPE = 0x2;
246 protected static final int NOPARAMS = 0x4;
247 protected static final int TYPEARG = 0x8;
248 protected static final int DIAMOND = 0x10;
456
457 /** If next input token matches given token, skip it, otherwise report
458 * an error.
459 */
460 public void accept(TokenKind tk) {
461 accept(tk, Errors::Expected);
462 }
463
464 /** If next input token matches given token, skip it, otherwise report
465 * an error.
466 */
467 public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
468 if (token.kind == tk) {
469 nextToken();
470 } else {
471 setErrorEndPos(token.pos);
472 reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
473 }
474 }
475
476 /** Report an illegal start of expression/type error at given position.
477 */
478 JCExpression illegal(int pos) {
479 setErrorEndPos(pos);
480 if ((mode & EXPR) != 0)
481 return syntaxError(pos, Errors.IllegalStartOfExpr);
482 else
483 return syntaxError(pos, Errors.IllegalStartOfType);
484
485 }
486
487 /** Report an illegal start of expression/type error at current position.
488 */
489 JCExpression illegal() {
490 return illegal(token.pos);
491 }
492
493 /** Diagnose a modifier flag from the set, if any. */
494 protected void checkNoMods(long mods) {
495 checkNoMods(token.pos, mods);
1348 break loop;
1349 case LPAREN:
1350 if ((mode & EXPR) != 0) {
1351 selectExprMode();
1352 t = arguments(typeArgs, t);
1353 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1354 typeArgs = null;
1355 }
1356 break loop;
1357 case DOT:
1358 nextToken();
1359 if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1360 return illegal();
1361 }
1362 int oldmode = mode;
1363 mode &= ~NOPARAMS;
1364 typeArgs = typeArgumentsOpt(EXPR);
1365 mode = oldmode;
1366 if ((mode & EXPR) != 0) {
1367 switch (token.kind) {
1368 case CLASS:
1369 if (typeArgs != null) return illegal();
1370 selectExprMode();
1371 t = to(F.at(pos).Select(t, names._class));
1372 nextToken();
1373 break loop;
1374 case THIS:
1375 if (typeArgs != null) return illegal();
1376 selectExprMode();
1377 t = to(F.at(pos).Select(t, names._this));
1378 nextToken();
1379 break loop;
1380 case SUPER:
1381 selectExprMode();
1382 t = to(F.at(pos).Select(t, names._super));
1383 t = superSuffix(typeArgs, t);
1384 typeArgs = null;
1385 break loop;
1386 case NEW:
1387 if (typeArgs != null) return illegal();
1405 token.kind == MONKEYS_AT) {
1406 //error recovery, case like:
1407 //int i = expr.<missing-ident>
1408 //@Deprecated
1409 if (typeArgs != null) illegal();
1410 return toP(t);
1411 }
1412 if (tyannos != null && tyannos.nonEmpty()) {
1413 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1414 }
1415 break;
1416 case ELLIPSIS:
1417 if (this.permitTypeAnnotationsPushBack) {
1418 this.typeAnnotationsPushedBack = annos;
1419 } else if (annos.nonEmpty()) {
1420 // Don't return here -- error recovery attempt
1421 illegal(annos.head.pos);
1422 }
1423 break loop;
1424 case LT:
1425 if ((mode & TYPE) == 0 && isUnboundMemberRef()) {
1426 //this is an unbound method reference whose qualifier
1427 //is a generic type i.e. A<S>::m
1428 int pos1 = token.pos;
1429 accept(LT);
1430 ListBuffer<JCExpression> args = new ListBuffer<>();
1431 args.append(typeArgument());
1432 while (token.kind == COMMA) {
1433 nextToken();
1434 args.append(typeArgument());
1435 }
1436 accept(GT);
1437 t = toP(F.at(pos1).TypeApply(t, args.toList()));
1438 while (token.kind == DOT) {
1439 nextToken();
1440 selectTypeMode();
1441 t = toP(F.at(token.pos).Select(t, ident()));
1442 t = typeArgumentsOpt(t);
1443 }
1444 t = bracketsOpt(t);
1445 if (token.kind != COLCOL) {
1446 //method reference expected here
1447 t = illegal();
1448 }
1449 selectExprMode();
1450 return term3Rest(t, typeArgs);
1451 }
1452 break loop;
1453 default:
1454 break loop;
1455 }
1456 }
1457 }
1458 if (typeArgs != null) illegal();
1459 t = typeArgumentsOpt(t);
1588 }
1589 return t;
1590 }
1591 mode = oldmode;
1592 }
1593 if ((mode & EXPR) != 0) {
1594 selectExprMode();
1595 JCExpression t1 = term();
1596 t = to(F.at(pos1).Indexed(t, t1));
1597 }
1598 accept(RBRACKET);
1599 } else if (token.kind == DOT) {
1600 nextToken();
1601 typeArgs = typeArgumentsOpt(EXPR);
1602 if (token.kind == SUPER && (mode & EXPR) != 0) {
1603 selectExprMode();
1604 t = to(F.at(pos1).Select(t, names._super));
1605 nextToken();
1606 t = arguments(typeArgs, t);
1607 typeArgs = null;
1608 } else if (token.kind == NEW && (mode & EXPR) != 0) {
1609 if (typeArgs != null) return illegal();
1610 selectExprMode();
1611 int pos2 = token.pos;
1612 nextToken();
1613 if (token.kind == LT) typeArgs = typeArguments(false);
1614 t = innerCreator(pos2, typeArgs, t);
1615 typeArgs = null;
1616 } else {
1617 List<JCAnnotation> tyannos = null;
1618 if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1619 // is the mode check needed?
1620 tyannos = typeAnnotationsOpt();
1621 }
1622 t = toP(F.at(pos1).Select(t, ident(true)));
1623 if (token.pos <= endPosTable.errorEndPos &&
1624 token.kind == MONKEYS_AT) {
1625 //error recovery, case like:
1626 //int i = expr.<missing-ident>
1627 //@Deprecated
1628 break;
1642 if (!annos.isEmpty()) {
1643 if (permitTypeAnnotationsPushBack)
1644 typeAnnotationsPushedBack = annos;
1645 else
1646 return illegal(annos.head.pos);
1647 }
1648 break;
1649 }
1650 }
1651 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1652 selectExprMode();
1653 t = to(F.at(token.pos).Unary(
1654 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1655 nextToken();
1656 }
1657 return toP(t);
1658 }
1659
1660 /**
1661 * If we see an identifier followed by a '<' it could be an unbound
1662 * method reference or a binary expression. To disambiguate, look for a
1663 * matching '>' and see if the subsequent terminal is either '.' or '::'.
1664 */
1665 @SuppressWarnings("fallthrough")
1666 boolean isUnboundMemberRef() {
1667 int pos = 0, depth = 0;
1668 outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1669 switch (t.kind) {
1670 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1671 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1672 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1673 case DOUBLE: case BOOLEAN: case CHAR:
1674 case MONKEYS_AT:
1675 break;
1676
1677 case LPAREN:
1678 // skip annotation values
1679 int nesting = 0;
1680 for (; ; pos++) {
1681 TokenKind tk2 = S.token(pos).kind;
1682 switch (tk2) {
1683 case EOF:
1684 return false;
1685 case LPAREN:
1686 nesting++;
2244
2245 private JCExpression bracketsOptCont(JCExpression t, int pos,
2246 List<JCAnnotation> annotations) {
2247 accept(RBRACKET);
2248 t = bracketsOpt(t);
2249 t = toP(F.at(pos).TypeArray(t));
2250 if (annotations.nonEmpty()) {
2251 t = toP(F.at(pos).AnnotatedType(annotations, t));
2252 }
2253 return t;
2254 }
2255
2256 /** BracketsSuffixExpr = "." CLASS
2257 * BracketsSuffixType =
2258 */
2259 JCExpression bracketsSuffix(JCExpression t) {
2260 if ((mode & EXPR) != 0 && token.kind == DOT) {
2261 selectExprMode();
2262 int pos = token.pos;
2263 nextToken();
2264 accept(CLASS);
2265 if (token.pos == endPosTable.errorEndPos) {
2266 // error recovery
2267 Name name;
2268 if (LAX_IDENTIFIER.test(token.kind)) {
2269 name = token.name();
2270 nextToken();
2271 } else {
2272 name = names.error;
2273 }
2274 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2275 } else {
2276 Tag tag = t.getTag();
2277 // Type annotations are illegal on class literals. Annotated non array class literals
2278 // are complained about directly in term3(), Here check for type annotations on dimensions
2279 // taking care to handle some interior dimension(s) being annotated.
2280 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2281 syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2282 t = toP(F.at(pos).Select(t, names._class));
2283 }
2284 } else if ((mode & TYPE) != 0) {
2285 if (token.kind != COLCOL) {
2286 selectTypeMode();
2287 }
2288 } else if (token.kind != COLCOL) {
2289 syntaxError(token.pos, Errors.DotClassExpected);
2290 }
2291 return t;
2292 }
2293
2294 /**
2295 * MemberReferenceSuffix = "::" [TypeArguments] Ident
2296 * | "::" [TypeArguments] "new"
2297 */
2298 JCExpression memberReferenceSuffix(JCExpression t) {
2299 int pos1 = token.pos;
2300 accept(COLCOL);
2301 return memberReferenceSuffix(pos1, t);
2302 }
2303
2304 JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2305 selectExprMode();
2306 List<JCExpression> typeArgs = null;
2307 if (token.kind == LT) {
2308 typeArgs = typeArguments(false);
2309 }
2310 Name refName;
2311 ReferenceMode refMode;
2312 if (token.kind == NEW) {
2313 refMode = ReferenceMode.NEW;
2314 refName = names.init;
2315 nextToken();
2316 } else {
2317 refMode = ReferenceMode.INVOKE;
2318 refName = ident();
2319 }
2320 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2321 }
2322
2323 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2324 */
2325 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2326 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2327
2328 switch (token.kind) {
2329 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2330 case DOUBLE: case BOOLEAN:
2331 if (typeArgs == null) {
2332 if (newAnnotations.isEmpty()) {
2333 return arrayCreatorRest(newpos, basicType());
2334 } else {
2335 return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2336 }
2337 }
2338 break;
2339 default:
2340 }
2341 JCExpression t = qualident(true);
2342
2343 int oldmode = mode;
2344 selectTypeMode();
2345 boolean diamondFound = false;
2346 int lastTypeargsPos = -1;
2347 if (token.kind == LT) {
2348 lastTypeargsPos = token.pos;
2349 t = typeArguments(t, true);
2350 diamondFound = (mode & DIAMOND) != 0;
2379 JCExpression e = arrayCreatorRest(newpos, t);
2380 if (diamondFound) {
2381 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2382 return toP(F.at(newpos).Erroneous(List.of(e)));
2383 }
2384 else if (typeArgs != null) {
2385 int pos = newpos;
2386 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2387 // note: this should always happen but we should
2388 // not rely on this as the parser is continuously
2389 // modified to improve error recovery.
2390 pos = typeArgs.head.pos;
2391 }
2392 setErrorEndPos(S.prevToken().endPos);
2393 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2394 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2395 return toP(err);
2396 }
2397 return e;
2398 } else if (token.kind == LPAREN) {
2399 // handle type annotations for instantiations and anonymous classes
2400 if (newAnnotations.nonEmpty()) {
2401 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2402 }
2403 return classCreatorRest(newpos, null, typeArgs, t);
2404 } else {
2405 setErrorEndPos(token.pos);
2406 reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2407 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2408 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2409 }
2410 }
2411
2412 /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2413 */
2414 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2415 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2416
2417 JCExpression t = toP(F.at(token.pos).Ident(ident()));
2418
2419 if (newAnnotations.nonEmpty()) {
2420 t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2421 }
2422
2423 if (token.kind == LT) {
2424 int oldmode = mode;
2425 t = typeArguments(t, true);
2426 mode = oldmode;
2427 }
2428 return classCreatorRest(newpos, encl, typeArgs, t);
2429 }
2430
2431 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2432 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
2433 */
2434 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2435 List<JCAnnotation> annos = typeAnnotationsOpt();
2436
2437 accept(LBRACKET);
2438 if (token.kind == RBRACKET) {
2439 accept(RBRACKET);
2440 elemtype = bracketsOpt(elemtype, annos);
2441 if (token.kind == LBRACE) {
2442 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2443 if (annos.nonEmpty()) {
2444 // when an array initializer is present then
2445 // the parsed annotations should target the
2446 // new array tree
2447 // bracketsOpt inserts the annotation in
2448 // elemtype, and it needs to be corrected
2486 if (token.kind == LBRACE) {
2487 elems = arrayInitializerElements(newpos, elemtype);
2488 }
2489
2490 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2491 na.dimAnnotations = dimAnnotations.toList();
2492
2493 if (elems != null) {
2494 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2495 }
2496
2497 return na;
2498 }
2499 }
2500
2501 /** ClassCreatorRest = Arguments [ClassBody]
2502 */
2503 JCNewClass classCreatorRest(int newpos,
2504 JCExpression encl,
2505 List<JCExpression> typeArgs,
2506 JCExpression t)
2507 {
2508 List<JCExpression> args = arguments();
2509 JCClassDecl body = null;
2510 if (token.kind == LBRACE) {
2511 int pos = token.pos;
2512 List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2513 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2514 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2515 }
2516 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2517 }
2518
2519 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2520 */
2521 JCExpression arrayInitializer(int newpos, JCExpression t) {
2522 List<JCExpression> elems = arrayInitializerElements(newpos, t);
2523 return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2524 }
2525
2526 List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2527 accept(LBRACE);
2528 ListBuffer<JCExpression> elems = new ListBuffer<>();
2529 if (token.kind == COMMA) {
2530 nextToken();
2531 } else if (token.kind != RBRACE) {
2532 elems.append(variableInitializer());
2533 while (token.kind == COMMA) {
2534 nextToken();
2535 if (token.kind == RBRACE) break;
2536 elems.append(variableInitializer());
2729 accept(SEMI);
2730 return List.of(toP(F.at(pos).Yield(t)));
2731 }
2732
2733 //else intentional fall-through
2734 } else {
2735 if (isNonSealedClassStart(true)) {
2736 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2737 nextToken();
2738 nextToken();
2739 nextToken();
2740 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2741 } else if (isSealedClassStart(true)) {
2742 checkSourceLevel(Feature.SEALED_CLASSES);
2743 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2744 nextToken();
2745 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2746 }
2747 }
2748 }
2749 if (isRecordStart() && allowRecords) {
2750 dc = token.comment(CommentStyle.JAVADOC);
2751 return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2752 } else {
2753 Token prevToken = token;
2754 JCExpression t = term(EXPR | TYPE);
2755 if (token.kind == COLON && t.hasTag(IDENT)) {
2756 nextToken();
2757 JCStatement stat = parseStatementAsBlock();
2758 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2759 } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2760 pos = token.pos;
2761 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2762 F.at(pos);
2763 return localVariableDeclarations(mods, t);
2764 } else {
2765 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2766 t = checkExprStat(t);
2767 accept(SEMI);
2768 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
3302 nextToken();
3303 pos = token.pos;
3304 JCExpression t = parseExpression();
3305 // This Exec is a "StatementExpression"; it subsumes no terminating token
3306 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3307 }
3308 return stats;
3309 }
3310
3311 /** ForInit = StatementExpression MoreStatementExpressions
3312 * | { FINAL | '@' Annotation } Type VariableDeclarators
3313 */
3314 List<JCStatement> forInit() {
3315 ListBuffer<JCStatement> stats = new ListBuffer<>();
3316 int pos = token.pos;
3317 if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3318 return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3319 } else {
3320 JCExpression t = term(EXPR | TYPE);
3321 if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3322 return variableDeclarators(modifiersOpt(), t, stats, true).toList();
3323 } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3324 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3325 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3326 } else {
3327 return moreStatementExpressions(pos, t, stats).toList();
3328 }
3329 }
3330 }
3331
3332 /** ForUpdate = StatementExpression MoreStatementExpressions
3333 */
3334 List<JCExpressionStatement> forUpdate() {
3335 return moreStatementExpressions(token.pos,
3336 parseExpression(),
3337 new ListBuffer<JCExpressionStatement>()).toList();
3338 }
3339
3340 /** AnnotationsOpt = { '@' Annotation }
3341 *
3342 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3399 case ABSTRACT : flag = Flags.ABSTRACT; break;
3400 case NATIVE : flag = Flags.NATIVE; break;
3401 case VOLATILE : flag = Flags.VOLATILE; break;
3402 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3403 case STRICTFP : flag = Flags.STRICTFP; break;
3404 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
3405 case DEFAULT : flag = Flags.DEFAULT; break;
3406 case ERROR : flag = 0; nextToken(); break;
3407 case IDENTIFIER : {
3408 if (isNonSealedClassStart(false)) {
3409 flag = Flags.NON_SEALED;
3410 nextToken();
3411 nextToken();
3412 break;
3413 }
3414 if (isSealedClassStart(false)) {
3415 checkSourceLevel(Feature.SEALED_CLASSES);
3416 flag = Flags.SEALED;
3417 break;
3418 }
3419 break loop;
3420 }
3421 default: break loop;
3422 }
3423 if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3424 lastPos = token.pos;
3425 nextToken();
3426 if (flag == Flags.ANNOTATION) {
3427 if (token.kind != INTERFACE) {
3428 JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3429 // if first modifier is an annotation, set pos to annotation's.
3430 if (flags == 0 && annotations.isEmpty())
3431 pos = ann.pos;
3432 annotations.append(ann);
3433 flag = 0;
3434 }
3435 }
3436 flags |= flag;
3437 }
3438 switch (token.kind) {
3650 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3651 return Source.JDK10;
3652 } else if (shouldWarn) {
3653 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3654 }
3655 }
3656 if (name == names.yield) {
3657 if (allowYieldStatement) {
3658 return Source.JDK14;
3659 } else if (shouldWarn) {
3660 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3661 }
3662 }
3663 if (name == names.record) {
3664 if (allowRecords) {
3665 return Source.JDK14;
3666 } else if (shouldWarn) {
3667 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3668 }
3669 }
3670 if (name == names.sealed) {
3671 if (allowSealedTypes) {
3672 return Source.JDK15;
3673 } else if (shouldWarn) {
3674 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3675 }
3676 }
3677 if (name == names.permits) {
3678 if (allowSealedTypes) {
3679 return Source.JDK15;
3680 } else if (shouldWarn) {
3681 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3682 }
3683 }
3684 return null;
3685 }
3686
3687 /** VariableDeclaratorId = Ident BracketsOpt
3688 */
3689 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
4087 mods.flags |= Flags.RECORD;
4088 Name name = typeName();
4089
4090 List<JCTypeParameter> typarams = typeParametersOpt();
4091
4092 List<JCVariableDecl> headerFields = formalParameters(false, true);
4093
4094 List<JCExpression> implementing = List.nil();
4095 if (token.kind == IMPLEMENTS) {
4096 nextToken();
4097 implementing = typeList();
4098 }
4099 List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4100 java.util.List<JCVariableDecl> fields = new ArrayList<>();
4101 for (JCVariableDecl field : headerFields) {
4102 fields.add(field);
4103 }
4104 for (JCTree def : defs) {
4105 if (def.hasTag(METHODDEF)) {
4106 JCMethodDecl methDef = (JCMethodDecl) def;
4107 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4108 ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4109 for (JCVariableDecl param : headerFields) {
4110 tmpParams.add(F.at(param)
4111 // we will get flags plus annotations from the record component
4112 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | param.mods.flags & Flags.VARARGS,
4113 param.mods.annotations),
4114 param.name, param.vartype, null));
4115 }
4116 methDef.params = tmpParams.toList();
4117 }
4118 }
4119 }
4120 for (int i = fields.size() - 1; i >= 0; i--) {
4121 JCVariableDecl field = fields.get(i);
4122 defs = defs.prepend(field);
4123 }
4124 JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4125 attach(result, dc);
4126 return result;
4127 }
4539 Token next = S.token(3);
4540 return allowedAfterSealedOrNonSealed(next, local, true);
4541 }
4542 return false;
4543 }
4544
4545 protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4546 if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4547 Token tokenSub = S.token(lookAheadOffset + 1);
4548 Token tokenSealed = S.token(lookAheadOffset + 2);
4549 if (someToken.endPos == tokenSub.pos &&
4550 tokenSub.endPos == tokenSealed.pos &&
4551 tokenSealed.name() == names.sealed) {
4552 checkSourceLevel(Feature.SEALED_CLASSES);
4553 return true;
4554 }
4555 }
4556 return false;
4557 }
4558
4559 protected boolean isSealedClassStart(boolean local) {
4560 if (token.name() == names.sealed) {
4561 Token next = S.token(1);
4562 if (allowedAfterSealedOrNonSealed(next, local, false)) {
4563 checkSourceLevel(Feature.SEALED_CLASSES);
4564 return true;
4565 }
4566 }
4567 return false;
4568 }
4569
4570 private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4571 return local ?
4572 switch (next.kind) {
4573 case MONKEYS_AT -> {
4574 Token afterNext = S.token(2);
4575 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4576 }
4577 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4578 default -> false;
4579 } :
4580 switch (next.kind) {
4581 case MONKEYS_AT -> {
4582 Token afterNext = S.token(2);
4583 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4584 }
4585 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4586 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;
4587 default -> false;
4588 };
4589 }
4590
4591 /** MethodDeclaratorRest =
4592 * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4593 * VoidMethodDeclaratorRest =
4594 * FormalParameters [THROWS TypeList] ( MethodBody | ";")
4595 * ConstructorDeclaratorRest =
4596 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4597 */
4598 protected JCTree methodDeclaratorRest(int pos,
4599 JCModifiers mods,
4600 JCExpression type,
4601 Name name,
4602 List<JCTypeParameter> typarams,
4603 boolean isInterface, boolean isVoid,
4604 boolean isRecord,
4605 Comment dc) {
4606 if (isInterface) {
4607 if ((mods.flags & Flags.PRIVATE) != 0) {
4608 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4609 }
4610 }
4611 JCVariableDecl prevReceiverParam = this.receiverParam;
4612 try {
4613 this.receiverParam = null;
4614 // Parsing formalParameters sets the receiverParam, if present
4615 List<JCVariableDecl> params = List.nil();
4616 List<JCExpression> thrown = List.nil();
4617 if (!isRecord || name != names.init || token.kind == LPAREN) {
4618 params = formalParameters();
4619 if (!isVoid) type = bracketsOpt(type);
4620 if (token.kind == THROWS) {
4621 nextToken();
4622 thrown = qualidentList(true);
4623 }
4624 }
4625 JCBlock body = null;
4626 JCExpression defaultValue;
4627 if (token.kind == LBRACE) {
4628 body = block();
4629 defaultValue = null;
4630 } else {
4631 if (token.kind == DEFAULT) {
4632 accept(DEFAULT);
4633 defaultValue = annotationValue();
4634 } else {
4635 defaultValue = null;
4636 }
4637 accept(SEMI);
5053 case INT:
5054 return TypeTag.INT;
5055 case LONG:
5056 return TypeTag.LONG;
5057 case FLOAT:
5058 return TypeTag.FLOAT;
5059 case DOUBLE:
5060 return TypeTag.DOUBLE;
5061 case BOOLEAN:
5062 return TypeTag.BOOLEAN;
5063 default:
5064 return TypeTag.NONE;
5065 }
5066 }
5067
5068 void checkSourceLevel(Feature feature) {
5069 checkSourceLevel(token.pos, feature);
5070 }
5071
5072 protected void checkSourceLevel(int pos, Feature feature) {
5073 if (preview.isPreview(feature) && !preview.isEnabled()) {
5074 //preview feature without --preview flag, error
5075 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5076 } else if (!feature.allowedInSource(source)) {
5077 //incompatible source level, error
5078 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5079 } else if (preview.isPreview(feature)) {
5080 //use of preview feature, warn
5081 preview.warnPreview(pos, feature);
5082 }
5083 }
5084
5085 /*
5086 * a functional source tree and end position mappings
5087 */
5088 protected static class SimpleEndPosTable extends AbstractEndPosTable {
5089
5090 private final IntHashTable endPosMap;
5091
5092 SimpleEndPosTable(JavacParser parser) {
5093 super(parser);
|
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 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 import java.util.function.Function;
30 import java.util.function.Predicate;
31 import java.util.stream.Collectors;
32
33 import com.sun.source.tree.CaseTree;
34 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
35 import com.sun.source.tree.ModuleTree.ModuleKind;
36
37 import com.sun.tools.javac.code.*;
38 import com.sun.tools.javac.code.Flags.Flag;
39 import com.sun.tools.javac.code.Source.Feature;
40 import com.sun.tools.javac.parser.Tokens.*;
41 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
42 import com.sun.tools.javac.resources.CompilerProperties.Errors;
43 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
44 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
45 import com.sun.tools.javac.tree.*;
46 import com.sun.tools.javac.tree.JCTree.*;
47 import com.sun.tools.javac.util.*;
48 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
49 import com.sun.tools.javac.util.JCDiagnostic.Error;
50 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
51 import com.sun.tools.javac.util.List;
52
53 import static com.sun.tools.javac.code.Flags.asFlagSet;
54 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
55 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
56 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
57 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
58 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
59 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
60 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
61 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
62 import static com.sun.tools.javac.parser.Tokens.TokenKind.SYNCHRONIZED;
63 import static com.sun.tools.javac.tree.JCTree.Tag.*;
64 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
65 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
66 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
67 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
68 import java.util.function.BiFunction;
69
70 /**
71 * The parser maps a token sequence into an abstract syntax tree.
72 * The parser is a hand-written recursive-descent parser that
73 * implements the grammar described in the Java Language Specification.
74 * For efficiency reasons, an operator precedence scheme is used
75 * for parsing binary operation expressions.
76 *
77 * <p><b>This is NOT part of any supported API.
78 * If you write code that depends on this, you do so at your own risk.
79 * This code and its internal interfaces are subject to change or
80 * deletion without notice.</b>
81 */
82 public class JavacParser implements Parser {
175 boolean keepLineMap,
176 boolean keepEndPositions,
177 boolean parseModuleInfo) {
178 this.S = S;
179 nextToken(); // prime the pump
180 this.F = fac.F;
181 this.log = fac.log;
182 this.names = fac.names;
183 this.source = fac.source;
184 this.preview = fac.preview;
185 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
186 this.keepDocComments = keepDocComments;
187 this.parseModuleInfo = parseModuleInfo;
188 docComments = newDocCommentTable(keepDocComments, fac);
189 this.keepLineMap = keepLineMap;
190 this.errorTree = F.Erroneous();
191 endPosTable = newEndPosTable(keepEndPositions);
192 this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
193 this.allowRecords = Feature.RECORDS.allowedInSource(source);
194 this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
195 this.allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && fac.options.isSet("enablePrimitiveClasses");
196 this.allowValueClasses = Feature.VALUE_CLASSES.allowedInSource(source);
197 }
198
199 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
200 return keepEndPositions
201 ? new SimpleEndPosTable(this)
202 : new EmptyEndPosTable(this);
203 }
204
205 protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
206 return keepDocComments ? new LazyDocCommentTable(fac) : null;
207 }
208
209 /** Switch: should we fold strings?
210 */
211 boolean allowStringFolding;
212
213 /** Switch: should we keep docComments?
214 */
215 boolean keepDocComments;
216
217 /** Switch: should we keep line table?
218 */
219 boolean keepLineMap;
220
221 /** Switch: is "this" allowed as an identifier?
222 * This is needed to parse receiver types.
223 */
224 boolean allowThisIdent;
225
226 /** Switch: is yield statement allowed in this source level?
227 */
228 boolean allowYieldStatement;
229
230 /** Switch: are records allowed in this source level?
231 */
232 boolean allowRecords;
233
234 /** Switch: are primitive classes allowed in this source level?
235 */
236 boolean allowPrimitiveClasses;
237
238 /** Switch: are value classes allowed in this source level?
239 */
240 boolean allowValueClasses;
241
242 /** Switch: are sealed types allowed in this source level?
243 */
244 boolean allowSealedTypes;
245
246 /** The type of the method receiver, as specified by a first "this" parameter.
247 */
248 JCVariableDecl receiverParam;
249
250 /** When terms are parsed, the mode determines which is expected:
251 * mode = EXPR : an expression
252 * mode = TYPE : a type
253 * mode = NOPARAMS : no parameters allowed for type
254 * mode = TYPEARG : type argument
255 * mode |= NOLAMBDA : lambdas are not allowed
256 */
257 protected static final int EXPR = 0x1;
258 protected static final int TYPE = 0x2;
259 protected static final int NOPARAMS = 0x4;
260 protected static final int TYPEARG = 0x8;
261 protected static final int DIAMOND = 0x10;
469
470 /** If next input token matches given token, skip it, otherwise report
471 * an error.
472 */
473 public void accept(TokenKind tk) {
474 accept(tk, Errors::Expected);
475 }
476
477 /** If next input token matches given token, skip it, otherwise report
478 * an error.
479 */
480 public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
481 if (token.kind == tk) {
482 nextToken();
483 } else {
484 setErrorEndPos(token.pos);
485 reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
486 }
487 }
488
489 /** If next input token matches one of the two given tokens, skip it, otherwise report
490 * an error.
491 *
492 * @return The actual token kind.
493 */
494 public TokenKind accept2(TokenKind tk1, TokenKind tk2) {
495 TokenKind returnValue = token.kind;
496 if (token.kind == tk1 || token.kind == tk2) {
497 nextToken();
498 } else {
499 setErrorEndPos(token.pos);
500 reportSyntaxError(S.prevToken().endPos, Errors.Expected2(tk1, tk2));
501 }
502 return returnValue;
503 }
504
505 /** Report an illegal start of expression/type error at given position.
506 */
507 JCExpression illegal(int pos) {
508 setErrorEndPos(pos);
509 if ((mode & EXPR) != 0)
510 return syntaxError(pos, Errors.IllegalStartOfExpr);
511 else
512 return syntaxError(pos, Errors.IllegalStartOfType);
513
514 }
515
516 /** Report an illegal start of expression/type error at current position.
517 */
518 JCExpression illegal() {
519 return illegal(token.pos);
520 }
521
522 /** Diagnose a modifier flag from the set, if any. */
523 protected void checkNoMods(long mods) {
524 checkNoMods(token.pos, mods);
1377 break loop;
1378 case LPAREN:
1379 if ((mode & EXPR) != 0) {
1380 selectExprMode();
1381 t = arguments(typeArgs, t);
1382 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1383 typeArgs = null;
1384 }
1385 break loop;
1386 case DOT:
1387 nextToken();
1388 if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1389 return illegal();
1390 }
1391 int oldmode = mode;
1392 mode &= ~NOPARAMS;
1393 typeArgs = typeArgumentsOpt(EXPR);
1394 mode = oldmode;
1395 if ((mode & EXPR) != 0) {
1396 switch (token.kind) {
1397 case DEFAULT:
1398 if (typeArgs != null) return illegal();
1399 selectExprMode();
1400 t = to(F.at(pos).DefaultValue(t));
1401 nextToken();
1402 break loop;
1403 case CLASS:
1404 if (typeArgs != null) return illegal();
1405 selectExprMode();
1406 t = to(F.at(pos).Select(t, names._class));
1407 nextToken();
1408 break loop;
1409 case THIS:
1410 if (typeArgs != null) return illegal();
1411 selectExprMode();
1412 t = to(F.at(pos).Select(t, names._this));
1413 nextToken();
1414 break loop;
1415 case SUPER:
1416 selectExprMode();
1417 t = to(F.at(pos).Select(t, names._super));
1418 t = superSuffix(typeArgs, t);
1419 typeArgs = null;
1420 break loop;
1421 case NEW:
1422 if (typeArgs != null) return illegal();
1440 token.kind == MONKEYS_AT) {
1441 //error recovery, case like:
1442 //int i = expr.<missing-ident>
1443 //@Deprecated
1444 if (typeArgs != null) illegal();
1445 return toP(t);
1446 }
1447 if (tyannos != null && tyannos.nonEmpty()) {
1448 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1449 }
1450 break;
1451 case ELLIPSIS:
1452 if (this.permitTypeAnnotationsPushBack) {
1453 this.typeAnnotationsPushedBack = annos;
1454 } else if (annos.nonEmpty()) {
1455 // Don't return here -- error recovery attempt
1456 illegal(annos.head.pos);
1457 }
1458 break loop;
1459 case LT:
1460 if ((mode & TYPE) == 0 && isParameterizedTypePrefix()) {
1461 //this is either an unbound method reference whose qualifier
1462 //is a generic type i.e. A<S>::m or a default value creation of
1463 //the form ValueType<S>.default
1464 int pos1 = token.pos;
1465 accept(LT);
1466 ListBuffer<JCExpression> args = new ListBuffer<>();
1467 args.append(typeArgument());
1468 while (token.kind == COMMA) {
1469 nextToken();
1470 args.append(typeArgument());
1471 }
1472 accept(GT);
1473 t = toP(F.at(pos1).TypeApply(t, args.toList()));
1474 while (token.kind == DOT) {
1475 nextToken();
1476 if (token.kind == DEFAULT) {
1477 t = toP(F.at(token.pos).DefaultValue(t));
1478 nextToken();
1479 selectExprMode();
1480 return term3Rest(t, typeArgs);
1481 }
1482 selectTypeMode();
1483 t = toP(F.at(token.pos).Select(t, ident()));
1484 t = typeArgumentsOpt(t);
1485 }
1486 t = bracketsOpt(t);
1487 if (token.kind != COLCOL) {
1488 //method reference expected here
1489 t = illegal();
1490 }
1491 selectExprMode();
1492 return term3Rest(t, typeArgs);
1493 }
1494 break loop;
1495 default:
1496 break loop;
1497 }
1498 }
1499 }
1500 if (typeArgs != null) illegal();
1501 t = typeArgumentsOpt(t);
1630 }
1631 return t;
1632 }
1633 mode = oldmode;
1634 }
1635 if ((mode & EXPR) != 0) {
1636 selectExprMode();
1637 JCExpression t1 = term();
1638 t = to(F.at(pos1).Indexed(t, t1));
1639 }
1640 accept(RBRACKET);
1641 } else if (token.kind == DOT) {
1642 nextToken();
1643 typeArgs = typeArgumentsOpt(EXPR);
1644 if (token.kind == SUPER && (mode & EXPR) != 0) {
1645 selectExprMode();
1646 t = to(F.at(pos1).Select(t, names._super));
1647 nextToken();
1648 t = arguments(typeArgs, t);
1649 typeArgs = null;
1650 } else if ((token.kind == NEW) && (mode & EXPR) != 0) {
1651 if (typeArgs != null) return illegal();
1652 selectExprMode();
1653 int pos2 = token.pos;
1654 nextToken();
1655 if (token.kind == LT) typeArgs = typeArguments(false);
1656 t = innerCreator(pos2, typeArgs, t);
1657 typeArgs = null;
1658 } else {
1659 List<JCAnnotation> tyannos = null;
1660 if ((mode & TYPE) != 0 && token.kind == MONKEYS_AT) {
1661 // is the mode check needed?
1662 tyannos = typeAnnotationsOpt();
1663 }
1664 t = toP(F.at(pos1).Select(t, ident(true)));
1665 if (token.pos <= endPosTable.errorEndPos &&
1666 token.kind == MONKEYS_AT) {
1667 //error recovery, case like:
1668 //int i = expr.<missing-ident>
1669 //@Deprecated
1670 break;
1684 if (!annos.isEmpty()) {
1685 if (permitTypeAnnotationsPushBack)
1686 typeAnnotationsPushedBack = annos;
1687 else
1688 return illegal(annos.head.pos);
1689 }
1690 break;
1691 }
1692 }
1693 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) {
1694 selectExprMode();
1695 t = to(F.at(token.pos).Unary(
1696 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1697 nextToken();
1698 }
1699 return toP(t);
1700 }
1701
1702 /**
1703 * If we see an identifier followed by a '<' it could be an unbound
1704 * method reference or a default value creation that uses a parameterized type
1705 * or a binary expression. To disambiguate, look for a
1706 * matching '>' and see if the subsequent terminal is either '.' or '::'.
1707 */
1708 @SuppressWarnings("fallthrough")
1709 boolean isParameterizedTypePrefix() {
1710 int pos = 0, depth = 0;
1711 outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1712 switch (t.kind) {
1713 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1714 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1715 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1716 case DOUBLE: case BOOLEAN: case CHAR:
1717 case MONKEYS_AT:
1718 break;
1719
1720 case LPAREN:
1721 // skip annotation values
1722 int nesting = 0;
1723 for (; ; pos++) {
1724 TokenKind tk2 = S.token(pos).kind;
1725 switch (tk2) {
1726 case EOF:
1727 return false;
1728 case LPAREN:
1729 nesting++;
2287
2288 private JCExpression bracketsOptCont(JCExpression t, int pos,
2289 List<JCAnnotation> annotations) {
2290 accept(RBRACKET);
2291 t = bracketsOpt(t);
2292 t = toP(F.at(pos).TypeArray(t));
2293 if (annotations.nonEmpty()) {
2294 t = toP(F.at(pos).AnnotatedType(annotations, t));
2295 }
2296 return t;
2297 }
2298
2299 /** BracketsSuffixExpr = "." CLASS
2300 * BracketsSuffixType =
2301 */
2302 JCExpression bracketsSuffix(JCExpression t) {
2303 if ((mode & EXPR) != 0 && token.kind == DOT) {
2304 selectExprMode();
2305 int pos = token.pos;
2306 nextToken();
2307 TokenKind selector = accept2(CLASS, DEFAULT);
2308 if (token.pos == endPosTable.errorEndPos) {
2309 // error recovery
2310 Name name;
2311 if (LAX_IDENTIFIER.test(token.kind)) {
2312 name = token.name();
2313 nextToken();
2314 } else {
2315 name = names.error;
2316 }
2317 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2318 } else {
2319 Tag tag = t.getTag();
2320 // Type annotations are illegal on class literals. Annotated non array class literals
2321 // are complained about directly in term3(), Here check for type annotations on dimensions
2322 // taking care to handle some interior dimension(s) being annotated.
2323 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2324 syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2325 if (selector == CLASS) {
2326 t = toP(F.at(pos).Select(t, names._class));
2327 } else {
2328 t = toP(F.at(pos).DefaultValue(t));
2329 }
2330 }
2331 } else if ((mode & TYPE) != 0) {
2332 if (token.kind != COLCOL) {
2333 selectTypeMode();
2334 }
2335 } else if (token.kind != COLCOL) {
2336 syntaxError(token.pos, Errors.DotClassExpected);
2337 }
2338 return t;
2339 }
2340
2341 /**
2342 * MemberReferenceSuffix = "::" [TypeArguments] Ident
2343 * | "::" [TypeArguments] "new"
2344 */
2345 JCExpression memberReferenceSuffix(JCExpression t) {
2346 int pos1 = token.pos;
2347 accept(COLCOL);
2348 return memberReferenceSuffix(pos1, t);
2349 }
2350
2351 JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2352 selectExprMode();
2353 List<JCExpression> typeArgs = null;
2354 if (token.kind == LT) {
2355 typeArgs = typeArguments(false);
2356 }
2357 Name refName;
2358 ReferenceMode refMode;
2359 if (token.kind == NEW) {
2360 refMode = ReferenceMode.NEW;
2361 // TODO - will be converted in Attr
2362 refName = names.init;
2363 nextToken();
2364 } else {
2365 refMode = ReferenceMode.INVOKE;
2366 refName = ident();
2367 }
2368 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2369 }
2370
2371 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2372 */
2373 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2374 final JCModifiers mods = modifiersOpt();
2375 List<JCAnnotation> newAnnotations = mods.annotations;
2376 switch (token.kind) {
2377 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2378 case DOUBLE: case BOOLEAN:
2379 if (mods.flags != 0) {
2380 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2381 }
2382 if (typeArgs == null) {
2383 if (newAnnotations.isEmpty()) {
2384 return arrayCreatorRest(newpos, basicType());
2385 } else {
2386 return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2387 }
2388 }
2389 break;
2390 default:
2391 }
2392 JCExpression t = qualident(true);
2393
2394 int oldmode = mode;
2395 selectTypeMode();
2396 boolean diamondFound = false;
2397 int lastTypeargsPos = -1;
2398 if (token.kind == LT) {
2399 lastTypeargsPos = token.pos;
2400 t = typeArguments(t, true);
2401 diamondFound = (mode & DIAMOND) != 0;
2430 JCExpression e = arrayCreatorRest(newpos, t);
2431 if (diamondFound) {
2432 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2433 return toP(F.at(newpos).Erroneous(List.of(e)));
2434 }
2435 else if (typeArgs != null) {
2436 int pos = newpos;
2437 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2438 // note: this should always happen but we should
2439 // not rely on this as the parser is continuously
2440 // modified to improve error recovery.
2441 pos = typeArgs.head.pos;
2442 }
2443 setErrorEndPos(S.prevToken().endPos);
2444 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2445 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2446 return toP(err);
2447 }
2448 return e;
2449 } else if (token.kind == LPAREN) {
2450 long badModifiers = mods.flags & ~(Flags.PRIMITIVE_CLASS | Flags.VALUE_CLASS | Flags.FINAL);
2451 if (badModifiers != 0)
2452 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2453 // handle type annotations for instantiations and anonymous classes
2454 if (newAnnotations.nonEmpty()) {
2455 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2456 }
2457 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2458 if ((newClass.def == null) && (mods.flags != 0)) {
2459 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2460 }
2461 return newClass;
2462 } else {
2463 setErrorEndPos(token.pos);
2464 reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2465 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2466 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2467 }
2468 }
2469
2470 /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2471 */
2472 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2473 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2474
2475 JCExpression t = toP(F.at(token.pos).Ident(ident()));
2476
2477 if (newAnnotations.nonEmpty()) {
2478 t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2479 }
2480
2481 if (token.kind == LT) {
2482 int oldmode = mode;
2483 t = typeArguments(t, true);
2484 mode = oldmode;
2485 }
2486 return classCreatorRest(newpos, encl, typeArgs, t, 0);
2487 }
2488
2489 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2490 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
2491 */
2492 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2493 List<JCAnnotation> annos = typeAnnotationsOpt();
2494
2495 accept(LBRACKET);
2496 if (token.kind == RBRACKET) {
2497 accept(RBRACKET);
2498 elemtype = bracketsOpt(elemtype, annos);
2499 if (token.kind == LBRACE) {
2500 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2501 if (annos.nonEmpty()) {
2502 // when an array initializer is present then
2503 // the parsed annotations should target the
2504 // new array tree
2505 // bracketsOpt inserts the annotation in
2506 // elemtype, and it needs to be corrected
2544 if (token.kind == LBRACE) {
2545 elems = arrayInitializerElements(newpos, elemtype);
2546 }
2547
2548 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2549 na.dimAnnotations = dimAnnotations.toList();
2550
2551 if (elems != null) {
2552 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2553 }
2554
2555 return na;
2556 }
2557 }
2558
2559 /** ClassCreatorRest = Arguments [ClassBody]
2560 */
2561 JCNewClass classCreatorRest(int newpos,
2562 JCExpression encl,
2563 List<JCExpression> typeArgs,
2564 JCExpression t,
2565 long flags)
2566 {
2567 List<JCExpression> args = arguments();
2568 JCClassDecl body = null;
2569 if (token.kind == LBRACE) {
2570 int pos = token.pos;
2571 List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2572 JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2573 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2574 }
2575 JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2576 return newClass;
2577 }
2578
2579 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2580 */
2581 JCExpression arrayInitializer(int newpos, JCExpression t) {
2582 List<JCExpression> elems = arrayInitializerElements(newpos, t);
2583 return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2584 }
2585
2586 List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2587 accept(LBRACE);
2588 ListBuffer<JCExpression> elems = new ListBuffer<>();
2589 if (token.kind == COMMA) {
2590 nextToken();
2591 } else if (token.kind != RBRACE) {
2592 elems.append(variableInitializer());
2593 while (token.kind == COMMA) {
2594 nextToken();
2595 if (token.kind == RBRACE) break;
2596 elems.append(variableInitializer());
2789 accept(SEMI);
2790 return List.of(toP(F.at(pos).Yield(t)));
2791 }
2792
2793 //else intentional fall-through
2794 } else {
2795 if (isNonSealedClassStart(true)) {
2796 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2797 nextToken();
2798 nextToken();
2799 nextToken();
2800 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2801 } else if (isSealedClassStart(true)) {
2802 checkSourceLevel(Feature.SEALED_CLASSES);
2803 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2804 nextToken();
2805 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2806 }
2807 }
2808 }
2809 if ((isPrimitiveModifier() && allowPrimitiveClasses) || (isValueModifier() || isIdentityModifier()) && allowValueClasses) {
2810 dc = token.comment(CommentStyle.JAVADOC);
2811 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2812 }
2813 if (isRecordStart() && allowRecords) {
2814 dc = token.comment(CommentStyle.JAVADOC);
2815 return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2816 } else {
2817 Token prevToken = token;
2818 JCExpression t = term(EXPR | TYPE);
2819 if (token.kind == COLON && t.hasTag(IDENT)) {
2820 nextToken();
2821 JCStatement stat = parseStatementAsBlock();
2822 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2823 } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
2824 pos = token.pos;
2825 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2826 F.at(pos);
2827 return localVariableDeclarations(mods, t);
2828 } else {
2829 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2830 t = checkExprStat(t);
2831 accept(SEMI);
2832 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
3366 nextToken();
3367 pos = token.pos;
3368 JCExpression t = parseExpression();
3369 // This Exec is a "StatementExpression"; it subsumes no terminating token
3370 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3371 }
3372 return stats;
3373 }
3374
3375 /** ForInit = StatementExpression MoreStatementExpressions
3376 * | { FINAL | '@' Annotation } Type VariableDeclarators
3377 */
3378 List<JCStatement> forInit() {
3379 ListBuffer<JCStatement> stats = new ListBuffer<>();
3380 int pos = token.pos;
3381 if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3382 return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3383 } else {
3384 JCExpression t = term(EXPR | TYPE);
3385 if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.test(token.kind)) {
3386 pos = token.pos;
3387 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3388 F.at(pos);
3389 return variableDeclarators(mods, t, stats, true).toList();
3390 } else if ((lastmode & TYPE) != 0 && token.kind == COLON) {
3391 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3392 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3393 } else {
3394 return moreStatementExpressions(pos, t, stats).toList();
3395 }
3396 }
3397 }
3398
3399 /** ForUpdate = StatementExpression MoreStatementExpressions
3400 */
3401 List<JCExpressionStatement> forUpdate() {
3402 return moreStatementExpressions(token.pos,
3403 parseExpression(),
3404 new ListBuffer<JCExpressionStatement>()).toList();
3405 }
3406
3407 /** AnnotationsOpt = { '@' Annotation }
3408 *
3409 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3466 case ABSTRACT : flag = Flags.ABSTRACT; break;
3467 case NATIVE : flag = Flags.NATIVE; break;
3468 case VOLATILE : flag = Flags.VOLATILE; break;
3469 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3470 case STRICTFP : flag = Flags.STRICTFP; break;
3471 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
3472 case DEFAULT : flag = Flags.DEFAULT; break;
3473 case ERROR : flag = 0; nextToken(); break;
3474 case IDENTIFIER : {
3475 if (isNonSealedClassStart(false)) {
3476 flag = Flags.NON_SEALED;
3477 nextToken();
3478 nextToken();
3479 break;
3480 }
3481 if (isSealedClassStart(false)) {
3482 checkSourceLevel(Feature.SEALED_CLASSES);
3483 flag = Flags.SEALED;
3484 break;
3485 }
3486 if (isPrimitiveModifier()) {
3487 flag = Flags.PRIMITIVE_CLASS;
3488 break;
3489 }
3490 if (isValueModifier()) {
3491 flag = Flags.VALUE_CLASS;
3492 break;
3493 }
3494 if (isIdentityModifier()) {
3495 flag = Flags.IDENTITY_TYPE;
3496 break;
3497 }
3498 break loop;
3499 }
3500 default: break loop;
3501 }
3502 if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3503 lastPos = token.pos;
3504 nextToken();
3505 if (flag == Flags.ANNOTATION) {
3506 if (token.kind != INTERFACE) {
3507 JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3508 // if first modifier is an annotation, set pos to annotation's.
3509 if (flags == 0 && annotations.isEmpty())
3510 pos = ann.pos;
3511 annotations.append(ann);
3512 flag = 0;
3513 }
3514 }
3515 flags |= flag;
3516 }
3517 switch (token.kind) {
3729 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3730 return Source.JDK10;
3731 } else if (shouldWarn) {
3732 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3733 }
3734 }
3735 if (name == names.yield) {
3736 if (allowYieldStatement) {
3737 return Source.JDK14;
3738 } else if (shouldWarn) {
3739 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3740 }
3741 }
3742 if (name == names.record) {
3743 if (allowRecords) {
3744 return Source.JDK14;
3745 } else if (shouldWarn) {
3746 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3747 }
3748 }
3749 if (name == names.primitive) {
3750 if (allowPrimitiveClasses) {
3751 return Source.JDK18;
3752 }
3753 }
3754 if (name == names.value) {
3755 if (allowValueClasses) {
3756 return Source.JDK18;
3757 } else if (shouldWarn) {
3758 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3759 }
3760 }
3761 if (name == names.identity) {
3762 if (allowPrimitiveClasses) {
3763 return Source.JDK18;
3764 } else if (shouldWarn) {
3765 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3766 }
3767 }
3768 if (name == names.sealed) {
3769 if (allowSealedTypes) {
3770 return Source.JDK15;
3771 } else if (shouldWarn) {
3772 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3773 }
3774 }
3775 if (name == names.permits) {
3776 if (allowSealedTypes) {
3777 return Source.JDK15;
3778 } else if (shouldWarn) {
3779 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3780 }
3781 }
3782 return null;
3783 }
3784
3785 /** VariableDeclaratorId = Ident BracketsOpt
3786 */
3787 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
4185 mods.flags |= Flags.RECORD;
4186 Name name = typeName();
4187
4188 List<JCTypeParameter> typarams = typeParametersOpt();
4189
4190 List<JCVariableDecl> headerFields = formalParameters(false, true);
4191
4192 List<JCExpression> implementing = List.nil();
4193 if (token.kind == IMPLEMENTS) {
4194 nextToken();
4195 implementing = typeList();
4196 }
4197 List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4198 java.util.List<JCVariableDecl> fields = new ArrayList<>();
4199 for (JCVariableDecl field : headerFields) {
4200 fields.add(field);
4201 }
4202 for (JCTree def : defs) {
4203 if (def.hasTag(METHODDEF)) {
4204 JCMethodDecl methDef = (JCMethodDecl) def;
4205 // TODO - specifically for record.
4206 if (names.isInitOrVNew(methDef.name) && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4207 ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4208 for (JCVariableDecl param : headerFields) {
4209 tmpParams.add(F.at(param)
4210 // we will get flags plus annotations from the record component
4211 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | param.mods.flags & Flags.VARARGS,
4212 param.mods.annotations),
4213 param.name, param.vartype, null));
4214 }
4215 methDef.params = tmpParams.toList();
4216 }
4217 }
4218 }
4219 for (int i = fields.size() - 1; i >= 0; i--) {
4220 JCVariableDecl field = fields.get(i);
4221 defs = defs.prepend(field);
4222 }
4223 JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4224 attach(result, dc);
4225 return result;
4226 }
4638 Token next = S.token(3);
4639 return allowedAfterSealedOrNonSealed(next, local, true);
4640 }
4641 return false;
4642 }
4643
4644 protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4645 if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4646 Token tokenSub = S.token(lookAheadOffset + 1);
4647 Token tokenSealed = S.token(lookAheadOffset + 2);
4648 if (someToken.endPos == tokenSub.pos &&
4649 tokenSub.endPos == tokenSealed.pos &&
4650 tokenSealed.name() == names.sealed) {
4651 checkSourceLevel(Feature.SEALED_CLASSES);
4652 return true;
4653 }
4654 }
4655 return false;
4656 }
4657
4658 protected boolean isPrimitiveModifier() {
4659 if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4660 boolean isPrimitiveModifier = false;
4661 Token next = S.token(1);
4662 switch (next.kind) {
4663 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4664 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4665 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4666 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4667 case CLASS: case INTERFACE: case ENUM:
4668 isPrimitiveModifier = true;
4669 break;
4670 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4671 if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4672 || next.name() == names.value || (mode & EXPR) != 0)
4673 isPrimitiveModifier = true;
4674 break;
4675 }
4676 if (isPrimitiveModifier) {
4677 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4678 return true;
4679 }
4680 }
4681 return false;
4682 }
4683
4684 protected boolean isValueModifier() {
4685 if (token.kind == IDENTIFIER && token.name() == names.value) {
4686 boolean isValueModifier = false;
4687 Token next = S.token(1);
4688 switch (next.kind) {
4689 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4690 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4691 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4692 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4693 case CLASS: case INTERFACE: case ENUM:
4694 isValueModifier = true;
4695 break;
4696 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4697 if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4698 || next.name() == names.primitive || (mode & EXPR) != 0)
4699 isValueModifier = true;
4700 break;
4701 }
4702 if (isValueModifier) {
4703 checkSourceLevel(Feature.VALUE_CLASSES);
4704 return true;
4705 }
4706 }
4707 return false;
4708 }
4709
4710 protected boolean isIdentityModifier() {
4711 if (token.kind == IDENTIFIER && token.name() == names.identity) {
4712 boolean isIdentityModifier = false;
4713 Token next = S.token(1);
4714 switch (next.kind) {
4715 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4716 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4717 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4718 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4719 case CLASS: case INTERFACE: case ENUM:
4720 isIdentityModifier = true;
4721 break;
4722 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4723 if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4724 || next.name() == names.value || (mode & EXPR) != 0)
4725 isIdentityModifier = true;
4726 break;
4727 }
4728 if (isIdentityModifier) {
4729 checkSourceLevel(Feature.VALUE_CLASSES);
4730 return true;
4731 }
4732 }
4733 return false;
4734 }
4735
4736 protected boolean isSealedClassStart(boolean local) {
4737 if (token.name() == names.sealed) {
4738 Token next = S.token(1);
4739 if (allowedAfterSealedOrNonSealed(next, local, false)) {
4740 checkSourceLevel(Feature.SEALED_CLASSES);
4741 return true;
4742 }
4743 }
4744 return false;
4745 }
4746
4747 private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4748 return local ?
4749 switch (next.kind) {
4750 case MONKEYS_AT -> {
4751 Token afterNext = S.token(2);
4752 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4753 }
4754 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4755 default -> false;
4756 } :
4757 switch (next.kind) {
4758 case MONKEYS_AT -> {
4759 Token afterNext = S.token(2);
4760 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4761 }
4762 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4763 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
4764 next.name() == names.sealed ||
4765 next.name() == names.value ||
4766 next.name() == names.identity;
4767 default -> false;
4768 };
4769 }
4770
4771 /** MethodDeclaratorRest =
4772 * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4773 * VoidMethodDeclaratorRest =
4774 * FormalParameters [THROWS TypeList] ( MethodBody | ";")
4775 * ConstructorDeclaratorRest =
4776 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4777 */
4778 protected JCTree methodDeclaratorRest(int pos,
4779 JCModifiers mods,
4780 JCExpression type,
4781 Name name,
4782 List<JCTypeParameter> typarams,
4783 boolean isInterface, boolean isVoid,
4784 boolean isRecord,
4785 Comment dc) {
4786 if (isInterface) {
4787 if ((mods.flags & Flags.PRIVATE) != 0) {
4788 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4789 }
4790 }
4791 JCVariableDecl prevReceiverParam = this.receiverParam;
4792 try {
4793 this.receiverParam = null;
4794 // Parsing formalParameters sets the receiverParam, if present
4795 List<JCVariableDecl> params = List.nil();
4796 List<JCExpression> thrown = List.nil();
4797 if (!isRecord || !names.isInitOrVNew(name) || token.kind == LPAREN) {
4798 params = formalParameters();
4799 if (!isVoid) type = bracketsOpt(type);
4800 if (token.kind == THROWS) {
4801 nextToken();
4802 thrown = qualidentList(true);
4803 }
4804 }
4805 JCBlock body = null;
4806 JCExpression defaultValue;
4807 if (token.kind == LBRACE) {
4808 body = block();
4809 defaultValue = null;
4810 } else {
4811 if (token.kind == DEFAULT) {
4812 accept(DEFAULT);
4813 defaultValue = annotationValue();
4814 } else {
4815 defaultValue = null;
4816 }
4817 accept(SEMI);
5233 case INT:
5234 return TypeTag.INT;
5235 case LONG:
5236 return TypeTag.LONG;
5237 case FLOAT:
5238 return TypeTag.FLOAT;
5239 case DOUBLE:
5240 return TypeTag.DOUBLE;
5241 case BOOLEAN:
5242 return TypeTag.BOOLEAN;
5243 default:
5244 return TypeTag.NONE;
5245 }
5246 }
5247
5248 void checkSourceLevel(Feature feature) {
5249 checkSourceLevel(token.pos, feature);
5250 }
5251
5252 protected void checkSourceLevel(int pos, Feature feature) {
5253 if (feature == Feature.PRIMITIVE_CLASSES && !allowPrimitiveClasses) {
5254 // primitive classes are special
5255 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5256 } else if (preview.isPreview(feature) && !preview.isEnabled()) {
5257 //preview feature without --preview flag, error
5258 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5259 } else if (!feature.allowedInSource(source)) {
5260 //incompatible source level, error
5261 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5262 } else if (preview.isPreview(feature)) {
5263 //use of preview feature, warn
5264 preview.warnPreview(pos, feature);
5265 }
5266 }
5267
5268 /*
5269 * a functional source tree and end position mappings
5270 */
5271 protected static class SimpleEndPosTable extends AbstractEndPosTable {
5272
5273 private final IntHashTable endPosMap;
5274
5275 SimpleEndPosTable(JavacParser parser) {
5276 super(parser);
|