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 javax.lang.model.SourceVersion;
34
35 import com.sun.source.tree.CaseTree;
36 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
37 import com.sun.source.tree.ModuleTree.ModuleKind;
38
39 import com.sun.tools.javac.code.*;
40 import com.sun.tools.javac.code.Source.Feature;
41 import com.sun.tools.javac.file.PathFileObject;
42 import com.sun.tools.javac.parser.Tokens.*;
43 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
44 import com.sun.tools.javac.resources.CompilerProperties.Errors;
45 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
46 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
47 import com.sun.tools.javac.tree.*;
48 import com.sun.tools.javac.tree.JCTree.*;
49 import com.sun.tools.javac.util.*;
50 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
51 import com.sun.tools.javac.util.JCDiagnostic.Error;
52 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
53 import com.sun.tools.javac.util.List;
54
55 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
56 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
57 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
58 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
59 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
60 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
61 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
62 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
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
69 /**
70 * The parser maps a token sequence into an abstract syntax tree.
71 * The parser is a hand-written recursive-descent parser that
72 * implements the grammar described in the Java Language Specification.
73 * For efficiency reasons, an operator precedence scheme is used
74 * for parsing binary operation expressions.
75 *
76 * <p><b>This is NOT part of any supported API.
77 * If you write code that depends on this, you do so at your own risk.
78 * This code and its internal interfaces are subject to change or
79 * deletion without notice.</b>
80 */
81 public class JavacParser implements Parser {
82
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 this.docComments = newDocCommentTable(keepDocComments, fac);
189 this.keepLineMap = keepLineMap;
190 this.errorTree = F.Erroneous();
191 this.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 }
196
197 /** Construct a parser from an existing parser, with minimal overhead.
198 */
199 @SuppressWarnings("this-escape")
200 protected JavacParser(JavacParser parser,
201 Lexer S) {
202 this.S = S;
203 this.token = parser.token;
204 this.F = parser.F;
205 this.log = parser.log;
206 this.names = parser.names;
207 this.source = parser.source;
208 this.preview = parser.preview;
209 this.allowStringFolding = parser.allowStringFolding;
210 this.keepDocComments = false;
211 this.parseModuleInfo = false;
212 this.docComments = null;
213 this.errorTree = F.Erroneous();
214 this.endPosTable = newEndPosTable(false);
215 this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
216 this.allowRecords = Feature.RECORDS.allowedInSource(source);
217 this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
218 }
219
220 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
221 return keepEndPositions
222 ? new SimpleEndPosTable(this)
223 : new EmptyEndPosTable(this);
224 }
225
226 protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
227 return keepDocComments ? new LazyDocCommentTable(fac) : null;
228 }
229
230 /** Switch: should we fold strings?
231 */
232 boolean allowStringFolding;
233
234 /** Switch: should we keep docComments?
235 */
236 boolean keepDocComments;
237
238 /** Switch: should we keep line table?
239 */
240 boolean keepLineMap;
241
242 /** Switch: is "this" allowed as an identifier?
243 * This is needed to parse receiver types.
244 */
245 boolean allowThisIdent;
246
247 /** Switch: is yield statement allowed in this source level?
248 */
249 boolean allowYieldStatement;
250
251 /** Switch: are records allowed in this source level?
252 */
253 boolean allowRecords;
254
255 /** Switch: are sealed types allowed in this source level?
256 */
257 boolean allowSealedTypes;
258
259 /** The type of the method receiver, as specified by a first "this" parameter.
260 */
261 JCVariableDecl receiverParam;
262
263 /** When terms are parsed, the mode determines which is expected:
264 * mode = EXPR : an expression
265 * mode = TYPE : a type
266 * mode = NOPARAMS : no parameters allowed for type
267 * mode = TYPEARG : type argument
268 * mode |= NOLAMBDA : lambdas are not allowed
269 */
270 protected static final int EXPR = 1 << 0;
271 protected static final int TYPE = 1 << 1;
272 protected static final int NOPARAMS = 1 << 2;
273 protected static final int TYPEARG = 1 << 3;
274 protected static final int DIAMOND = 1 << 4;
498
499 /** If next input token matches given token, skip it, otherwise report
500 * an error.
501 */
502 public void accept(TokenKind tk) {
503 accept(tk, Errors::Expected);
504 }
505
506 /** If next input token matches given token, skip it, otherwise report
507 * an error.
508 */
509 public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
510 if (token.kind == tk) {
511 nextToken();
512 } else {
513 setErrorEndPos(token.pos);
514 reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
515 }
516 }
517
518 /** Report an illegal start of expression/type error at given position.
519 */
520 JCExpression illegal(int pos) {
521 setErrorEndPos(pos);
522 if (isMode(EXPR))
523 return syntaxError(pos, Errors.IllegalStartOfExpr);
524 else
525 return syntaxError(pos, Errors.IllegalStartOfType);
526
527 }
528
529 /** Report an illegal start of expression/type error at current position.
530 */
531 JCExpression illegal() {
532 return illegal(token.pos);
533 }
534
535 /** Diagnose a modifier flag from the set, if any. */
536 protected void checkNoMods(long mods) {
537 checkNoMods(token.pos, mods);
1488 break loop;
1489 case LPAREN:
1490 if (isMode(EXPR)) {
1491 selectExprMode();
1492 t = arguments(typeArgs, t);
1493 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1494 typeArgs = null;
1495 }
1496 break loop;
1497 case DOT:
1498 nextToken();
1499 if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1500 return illegal();
1501 }
1502 int prevmode = mode;
1503 setMode(mode & ~NOPARAMS);
1504 typeArgs = typeArgumentsOpt(EXPR);
1505 setMode(prevmode);
1506 if (isMode(EXPR)) {
1507 switch (token.kind) {
1508 case CLASS:
1509 if (typeArgs != null) return illegal();
1510 selectExprMode();
1511 t = to(F.at(pos).Select(t, names._class));
1512 nextToken();
1513 break loop;
1514 case THIS:
1515 if (typeArgs != null) return illegal();
1516 selectExprMode();
1517 t = to(F.at(pos).Select(t, names._this));
1518 nextToken();
1519 break loop;
1520 case SUPER:
1521 selectExprMode();
1522 t = to(F.at(pos).Select(t, names._super));
1523 t = superSuffix(typeArgs, t);
1524 typeArgs = null;
1525 break loop;
1526 case NEW:
1527 if (typeArgs != null) return illegal();
1551 token.kind == MONKEYS_AT) {
1552 //error recovery, case like:
1553 //int i = expr.<missing-ident>
1554 //@Deprecated
1555 if (typeArgs != null) illegal();
1556 return toP(t);
1557 }
1558 if (tyannos != null && tyannos.nonEmpty()) {
1559 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1560 }
1561 break;
1562 case ELLIPSIS:
1563 if (this.permitTypeAnnotationsPushBack) {
1564 this.typeAnnotationsPushedBack = annos;
1565 } else if (annos.nonEmpty()) {
1566 // Don't return here -- error recovery attempt
1567 illegal(annos.head.pos);
1568 }
1569 break loop;
1570 case LT:
1571 if (!isMode(TYPE) && isUnboundMemberRef()) {
1572 //this is an unbound method reference whose qualifier
1573 //is a generic type i.e. A<S>::m
1574 int pos1 = token.pos;
1575 accept(LT);
1576 ListBuffer<JCExpression> args = new ListBuffer<>();
1577 args.append(typeArgument());
1578 while (token.kind == COMMA) {
1579 nextToken();
1580 args.append(typeArgument());
1581 }
1582 accept(GT);
1583 t = toP(F.at(pos1).TypeApply(t, args.toList()));
1584 while (token.kind == DOT) {
1585 nextToken();
1586 selectTypeMode();
1587 t = toP(F.at(token.pos).Select(t, ident()));
1588 t = typeArgumentsOpt(t);
1589 }
1590 t = bracketsOpt(t);
1591 if (token.kind != COLCOL) {
1592 //method reference expected here
1593 t = illegal();
1594 }
1595 selectExprMode();
1596 return term3Rest(t, typeArgs);
1597 }
1598 break loop;
1599 default:
1600 break loop;
1601 }
1602 }
1603 }
1604 if (typeArgs != null) illegal();
1605 t = typeArgumentsOpt(t);
1796 if (!annos.isEmpty()) {
1797 if (permitTypeAnnotationsPushBack)
1798 typeAnnotationsPushedBack = annos;
1799 else
1800 return illegal(annos.head.pos);
1801 }
1802 break;
1803 }
1804 }
1805 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1806 selectExprMode();
1807 t = to(F.at(token.pos).Unary(
1808 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1809 nextToken();
1810 }
1811 return toP(t);
1812 }
1813
1814 /**
1815 * If we see an identifier followed by a '<' it could be an unbound
1816 * method reference or a binary expression. To disambiguate, look for a
1817 * matching '>' and see if the subsequent terminal is either '.' or '::'.
1818 */
1819 @SuppressWarnings("fallthrough")
1820 boolean isUnboundMemberRef() {
1821 int pos = 0, depth = 0;
1822 outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1823 switch (t.kind) {
1824 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1825 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1826 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1827 case DOUBLE: case BOOLEAN: case CHAR:
1828 case MONKEYS_AT:
1829 break;
1830
1831 case LPAREN:
1832 // skip annotation values
1833 int nesting = 0;
1834 for (; ; pos++) {
1835 TokenKind tk2 = S.token(pos).kind;
1836 switch (tk2) {
1837 case EOF:
1838 return false;
1839 case LPAREN:
1840 nesting++;
2407
2408 private JCExpression bracketsOptCont(JCExpression t, int pos,
2409 List<JCAnnotation> annotations) {
2410 accept(RBRACKET);
2411 t = bracketsOpt(t);
2412 t = toP(F.at(pos).TypeArray(t));
2413 if (annotations.nonEmpty()) {
2414 t = toP(F.at(pos).AnnotatedType(annotations, t));
2415 }
2416 return t;
2417 }
2418
2419 /** BracketsSuffixExpr = "." CLASS
2420 * BracketsSuffixType =
2421 */
2422 JCExpression bracketsSuffix(JCExpression t) {
2423 if (isMode(EXPR) && token.kind == DOT) {
2424 selectExprMode();
2425 int pos = token.pos;
2426 nextToken();
2427 accept(CLASS);
2428 if (token.pos == endPosTable.errorEndPos) {
2429 // error recovery
2430 Name name;
2431 if (LAX_IDENTIFIER.test(token.kind)) {
2432 name = token.name();
2433 nextToken();
2434 } else {
2435 name = names.error;
2436 }
2437 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2438 } else {
2439 Tag tag = t.getTag();
2440 // Type annotations are illegal on class literals. Annotated non array class literals
2441 // are complained about directly in term3(), Here check for type annotations on dimensions
2442 // taking care to handle some interior dimension(s) being annotated.
2443 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2444 syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2445 t = toP(F.at(pos).Select(t, names._class));
2446 }
2447 } else if (isMode(TYPE)) {
2448 if (token.kind != COLCOL) {
2449 selectTypeMode();
2450 }
2451 } else if (token.kind != COLCOL) {
2452 syntaxError(token.pos, Errors.DotClassExpected);
2453 }
2454 return t;
2455 }
2456
2457 /**
2458 * MemberReferenceSuffix = "::" [TypeArguments] Ident
2459 * | "::" [TypeArguments] "new"
2460 */
2461 JCExpression memberReferenceSuffix(JCExpression t) {
2462 int pos1 = token.pos;
2463 accept(COLCOL);
2464 return memberReferenceSuffix(pos1, t);
2465 }
2466
2467 JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2468 selectExprMode();
2469 List<JCExpression> typeArgs = null;
2470 if (token.kind == LT) {
2471 typeArgs = typeArguments(false);
2472 }
2473 Name refName;
2474 ReferenceMode refMode;
2475 if (token.kind == NEW) {
2476 refMode = ReferenceMode.NEW;
2477 refName = names.init;
2478 nextToken();
2479 } else {
2480 refMode = ReferenceMode.INVOKE;
2481 refName = ident();
2482 }
2483 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2484 }
2485
2486 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2487 */
2488 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2489 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2490
2491 switch (token.kind) {
2492 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2493 case DOUBLE: case BOOLEAN:
2494 if (typeArgs == null) {
2495 if (newAnnotations.isEmpty()) {
2496 return arrayCreatorRest(newpos, basicType());
2497 } else {
2498 return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2499 }
2500 }
2501 break;
2502 default:
2503 }
2504 JCExpression t = qualident(true);
2505
2506 int prevmode = mode;
2507 selectTypeMode();
2508 boolean diamondFound = false;
2509 int lastTypeargsPos = -1;
2510 if (token.kind == LT) {
2511 lastTypeargsPos = token.pos;
2512 t = typeArguments(t, true);
2513 diamondFound = isMode(DIAMOND);
2542 JCExpression e = arrayCreatorRest(newpos, t);
2543 if (diamondFound) {
2544 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2545 return toP(F.at(newpos).Erroneous(List.of(e)));
2546 }
2547 else if (typeArgs != null) {
2548 int pos = newpos;
2549 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2550 // note: this should always happen but we should
2551 // not rely on this as the parser is continuously
2552 // modified to improve error recovery.
2553 pos = typeArgs.head.pos;
2554 }
2555 setErrorEndPos(S.prevToken().endPos);
2556 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2557 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2558 return toP(err);
2559 }
2560 return e;
2561 } else if (token.kind == LPAREN) {
2562 // handle type annotations for instantiations and anonymous classes
2563 if (newAnnotations.nonEmpty()) {
2564 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2565 }
2566 return classCreatorRest(newpos, null, typeArgs, t);
2567 } else {
2568 setErrorEndPos(token.pos);
2569 reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2570 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2571 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2572 }
2573 }
2574
2575 /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2576 */
2577 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2578 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2579
2580 JCExpression t = toP(F.at(token.pos).Ident(ident()));
2581
2582 if (newAnnotations.nonEmpty()) {
2583 t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2584 }
2585
2586 if (token.kind == LT) {
2587 int prevmode = mode;
2588 t = typeArguments(t, true);
2589 setMode(prevmode);
2590 }
2591 return classCreatorRest(newpos, encl, typeArgs, t);
2592 }
2593
2594 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2595 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
2596 */
2597 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2598 List<JCAnnotation> annos = typeAnnotationsOpt();
2599
2600 accept(LBRACKET);
2601 if (token.kind == RBRACKET) {
2602 accept(RBRACKET);
2603 elemtype = bracketsOpt(elemtype, annos);
2604 if (token.kind == LBRACE) {
2605 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2606 if (annos.nonEmpty()) {
2607 // when an array initializer is present then
2608 // the parsed annotations should target the
2609 // new array tree
2610 // bracketsOpt inserts the annotation in
2611 // elemtype, and it needs to be corrected
2649 if (token.kind == LBRACE) {
2650 elems = arrayInitializerElements(newpos, elemtype);
2651 }
2652
2653 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2654 na.dimAnnotations = dimAnnotations.toList();
2655
2656 if (elems != null) {
2657 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2658 }
2659
2660 return na;
2661 }
2662 }
2663
2664 /** ClassCreatorRest = Arguments [ClassBody]
2665 */
2666 JCNewClass classCreatorRest(int newpos,
2667 JCExpression encl,
2668 List<JCExpression> typeArgs,
2669 JCExpression t)
2670 {
2671 List<JCExpression> args = arguments();
2672 JCClassDecl body = null;
2673 if (token.kind == LBRACE) {
2674 int pos = token.pos;
2675 List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2676 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2677 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2678 }
2679 return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2680 }
2681
2682 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2683 */
2684 JCExpression arrayInitializer(int newpos, JCExpression t) {
2685 List<JCExpression> elems = arrayInitializerElements(newpos, t);
2686 return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2687 }
2688
2689 List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2690 accept(LBRACE);
2691 ListBuffer<JCExpression> elems = new ListBuffer<>();
2692 if (token.kind == COMMA) {
2693 nextToken();
2694 } else if (token.kind != RBRACE) {
2695 elems.append(variableInitializer());
2696 while (token.kind == COMMA) {
2697 nextToken();
2698 if (token.kind == RBRACE) break;
2699 elems.append(variableInitializer());
2890 accept(SEMI);
2891 return List.of(toP(F.at(pos).Yield(t)));
2892 }
2893
2894 //else intentional fall-through
2895 } else {
2896 if (isNonSealedClassStart(true)) {
2897 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2898 nextToken();
2899 nextToken();
2900 nextToken();
2901 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2902 } else if (isSealedClassStart(true)) {
2903 checkSourceLevel(Feature.SEALED_CLASSES);
2904 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2905 nextToken();
2906 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2907 }
2908 }
2909 }
2910 if (isRecordStart() && allowRecords) {
2911 dc = token.comment(CommentStyle.JAVADOC);
2912 return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2913 } else {
2914 Token prevToken = token;
2915 JCExpression t = term(EXPR | TYPE);
2916 if (token.kind == COLON && t.hasTag(IDENT)) {
2917 nextToken();
2918 JCStatement stat = parseStatementAsBlock();
2919 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2920 } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2921 pos = token.pos;
2922 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2923 F.at(pos);
2924 return localVariableDeclarations(mods, t);
2925 } else {
2926 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2927 t = checkExprStat(t);
2928 accept(SEMI);
2929 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
3381 nextToken();
3382 pos = token.pos;
3383 JCExpression t = parseExpression();
3384 // This Exec is a "StatementExpression"; it subsumes no terminating token
3385 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3386 }
3387 return stats;
3388 }
3389
3390 /** ForInit = StatementExpression MoreStatementExpressions
3391 * | { FINAL | '@' Annotation } Type VariableDeclarators
3392 */
3393 List<JCStatement> forInit() {
3394 ListBuffer<JCStatement> stats = new ListBuffer<>();
3395 int pos = token.pos;
3396 if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3397 return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3398 } else {
3399 JCExpression t = term(EXPR | TYPE);
3400 if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3401 return variableDeclarators(modifiersOpt(), t, stats, true).toList();
3402 } else if (wasTypeMode() && token.kind == COLON) {
3403 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3404 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3405 } else {
3406 return moreStatementExpressions(pos, t, stats).toList();
3407 }
3408 }
3409 }
3410
3411 /** ForUpdate = StatementExpression MoreStatementExpressions
3412 */
3413 List<JCExpressionStatement> forUpdate() {
3414 return moreStatementExpressions(token.pos,
3415 parseExpression(),
3416 new ListBuffer<JCExpressionStatement>()).toList();
3417 }
3418
3419 /** AnnotationsOpt = { '@' Annotation }
3420 *
3421 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3478 case ABSTRACT : flag = Flags.ABSTRACT; break;
3479 case NATIVE : flag = Flags.NATIVE; break;
3480 case VOLATILE : flag = Flags.VOLATILE; break;
3481 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3482 case STRICTFP : flag = Flags.STRICTFP; break;
3483 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
3484 case DEFAULT : flag = Flags.DEFAULT; break;
3485 case ERROR : flag = 0; nextToken(); break;
3486 case IDENTIFIER : {
3487 if (isNonSealedClassStart(false)) {
3488 flag = Flags.NON_SEALED;
3489 nextToken();
3490 nextToken();
3491 break;
3492 }
3493 if (isSealedClassStart(false)) {
3494 checkSourceLevel(Feature.SEALED_CLASSES);
3495 flag = Flags.SEALED;
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) {
3744 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3745 return Source.JDK10;
3746 } else if (shouldWarn) {
3747 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3748 }
3749 }
3750 if (name == names.yield) {
3751 if (allowYieldStatement) {
3752 return Source.JDK14;
3753 } else if (shouldWarn) {
3754 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3755 }
3756 }
3757 if (name == names.record) {
3758 if (allowRecords) {
3759 return Source.JDK14;
3760 } else if (shouldWarn) {
3761 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3762 }
3763 }
3764 if (name == names.sealed) {
3765 if (allowSealedTypes) {
3766 return Source.JDK15;
3767 } else if (shouldWarn) {
3768 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3769 }
3770 }
3771 if (name == names.permits) {
3772 if (allowSealedTypes) {
3773 return Source.JDK15;
3774 } else if (shouldWarn) {
3775 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3776 }
3777 }
3778 return null;
3779 }
3780
3781 /** VariableDeclaratorId = Ident BracketsOpt
3782 */
3783 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {
4268 mods.flags |= Flags.RECORD;
4269 Name name = typeName();
4270
4271 List<JCTypeParameter> typarams = typeParametersOpt();
4272
4273 List<JCVariableDecl> headerFields = formalParameters(false, true);
4274
4275 List<JCExpression> implementing = List.nil();
4276 if (token.kind == IMPLEMENTS) {
4277 nextToken();
4278 implementing = typeList();
4279 }
4280 List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4281 java.util.List<JCVariableDecl> fields = new ArrayList<>();
4282 for (JCVariableDecl field : headerFields) {
4283 fields.add(field);
4284 }
4285 for (JCTree def : defs) {
4286 if (def.hasTag(METHODDEF)) {
4287 JCMethodDecl methDef = (JCMethodDecl) def;
4288 if (methDef.name == names.init && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4289 ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4290 for (JCVariableDecl param : headerFields) {
4291 tmpParams.add(F.at(param)
4292 // we will get flags plus annotations from the record component
4293 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | Flags.MANDATED | param.mods.flags & Flags.VARARGS,
4294 param.mods.annotations),
4295 param.name, param.vartype, null));
4296 }
4297 methDef.params = tmpParams.toList();
4298 }
4299 }
4300 }
4301 for (int i = fields.size() - 1; i >= 0; i--) {
4302 JCVariableDecl field = fields.get(i);
4303 defs = defs.prepend(field);
4304 }
4305 JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4306 attach(result, dc);
4307 return result;
4308 }
4809 Token next = S.token(3);
4810 return allowedAfterSealedOrNonSealed(next, local, true);
4811 }
4812 return false;
4813 }
4814
4815 protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4816 if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4817 Token tokenSub = S.token(lookAheadOffset + 1);
4818 Token tokenSealed = S.token(lookAheadOffset + 2);
4819 if (someToken.endPos == tokenSub.pos &&
4820 tokenSub.endPos == tokenSealed.pos &&
4821 tokenSealed.name() == names.sealed) {
4822 checkSourceLevel(Feature.SEALED_CLASSES);
4823 return true;
4824 }
4825 }
4826 return false;
4827 }
4828
4829 protected boolean isSealedClassStart(boolean local) {
4830 if (token.name() == names.sealed) {
4831 Token next = S.token(1);
4832 if (allowedAfterSealedOrNonSealed(next, local, false)) {
4833 checkSourceLevel(Feature.SEALED_CLASSES);
4834 return true;
4835 }
4836 }
4837 return false;
4838 }
4839
4840 private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4841 return local ?
4842 switch (next.kind) {
4843 case MONKEYS_AT -> {
4844 Token afterNext = S.token(2);
4845 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4846 }
4847 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4848 default -> false;
4849 } :
4850 switch (next.kind) {
4851 case MONKEYS_AT -> {
4852 Token afterNext = S.token(2);
4853 yield afterNext.kind != INTERFACE || currentIsNonSealed;
4854 }
4855 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4856 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;
4857 default -> false;
4858 };
4859 }
4860
4861 /** MethodDeclaratorRest =
4862 * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4863 * VoidMethodDeclaratorRest =
4864 * FormalParameters [THROWS TypeList] ( MethodBody | ";")
4865 * ConstructorDeclaratorRest =
4866 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4867 */
4868 protected JCTree methodDeclaratorRest(int pos,
4869 JCModifiers mods,
4870 JCExpression type,
4871 Name name,
4872 List<JCTypeParameter> typarams,
4873 boolean isInterface, boolean isVoid,
4874 boolean isRecord,
4875 Comment dc) {
4876 if (isInterface) {
4877 if ((mods.flags & Flags.PRIVATE) != 0) {
4878 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4879 }
4880 }
4881 JCVariableDecl prevReceiverParam = this.receiverParam;
4882 try {
4883 this.receiverParam = null;
4884 // Parsing formalParameters sets the receiverParam, if present
4885 List<JCVariableDecl> params = List.nil();
4886 List<JCExpression> thrown = List.nil();
4887 if (!isRecord || name != names.init || token.kind == LPAREN) {
4888 params = formalParameters();
4889 if (!isVoid) type = bracketsOpt(type);
4890 if (token.kind == THROWS) {
4891 nextToken();
4892 thrown = qualidentList(true);
4893 }
4894 }
4895 JCBlock body = null;
4896 JCExpression defaultValue;
4897 if (token.kind == LBRACE) {
4898 body = block();
4899 defaultValue = null;
4900 } else {
4901 if (token.kind == DEFAULT) {
4902 accept(DEFAULT);
4903 defaultValue = annotationValue();
4904 } else {
4905 defaultValue = null;
4906 }
4907 accept(SEMI);
5323 case INT:
5324 return TypeTag.INT;
5325 case LONG:
5326 return TypeTag.LONG;
5327 case FLOAT:
5328 return TypeTag.FLOAT;
5329 case DOUBLE:
5330 return TypeTag.DOUBLE;
5331 case BOOLEAN:
5332 return TypeTag.BOOLEAN;
5333 default:
5334 return TypeTag.NONE;
5335 }
5336 }
5337
5338 void checkSourceLevel(Feature feature) {
5339 checkSourceLevel(token.pos, feature);
5340 }
5341
5342 protected void checkSourceLevel(int pos, Feature feature) {
5343 if (preview.isPreview(feature) && !preview.isEnabled()) {
5344 //preview feature without --preview flag, error
5345 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5346 } else if (!feature.allowedInSource(source)) {
5347 //incompatible source level, error
5348 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5349 } else if (preview.isPreview(feature)) {
5350 //use of preview feature, warn
5351 preview.warnPreview(pos, feature);
5352 }
5353 }
5354
5355 /*
5356 * a functional source tree and end position mappings
5357 */
5358 protected static class SimpleEndPosTable extends AbstractEndPosTable {
5359
5360 private final IntHashTable endPosMap;
5361
5362 SimpleEndPosTable(JavacParser parser) {
5363 super(parser);
|
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 javax.lang.model.SourceVersion;
34
35 import com.sun.source.tree.CaseTree;
36 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
37 import com.sun.source.tree.ModuleTree.ModuleKind;
38
39 import com.sun.tools.javac.code.*;
40 import com.sun.tools.javac.code.Flags.Flag;
41 import com.sun.tools.javac.code.Source.Feature;
42 import com.sun.tools.javac.file.PathFileObject;
43 import com.sun.tools.javac.parser.Tokens.*;
44 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
45 import com.sun.tools.javac.resources.CompilerProperties.Errors;
46 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
47 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
48 import com.sun.tools.javac.tree.*;
49 import com.sun.tools.javac.tree.JCTree.*;
50 import com.sun.tools.javac.util.*;
51 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
52 import com.sun.tools.javac.util.JCDiagnostic.Error;
53 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
54 import com.sun.tools.javac.util.List;
55
56 import static com.sun.tools.javac.code.Flags.asFlagSet;
57 import static com.sun.tools.javac.parser.Tokens.TokenKind.*;
58 import static com.sun.tools.javac.parser.Tokens.TokenKind.ASSERT;
59 import static com.sun.tools.javac.parser.Tokens.TokenKind.CASE;
60 import static com.sun.tools.javac.parser.Tokens.TokenKind.CATCH;
61 import static com.sun.tools.javac.parser.Tokens.TokenKind.EQ;
62 import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
63 import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
64 import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
65 import static com.sun.tools.javac.parser.Tokens.TokenKind.SYNCHRONIZED;
66 import static com.sun.tools.javac.tree.JCTree.Tag.*;
67 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
68 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
69 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
70 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
71
72 /**
73 * The parser maps a token sequence into an abstract syntax tree.
74 * The parser is a hand-written recursive-descent parser that
75 * implements the grammar described in the Java Language Specification.
76 * For efficiency reasons, an operator precedence scheme is used
77 * for parsing binary operation expressions.
78 *
79 * <p><b>This is NOT part of any supported API.
80 * If you write code that depends on this, you do so at your own risk.
81 * This code and its internal interfaces are subject to change or
82 * deletion without notice.</b>
83 */
84 public class JavacParser implements Parser {
85
178 boolean keepLineMap,
179 boolean keepEndPositions,
180 boolean parseModuleInfo) {
181 this.S = S;
182 nextToken(); // prime the pump
183 this.F = fac.F;
184 this.log = fac.log;
185 this.names = fac.names;
186 this.source = fac.source;
187 this.preview = fac.preview;
188 this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
189 this.keepDocComments = keepDocComments;
190 this.parseModuleInfo = parseModuleInfo;
191 this.docComments = newDocCommentTable(keepDocComments, fac);
192 this.keepLineMap = keepLineMap;
193 this.errorTree = F.Erroneous();
194 this.endPosTable = newEndPosTable(keepEndPositions);
195 this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
196 this.allowRecords = Feature.RECORDS.allowedInSource(source);
197 this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
198 this.allowPrimitiveClasses = Feature.PRIMITIVE_CLASSES.allowedInSource(source) && fac.options.isSet("enablePrimitiveClasses");
199 this.allowValueClasses = Feature.VALUE_CLASSES.allowedInSource(source);
200 }
201
202 /** Construct a parser from an existing parser, with minimal overhead.
203 */
204 @SuppressWarnings("this-escape")
205 protected JavacParser(JavacParser parser,
206 Lexer S) {
207 this.S = S;
208 this.token = parser.token;
209 this.F = parser.F;
210 this.log = parser.log;
211 this.names = parser.names;
212 this.source = parser.source;
213 this.preview = parser.preview;
214 this.allowStringFolding = parser.allowStringFolding;
215 this.keepDocComments = false;
216 this.parseModuleInfo = false;
217 this.docComments = null;
218 this.errorTree = F.Erroneous();
219 this.endPosTable = newEndPosTable(false);
220 this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
221 this.allowRecords = Feature.RECORDS.allowedInSource(source);
222 this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);
223 this.allowPrimitiveClasses = parser.allowPrimitiveClasses;
224 this.allowValueClasses = parser.allowValueClasses;
225 }
226
227 protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
228 return keepEndPositions
229 ? new SimpleEndPosTable(this)
230 : new EmptyEndPosTable(this);
231 }
232
233 protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
234 return keepDocComments ? new LazyDocCommentTable(fac) : null;
235 }
236
237 /** Switch: should we fold strings?
238 */
239 boolean allowStringFolding;
240
241 /** Switch: should we keep docComments?
242 */
243 boolean keepDocComments;
244
245 /** Switch: should we keep line table?
246 */
247 boolean keepLineMap;
248
249 /** Switch: is "this" allowed as an identifier?
250 * This is needed to parse receiver types.
251 */
252 boolean allowThisIdent;
253
254 /** Switch: is yield statement allowed in this source level?
255 */
256 boolean allowYieldStatement;
257
258 /** Switch: are records allowed in this source level?
259 */
260 boolean allowRecords;
261
262 /** Switch: are primitive classes allowed in this source level?
263 */
264 boolean allowPrimitiveClasses;
265
266 /** Switch: are value classes allowed in this source level?
267 */
268 boolean allowValueClasses;
269
270 /** Switch: are sealed types allowed in this source level?
271 */
272 boolean allowSealedTypes;
273
274 /** The type of the method receiver, as specified by a first "this" parameter.
275 */
276 JCVariableDecl receiverParam;
277
278 /** When terms are parsed, the mode determines which is expected:
279 * mode = EXPR : an expression
280 * mode = TYPE : a type
281 * mode = NOPARAMS : no parameters allowed for type
282 * mode = TYPEARG : type argument
283 * mode |= NOLAMBDA : lambdas are not allowed
284 */
285 protected static final int EXPR = 1 << 0;
286 protected static final int TYPE = 1 << 1;
287 protected static final int NOPARAMS = 1 << 2;
288 protected static final int TYPEARG = 1 << 3;
289 protected static final int DIAMOND = 1 << 4;
513
514 /** If next input token matches given token, skip it, otherwise report
515 * an error.
516 */
517 public void accept(TokenKind tk) {
518 accept(tk, Errors::Expected);
519 }
520
521 /** If next input token matches given token, skip it, otherwise report
522 * an error.
523 */
524 public void accept(TokenKind tk, Function<TokenKind, Error> errorProvider) {
525 if (token.kind == tk) {
526 nextToken();
527 } else {
528 setErrorEndPos(token.pos);
529 reportSyntaxError(S.prevToken().endPos, errorProvider.apply(tk));
530 }
531 }
532
533 /** If next input token matches one of the two given tokens, skip it, otherwise report
534 * an error.
535 *
536 * @return The actual token kind.
537 */
538 public TokenKind accept2(TokenKind tk1, TokenKind tk2) {
539 TokenKind returnValue = token.kind;
540 if (token.kind == tk1 || token.kind == tk2) {
541 nextToken();
542 } else {
543 setErrorEndPos(token.pos);
544 reportSyntaxError(S.prevToken().endPos, Errors.Expected2(tk1, tk2));
545 }
546 return returnValue;
547 }
548
549 /** Report an illegal start of expression/type error at given position.
550 */
551 JCExpression illegal(int pos) {
552 setErrorEndPos(pos);
553 if (isMode(EXPR))
554 return syntaxError(pos, Errors.IllegalStartOfExpr);
555 else
556 return syntaxError(pos, Errors.IllegalStartOfType);
557
558 }
559
560 /** Report an illegal start of expression/type error at current position.
561 */
562 JCExpression illegal() {
563 return illegal(token.pos);
564 }
565
566 /** Diagnose a modifier flag from the set, if any. */
567 protected void checkNoMods(long mods) {
568 checkNoMods(token.pos, mods);
1519 break loop;
1520 case LPAREN:
1521 if (isMode(EXPR)) {
1522 selectExprMode();
1523 t = arguments(typeArgs, t);
1524 if (!annos.isEmpty()) t = illegal(annos.head.pos);
1525 typeArgs = null;
1526 }
1527 break loop;
1528 case DOT:
1529 nextToken();
1530 if (token.kind == TokenKind.IDENTIFIER && typeArgs != null) {
1531 return illegal();
1532 }
1533 int prevmode = mode;
1534 setMode(mode & ~NOPARAMS);
1535 typeArgs = typeArgumentsOpt(EXPR);
1536 setMode(prevmode);
1537 if (isMode(EXPR)) {
1538 switch (token.kind) {
1539 case DEFAULT:
1540 if (typeArgs != null) return illegal();
1541 selectExprMode();
1542 t = to(F.at(pos).DefaultValue(t));
1543 nextToken();
1544 break loop;
1545 case CLASS:
1546 if (typeArgs != null) return illegal();
1547 selectExprMode();
1548 t = to(F.at(pos).Select(t, names._class));
1549 nextToken();
1550 break loop;
1551 case THIS:
1552 if (typeArgs != null) return illegal();
1553 selectExprMode();
1554 t = to(F.at(pos).Select(t, names._this));
1555 nextToken();
1556 break loop;
1557 case SUPER:
1558 selectExprMode();
1559 t = to(F.at(pos).Select(t, names._super));
1560 t = superSuffix(typeArgs, t);
1561 typeArgs = null;
1562 break loop;
1563 case NEW:
1564 if (typeArgs != null) return illegal();
1588 token.kind == MONKEYS_AT) {
1589 //error recovery, case like:
1590 //int i = expr.<missing-ident>
1591 //@Deprecated
1592 if (typeArgs != null) illegal();
1593 return toP(t);
1594 }
1595 if (tyannos != null && tyannos.nonEmpty()) {
1596 t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1597 }
1598 break;
1599 case ELLIPSIS:
1600 if (this.permitTypeAnnotationsPushBack) {
1601 this.typeAnnotationsPushedBack = annos;
1602 } else if (annos.nonEmpty()) {
1603 // Don't return here -- error recovery attempt
1604 illegal(annos.head.pos);
1605 }
1606 break loop;
1607 case LT:
1608 if (!isMode(TYPE) && isParameterizedTypePrefix()) {
1609 //this is either an unbound method reference whose qualifier
1610 //is a generic type i.e. A<S>::m or a default value creation of
1611 //the form ValueType<S>.default
1612 int pos1 = token.pos;
1613 accept(LT);
1614 ListBuffer<JCExpression> args = new ListBuffer<>();
1615 args.append(typeArgument());
1616 while (token.kind == COMMA) {
1617 nextToken();
1618 args.append(typeArgument());
1619 }
1620 accept(GT);
1621 t = toP(F.at(pos1).TypeApply(t, args.toList()));
1622 while (token.kind == DOT) {
1623 nextToken();
1624 if (token.kind == DEFAULT) {
1625 t = toP(F.at(token.pos).DefaultValue(t));
1626 nextToken();
1627 selectExprMode();
1628 return term3Rest(t, typeArgs);
1629 }
1630 selectTypeMode();
1631 t = toP(F.at(token.pos).Select(t, ident()));
1632 t = typeArgumentsOpt(t);
1633 }
1634 t = bracketsOpt(t);
1635 if (token.kind != COLCOL) {
1636 //method reference expected here
1637 t = illegal();
1638 }
1639 selectExprMode();
1640 return term3Rest(t, typeArgs);
1641 }
1642 break loop;
1643 default:
1644 break loop;
1645 }
1646 }
1647 }
1648 if (typeArgs != null) illegal();
1649 t = typeArgumentsOpt(t);
1840 if (!annos.isEmpty()) {
1841 if (permitTypeAnnotationsPushBack)
1842 typeAnnotationsPushedBack = annos;
1843 else
1844 return illegal(annos.head.pos);
1845 }
1846 break;
1847 }
1848 }
1849 while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1850 selectExprMode();
1851 t = to(F.at(token.pos).Unary(
1852 token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1853 nextToken();
1854 }
1855 return toP(t);
1856 }
1857
1858 /**
1859 * If we see an identifier followed by a '<' it could be an unbound
1860 * method reference or a default value creation that uses a parameterized type
1861 * or a binary expression. To disambiguate, look for a
1862 * matching '>' and see if the subsequent terminal is either '.' or '::'.
1863 */
1864 @SuppressWarnings("fallthrough")
1865 boolean isParameterizedTypePrefix() {
1866 int pos = 0, depth = 0;
1867 outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1868 switch (t.kind) {
1869 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1870 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1871 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1872 case DOUBLE: case BOOLEAN: case CHAR:
1873 case MONKEYS_AT:
1874 break;
1875
1876 case LPAREN:
1877 // skip annotation values
1878 int nesting = 0;
1879 for (; ; pos++) {
1880 TokenKind tk2 = S.token(pos).kind;
1881 switch (tk2) {
1882 case EOF:
1883 return false;
1884 case LPAREN:
1885 nesting++;
2452
2453 private JCExpression bracketsOptCont(JCExpression t, int pos,
2454 List<JCAnnotation> annotations) {
2455 accept(RBRACKET);
2456 t = bracketsOpt(t);
2457 t = toP(F.at(pos).TypeArray(t));
2458 if (annotations.nonEmpty()) {
2459 t = toP(F.at(pos).AnnotatedType(annotations, t));
2460 }
2461 return t;
2462 }
2463
2464 /** BracketsSuffixExpr = "." CLASS
2465 * BracketsSuffixType =
2466 */
2467 JCExpression bracketsSuffix(JCExpression t) {
2468 if (isMode(EXPR) && token.kind == DOT) {
2469 selectExprMode();
2470 int pos = token.pos;
2471 nextToken();
2472 TokenKind selector = accept2(CLASS, DEFAULT);
2473 if (token.pos == endPosTable.errorEndPos) {
2474 // error recovery
2475 Name name;
2476 if (LAX_IDENTIFIER.test(token.kind)) {
2477 name = token.name();
2478 nextToken();
2479 } else {
2480 name = names.error;
2481 }
2482 t = F.at(pos).Erroneous(List.<JCTree>of(toP(F.at(pos).Select(t, name))));
2483 } else {
2484 Tag tag = t.getTag();
2485 // Type annotations are illegal on class literals. Annotated non array class literals
2486 // are complained about directly in term3(), Here check for type annotations on dimensions
2487 // taking care to handle some interior dimension(s) being annotated.
2488 if ((tag == TYPEARRAY && TreeInfo.containsTypeAnnotation(t)) || tag == ANNOTATED_TYPE)
2489 syntaxError(token.pos, Errors.NoAnnotationsOnDotClass);
2490 if (selector == CLASS) {
2491 t = toP(F.at(pos).Select(t, names._class));
2492 } else {
2493 t = toP(F.at(pos).DefaultValue(t));
2494 }
2495 }
2496 } else if (isMode(TYPE)) {
2497 if (token.kind != COLCOL) {
2498 selectTypeMode();
2499 }
2500 } else if (token.kind != COLCOL) {
2501 syntaxError(token.pos, Errors.DotClassExpected);
2502 }
2503 return t;
2504 }
2505
2506 /**
2507 * MemberReferenceSuffix = "::" [TypeArguments] Ident
2508 * | "::" [TypeArguments] "new"
2509 */
2510 JCExpression memberReferenceSuffix(JCExpression t) {
2511 int pos1 = token.pos;
2512 accept(COLCOL);
2513 return memberReferenceSuffix(pos1, t);
2514 }
2515
2516 JCExpression memberReferenceSuffix(int pos1, JCExpression t) {
2517 selectExprMode();
2518 List<JCExpression> typeArgs = null;
2519 if (token.kind == LT) {
2520 typeArgs = typeArguments(false);
2521 }
2522 Name refName;
2523 ReferenceMode refMode;
2524 if (token.kind == NEW) {
2525 refMode = ReferenceMode.NEW;
2526 // TODO - will be converted in Attr
2527 refName = names.init;
2528 nextToken();
2529 } else {
2530 refMode = ReferenceMode.INVOKE;
2531 refName = ident();
2532 }
2533 return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2534 }
2535
2536 /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2537 */
2538 JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2539 final JCModifiers mods = modifiersOpt();
2540 List<JCAnnotation> newAnnotations = mods.annotations;
2541 switch (token.kind) {
2542 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2543 case DOUBLE: case BOOLEAN:
2544 if (mods.flags != 0) {
2545 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2546 }
2547 if (typeArgs == null) {
2548 if (newAnnotations.isEmpty()) {
2549 return arrayCreatorRest(newpos, basicType());
2550 } else {
2551 return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2552 }
2553 }
2554 break;
2555 default:
2556 }
2557 JCExpression t = qualident(true);
2558
2559 int prevmode = mode;
2560 selectTypeMode();
2561 boolean diamondFound = false;
2562 int lastTypeargsPos = -1;
2563 if (token.kind == LT) {
2564 lastTypeargsPos = token.pos;
2565 t = typeArguments(t, true);
2566 diamondFound = isMode(DIAMOND);
2595 JCExpression e = arrayCreatorRest(newpos, t);
2596 if (diamondFound) {
2597 reportSyntaxError(lastTypeargsPos, Errors.CannotCreateArrayWithDiamond);
2598 return toP(F.at(newpos).Erroneous(List.of(e)));
2599 }
2600 else if (typeArgs != null) {
2601 int pos = newpos;
2602 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2603 // note: this should always happen but we should
2604 // not rely on this as the parser is continuously
2605 // modified to improve error recovery.
2606 pos = typeArgs.head.pos;
2607 }
2608 setErrorEndPos(S.prevToken().endPos);
2609 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2610 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2611 return toP(err);
2612 }
2613 return e;
2614 } else if (token.kind == LPAREN) {
2615 long badModifiers = mods.flags & ~(Flags.PRIMITIVE_CLASS | Flags.VALUE_CLASS | Flags.FINAL);
2616 if (badModifiers != 0)
2617 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(badModifiers)));
2618 // handle type annotations for instantiations and anonymous classes
2619 if (newAnnotations.nonEmpty()) {
2620 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2621 }
2622 JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2623 if ((newClass.def == null) && (mods.flags != 0)) {
2624 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2625 }
2626 return newClass;
2627 } else {
2628 setErrorEndPos(token.pos);
2629 reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2630 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2631 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2632 }
2633 }
2634
2635 /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2636 */
2637 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2638 List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2639
2640 JCExpression t = toP(F.at(token.pos).Ident(ident()));
2641
2642 if (newAnnotations.nonEmpty()) {
2643 t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2644 }
2645
2646 if (token.kind == LT) {
2647 int prevmode = mode;
2648 t = typeArguments(t, true);
2649 setMode(prevmode);
2650 }
2651 return classCreatorRest(newpos, encl, typeArgs, t, 0);
2652 }
2653
2654 /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2655 * | Expression "]" {[Annotations] "[" Expression "]"} BracketsOpt )
2656 */
2657 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2658 List<JCAnnotation> annos = typeAnnotationsOpt();
2659
2660 accept(LBRACKET);
2661 if (token.kind == RBRACKET) {
2662 accept(RBRACKET);
2663 elemtype = bracketsOpt(elemtype, annos);
2664 if (token.kind == LBRACE) {
2665 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2666 if (annos.nonEmpty()) {
2667 // when an array initializer is present then
2668 // the parsed annotations should target the
2669 // new array tree
2670 // bracketsOpt inserts the annotation in
2671 // elemtype, and it needs to be corrected
2709 if (token.kind == LBRACE) {
2710 elems = arrayInitializerElements(newpos, elemtype);
2711 }
2712
2713 JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2714 na.dimAnnotations = dimAnnotations.toList();
2715
2716 if (elems != null) {
2717 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2718 }
2719
2720 return na;
2721 }
2722 }
2723
2724 /** ClassCreatorRest = Arguments [ClassBody]
2725 */
2726 JCNewClass classCreatorRest(int newpos,
2727 JCExpression encl,
2728 List<JCExpression> typeArgs,
2729 JCExpression t,
2730 long flags)
2731 {
2732 List<JCExpression> args = arguments();
2733 JCClassDecl body = null;
2734 if (token.kind == LBRACE) {
2735 int pos = token.pos;
2736 List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2737 JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2738 body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2739 }
2740 JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2741 return newClass;
2742 }
2743
2744 /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2745 */
2746 JCExpression arrayInitializer(int newpos, JCExpression t) {
2747 List<JCExpression> elems = arrayInitializerElements(newpos, t);
2748 return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2749 }
2750
2751 List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2752 accept(LBRACE);
2753 ListBuffer<JCExpression> elems = new ListBuffer<>();
2754 if (token.kind == COMMA) {
2755 nextToken();
2756 } else if (token.kind != RBRACE) {
2757 elems.append(variableInitializer());
2758 while (token.kind == COMMA) {
2759 nextToken();
2760 if (token.kind == RBRACE) break;
2761 elems.append(variableInitializer());
2952 accept(SEMI);
2953 return List.of(toP(F.at(pos).Yield(t)));
2954 }
2955
2956 //else intentional fall-through
2957 } else {
2958 if (isNonSealedClassStart(true)) {
2959 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2960 nextToken();
2961 nextToken();
2962 nextToken();
2963 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2964 } else if (isSealedClassStart(true)) {
2965 checkSourceLevel(Feature.SEALED_CLASSES);
2966 log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2967 nextToken();
2968 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.comment(CommentStyle.JAVADOC)));
2969 }
2970 }
2971 }
2972 if ((isPrimitiveModifier() && allowPrimitiveClasses) || (isValueModifier() || isIdentityModifier()) && allowValueClasses) {
2973 dc = token.comment(CommentStyle.JAVADOC);
2974 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2975 }
2976 if (isRecordStart() && allowRecords) {
2977 dc = token.comment(CommentStyle.JAVADOC);
2978 return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2979 } else {
2980 Token prevToken = token;
2981 JCExpression t = term(EXPR | TYPE);
2982 if (token.kind == COLON && t.hasTag(IDENT)) {
2983 nextToken();
2984 JCStatement stat = parseStatementAsBlock();
2985 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2986 } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2987 pos = token.pos;
2988 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2989 F.at(pos);
2990 return localVariableDeclarations(mods, t);
2991 } else {
2992 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2993 t = checkExprStat(t);
2994 accept(SEMI);
2995 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
3447 nextToken();
3448 pos = token.pos;
3449 JCExpression t = parseExpression();
3450 // This Exec is a "StatementExpression"; it subsumes no terminating token
3451 stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3452 }
3453 return stats;
3454 }
3455
3456 /** ForInit = StatementExpression MoreStatementExpressions
3457 * | { FINAL | '@' Annotation } Type VariableDeclarators
3458 */
3459 List<JCStatement> forInit() {
3460 ListBuffer<JCStatement> stats = new ListBuffer<>();
3461 int pos = token.pos;
3462 if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3463 return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3464 } else {
3465 JCExpression t = term(EXPR | TYPE);
3466 if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3467 pos = token.pos;
3468 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3469 F.at(pos);
3470 return variableDeclarators(mods, t, stats, true).toList();
3471 } else if (wasTypeMode() && token.kind == COLON) {
3472 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3473 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3474 } else {
3475 return moreStatementExpressions(pos, t, stats).toList();
3476 }
3477 }
3478 }
3479
3480 /** ForUpdate = StatementExpression MoreStatementExpressions
3481 */
3482 List<JCExpressionStatement> forUpdate() {
3483 return moreStatementExpressions(token.pos,
3484 parseExpression(),
3485 new ListBuffer<JCExpressionStatement>()).toList();
3486 }
3487
3488 /** AnnotationsOpt = { '@' Annotation }
3489 *
3490 * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION
3547 case ABSTRACT : flag = Flags.ABSTRACT; break;
3548 case NATIVE : flag = Flags.NATIVE; break;
3549 case VOLATILE : flag = Flags.VOLATILE; break;
3550 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3551 case STRICTFP : flag = Flags.STRICTFP; break;
3552 case MONKEYS_AT : flag = Flags.ANNOTATION; break;
3553 case DEFAULT : flag = Flags.DEFAULT; break;
3554 case ERROR : flag = 0; nextToken(); break;
3555 case IDENTIFIER : {
3556 if (isNonSealedClassStart(false)) {
3557 flag = Flags.NON_SEALED;
3558 nextToken();
3559 nextToken();
3560 break;
3561 }
3562 if (isSealedClassStart(false)) {
3563 checkSourceLevel(Feature.SEALED_CLASSES);
3564 flag = Flags.SEALED;
3565 break;
3566 }
3567 if (isPrimitiveModifier()) {
3568 flag = Flags.PRIMITIVE_CLASS;
3569 break;
3570 }
3571 if (isValueModifier()) {
3572 flag = Flags.VALUE_CLASS;
3573 break;
3574 }
3575 if (isIdentityModifier()) {
3576 flag = Flags.IDENTITY_TYPE;
3577 break;
3578 }
3579 break loop;
3580 }
3581 default: break loop;
3582 }
3583 if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3584 lastPos = token.pos;
3585 nextToken();
3586 if (flag == Flags.ANNOTATION) {
3587 if (token.kind != INTERFACE) {
3588 JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3589 // if first modifier is an annotation, set pos to annotation's.
3590 if (flags == 0 && annotations.isEmpty())
3591 pos = ann.pos;
3592 annotations.append(ann);
3593 flag = 0;
3594 }
3595 }
3596 flags |= flag;
3597 }
3598 switch (token.kind) {
3825 if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3826 return Source.JDK10;
3827 } else if (shouldWarn) {
3828 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3829 }
3830 }
3831 if (name == names.yield) {
3832 if (allowYieldStatement) {
3833 return Source.JDK14;
3834 } else if (shouldWarn) {
3835 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3836 }
3837 }
3838 if (name == names.record) {
3839 if (allowRecords) {
3840 return Source.JDK14;
3841 } else if (shouldWarn) {
3842 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3843 }
3844 }
3845 if (name == names.primitive) {
3846 if (allowPrimitiveClasses) {
3847 return Source.JDK18;
3848 }
3849 }
3850 if (name == names.value) {
3851 if (allowValueClasses) {
3852 return Source.JDK18;
3853 } else if (shouldWarn) {
3854 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3855 }
3856 }
3857 if (name == names.identity) {
3858 if (allowPrimitiveClasses) {
3859 return Source.JDK18;
3860 } else if (shouldWarn) {
3861 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK18));
3862 }
3863 }
3864 if (name == names.sealed) {
3865 if (allowSealedTypes) {
3866 return Source.JDK15;
3867 } else if (shouldWarn) {
3868 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3869 }
3870 }
3871 if (name == names.permits) {
3872 if (allowSealedTypes) {
3873 return Source.JDK15;
3874 } else if (shouldWarn) {
3875 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3876 }
3877 }
3878 return null;
3879 }
3880
3881 /** VariableDeclaratorId = Ident BracketsOpt
3882 */
3883 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {
4368 mods.flags |= Flags.RECORD;
4369 Name name = typeName();
4370
4371 List<JCTypeParameter> typarams = typeParametersOpt();
4372
4373 List<JCVariableDecl> headerFields = formalParameters(false, true);
4374
4375 List<JCExpression> implementing = List.nil();
4376 if (token.kind == IMPLEMENTS) {
4377 nextToken();
4378 implementing = typeList();
4379 }
4380 List<JCTree> defs = classInterfaceOrRecordBody(name, false, true);
4381 java.util.List<JCVariableDecl> fields = new ArrayList<>();
4382 for (JCVariableDecl field : headerFields) {
4383 fields.add(field);
4384 }
4385 for (JCTree def : defs) {
4386 if (def.hasTag(METHODDEF)) {
4387 JCMethodDecl methDef = (JCMethodDecl) def;
4388 // TODO - specifically for record.
4389 if (names.isInitOrVNew(methDef.name) && methDef.params.isEmpty() && (methDef.mods.flags & Flags.COMPACT_RECORD_CONSTRUCTOR) != 0) {
4390 ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
4391 for (JCVariableDecl param : headerFields) {
4392 tmpParams.add(F.at(param)
4393 // we will get flags plus annotations from the record component
4394 .VarDef(F.Modifiers(Flags.PARAMETER | Flags.GENERATED_MEMBER | Flags.MANDATED | param.mods.flags & Flags.VARARGS,
4395 param.mods.annotations),
4396 param.name, param.vartype, null));
4397 }
4398 methDef.params = tmpParams.toList();
4399 }
4400 }
4401 }
4402 for (int i = fields.size() - 1; i >= 0; i--) {
4403 JCVariableDecl field = fields.get(i);
4404 defs = defs.prepend(field);
4405 }
4406 JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
4407 attach(result, dc);
4408 return result;
4409 }
4910 Token next = S.token(3);
4911 return allowedAfterSealedOrNonSealed(next, local, true);
4912 }
4913 return false;
4914 }
4915
4916 protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4917 if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4918 Token tokenSub = S.token(lookAheadOffset + 1);
4919 Token tokenSealed = S.token(lookAheadOffset + 2);
4920 if (someToken.endPos == tokenSub.pos &&
4921 tokenSub.endPos == tokenSealed.pos &&
4922 tokenSealed.name() == names.sealed) {
4923 checkSourceLevel(Feature.SEALED_CLASSES);
4924 return true;
4925 }
4926 }
4927 return false;
4928 }
4929
4930 protected boolean isPrimitiveModifier() {
4931 if (token.kind == IDENTIFIER && token.name() == names.primitive) {
4932 boolean isPrimitiveModifier = false;
4933 Token next = S.token(1);
4934 switch (next.kind) {
4935 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4936 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4937 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4938 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4939 case CLASS: case INTERFACE: case ENUM:
4940 isPrimitiveModifier = true;
4941 break;
4942 case IDENTIFIER: // primitive record R || primitive primitive || primitive identity || primitive value || new primitive Comparable() {}
4943 if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4944 || next.name() == names.value || (mode & EXPR) != 0)
4945 isPrimitiveModifier = true;
4946 break;
4947 }
4948 if (isPrimitiveModifier) {
4949 checkSourceLevel(Feature.PRIMITIVE_CLASSES);
4950 return true;
4951 }
4952 }
4953 return false;
4954 }
4955
4956 protected boolean isValueModifier() {
4957 if (token.kind == IDENTIFIER && token.name() == names.value) {
4958 boolean isValueModifier = false;
4959 Token next = S.token(1);
4960 switch (next.kind) {
4961 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4962 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4963 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4964 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4965 case CLASS: case INTERFACE: case ENUM:
4966 isValueModifier = true;
4967 break;
4968 case IDENTIFIER: // value record R || value value || value identity || value primitive || new value Comparable() {} ??
4969 if (next.name() == names.record || next.name() == names.value || next.name() == names.identity
4970 || next.name() == names.primitive || (mode & EXPR) != 0)
4971 isValueModifier = true;
4972 break;
4973 }
4974 if (isValueModifier) {
4975 checkSourceLevel(Feature.VALUE_CLASSES);
4976 return true;
4977 }
4978 }
4979 return false;
4980 }
4981
4982 protected boolean isIdentityModifier() {
4983 if (token.kind == IDENTIFIER && token.name() == names.identity) {
4984 boolean isIdentityModifier = false;
4985 Token next = S.token(1);
4986 switch (next.kind) {
4987 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4988 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4989 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4990 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4991 case CLASS: case INTERFACE: case ENUM:
4992 isIdentityModifier = true;
4993 break;
4994 case IDENTIFIER: // identity record R || identity primitive || || identity identity || identity value || new identity Comparable() {}
4995 if (next.name() == names.record || next.name() == names.primitive || next.name() == names.identity
4996 || next.name() == names.value || (mode & EXPR) != 0)
4997 isIdentityModifier = true;
4998 break;
4999 }
5000 if (isIdentityModifier) {
5001 checkSourceLevel(Feature.VALUE_CLASSES);
5002 return true;
5003 }
5004 }
5005 return false;
5006 }
5007
5008 protected boolean isSealedClassStart(boolean local) {
5009 if (token.name() == names.sealed) {
5010 Token next = S.token(1);
5011 if (allowedAfterSealedOrNonSealed(next, local, false)) {
5012 checkSourceLevel(Feature.SEALED_CLASSES);
5013 return true;
5014 }
5015 }
5016 return false;
5017 }
5018
5019 private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
5020 return local ?
5021 switch (next.kind) {
5022 case MONKEYS_AT -> {
5023 Token afterNext = S.token(2);
5024 yield afterNext.kind != INTERFACE || currentIsNonSealed;
5025 }
5026 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
5027 default -> false;
5028 } :
5029 switch (next.kind) {
5030 case MONKEYS_AT -> {
5031 Token afterNext = S.token(2);
5032 yield afterNext.kind != INTERFACE || currentIsNonSealed;
5033 }
5034 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
5035 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
5036 next.name() == names.sealed ||
5037 next.name() == names.value ||
5038 next.name() == names.identity;
5039 default -> false;
5040 };
5041 }
5042
5043 /** MethodDeclaratorRest =
5044 * FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
5045 * VoidMethodDeclaratorRest =
5046 * FormalParameters [THROWS TypeList] ( MethodBody | ";")
5047 * ConstructorDeclaratorRest =
5048 * "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
5049 */
5050 protected JCTree methodDeclaratorRest(int pos,
5051 JCModifiers mods,
5052 JCExpression type,
5053 Name name,
5054 List<JCTypeParameter> typarams,
5055 boolean isInterface, boolean isVoid,
5056 boolean isRecord,
5057 Comment dc) {
5058 if (isInterface) {
5059 if ((mods.flags & Flags.PRIVATE) != 0) {
5060 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
5061 }
5062 }
5063 JCVariableDecl prevReceiverParam = this.receiverParam;
5064 try {
5065 this.receiverParam = null;
5066 // Parsing formalParameters sets the receiverParam, if present
5067 List<JCVariableDecl> params = List.nil();
5068 List<JCExpression> thrown = List.nil();
5069 if (!isRecord || !names.isInitOrVNew(name) || token.kind == LPAREN) {
5070 params = formalParameters();
5071 if (!isVoid) type = bracketsOpt(type);
5072 if (token.kind == THROWS) {
5073 nextToken();
5074 thrown = qualidentList(true);
5075 }
5076 }
5077 JCBlock body = null;
5078 JCExpression defaultValue;
5079 if (token.kind == LBRACE) {
5080 body = block();
5081 defaultValue = null;
5082 } else {
5083 if (token.kind == DEFAULT) {
5084 accept(DEFAULT);
5085 defaultValue = annotationValue();
5086 } else {
5087 defaultValue = null;
5088 }
5089 accept(SEMI);
5505 case INT:
5506 return TypeTag.INT;
5507 case LONG:
5508 return TypeTag.LONG;
5509 case FLOAT:
5510 return TypeTag.FLOAT;
5511 case DOUBLE:
5512 return TypeTag.DOUBLE;
5513 case BOOLEAN:
5514 return TypeTag.BOOLEAN;
5515 default:
5516 return TypeTag.NONE;
5517 }
5518 }
5519
5520 void checkSourceLevel(Feature feature) {
5521 checkSourceLevel(token.pos, feature);
5522 }
5523
5524 protected void checkSourceLevel(int pos, Feature feature) {
5525 if (feature == Feature.PRIMITIVE_CLASSES && !allowPrimitiveClasses) {
5526 // primitive classes are special
5527 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5528 } else if (preview.isPreview(feature) && !preview.isEnabled()) {
5529 //preview feature without --preview flag, error
5530 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, preview.disabledError(feature));
5531 } else if (!feature.allowedInSource(source)) {
5532 //incompatible source level, error
5533 log.error(DiagnosticFlag.SOURCE_LEVEL, pos, feature.error(source.name));
5534 } else if (preview.isPreview(feature)) {
5535 //use of preview feature, warn
5536 preview.warnPreview(pos, feature);
5537 }
5538 }
5539
5540 /*
5541 * a functional source tree and end position mappings
5542 */
5543 protected static class SimpleEndPosTable extends AbstractEndPosTable {
5544
5545 private final IntHashTable endPosMap;
5546
5547 SimpleEndPosTable(JavacParser parser) {
5548 super(parser);
|