@@ -51,7 +51,23 @@ object Parsers {
51
51
case ElseWhere extends Location (false , false , false )
52
52
53
53
enum ParamOwner :
54
- case Class , Type , TypeParam , Def
54
+ case Class // class or trait or enum
55
+ case CaseClass // case class or enum case
56
+ case Type // type alias or abstract type
57
+ case TypeParam // type parameter
58
+ case Def // method
59
+ case Given // given definition
60
+ case ExtensionPrefix // extension clause, up to and including extension parameter
61
+ case ExtensionFollow // extension clause, following extension parameter
62
+
63
+ def isClass = // owner is a class
64
+ this == Class || this == CaseClass
65
+ def takesOnlyUsingClauses = // only using clauses allowed for this owner
66
+ this == Given || this == ExtensionFollow
67
+ def acceptsVariance =
68
+ this == Class || this == CaseClass || this == Type
69
+
70
+ end ParamOwner
55
71
56
72
enum ParseKind :
57
73
case Expr , Type , Pattern
@@ -3169,33 +3185,29 @@ object Parsers {
3169
3185
* | UsingParamClause
3170
3186
*/
3171
3187
def typeOrTermParamClauses (
3172
- ownerKind : ParamOwner ,
3173
- numLeadParams : Int = 0
3174
- ): List [List [TypeDef ] | List [ValDef ]] =
3188
+ paramOwner : ParamOwner , numLeadParams : Int = 0 ): List [List [TypeDef ] | List [ValDef ]] =
3175
3189
3176
- def recur (firstClause : Boolean , numLeadParams : Int , prevIsTypeClause : Boolean ): List [List [TypeDef ] | List [ValDef ]] =
3190
+ def recur (numLeadParams : Int , firstClause : Boolean , prevIsTypeClause : Boolean ): List [List [TypeDef ] | List [ValDef ]] =
3177
3191
newLineOptWhenFollowedBy(LPAREN )
3178
3192
newLineOptWhenFollowedBy(LBRACKET )
3179
3193
if in.token == LPAREN then
3180
3194
val paramsStart = in.offset
3181
- val params = termParamClause(
3182
- numLeadParams,
3183
- firstClause = firstClause)
3195
+ val params = termParamClause(paramOwner, numLeadParams, firstClause)
3184
3196
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
3185
3197
params :: (
3186
3198
if lastClause then Nil
3187
- else recur(firstClause = false , numLeadParams + params.length, prevIsTypeClause = false ))
3199
+ else recur(numLeadParams + params.length, firstClause = false , prevIsTypeClause = false ))
3188
3200
else if in.token == LBRACKET then
3189
3201
if prevIsTypeClause then
3190
3202
syntaxError(
3191
3203
em " Type parameter lists must be separated by a term or using parameter list " ,
3192
3204
in.offset
3193
3205
)
3194
- typeParamClause(ownerKind ) :: recur(firstClause, numLeadParams , prevIsTypeClause = true )
3206
+ typeParamClause(paramOwner ) :: recur(numLeadParams, firstClause , prevIsTypeClause = true )
3195
3207
else Nil
3196
3208
end recur
3197
3209
3198
- recur(firstClause = true , numLeadParams = numLeadParams , prevIsTypeClause = false )
3210
+ recur(numLeadParams, firstClause = true , prevIsTypeClause = false )
3199
3211
end typeOrTermParamClauses
3200
3212
3201
3213
@@ -3214,21 +3226,22 @@ object Parsers {
3214
3226
* HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
3215
3227
* HkTypeParam ::= {Annotation} [‘+’ | ‘-’] (id [HkTypePamClause] | ‘_’) TypeBounds
3216
3228
*/
3217
- def typeParamClause (ownerKind : ParamOwner ): List [TypeDef ] = inBracketsWithCommas {
3229
+ def typeParamClause (paramOwner : ParamOwner ): List [TypeDef ] = inBracketsWithCommas {
3218
3230
3219
3231
def checkVarianceOK (): Boolean =
3220
- val ok = ownerKind != ParamOwner . Def && ownerKind != ParamOwner . TypeParam
3232
+ val ok = paramOwner.acceptsVariance
3221
3233
if ! ok then syntaxError(em " no `+/-` variance annotation allowed here " )
3222
3234
in.nextToken()
3223
3235
ok
3224
3236
3225
3237
def typeParam (): TypeDef = {
3226
- val isAbstractOwner = ownerKind == ParamOwner .Type || ownerKind == ParamOwner .TypeParam
3238
+ val isAbstractOwner = paramOwner == ParamOwner .Type || paramOwner == ParamOwner .TypeParam
3227
3239
val start = in.offset
3228
3240
var mods = annotsAsMods() | Param
3229
- if ownerKind == ParamOwner .Class then mods |= PrivateLocal
3241
+ if paramOwner == ParamOwner .Class || paramOwner == ParamOwner .CaseClass then
3242
+ mods |= PrivateLocal
3230
3243
if Feature .ccEnabled && in.token == SEALED then
3231
- if ownerKind == ParamOwner .Def then mods |= Sealed
3244
+ if paramOwner == ParamOwner .Def then mods |= Sealed
3232
3245
else syntaxError(em " `sealed` modifier only allowed for method type parameters " )
3233
3246
in.nextToken()
3234
3247
if isIdent(nme.raw.PLUS ) && checkVarianceOK() then
@@ -3250,16 +3263,16 @@ object Parsers {
3250
3263
commaSeparated(() => typeParam())
3251
3264
}
3252
3265
3253
- def typeParamClauseOpt (ownerKind : ParamOwner ): List [TypeDef ] =
3254
- if (in.token == LBRACKET ) typeParamClause(ownerKind ) else Nil
3266
+ def typeParamClauseOpt (paramOwner : ParamOwner ): List [TypeDef ] =
3267
+ if (in.token == LBRACKET ) typeParamClause(paramOwner ) else Nil
3255
3268
3256
3269
/** ContextTypes ::= FunArgType {‘,’ FunArgType}
3257
3270
*/
3258
- def contextTypes (ofClass : Boolean , numLeadParams : Int , impliedMods : Modifiers ): List [ValDef ] =
3271
+ def contextTypes (paramOwner : ParamOwner , numLeadParams : Int , impliedMods : Modifiers ): List [ValDef ] =
3259
3272
val tps = commaSeparated(funArgType)
3260
3273
var counter = numLeadParams
3261
3274
def nextIdx = { counter += 1 ; counter }
3262
- val paramFlags = if ofClass then LocalParamAccessor else Param
3275
+ val paramFlags = if paramOwner.isClass then LocalParamAccessor else Param
3263
3276
tps.map(makeSyntheticParameter(nextIdx, _, paramFlags | Synthetic | impliedMods.flags))
3264
3277
3265
3278
/** ClsTermParamClause ::= ‘(’ ClsParams ‘)’ | UsingClsTermParamClause
@@ -3281,11 +3294,8 @@ object Parsers {
3281
3294
* @return the list of parameter definitions
3282
3295
*/
3283
3296
def termParamClause (
3297
+ paramOwner : ParamOwner ,
3284
3298
numLeadParams : Int , // number of parameters preceding this clause
3285
- ofClass : Boolean = false , // owner is a class
3286
- ofCaseClass : Boolean = false , // owner is a case class
3287
- prefix : Boolean = false , // clause precedes name of an extension method
3288
- givenOnly : Boolean = false , // only given parameters allowed
3289
3299
firstClause : Boolean = false // clause is the first in regular list of clauses
3290
3300
): List [ValDef ] = {
3291
3301
var impliedMods : Modifiers = EmptyModifiers
@@ -3304,7 +3314,7 @@ object Parsers {
3304
3314
var mods = impliedMods.withAnnotations(annotations())
3305
3315
if isErasedKw then
3306
3316
mods = addModifier(mods)
3307
- if (ofClass) {
3317
+ if paramOwner.isClass then
3308
3318
mods = addFlag(modifiers(start = mods), ParamAccessor )
3309
3319
mods =
3310
3320
if in.token == VAL then
@@ -3316,9 +3326,8 @@ object Parsers {
3316
3326
else
3317
3327
if (! (mods.flags &~ (ParamAccessor | Inline | Erased | impliedMods.flags)).isEmpty)
3318
3328
syntaxError(em " `val` or `var` expected " )
3319
- if ( firstClause && ofCaseClass) mods
3329
+ if firstClause && paramOwner == ParamOwner . CaseClass then mods
3320
3330
else mods | PrivateLocal
3321
- }
3322
3331
else {
3323
3332
if (isIdent(nme.inline) && in.isSoftModifierInParamModifierPosition)
3324
3333
mods = addModifier(mods)
@@ -3327,7 +3336,7 @@ object Parsers {
3327
3336
atSpan(start, nameStart) {
3328
3337
val name = ident()
3329
3338
acceptColon()
3330
- if (in.token == ARROW && ofClass && ! mods.is(Local ))
3339
+ if (in.token == ARROW && paramOwner.isClass && ! mods.is(Local ))
3331
3340
syntaxError(VarValParametersMayNotBeCallByName (name, mods.is(Mutable )))
3332
3341
// needed?, it's checked later anyway
3333
3342
val tpt = paramType()
@@ -3342,7 +3351,7 @@ object Parsers {
3342
3351
3343
3352
def checkVarArgsRules (vparams : List [ValDef ]): Unit = vparams match {
3344
3353
case Nil =>
3345
- case _ :: Nil if ! prefix =>
3354
+ case _ :: Nil if paramOwner != ParamOwner . ExtensionPrefix =>
3346
3355
case vparam :: rest =>
3347
3356
vparam.tpt match {
3348
3357
case PostfixOp (_, op) if op.name == tpnme.raw.STAR =>
@@ -3354,13 +3363,17 @@ object Parsers {
3354
3363
3355
3364
// begin termParamClause
3356
3365
inParensWithCommas {
3357
- if in.token == RPAREN && ! prefix && ! impliedMods.is(Given ) then Nil
3366
+ if in.token == RPAREN && paramOwner != ParamOwner .ExtensionPrefix && ! impliedMods.is(Given )
3367
+ then Nil
3358
3368
else
3359
3369
val clause =
3360
- if prefix && ! isIdent(nme.using) && ! isIdent(nme.erased) then param() :: Nil
3370
+ if paramOwner == ParamOwner .ExtensionPrefix
3371
+ && ! isIdent(nme.using) && ! isIdent(nme.erased)
3372
+ then
3373
+ param() :: Nil
3361
3374
else
3362
3375
paramMods()
3363
- if givenOnly && ! impliedMods.is(Given ) then
3376
+ if paramOwner.takesOnlyUsingClauses && ! impliedMods.is(Given ) then
3364
3377
syntaxError(em " `using` expected " )
3365
3378
val (firstParamMod, isParams) =
3366
3379
var mods = EmptyModifiers
@@ -3374,7 +3387,7 @@ object Parsers {
3374
3387
|| isIdent && (in.name == nme.inline || in.lookahead.isColon)
3375
3388
(mods, isParams)
3376
3389
(if isParams then commaSeparated(() => param())
3377
- else contextTypes(ofClass , numLeadParams, impliedMods)) match {
3390
+ else contextTypes(paramOwner , numLeadParams, impliedMods)) match {
3378
3391
case Nil => Nil
3379
3392
case (h :: t) => h.withAddedFlags(firstParamMod.flags) :: t
3380
3393
}
@@ -3388,31 +3401,21 @@ object Parsers {
3388
3401
*
3389
3402
* @return The parameter definitions
3390
3403
*/
3391
- def termParamClauses (
3392
- ofClass : Boolean = false ,
3393
- ofCaseClass : Boolean = false ,
3394
- givenOnly : Boolean = false ,
3395
- numLeadParams : Int = 0
3396
- ): List [List [ValDef ]] =
3404
+ def termParamClauses (paramOwner : ParamOwner , numLeadParams : Int = 0 ): List [List [ValDef ]] =
3397
3405
3398
- def recur (firstClause : Boolean , numLeadParams : Int ): List [List [ValDef ]] =
3406
+ def recur (numLeadParams : Int , firstClause : Boolean ): List [List [ValDef ]] =
3399
3407
newLineOptWhenFollowedBy(LPAREN )
3400
3408
if in.token == LPAREN then
3401
3409
val paramsStart = in.offset
3402
- val params = termParamClause(
3403
- numLeadParams,
3404
- ofClass = ofClass,
3405
- ofCaseClass = ofCaseClass,
3406
- givenOnly = givenOnly,
3407
- firstClause = firstClause)
3410
+ val params = termParamClause(paramOwner, numLeadParams, firstClause)
3408
3411
val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
3409
3412
params :: (
3410
3413
if lastClause then Nil
3411
- else recur(firstClause = false , numLeadParams + params.length))
3414
+ else recur(numLeadParams + params.length, firstClause = false ))
3412
3415
else Nil
3413
3416
end recur
3414
3417
3415
- recur(firstClause = true , numLeadParams )
3418
+ recur(numLeadParams, firstClause = true )
3416
3419
end termParamClauses
3417
3420
3418
3421
/* -------- DEFS ------------------------------------------- */
@@ -3679,7 +3682,7 @@ object Parsers {
3679
3682
3680
3683
if (in.token == THIS ) {
3681
3684
in.nextToken()
3682
- val vparamss = termParamClauses(numLeadParams = numLeadParams)
3685
+ val vparamss = termParamClauses(ParamOwner . Def , numLeadParams)
3683
3686
if (vparamss.isEmpty || vparamss.head.take(1 ).exists(_.mods.isOneOf(GivenOrImplicit )))
3684
3687
in.token match {
3685
3688
case LBRACKET => syntaxError(em " no type parameters allowed here " )
@@ -3700,10 +3703,10 @@ object Parsers {
3700
3703
val paramss =
3701
3704
if in.featureEnabled(Feature .clauseInterleaving) then
3702
3705
// If you are making interleaving stable manually, please refer to the PR introducing it instead, section "How to make non-experimental"
3703
- typeOrTermParamClauses(ParamOwner .Def , numLeadParams = numLeadParams )
3706
+ typeOrTermParamClauses(ParamOwner .Def , numLeadParams)
3704
3707
else
3705
3708
val tparams = typeParamClauseOpt(ParamOwner .Def )
3706
- val vparamss = termParamClauses(numLeadParams = numLeadParams)
3709
+ val vparamss = termParamClauses(ParamOwner . Def , numLeadParams)
3707
3710
3708
3711
joinParams(tparams, vparamss)
3709
3712
@@ -3842,16 +3845,16 @@ object Parsers {
3842
3845
}
3843
3846
3844
3847
def classDefRest (start : Offset , mods : Modifiers , name : TypeName ): TypeDef =
3845
- val constr = classConstr(isCaseClass = mods.is(Case ))
3848
+ val constr = classConstr(if mods.is(Case ) then ParamOwner . CaseClass else ParamOwner . Class )
3846
3849
val templ = templateOpt(constr)
3847
3850
finalizeDef(TypeDef (name, templ), mods, start)
3848
3851
3849
3852
/** ClassConstr ::= [ClsTypeParamClause] [ConstrMods] ClsTermParamClauses
3850
3853
*/
3851
- def classConstr (isCaseClass : Boolean = false ): DefDef = atSpan(in.lastOffset) {
3852
- val tparams = typeParamClauseOpt(ParamOwner . Class )
3854
+ def classConstr (paramOwner : ParamOwner ): DefDef = atSpan(in.lastOffset) {
3855
+ val tparams = typeParamClauseOpt(paramOwner )
3853
3856
val cmods = fromWithinClassConstr(constrModsOpt())
3854
- val vparamss = termParamClauses(ofClass = true , ofCaseClass = isCaseClass )
3857
+ val vparamss = termParamClauses(paramOwner )
3855
3858
makeConstructor(tparams, vparamss).withMods(cmods)
3856
3859
}
3857
3860
@@ -3880,7 +3883,7 @@ object Parsers {
3880
3883
val mods1 = checkAccessOnly(mods, " definitions" )
3881
3884
val modulName = ident()
3882
3885
val clsName = modulName.toTypeName
3883
- val constr = classConstr()
3886
+ val constr = classConstr(ParamOwner . Class )
3884
3887
val templ = template(constr, isEnum = true )
3885
3888
finalizeDef(TypeDef (clsName, templ), mods1, start)
3886
3889
}
@@ -3902,7 +3905,7 @@ object Parsers {
3902
3905
val caseDef =
3903
3906
if (in.token == LBRACKET || in.token == LPAREN || in.token == AT || isModifier) {
3904
3907
val clsName = id.name.toTypeName
3905
- val constr = classConstr(isCaseClass = true )
3908
+ val constr = classConstr(ParamOwner . CaseClass )
3906
3909
TypeDef (clsName, caseTemplate(constr))
3907
3910
}
3908
3911
else
@@ -3949,11 +3952,11 @@ object Parsers {
3949
3952
val name = if isIdent && followingIsGivenSig() then ident() else EmptyTermName
3950
3953
3951
3954
val gdef =
3952
- val tparams = typeParamClauseOpt(ParamOwner .Def )
3955
+ val tparams = typeParamClauseOpt(ParamOwner .Given )
3953
3956
newLineOpt()
3954
3957
val vparamss =
3955
3958
if in.token == LPAREN && in.lookahead.isIdent(nme.using)
3956
- then termParamClauses(givenOnly = true )
3959
+ then termParamClauses(ParamOwner . Given )
3957
3960
else Nil
3958
3961
newLinesOpt()
3959
3962
val noParams = tparams.isEmpty && vparamss.isEmpty
@@ -3993,15 +3996,15 @@ object Parsers {
3993
3996
*/
3994
3997
def extension (): ExtMethods =
3995
3998
val start = in.skipToken()
3996
- val tparams = typeParamClauseOpt(ParamOwner .Def )
3999
+ val tparams = typeParamClauseOpt(ParamOwner .ExtensionPrefix )
3997
4000
val leadParamss = ListBuffer [List [ValDef ]]()
3998
4001
def numLeadParams = leadParamss.map(_.length).sum
3999
4002
while
4000
- val extParams = termParamClause(numLeadParams, prefix = true )
4003
+ val extParams = termParamClause(ParamOwner . ExtensionPrefix , numLeadParams )
4001
4004
leadParamss += extParams
4002
4005
isUsingClause(extParams)
4003
4006
do ()
4004
- leadParamss ++= termParamClauses(givenOnly = true , numLeadParams = numLeadParams)
4007
+ leadParamss ++= termParamClauses(ParamOwner . ExtensionFollow , numLeadParams)
4005
4008
if in.isColon then
4006
4009
syntaxError(em " no `:` expected here " )
4007
4010
in.nextToken()
0 commit comments