< 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 = false;
 210         this.parseModuleInfo = false;
 211         this.docComments = null;
 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;

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

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 '&lt;' it could be an unbound
1816      * method reference or a binary expression. To disambiguate, look for a
1817      * matching '&gt;' 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++;

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);

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) {

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.docComment()));
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.docComment()));
2907                 }
2908             }
2909         }





2910         if (isRecordStart() && allowRecords) {
2911             dc = token.docComment();
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));

3383             nextToken();
3384             pos = token.pos;
3385             JCExpression t = parseExpression();
3386             // This Exec is a "StatementExpression"; it subsumes no terminating token
3387             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3388         }
3389         return stats;
3390     }
3391 
3392     /** ForInit = StatementExpression MoreStatementExpressions
3393      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3394      */
3395     List<JCStatement> forInit() {
3396         ListBuffer<JCStatement> stats = new ListBuffer<>();
3397         int pos = token.pos;
3398         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3399             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3400         } else {
3401             JCExpression t = term(EXPR | TYPE);
3402             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3403                 return variableDeclarators(modifiersOpt(), t, stats, true).toList();



3404             } else if (wasTypeMode() && token.kind == COLON) {
3405                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3406                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3407             } else {
3408                 return moreStatementExpressions(pos, t, stats).toList();
3409             }
3410         }
3411     }
3412 
3413     /** ForUpdate = StatementExpression MoreStatementExpressions
3414      */
3415     List<JCExpressionStatement> forUpdate() {
3416         return moreStatementExpressions(token.pos,
3417                                         parseExpression(),
3418                                         new ListBuffer<JCExpressionStatement>()).toList();
3419     }
3420 
3421     /** AnnotationsOpt = { '@' Annotation }
3422      *
3423      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3480             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3481             case NATIVE      : flag = Flags.NATIVE; break;
3482             case VOLATILE    : flag = Flags.VOLATILE; break;
3483             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3484             case STRICTFP    : flag = Flags.STRICTFP; break;
3485             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3486             case DEFAULT     : flag = Flags.DEFAULT; break;
3487             case ERROR       : flag = 0; nextToken(); break;
3488             case IDENTIFIER  : {
3489                 if (isNonSealedClassStart(false)) {
3490                     flag = Flags.NON_SEALED;
3491                     nextToken();
3492                     nextToken();
3493                     break;
3494                 }
3495                 if (isSealedClassStart(false)) {
3496                     checkSourceLevel(Feature.SEALED_CLASSES);
3497                     flag = Flags.SEALED;
3498                     break;
3499                 }





3500                 break loop;
3501             }
3502             default: break loop;
3503             }
3504             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3505             lastPos = token.pos;
3506             nextToken();
3507             if (flag == Flags.ANNOTATION) {
3508                 if (token.kind != INTERFACE) {
3509                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3510                     // if first modifier is an annotation, set pos to annotation's.
3511                     if (flags == 0 && annotations.isEmpty())
3512                         pos = ann.pos;
3513                     annotations.append(ann);
3514                     flag = 0;
3515                 }
3516             }
3517             flags |= flag;
3518         }
3519         switch (token.kind) {

3746             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3747                 return Source.JDK10;
3748             } else if (shouldWarn) {
3749                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3750             }
3751         }
3752         if (name == names.yield) {
3753             if (allowYieldStatement) {
3754                 return Source.JDK14;
3755             } else if (shouldWarn) {
3756                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3757             }
3758         }
3759         if (name == names.record) {
3760             if (allowRecords) {
3761                 return Source.JDK14;
3762             } else if (shouldWarn) {
3763                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3764             }
3765         }







3766         if (name == names.sealed) {
3767             if (allowSealedTypes) {
3768                 return Source.JDK15;
3769             } else if (shouldWarn) {
3770                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3771             }
3772         }
3773         if (name == names.permits) {
3774             if (allowSealedTypes) {
3775                 return Source.JDK15;
3776             } else if (shouldWarn) {
3777                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3778             }
3779         }
3780         return null;
3781     }
3782 
3783     /** VariableDeclaratorId = Ident BracketsOpt
3784      */
3785     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4813             Token next = S.token(3);
4814             return allowedAfterSealedOrNonSealed(next, local, true);
4815         }
4816         return false;
4817     }
4818 
4819     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4820         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4821             Token tokenSub = S.token(lookAheadOffset + 1);
4822             Token tokenSealed = S.token(lookAheadOffset + 2);
4823             if (someToken.endPos == tokenSub.pos &&
4824                     tokenSub.endPos == tokenSealed.pos &&
4825                     tokenSealed.name() == names.sealed) {
4826                 checkSourceLevel(Feature.SEALED_CLASSES);
4827                 return true;
4828             }
4829         }
4830         return false;
4831     }
4832 


























4833     protected boolean isSealedClassStart(boolean local) {
4834         if (token.name() == names.sealed) {
4835             Token next = S.token(1);
4836             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4837                 checkSourceLevel(Feature.SEALED_CLASSES);
4838                 return true;
4839             }
4840         }
4841         return false;
4842     }
4843 
4844     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4845         return local ?
4846             switch (next.kind) {
4847                 case MONKEYS_AT -> {
4848                     Token afterNext = S.token(2);
4849                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4850                 }
4851                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4852                 default -> false;
4853             } :
4854             switch (next.kind) {
4855                 case MONKEYS_AT -> {
4856                     Token afterNext = S.token(2);
4857                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4858                 }
4859                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4860                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;


4861                 default -> false;
4862             };
4863     }
4864 
4865     /** MethodDeclaratorRest =
4866      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4867      *  VoidMethodDeclaratorRest =
4868      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4869      *  ConstructorDeclaratorRest =
4870      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4871      */
4872     protected JCTree methodDeclaratorRest(int pos,
4873                               JCModifiers mods,
4874                               JCExpression type,
4875                               Name name,
4876                               List<JCTypeParameter> typarams,
4877                               boolean isInterface, boolean isVoid,
4878                               boolean isRecord,
4879                               Comment dc) {
4880         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 = 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.allowValueClasses = parser.allowValueClasses;
 224     }
 225 
 226     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
 227         return  keepEndPositions
 228                 ? new SimpleEndPosTable(this)
 229                 : new EmptyEndPosTable(this);
 230     }
 231 
 232     protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFactory fac) {
 233         return keepDocComments ? new LazyDocCommentTable(fac) : null;
 234     }
 235 
 236     /** Switch: should we fold strings?
 237      */
 238     boolean allowStringFolding;
 239 
 240     /** Switch: should we keep docComments?
 241      */
 242     boolean keepDocComments;
 243 
 244     /** Switch: should we keep line table?
 245      */
 246     boolean keepLineMap;
 247 
 248     /** Switch: is "this" allowed as an identifier?
 249      * This is needed to parse receiver types.
 250      */
 251     boolean allowThisIdent;
 252 
 253     /** Switch: is yield statement allowed in this source level?
 254      */
 255     boolean allowYieldStatement;
 256 
 257     /** Switch: are records allowed in this source level?
 258      */
 259     boolean allowRecords;
 260 
 261     /** Switch: are value classes allowed in this source level?
 262      */
 263     boolean allowValueClasses;
 264 
 265     /** Switch: are sealed types allowed in this source level?
 266      */
 267     boolean allowSealedTypes;
 268 
 269     /** The type of the method receiver, as specified by a first "this" parameter.
 270      */
 271     JCVariableDecl receiverParam;
 272 
 273     /** When terms are parsed, the mode determines which is expected:
 274      *     mode = EXPR        : an expression
 275      *     mode = TYPE        : a type
 276      *     mode = NOPARAMS    : no parameters allowed for type
 277      *     mode = TYPEARG     : type argument
 278      *     mode |= NOLAMBDA   : lambdas are not allowed
 279      */
 280     protected static final int EXPR          = 1 << 0;
 281     protected static final int TYPE          = 1 << 1;
 282     protected static final int NOPARAMS      = 1 << 2;
 283     protected static final int TYPEARG       = 1 << 3;
 284     protected static final int DIAMOND       = 1 << 4;

1562                             token.kind == MONKEYS_AT) {
1563                             //error recovery, case like:
1564                             //int i = expr.<missing-ident>
1565                             //@Deprecated
1566                             if (typeArgs != null) illegal();
1567                             return toP(t);
1568                         }
1569                         if (tyannos != null && tyannos.nonEmpty()) {
1570                             t = toP(F.at(tyannos.head.pos).AnnotatedType(tyannos, t));
1571                         }
1572                         break;
1573                     case ELLIPSIS:
1574                         if (this.permitTypeAnnotationsPushBack) {
1575                             this.typeAnnotationsPushedBack = annos;
1576                         } else if (annos.nonEmpty()) {
1577                             // Don't return here -- error recovery attempt
1578                             illegal(annos.head.pos);
1579                         }
1580                         break loop;
1581                     case LT:
1582                         if (!isMode(TYPE) && isParameterizedTypePrefix()) {
1583                             //this is either an unbound method reference whose qualifier
1584                             //is a generic type i.e. A<S>::m
1585                             int pos1 = token.pos;
1586                             accept(LT);
1587                             ListBuffer<JCExpression> args = new ListBuffer<>();
1588                             args.append(typeArgument());
1589                             while (token.kind == COMMA) {
1590                                 nextToken();
1591                                 args.append(typeArgument());
1592                             }
1593                             accept(GT);
1594                             t = toP(F.at(pos1).TypeApply(t, args.toList()));
1595                             while (token.kind == DOT) {
1596                                 nextToken();
1597                                 selectTypeMode();
1598                                 t = toP(F.at(token.pos).Select(t, ident()));
1599                                 t = typeArgumentsOpt(t);
1600                             }
1601                             t = bracketsOpt(t);
1602                             if (token.kind != COLCOL) {
1603                                 //method reference expected here

1811                         return illegal(annos.head.pos);
1812                 }
1813                 break;
1814             }
1815         }
1816         while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && isMode(EXPR)) {
1817             selectExprMode();
1818             t = to(F.at(token.pos).Unary(
1819                   token.kind == PLUSPLUS ? POSTINC : POSTDEC, t));
1820             nextToken();
1821         }
1822         return toP(t);
1823     }
1824 
1825     /**
1826      * If we see an identifier followed by a '&lt;' it could be an unbound
1827      * method reference or a binary expression. To disambiguate, look for a
1828      * matching '&gt;' and see if the subsequent terminal is either '.' or '::'.
1829      */
1830     @SuppressWarnings("fallthrough")
1831     boolean isParameterizedTypePrefix() {
1832         int pos = 0, depth = 0;
1833         outer: for (Token t = S.token(pos) ; ; t = S.token(++pos)) {
1834             switch (t.kind) {
1835                 case IDENTIFIER: case UNDERSCORE: case QUES: case EXTENDS: case SUPER:
1836                 case DOT: case RBRACKET: case LBRACKET: case COMMA:
1837                 case BYTE: case SHORT: case INT: case LONG: case FLOAT:
1838                 case DOUBLE: case BOOLEAN: case CHAR:
1839                 case MONKEYS_AT:
1840                     break;
1841 
1842                 case LPAREN:
1843                     // skip annotation values
1844                     int nesting = 0;
1845                     for (; ; pos++) {
1846                         TokenKind tk2 = S.token(pos).kind;
1847                         switch (tk2) {
1848                             case EOF:
1849                                 return false;
1850                             case LPAREN:
1851                                 nesting++;

2480         List<JCExpression> typeArgs = null;
2481         if (token.kind == LT) {
2482             typeArgs = typeArguments(false);
2483         }
2484         Name refName;
2485         ReferenceMode refMode;
2486         if (token.kind == NEW) {
2487             refMode = ReferenceMode.NEW;
2488             refName = names.init;
2489             nextToken();
2490         } else {
2491             refMode = ReferenceMode.INVOKE;
2492             refName = ident();
2493         }
2494         return toP(F.at(t.getStartPosition()).Reference(refMode, refName, t, typeArgs));
2495     }
2496 
2497     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
2498      */
2499     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
2500         final JCModifiers mods = modifiersOpt();
2501         List<JCAnnotation> newAnnotations = mods.annotations;
2502         switch (token.kind) {
2503         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
2504         case DOUBLE: case BOOLEAN:
2505             if (mods.flags != 0) {
2506                 log.error(token.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2507             }
2508             if (typeArgs == null) {
2509                 if (newAnnotations.isEmpty()) {
2510                     return arrayCreatorRest(newpos, basicType());
2511                 } else {
2512                     return arrayCreatorRest(newpos, toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, basicType())));
2513                 }
2514             }
2515             break;
2516         default:
2517         }
2518         JCExpression t = qualident(true);
2519 
2520         int prevmode = mode;
2521         selectTypeMode();
2522         boolean diamondFound = false;
2523         int lastTypeargsPos = -1;
2524         if (token.kind == LT) {
2525             lastTypeargsPos = token.pos;
2526             t = typeArguments(t, true);
2527             diamondFound = isMode(DIAMOND);

2560             }
2561             else if (typeArgs != null) {
2562                 int pos = newpos;
2563                 if (!typeArgs.isEmpty() && typeArgs.head.pos != Position.NOPOS) {
2564                     // note: this should always happen but we should
2565                     // not rely on this as the parser is continuously
2566                     // modified to improve error recovery.
2567                     pos = typeArgs.head.pos;
2568                 }
2569                 setErrorEndPos(S.prevToken().endPos);
2570                 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
2571                 reportSyntaxError(err, Errors.CannotCreateArrayWithTypeArguments);
2572                 return toP(err);
2573             }
2574             return e;
2575         } else if (token.kind == LPAREN) {
2576             // handle type annotations for instantiations and anonymous classes
2577             if (newAnnotations.nonEmpty()) {
2578                 t = insertAnnotationsToMostInner(t, newAnnotations, false);
2579             }
2580             JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t, mods.flags);
2581             if ((newClass.def == null) && (mods.flags != 0)) {
2582                 log.error(newClass.pos, Errors.ModNotAllowedHere(asFlagSet(mods.flags)));
2583             }
2584             return newClass;
2585         } else {
2586             setErrorEndPos(token.pos);
2587             reportSyntaxError(token.pos, Errors.Expected2(LPAREN, LBRACKET));
2588             t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.nil(), null));
2589             return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
2590         }
2591     }
2592 
2593     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
2594      */
2595     JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
2596         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
2597 
2598         JCExpression t = toP(F.at(token.pos).Ident(ident()));
2599 
2600         if (newAnnotations.nonEmpty()) {
2601             t = toP(F.at(newAnnotations.head.pos).AnnotatedType(newAnnotations, t));
2602         }
2603 
2604         if (token.kind == LT) {
2605             int prevmode = mode;
2606             t = typeArguments(t, true);
2607             setMode(prevmode);
2608         }
2609         return classCreatorRest(newpos, encl, typeArgs, t, 0);
2610     }
2611 
2612     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
2613      *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
2614      */
2615     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
2616         List<JCAnnotation> annos = typeAnnotationsOpt();
2617 
2618         accept(LBRACKET);
2619         if (token.kind == RBRACKET) {
2620             accept(RBRACKET);
2621             elemtype = bracketsOpt(elemtype, annos);
2622             if (token.kind == LBRACE) {
2623                 JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
2624                 if (annos.nonEmpty()) {
2625                     // when an array initializer is present then
2626                     // the parsed annotations should target the
2627                     // new array tree
2628                     // bracketsOpt inserts the annotation in
2629                     // elemtype, and it needs to be corrected

2667             if (token.kind == LBRACE) {
2668                 elems = arrayInitializerElements(newpos, elemtype);
2669             }
2670 
2671             JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), elems));
2672             na.dimAnnotations = dimAnnotations.toList();
2673 
2674             if (elems != null) {
2675                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2676             }
2677 
2678             return na;
2679         }
2680     }
2681 
2682     /** ClassCreatorRest = Arguments [ClassBody]
2683      */
2684     JCNewClass classCreatorRest(int newpos,
2685                                   JCExpression encl,
2686                                   List<JCExpression> typeArgs,
2687                                   JCExpression t,
2688                                   long flags)
2689     {
2690         List<JCExpression> args = arguments();
2691         JCClassDecl body = null;
2692         if (token.kind == LBRACE) {
2693             int pos = token.pos;
2694             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2695             JCModifiers mods = F.at(Position.NOPOS).Modifiers(flags);
2696             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2697         }
2698         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2699     }
2700 
2701     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2702      */
2703     JCExpression arrayInitializer(int newpos, JCExpression t) {
2704         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2705         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2706     }
2707 
2708     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2709         accept(LBRACE);
2710         ListBuffer<JCExpression> elems = new ListBuffer<>();
2711         if (token.kind == COMMA) {
2712             nextToken();
2713         } else if (token.kind != RBRACE) {
2714             elems.append(variableInitializer());
2715             while (token.kind == COMMA) {

2909                     accept(SEMI);
2910                     return List.of(toP(F.at(pos).Yield(t)));
2911                 }
2912 
2913                 //else intentional fall-through
2914             } else {
2915                 if (isNonSealedClassStart(true)) {
2916                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2917                     nextToken();
2918                     nextToken();
2919                     nextToken();
2920                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2921                 } else if (isSealedClassStart(true)) {
2922                     checkSourceLevel(Feature.SEALED_CLASSES);
2923                     log.error(token.pos, Errors.SealedOrNonSealedLocalClassesNotAllowed);
2924                     nextToken();
2925                     return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), token.docComment()));
2926                 }
2927             }
2928         }
2929         if ((isValueModifier()) && allowValueClasses) {
2930             checkSourceLevel(Feature.VALUE_CLASSES);
2931             dc = token.docComment();
2932             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2933         }
2934         if (isRecordStart() && allowRecords) {
2935             dc = token.docComment();
2936             return List.of(recordDeclaration(F.at(pos).Modifiers(0), dc));
2937         } else {
2938             Token prevToken = token;
2939             JCExpression t = term(EXPR | TYPE);
2940             if (token.kind == COLON && t.hasTag(IDENT)) {
2941                 nextToken();
2942                 JCStatement stat = parseStatementAsBlock();
2943                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2944             } else if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
2945                 pos = token.pos;
2946                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2947                 F.at(pos);
2948                 return localVariableDeclarations(mods, t);
2949             } else {
2950                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2951                 t = checkExprStat(t);
2952                 accept(SEMI);
2953                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));

3407             nextToken();
3408             pos = token.pos;
3409             JCExpression t = parseExpression();
3410             // This Exec is a "StatementExpression"; it subsumes no terminating token
3411             stats.append(toP(F.at(pos).Exec(checkExprStat(t))));
3412         }
3413         return stats;
3414     }
3415 
3416     /** ForInit = StatementExpression MoreStatementExpressions
3417      *           |  { FINAL | '@' Annotation } Type VariableDeclarators
3418      */
3419     List<JCStatement> forInit() {
3420         ListBuffer<JCStatement> stats = new ListBuffer<>();
3421         int pos = token.pos;
3422         if (token.kind == FINAL || token.kind == MONKEYS_AT) {
3423             return variableDeclarators(optFinal(0), parseType(true), stats, true).toList();
3424         } else {
3425             JCExpression t = term(EXPR | TYPE);
3426             if (wasTypeMode() && LAX_IDENTIFIER.test(token.kind)) {
3427                 pos = token.pos;
3428                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
3429                 F.at(pos);
3430                 return variableDeclarators(mods, t, stats, true).toList();
3431             } else if (wasTypeMode() && token.kind == COLON) {
3432                 log.error(DiagnosticFlag.SYNTAX, pos, Errors.BadInitializer("for-loop"));
3433                 return List.of((JCStatement)F.at(pos).VarDef(modifiersOpt(), names.error, t, null));
3434             } else {
3435                 return moreStatementExpressions(pos, t, stats).toList();
3436             }
3437         }
3438     }
3439 
3440     /** ForUpdate = StatementExpression MoreStatementExpressions
3441      */
3442     List<JCExpressionStatement> forUpdate() {
3443         return moreStatementExpressions(token.pos,
3444                                         parseExpression(),
3445                                         new ListBuffer<JCExpressionStatement>()).toList();
3446     }
3447 
3448     /** AnnotationsOpt = { '@' Annotation }
3449      *
3450      * @param kind Whether to parse an ANNOTATION or TYPE_ANNOTATION

3507             case ABSTRACT    : flag = Flags.ABSTRACT; break;
3508             case NATIVE      : flag = Flags.NATIVE; break;
3509             case VOLATILE    : flag = Flags.VOLATILE; break;
3510             case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
3511             case STRICTFP    : flag = Flags.STRICTFP; break;
3512             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
3513             case DEFAULT     : flag = Flags.DEFAULT; break;
3514             case ERROR       : flag = 0; nextToken(); break;
3515             case IDENTIFIER  : {
3516                 if (isNonSealedClassStart(false)) {
3517                     flag = Flags.NON_SEALED;
3518                     nextToken();
3519                     nextToken();
3520                     break;
3521                 }
3522                 if (isSealedClassStart(false)) {
3523                     checkSourceLevel(Feature.SEALED_CLASSES);
3524                     flag = Flags.SEALED;
3525                     break;
3526                 }
3527                 if (isValueModifier()) {
3528                     checkSourceLevel(Feature.VALUE_CLASSES);
3529                     flag = Flags.VALUE_CLASS;
3530                     break;
3531                 }
3532                 break loop;
3533             }
3534             default: break loop;
3535             }
3536             if ((flags & flag) != 0) log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier);
3537             lastPos = token.pos;
3538             nextToken();
3539             if (flag == Flags.ANNOTATION) {
3540                 if (token.kind != INTERFACE) {
3541                     JCAnnotation ann = annotation(lastPos, Tag.ANNOTATION);
3542                     // if first modifier is an annotation, set pos to annotation's.
3543                     if (flags == 0 && annotations.isEmpty())
3544                         pos = ann.pos;
3545                     annotations.append(ann);
3546                     flag = 0;
3547                 }
3548             }
3549             flags |= flag;
3550         }
3551         switch (token.kind) {

3778             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3779                 return Source.JDK10;
3780             } else if (shouldWarn) {
3781                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
3782             }
3783         }
3784         if (name == names.yield) {
3785             if (allowYieldStatement) {
3786                 return Source.JDK14;
3787             } else if (shouldWarn) {
3788                 log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
3789             }
3790         }
3791         if (name == names.record) {
3792             if (allowRecords) {
3793                 return Source.JDK14;
3794             } else if (shouldWarn) {
3795                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
3796             }
3797         }
3798         if (name == names.value) {
3799             if (allowValueClasses) {
3800                 return Source.JDK22;
3801             } else if (shouldWarn) {
3802                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK22));
3803             }
3804         }
3805         if (name == names.sealed) {
3806             if (allowSealedTypes) {
3807                 return Source.JDK15;
3808             } else if (shouldWarn) {
3809                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3810             }
3811         }
3812         if (name == names.permits) {
3813             if (allowSealedTypes) {
3814                 return Source.JDK15;
3815             } else if (shouldWarn) {
3816                 log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK15));
3817             }
3818         }
3819         return null;
3820     }
3821 
3822     /** VariableDeclaratorId = Ident BracketsOpt
3823      */
3824     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean catchParameter, boolean lambdaParameter, boolean recordComponent) {

4852             Token next = S.token(3);
4853             return allowedAfterSealedOrNonSealed(next, local, true);
4854         }
4855         return false;
4856     }
4857 
4858     protected boolean isNonSealedIdentifier(Token someToken, int lookAheadOffset) {
4859         if (someToken.name() == names.non && peekToken(lookAheadOffset, TokenKind.SUB, TokenKind.IDENTIFIER)) {
4860             Token tokenSub = S.token(lookAheadOffset + 1);
4861             Token tokenSealed = S.token(lookAheadOffset + 2);
4862             if (someToken.endPos == tokenSub.pos &&
4863                     tokenSub.endPos == tokenSealed.pos &&
4864                     tokenSealed.name() == names.sealed) {
4865                 checkSourceLevel(Feature.SEALED_CLASSES);
4866                 return true;
4867             }
4868         }
4869         return false;
4870     }
4871 
4872     protected boolean isValueModifier() {
4873         if (token.kind == IDENTIFIER && token.name() == names.value) {
4874             boolean isValueModifier = false;
4875             Token next = S.token(1);
4876             switch (next.kind) {
4877                 case PRIVATE: case PROTECTED: case PUBLIC: case STATIC: case TRANSIENT:
4878                 case FINAL: case ABSTRACT: case NATIVE: case VOLATILE: case SYNCHRONIZED:
4879                 case STRICTFP: case MONKEYS_AT: case DEFAULT: case BYTE: case SHORT:
4880                 case CHAR: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
4881                 case CLASS: case INTERFACE: case ENUM:
4882                     isValueModifier = true;
4883                     break;
4884                 case IDENTIFIER: // value record R || value value || new value Comparable() {} ??
4885                     if (next.name() == names.record || next.name() == names.value
4886                             || (mode & EXPR) != 0)
4887                         isValueModifier = true;
4888                     break;
4889             }
4890             if (isValueModifier) {
4891                 checkSourceLevel(Feature.VALUE_CLASSES);
4892                 return true;
4893             }
4894         }
4895         return false;
4896     }
4897 
4898     protected boolean isSealedClassStart(boolean local) {
4899         if (token.name() == names.sealed) {
4900             Token next = S.token(1);
4901             if (allowedAfterSealedOrNonSealed(next, local, false)) {
4902                 checkSourceLevel(Feature.SEALED_CLASSES);
4903                 return true;
4904             }
4905         }
4906         return false;
4907     }
4908 
4909     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
4910         return local ?
4911             switch (next.kind) {
4912                 case MONKEYS_AT -> {
4913                     Token afterNext = S.token(2);
4914                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4915                 }
4916                 case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4917                 default -> false;
4918             } :
4919             switch (next.kind) {
4920                 case MONKEYS_AT -> {
4921                     Token afterNext = S.token(2);
4922                     yield afterNext.kind != INTERFACE || currentIsNonSealed;
4923                 }
4924                 case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
4925                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) ||
4926                         next.name() == names.sealed ||
4927                         allowValueClasses && next.name() == names.value;
4928                 default -> false;
4929             };
4930     }
4931 
4932     /** MethodDeclaratorRest =
4933      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4934      *  VoidMethodDeclaratorRest =
4935      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4936      *  ConstructorDeclaratorRest =
4937      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4938      */
4939     protected JCTree methodDeclaratorRest(int pos,
4940                               JCModifiers mods,
4941                               JCExpression type,
4942                               Name name,
4943                               List<JCTypeParameter> typarams,
4944                               boolean isInterface, boolean isVoid,
4945                               boolean isRecord,
4946                               Comment dc) {
4947         if (isInterface) {
< prev index next >