< prev index next >

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

Print this page




  84 
  85     /** The scanner used for lexical analysis.
  86      */
  87     protected Lexer S;
  88 
  89     /** The factory to be used for abstract syntax tree construction.
  90      */
  91     protected TreeMaker F;
  92 
  93     /** The log to be used for error diagnostics.
  94      */
  95     private Log log;
  96 
  97     /** The Source language setting. */
  98     private Source source;
  99 
 100     /** The Preview language setting. */
 101     private Preview preview;
 102 
 103     /** The name table. */
 104     private Names names;
 105 
 106     /** End position mappings container */
 107     protected final AbstractEndPosTable endPosTable;
 108 
 109     // Because of javac's limited lookahead, some contexts are ambiguous in
 110     // the presence of type annotations even though they are not ambiguous
 111     // in the absence of type annotations.  Consider this code:
 112     //   void m(String [] m) { }
 113     //   void m(String ... m) { }
 114     // After parsing "String", javac calls bracketsOpt which immediately
 115     // returns if the next character is not '['.  Similarly, javac can see
 116     // if the next token is ... and in that case parse an ellipsis.  But in
 117     // the presence of type annotations:
 118     //   void m(String @A [] m) { }
 119     //   void m(String @A ... m) { }
 120     // no finite lookahead is enough to determine whether to read array
 121     // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
 122     // bracketsOpt first reads all the leading annotations and only then
 123     // discovers that it needs to fail.  bracketsOpt needs a way to push
 124     // back the extra annotations that it read.  (But, bracketsOpt should


2356 
2357             if (elems != null) {
2358                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2359             }
2360 
2361             return na;
2362         }
2363     }
2364 
2365     /** ClassCreatorRest = Arguments [ClassBody]
2366      */
2367     JCNewClass classCreatorRest(int newpos,
2368                                   JCExpression encl,
2369                                   List<JCExpression> typeArgs,
2370                                   JCExpression t)
2371     {
2372         List<JCExpression> args = arguments();
2373         JCClassDecl body = null;
2374         if (token.kind == LBRACE) {
2375             int pos = token.pos;
2376             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
2377             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2378             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2379         }
2380         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2381     }
2382 
2383     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2384      */
2385     JCExpression arrayInitializer(int newpos, JCExpression t) {
2386         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2387         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2388     }
2389 
2390     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2391         accept(LBRACE);
2392         ListBuffer<JCExpression> elems = new ListBuffer<>();
2393         if (token.kind == COMMA) {
2394             nextToken();
2395         } else if (token.kind != RBRACE) {
2396             elems.append(variableInitializer());


2490             case CLASSDEF:
2491                 error = Errors.ClassNotAllowed;
2492                 break;
2493             case VARDEF:
2494                 error = Errors.VariableNotAllowed;
2495                 break;
2496             }
2497             if (error != null) {
2498                 log.error(DiagnosticFlag.SYNTAX, first, error);
2499                 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2500                 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2501             }
2502             return first;
2503         }
2504     }
2505 
2506     /**This method parses a statement appearing inside a block.
2507      */
2508     List<JCStatement> blockStatement() {
2509         //todo: skip to anchor on error(?)

2510         int pos = token.pos;
2511         switch (token.kind) {
2512         case RBRACE: case CASE: case DEFAULT: case EOF:
2513             return List.nil();
2514         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2515         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2516         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2517         case ASSERT:
2518             return List.of(parseSimpleStatement());
2519         case MONKEYS_AT:
2520         case FINAL: {
2521             Comment dc = token.comment(CommentStyle.JAVADOC);
2522             JCModifiers mods = modifiersOpt();
2523             if (token.kind == INTERFACE ||
2524                 token.kind == CLASS ||
2525                 token.kind == ENUM) {
2526                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2527             } else {
2528                 JCExpression t = parseType(true);
2529                 return localVariableDeclarations(mods, t);
2530             }
2531         }
2532         case ABSTRACT: case STRICTFP: {
2533             Comment dc = token.comment(CommentStyle.JAVADOC);
2534             JCModifiers mods = modifiersOpt();
2535             return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
2536         }
2537         case INTERFACE:
2538         case CLASS:
2539             Comment dc = token.comment(CommentStyle.JAVADOC);
2540             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2541         case ENUM:
2542             log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
2543             dc = token.comment(CommentStyle.JAVADOC);
2544             return List.of(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2545         default:





2546             Token prevToken = token;
2547             JCExpression t = term(EXPR | TYPE);
2548             if (token.kind == COLON && t.hasTag(IDENT)) {
2549                 nextToken();
2550                 JCStatement stat = parseStatementAsBlock();
2551                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2552             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2553                 pos = token.pos;
2554                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2555                 F.at(pos);
2556                 return localVariableDeclarations(mods, t);
2557             } else {
2558                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2559                 t = checkExprStat(t);
2560                 accept(SEMI);
2561                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
2562                 return List.of(expr);
2563             }
2564         }
2565     }


3208             case IDENT:
3209                 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos, shouldWarn);
3210             case TYPEARRAY:
3211                 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
3212             default:
3213                 return false;
3214         }
3215     }
3216 
3217     boolean isRestrictedLocalVarTypeName(Name name, int pos, boolean shouldWarn) {
3218         if (name == names.var) {
3219             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3220                 return true;
3221             } else if (shouldWarn) {
3222                 log.warning(pos, Warnings.VarNotAllowed);
3223             }
3224         }
3225         return false;
3226     }
3227 




3228     /** VariableDeclaratorId = Ident BracketsOpt
3229      */
3230     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3231         return variableDeclaratorId(mods, type, false);
3232     }
3233     //where
3234     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3235         int pos = token.pos;
3236         Name name;
3237         if (lambdaParameter && token.kind == UNDERSCORE) {
3238             log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3239             name = token.name();
3240             nextToken();
3241         } else {
3242             if (allowThisIdent ||
3243                 !lambdaParameter ||
3244                 LAX_IDENTIFIER.accepts(token.kind) ||
3245                 mods.flags != Flags.PARAMETER ||
3246                 mods.annotations.nonEmpty()) {
3247                 JCExpression pn = qualident(false);


3529                 pid = to(F.at(pos1).Select(pid, names.asterisk));
3530                 nextToken();
3531                 break;
3532             } else {
3533                 pid = toP(F.at(pos1).Select(pid, ident()));
3534             }
3535         } while (token.kind == DOT);
3536         accept(SEMI);
3537         return toP(F.at(pos).Import(pid, importStatic));
3538     }
3539 
3540     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3541      *                  | ";"
3542      */
3543     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3544         int pos = token.pos;
3545         if (mods == null && token.kind == SEMI) {
3546             nextToken();
3547             return toP(F.at(pos).Skip());
3548         } else {
3549             return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3550         }
3551     }
3552 
3553     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3554      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3555      *  @param mods     Any modifiers starting the class or interface declaration
3556      *  @param dc       The documentation comment for the class, or null.
3557      */
3558     protected JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3559         if (token.kind == CLASS) {
3560             return classDeclaration(mods, dc);


3561         } else if (token.kind == INTERFACE) {
3562             return interfaceDeclaration(mods, dc);
3563         } else if (token.kind == ENUM) {
3564             return enumDeclaration(mods, dc);
3565         } else {
3566             int pos = token.pos;
3567             List<JCTree> errs;
3568             if (LAX_IDENTIFIER.accepts(token.kind)) {
3569                 errs = List.of(mods, toP(F.at(pos).Ident(ident())));
3570                 setErrorEndPos(token.pos);
3571             } else {
3572                 errs = List.of(mods);
3573             }
3574             final JCErroneous erroneousTree;
3575             if (parseModuleInfo) {
3576                 erroneousTree = syntaxError(pos, errs, Errors.ExpectedModuleOrOpen);
3577             } else {
3578                 erroneousTree = syntaxError(pos, errs, Errors.Expected3(CLASS, INTERFACE, ENUM));
3579             }
3580             return toP(F.Exec(erroneousTree));
3581         }
3582     }
3583 
3584     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3585      *                     [IMPLEMENTS TypeList] ClassBody
3586      *  @param mods    The modifiers starting the class declaration
3587      *  @param dc       The documentation comment for the class, or null.
3588      */
3589     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3590         int pos = token.pos;
3591         accept(CLASS);
3592         Name name = typeName();
3593 
3594         List<JCTypeParameter> typarams = typeParametersOpt();
3595 
3596         JCExpression extending = null;
3597         if (token.kind == EXTENDS) {
3598             nextToken();
3599             extending = parseType();
3600         }
3601         List<JCExpression> implementing = List.nil();
3602         if (token.kind == IMPLEMENTS) {
3603             nextToken();
3604             implementing = typeList();
3605         }
3606         List<JCTree> defs = classOrInterfaceBody(name, false);
3607         JCClassDecl result = toP(F.at(pos).ClassDef(
3608             mods, name, typarams, extending, implementing, defs));
3609         attach(result, dc);
3610         return result;
3611     }
3612 
















































3613     Name typeName() {
3614         int pos = token.pos;
3615         Name name = ident();
3616         if (isRestrictedLocalVarTypeName(name, pos, true)) {
3617             reportSyntaxError(pos, Errors.VarNotAllowed);
3618         }




3619         return name;
3620     }
3621 



























3622     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3623      *                         [EXTENDS TypeList] InterfaceBody
3624      *  @param mods    The modifiers starting the interface declaration
3625      *  @param dc       The documentation comment for the interface, or null.
3626      */
3627     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3628         int pos = token.pos;
3629         accept(INTERFACE);
3630 
3631         Name name = typeName();
3632 
3633         List<JCTypeParameter> typarams = typeParametersOpt();
3634 
3635         List<JCExpression> extending = List.nil();
3636         if (token.kind == EXTENDS) {
3637             nextToken();
3638             extending = typeList();
3639         }
3640         List<JCTree> defs = classOrInterfaceBody(name, true);






3641         JCClassDecl result = toP(F.at(pos).ClassDef(
3642             mods, name, typarams, null, extending, defs));
3643         attach(result, dc);
3644         return result;
3645     }
3646 
3647     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3648      *  @param mods    The modifiers starting the enum declaration
3649      *  @param dc       The documentation comment for the enum, or null.
3650      */
3651     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3652         int pos = token.pos;
3653         accept(ENUM);
3654 
3655         Name name = typeName();
3656 
3657         List<JCExpression> implementing = List.nil();
3658         if (token.kind == IMPLEMENTS) {
3659             nextToken();
3660             implementing = typeList();


3707     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3708      */
3709     JCTree enumeratorDeclaration(Name enumName) {
3710         Comment dc = token.comment(CommentStyle.JAVADOC);
3711         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3712         if (token.deprecatedFlag()) {
3713             flags |= Flags.DEPRECATED;
3714         }
3715         int pos = token.pos;
3716         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3717         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3718         List<JCExpression> typeArgs = typeArgumentsOpt();
3719         int identPos = token.pos;
3720         Name name = ident();
3721         int createPos = token.pos;
3722         List<JCExpression> args = (token.kind == LPAREN)
3723             ? arguments() : List.nil();
3724         JCClassDecl body = null;
3725         if (token.kind == LBRACE) {
3726             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3727             List<JCTree> defs = classOrInterfaceBody(names.empty, false);
3728             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3729         }
3730         if (args.isEmpty() && body == null)
3731             createPos = identPos;
3732         JCIdent ident = F.at(identPos).Ident(enumName);
3733         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3734         if (createPos != identPos)
3735             storeEnd(create, S.prevToken().endPos);
3736         ident = F.at(identPos).Ident(enumName);
3737         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3738         attach(result, dc);
3739         return result;
3740     }
3741 
3742     /** TypeList = Type {"," Type}
3743      */
3744     List<JCExpression> typeList() {
3745         ListBuffer<JCExpression> ts = new ListBuffer<>();
3746         ts.append(parseType());
3747         while (token.kind == COMMA) {
3748             nextToken();
3749             ts.append(parseType());
3750         }
3751         return ts.toList();
3752     }
3753 
3754     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3755      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3756      */
3757     List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) {
3758         accept(LBRACE);
3759         if (token.pos <= endPosTable.errorEndPos) {
3760             // error recovery
3761             skip(false, true, false, false);
3762             if (token.kind == LBRACE)
3763                 nextToken();
3764         }
3765         ListBuffer<JCTree> defs = new ListBuffer<>();
3766         while (token.kind != RBRACE && token.kind != EOF) {
3767             defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));




3768             if (token.pos <= endPosTable.errorEndPos) {
3769                // error recovery
3770                skip(false, true, true, false);
3771            }
3772         }
3773         accept(RBRACE);
3774         return defs.toList();
3775     }
3776 
3777     /** ClassBodyDeclaration =
3778      *      ";"
3779      *    | [STATIC] Block
3780      *    | ModifiersOpt
3781      *      ( Type Ident
3782      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3783      *      | VOID Ident VoidMethodDeclaratorRest
3784      *      | TypeParameters [Annotations]
3785      *        ( Type Ident MethodDeclaratorRest
3786      *        | VOID Ident VoidMethodDeclaratorRest
3787      *        )


3795      *      ( Type Ident
3796      *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3797      *      | VOID Ident MethodDeclaratorRest
3798      *      | TypeParameters [Annotations]
3799      *        ( Type Ident MethodDeclaratorRest
3800      *        | VOID Ident VoidMethodDeclaratorRest
3801      *        )
3802      *      | ClassOrInterfaceOrEnumDeclaration
3803      *      )
3804      *
3805      */
3806     protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3807         if (token.kind == SEMI) {
3808             nextToken();
3809             return List.nil();
3810         } else {
3811             Comment dc = token.comment(CommentStyle.JAVADOC);
3812             int pos = token.pos;
3813             JCModifiers mods = modifiersOpt();
3814             if (token.kind == CLASS ||

3815                 token.kind == INTERFACE ||
3816                 token.kind == ENUM) {
3817                 return List.of(classOrInterfaceOrEnumDeclaration(mods, dc));
3818             } else if (token.kind == LBRACE &&
3819                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3820                        mods.annotations.isEmpty()) {
3821                 if (isInterface) {
3822                     log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.InitializerNotAllowed);
3823                 }
3824                 return List.of(block(pos, mods.flags));
3825             } else {
3826                 pos = token.pos;
3827                 List<JCTypeParameter> typarams = typeParametersOpt();
3828                 // if there are type parameters but no modifiers, save the start
3829                 // position of the method in the modifiers.
3830                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3831                     mods.pos = pos;
3832                     storeEnd(mods, pos);
3833                 }
3834                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3835 
3836                 if (annosAfterParams.nonEmpty()) {
3837                     checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);


3841                 }
3842 
3843                 Token tk = token;
3844                 pos = token.pos;
3845                 JCExpression type;
3846                 boolean isVoid = token.kind == VOID;
3847                 if (isVoid) {
3848                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3849                     nextToken();
3850                 } else {
3851                     // method returns types are un-annotated types
3852                     type = unannotatedType(false);
3853                 }
3854                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3855                     if (isInterface || tk.name() != className)
3856                         log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidMethDeclRetTypeReq);
3857                     else if (annosAfterParams.nonEmpty())
3858                         illegal(annosAfterParams.head.pos);
3859                     return List.of(methodDeclaratorRest(
3860                         pos, mods, null, names.init, typarams,
3861                         isInterface, true, dc));
3862                 } else {
3863                     pos = token.pos;
3864                     Name name = ident();
3865                     if (token.kind == LPAREN) {
3866                         return List.of(methodDeclaratorRest(
3867                             pos, mods, type, name, typarams,
3868                             isInterface, isVoid, dc));
3869                     } else if (!isVoid && typarams.isEmpty()) {
3870                         List<JCTree> defs =
3871                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3872                                                     new ListBuffer<JCTree>(), false).toList();
3873                         accept(SEMI);
3874                         storeEnd(defs.last(), S.prevToken().endPos);
3875                         return defs;
3876                     } else {
3877                         pos = token.pos;
3878                         List<JCTree> err;
3879                         if (isVoid || typarams.nonEmpty()) {
3880                             JCMethodDecl m =
3881                                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
3882                                                             List.nil(), List.nil(), null, null));
3883                             attach(m, dc);
3884                             err = List.of(m);
3885                         } else {
3886                             err = List.nil();
3887                         }
3888                         return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
3889                     }
3890                 }
3891             }
3892         }
3893     }
3894 

















































































3895     /** MethodDeclaratorRest =
3896      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
3897      *  VoidMethodDeclaratorRest =
3898      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
3899      *  ConstructorDeclaratorRest =
3900      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
3901      */
3902     protected JCTree methodDeclaratorRest(int pos,
3903                               JCModifiers mods,
3904                               JCExpression type,
3905                               Name name,
3906                               List<JCTypeParameter> typarams,
3907                               boolean isInterface, boolean isVoid,

3908                               Comment dc) {
3909         if (isInterface) {
3910             if ((mods.flags & Flags.STATIC) != 0) {
3911                 checkSourceLevel(Feature.STATIC_INTERFACE_METHODS);
3912             }
3913             if ((mods.flags & Flags.PRIVATE) != 0) {
3914                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
3915             }
3916         }
3917         JCVariableDecl prevReceiverParam = this.receiverParam;
3918         try {
3919             this.receiverParam = null;
3920             // Parsing formalParameters sets the receiverParam, if present
3921             List<JCVariableDecl> params = formalParameters();
3922             if (!isVoid) type = bracketsOpt(type);
3923             List<JCExpression> thrown = List.nil();
3924             if (token.kind == THROWS) {
3925                 nextToken();
3926                 thrown = qualidentList(true);




3927             }
3928             JCBlock body = null;
3929             JCExpression defaultValue;
3930             if (token.kind == LBRACE) {
3931                 body = block();
3932                 defaultValue = null;
3933             } else {
3934                 if (token.kind == DEFAULT) {
3935                     accept(DEFAULT);
3936                     defaultValue = annotationValue();
3937                 } else {
3938                     defaultValue = null;
3939                 }
3940                 accept(SEMI);
3941                 if (token.pos <= endPosTable.errorEndPos) {
3942                     // error recovery
3943                     skip(false, true, false, false);
3944                     if (token.kind == LBRACE) {
3945                         body = block();
3946                     }
3947                 }
3948             }
3949 
3950             JCMethodDecl result =
3951                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
3952                                             receiverParam, params, thrown,
3953                                             body, defaultValue));
3954             attach(result, dc);
3955             return result;
3956         } finally {
3957             this.receiverParam = prevReceiverParam;
3958         }
3959     }
3960 
3961     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
3962      */
3963     List<JCExpression> qualidentList(boolean allowAnnos) {
3964         ListBuffer<JCExpression> ts = new ListBuffer<>();
3965 
3966         List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
3967         JCExpression qi = qualident(allowAnnos);
3968         if (!typeAnnos.isEmpty()) {
3969             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);




  84 
  85     /** The scanner used for lexical analysis.
  86      */
  87     protected Lexer S;
  88 
  89     /** The factory to be used for abstract syntax tree construction.
  90      */
  91     protected TreeMaker F;
  92 
  93     /** The log to be used for error diagnostics.
  94      */
  95     private Log log;
  96 
  97     /** The Source language setting. */
  98     private Source source;
  99 
 100     /** The Preview language setting. */
 101     private Preview preview;
 102 
 103     /** The name table. */
 104     protected Names names;
 105 
 106     /** End position mappings container */
 107     protected final AbstractEndPosTable endPosTable;
 108 
 109     // Because of javac's limited lookahead, some contexts are ambiguous in
 110     // the presence of type annotations even though they are not ambiguous
 111     // in the absence of type annotations.  Consider this code:
 112     //   void m(String [] m) { }
 113     //   void m(String ... m) { }
 114     // After parsing "String", javac calls bracketsOpt which immediately
 115     // returns if the next character is not '['.  Similarly, javac can see
 116     // if the next token is ... and in that case parse an ellipsis.  But in
 117     // the presence of type annotations:
 118     //   void m(String @A [] m) { }
 119     //   void m(String @A ... m) { }
 120     // no finite lookahead is enough to determine whether to read array
 121     // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
 122     // bracketsOpt first reads all the leading annotations and only then
 123     // discovers that it needs to fail.  bracketsOpt needs a way to push
 124     // back the extra annotations that it read.  (But, bracketsOpt should


2356 
2357             if (elems != null) {
2358                 return syntaxError(errpos, List.of(na), Errors.IllegalArrayCreationBothDimensionAndInitialization);
2359             }
2360 
2361             return na;
2362         }
2363     }
2364 
2365     /** ClassCreatorRest = Arguments [ClassBody]
2366      */
2367     JCNewClass classCreatorRest(int newpos,
2368                                   JCExpression encl,
2369                                   List<JCExpression> typeArgs,
2370                                   JCExpression t)
2371     {
2372         List<JCExpression> args = arguments();
2373         JCClassDecl body = null;
2374         if (token.kind == LBRACE) {
2375             int pos = token.pos;
2376             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
2377             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2378             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
2379         }
2380         return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
2381     }
2382 
2383     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
2384      */
2385     JCExpression arrayInitializer(int newpos, JCExpression t) {
2386         List<JCExpression> elems = arrayInitializerElements(newpos, t);
2387         return toP(F.at(newpos).NewArray(t, List.nil(), elems));
2388     }
2389 
2390     List<JCExpression> arrayInitializerElements(int newpos, JCExpression t) {
2391         accept(LBRACE);
2392         ListBuffer<JCExpression> elems = new ListBuffer<>();
2393         if (token.kind == COMMA) {
2394             nextToken();
2395         } else if (token.kind != RBRACE) {
2396             elems.append(variableInitializer());


2490             case CLASSDEF:
2491                 error = Errors.ClassNotAllowed;
2492                 break;
2493             case VARDEF:
2494                 error = Errors.VariableNotAllowed;
2495                 break;
2496             }
2497             if (error != null) {
2498                 log.error(DiagnosticFlag.SYNTAX, first, error);
2499                 List<JCBlock> blist = List.of(F.at(first.pos).Block(0, stats));
2500                 return toP(F.at(pos).Exec(F.at(first.pos).Erroneous(blist)));
2501             }
2502             return first;
2503         }
2504     }
2505 
2506     /**This method parses a statement appearing inside a block.
2507      */
2508     List<JCStatement> blockStatement() {
2509         //todo: skip to anchor on error(?)
2510         Comment dc;
2511         int pos = token.pos;
2512         switch (token.kind) {
2513         case RBRACE: case CASE: case DEFAULT: case EOF:
2514             return List.nil();
2515         case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY:
2516         case SWITCH: case SYNCHRONIZED: case RETURN: case THROW: case BREAK:
2517         case CONTINUE: case SEMI: case ELSE: case FINALLY: case CATCH:
2518         case ASSERT:
2519             return List.of(parseSimpleStatement());
2520         case MONKEYS_AT:
2521         case FINAL: {
2522             dc = token.comment(CommentStyle.JAVADOC);
2523             JCModifiers mods = modifiersOpt();
2524             if (token.kind == INTERFACE ||
2525                 token.kind == CLASS ||
2526                 token.kind == ENUM) {
2527                 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
2528             } else {
2529                 JCExpression t = parseType(true);
2530                 return localVariableDeclarations(mods, t);
2531             }
2532         }
2533         case ABSTRACT: case STRICTFP: {
2534             dc = token.comment(CommentStyle.JAVADOC);
2535             JCModifiers mods = modifiersOpt();
2536             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
2537         }
2538         case INTERFACE:
2539         case CLASS:
2540             dc = token.comment(CommentStyle.JAVADOC);
2541             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2542         case ENUM:
2543             log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.LocalEnum);
2544             dc = token.comment(CommentStyle.JAVADOC);
2545             return List.of(classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(), dc));
2546         }
2547         if (isRecordDeclaration()) {
2548             JCModifiers mods = modifiersOpt();
2549             dc = token.comment(CommentStyle.JAVADOC);
2550             return List.of(recordDeclaration(mods, dc));
2551         } else {
2552             Token prevToken = token;
2553             JCExpression t = term(EXPR | TYPE);
2554             if (token.kind == COLON && t.hasTag(IDENT)) {
2555                 nextToken();
2556                 JCStatement stat = parseStatementAsBlock();
2557                 return List.of(F.at(pos).Labelled(prevToken.name(), stat));
2558             } else if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
2559                 pos = token.pos;
2560                 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
2561                 F.at(pos);
2562                 return localVariableDeclarations(mods, t);
2563             } else {
2564                 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon
2565                 t = checkExprStat(t);
2566                 accept(SEMI);
2567                 JCExpressionStatement expr = toP(F.at(pos).Exec(t));
2568                 return List.of(expr);
2569             }
2570         }
2571     }


3214             case IDENT:
3215                 return isRestrictedLocalVarTypeName(((JCIdent)e).name, e.pos, shouldWarn);
3216             case TYPEARRAY:
3217                 return isRestrictedLocalVarTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
3218             default:
3219                 return false;
3220         }
3221     }
3222 
3223     boolean isRestrictedLocalVarTypeName(Name name, int pos, boolean shouldWarn) {
3224         if (name == names.var) {
3225             if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
3226                 return true;
3227             } else if (shouldWarn) {
3228                 log.warning(pos, Warnings.VarNotAllowed);
3229             }
3230         }
3231         return false;
3232     }
3233 
3234     boolean isRestrictedRecordTypeName(Name name) {
3235         return Feature.RECORDS.allowedInSource(source) && name == names.record;
3236     }
3237 
3238     /** VariableDeclaratorId = Ident BracketsOpt
3239      */
3240     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
3241         return variableDeclaratorId(mods, type, false);
3242     }
3243     //where
3244     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter) {
3245         int pos = token.pos;
3246         Name name;
3247         if (lambdaParameter && token.kind == UNDERSCORE) {
3248             log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
3249             name = token.name();
3250             nextToken();
3251         } else {
3252             if (allowThisIdent ||
3253                 !lambdaParameter ||
3254                 LAX_IDENTIFIER.accepts(token.kind) ||
3255                 mods.flags != Flags.PARAMETER ||
3256                 mods.annotations.nonEmpty()) {
3257                 JCExpression pn = qualident(false);


3539                 pid = to(F.at(pos1).Select(pid, names.asterisk));
3540                 nextToken();
3541                 break;
3542             } else {
3543                 pid = toP(F.at(pos1).Select(pid, ident()));
3544             }
3545         } while (token.kind == DOT);
3546         accept(SEMI);
3547         return toP(F.at(pos).Import(pid, importStatic));
3548     }
3549 
3550     /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration
3551      *                  | ";"
3552      */
3553     JCTree typeDeclaration(JCModifiers mods, Comment docComment) {
3554         int pos = token.pos;
3555         if (mods == null && token.kind == SEMI) {
3556             nextToken();
3557             return toP(F.at(pos).Skip());
3558         } else {
3559             return classOrRecordOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment);
3560         }
3561     }
3562 
3563     /** ClassOrInterfaceOrEnumDeclaration = ModifiersOpt
3564      *           (ClassDeclaration | InterfaceDeclaration | EnumDeclaration)
3565      *  @param mods     Any modifiers starting the class or interface declaration
3566      *  @param dc       The documentation comment for the class, or null.
3567      */
3568     protected JCStatement classOrRecordOrInterfaceOrEnumDeclaration(JCModifiers mods, Comment dc) {
3569         if (token.kind == CLASS) {
3570             return classDeclaration(mods, dc);
3571         } if (isRecordDeclaration()) {
3572             return recordDeclaration(mods, dc);
3573         } else if (token.kind == INTERFACE) {
3574             return interfaceDeclaration(mods, dc);
3575         } else if (token.kind == ENUM) {
3576             return enumDeclaration(mods, dc);
3577         } else {
3578             int pos = token.pos;
3579             List<JCTree> errs;
3580             if (LAX_IDENTIFIER.accepts(token.kind)) {
3581                 errs = List.of(mods, toP(F.at(pos).Ident(ident())));
3582                 setErrorEndPos(token.pos);
3583             } else {
3584                 errs = List.of(mods);
3585             }
3586             final JCErroneous erroneousTree;
3587             if (parseModuleInfo) {
3588                 erroneousTree = syntaxError(pos, errs, Errors.ExpectedModuleOrOpen);
3589             } else {
3590                 erroneousTree = syntaxError(pos, errs, Errors.Expected4(CLASS, INTERFACE, ENUM, RECORD));
3591             }
3592             return toP(F.Exec(erroneousTree));
3593         }
3594     }
3595 
3596     /** ClassDeclaration = CLASS Ident TypeParametersOpt [EXTENDS Type]
3597      *                     [IMPLEMENTS TypeList] ClassBody
3598      *  @param mods    The modifiers starting the class declaration
3599      *  @param dc       The documentation comment for the class, or null.
3600      */
3601     protected JCClassDecl classDeclaration(JCModifiers mods, Comment dc) {
3602         int pos = token.pos;
3603         accept(CLASS);
3604         Name name = typeName();
3605 
3606         List<JCTypeParameter> typarams = typeParametersOpt();
3607 
3608         JCExpression extending = null;
3609         if (token.kind == EXTENDS) {
3610             nextToken();
3611             extending = parseType();
3612         }
3613         List<JCExpression> implementing = List.nil();
3614         if (token.kind == IMPLEMENTS) {
3615             nextToken();
3616             implementing = typeList();
3617         }
3618         List<JCTree> defs = classInterfaceOrRecordBody(name, false, false);
3619         JCClassDecl result = toP(F.at(pos).ClassDef(
3620             mods, name, typarams, extending, implementing, defs));
3621         attach(result, dc);
3622         return result;
3623     }
3624 
3625     protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
3626         int pos = token.pos;
3627         if ((mods.flags & Flags.ABSTRACT) != 0) {
3628             log.error(mods.pos, Errors.RecordCantBeAbstract);
3629         }
3630         nextToken();
3631         mods.flags |= Flags.RECORD | Flags.STATIC | Flags.FINAL;
3632         Name name = typeName();
3633 
3634         List<JCTypeParameter> typarams = typeParametersOpt();
3635 
3636         Map<Name, JCVariableDecl> optHeaderFields = headerFields(mods);
3637 
3638         List<JCExpression> implementing = List.nil();
3639         if (token.kind == IMPLEMENTS) {
3640             nextToken();
3641             implementing = typeList();
3642         }
3643         List<JCTree> defs = List.nil();
3644         if (token.kind == LBRACE) {
3645             defs = classInterfaceOrRecordBody(name, false, true);
3646         } else {
3647             accept(SEMI);
3648         }
3649         java.util.List<JCVariableDecl> fields = new ArrayList<>();
3650         for (JCVariableDecl field : optHeaderFields.values()) {
3651             fields.add(field);
3652         }
3653         for (JCTree def : defs) {
3654             if (def.hasTag(METHODDEF)) {
3655                 JCMethodDecl methDef = (JCMethodDecl) def;
3656                 if (methDef.name == names.init && methDef.params.isEmpty()) {
3657                     ListBuffer<JCVariableDecl> tmpParams = new ListBuffer<>();
3658                     for (JCVariableDecl param : fields) {
3659                         tmpParams.add(F.at(param).VarDef(F.Modifiers(Flags.PARAMETER), param.name, param.vartype, null));
3660                     }
3661                     methDef.params = tmpParams.toList();
3662                 }
3663             }
3664         }
3665         for (int i = fields.size() - 1; i >= 0; i--) {
3666             defs = defs.prepend(fields.get(i));
3667         }
3668         JCClassDecl result = toP(F.at(pos).ClassDef(mods, name, typarams, null, implementing, defs));
3669         attach(result, dc);
3670         return result;
3671     }
3672 
3673     Name typeName() {
3674         int pos = token.pos;
3675         Name name = ident();
3676         if (isRestrictedLocalVarTypeName(name, pos, true)) {
3677             reportSyntaxError(pos, Errors.VarNotAllowed);
3678         }
3679 
3680         if (isRestrictedRecordTypeName(name)) {
3681             reportSyntaxError(pos, Errors.RecordNotAllowed(name));
3682         }
3683         return name;
3684     }
3685 
3686     Map<Name, JCVariableDecl> headerFields(JCModifiers recordClassMods) {
3687         accept(LPAREN);
3688         Map<Name, JCVariableDecl> fields = new LinkedHashMap<>();
3689         while (token.kind != RPAREN) {
3690             JCModifiers mods = modifiersOpt();
3691             if (mods.flags != 0) {
3692                 log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
3693             }
3694             mods.flags |= Flags.RECORD | Flags.FINAL;
3695             mods.flags |= (recordClassMods.flags & Flags.ABSTRACT) != 0 ? Flags.PROTECTED : 0;
3696             JCExpression type = parseType();
3697             int pos = token.pos;
3698             Name id = ident();
3699             if (!fields.containsKey(id)) {
3700                 List<Pair<Accessors.Kind, Name>> accessors = List.of(new Pair<>(Accessors.Kind.GET, id));
3701                 fields.put(id, toP(F.at(pos).VarDef(mods, id, type, null, accessors)));
3702             } else {
3703                 log.error(pos, Errors.RecordCantDeclareDuplicateFields);
3704             }
3705             if (token.kind == COMMA) {
3706                 nextToken();
3707             }
3708         }
3709         accept(RPAREN);
3710         return fields;
3711     }
3712 
3713     /** InterfaceDeclaration = INTERFACE Ident TypeParametersOpt
3714      *                         [EXTENDS TypeList] InterfaceBody
3715      *  @param mods    The modifiers starting the interface declaration
3716      *  @param dc       The documentation comment for the interface, or null.
3717      */
3718     protected JCClassDecl interfaceDeclaration(JCModifiers mods, Comment dc) {
3719         int pos = token.pos;
3720         accept(INTERFACE);
3721 
3722         Name name = typeName();
3723 
3724         List<JCTypeParameter> typarams = typeParametersOpt();
3725 
3726         List<JCExpression> extending = List.nil();
3727         if (token.kind == EXTENDS) {
3728             nextToken();
3729             extending = typeList();
3730         }
3731         List<JCTree> defs;
3732         if (token.kind == LBRACE) {
3733             defs = classInterfaceOrRecordBody(name, true, false);
3734         } else {
3735             accept(SEMI);
3736             defs = List.nil();
3737         }
3738         JCClassDecl result = toP(F.at(pos).ClassDef(
3739             mods, name, typarams, null, extending, defs));
3740         attach(result, dc);
3741         return result;
3742     }
3743 
3744     /** EnumDeclaration = ENUM Ident [IMPLEMENTS TypeList] EnumBody
3745      *  @param mods    The modifiers starting the enum declaration
3746      *  @param dc       The documentation comment for the enum, or null.
3747      */
3748     protected JCClassDecl enumDeclaration(JCModifiers mods, Comment dc) {
3749         int pos = token.pos;
3750         accept(ENUM);
3751 
3752         Name name = typeName();
3753 
3754         List<JCExpression> implementing = List.nil();
3755         if (token.kind == IMPLEMENTS) {
3756             nextToken();
3757             implementing = typeList();


3804     /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ]
3805      */
3806     JCTree enumeratorDeclaration(Name enumName) {
3807         Comment dc = token.comment(CommentStyle.JAVADOC);
3808         int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM;
3809         if (token.deprecatedFlag()) {
3810             flags |= Flags.DEPRECATED;
3811         }
3812         int pos = token.pos;
3813         List<JCAnnotation> annotations = annotationsOpt(Tag.ANNOTATION);
3814         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
3815         List<JCExpression> typeArgs = typeArgumentsOpt();
3816         int identPos = token.pos;
3817         Name name = ident();
3818         int createPos = token.pos;
3819         List<JCExpression> args = (token.kind == LPAREN)
3820             ? arguments() : List.nil();
3821         JCClassDecl body = null;
3822         if (token.kind == LBRACE) {
3823             JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM);
3824             List<JCTree> defs = classInterfaceOrRecordBody(names.empty, false, false);
3825             body = toP(F.at(identPos).AnonymousClassDef(mods1, defs));
3826         }
3827         if (args.isEmpty() && body == null)
3828             createPos = identPos;
3829         JCIdent ident = F.at(identPos).Ident(enumName);
3830         JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body);
3831         if (createPos != identPos)
3832             storeEnd(create, S.prevToken().endPos);
3833         ident = F.at(identPos).Ident(enumName);
3834         JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create));
3835         attach(result, dc);
3836         return result;
3837     }
3838 
3839     /** TypeList = Type {"," Type}
3840      */
3841     List<JCExpression> typeList() {
3842         ListBuffer<JCExpression> ts = new ListBuffer<>();
3843         ts.append(parseType());
3844         while (token.kind == COMMA) {
3845             nextToken();
3846             ts.append(parseType());
3847         }
3848         return ts.toList();
3849     }
3850 
3851     /** ClassBody     = "{" {ClassBodyDeclaration} "}"
3852      *  InterfaceBody = "{" {InterfaceBodyDeclaration} "}"
3853      */
3854     List<JCTree> classInterfaceOrRecordBody(Name className, boolean isInterface, boolean isRecord) {
3855         accept(LBRACE);
3856         if (token.pos <= endPosTable.errorEndPos) {
3857             // error recovery
3858             skip(false, true, false, false);
3859             if (token.kind == LBRACE)
3860                 nextToken();
3861         }
3862         ListBuffer<JCTree> defs = new ListBuffer<>();
3863         while (token.kind != RBRACE && token.kind != EOF) {
3864             if (!isRecord) {
3865                 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface));
3866             } else {
3867                 defs.appendList(recordBodyDeclaration(className));
3868             }
3869             if (token.pos <= endPosTable.errorEndPos) {
3870                // error recovery
3871                skip(false, true, true, false);
3872            }
3873         }
3874         accept(RBRACE);
3875         return defs.toList();
3876     }
3877 
3878     /** ClassBodyDeclaration =
3879      *      ";"
3880      *    | [STATIC] Block
3881      *    | ModifiersOpt
3882      *      ( Type Ident
3883      *        ( VariableDeclaratorsRest ";" | MethodDeclaratorRest )
3884      *      | VOID Ident VoidMethodDeclaratorRest
3885      *      | TypeParameters [Annotations]
3886      *        ( Type Ident MethodDeclaratorRest
3887      *        | VOID Ident VoidMethodDeclaratorRest
3888      *        )


3896      *      ( Type Ident
3897      *        ( ConstantDeclaratorsRest ";" | MethodDeclaratorRest )
3898      *      | VOID Ident MethodDeclaratorRest
3899      *      | TypeParameters [Annotations]
3900      *        ( Type Ident MethodDeclaratorRest
3901      *        | VOID Ident VoidMethodDeclaratorRest
3902      *        )
3903      *      | ClassOrInterfaceOrEnumDeclaration
3904      *      )
3905      *
3906      */
3907     protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
3908         if (token.kind == SEMI) {
3909             nextToken();
3910             return List.nil();
3911         } else {
3912             Comment dc = token.comment(CommentStyle.JAVADOC);
3913             int pos = token.pos;
3914             JCModifiers mods = modifiersOpt();
3915             if (token.kind == CLASS ||
3916                 isRecordDeclaration() ||
3917                 token.kind == INTERFACE ||
3918                 token.kind == ENUM) {
3919                 return List.of(classOrRecordOrInterfaceOrEnumDeclaration(mods, dc));
3920             } else if (token.kind == LBRACE &&
3921                        (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 &&
3922                        mods.annotations.isEmpty()) {
3923                 if (isInterface) {
3924                     log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.InitializerNotAllowed);
3925                 }
3926                 return List.of(block(pos, mods.flags));
3927             } else {
3928                 pos = token.pos;
3929                 List<JCTypeParameter> typarams = typeParametersOpt();
3930                 // if there are type parameters but no modifiers, save the start
3931                 // position of the method in the modifiers.
3932                 if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
3933                     mods.pos = pos;
3934                     storeEnd(mods, pos);
3935                 }
3936                 List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
3937 
3938                 if (annosAfterParams.nonEmpty()) {
3939                     checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);


3943                 }
3944 
3945                 Token tk = token;
3946                 pos = token.pos;
3947                 JCExpression type;
3948                 boolean isVoid = token.kind == VOID;
3949                 if (isVoid) {
3950                     type = to(F.at(pos).TypeIdent(TypeTag.VOID));
3951                     nextToken();
3952                 } else {
3953                     // method returns types are un-annotated types
3954                     type = unannotatedType(false);
3955                 }
3956                 if (token.kind == LPAREN && !isInterface && type.hasTag(IDENT)) {
3957                     if (isInterface || tk.name() != className)
3958                         log.error(DiagnosticFlag.SYNTAX, pos, Errors.InvalidMethDeclRetTypeReq);
3959                     else if (annosAfterParams.nonEmpty())
3960                         illegal(annosAfterParams.head.pos);
3961                     return List.of(methodDeclaratorRest(
3962                         pos, mods, null, names.init, typarams,
3963                         isInterface, true, false, dc));
3964                 } else {
3965                     pos = token.pos;
3966                     Name name = ident();
3967                     if (token.kind == LPAREN) {
3968                         return List.of(methodDeclaratorRest(
3969                             pos, mods, type, name, typarams,
3970                             isInterface, isVoid, false, dc));
3971                     } else if (!isVoid && typarams.isEmpty()) {
3972                         List<JCTree> defs =
3973                             variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
3974                                                     new ListBuffer<JCTree>(), false).toList();
3975                         accept(SEMI);
3976                         storeEnd(defs.last(), S.prevToken().endPos);
3977                         return defs;
3978                     } else {
3979                         pos = token.pos;
3980                         List<JCTree> err;
3981                         if (isVoid || typarams.nonEmpty()) {
3982                             JCMethodDecl m =
3983                                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
3984                                                             List.nil(), List.nil(), null, null));
3985                             attach(m, dc);
3986                             err = List.of(m);
3987                         } else {
3988                             err = List.nil();
3989                         }
3990                         return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
3991                     }
3992                 }
3993             }
3994         }
3995     }
3996 
3997     boolean isRecordDeclaration() {
3998         return token.kind == IDENTIFIER && token.name() == names.record &&
3999                 (peekToken(TokenKind.IDENTIFIER, TokenKind.LPAREN) ||
4000                 peekToken(TokenKind.IDENTIFIER, TokenKind.LT));
4001     }
4002 
4003     protected List<JCTree> recordBodyDeclaration(Name className) {
4004         Comment dc = token.comment(CommentStyle.JAVADOC);
4005         JCModifiers mods = modifiersOpt();
4006         return methodOrFieldMemberDecl(className, mods, false, dc);
4007     }
4008 
4009     private List<JCTree> methodOrFieldMemberDecl(Name className, JCModifiers mods, boolean isInterface, Comment dc) {
4010         int pos = token.pos;
4011         List<JCTypeParameter> typarams = typeParametersOpt();
4012         // if there are type parameters but no modifiers, save the start
4013         // position of the method in the modifiers.
4014         if (typarams.nonEmpty() && mods.pos == Position.NOPOS) {
4015             mods.pos = pos;
4016             storeEnd(mods, pos);
4017         }
4018         List<JCAnnotation> annosAfterParams = annotationsOpt(Tag.ANNOTATION);
4019 
4020         if (annosAfterParams.nonEmpty()) {
4021             checkSourceLevel(annosAfterParams.head.pos, Feature.ANNOTATIONS_AFTER_TYPE_PARAMS);
4022             mods.annotations = mods.annotations.appendList(annosAfterParams);
4023             if (mods.pos == Position.NOPOS)
4024                 mods.pos = mods.annotations.head.pos;
4025         }
4026 
4027         Token tk = token;
4028         pos = token.pos;
4029         JCExpression type;
4030         boolean isVoid = token.kind == VOID;
4031         if (isVoid) {
4032             type = to(F.at(pos).TypeIdent(TypeTag.VOID));
4033             nextToken();
4034         } else {
4035             // method returns types are un-annotated types
4036             type = unannotatedType(false);
4037         }
4038         if ((token.kind == LPAREN && !isInterface ||
4039                 token.kind == LBRACE) && type.hasTag(IDENT)) {
4040             if (isInterface || tk.name() != className)
4041                 log.error(pos, Errors.InvalidMethDeclRetTypeReq);
4042             else if (annosAfterParams.nonEmpty())
4043                 illegal(annosAfterParams.head.pos);
4044             return List.of(methodDeclaratorRest(
4045                 pos, mods, null, names.init, typarams,
4046                 isInterface, true, true, dc));
4047         } else {
4048             pos = token.pos;
4049             Name name = ident();
4050             if (token.kind == LPAREN) {
4051                 return List.of(methodDeclaratorRest(
4052                     pos, mods, type, name, typarams,
4053                     isInterface, isVoid, true, dc));
4054             } else if (!isVoid && typarams.isEmpty()) {
4055                 if ((mods.flags & Flags.STATIC) != 0) {
4056                     List<JCTree> defs =
4057                         variableDeclaratorsRest(pos, mods, type, name, isInterface, dc,
4058                                                 new ListBuffer<JCTree>(), false).toList();
4059                     accept(SEMI);
4060                     storeEnd(defs.last(), S.prevToken().endPos);
4061                     return defs;
4062                 } else {
4063                     log.error(pos, Errors.RecordFieldsMustBeInHeader);
4064                     int tmpPos = token.pos;
4065                     nextToken();
4066                     return List.of(syntaxError(tmpPos, null, Errors.Expected(LPAREN)));
4067                 }
4068             } else {
4069                 pos = token.pos;
4070                 List<JCTree> err = isVoid
4071                     ? List.of(toP(F.at(pos).MethodDef(mods, name, type, typarams,
4072                         List.nil(), List.nil(), null, null)))
4073                     : null;
4074                 return List.of(syntaxError(token.pos, err, Errors.Expected(LPAREN)));
4075             }
4076         }
4077     }
4078     /** MethodDeclaratorRest =
4079      *      FormalParameters BracketsOpt [THROWS TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
4080      *  VoidMethodDeclaratorRest =
4081      *      FormalParameters [THROWS TypeList] ( MethodBody | ";")
4082      *  ConstructorDeclaratorRest =
4083      *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
4084      */
4085     protected JCTree methodDeclaratorRest(int pos,
4086                               JCModifiers mods,
4087                               JCExpression type,
4088                               Name name,
4089                               List<JCTypeParameter> typarams,
4090                               boolean isInterface, boolean isVoid,
4091                               boolean isRecord,
4092                               Comment dc) {
4093         if (isInterface) {
4094             if ((mods.flags & Flags.STATIC) != 0) {
4095                 checkSourceLevel(Feature.STATIC_INTERFACE_METHODS);
4096             }
4097             if ((mods.flags & Flags.PRIVATE) != 0) {
4098                 checkSourceLevel(Feature.PRIVATE_INTERFACE_METHODS);
4099             }
4100         }
4101         JCVariableDecl prevReceiverParam = this.receiverParam;
4102         try {
4103             this.receiverParam = null;
4104             // Parsing formalParameters sets the receiverParam, if present
4105             List<JCVariableDecl> params = List.nil();

4106             List<JCExpression> thrown = List.nil();
4107             if (!isRecord || name != names.init || token.kind == LPAREN) {
4108                 params = formalParameters();
4109                 if (!isVoid) type = bracketsOpt(type);
4110                 if (token.kind == THROWS) {
4111                     nextToken();
4112                     thrown = qualidentList(true);
4113                 }
4114             }
4115             JCBlock body = null;
4116             JCExpression defaultValue;
4117             if (token.kind == LBRACE) {
4118                 body = block();
4119                 defaultValue = null;
4120             } else {
4121                 if (token.kind == DEFAULT) {
4122                     accept(DEFAULT);
4123                     defaultValue = annotationValue();
4124                 } else {
4125                     defaultValue = null;
4126                 }
4127                 accept(SEMI);
4128                 if (token.pos <= endPosTable.errorEndPos) {
4129                     // error recovery
4130                     skip(false, true, false, false);
4131                     if (token.kind == LBRACE) {
4132                         body = block();
4133                     }
4134                 }
4135             }

4136             JCMethodDecl result =
4137                     toP(F.at(pos).MethodDef(mods, name, type, typarams,
4138                                             receiverParam, params, thrown,
4139                                             body, defaultValue));
4140             attach(result, dc);
4141             return result;
4142         } finally {
4143             this.receiverParam = prevReceiverParam;
4144         }
4145     }
4146 
4147     /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
4148      */
4149     List<JCExpression> qualidentList(boolean allowAnnos) {
4150         ListBuffer<JCExpression> ts = new ListBuffer<>();
4151 
4152         List<JCAnnotation> typeAnnos = allowAnnos ? typeAnnotationsOpt() : List.nil();
4153         JCExpression qi = qualident(allowAnnos);
4154         if (!typeAnnos.isEmpty()) {
4155             JCExpression at = insertAnnotationsToMostInner(qi, typeAnnos, false);


< prev index next >