Skip to content

Retargeting for generative type providers #139

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Type providers may be used in projects that generate .NET Standard code or targe
that being used to execute the F# compiler. Use

```fsharp
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)
```

to your code and always create provided entities using this ``ctxt`` object:
Expand All @@ -68,7 +68,7 @@ type BasicProvider (config : TypeProviderConfig) as this =

let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
Expand Down
5 changes: 4 additions & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#### 3.0.1 - October 1 2017
* Cross-targeting for generative type providers, and reimplement binary reader

#### 3.0.0 - October 9 2017
* All type providers now use a ProvidedTypesContext, e.g.
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)
...
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
...
Expand Down
6 changes: 3 additions & 3 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ Target "Clean" (fun _ ->
Target "Restore" (fun _ ->
exec "dotnet" "restore"
)
Target "Compile" (fun _ ->
Target "Build" (fun _ ->
exec "dotnet" "build"
)

Expand All @@ -87,7 +87,7 @@ Target "RunTests" (fun _ ->
#else
exec "dotnet" ("test tests/FSharp.TypeProviders.SDK.Tests.fsproj -c " + config)
// This also gives console output:
//exec "packages/xunit.runner.console/tools/net452/xunit.console.exe" ("/p:Configuration=" + config + " tests/bin/" + config + "/net461/FSharp.TypeProviders.SDK.Tests.dll -parallel none")
// packages\xunit.runner.console\tools\net452\xunit.console.exe testsbin\Release\net461\FSharp.TypeProviders.SDK.Tests.dll -parallel none
#endif
()
)
Expand All @@ -104,7 +104,7 @@ Target "NuGet" (fun _ ->
==> "NuGet"

"Restore"
==> "Compile"
==> "Build"
//#if EXAMPLES
// ==> "Examples"
//#endif
Expand Down
2 changes: 1 addition & 1 deletion examples/ErasedWithConstructor.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type BasicErasingProvider (config : TypeProviderConfig) as this =

let ns = "ErasedWithConstructor.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
Expand Down
2 changes: 1 addition & 1 deletion examples/StaticProperty.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type BasicProvider (config : TypeProviderConfig) as this =

let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
Expand Down
7,410 changes: 6,495 additions & 915 deletions src/ProvidedTypes.fs

Large diffs are not rendered by default.

68 changes: 31 additions & 37 deletions src/ProvidedTypes.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,6 @@ namespace ProviderImplementation.ProvidedTypes
/// Set the attributes on the provided type. This fully replaces the default TypeAttributes.
member SetAttributes: TypeAttributes -> unit

/// Reset the enclosing type (for generated nested types)
member ResetEnclosingType: enclosingType:Type -> unit

/// Add a method, property, nested type or other member to a ProvidedTypeDefinition
member AddMember: memberInfo:MemberInfo -> unit

Expand Down Expand Up @@ -392,9 +389,8 @@ namespace ProviderImplementation.ProvidedTypes
type ProvidedTypesContext =

/// Create a context for providing types for a particular rntime target.
/// If this context is for a generative type provider then isForGenerated should be set to true.
/// If specific assembly renaming replacements are required set assemblyReplacementMap.
static member Create : cfg: TypeProviderConfig * isForGenerated: bool * ?assemblyReplacementMap : seq<string*string> -> ProvidedTypesContext
/// Specific assembly renaming replacements can be provided using assemblyReplacementMap.
static member Create : cfg: TypeProviderConfig * ?assemblyReplacementMap : seq<string*string> -> ProvidedTypesContext

/// Create a new provided static parameter, for use with DefineStaticParamaeters on a provided type definition.
///
Expand Down Expand Up @@ -461,37 +457,6 @@ namespace ProviderImplementation.ProvidedTypes




#if !NO_GENERATIVE
/// A provided generated assembly
type ProvidedAssembly =
/// Create a provided generated assembly
new: assemblyFileName:string -> ProvidedAssembly

/// Emit the given provided type definitions as part of the assembly
/// and adjust the 'Assembly' property of all provided type definitions to return that
/// assembly.
///
/// The assembly is only emitted when the Assembly property on the root type is accessed for the first time.
/// The host F# compiler does this when processing a generative type declaration for the type.
member AddTypes: types: ProvidedTypeDefinition list -> unit

/// <summary>
/// Emit the given nested provided type definitions as part of the assembly.
/// and adjust the 'Assembly' property of all provided type definitions to return that
/// assembly.
/// </summary>
/// <param name="enclosingTypeNames">A path of type names to wrap the generated types. The generated types are then generated as nested types.</param>
member AddNestedTypes: types: ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit

#if !FX_NO_LOCAL_FILESYSTEM
/// Register that a given file is a provided generated assembly
static member RegisterGenerated: fileName:string -> Assembly
#endif

#endif


/// A base type providing default implementations of type provider functionality when all provided
/// types are of type ProvidedTypeDefinition.
type TypeProviderForNamespaces =
Expand Down Expand Up @@ -536,6 +501,35 @@ namespace ProviderImplementation.ProvidedTypes
interface ITypeProvider


#if !NO_GENERATIVE
/// A provided generated assembly
type ProvidedAssembly =
/// Create a provided generated assembly
new: assemblyFileName:string * context:ProvidedTypesContext -> ProvidedAssembly

/// Emit the given provided type definitions as part of the assembly
/// and adjust the 'Assembly' property of all provided type definitions to return that
/// assembly.
///
/// The assembly is only emitted when the Assembly property on the root type is accessed for the first time.
/// The host F# compiler does this when processing a generative type declaration for the type.
member AddTypes: types: ProvidedTypeDefinition list -> unit

/// <summary>
/// Emit the given nested provided type definitions as part of the assembly.
/// and adjust the 'Assembly' property of all provided type definitions to return that
/// assembly.
/// </summary>
/// <param name="enclosingTypeNames">A path of type names to wrap the generated types. The generated types are then generated as nested types.</param>
member AddNestedTypes: types: ProvidedTypeDefinition list * enclosingGeneratedTypeNames: string list -> unit

#if !FX_NO_LOCAL_FILESYSTEM
/// Register that a given file is a provided generated assembly
static member RegisterGenerated: context: ProvidedTypesContext * fileName: string -> Assembly
#endif

#endif



module internal UncheckedQuotations =
Expand Down
1 change: 1 addition & 0 deletions src/ProvidedTypesTesting.fs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ type internal Testing() =
printExpr false true e

and printCall fromPipe printName (mi:MethodInfo) args =
//eprintfn "printCall: %s" mi.Name
if fromPipe && List.length args = 1 then
printName()
elif not (hasAttr "CompilationArgumentCountsAttribute" mi) then
Expand Down
8 changes: 4 additions & 4 deletions tests/BasicErasedProvisionTests.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#if INTERACTIVE
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs" "../src/AssemblyReader.fs" "../src/AssemblyReaderReflection.fs" "../src/ProvidedTypesContext.fs"
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs"
#load "../src/ProvidedTypesTesting.fs"

#else
Expand All @@ -24,7 +24,7 @@ type ErasingProvider (config : TypeProviderConfig) as this =

let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
Expand All @@ -49,7 +49,7 @@ type ErasingConstructorProvider (config : TypeProviderConfig) as this =

let ns = "ErasedWithConstructor.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createTypes () =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, "MyType", Some typeof<obj>)
Expand All @@ -74,7 +74,7 @@ type ErasingProviderWithStaticParams (config : TypeProviderConfig) as this =

let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=false)
let ctxt = ProvidedTypesContext.Create(config)

let createType (typeName, n:int) =
let myType = ctxt.ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>)
Expand Down
10 changes: 6 additions & 4 deletions tests/BasicGenerativeProvisionTests.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#if INTERACTIVE
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs" "../src/AssemblyReader.fs" "../src/AssemblyReaderReflection.fs" "../src/ProvidedTypesContext.fs"
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs"
#load "../src/ProvidedTypesTesting.fs"

#else
Expand All @@ -25,12 +25,12 @@ type GenerativePropertyProviderWithStaticParams (config : TypeProviderConfig) as
let ns = "StaticProperty.Provided"
let asm = Assembly.GetExecutingAssembly()

let ctxt = ProvidedTypesContext.Create(config, isForGenerated=true)
let ctxt = ProvidedTypesContext.Create(config)
let createType (typeName, n:int) =
let tmp = Path.ChangeExtension(Path.GetTempFileName(), "dll")
let myAssem = ProvidedAssembly(tmp)
let myAssem = ProvidedAssembly(tmp, ctxt)
let myType = ctxt.ProvidedTypeDefinition(asm, ns, typeName, Some typeof<obj>, isErased=false)
let myProp = ctxt.ProvidedProperty("MyProperty", typeof<string list>, isStatic = true, getterCode = (fun args -> <@@ Set.ofList [ "Hello world" ] @@>))
let myProp = ctxt.ProvidedProperty("MyProperty", typeof<string list>, isStatic = true, getterCode = (fun args -> <@@ Set.toList (Set.ofList [ "Hello world" ]) @@>))
myType.AddMember(myProp)
myAssem.AddTypes [myType]
myType
Expand Down Expand Up @@ -62,4 +62,6 @@ let ``GenerativePropertyProviderWithStaticParams generates for .NET 4.5 F# 4.0 c
Assert.NotEqual(assemContents.Length, 0)


// TEST: Register binary
// TEST: Many more F# constructs in generated code, giveing full coverage
#endif
6 changes: 3 additions & 3 deletions tests/GenerativeEnumsProvisionTests.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#if INTERACTIVE
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs" "../src/AssemblyReader.fs" "../src/AssemblyReaderReflection.fs" "../src/ProvidedTypesContext.fs"
#load "../src/ProvidedTypes.fsi" "../src/ProvidedTypes.fs"
#load "../src/ProvidedTypesTesting.fs"

#else
Expand Down Expand Up @@ -27,8 +27,8 @@ type GenerativeEnumsProvider (config: TypeProviderConfig) as this =

let ns = "Enums.Provided"
let asm = Assembly.GetExecutingAssembly()
let ctxt = ProvidedTypesContext.Create(config, isForGenerated=true)
let tempAssembly = ProvidedAssembly(Path.ChangeExtension(Path.GetTempFileName(), "dll"))
let ctxt = ProvidedTypesContext.Create(config)
let tempAssembly = ProvidedAssembly(Path.ChangeExtension(Path.GetTempFileName(), "dll"), ctxt)
let container = ctxt.ProvidedTypeDefinition(asm, ns, "Container", Some typeof<obj>, isErased = false)

let createEnum name (values: list<string*int>) =
Expand Down