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

Workaround for target assemblies where packages with transitive references contain type providers #388

Closed dsyme closed 2 years ago

dsyme commented 2 years ago

Enables type providers to get the correct set of target assemblies when nuget packages with transitive references to other packages contain type providers, and these are used in scripts.

This is a workaround for F# tooling bug https://github.com/dotnet/fsharp/issues/13710 where the type providers are instnatiated before the complete set of references relevant to a nuget package are reported correctly by ReferencedAssemblies

// The 'ReferencedAssemblies' reported to type providers by TypeProviderConfig have a problem in scripting scenarios
// involving incremental additions to the referenced assembly set, see 
//
//   https://github.com/dotnet/fsharp/issues/13710
//
// There is a long-standing reflection hack to determine the set of
// referenced assemblies by reflecting over the SystemRuntimeContainsType
// closure in the TypeProviderConfig object.
//
// We removed the use of this hack in 2019, however the bug above indicates that
// it is still necessary when type providers have transitive nuget package references
// relevant to the public surface area of the provided types.
//
// Further, the ReferencedAssemblies need to be evaluated "late", after the type provider
// has been created, because additional references may be added to the compilation context by
// processing further #r references implied by a set of nuget packages. This will be addressed
// in the core F# tooling as part of fixing the bug above by instead simultaneously registering
// all `#r` implied by a load script. However until it is fixed we need to delay the recomputation
// of the referenced assemblies.

The "proper" F# tooling fix for https://github.com/dotnet/fsharp/issues/13710 is for F# tooling to register all transitive referenced assemblies implied by a nuget package reference simultaneously, and thus report ReferencedAssemblies correctly.

The workaround for getting referenced assemblies was removed here: https://github.com/fsprojects/FSharp.TypeProviders.SDK/pull/305. We will eventually be able to remove the workaround again once a proper fix for https://github.com/dotnet/fsharp/issues/13710 propagates through the F# tooling ecosystem for all tooling that loads type providers.