fsprojects / FSharp.TypeProviders.SDK

The SDK for creating F# type providers
https://fsprojects.github.io/FSharp.TypeProviders.SDK/
MIT License
298 stars 94 forks source link

Use most recent assembly containing type #276

Closed kevmal closed 5 years ago

kevmal commented 5 years ago

Something like

    let prop1 = ProvidedProperty("InnerState", typeof<string>, getterCode = fun args -> <@@ "hello" @@>)
    myType.AddMember(prop1)
    let meth2 = ProvidedMethod("InstanceMethod", [], typeof<string>, isStatic=false, invokeCode = (fun args -> Expr.PropertyGet(args.[0],prop1)))
    myType.AddMember(meth2)

in a generative type provider has issues in hosted environments. It'll compile fine since the asm only gets generated once but fsi and source checking will fail (particularly if static parameters change). This is due to ProvidedTypesContext always returning the first "version" of a given type. The new invokeCode will be called but with the wrong type for the this parameter resulting in an "incorrect instance type" error. The workaround for source checking would be to either use reflection

let meth2 = 
    ProvidedMethod("InstanceMethod", [], typeof<string>, isStatic=false, 
        invokeCode = (fun args -> Expr.PropertyGet(args.[0],args.[0].Type.GetProperty("InnerState"))))

(which would fail if the type of "InnerState" changes) or to use unchecked expressions. In either case both still have issues when used in fsi.

This is probably the simplest change addressing this issue. It simply favors the most recent assembly containing the desired type instead of the first. However, it leaves open the issue that stale assemblies are not being removed from ProvidedTypesContext.sourceAssemblies_.

dsyme commented 5 years ago

Why is paket.restore.cached added? thanks

kevmal commented 5 years ago

Oops, fixed.

sergey-tihon commented 5 years ago

Confirm that this fix works for me too. Thank you @kevmal ! Great work!

dsyme commented 5 years ago

Good work