< prev index next >

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

Print this page

  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.resources.CompilerProperties.Errors;
  44 import com.sun.tools.javac.resources.CompilerProperties.Fragments;
  45 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
  46 import com.sun.tools.javac.tree.*;
  47 import com.sun.tools.javac.tree.JCTree.*;
  48 import com.sun.tools.javac.util.*;
  49 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
  50 import com.sun.tools.javac.util.JCDiagnostic.Error;
  51 import com.sun.tools.javac.util.JCDiagnostic.Fragment;
  52 import com.sun.tools.javac.util.List;
  53 

  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.tree.JCTree.Tag.*;
  63 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.ImplicitAndExplicitNotAllowed;
  64 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndExplicitNotAllowed;
  65 import static com.sun.tools.javac.resources.CompilerProperties.Fragments.VarAndImplicitNotAllowed;
  66 import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
  67 
  68 /**
  69  * The parser maps a token sequence into an abstract syntax tree.
  70  * The parser is a hand-written recursive-descent parser that
  71  * implements the grammar described in the Java Language Specification.
  72  * For efficiency reasons, an operator precedence scheme is used
  73  * for parsing binary operation expressions.
  74  *
  75  *  <p><b>This is NOT part of any supported API.
  76  *  If you write code that depends on this, you do so at your own risk.
  77  *  This code and its internal interfaces are subject to change or
  78  *  deletion without notice.</b>
  79  */
  80 public class JavacParser implements Parser {
  81 

 174                      boolean keepLineMap,
 175                      boolean keepEndPositions,
 176                      boolean parseModuleInfo) {
 177         this.S = S;
 178         nextToken(); // prime the pump
 179         this.F = fac.F;
 180         this.log = fac.log;
 181         this.names = fac.names;
 182         this.source = fac.source;
 183         this.preview = fac.preview;
 184         this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
 185         this.keepDocComments = keepDocComments;
 186         this.parseModuleInfo = parseModuleInfo;
 187         this.docComments = newDocCommentTable(keepDocComments, fac);
 188         this.keepLineMap = keepLineMap;
 189         this.errorTree = F.Erroneous();
 190         this.endPosTable = newEndPosTable(keepEndPositions);
 191         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 192         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 193         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);


 194     }
 195 
 196     /** Construct a parser from an existing parser, with minimal overhead.
 197      */
 198     @SuppressWarnings("this-escape")
 199     protected JavacParser(JavacParser parser,
 200                           Lexer S) {
 201         this.S = S;
 202         this.token = parser.token;
 203         this.F = parser.F;
 204         this.log = parser.log;
 205         this.names = parser.names;
 206         this.source = parser.source;
 207         this.preview = parser.preview;
 208         this.allowStringFolding = parser.allowStringFolding;
 209         this.keepDocComments = parser.keepDocComments;
 210         this.parseModuleInfo = false;
 211         this.docComments = parser.docComments;
 212         this.errorTree = F.Erroneous();
 213         this.endPosTable = newEndPosTable(false);
 214         this.allowYieldStatement = Feature.SWITCH_EXPRESSION.allowedInSource(source);
 215         this.allowRecords = Feature.RECORDS.allowedInSource(source);
 216         this.allowSealedTypes = Feature.SEALED_CLASSES.allowedInSource(source);


 217     }
 218 
 219     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 220         return  keepEndPositions
 221                 ? new SimpleEndPosTable(this)
 222                 : new EmptyEndPosTable(this);
 223     }
 224 
 225     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 226         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 227     }
 228 
 229     /** Switch: should we fold strings?
 230      */
 231     boolean allowStringFolding;
 232 
 233     /** Switch: should we keep docComments?
 234      */
 235     boolean keepDocComments;
 236 
 237     /** Switch: should we keep line table?
 238      */
 239     boolean keepLineMap;
 240 
 241     /** Switch: is "this" allowed as an identifier?
 242      * This is needed to parse receiver types.
 243      */
 244     boolean allowThisIdent;
 245 
 246     /** Switch: is yield statement allowed in this source level?
 247      */
 248     boolean allowYieldStatement;
 249 
 250     /** Switch: are records allowed in this source level?
 251      */
 252     boolean allowRecords;
 253 




 254     /** Switch: are sealed types allowed in this source level?
 255      */
 256     boolean allowSealedTypes;
 257 
 258     /** The type of the method receiver, as specified by a first "this" parameter.
 259      */
 260     JCVariableDecl receiverParam;
 261 
 262     /** When terms are parsed, the mode determines which is expected:
 263      *     mode = EXPR        : an expression
 264      *     mode = TYPE        : a type
 265      *     mode = NOPARAMS    : no parameters allowed for type
 266      *     mode = TYPEARG     : type argument
 267      *     mode |= NOLAMBDA   : lambdas are not allowed
 268      */
 269     protected static final int EXPR          = 1 << 0;
 270     protected static final int TYPE          = 1 << 1;
 271     protected static final int NOPARAMS      = 1 << 2;
 272     protected static final int TYPEARG       = 1 << 3;
 273     protected static final int DIAMOND       = 1 << 4;

1579                             token.kind == MONKEYS_AT) {
1580                             //error recovery, case like:
1581                             //int i = expr.<missing-ident>
1582                             //@Deprecated
1583                             if (typeArgs != null) illegal();
1584                             return toP(t);
1585                         }
1586                         if (tyannos != null && tyannos.nonEmpty()) {
1587                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1588                         }
1589                         break;
1590                     case ELLIPSIS:
1591                         if (this.permitTypeAnnotationsPushBack) {
1592                             this.typeAnnotationsPushedBack = annos;
1593                         } else if (annos.nonEmpty()) {
1594                             // Don't return here -- error recovery attempt
1595                             illegal(annos.head.pos);
1596                         }
1597                         break loop;
1598                     case LT:
1599                         if (!isMode(TYPE) && isUnboundMemberRef()) {
1600                             //this is an unbound method reference whose qualifier
1601                             //is a generic type i.e. A<S>::m
1602                             int pos1 = token.pos;
1603                             accept(LT);
1604                             ListBuffer<JCExpression> args = new ListBuffer<>();
1605                             args.append(typeArgument());
1606                             while (token.kind == COMMA) {
1607                                 nextToken();
1608                                 args.append(typeArgument());
1609                             }
1610                             accept(GT);
1611                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1612                             while (token.kind == DOT) {
1613                                 nextToken();
1614                                 selectTypeMode();
1615                                 t = toP(F.at(token.pos).Select(t, ident()));
1616                                 t = typeArgumentsOpt(t);
1617                             }
1618                             t = bracketsOpt(t);
1619                             if (token.kind != COLCOL) {
1620                                 //method reference expected here

1828                         return illegal(annos.head.pos);
1829                 }
1830                 break;
1831             }
1832         }
1833         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1834             selectExprMode();
1835             t = to(F.at(token.pos).Unary(
1836                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1837             nextToken();
1838         }
1839         return toP(t);
1840     }
1841 
1842     /**
1843      * If we see an identifier followed by a '&lt;' it could be an unbound
1844      * method reference or a binary expression. To disambiguate, look for a
1845      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1846      */
1847     @SuppressWarnings("fallthrough")
1848     boolean isUnboundMemberRef() {
1849         int pos = 0, depth = 0;
1850         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1851             switch (t.kind) {
1852                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1853                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1854                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1855                 case DOUBLE: case BOOLEAN: case CHAR:
1856                 case MONKEYS_AT:
1857                     break;
1858 
1859                 case LPAREN:
1860                     // skip annotation values
1861                     int nesting = 0;
1862                     for (; ; pos++) {
1863                         TokenKind tk2 = S.token(pos).kind;
1864                         switch (tk2) {
1865                             case EOF:
1866                                 return false;
1867                             case LPAREN:
1868                                 nesting++;

2497         List<JCExpression> typeArgs = null;
2498         if (token.kind == LT) {
2499             typeArgs = typeArguments(false);
2500         }
2501         Name refName;
2502         ReferenceMode refMode;
2503         if (token.kind == NEW) {
2504             refMode = ReferenceMode.NEW;
2505             refName = names.init;
2506             nextToken();
2507         } else {
2508             refMode = ReferenceMode.INVOKE;
2509             refName = ident();
2510         }
2511         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2512     }
2513 
2514     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2515      */
2516     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2517         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2518 
2519         switch (token.kind) {
2520         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2521         case DOUBLE: case BOOLEAN:



2522             if (typeArgs == null) {
2523                 if (newAnnotations.isEmpty()) {
2524                     return arrayCreatorRest(newpos, basicType());
2525                 } else {
2526                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2527                 }
2528             }
2529             break;
2530         default:
2531         }
2532         JCExpression t = qualident(true);
2533 
2534         int prevmode = mode;
2535         selectTypeMode();
2536         boolean diamondFound = false;
2537         int lastTypeargsPos = -1;
2538         if (token.kind == LT) {
2539             lastTypeargsPos = token.pos;
2540             t = typeArguments(t, true);
2541             diamondFound = isMode(DIAMOND);

2574             }
2575             else if (typeArgs != null) {
2576                 int pos = newpos;
2577                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2578                     // note: this should always happen but we should
2579                     // not rely on this as the parser is continuously
2580                     // modified to improve error recovery.
2581                     pos = typeArgs.head.pos;
2582                 }
2583                 setErrorEndPos(S.prevToken().endPos);
2584                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2585                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2586                 return toP(err);
2587             }
2588             return e;
2589         } else if (token.kind == LPAREN) {
2590             // handle type annotations for instantiations and anonymous classes
2591             if (newAnnotations.nonEmpty()) {
2592                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2593             }
2594             return classCreatorRest(newpos, null, typeArgs, t);




2595         } else {
2596             setErrorEndPos(token.pos);
2597             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2598             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2599             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2600         }
2601     }
2602 
2603     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2604      */
2605     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2606         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2607 
2608         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2609 
2610         if (newAnnotations.nonEmpty()) {
2611             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2612         }
2613 
2614         if (token.kind == LT) {
2615             int prevmode = mode;
2616             t = typeArguments(t, true);
2617             setMode(prevmode);
2618         }
2619         return classCreatorRest(newpos, encl, typeArgs, t);
2620     }
2621 
2622     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2623      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2624      */
2625     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2626         List<JCAnnotation> annos = typeAnnotationsOpt();
2627 
2628         accept(LBRACKET);
2629         if (token.kind == RBRACKET) {
2630             accept(RBRACKET);
2631             elemtype = bracketsOpt(elemtype, annos);
2632             if (token.kind == LBRACE) {
2633                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2634                 if (annos.nonEmpty()) {
2635                     // when an array initializer is present then
2636                     // the parsed annotations should target the
2637                     // new array tree
2638                     // bracketsOpt inserts the annotation in
2639                     // elemtype, and it needs to be corrected

2677             if (token.kind == LBRACE) {
2678                 elems = arrayInitializerElements(newpos, elemtype);
2679             }
2680 
2681             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2682             na.dimAnnotations = dimAnnotations.toList();
2683 
2684             if (elems != null) {
2685                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2686             }
2687 
2688             return na;
2689         }
2690     }
2691 
2692     /** ClassCreatorRest = Arguments [ClassBody]
2693      */
2694     JCNewClass classCreatorRest(int newpos,
2695                                   JCExpression encl,
2696                                   List<JCExpression> typeArgs,
2697                                   JCExpression t)

2698     {
2699         List<JCExpression> args = arguments();
2700         JCClassDecl body = null;
2701         if (token.kind == LBRACE) {
2702             int pos = token.pos;
2703             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2704             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2705             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2706         }
2707         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2708     }
2709 
2710     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2711      */
2712     JCExpression arrayInitializer(int newpos, JCExpression t) {
2713         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2714         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2715     }
2716 
2717     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2718         accept(LBRACE);
2719         ListBuffer<JCExpression> elems = new ListBuffer<>();
2720         if (token.kind == COMMA) {
2721             nextToken();
2722         } else if (token.kind != RBRACE) {
2723             elems.append(variableInitializer());
2724             while (token.kind == COMMA) {

2919                     accept(SEMI);
2920                     return List.of(toP(F.at(pos).Yield(t)));
2921                 }
2922 
2923                 //else intentional fall-through
2924             } else {
2925                 if (isNonSealedClassStart(true)) {
2926                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2927                     nextToken();
2928                     nextToken();
2929                     nextToken();
2930                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2931                 } else if (isSealedClassStart(true)) {
2932                     checkSourceLevel(Feature.SEALED_CLASSES);
2933                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2934                     nextToken();
2935                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2936                 }
2937             }
2938         }





2939         if (isRecordStart() && allowRecords) {
2940             dc = token.docComment();
2941             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2942         } else {
2943             Token prevToken = token;
2944             JCExpression t = term(EXPR | TYPE);
2945             if (token.kind == COLON && t.hasTag(IDENT)) {
2946                 nextToken();
2947                 JCStatement stat = parseStatementAsBlock();
2948                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2949             } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2950                 pos = token.pos;
2951                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2952                 F.at(pos);
2953                 return localVariableDeclarations(mods, t);
2954             } else {
2955                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2956                 t = checkExprStat(t);
2957                 accept(SEMI);
2958                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3414             nextToken();
3415             pos = token.pos;
3416             JCExpression t = parseExpression();
3417             // This Exec is a "StatementExpression"; it subsumes no terminating token
3418             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3419         }
3420         return stats;
3421     }
3422 
3423     /** ForInit = StatementExpression MoreStatementExpressions
3424      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3425      */
3426     List<JCStatement> forInit() {
3427         ListBuffer<JCStatement> stats = new ListBuffer<>();
3428         int pos = token.pos;
3429         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3430             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3431         } else {
3432             JCExpression t = term(EXPR | TYPE);
3433             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3434                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3435             } else if (wasTypeMode() && token.kind == COLON) {
3436                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3437                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3438             } else {
3439                 return moreStatementExpressions(pos, t, stats).toList();
3440             }
3441         }
3442     }
3443 
3444     /** ForUpdate = StatementExpression MoreStatementExpressions
3445      */
3446     List<JCExpressionStatement> forUpdate() {
3447         return moreStatementExpressions(token.pos,
3448                                         parseExpression(),
3449                                         new ListBuffer<JCExpressionStatement>()).toList();
3450     }
3451 
3452     /** AnnotationsOpt = { '@' Annotation }
3453      *
3454      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3511             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3512             case NATIVE      : flag = Flags.NATIVE; break;
3513             case VOLATILE    : flag = Flags.VOLATILE; break;
3514             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3515             case STRICTFP    : flag = Flags.STRICTFP; break;
3516             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3517             case DEFAULT     : flag = Flags.DEFAULT; break;
3518             case ERROR       : flag = 0; nextToken(); break;
3519             case IDENTIFIER  : {
3520                 if (isNonSealedClassStart(false)) {
3521                     flag = Flags.NON_SEALED;
3522                     nextToken();
3523                     nextToken();
3524                     break;
3525                 }
3526                 if (isSealedClassStart(false)) {
3527                     checkSourceLevel(Feature.SEALED_CLASSES);
3528                     flag = Flags.SEALED;
3529                     break;
3530                 }





3531                 break loop;
3532             }
3533             default: break loop;
3534             }
3535             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3536             lastPos = token.pos;
3537             nextToken();
3538             if (flag == Flags.ANNOTATION) {
3539                 if (token.kind != INTERFACE) {
3540                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3541                     // if first modifier is an annotation, set pos to annotation's.
3542                     if (flags == 0 && annotations.isEmpty())
3543                         pos = ann.pos;
3544                     annotations.append(ann);
3545                     flag = 0;
3546                 }
3547             }
3548             flags |= flag;
3549         }
3550         switch (token.kind) {

3777             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3778                 return Source.JDK10;
3779             } else if (shouldWarn) {
3780                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3781             }
3782         }
3783         if (name == names.yield) {
3784             if (allowYieldStatement) {
3785                 return Source.JDK14;
3786             } else if (shouldWarn) {
3787                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3788             }
3789         }
3790         if (name == names.record) {
3791             if (allowRecords) {
3792                 return Source.JDK14;
3793             } else if (shouldWarn) {
3794                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3795             }
3796         }







3797         if (name == names.sealed) {
3798             if (allowSealedTypes) {
3799                 return Source.JDK15;
3800             } else if (shouldWarn) {
3801                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3802             }
3803         }
3804         if (name == names.permits) {
3805             if (allowSealedTypes) {
3806                 return Source.JDK15;
3807             } else if (shouldWarn) {
3808                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3809             }
3810         }
3811         return null;
3812     }
3813 
3814     /** VariableDeclaratorId = Ident BracketsOpt
3815      */
3816     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4843             Token next = S.token(3);
4844             return allowedAfterSealedOrNonSealed(next, local, true);
4845         }
4846         return false;
4847     }
4848 
4849     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4850         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4851             Token tokenSub = S.token(lookAheadOffset + 1);
4852             Token tokenSealed = S.token(lookAheadOffset + 2);
4853             if (someToken.endPos == tokenSub.pos &&
4854                     tokenSub.endPos == tokenSealed.pos &&
4855                     tokenSealed.name() == names.sealed) {
4856                 checkSourceLevel(Feature.SEALED_CLASSES);
4857                 return true;
4858             }
4859         }
4860         return false;
4861     }
4862 


























4863     protected boolean isSealedClassStart(boolean local) {
4864         if (token.name() == names.sealed) {
4865             Token next = S.token(1);
4866             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4867                 checkSourceLevel(Feature.SEALED_CLASSES);
4868                 return true;
4869             }
4870         }
4871         return false;
4872     }
4873 
4874     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4875         return local ?
4876             switch (next.kind) {
4877                 case MONKEYS_AT -> {
4878                     Token afterNext = S.token(2);
4879                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4880                 }
4881                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4882                 default -> false;
4883             } :
4884             switch (next.kind) {
4885                 case MONKEYS_AT -> {
4886                     Token afterNext = S.token(2);
4887                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4888                 }
4889                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4890                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;


4891                 default -> false;
4892             };
4893     }
4894 
4895     /** MethodDeclaratorRest =
4896      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4897      *  VoidMethodDeclaratorRest =
4898      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4899      *  ConstructorDeclaratorRest =
4900      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4901      */
4902     protected JCTree methodDeclaratorRest(int pos,
4903                               JCModifiers mods,
4904                               JCExpression type,
4905                               Name name,
4906                               List<JCTypeParameter> typarams,
4907                               boolean isInterface, boolean isVoid,
4908                               boolean isRecord,
4909                               Comment dc) {
4910         if (isInterface) {

  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.allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 199                 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 = parser.keepDocComments;
 216         this.parseModuleInfo = false;
 217         this.docComments = parser.docComments;
 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.allowValueClasses = (!preview.isPreview(Feature.VALUE_CLASSES) || preview.isEnabled()) &&
 224                 Feature.VALUE_CLASSES.allowedInSource(source);
 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 value classes allowed in this source level?
 263      */
 264     boolean allowValueClasses;
 265 
 266     /** Switch: are sealed types allowed in this source level?
 267      */
 268     boolean allowSealedTypes;
 269 
 270     /** The type of the method receiver, as specified by a first "this" parameter.
 271      */
 272     JCVariableDecl receiverParam;
 273 
 274     /** When terms are parsed, the mode determines which is expected:
 275      *     mode = EXPR        : an expression
 276      *     mode = TYPE        : a type
 277      *     mode = NOPARAMS    : no parameters allowed for type
 278      *     mode = TYPEARG     : type argument
 279      *     mode |= NOLAMBDA   : lambdas are not allowed
 280      */
 281     protected static final int EXPR          = 1 << 0;
 282     protected static final int TYPE          = 1 << 1;
 283     protected static final int NOPARAMS      = 1 << 2;
 284     protected static final int TYPEARG       = 1 << 3;
 285     protected static final int DIAMOND       = 1 << 4;

1591                             token.kind == MONKEYS_AT) {
1592                             //error recovery, case like:
1593                             //int i = expr.<missing-ident>
1594                             //@Deprecated
1595                             if (typeArgs != null) illegal();
1596                             return toP(t);
1597                         }
1598                         if (tyannos != null && tyannos.nonEmpty()) {
1599                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1600                         }
1601                         break;
1602                     case ELLIPSIS:
1603                         if (this.permitTypeAnnotationsPushBack) {
1604                             this.typeAnnotationsPushedBack = annos;
1605                         } else if (annos.nonEmpty()) {
1606                             // Don't return here -- error recovery attempt
1607                             illegal(annos.head.pos);
1608                         }
1609                         break loop;
1610                     case LT:
1611                         if (!isMode(TYPE) && isParameterizedTypePrefix()) {
1612                             //this is either an unbound method reference whose qualifier
1613                             //is a generic type i.e. A<S>::m
1614                             int pos1 = token.pos;
1615                             accept(LT);
1616                             ListBuffer<JCExpression> args = new ListBuffer<>();
1617                             args.append(typeArgument());
1618                             while (token.kind == COMMA) {
1619                                 nextToken();
1620                                 args.append(typeArgument());
1621                             }
1622                             accept(GT);
1623                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1624                             while (token.kind == DOT) {
1625                                 nextToken();
1626                                 selectTypeMode();
1627                                 t = toP(F.at(token.pos).Select(t, ident()));
1628                                 t = typeArgumentsOpt(t);
1629                             }
1630                             t = bracketsOpt(t);
1631                             if (token.kind != COLCOL) {
1632                                 //method reference expected here

1840                         return illegal(annos.head.pos);
1841                 }
1842                 break;
1843             }
1844         }
1845         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1846             selectExprMode();
1847             t = to(F.at(token.pos).Unary(
1848                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1849             nextToken();
1850         }
1851         return toP(t);
1852     }
1853 
1854     /**
1855      * If we see an identifier followed by a '&lt;' it could be an unbound
1856      * method reference or a binary expression. To disambiguate, look for a
1857      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1858      */
1859     @SuppressWarnings("fallthrough")
1860     boolean isParameterizedTypePrefix() {
1861         int pos = 0, depth = 0;
1862         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1863             switch (t.kind) {
1864                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1865                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1866                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1867                 case DOUBLE: case BOOLEAN: case CHAR:
1868                 case MONKEYS_AT:
1869                     break;
1870 
1871                 case LPAREN:
1872                     // skip annotation values
1873                     int nesting = 0;
1874                     for (; ; pos++) {
1875                         TokenKind tk2 = S.token(pos).kind;
1876                         switch (tk2) {
1877                             case EOF:
1878                                 return false;
1879                             case LPAREN:
1880                                 nesting++;

2509         List<JCExpression> typeArgs = null;
2510         if (token.kind == LT) {
2511             typeArgs = typeArguments(false);
2512         }
2513         Name refName;
2514         ReferenceMode refMode;
2515         if (token.kind == NEW) {
2516             refMode = ReferenceMode.NEW;
2517             refName = names.init;
2518             nextToken();
2519         } else {
2520             refMode = ReferenceMode.INVOKE;
2521             refName = ident();
2522         }
2523         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2524     }
2525 
2526     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2527      */
2528     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2529         final JCModifiers mods = modifiersOpt();
2530         List<JCAnnotation> newAnnotations = mods.annotations;
2531         switch (token.kind) {
2532         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2533         case DOUBLE: case BOOLEAN:
2534             if (mods.flags != 0) {
2535                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2536             }
2537             if (typeArgs == null) {
2538                 if (newAnnotations.isEmpty()) {
2539                     return arrayCreatorRest(newpos, basicType());
2540                 } else {
2541                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2542                 }
2543             }
2544             break;
2545         default:
2546         }
2547         JCExpression t = qualident(true);
2548 
2549         int prevmode = mode;
2550         selectTypeMode();
2551         boolean diamondFound = false;
2552         int lastTypeargsPos = -1;
2553         if (token.kind == LT) {
2554             lastTypeargsPos = token.pos;
2555             t = typeArguments(t, true);
2556             diamondFound = isMode(DIAMOND);

2589             }
2590             else if (typeArgs != null) {
2591                 int pos = newpos;
2592                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2593                     // note: this should always happen but we should
2594                     // not rely on this as the parser is continuously
2595                     // modified to improve error recovery.
2596                     pos = typeArgs.head.pos;
2597                 }
2598                 setErrorEndPos(S.prevToken().endPos);
2599                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2600                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2601                 return toP(err);
2602             }
2603             return e;
2604         } else if (token.kind == LPAREN) {
2605             // handle type annotations for instantiations and anonymous classes
2606             if (newAnnotations.nonEmpty()) {
2607                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2608             }
2609             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2610             if ((newClass.def == null) && (mods.flags != 0)) {
2611                 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2612             }
2613             return newClass;
2614         } else {
2615             setErrorEndPos(token.pos);
2616             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2617             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2618             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2619         }
2620     }
2621 
2622     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2623      */
2624     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2625         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2626 
2627         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2628 
2629         if (newAnnotations.nonEmpty()) {
2630             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2631         }
2632 
2633         if (token.kind == LT) {
2634             int prevmode = mode;
2635             t = typeArguments(t, true);
2636             setMode(prevmode);
2637         }
2638         return classCreatorRest(newpos, encl, typeArgs, t, 0);
2639     }
2640 
2641     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2642      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2643      */
2644     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2645         List<JCAnnotation> annos = typeAnnotationsOpt();
2646 
2647         accept(LBRACKET);
2648         if (token.kind == RBRACKET) {
2649             accept(RBRACKET);
2650             elemtype = bracketsOpt(elemtype, annos);
2651             if (token.kind == LBRACE) {
2652                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2653                 if (annos.nonEmpty()) {
2654                     // when an array initializer is present then
2655                     // the parsed annotations should target the
2656                     // new array tree
2657                     // bracketsOpt inserts the annotation in
2658                     // elemtype, and it needs to be corrected

2696             if (token.kind == LBRACE) {
2697                 elems = arrayInitializerElements(newpos, elemtype);
2698             }
2699 
2700             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2701             na.dimAnnotations = dimAnnotations.toList();
2702 
2703             if (elems != null) {
2704                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2705             }
2706 
2707             return na;
2708         }
2709     }
2710 
2711     /** ClassCreatorRest = Arguments [ClassBody]
2712      */
2713     JCNewClass classCreatorRest(int newpos,
2714                                   JCExpression encl,
2715                                   List<JCExpression> typeArgs,
2716                                   JCExpression t,
2717                                   long flags)
2718     {
2719         List<JCExpression> args = arguments();
2720         JCClassDecl body = null;
2721         if (token.kind == LBRACE) {
2722             int pos = token.pos;
2723             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2724             JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2725             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2726         }
2727         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2728     }
2729 
2730     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2731      */
2732     JCExpression arrayInitializer(int newpos, JCExpression t) {
2733         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2734         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2735     }
2736 
2737     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2738         accept(LBRACE);
2739         ListBuffer<JCExpression> elems = new ListBuffer<>();
2740         if (token.kind == COMMA) {
2741             nextToken();
2742         } else if (token.kind != RBRACE) {
2743             elems.append(variableInitializer());
2744             while (token.kind == COMMA) {

2939                     accept(SEMI);
2940                     return List.of(toP(F.at(pos).Yield(t)));
2941                 }
2942 
2943                 //else intentional fall-through
2944             } else {
2945                 if (isNonSealedClassStart(true)) {
2946                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2947                     nextToken();
2948                     nextToken();
2949                     nextToken();
2950                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2951                 } else if (isSealedClassStart(true)) {
2952                     checkSourceLevel(Feature.SEALED_CLASSES);
2953                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2954                     nextToken();
2955                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2956                 }
2957             }
2958         }
2959         if ((isValueModifier()) && allowValueClasses) {
2960             checkSourceLevel(Feature.VALUE_CLASSES);
2961             dc = token.docComment();
2962             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2963         }
2964         if (isRecordStart() && allowRecords) {
2965             dc = token.docComment();
2966             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2967         } else {
2968             Token prevToken = token;
2969             JCExpression t = term(EXPR | TYPE);
2970             if (token.kind == COLON && t.hasTag(IDENT)) {
2971                 nextToken();
2972                 JCStatement stat = parseStatementAsBlock();
2973                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2974             } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2975                 pos = token.pos;
2976                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2977                 F.at(pos);
2978                 return localVariableDeclarations(mods, t);
2979             } else {
2980                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2981                 t = checkExprStat(t);
2982                 accept(SEMI);
2983                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3439             nextToken();
3440             pos = token.pos;
3441             JCExpression t = parseExpression();
3442             // This Exec is a "StatementExpression"; it subsumes no terminating token
3443             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3444         }
3445         return stats;
3446     }
3447 
3448     /** ForInit = StatementExpression MoreStatementExpressions
3449      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3450      */
3451     List<JCStatement> forInit() {
3452         ListBuffer<JCStatement> stats = new ListBuffer<>();
3453         int pos = token.pos;
3454         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3455             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3456         } else {
3457             JCExpression t = term(EXPR | TYPE);
3458             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3459                 pos = token.pos;
3460                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3461                 F.at(pos);
3462                 return variableDeclarators(mods, t, stats, true).toList();
3463             } else if (wasTypeMode() && token.kind == COLON) {
3464                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3465                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3466             } else {
3467                 return moreStatementExpressions(pos, t, stats).toList();
3468             }
3469         }
3470     }
3471 
3472     /** ForUpdate = StatementExpression MoreStatementExpressions
3473      */
3474     List<JCExpressionStatement> forUpdate() {
3475         return moreStatementExpressions(token.pos,
3476                                         parseExpression(),
3477                                         new ListBuffer<JCExpressionStatement>()).toList();
3478     }
3479 
3480     /** AnnotationsOpt = { '@' Annotation }
3481      *
3482      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3539             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3540             case NATIVE      : flag = Flags.NATIVE; break;
3541             case VOLATILE    : flag = Flags.VOLATILE; break;
3542             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3543             case STRICTFP    : flag = Flags.STRICTFP; break;
3544             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3545             case DEFAULT     : flag = Flags.DEFAULT; break;
3546             case ERROR       : flag = 0; nextToken(); break;
3547             case IDENTIFIER  : {
3548                 if (isNonSealedClassStart(false)) {
3549                     flag = Flags.NON_SEALED;
3550                     nextToken();
3551                     nextToken();
3552                     break;
3553                 }
3554                 if (isSealedClassStart(false)) {
3555                     checkSourceLevel(Feature.SEALED_CLASSES);
3556                     flag = Flags.SEALED;
3557                     break;
3558                 }
3559                 if (isValueModifier()) {
3560                     checkSourceLevel(Feature.VALUE_CLASSES);
3561                     flag = Flags.VALUE_CLASS;
3562                     break;
3563                 }
3564                 break loop;
3565             }
3566             default: break loop;
3567             }
3568             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3569             lastPos = token.pos;
3570             nextToken();
3571             if (flag == Flags.ANNOTATION) {
3572                 if (token.kind != INTERFACE) {
3573                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3574                     // if first modifier is an annotation, set pos to annotation's.
3575                     if (flags == 0 && annotations.isEmpty())
3576                         pos = ann.pos;
3577                     annotations.append(ann);
3578                     flag = 0;
3579                 }
3580             }
3581             flags |= flag;
3582         }
3583         switch (token.kind) {

3810             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3811                 return Source.JDK10;
3812             } else if (shouldWarn) {
3813                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3814             }
3815         }
3816         if (name == names.yield) {
3817             if (allowYieldStatement) {
3818                 return Source.JDK14;
3819             } else if (shouldWarn) {
3820                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3821             }
3822         }
3823         if (name == names.record) {
3824             if (allowRecords) {
3825                 return Source.JDK14;
3826             } else if (shouldWarn) {
3827                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3828             }
3829         }
3830         if (name == names.value) {
3831             if (allowValueClasses) {
3832                 return Source.JDK23;
3833             } else if (shouldWarn) {
3834                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK23));
3835             }
3836         }
3837         if (name == names.sealed) {
3838             if (allowSealedTypes) {
3839                 return Source.JDK15;
3840             } else if (shouldWarn) {
3841                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3842             }
3843         }
3844         if (name == names.permits) {
3845             if (allowSealedTypes) {
3846                 return Source.JDK15;
3847             } else if (shouldWarn) {
3848                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3849             }
3850         }
3851         return null;
3852     }
3853 
3854     /** VariableDeclaratorId = Ident BracketsOpt
3855      */
3856     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4883             Token next = S.token(3);
4884             return allowedAfterSealedOrNonSealed(next, local, true);
4885         }
4886         return false;
4887     }
4888 
4889     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4890         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4891             Token tokenSub = S.token(lookAheadOffset + 1);
4892             Token tokenSealed = S.token(lookAheadOffset + 2);
4893             if (someToken.endPos == tokenSub.pos &&
4894                     tokenSub.endPos == tokenSealed.pos &&
4895                     tokenSealed.name() == names.sealed) {
4896                 checkSourceLevel(Feature.SEALED_CLASSES);
4897                 return true;
4898             }
4899         }
4900         return false;
4901     }
4902 
4903     protected boolean isValueModifier() {
4904         if (token.kind == IDENTIFIER && token.name() == names.value) {
4905             boolean isValueModifier = false;
4906             Token next = S.token(1);
4907             switch (next.kind) {
4908                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4909                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4910                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4911                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4912                 case CLASS: case INTERFACE: case ENUM:
4913                     isValueModifier = true;
4914                     break;
4915                 case IDENTIFIER: // value record R || value value || new value Comparable() {} ??
4916                     if (next.name() == names.record || next.name() == names.value
4917                             || (mode & EXPR) != 0)
4918                         isValueModifier = true;
4919                     break;
4920             }
4921             if (isValueModifier) {
4922                 checkSourceLevel(Feature.VALUE_CLASSES);
4923                 return true;
4924             }
4925         }
4926         return false;
4927     }
4928 
4929     protected boolean isSealedClassStart(boolean local) {
4930         if (token.name() == names.sealed) {
4931             Token next = S.token(1);
4932             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4933                 checkSourceLevel(Feature.SEALED_CLASSES);
4934                 return true;
4935             }
4936         }
4937         return false;
4938     }
4939 
4940     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4941         return local ?
4942             switch (next.kind) {
4943                 case MONKEYS_AT -> {
4944                     Token afterNext = S.token(2);
4945                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4946                 }
4947                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4948                 default -> false;
4949             } :
4950             switch (next.kind) {
4951                 case MONKEYS_AT -> {
4952                     Token afterNext = S.token(2);
4953                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4954                 }
4955                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4956                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
4957                         next.name() == names.sealed ||
4958                         allowValueClasses && next.name() == names.value;
4959                 default -> false;
4960             };
4961     }
4962 
4963     /** MethodDeclaratorRest =
4964      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4965      *  VoidMethodDeclaratorRest =
4966      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4967      *  ConstructorDeclaratorRest =
4968      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4969      */
4970     protected JCTree methodDeclaratorRest(int pos,
4971                               JCModifiers mods,
4972                               JCExpression type,
4973                               Name name,
4974                               List<JCTypeParameter> typarams,
4975                               boolean isInterface, boolean isVoid,
4976                               boolean isRecord,
4977                               Comment dc) {
4978         if (isInterface) {
< prev index next >