@@ -859,21 +859,22 @@ object desugar {
859
859
* given object name extends parents { self => body' }
860
860
*
861
861
* where every definition in `body` is expanded to an extension method
862
- * taking type parameters `tparams` and a leading parameter `(x: T)`.
863
- * See: makeExtensionDef
862
+ * taking type parameters `tparams` and a leading paramter `(x: T)`.
863
+ * See: collectiveExtensionBody
864
864
*/
865
865
def moduleDef (mdef : ModuleDef )(implicit ctx : Context ): Tree = {
866
866
val impl = mdef.impl
867
867
val mods = mdef.mods
868
868
impl.constr match {
869
- case DefDef (_, tparams, (vparams @ (vparam :: Nil )) :: givenParamss, _, _) =>
869
+ case DefDef (_, tparams, vparamss @ (vparam :: Nil ) :: givenParamss, _, _) =>
870
+ // Transform collective extension
870
871
assert(mods.is(Given ))
871
872
return moduleDef(
872
873
cpy.ModuleDef (mdef)(
873
874
mdef.name,
874
875
cpy.Template (impl)(
875
876
constr = emptyConstructor,
876
- body = impl.body.map(makeExtensionDef(_ , tparams, vparams, givenParamss) ))))
877
+ body = collectiveExtensionBody( impl.body, tparams, vparamss ))))
877
878
case _ =>
878
879
}
879
880
@@ -916,43 +917,40 @@ object desugar {
916
917
}
917
918
}
918
919
919
- /** Given tpe parameters `Ts` (possibly empty) and a leading value parameter `(x: T)`,
920
- * map a method definition
920
+ /** Transform the statements of a collective extension
921
+ * @param stats the original statements as they were parsed
922
+ * @param tparams the collective type parameters
923
+ * @param vparamss the collective value parameters, consisting
924
+ * of a single leading value parameter, followed by
925
+ * zero or more context parameter clauses
921
926
*
922
- * def foo [Us] paramss ...
927
+ * Note: It is already assured by Parser.checkExtensionMethod that all
928
+ * statements conform to requirements.
923
929
*
924
- * to
930
+ * Each method in stats is transformed into an extension method. Example:
931
+ *
932
+ * extension on [Ts](x: T)(using C):
933
+ * def f(y: T) = ???
934
+ * def g(z: T) = f(z)
925
935
*
926
- * <extension> def foo[Ts ++ Us](x: T) parammss ...
936
+ * is turned into
927
937
*
928
- * If the given member `mdef` is not of this form, flag it as an error.
938
+ * extension:
939
+ * <extension> def f[Ts](x: T)(using C)(y: T) = ???
940
+ * <extension> def g[Ts](x: T)(using C)(z: T) = f(z)
929
941
*/
930
-
931
- def makeExtensionDef (mdef : Tree , tparams : List [TypeDef ], leadingParams : List [ValDef ],
932
- givenParamss : List [List [ValDef ]])(using ctx : Context ): Tree = {
933
- mdef match {
934
- case mdef : DefDef =>
935
- if (mdef.mods.is(Extension )) {
936
- ctx.error(NoExtensionMethodAllowed (mdef), mdef.sourcePos)
937
- mdef
938
- } else {
939
- if (tparams.nonEmpty && mdef.tparams.nonEmpty) then
940
- ctx.error(ExtensionMethodCannotHaveTypeParams (mdef), mdef.tparams.head.sourcePos)
941
- mdef
942
- else cpy.DefDef (mdef)(
942
+ def collectiveExtensionBody (stats : List [Tree ],
943
+ tparams : List [TypeDef ], vparamss : List [List [ValDef ]])(using ctx : Context ): List [Tree ] =
944
+ for stat <- stats yield
945
+ stat match
946
+ case mdef : DefDef =>
947
+ cpy.DefDef (mdef)(
943
948
tparams = tparams ++ mdef.tparams,
944
- vparamss = leadingParams :: givenParamss ::: mdef.vparamss
949
+ vparamss = vparamss ::: mdef.vparamss,
945
950
).withMods(mdef.mods | Extension )
946
- }
947
- case mdef : Import =>
948
- mdef
949
- case mdef if ! mdef.isEmpty => {
950
- ctx.error(ExtensionCanOnlyHaveDefs (mdef), mdef.sourcePos)
951
- mdef
952
- }
953
- case mdef => mdef
954
- }
955
- }
951
+ case mdef =>
952
+ mdef
953
+ end collectiveExtensionBody
956
954
957
955
/** Transforms
958
956
*
0 commit comments