Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
ber.a committed Jan 16, 2020
1 parent 4b15d8d commit cd408f5
Show file tree
Hide file tree
Showing 7 changed files with 198 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\netfx.props" />
<PropertyGroup>
<TargetFrameworks>$(FcsTargetNetFxFramework);netcoreapp3.0</TargetFrameworks>
Expand All @@ -24,6 +24,9 @@
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\AssemblyReaderShim.fs">
<Link>AssemblyReaderShim.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\ExtensionTypingProviderTests.fs">
<Link>ExtensionTypingProviderTests.fs</Link>
</Compile>
<Compile Include="$(FSharpSourcesRoot)\..\tests\service\EditorTests.fs">
<Link>EditorTests.fs</Link>
</Compile>
Expand Down
3 changes: 2 additions & 1 deletion src/fsharp/CompileOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -4252,7 +4252,8 @@ and [<Sealed>] TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAsse

let providers = [
for designTimeAssemblyName in designTimeAssemblyNames do
yield! ExtensionTyping.GetTypeProvidersOfAssembly(fileNameOfRuntimeAssembly,
yield! Shim.ExtensionTypingProvider.InstantiateTypeProvidersOfAssembly(
fileNameOfRuntimeAssembly,
ilScopeRefOfRuntimeAssembly,
designTimeAssemblyName,
typeProviderEnvironment,
Expand Down
48 changes: 46 additions & 2 deletions src/fsharp/ExtensionTyping.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace FSharp.Compiler

#if !NO_EXTENSIONTYPING

module internal ExtensionTyping =
module ExtensionTyping =
open System
open System.IO
open System.Collections.Generic
Expand Down Expand Up @@ -1186,5 +1186,49 @@ module internal ExtensionTyping =
/// We check by seeing if the type is absent from the remapping context.
let IsGeneratedTypeDirectReference (st: Tainted<ProvidedType>, m) =
st.PUntaint((fun st -> st.TryGetTyconRef() |> Option.isNone), m)


[<AutoOpen>]
module Shim =

type IExtensionTypingProvider =
abstract InstantiateTypeProvidersOfAssembly :
runtimeAssemblyFilename: string
* ilScopeRefOfRuntimeAssembly:ILScopeRef
* designerAssemblyName: string
* ResolutionEnvironment
* bool
* isInteractive: bool
* systemRuntimeContainsType : (string -> bool)
* systemRuntimeAssemblyVersion : System.Version
* compilerToolsPath : string list
* range -> Tainted<ITypeProvider> list

[<Sealed>]
type DefaultExtensionTypingProvider() =
interface IExtensionTypingProvider with
member this.InstantiateTypeProvidersOfAssembly
(runTimeAssemblyFileName: string,
ilScopeRefOfRuntimeAssembly: ILScopeRef,
designTimeAssemblyNameString: string,
resolutionEnvironment: ResolutionEnvironment,
isInvalidationSupported: bool,
isInteractive: bool,
systemRuntimeContainsType : string -> bool,
systemRuntimeAssemblyVersion : System.Version,
compilerToolPaths: string list,
m:range) =

GetTypeProvidersOfAssembly(runTimeAssemblyFileName,
ilScopeRefOfRuntimeAssembly,
designTimeAssemblyNameString,
resolutionEnvironment,
isInvalidationSupported,
isInteractive,
systemRuntimeContainsType,
systemRuntimeAssemblyVersion,
compilerToolPaths,
m)

let mutable ExtensionTypingProvider = DefaultExtensionTypingProvider() :> IExtensionTypingProvider

#endif
43 changes: 29 additions & 14 deletions src/fsharp/ExtensionTyping.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace FSharp.Compiler

#if !NO_EXTENSIONTYPING

module internal ExtensionTyping =
module ExtensionTyping =

open System
open System.IO
Expand Down Expand Up @@ -44,19 +44,6 @@ module internal ExtensionTyping =
temporaryFolder : string
}

/// Find and instantiate the set of ITypeProvider components for the given assembly reference
val GetTypeProvidersOfAssembly :
runtimeAssemblyFilename: string
* ilScopeRefOfRuntimeAssembly:ILScopeRef
* designerAssemblyName: string
* ResolutionEnvironment
* bool
* isInteractive: bool
* systemRuntimeContainsType : (string -> bool)
* systemRuntimeAssemblyVersion : System.Version
* compilerToolsPath : string list
* range -> Tainted<ITypeProvider> list

/// Given an extension type resolver, supply a human-readable name suitable for error messages.
val DisplayNameOfTypeProvider : Tainted<Microsoft.FSharp.Core.CompilerServices.ITypeProvider> * range -> string

Expand Down Expand Up @@ -370,5 +357,33 @@ module internal ExtensionTyping =
/// Check if this is a direct reference to a non-embedded generated type. This is not permitted at any name resolution.
/// We check by seeing if the type is absent from the remapping context.
val IsGeneratedTypeDirectReference : Tainted<ProvidedType> * range -> bool
[<AutoOpen>]
module Shim =
open System
open FSharp.Core.CompilerServices
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.Range

type IExtensionTypingProvider =

/// Find and instantiate the set of ITypeProvider components for the given assembly reference
abstract InstantiateTypeProvidersOfAssembly :
runtimeAssemblyFilename: string
* ilScopeRefOfRuntimeAssembly:ILScopeRef
* designerAssemblyName: string
* ResolutionEnvironment
* bool
* isInteractive: bool
* systemRuntimeContainsType : (string -> bool)
* systemRuntimeAssemblyVersion : System.Version
* compilerToolsPath : string list
* range -> Tainted<ITypeProvider> list

[<Sealed>]
type DefaultExtensionTypingProvider =
interface IExtensionTypingProvider

val mutable ExtensionTypingProvider: IExtensionTypingProvider

#endif
6 changes: 3 additions & 3 deletions src/fsharp/tainted.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ open Microsoft.FSharp.Core.CompilerServices
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Internal.Library

type internal TypeProviderError
type TypeProviderError
(
errNum : int,
tpDesignation : string,
Expand Down Expand Up @@ -72,7 +72,7 @@ type internal TypeProviderError
type TaintedContext = { TypeProvider : ITypeProvider; TypeProviderAssemblyRef : ILScopeRef }

[<NoEquality>][<NoComparison>]
type internal Tainted<'T> (context : TaintedContext, value : 'T) =
type Tainted<'T> (context : TaintedContext, value : 'T) =
do
match box context.TypeProvider with
| null ->
Expand Down Expand Up @@ -153,7 +153,7 @@ type internal Tainted<'T> (context : TaintedContext, value : 'T) =
member this.Coerce<'U> (range:range) =
Tainted(context, this.Protect(fun value -> box value :?> 'U) range)

module internal Tainted =
module Tainted =
let (|Null|_|) (p:Tainted<'T>) =
if p.PUntaintNoFailure(fun p -> match p with null -> true | _ -> false) then Some() else None

Expand Down
6 changes: 3 additions & 3 deletions src/fsharp/tainted.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ open FSharp.Compiler.Range
open FSharp.Compiler.AbstractIL.IL

/// Stores and transports aggregated list of errors reported by the type provider
type internal TypeProviderError =
type TypeProviderError =
inherit System.Exception

/// creates new instance of TypeProviderError that represents one error
Expand All @@ -39,7 +39,7 @@ type internal TypeProviderError =

/// This struct wraps a value produced by a type provider to properly attribute any failures.
[<NoEquality; NoComparison; Class>]
type internal Tainted<'T> =
type Tainted<'T> =

/// Create an initial tainted value
static member CreateAll : (ITypeProvider * ILScopeRef) list -> Tainted<ITypeProvider> list
Expand Down Expand Up @@ -93,7 +93,7 @@ type internal Tainted<'T> =


[<RequireQualifiedAccess>]
module internal Tainted =
module Tainted =

/// Test whether the tainted value is null
val (|Null|_|) : Tainted<'T> -> unit option when 'T : null
Expand Down
111 changes: 111 additions & 0 deletions tests/service/ExtensionTypingProviderTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
#if INTERACTIVE
#r "../../artifacts/bin/fcs/net461/FSharp.Compiler.Service.dll" // note, build FSharp.Compiler.Service.Tests.fsproj to generate this, this DLL has a public API so can be used from F# Interactive
#r "../../artifacts/bin/fcs/net461/nunit.framework.dll"
#load "FsUnit.fs"
#load "Common.fs"
#else
module FSharp.Compiler.Service.Tests.ExtensionTypingProvider
#endif

open System
open System.IO
open FsUnit
open NUnit.Framework
open FSharp.Compiler.ExtensionTyping
open FSharp.Compiler.Range
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.AbstractIL.Internal.Library
open FSharp.Compiler.Service.Tests.Common
open FSharp.Compiler
open FSharp.Compiler.SourceCodeServices

let typeProviderProjectOptions =
{ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/TypeProviderConsole.fsproj";
ProjectId = None
SourceFiles = [|__SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/Program.fs"|];
Stamp = None
OtherOptions =
[|yield "--simpleresolution";
yield "--noframework";
yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/bin/Debug/TypeProviderConsole.exe";
yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderConsole/bin/Debug/TypeProviderConsole.xml";
yield "--subsystemversion:6.00";
yield "--highentropyva+";
yield "--fullpaths";
yield "--flaterrors";
yield "--target:exe";
yield "--define:DEBUG";
yield "--define:TRACE";
yield "--debug+";
yield "--optimize-";
yield "--tailcalls-";
yield "--debug:full";
yield "--platform:anycpu";
for r in mkStandardProjectReferences () do
yield "-r:" + r
yield "-r:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll"|];
ReferencedProjects =
[|(__SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll",
{ProjectFileName = __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.fsproj";
ProjectId = None
SourceFiles = [|__SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/Library1.fs"|];
Stamp = None
OtherOptions =
[|yield "--simpleresolution";
yield "--noframework";
yield "--out:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/TypeProviderLibrary.dll";
yield "--doc:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/bin/Debug/TypeProviderLibrary.xml";
yield "--subsystemversion:6.00";
yield "--highentropyva+";
yield "--fullpaths";
yield "--flaterrors";
yield "--target:library";
yield "--define:DEBUG";
yield "--define:TRACE";
yield "--debug+";
yield "--optimize-";
yield "--tailcalls-";
yield "--debug:full";
yield "--platform:anycpu";
for r in mkStandardProjectReferences () do
yield "-r:" + r
yield "-r:" + __SOURCE_DIRECTORY__ + @"/data/TypeProviderLibrary/FSharp.Data.TypeProviders.dll";
|];
ReferencedProjects = [||];
IsIncompleteTypeCheckEnvironment = false;
UseScriptResolutionRules = false;
LoadTime = System.DateTime.Now
UnresolvedReferences = None;
OriginalLoadReferences = [];
ExtraProjectInfo = None;})|];
IsIncompleteTypeCheckEnvironment = false;
UseScriptResolutionRules = false;
LoadTime = System.DateTime.Now
UnresolvedReferences = None;
OriginalLoadReferences = [];
ExtraProjectInfo = None;}

[<Test>]
let ``Extension typing shim gets requests`` () =
let mutable gotRequest = false
let extensionTypingProvider =
{ new IExtensionTypingProvider with
member this.InstantiateTypeProvidersOfAssembly
(runTimeAssemblyFileName: string,
ilScopeRefOfRuntimeAssembly: ILScopeRef,
designTimeAssemblyNameString: string,
resolutionEnvironment: ResolutionEnvironment,
isInvalidationSupported: bool,
isInteractive: bool,
systemRuntimeContainsType : string -> bool,
systemRuntimeAssemblyVersion : System.Version,
compilerToolPaths: string list,
m:range) =
gotRequest <- true
[]
}

Shim.ExtensionTypingProvider <- extensionTypingProvider

checker.ParseAndCheckProject(typeProviderProjectOptions) |> Async.RunSynchronously |> ignore
gotRequest |> should be True

0 comments on commit cd408f5

Please sign in to comment.