@@ -2733,7 +2733,7 @@ object Parsers {
27332733 * DefTypeParamClause::= ‘[’ DefTypeParam {‘,’ DefTypeParam} ‘]’
27342734 * DefTypeParam ::= {Annotation} id [HkTypeParamClause] TypeParamBounds
27352735 *
2736- * TypTypeParamCaluse ::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’
2736+ * TypTypeParamClause ::= ‘[’ TypTypeParam {‘,’ TypTypeParam} ‘]’
27372737 * TypTypeParam ::= {Annotation} id [HkTypePamClause] TypeBounds
27382738 *
27392739 * HkTypeParamClause ::= ‘[’ HkTypeParam {‘,’ HkTypeParam} ‘]’
@@ -2799,6 +2799,7 @@ object Parsers {
27992799 ofClass : Boolean = false , // owner is a class
28002800 ofCaseClass : Boolean = false , // owner is a case class
28012801 prefix : Boolean = false , // clause precedes name of an extension method
2802+ givenOnly : Boolean = false , // only given parameters allowed
28022803 firstClause : Boolean = false // clause is the first in regular list of clauses
28032804 ): List [ValDef ] = {
28042805 var impliedMods : Modifiers = EmptyModifiers
@@ -2870,6 +2871,8 @@ object Parsers {
28702871 if ! impliedModOpt(IMPLICIT , () => Mod .Implicit ()) then
28712872 impliedModOpt(GIVEN , () => Mod .Given ())
28722873 impliedModOpt(ERASED , () => Mod .Erased ())
2874+ if givenOnly && ! impliedMods.is(Given ) then
2875+ syntaxError(ExpectedTokenButFound (GIVEN , in.token))
28732876 val isParams =
28742877 ! impliedMods.is(Given )
28752878 || startParamTokens.contains(in.token)
@@ -2890,7 +2893,7 @@ object Parsers {
28902893 */
28912894 def paramClauses (ofClass : Boolean = false ,
28922895 ofCaseClass : Boolean = false ,
2893- ofInstance : Boolean = false ): List [List [ValDef ]] =
2896+ givenOnly : Boolean = false ): List [List [ValDef ]] =
28942897
28952898 def recur (firstClause : Boolean , nparams : Int ): List [List [ValDef ]] =
28962899 newLineOptWhenFollowedBy(LPAREN )
@@ -2900,6 +2903,7 @@ object Parsers {
29002903 nparams,
29012904 ofClass = ofClass,
29022905 ofCaseClass = ofCaseClass,
2906+ givenOnly = givenOnly,
29032907 firstClause = firstClause)
29042908 val lastClause = params.nonEmpty && params.head.mods.flags.is(Implicit )
29052909 params :: (
@@ -3394,58 +3398,74 @@ object Parsers {
33943398
33953399 /** GivenDef ::= [GivenSig (‘:’ | <:)] Type ‘=’ Expr
33963400 * | [GivenSig ‘:’] [ConstrApp {‘,’ ConstrApp }] [TemplateBody]
3397- * | [id ‘:’] ExtParamClause ExtMethods
3401+ * | [id ‘:’] ‘extension’ ExtParamClause {GivenParamClause} ExtMethods
33983402 * GivenSig ::= [id] [DefTypeParamClause] {GivenParamClause}
33993403 * ExtParamClause ::= [DefTypeParamClause] DefParamClause {GivenParamClause}
34003404 * ExtMethods ::= [nl] ‘{’ ‘def’ DefDef {semi ‘def’ DefDef} ‘}’
34013405 */
34023406 def givenDef (start : Offset , mods : Modifiers , instanceMod : Mod ) = atSpan(start, nameStart) {
34033407 var mods1 = addMod(mods, instanceMod)
34043408 val hasGivenSig = followingIsGivenSig()
3405- val name = if isIdent && hasGivenSig then ident() else EmptyTermName
3406- indentRegion(name) {
3407- var tparams : List [TypeDef ] = Nil
3408- var vparamss : List [List [ValDef ]] = Nil
3409- var hasExtensionParams = false
3410-
3411- def parseParams (isExtension : Boolean ): Unit =
3412- if isExtension && (in.token == LBRACKET || in.token == LPAREN ) then
3413- hasExtensionParams = true
3414- if tparams.nonEmpty || vparamss.nonEmpty then
3415- syntaxError(i " cannot have parameters before and after `:` in extension " )
3416- if in.token == LBRACKET then
3417- tparams = typeParamClause(ParamOwner .Def )
3418- if in.token == LPAREN && followingIsParamOrGivenType() then
3419- val paramsStart = in.offset
3420- vparamss = paramClauses(ofInstance = ! isExtension)
3421- if isExtension then
3422- checkExtensionParams(paramsStart, vparamss)
3423-
3424- parseParams(isExtension = ! hasGivenSig)
3425- val parents =
3426- if in.token == COLON then
3427- in.nextToken()
3428- if in.token == LBRACE
3429- || in.token == WITH
3430- || in.token == LBRACKET
3431- || in.token == LPAREN && followingIsParamOrGivenType()
3432- then
3433- parseParams(isExtension = true )
3434- Nil
3435- else
3436- tokenSeparated(COMMA , constrApp)
3437- else if in.token == SUBTYPE then
3438- if ! mods.is(Inline ) then
3439- syntaxError(" `<:' is only allowed for given with `inline' modifier" )
3440- in.nextToken()
3441- TypeBoundsTree (EmptyTree , toplevelTyp()) :: Nil
3442- else if name.isEmpty
3443- && in.token != LBRACE && in.token != WITH
3444- && ! hasExtensionParams
3445- then tokenSeparated(COMMA , constrApp)
3446- else Nil
3409+ val (name, isExtension) =
3410+ if isIdent && hasGivenSig then
3411+ (ident(), in.token == COLON && in.lookaheadIn(nme.extension))
3412+ else
3413+ (EmptyTermName , isIdent(nme.extension))
3414+
3415+ val gdef = indentRegion(name) {
3416+ if isExtension then
3417+ if (in.token == COLON ) in.nextToken()
3418+ assert(ident() == nme.extension)
3419+ val tparams = typeParamClauseOpt(ParamOwner .Def )
3420+ val extParams = paramClause(0 , prefix = true )
3421+ val givenParamss = paramClauses(givenOnly = true )
3422+ possibleTemplateStart()
3423+ val templ = templateBodyOpt(
3424+ makeConstructor(tparams, extParams :: givenParamss), Nil , Nil )
3425+ templ.body.foreach(checkExtensionMethod)
3426+ ModuleDef (name, templ)
3427+ else
3428+ var tparams : List [TypeDef ] = Nil
3429+ var vparamss : List [List [ValDef ]] = Nil
3430+ var hasExtensionParams = false
3431+
3432+ def parseParams (isExtension : Boolean ): Unit =
3433+ if isExtension && (in.token == LBRACKET || in.token == LPAREN ) then
3434+ hasExtensionParams = true
3435+ if tparams.nonEmpty || vparamss.nonEmpty then
3436+ syntaxError(i " cannot have parameters before and after `:` in extension " )
3437+ if in.token == LBRACKET then
3438+ tparams = typeParamClause(ParamOwner .Def )
3439+ if in.token == LPAREN && followingIsParamOrGivenType() then
3440+ val paramsStart = in.offset
3441+ vparamss = paramClauses(givenOnly = ! isExtension)
3442+ if isExtension then
3443+ checkExtensionParams(paramsStart, vparamss)
3444+
3445+ parseParams(isExtension = false )
3446+ val parents =
3447+ if in.token == COLON then
3448+ in.nextToken()
3449+ if in.token == LBRACE
3450+ || in.token == WITH
3451+ || in.token == LBRACKET
3452+ || in.token == LPAREN && followingIsParamOrGivenType()
3453+ then
3454+ parseParams(isExtension = true )
3455+ Nil
3456+ else
3457+ tokenSeparated(COMMA , constrApp)
3458+ else if in.token == SUBTYPE then
3459+ if ! mods.is(Inline ) then
3460+ syntaxError(" `<:' is only allowed for given with `inline' modifier" )
3461+ in.nextToken()
3462+ TypeBoundsTree (EmptyTree , toplevelTyp()) :: Nil
3463+ else if name.isEmpty
3464+ && in.token != LBRACE && in.token != WITH
3465+ && ! hasExtensionParams
3466+ then tokenSeparated(COMMA , constrApp)
3467+ else Nil
34473468
3448- val gdef =
34493469 if in.token == EQUALS && parents.length == 1 && parents.head.isType then
34503470 in.nextToken()
34513471 mods1 |= Final
@@ -3467,9 +3487,8 @@ object Parsers {
34673487 ModuleDef (name, templ)
34683488 else if tparams.isEmpty && vparamss.isEmpty then ModuleDef (name, templ)
34693489 else TypeDef (name.toTypeName, templ)
3470-
3471- finalizeDef(gdef, mods1, start)
34723490 }
3491+ finalizeDef(gdef, mods1, start)
34733492 }
34743493
34753494/* -------- TEMPLATES ------------------------------------------- */
0 commit comments