@@ -3362,16 +3362,6 @@ object Parsers {
33623362 Template (constr, parents, Nil , EmptyValDef , Nil )
33633363 }
33643364
3365- /** Check that `vparamss` represents a legal collective parameter list for a given extension
3366- */
3367- def checkExtensionParams (start : Offset , vparamss : List [List [ValDef ]]): Unit = vparamss match
3368- case (vparam :: Nil ) :: vparamss1 if ! vparam.mods.is(Given ) =>
3369- vparamss1.foreach(_.foreach(vparam =>
3370- if ! vparam.mods.is(Given ) then
3371- syntaxError(em " follow-on parameter in extension clause must be `given` " , vparam.span)))
3372- case _ =>
3373- syntaxError(em " extension clause must start with a single regular parameter " , start)
3374-
33753365 def checkExtensionMethod (tparams : List [Tree ], stat : Tree ): Unit = stat match {
33763366 case stat : DefDef =>
33773367 if stat.mods.is(Extension ) then
@@ -3385,22 +3375,23 @@ object Parsers {
33853375
33863376 /** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
33873377 * | [GivenSig ‘:’] ConstrApps [[‘with’] TemplateBody]
3388- * | [id ‘:’] ‘extension’ ExtParamClause {GivenParamClause} ExtMethods
3378+ * | [id ‘:’] ExtParamClause {GivenParamClause} ‘extended’ ‘with’ ExtMethods
33893379 * GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
3390- * ExtParamClause ::= [DefTypeParamClause] DefParamClause {GivenParamClause}
3380+ * ExtParamClause ::= [DefTypeParamClause] DefParamClause
33913381 * ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
33923382 */
33933383 def givenDef (start : Offset , mods : Modifiers , instanceMod : Mod ) = atSpan(start, nameStart) {
33943384 var mods1 = addMod(mods, instanceMod)
33953385 val hasGivenSig = followingIsGivenSig()
3396- val (name, isExtension) =
3386+ val nameStart = in.offset
3387+ val (name, isOldExtension) =
33973388 if isIdent && hasGivenSig then
33983389 (ident(), in.token == COLON && in.lookaheadIn(nme.extension))
33993390 else
34003391 (EmptyTermName , isIdent(nme.extension))
34013392
34023393 val gdef = in.endMarkerScope(if name.isEmpty then GIVEN else name) {
3403- if isExtension then
3394+ if isOldExtension then
34043395 if (in.token == COLON ) in.nextToken()
34053396 assert(ident() == nme.extension)
34063397 val tparams = typeParamClauseOpt(ParamOwner .Def )
@@ -3412,65 +3403,61 @@ object Parsers {
34123403 templ.body.foreach(checkExtensionMethod(tparams, _))
34133404 ModuleDef (name, templ)
34143405 else
3415- var tparams : List [TypeDef ] = Nil
3416- var vparamss : List [List [ValDef ]] = Nil
3417- var hasExtensionParams = false
3418-
3419- def parseParams (isExtension : Boolean ): Unit =
3420- if isExtension && (in.token == LBRACKET || in.token == LPAREN ) then
3421- hasExtensionParams = true
3422- if tparams.nonEmpty || vparamss.nonEmpty then
3423- syntaxError(i " cannot have parameters before and after `:` in extension " )
3424- if in.token == LBRACKET then
3425- tparams = typeParamClause(ParamOwner .Def )
3426- if in.token == LPAREN && followingIsParamOrGivenType() then
3427- val paramsStart = in.offset
3428- vparamss = paramClauses(givenOnly = ! isExtension)
3429- if isExtension then
3430- checkExtensionParams(paramsStart, vparamss)
3431-
3432- parseParams(isExtension = false )
3433- val parents =
3434- if in.token == COLON then
3435- in.nextToken()
3436- if in.token == LBRACKET
3437- || in.token == LPAREN && followingIsParamOrGivenType()
3438- then
3439- parseParams(isExtension = true )
3440- Nil
3441- else
3442- constrApps(commaOK = true , templateCanFollow = true )
3443- else if in.token == SUBTYPE then
3444- if ! mods.is(Inline ) then
3445- syntaxError(" `<:' is only allowed for given with `inline' modifier" )
3446- in.nextToken()
3447- TypeBoundsTree (EmptyTree , toplevelTyp()) :: Nil
3448- else if name.isEmpty && ! hasExtensionParams then
3449- constrApps(commaOK = true , templateCanFollow = true )
3406+ val hasLabel = ! name.isEmpty && in.token == COLON
3407+ if hasLabel then in.nextToken()
3408+ val tparams = typeParamClauseOpt(ParamOwner .Def )
3409+ val paramsStart = in.offset
3410+ val vparamss =
3411+ if in.token == LPAREN && followingIsParamOrGivenType()
3412+ then paramClauses()
34503413 else Nil
3451-
3452- if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3414+ val isExtension = isIdent(nme.extended)
3415+ def checkAllGivens (vparamss : List [List [ValDef ]], what : String ) =
3416+ vparamss.foreach(_.foreach(vparam =>
3417+ if ! vparam.mods.is(Given ) then syntaxError(em " $what must be `given` " , vparam.span)))
3418+ if isExtension then
3419+ if ! name.isEmpty && ! hasLabel then
3420+ syntaxError(em " name $name of extension clause must be followed by `:` " , nameStart)
3421+ vparamss match
3422+ case (vparam :: Nil ) :: vparamss1 if ! vparam.mods.is(Given ) =>
3423+ checkAllGivens(vparamss1, " follow-on parameter in extension clause" )
3424+ case _ =>
3425+ syntaxError(" extension clause must start with a single regular parameter" , paramsStart)
34533426 in.nextToken()
3454- mods1 |= Final
3455- DefDef (name, tparams, vparamss, parents.head, subExpr())
3427+ accept(WITH )
3428+ val (self, stats) = templateBody()
3429+ stats.foreach(checkExtensionMethod(tparams, _))
3430+ ModuleDef (name, Template (makeConstructor(tparams, vparamss), Nil , Nil , self, stats))
34563431 else
3457- parents match
3458- case TypeBoundsTree (_, _) :: _ => syntaxError(" `=' expected" )
3459- case _ =>
3460- possibleTemplateStart()
3461- if hasExtensionParams then
3462- in.observeIndented()
3432+ checkAllGivens(vparamss, " parameter of given instance" )
3433+ val parents =
3434+ if hasLabel then
3435+ constrApps(commaOK = true , templateCanFollow = true )
3436+ else if in.token == SUBTYPE then
3437+ if ! mods.is(Inline ) then
3438+ syntaxError(" `<:' is only allowed for given with `inline' modifier" )
3439+ in.nextToken()
3440+ TypeBoundsTree (EmptyTree , toplevelTyp()) :: Nil
3441+ else
3442+ if ! (name.isEmpty && tparams.isEmpty && vparamss.isEmpty) then
3443+ accept(COLON )
3444+ constrApps(commaOK = true , templateCanFollow = true )
3445+ if in.token == EQUALS && parents.length == 1 && parents.head.isType then
3446+ in.nextToken()
3447+ mods1 |= Final
3448+ DefDef (name, tparams, vparamss, parents.head, subExpr())
34633449 else
3464- tparams = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal ))
3465- vparamss = vparamss.map(_.map(vparam =>
3450+ parents match
3451+ case TypeBoundsTree (_, _) :: _ => syntaxError(" `=' expected" )
3452+ case _ =>
3453+ possibleTemplateStart()
3454+ val tparams1 = tparams.map(tparam => tparam.withMods(tparam.mods | PrivateLocal ))
3455+ val vparamss1 = vparamss.map(_.map(vparam =>
34663456 vparam.withMods(vparam.mods &~ Param | ParamAccessor | PrivateLocal )))
3467- val templ = templateBodyOpt(makeConstructor(tparams, vparamss), parents, Nil )
3468- if hasExtensionParams then
3469- templ.body.foreach(checkExtensionMethod(tparams, _))
3470- ModuleDef (name, templ)
3471- else if tparams.isEmpty && vparamss.isEmpty then ModuleDef (name, templ)
3472- else TypeDef (name.toTypeName, templ)
3473- }
3457+ val templ = templateBodyOpt(makeConstructor(tparams1, vparamss1), parents, Nil )
3458+ if tparams.isEmpty && vparamss.isEmpty then ModuleDef (name, templ)
3459+ else TypeDef (name.toTypeName, templ)
3460+ }
34743461 finalizeDef(gdef, mods1, start)
34753462 }
34763463
@@ -3547,8 +3534,8 @@ object Parsers {
35473534 checkNextNotIndented()
35483535 Template (constr, Nil , Nil , EmptyValDef , Nil )
35493536
3550- /** TemplateBody ::= [nl | `with' ] `{' TemplateStatSeq `}'
3551- * EnumBody ::= [nl | ‘with’ ] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’
3537+ /** TemplateBody ::= [nl] `{' TemplateStatSeq `}'
3538+ * EnumBody ::= [nl] ‘{’ [SelfType] EnumStat {semi EnumStat} ‘}’
35523539 */
35533540 def templateBodyOpt (constr : DefDef , parents : List [Tree ], derived : List [Tree ]): Template =
35543541 val (self, stats) =
0 commit comments