The following type provider was intended to create GeneratedNamespace.MyType
which accepts a static parameter of type string
and contains only an empty constructor
namespace TypeProviderTest
open Microsoft.FSharp.Core.CompilerServices
open ProviderImplementation.ProvidedTypes
open System.Reflection
open System
[<TypeProvider>]
type MyTypeProvider(config:TypeProviderConfig) as this =
inherit TypeProviderForNamespaces()
let namespaceName="GeneratedNamespace"
let assembly = Assembly.LoadFrom(config.RuntimeAssembly)
//Provides definition, based on type parameters
let instantiationFunction typeName (typeParams:obj[]) =
match typeParams with
| [|:? string as param|] ->
//Creates an empty non-erased type
let definition = ProvidedTypeDefinition(
assembly,
namespaceName,
typeName,
Some typedefof<Object>,
IsErased = false
)
//Creates an empty constructor
let emptyCtor = ProvidedConstructor (parameters = [])
//Provides a call to base constructor
//(https://stackoverflow.com/questions/22520352/)
//Doesn't seem to help
let objCtor = typedefof<Object>.GetType().GetConstructor([||])
emptyCtor.BaseConstructorCall <- (fun _ -> objCtor,[])
emptyCtor.AddXmlDoc("Empty constructor test")
definition.AddMember(emptyCtor)
definition
| _ -> failwith "That was not supported"
let staticParams = [ProvidedStaticParameter("value",typedefof<string>)]
let t = ProvidedTypeDefinition(assembly,namespaceName,"MyType",Some typedefof<Object>)
do t.DefineStaticParameters(staticParams,instantiationFunction)
do this.AddNamespace(namespaceName,[t])
[<assembly:TypeProviderAssembly>]
do ()
When I try to use it like this
open System
open GeneratedNamespace
type X = MyType<"Abacaba">
[<EntryPoint>]
let main argv =
printfn "%A %A" typedefof<X> (new X())
Console.ReadLine() |> ignore
0
The line type X = MyType<"Abacaba">
produces the error
Error FS3039: A direct reference to the generated type 'MyType' is not permitted.
I added a base constructor call, but it didn't help
The type provider is made generative intentionally
Is there an error in my type provider?
I'm not sure how to make it fully work, but I think the reason why you're getting the error is that the parameterised type is an erased type (while the type that you return once static parameters are provided is not an erased type).
Adding IsErased = false
to t
makes the error go away:
let staticParams = [ProvidedStaticParameter("value",typedefof<string>)]
let t =
ProvidedTypeDefinition
(assembly,namespaceName,"MyType",Some typedefof<Object>,IsErased = false)
do t.DefineStaticParameters(staticParams,instantiationFunction)
With this, the code can be compiled, but trying to create an instance using new X()
gives:
error FS0192: internal error: null: GetTRefType
So, there is probably something else that I'm missing too. Perhaps it can point you into the right direction though!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With