@@ -931,7 +931,11 @@ object Parsers {
931931 lookahead.nextToken()
932932 if lookahead.isIdent && ! lookahead.isIdent(nme.on) then
933933 lookahead.nextToken()
934+ if lookahead.isNewLine then
935+ lookahead.nextToken()
934936 lookahead.isIdent(nme.on)
937+ || lookahead.token == LBRACE
938+ || lookahead.token == COLON
935939
936940/* --------- OPERAND/OPERATOR STACK --------------------------------------- */
937941
@@ -3470,6 +3474,20 @@ object Parsers {
34703474 Template (constr, parents, Nil , EmptyValDef , Nil )
34713475 }
34723476
3477+ def checkExtensionMethod (tparams : List [Tree ],
3478+ vparamss : List [List [Tree ]], stat : Tree ): Unit = stat match {
3479+ case stat : DefDef =>
3480+ if stat.mods.is(Extension ) && vparamss.nonEmpty then
3481+ syntaxError(i " no extension method allowed here since leading parameter was already given " , stat.span)
3482+ else if ! stat.mods.is(Extension ) && vparamss.isEmpty then
3483+ syntaxError(i " an extension method is required here " , stat.span)
3484+ else if tparams.nonEmpty && stat.tparams.nonEmpty then
3485+ syntaxError(i " extension method cannot have type parameters since some were already given previously " ,
3486+ stat.tparams.head.span)
3487+ case stat =>
3488+ syntaxError(i " extension clause can only define methods " , stat.span)
3489+ }
3490+
34733491 /** GivenDef ::= [GivenSig] [‘_’ ‘<:’] Type ‘=’ Expr
34743492 * | [GivenSig] ConstrApps [TemplateBody]
34753493 * GivenSig ::= [id] [DefTypeParamClause] {UsingParamClauses} ‘as’
@@ -3516,20 +3534,25 @@ object Parsers {
35163534 finalizeDef(gdef, mods1, start)
35173535 }
35183536
3519- /** ExtensionDef ::= [id] ‘on’ ExtParamClause {UsingParamClause} ExtMethods
3537+ /** ExtensionDef ::= [id] [ ‘on’ ExtParamClause {UsingParamClause}] TemplateBody
35203538 */
35213539 def extensionDef (start : Offset , mods : Modifiers ): ModuleDef =
35223540 in.nextToken()
35233541 val name = if isIdent && ! isIdent(nme.on) then ident() else EmptyTermName
35243542 in.endMarkerScope(if name.isEmpty then nme.extension else name) {
3525- if ! isIdent(nme.on) then syntaxErrorOrIncomplete(" `on` expected" )
3526- if isIdent(nme.on) then in.nextToken()
3527- val tparams = typeParamClauseOpt(ParamOwner .Def )
3528- val extParams = paramClause(0 , prefix = true )
3529- val givenParamss = paramClauses(givenOnly = true )
3543+ val (tparams, vparamss) =
3544+ if isIdent(nme.on) then
3545+ in.nextToken()
3546+ val tparams = typeParamClauseOpt(ParamOwner .Def )
3547+ val extParams = paramClause(0 , prefix = true )
3548+ val givenParamss = paramClauses(givenOnly = true )
3549+ (tparams, extParams :: givenParamss)
3550+ else
3551+ (Nil , Nil )
35303552 possibleTemplateStart()
35313553 if ! in.isNestedStart then syntaxError(" Extension without extension methods" )
3532- val templ = templateBodyOpt(makeConstructor(tparams, extParams :: givenParamss), Nil , Nil )
3554+ val templ = templateBodyOpt(makeConstructor(tparams, vparamss), Nil , Nil )
3555+ templ.body.foreach(checkExtensionMethod(tparams, vparamss, _))
35333556 val edef = ModuleDef (name, templ)
35343557 finalizeDef(edef, addFlag(mods, Given ), start)
35353558 }
0 commit comments