@@ -57,35 +57,33 @@ module AutoGenConfig =
5757 /// The type is expected to have static methods that return Gen<'a>.
5858 /// These methods can have parameters which are required to be of type Gen<_ >.
5959 let addGenerators < 'a > ( config : AutoGenConfig ) =
60- let isGen ( t : Type ) = t.IsGenericType && t.GetGenericTypeDefinition() = typedefof< Gen<_>>
61-
62- // Ensure that all the parameters are of type Gen<_>, and return the unwrapped types.
63- let unwrapGenParameters ( methodInfo : MethodInfo ) : Type [] =
64- methodInfo.GetParameters()
65- |> Array.map ( fun param ->
66- if isGen param.ParameterType then
67- param.ParameterType.GetGenericArguments()[ 0 ]
68- else
69- failwithf " Method %s .%s has a parameter '%s ' which is not of type Gen<...>"
70- methodInfo.DeclaringType.Name
71- methodInfo.Name
72- param.Name)
60+ let isGen ( t : Type ) =
61+ t.IsGenericType && t.GetGenericTypeDefinition() = typedefof< Gen<_>>
62+
63+ let tryUnwrapGenParameters ( methodInfo : MethodInfo ) : Option < Type []> =
64+ methodInfo.GetParameters()
65+ |> Array.fold ( fun acc param ->
66+ match acc, isGen param.ParameterType with
67+ | Some types, true ->
68+ Some ( Array.append types [| param.ParameterType.GetGenericArguments().[ 0 ] |])
69+ | _ -> None
70+ ) ( Some [||])
7371
74- // find all the static methods that return Gen<'a>
75- let methods =
7672 typeof< 'a>. GetMethods( BindingFlags.Static ||| BindingFlags.Public)
77- |> Seq.filter ( fun m -> isGen m.ReturnType)
78-
79- // Register these methods as generator factories
80- methods
81- |> Seq.fold ( fun cfg methodInfo ->
82- let targetType = methodInfo.ReturnType.GetGenericArguments()[ 0 ]
83- let typeArray = unwrapGenParameters methodInfo
84- let factory : Type [] -> obj [] -> obj = fun types gens ->
85- let methodToCall = if Array.isEmpty types then methodInfo else methodInfo.MakeGenericMethod( types)
86- methodToCall.Invoke( null , gens)
87- cfg |> mapGenerators ( GeneratorCollection.addGenerator targetType typeArray factory)
88- ) config
73+ |> Seq.choose ( fun methodInfo ->
74+ match isGen methodInfo.ReturnType, tryUnwrapGenParameters methodInfo with
75+ | true , Some typeArray ->
76+ let targetType = methodInfo.ReturnType.GetGenericArguments().[ 0 ]
77+ let factory : Type [] -> obj [] -> obj = fun types gens ->
78+ let methodToCall =
79+ if Array.isEmpty types then methodInfo
80+ else methodInfo.MakeGenericMethod( types)
81+ methodToCall.Invoke( null , gens)
82+ Some ( targetType, typeArray, factory)
83+ | _ -> None)
84+ |> Seq.fold ( fun cfg ( targetType , typeArray , factory ) ->
85+ cfg |> mapGenerators ( GeneratorCollection.addGenerator targetType typeArray factory))
86+ config
8987
9088module GenX =
9189
0 commit comments