"Fossies" - the Fresh Open Source Software Archive

Member "fsharp-4.5/src/fsharp/ExtensionTyping.fs" (5 Sep 2018, 78964 Bytes) of package /linux/misc/mono-sources/fsharp/fsharp-4.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) F# source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "ExtensionTyping.fs": 4.1.33_vs_4.5.

    1 // Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.
    2 
    3 // Type providers, validation of provided types, etc.
    4 
    5 namespace Microsoft.FSharp.Compiler
    6 
    7 #if !NO_EXTENSIONTYPING
    8 
    9 module internal ExtensionTyping =
   10     open System
   11     open System.IO
   12     open System.Collections.Generic
   13     open System.Reflection
   14     open Microsoft.FSharp.Core.CompilerServices
   15     open Microsoft.FSharp.Compiler.ErrorLogger
   16     open Microsoft.FSharp.Compiler.Range
   17     open Microsoft.FSharp.Compiler.AbstractIL.IL
   18     open Microsoft.FSharp.Compiler.AbstractIL.Diagnostics // dprintfn
   19     open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library // frontAndBack
   20 
   21 #if FX_RESHAPED_REFLECTION
   22     open Microsoft.FSharp.Core.ReflectionAdapters
   23 #endif
   24 
   25     type TypeProviderDesignation = TypeProviderDesignation of string
   26 
   27     exception ProvidedTypeResolution of range * System.Exception 
   28     exception ProvidedTypeResolutionNoRange of System.Exception 
   29 
   30     /// Represents some of the configuration parameters passed to type provider components 
   31     type ResolutionEnvironment =
   32         { resolutionFolder          : string
   33           outputFile                : string option
   34           showResolutionMessages    : bool
   35           referencedAssemblies      : string[]
   36           temporaryFolder           : string } 
   37 
   38 
   39     // Specify the tooling-compatible fragments of a path such as:
   40     //     typeproviders/fsharp41/net461/MyProvider.DesignTime.dll
   41     //     tools/fsharp41/net461/MyProvider.DesignTime.dll
   42     // See https://github.com/Microsoft/visualfsharp/issues/3736
   43 
   44     // Represents the FF#-compiler <-> type provider protocol.
   45     // When the API or protocol updates, add a new version moniker to the front of the list here.
   46     let toolingCompatibleTypeProviderProtocolMonikers() = 
   47         [ "fsharp41" ] 
   48 
   49     // Detect the host tooling context
   50     let toolingCompatibleVersions() = 
   51         if typeof<obj>.Assembly.GetName().Name = "mscorlib" then 
   52             [ "net461"; "net452"; "net451"; "net45"; "netstandard2.0"]
   53         elif typeof<obj>.Assembly.GetName().Name = "System.Private.CoreLib" then 
   54             [ "netcoreapp2.0"; "netstandard2.0"]
   55         else
   56             System.Diagnostics.Debug.Assert(false, "Couldn't determine runtime tooling context, assuming it supports at least .NET Standard 2.0")
   57             [  "netstandard2.0"]
   58 
   59 
   60     let toolingCompatiblePaths() = 
   61         [ for protocol in toolingCompatibleTypeProviderProtocolMonikers() do
   62             for netRuntime in toolingCompatibleVersions() do 
   63                 yield Path.Combine("typeproviders", protocol, netRuntime)
   64                 yield Path.Combine("tools", protocol, netRuntime)
   65         ]
   66 
   67     /// Load a the design-time part of a type-provider into the host process, and look for types
   68     /// marked with the TypeProviderAttribute attribute.
   69     let GetTypeProviderImplementationTypes (runTimeAssemblyFileName, designTimeAssemblyNameString, m:range) =
   70 
   71         // Report an error, blaming the particular type provider component
   72         let raiseError (e:exn) =
   73             raise (TypeProviderError(FSComp.SR.etProviderHasWrongDesignerAssembly(typeof<TypeProviderAssemblyAttribute>.Name, designTimeAssemblyNameString, e.Message), runTimeAssemblyFileName, m))
   74 
   75         // Find and load the designer assembly for the type provider component.
   76         //
   77         // We look in the directories stepping up from the location of the runtime assembly.
   78 
   79         let loadFromLocation designTimeAssemblyPath =
   80             try
   81                 Some (FileSystem.AssemblyLoadFrom designTimeAssemblyPath)
   82             with e ->
   83                 raiseError e
   84 
   85         let rec searchParentDirChain dir designTimeAssemblyName = 
   86             seq { 
   87                 for subdir in toolingCompatiblePaths() do
   88                     let designTimeAssemblyPath  = Path.Combine (dir, subdir, designTimeAssemblyName)
   89                     if FileSystem.SafeExists designTimeAssemblyPath then 
   90                         yield loadFromLocation designTimeAssemblyPath
   91                 match Path.GetDirectoryName(dir) with
   92                 | s when s = "" || s = null || Path.GetFileName(dir) = "packages" || s = dir -> ()
   93                 | parentDir -> yield! searchParentDirChain parentDir designTimeAssemblyName 
   94             } 
   95 
   96         let loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName = 
   97             let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName
   98             searchParentDirChain runTimeAssemblyPath  designTimeAssemblyName
   99             |> Seq.tryHead
  100             |> function 
  101                | Some res -> res 
  102                | None -> 
  103                 // The search failed, just load from the first location and report an error
  104                 let runTimeAssemblyPath = Path.GetDirectoryName runTimeAssemblyFileName
  105                 loadFromLocation (Path.Combine (runTimeAssemblyPath, designTimeAssemblyName))
  106 
  107         let designTimeAssemblyOpt = 
  108 
  109             if designTimeAssemblyNameString.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then
  110                 loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyNameString
  111             else
  112                 // Cover the case where the ".dll" extension has been left off and no version etc. has been used in the assembly
  113                 // string specification.  The Name=FullName comparison is particularly strange, and was there to support
  114                 // design-time DLLs specified using "x.DesignTIme, Version= ..." long assembly names and GAC loads.
  115                 // These kind of design-time assembly specifications are no longer used to our knowledge so that comparison is basically legacy
  116                 // and will always succeed.  
  117                 let name = System.Reflection.AssemblyName (Path.GetFileNameWithoutExtension designTimeAssemblyNameString)
  118                 if name.Name.Equals(name.FullName, StringComparison.OrdinalIgnoreCase) then
  119                     let designTimeAssemblyName = designTimeAssemblyNameString+".dll"
  120                     loadFromParentDirRelativeToRuntimeAssemblyLocation designTimeAssemblyName
  121                 else
  122                     // Load from the GAC using Assembly.Load.  This is legacy since type provider design-time components are
  123                     // never in the GAC these days and  "x.DesignTIme, Version= ..." specifications are never used.
  124                     try
  125                         let asmName = System.Reflection.AssemblyName designTimeAssemblyNameString
  126                         Some (FileSystem.AssemblyLoad (asmName))
  127                     with e ->
  128                         raiseError e
  129 
  130         // If we've find a design-time assembly, look for the public types with TypeProviderAttribute
  131         match designTimeAssemblyOpt with
  132         | Some loadedDesignTimeAssembly ->
  133             try
  134                 let exportedTypes = loadedDesignTimeAssembly.GetExportedTypes() 
  135                 let filtered = 
  136                     [ for t in exportedTypes do 
  137                           let ca = t.GetCustomAttributes(typeof<TypeProviderAttribute>, true)
  138                           if ca <> null && ca.Length > 0 then 
  139                               yield t ]
  140                 filtered
  141             with e ->
  142                 raiseError e
  143         | None -> []
  144 
  145     let StripException (e:exn) =
  146         match e with
  147 #if !FX_REDUCED_EXCEPTIONS
  148         |   :? System.Reflection.TargetInvocationException as e -> e.InnerException
  149 #endif
  150         |   :? TypeInitializationException as e -> e.InnerException
  151         |   _ -> e
  152 
  153     /// Create an instance of a type provider from the implementation type for the type provider in the
  154     /// design-time assembly by using reflection-invoke on a constructor for the type provider.
  155     let CreateTypeProvider (typeProviderImplementationType:System.Type, 
  156                             runtimeAssemblyPath, 
  157                             resolutionEnvironment:ResolutionEnvironment, 
  158                             isInvalidationSupported:bool, 
  159                             isInteractive:bool, 
  160                             systemRuntimeContainsType, 
  161                             systemRuntimeAssemblyVersion, 
  162                             m) =
  163 
  164         // Protect a .NET reflection call as we load the type provider component into the host process, 
  165         // reporting errors.
  166         let protect f =
  167             try 
  168                 f ()
  169             with err ->
  170                 let e = StripException (StripException err)
  171                 raise (TypeProviderError(FSComp.SR.etTypeProviderConstructorException(e.Message), typeProviderImplementationType.FullName, m))
  172 
  173         if typeProviderImplementationType.GetConstructor([| typeof<TypeProviderConfig> |]) <> null then
  174 
  175             // Create the TypeProviderConfig to pass to the type provider constructor
  176             let e = TypeProviderConfig(systemRuntimeContainsType, 
  177                                        ResolutionFolder=resolutionEnvironment.resolutionFolder, 
  178                                        RuntimeAssembly=runtimeAssemblyPath, 
  179                                        ReferencedAssemblies=Array.copy resolutionEnvironment.referencedAssemblies, 
  180                                        TemporaryFolder=resolutionEnvironment.temporaryFolder, 
  181                                        IsInvalidationSupported=isInvalidationSupported, 
  182                                        IsHostedExecution= isInteractive, 
  183                                        SystemRuntimeAssemblyVersion = systemRuntimeAssemblyVersion)
  184 
  185             protect (fun () -> Activator.CreateInstance(typeProviderImplementationType, [| box e|]) :?> ITypeProvider )
  186 
  187         elif typeProviderImplementationType.GetConstructor [| |] <> null then 
  188             protect (fun () -> Activator.CreateInstance(typeProviderImplementationType) :?> ITypeProvider )
  189 
  190         else
  191             // No appropriate constructor found
  192             raise (TypeProviderError(FSComp.SR.etProviderDoesNotHaveValidConstructor(), typeProviderImplementationType.FullName, m))
  193 
  194     let GetTypeProvidersOfAssembly
  195             (runTimeAssemblyFileName:string, 
  196              ilScopeRefOfRuntimeAssembly:ILScopeRef, 
  197              designTimeAssemblyNameString:string, 
  198              resolutionEnvironment:ResolutionEnvironment, 
  199              isInvalidationSupported:bool, 
  200              isInteractive:bool, 
  201              systemRuntimeContainsType : string -> bool, 
  202              systemRuntimeAssemblyVersion : System.Version, 
  203              m:range) =         
  204 
  205         let providerSpecs = 
  206                 try
  207                     let designTimeAssemblyName = 
  208                         try
  209                             if designTimeAssemblyNameString.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then
  210                                 Some (System.Reflection.AssemblyName (Path.GetFileNameWithoutExtension designTimeAssemblyNameString))
  211                             else
  212                                 Some (System.Reflection.AssemblyName designTimeAssemblyNameString)
  213                         with :? ArgumentException ->
  214                             errorR(Error(FSComp.SR.etInvalidTypeProviderAssemblyName(runTimeAssemblyFileName, designTimeAssemblyNameString), m))
  215                             None
  216 
  217                     [ match designTimeAssemblyName, resolutionEnvironment.outputFile with
  218                       // Check if the attribute is pointing to the file being compiled, in which case ignore it
  219                       // This checks seems like legacy but is included for compat.
  220                       | Some designTimeAssemblyName, Some path when String.Compare(designTimeAssemblyName.Name, Path.GetFileNameWithoutExtension path, StringComparison.OrdinalIgnoreCase) = 0 ->
  221                           ()
  222                       | Some _, _ ->
  223                           for t in GetTypeProviderImplementationTypes (runTimeAssemblyFileName, designTimeAssemblyNameString, m) do
  224                             let resolver = CreateTypeProvider (t, runTimeAssemblyFileName, resolutionEnvironment, isInvalidationSupported, isInteractive, systemRuntimeContainsType, systemRuntimeAssemblyVersion, m)
  225                             match box resolver with 
  226                             | null -> ()
  227                             | _ -> yield (resolver, ilScopeRefOfRuntimeAssembly)
  228                       |   None, _ -> 
  229                           () ]
  230 
  231                 with :? TypeProviderError as tpe ->
  232                     tpe.Iter(fun e -> errorR(NumberedError((e.Number, e.ContextualErrorMessage), m)) )                        
  233                     []
  234 
  235         let providers = Tainted<_>.CreateAll(providerSpecs)
  236 
  237         providers
  238 
  239     let unmarshal (t:Tainted<_>) = t.PUntaintNoFailure id
  240 
  241     /// Try to access a member on a provided type, catching and reporting errors
  242     let TryTypeMember(st:Tainted<_>, fullName, memberName, m, recover, f) =
  243         try
  244             st.PApply (f, m)
  245         with :? TypeProviderError as tpe -> 
  246             tpe.Iter (fun e -> errorR(Error(FSComp.SR.etUnexpectedExceptionFromProvidedTypeMember(fullName, memberName, e.ContextualErrorMessage), m)))
  247             st.PApplyNoFailure(fun _ -> recover)
  248 
  249     /// Try to access a member on a provided type, where the result is an array of values, catching and reporting errors
  250     let TryTypeMemberArray (st:Tainted<_>, fullName, memberName, m, f) =
  251         let result =
  252             try
  253                 st.PApplyArray(f, memberName, m)
  254             with :? TypeProviderError as tpe ->
  255                 tpe.Iter (fun e -> error(Error(FSComp.SR.etUnexpectedExceptionFromProvidedTypeMember(fullName, memberName, e.ContextualErrorMessage), m)))
  256                 [||]
  257 
  258         match result with 
  259         | null -> error(Error(FSComp.SR.etUnexpectedNullFromProvidedTypeMember(fullName, memberName), m)); [||]
  260         | r -> r
  261 
  262     /// Try to access a member on a provided type, catching and reporting errors and checking the result is non-null, 
  263     let TryTypeMemberNonNull (st:Tainted<_>, fullName, memberName, m, recover, f) =
  264         match TryTypeMember(st, fullName, memberName, m, recover, f) with 
  265         | Tainted.Null -> 
  266             errorR(Error(FSComp.SR.etUnexpectedNullFromProvidedTypeMember(fullName, memberName), m)); 
  267             st.PApplyNoFailure(fun _ -> recover)
  268         | r -> r
  269 
  270     /// Try to access a property or method on a provided member, catching and reporting errors
  271     let TryMemberMember (mi:Tainted<_>, typeName, memberName, memberMemberName, m, recover, f) = 
  272         try
  273             mi.PApply (f, m)
  274         with :? TypeProviderError as tpe ->
  275             tpe.Iter (fun e -> errorR(Error(FSComp.SR.etUnexpectedExceptionFromProvidedMemberMember(memberMemberName, typeName, memberName, e.ContextualErrorMessage), m)))
  276             mi.PApplyNoFailure(fun _ -> recover)
  277 
  278     /// Get the string to show for the name of a type provider
  279     let DisplayNameOfTypeProvider(resolver:Tainted<ITypeProvider>, m:range) =
  280         resolver.PUntaint((fun tp -> tp.GetType().Name), m)
  281 
  282     /// Validate a provided namespace name
  283     let ValidateNamespaceName(name, typeProvider:Tainted<ITypeProvider>, m, nsp:string) =
  284         if nsp<>null then // Null namespace designates the global namespace.
  285             if String.IsNullOrWhiteSpace nsp then
  286                 // Empty namespace is not allowed
  287                 errorR(Error(FSComp.SR.etEmptyNamespaceOfTypeNotAllowed(name, typeProvider.PUntaint((fun tp -> tp.GetType().Name), m)), m))
  288             else
  289                 for s in nsp.Split('.') do
  290                     match s.IndexOfAny(PrettyNaming.IllegalCharactersInTypeAndNamespaceNames) with
  291                     | -1 -> ()
  292                     | n -> errorR(Error(FSComp.SR.etIllegalCharactersInNamespaceName(string s.[n], s), m))  
  293 
  294     let bindingFlags =
  295         BindingFlags.DeclaredOnly |||
  296         BindingFlags.Static |||
  297         BindingFlags.Instance |||
  298         BindingFlags.Public
  299 
  300     // NOTE: for the purposes of remapping the closure of generated types, the FullName is sufficient.
  301     // We do _not_ rely on object identity or any other notion of equivalence provided by System.Type
  302     // itself. The mscorlib implementations of System.Type equality relations are not suitable: for
  303     // example RuntimeType overrides the equality relation to be reference equality for the Equals(object)
  304     // override, but the other subtypes of System.Type do not, making the relation non-reflective.
  305     //
  306     // Further, avoiding reliance on canonicalization (UnderlyingSystemType) or System.Type object identity means that 
  307     // providers can implement wrap-and-filter "views" over existing System.Type clusters without needing
  308     // to preserve object identity when presenting the types to the F# compiler.
  309 
  310     let providedSystemTypeComparer = 
  311         let key (ty:System.Type) = (ty.Assembly.FullName, ty.FullName)
  312         { new IEqualityComparer<Type> with 
  313             member __.GetHashCode(ty:Type) = hash (key ty)
  314             member __.Equals(ty1:Type, ty2:Type) = (key ty1 = key ty2) }
  315 
  316     /// The context used to interpret information in the closure of System.Type, System.MethodInfo and other 
  317     /// info objects coming from the type provider.
  318     ///
  319     /// This is the "Type --> Tycon" remapping context of the type. This is only present for generated provided types, and contains
  320     /// all the entries in the remappings for the generative declaration.
  321     ///
  322     /// Laziness is used "to prevent needless computation for every type during remapping". However it
  323     /// appears that the laziness likely serves no purpose and could be safely removed.
  324     type ProvidedTypeContext = 
  325         | NoEntries
  326         | Entries of Dictionary<System.Type, ILTypeRef> * Lazy<Dictionary<System.Type, obj>>
  327 
  328         static member Empty = NoEntries
  329 
  330         static member Create(d1, d2) = Entries(d1, notlazy d2)
  331 
  332         member ctxt.GetDictionaries()  = 
  333             match ctxt with
  334             | NoEntries -> 
  335                 Dictionary<System.Type, ILTypeRef>(providedSystemTypeComparer), Dictionary<System.Type, obj>(providedSystemTypeComparer)
  336             | Entries (lookupILTR, lookupILTCR) ->
  337                 lookupILTR, lookupILTCR.Force()
  338 
  339         member ctxt.TryGetILTypeRef st = 
  340             match ctxt with 
  341             | NoEntries -> None 
  342             | Entries(d, _) -> 
  343                 let mutable res = Unchecked.defaultof<_>
  344                 if d.TryGetValue(st, &res) then Some res else None
  345 
  346         member ctxt.TryGetTyconRef(st) = 
  347             match ctxt with 
  348             | NoEntries -> None 
  349             | Entries(_, d) -> 
  350                 let d = d.Force()
  351                 let mutable res = Unchecked.defaultof<_>
  352                 if d.TryGetValue(st, &res) then Some res else None
  353 
  354         member ctxt.RemapTyconRefs (f:obj->obj) = 
  355             match ctxt with 
  356             | NoEntries -> NoEntries
  357             | Entries(d1, d2) ->
  358                 Entries(d1, lazy (let dict = new Dictionary<System.Type, obj>(providedSystemTypeComparer)
  359                                   for KeyValue (st, tcref) in d2.Force() do dict.Add(st, f tcref)
  360                                   dict))
  361 
  362 #if FX_NO_CUSTOMATTRIBUTEDATA
  363     type CustomAttributeData = Microsoft.FSharp.Core.CompilerServices.IProvidedCustomAttributeData
  364     type CustomAttributeNamedArgument = Microsoft.FSharp.Core.CompilerServices.IProvidedCustomAttributeNamedArgument
  365     type CustomAttributeTypedArgument = Microsoft.FSharp.Core.CompilerServices.IProvidedCustomAttributeTypedArgument
  366 #else
  367     type CustomAttributeData = System.Reflection.CustomAttributeData
  368     type CustomAttributeNamedArgument = System.Reflection.CustomAttributeNamedArgument
  369     type CustomAttributeTypedArgument = System.Reflection.CustomAttributeTypedArgument
  370 #endif
  371 
  372     [<AllowNullLiteral; Sealed>]
  373     type ProvidedType (x:System.Type, ctxt: ProvidedTypeContext) =
  374 #if FX_RESHAPED_REFLECTION
  375         inherit ProvidedMemberInfo(x.GetTypeInfo(), ctxt)
  376 #if FX_NO_CUSTOMATTRIBUTEDATA
  377         let provide () = ProvidedCustomAttributeProvider.Create (fun provider -> provider.GetMemberCustomAttributesData(x.GetTypeInfo()) :> _)
  378 #else
  379         let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.GetTypeInfo().CustomAttributes)
  380 #endif
  381 #else
  382         inherit ProvidedMemberInfo(x, ctxt)
  383 #if FX_NO_CUSTOMATTRIBUTEDATA
  384         let provide () = ProvidedCustomAttributeProvider.Create (fun provider -> provider.GetMemberCustomAttributesData(x) :> _)
  385 #else
  386         let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
  387 #endif
  388 #endif
  389         interface IProvidedCustomAttributeProvider with 
  390             member __.GetHasTypeProviderEditorHideMethodsAttribute(provider) = provide().GetHasTypeProviderEditorHideMethodsAttribute(provider)
  391             member __.GetDefinitionLocationAttribute(provider) = provide().GetDefinitionLocationAttribute(provider)
  392             member __.GetXmlDocAttributes(provider) = provide().GetXmlDocAttributes(provider)
  393         
  394         // The type provider spec distinguishes between 
  395         //   - calls that can be made on provided types (i.e. types given by ReturnType, ParameterType, and generic argument types)
  396         //   - calls that can be made on provided type definitions (types returned by ResolveTypeName, GetTypes etc.)
  397         // Ideally we would enforce this decision structurally by having both ProvidedType and ProvidedTypeDefinition.
  398         // Alternatively we could use assertions to enforce this.
  399 
  400         // Suppress relocation of generated types
  401         member __.IsSuppressRelocate = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.SuppressRelocate)) <> enum 0  
  402         member __.IsErased = (x.Attributes &&& enum (int32 TypeProviderTypeAttributes.IsErased)) <> enum 0  
  403         member __.IsGenericType = x.IsGenericType
  404         member __.Namespace = x.Namespace
  405         member __.FullName = x.FullName
  406         member __.IsArray = x.IsArray
  407         member __.Assembly = x.Assembly |> ProvidedAssembly.Create ctxt
  408         member __.GetInterfaces() = x.GetInterfaces() |> ProvidedType.CreateArray ctxt
  409         member __.GetMethods() = x.GetMethods(bindingFlags) |> ProvidedMethodInfo.CreateArray ctxt
  410         member __.GetEvents() = x.GetEvents(bindingFlags) |> ProvidedEventInfo.CreateArray ctxt
  411         member __.GetEvent nm = x.GetEvent(nm, bindingFlags) |> ProvidedEventInfo.Create ctxt
  412         member __.GetProperties() = x.GetProperties(bindingFlags) |> ProvidedPropertyInfo.CreateArray ctxt
  413         member __.GetProperty nm = x.GetProperty(nm, bindingFlags) |> ProvidedPropertyInfo.Create ctxt
  414         member __.GetConstructors() = x.GetConstructors(bindingFlags) |> ProvidedConstructorInfo.CreateArray ctxt
  415         member __.GetFields() = x.GetFields(bindingFlags) |> ProvidedFieldInfo.CreateArray ctxt
  416         member __.GetField nm = x.GetField(nm, bindingFlags) |> ProvidedFieldInfo.Create ctxt
  417         member __.GetAllNestedTypes() = x.GetNestedTypes(bindingFlags ||| BindingFlags.NonPublic) |> ProvidedType.CreateArray ctxt
  418         member __.GetNestedTypes() = x.GetNestedTypes(bindingFlags) |> ProvidedType.CreateArray ctxt
  419         /// Type.GetNestedType(string) can return null if there is no nested type with given name
  420         member __.GetNestedType nm = x.GetNestedType (nm, bindingFlags) |> ProvidedType.Create ctxt
  421         /// Type.GetGenericTypeDefinition() either returns type or throws exception, null is not permitted
  422         member __.GetGenericTypeDefinition() = x.GetGenericTypeDefinition() |> ProvidedType.CreateWithNullCheck ctxt "GenericTypeDefinition"
  423         /// Type.BaseType can be null when Type is interface or object
  424         member __.BaseType = x.BaseType |> ProvidedType.Create ctxt
  425         member __.GetStaticParameters(provider: ITypeProvider) = provider.GetStaticParameters(x) |> ProvidedParameterInfo.CreateArray ctxt
  426         /// Type.GetElementType can be null if i.e. Type is not array\pointer\byref type
  427         member __.GetElementType() = x.GetElementType() |> ProvidedType.Create ctxt
  428         member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt
  429         member __.ApplyStaticArguments(provider: ITypeProvider, fullTypePathAfterArguments, staticArgs: obj[]) = 
  430             provider.ApplyStaticArguments(x, fullTypePathAfterArguments,  staticArgs) |> ProvidedType.Create ctxt
  431         member __.IsVoid = (typeof<System.Void>.Equals(x))
  432         member __.IsGenericParameter = x.IsGenericParameter
  433         member __.IsValueType = x.IsValueType
  434         member __.IsByRef = x.IsByRef
  435         member __.IsPointer = x.IsPointer
  436         member __.IsPublic = x.IsPublic
  437         member __.IsNestedPublic = x.IsNestedPublic
  438         member __.IsEnum = x.IsEnum
  439         member __.IsClass = x.IsClass
  440         member __.IsSealed = x.IsSealed
  441         member __.IsInterface = x.IsInterface
  442         member __.GetArrayRank() = x.GetArrayRank()
  443         member __.GenericParameterPosition = x.GenericParameterPosition
  444         member __.RawSystemType = x
  445         /// Type.GetEnumUnderlyingType either returns type or raises exception, null is not permitted
  446         member __.GetEnumUnderlyingType() = 
  447             x.GetEnumUnderlyingType() 
  448             |> ProvidedType.CreateWithNullCheck ctxt "EnumUnderlyingType"
  449         static member Create ctxt x = match x with null -> null | t -> ProvidedType (t, ctxt)
  450         static member CreateWithNullCheck ctxt name x = match x with null -> nullArg name | t -> ProvidedType (t, ctxt)
  451         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedType.Create ctxt)
  452         static member CreateNoContext (x:Type) = ProvidedType.Create ProvidedTypeContext.Empty x
  453         static member Void = ProvidedType.CreateNoContext typeof<System.Void>
  454         member __.Handle = x
  455         override __.Equals y = assert false; match y with :? ProvidedType as y -> x.Equals y.Handle | _ -> false
  456         override __.GetHashCode() = assert false; x.GetHashCode()
  457         member __.TryGetILTypeRef() = ctxt.TryGetILTypeRef x
  458         member __.TryGetTyconRef() = ctxt.TryGetTyconRef x
  459         member __.Context = ctxt
  460         static member ApplyContext (pt:ProvidedType, ctxt) = ProvidedType(pt.Handle, ctxt)
  461         static member TaintedEquals (pt1:Tainted<ProvidedType>, pt2:Tainted<ProvidedType>) = 
  462            Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
  463 
  464     and [<AllowNullLiteral>] 
  465         IProvidedCustomAttributeProvider =
  466         abstract GetDefinitionLocationAttribute : provider:ITypeProvider -> (string * int * int) option 
  467         abstract GetXmlDocAttributes : provider:ITypeProvider -> string[]
  468         abstract GetHasTypeProviderEditorHideMethodsAttribute : provider:ITypeProvider -> bool
  469         abstract GetAttributeConstructorArgs: provider:ITypeProvider * attribName:string -> (obj option list * (string * obj option) list) option
  470 
  471     and ProvidedCustomAttributeProvider =
  472         static member Create (attributes :(ITypeProvider -> seq<CustomAttributeData>)) : IProvidedCustomAttributeProvider = 
  473             let (|Member|_|) (s:string) (x: CustomAttributeNamedArgument) = if x.MemberName = s then Some x.TypedValue else None
  474             let (|Arg|_|) (x: CustomAttributeTypedArgument) = match x.Value with null -> None | v -> Some v
  475             let findAttribByName tyFullName (a:CustomAttributeData) = (a.Constructor.DeclaringType.FullName = tyFullName)  
  476             let findAttrib (ty:System.Type) a = findAttribByName ty.FullName a
  477             { new IProvidedCustomAttributeProvider with 
  478                   member __.GetAttributeConstructorArgs (provider, attribName) = 
  479                       attributes(provider) 
  480                         |> Seq.tryFind (findAttribByName  attribName)  
  481                         |> Option.map (fun a -> 
  482                             let ctorArgs = 
  483                                 a.ConstructorArguments 
  484                                 |> Seq.toList 
  485                                 |> List.map (function Arg null -> None | Arg obj -> Some obj | _ -> None)
  486                             let namedArgs = 
  487                                 a.NamedArguments 
  488                                 |> Seq.toList 
  489                                 |> List.map (fun arg -> arg.MemberName, match arg.TypedValue with Arg null -> None | Arg obj -> Some obj | _ -> None)
  490                             ctorArgs, namedArgs)
  491 
  492                   member __.GetHasTypeProviderEditorHideMethodsAttribute provider = 
  493                       attributes(provider) 
  494                         |> Seq.exists (findAttrib typeof<Microsoft.FSharp.Core.CompilerServices.TypeProviderEditorHideMethodsAttribute>) 
  495 
  496                   member __.GetDefinitionLocationAttribute(provider) = 
  497                       attributes(provider) 
  498                         |> Seq.tryFind (findAttrib  typeof<Microsoft.FSharp.Core.CompilerServices.TypeProviderDefinitionLocationAttribute>)  
  499                         |> Option.map (fun a -> 
  500                                (defaultArg (a.NamedArguments |> Seq.tryPick (function Member "FilePath" (Arg (:? string as v)) -> Some v | _ -> None)) null, 
  501                                 defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Line" (Arg (:? int as v)) -> Some v | _ -> None)) 0, 
  502                                 defaultArg (a.NamedArguments |> Seq.tryPick (function Member "Column" (Arg (:? int as v)) -> Some v | _ -> None)) 0))
  503 
  504                   member __.GetXmlDocAttributes(provider) = 
  505                       attributes(provider) 
  506                         |> Seq.choose (fun a -> 
  507                              if findAttrib  typeof<Microsoft.FSharp.Core.CompilerServices.TypeProviderXmlDocAttribute> a then 
  508                                 match a.ConstructorArguments |> Seq.toList with 
  509                                 | [ Arg(:? string as s) ] -> Some s
  510                                 | _ -> None
  511                              else 
  512                                 None) 
  513                         |> Seq.toArray  }
  514 
  515     and [<AllowNullLiteral; AbstractClass>] 
  516         ProvidedMemberInfo (x: System.Reflection.MemberInfo, ctxt) = 
  517 #if FX_NO_CUSTOMATTRIBUTEDATA
  518         let provide () = ProvidedCustomAttributeProvider.Create (fun provider -> provider.GetMemberCustomAttributesData(x) :> _)
  519 #else
  520         let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
  521 #endif
  522 
  523         member __.Name = x.Name
  524         /// DeclaringType can be null if MemberInfo belongs to Module, not to Type
  525         member __.DeclaringType = ProvidedType.Create ctxt x.DeclaringType
  526         interface IProvidedCustomAttributeProvider with 
  527             member __.GetHasTypeProviderEditorHideMethodsAttribute(provider) = provide().GetHasTypeProviderEditorHideMethodsAttribute(provider)
  528             member __.GetDefinitionLocationAttribute(provider) = provide().GetDefinitionLocationAttribute(provider)
  529             member __.GetXmlDocAttributes(provider) = provide().GetXmlDocAttributes(provider)
  530             member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName)
  531 
  532     and [<AllowNullLiteral; Sealed>] 
  533         ProvidedParameterInfo (x: System.Reflection.ParameterInfo, ctxt) = 
  534 #if FX_NO_CUSTOMATTRIBUTEDATA
  535         let provide () = ProvidedCustomAttributeProvider.Create (fun provider -> provider.GetParameterCustomAttributesData(x) :> _)
  536 #else
  537         let provide () = ProvidedCustomAttributeProvider.Create (fun _provider -> x.CustomAttributes)
  538 #endif
  539         member __.Name = x.Name
  540         member __.IsOut = x.IsOut
  541 #if FX_NO_ISIN_ON_PARAMETER_INFO 
  542         member __.IsIn = not x.IsOut
  543 #else
  544         member __.IsIn = x.IsIn
  545 #endif
  546         member __.IsOptional = x.IsOptional
  547         member __.RawDefaultValue = x.RawDefaultValue
  548         member __.HasDefaultValue = x.Attributes.HasFlag(System.Reflection.ParameterAttributes.HasDefault)
  549         /// ParameterInfo.ParameterType cannot be null
  550         member __.ParameterType = ProvidedType.CreateWithNullCheck ctxt "ParameterType" x.ParameterType 
  551         static member Create ctxt x = match x with null -> null | t -> ProvidedParameterInfo (t, ctxt)
  552         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedParameterInfo.Create ctxt)  // TODO null wrong?
  553         interface IProvidedCustomAttributeProvider with 
  554             member __.GetHasTypeProviderEditorHideMethodsAttribute(provider) = provide().GetHasTypeProviderEditorHideMethodsAttribute(provider)
  555             member __.GetDefinitionLocationAttribute(provider) = provide().GetDefinitionLocationAttribute(provider)
  556             member __.GetXmlDocAttributes(provider) = provide().GetXmlDocAttributes(provider)
  557             member __.GetAttributeConstructorArgs (provider, attribName) = provide().GetAttributeConstructorArgs (provider, attribName)
  558         member __.Handle = x
  559         override __.Equals y = assert false; match y with :? ProvidedParameterInfo as y -> x.Equals y.Handle | _ -> false
  560         override __.GetHashCode() = assert false; x.GetHashCode()
  561 
  562     and [<AllowNullLiteral; Sealed>] 
  563         ProvidedAssembly (x: System.Reflection.Assembly, _ctxt) = 
  564         member __.GetName() = x.GetName()
  565         member __.FullName = x.FullName
  566         member __.GetManifestModuleContents(provider: ITypeProvider) = provider.GetGeneratedAssemblyContents(x)
  567         static member Create ctxt x = match x with null -> null | t -> ProvidedAssembly (t, ctxt)
  568         member __.Handle = x
  569         override __.Equals y = assert false; match y with :? ProvidedAssembly as y -> x.Equals y.Handle | _ -> false
  570         override __.GetHashCode() = assert false; x.GetHashCode()
  571 
  572     and [<AllowNullLiteral; AbstractClass>] 
  573         ProvidedMethodBase (x: System.Reflection.MethodBase, ctxt) = 
  574         inherit ProvidedMemberInfo(x, ctxt)
  575         member __.Context = ctxt
  576         member __.IsGenericMethod = x.IsGenericMethod
  577         member __.IsStatic  = x.IsStatic
  578         member __.IsFamily  = x.IsFamily
  579         member __.IsFamilyOrAssembly = x.IsFamilyOrAssembly
  580         member __.IsFamilyAndAssembly = x.IsFamilyAndAssembly
  581         member __.IsVirtual  = x.IsVirtual
  582         member __.IsFinal = x.IsFinal
  583         member __.IsPublic = x.IsPublic
  584         member __.IsAbstract  = x.IsAbstract
  585         member __.IsHideBySig = x.IsHideBySig
  586         member __.IsConstructor  = x.IsConstructor
  587         member __.GetParameters() = x.GetParameters() |> ProvidedParameterInfo.CreateArray ctxt 
  588         member __.GetGenericArguments() = x.GetGenericArguments() |> ProvidedType.CreateArray ctxt
  589         member __.Handle = x
  590         static member TaintedGetHashCode (x:Tainted<ProvidedMethodBase>) =            
  591            Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) 
  592         static member TaintedEquals (pt1:Tainted<ProvidedMethodBase>, pt2:Tainted<ProvidedMethodBase>) = 
  593            Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
  594 
  595         member __.GetStaticParametersForMethod(provider: ITypeProvider) = 
  596             let bindingFlags = BindingFlags.Instance ||| BindingFlags.NonPublic ||| BindingFlags.Public 
  597 
  598             let staticParams = 
  599                 match provider with 
  600                 | :? ITypeProvider2 as itp2 -> 
  601                     itp2.GetStaticParametersForMethod(x)  
  602                 | _ -> 
  603                     // To allow a type provider to depend only on FSharp.Core 4.3.0.0, it can alternatively implement an appropriate method called GetStaticParametersForMethod
  604                     let meth = provider.GetType().GetMethod( "GetStaticParametersForMethod", bindingFlags, null, [| typeof<System.Reflection.MethodBase> |], null)  
  605                     if isNull meth then [| |] else
  606                     let paramsAsObj = 
  607                         try meth.Invoke(provider, bindingFlags ||| BindingFlags.InvokeMethod, null, [| box x |], null) 
  608                         with err -> raise (StripException (StripException err))
  609                     paramsAsObj :?> System.Reflection.ParameterInfo[] 
  610 
  611             staticParams |> ProvidedParameterInfo.CreateArray ctxt
  612 
  613         member __.ApplyStaticArgumentsForMethod(provider: ITypeProvider, fullNameAfterArguments:string, staticArgs: obj[]) = 
  614             let bindingFlags = BindingFlags.Instance ||| BindingFlags.Public ||| BindingFlags.InvokeMethod
  615 
  616             let mb = 
  617                 match provider with 
  618                 | :? ITypeProvider2 as itp2 -> 
  619                     itp2.ApplyStaticArgumentsForMethod(x, fullNameAfterArguments, staticArgs)  
  620                 | _ -> 
  621                     // To allow a type provider to depend only on FSharp.Core 4.3.0.0, it can alternatively implement a method called GetStaticParametersForMethod
  622                     let meth = provider.GetType().GetMethod( "ApplyStaticArgumentsForMethod", bindingFlags, null, [| typeof<System.Reflection.MethodBase>; typeof<string>; typeof<obj[]> |], null)  
  623                     match meth with 
  624                     | null -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented())
  625                     | _ -> 
  626                     let mbAsObj = 
  627                        try meth.Invoke(provider, bindingFlags ||| BindingFlags.InvokeMethod, null, [| box x; box fullNameAfterArguments; box staticArgs  |], null) 
  628                        with err -> raise (StripException (StripException err))
  629 
  630                     match mbAsObj with 
  631                     | :? System.Reflection.MethodBase as mb -> mb
  632                     | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented())
  633             match mb with 
  634             | :? System.Reflection.MethodInfo as mi -> (mi |> ProvidedMethodInfo.Create ctxt : ProvidedMethodInfo) :> ProvidedMethodBase
  635             | :? System.Reflection.ConstructorInfo as ci -> (ci |> ProvidedConstructorInfo.Create ctxt : ProvidedConstructorInfo) :> ProvidedMethodBase
  636             | _ -> failwith (FSComp.SR.estApplyStaticArgumentsForMethodNotImplemented())
  637 
  638 
  639     and [<AllowNullLiteral; Sealed>] 
  640         ProvidedFieldInfo (x: System.Reflection.FieldInfo, ctxt) = 
  641         inherit ProvidedMemberInfo(x, ctxt)
  642         static member Create ctxt x = match x with null -> null | t -> ProvidedFieldInfo (t, ctxt)
  643         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedFieldInfo.Create ctxt)
  644         member __.IsInitOnly = x.IsInitOnly
  645         member __.IsStatic = x.IsStatic
  646         member __.IsSpecialName = x.IsSpecialName
  647         member __.IsLiteral = x.IsLiteral
  648         member __.GetRawConstantValue() = x.GetRawConstantValue()
  649         /// FieldInfo.FieldType cannot be null
  650         member __.FieldType = x.FieldType |> ProvidedType.CreateWithNullCheck ctxt "FieldType" 
  651         member __.Handle = x
  652         member __.IsPublic = x.IsPublic
  653         member __.IsFamily = x.IsFamily
  654         member __.IsPrivate = x.IsPrivate
  655         member __.IsFamilyOrAssembly = x.IsFamilyOrAssembly
  656         member __.IsFamilyAndAssembly = x.IsFamilyAndAssembly
  657         override __.Equals y = assert false; match y with :? ProvidedFieldInfo as y -> x.Equals y.Handle | _ -> false
  658         override __.GetHashCode() = assert false; x.GetHashCode()
  659         static member TaintedEquals (pt1:Tainted<ProvidedFieldInfo>, pt2:Tainted<ProvidedFieldInfo>) = 
  660            Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
  661 
  662 
  663 
  664     and [<AllowNullLiteral; Sealed>] 
  665         ProvidedMethodInfo (x: System.Reflection.MethodInfo, ctxt) = 
  666         inherit ProvidedMethodBase(x, ctxt)
  667 
  668         member __.ReturnType = x.ReturnType |> ProvidedType.CreateWithNullCheck ctxt "ReturnType"
  669 
  670         static member Create ctxt x = match x with null -> null | t -> ProvidedMethodInfo (t, ctxt)
  671 
  672         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedMethodInfo.Create ctxt)
  673         member __.Handle = x
  674 #if !FX_NO_REFLECTION_METADATA_TOKENS
  675         member __.MetadataToken = x.MetadataToken
  676 #endif
  677         override __.Equals y = assert false; match y with :? ProvidedMethodInfo as y -> x.Equals y.Handle | _ -> false
  678         override __.GetHashCode() = assert false; x.GetHashCode()
  679 
  680     and [<AllowNullLiteral; Sealed>] 
  681         ProvidedPropertyInfo (x: System.Reflection.PropertyInfo, ctxt) = 
  682         inherit ProvidedMemberInfo(x, ctxt)
  683         member __.GetGetMethod() = x.GetGetMethod() |> ProvidedMethodInfo.Create ctxt
  684         member __.GetSetMethod() = x.GetSetMethod() |> ProvidedMethodInfo.Create ctxt
  685         member __.CanRead = x.CanRead
  686         member __.CanWrite = x.CanWrite
  687         member __.GetIndexParameters() = x.GetIndexParameters() |> ProvidedParameterInfo.CreateArray ctxt
  688         /// PropertyInfo.PropertyType cannot be null
  689         member __.PropertyType = x.PropertyType |> ProvidedType.CreateWithNullCheck ctxt "PropertyType"
  690         static member Create ctxt x = match x with null -> null | t -> ProvidedPropertyInfo (t, ctxt)
  691         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedPropertyInfo.Create ctxt)
  692         member __.Handle = x
  693         override __.Equals y = assert false; match y with :? ProvidedPropertyInfo as y -> x.Equals y.Handle | _ -> false
  694         override __.GetHashCode() = assert false; x.GetHashCode()
  695         static member TaintedGetHashCode (x:Tainted<ProvidedPropertyInfo>) = 
  696            Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) 
  697         static member TaintedEquals (pt1:Tainted<ProvidedPropertyInfo>, pt2:Tainted<ProvidedPropertyInfo>) = 
  698            Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
  699 
  700     and [<AllowNullLiteral; Sealed>] 
  701         ProvidedEventInfo (x: System.Reflection.EventInfo, ctxt) = 
  702         inherit ProvidedMemberInfo(x, ctxt)
  703         member __.GetAddMethod() = x.GetAddMethod() |> ProvidedMethodInfo.Create  ctxt
  704         member __.GetRemoveMethod() = x.GetRemoveMethod() |> ProvidedMethodInfo.Create ctxt
  705         /// EventInfo.EventHandlerType cannot be null
  706         member __.EventHandlerType = x.EventHandlerType |> ProvidedType.CreateWithNullCheck ctxt "EventHandlerType"
  707         static member Create ctxt x = match x with null -> null | t -> ProvidedEventInfo (t, ctxt)
  708         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedEventInfo.Create ctxt)
  709         member __.Handle = x
  710         override __.Equals y = assert false; match y with :? ProvidedEventInfo as y -> x.Equals y.Handle | _ -> false
  711         override __.GetHashCode() = assert false; x.GetHashCode()
  712         static member TaintedGetHashCode (x:Tainted<ProvidedEventInfo>) = 
  713            Tainted.GetHashCodeTainted (x.PApplyNoFailure(fun st -> (st.Name, st.DeclaringType.Assembly.FullName, st.DeclaringType.FullName))) 
  714         static member TaintedEquals (pt1:Tainted<ProvidedEventInfo>, pt2:Tainted<ProvidedEventInfo>) = 
  715            Tainted.EqTainted (pt1.PApplyNoFailure(fun st -> st.Handle)) (pt2.PApplyNoFailure(fun st -> st.Handle))
  716 
  717     and [<AllowNullLiteral; Sealed>] 
  718         ProvidedConstructorInfo (x: System.Reflection.ConstructorInfo, ctxt) = 
  719         inherit ProvidedMethodBase(x, ctxt)
  720         static member Create ctxt x = match x with null -> null | t -> ProvidedConstructorInfo (t, ctxt)
  721         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedConstructorInfo.Create ctxt)
  722         member __.Handle = x
  723         override __.Equals y = assert false; match y with :? ProvidedConstructorInfo as y -> x.Equals y.Handle | _ -> false
  724         override __.GetHashCode() = assert false; x.GetHashCode()
  725 
  726     [<RequireQualifiedAccess; Class; AllowNullLiteral; Sealed>]
  727     type ProvidedExpr (x:Quotations.Expr, ctxt) =
  728         member __.Type = x.Type |> ProvidedType.Create ctxt
  729         member __.Handle = x
  730         member __.Context = ctxt
  731         member __.UnderlyingExpressionString = x.ToString()
  732         static member Create ctxt t = match box t with null -> null | _ -> ProvidedExpr (t, ctxt)
  733         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedExpr.Create ctxt)
  734         override __.Equals y = match y with :? ProvidedExpr as y -> x.Equals y.Handle | _ -> false
  735         override __.GetHashCode() = x.GetHashCode()
  736 
  737     [<RequireQualifiedAccess; Class; AllowNullLiteral; Sealed>]
  738     type ProvidedVar (x:Quotations.Var, ctxt) =
  739         member __.Type = x.Type |> ProvidedType.Create ctxt
  740         member __.Name = x.Name
  741         member __.IsMutable = x.IsMutable
  742         member __.Handle = x
  743         member __.Context = ctxt
  744         static member Create ctxt t = match box t with null -> null | _ -> ProvidedVar (t, ctxt)
  745         static member Fresh (nm, ty:ProvidedType) = ProvidedVar.Create ty.Context (new Quotations.Var(nm, ty.Handle))
  746         static member CreateArray ctxt xs = match xs with null -> null | _ -> xs |> Array.map (ProvidedVar.Create ctxt)
  747         override __.Equals y = match y with :? ProvidedVar as y -> x.Equals y.Handle | _ -> false
  748         override __.GetHashCode() = x.GetHashCode()
  749 
  750 
  751     /// Detect a provided new-object expression 
  752     let (|ProvidedNewObjectExpr|_|) (x:ProvidedExpr) = 
  753         match x.Handle with 
  754         |  Quotations.Patterns.NewObject(ctor, args)  -> 
  755             Some (ProvidedConstructorInfo.Create x.Context ctor, [| for a in args -> ProvidedExpr.Create x.Context a |])
  756         | _ -> None
  757 
  758     /// Detect a provided while-loop expression 
  759     let (|ProvidedWhileLoopExpr|_|) (x:ProvidedExpr) = 
  760         match x.Handle with 
  761         |  Quotations.Patterns.WhileLoop(guardExpr, bodyExpr)  -> 
  762             Some (ProvidedExpr.Create x.Context guardExpr, ProvidedExpr.Create x.Context bodyExpr)
  763         | _ -> None
  764 
  765     /// Detect a provided new-delegate expression 
  766     let (|ProvidedNewDelegateExpr|_|) (x:ProvidedExpr) = 
  767         match x.Handle with 
  768         |  Quotations.Patterns.NewDelegate(ty, vs, expr)  -> 
  769             Some (ProvidedType.Create x.Context ty, ProvidedVar.CreateArray x.Context (List.toArray vs), ProvidedExpr.Create x.Context expr)
  770         | _ -> None
  771 
  772     /// Detect a provided call expression 
  773     let (|ProvidedCallExpr|_|) (x:ProvidedExpr) = 
  774         match x.Handle with 
  775         |  Quotations.Patterns.Call(objOpt, meth, args) -> 
  776             Some ((match objOpt with None -> None | Some obj -> Some (ProvidedExpr.Create  x.Context obj)), 
  777                   ProvidedMethodInfo.Create x.Context meth, 
  778                   [| for a in args -> ProvidedExpr.Create  x.Context a |])
  779         | _ -> None
  780 
  781     /// Detect a provided default-value expression 
  782     let (|ProvidedDefaultExpr|_|) (x:ProvidedExpr) = 
  783         match x.Handle with 
  784         |  Quotations.Patterns.DefaultValue ty   -> Some (ProvidedType.Create x.Context ty)
  785         | _ -> None
  786 
  787     /// Detect a provided constant expression 
  788     let (|ProvidedConstantExpr|_|) (x:ProvidedExpr) = 
  789         match x.Handle with 
  790         |  Quotations.Patterns.Value(obj, ty)   -> Some (obj, ProvidedType.Create x.Context ty)
  791         | _ -> None
  792 
  793     /// Detect a provided type-as expression 
  794     let (|ProvidedTypeAsExpr|_|) (x:ProvidedExpr) = 
  795         match x.Handle with 
  796         |  Quotations.Patterns.Coerce(arg, ty) -> Some (ProvidedExpr.Create x.Context arg, ProvidedType.Create  x.Context ty)
  797         | _ -> None
  798 
  799     /// Detect a provided new-tuple expression 
  800     let (|ProvidedNewTupleExpr|_|) (x:ProvidedExpr) = 
  801         match x.Handle with 
  802         |  Quotations.Patterns.NewTuple(args) -> Some (ProvidedExpr.CreateArray x.Context (Array.ofList args))
  803         | _ -> None
  804 
  805     /// Detect a provided tuple-get expression 
  806     let (|ProvidedTupleGetExpr|_|) (x:ProvidedExpr) = 
  807         match x.Handle with 
  808         |  Quotations.Patterns.TupleGet(arg, n) -> Some (ProvidedExpr.Create x.Context arg, n)
  809         | _ -> None
  810 
  811     /// Detect a provided new-array expression 
  812     let (|ProvidedNewArrayExpr|_|) (x:ProvidedExpr) = 
  813         match x.Handle with 
  814         |  Quotations.Patterns.NewArray(ty, args) -> Some (ProvidedType.Create  x.Context ty, ProvidedExpr.CreateArray x.Context (Array.ofList args))
  815         | _ -> None
  816 
  817     /// Detect a provided sequential expression 
  818     let (|ProvidedSequentialExpr|_|) (x:ProvidedExpr) = 
  819         match x.Handle with 
  820         |  Quotations.Patterns.Sequential(e1, e2) -> Some (ProvidedExpr.Create x.Context e1, ProvidedExpr.Create x.Context e2)
  821         | _ -> None
  822 
  823     /// Detect a provided lambda expression 
  824     let (|ProvidedLambdaExpr|_|) (x:ProvidedExpr) = 
  825         match x.Handle with 
  826         |  Quotations.Patterns.Lambda(v, body) -> Some (ProvidedVar.Create x.Context v,  ProvidedExpr.Create x.Context body)
  827         | _ -> None
  828 
  829     /// Detect a provided try/finally expression 
  830     let (|ProvidedTryFinallyExpr|_|) (x:ProvidedExpr) = 
  831         match x.Handle with 
  832         |  Quotations.Patterns.TryFinally(b1, b2) -> Some (ProvidedExpr.Create x.Context b1, ProvidedExpr.Create x.Context b2)
  833         | _ -> None
  834 
  835     /// Detect a provided try/with expression 
  836     let (|ProvidedTryWithExpr|_|) (x:ProvidedExpr) = 
  837         match x.Handle with 
  838         |  Quotations.Patterns.TryWith(b, v1, e1, v2, e2) -> Some (ProvidedExpr.Create x.Context b, ProvidedVar.Create x.Context v1, ProvidedExpr.Create x.Context e1, ProvidedVar.Create x.Context v2, ProvidedExpr.Create x.Context e2)
  839         | _ -> None
  840 
  841 #if PROVIDED_ADDRESS_OF
  842     let (|ProvidedAddressOfExpr|_|) (x:ProvidedExpr) = 
  843         match x.Handle with 
  844         |  Quotations.Patterns.AddressOf(e) -> Some (ProvidedExpr.Create x.Context e)
  845         | _ -> None
  846 #endif
  847 
  848     /// Detect a provided type-test expression 
  849     let (|ProvidedTypeTestExpr|_|) (x:ProvidedExpr) = 
  850         match x.Handle with 
  851         |  Quotations.Patterns.TypeTest(e, ty) -> Some (ProvidedExpr.Create x.Context e, ProvidedType.Create x.Context ty)
  852         | _ -> None
  853 
  854     /// Detect a provided 'let' expression 
  855     let (|ProvidedLetExpr|_|) (x:ProvidedExpr) = 
  856         match x.Handle with 
  857         |  Quotations.Patterns.Let(v, e, b) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e, ProvidedExpr.Create x.Context b)
  858         | _ -> None
  859 
  860 
  861     /// Detect a provided expression which is a for-loop over integers
  862     let (|ProvidedForIntegerRangeLoopExpr|_|) (x:ProvidedExpr) = 
  863         match x.Handle with 
  864         |  Quotations.Patterns.ForIntegerRangeLoop (v, e1, e2, e3) -> 
  865             Some (ProvidedVar.Create x.Context v, 
  866                   ProvidedExpr.Create x.Context e1, 
  867                   ProvidedExpr.Create x.Context e2, 
  868                   ProvidedExpr.Create x.Context e3)
  869         | _ -> None
  870 
  871     /// Detect a provided 'set variable' expression 
  872     let (|ProvidedVarSetExpr|_|) (x:ProvidedExpr) = 
  873         match x.Handle with 
  874         |  Quotations.Patterns.VarSet(v, e) -> Some (ProvidedVar.Create x.Context v, ProvidedExpr.Create x.Context e)
  875         | _ -> None
  876 
  877     /// Detect a provided 'IfThenElse' expression 
  878     let (|ProvidedIfThenElseExpr|_|) (x:ProvidedExpr) = 
  879         match x.Handle with 
  880         |  Quotations.Patterns.IfThenElse(g, t, e) ->  Some (ProvidedExpr.Create x.Context g, ProvidedExpr.Create x.Context t, ProvidedExpr.Create x.Context e)
  881         | _ -> None
  882 
  883     /// Detect a provided 'Var' expression 
  884     let (|ProvidedVarExpr|_|) (x:ProvidedExpr) = 
  885         match x.Handle with 
  886         |  Quotations.Patterns.Var v  -> Some (ProvidedVar.Create x.Context v)
  887         | _ -> None
  888 
  889     /// Get the provided invoker expression for a particular use of a method.
  890     let GetInvokerExpression (provider: ITypeProvider, methodBase: ProvidedMethodBase, paramExprs: ProvidedVar[]) = 
  891         provider.GetInvokerExpression(methodBase.Handle, [| for p in paramExprs -> Quotations.Expr.Var(p.Handle) |]) |> ProvidedExpr.Create methodBase.Context
  892 
  893     /// Compute the Name or FullName property of a provided type, reporting appropriate errors
  894     let CheckAndComputeProvidedNameProperty(m, st:Tainted<ProvidedType>, proj, propertyString) =
  895         let name = 
  896             try st.PUntaint(proj, m) 
  897             with :? TypeProviderError as tpe -> 
  898                 let newError = tpe.MapText((fun msg -> FSComp.SR.etProvidedTypeWithNameException(propertyString, msg)), st.TypeProviderDesignation, m)
  899                 raise newError
  900         if String.IsNullOrEmpty name then
  901             raise (TypeProviderError(FSComp.SR.etProvidedTypeWithNullOrEmptyName(propertyString), st.TypeProviderDesignation, m))
  902         name
  903 
  904     /// Verify that this type provider has supported attributes
  905     let ValidateAttributesOfProvidedType (m, st:Tainted<ProvidedType>) =         
  906         let fullName = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.FullName), "FullName")
  907         if TryTypeMember(st, fullName, "IsGenericType", m, false, fun st->st.IsGenericType) |> unmarshal then  
  908             errorR(Error(FSComp.SR.etMustNotBeGeneric(fullName), m))  
  909         if TryTypeMember(st, fullName, "IsArray", m, false, fun st->st.IsArray) |> unmarshal then 
  910             errorR(Error(FSComp.SR.etMustNotBeAnArray(fullName), m))  
  911         TryTypeMemberNonNull(st, fullName, "GetInterfaces", m, [||], fun st -> st.GetInterfaces()) |> ignore
  912 
  913 
  914     /// Verify that a provided type has the expected name
  915     let ValidateExpectedName m expectedPath expectedName (st : Tainted<ProvidedType>) =
  916         let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name")
  917         if name <> expectedName then
  918             raise (TypeProviderError(FSComp.SR.etProvidedTypeHasUnexpectedName(expectedName, name), st.TypeProviderDesignation, m))
  919 
  920         let namespaceName = TryTypeMember(st, name, "Namespace", m, "", fun st -> st.Namespace) |> unmarshal
  921         let rec declaringTypes (st:Tainted<ProvidedType>) accu =
  922             match TryTypeMember(st, name, "DeclaringType", m, null, fun st -> st.DeclaringType) with
  923             |   Tainted.Null -> accu
  924             |   dt -> declaringTypes dt (CheckAndComputeProvidedNameProperty(m, dt, (fun dt -> dt.Name), "Name")::accu)
  925         let path = 
  926             [|  match namespaceName with 
  927                 | null -> ()
  928                 | _ -> yield! namespaceName.Split([|'.'|])
  929                 yield! declaringTypes st [] |]
  930         
  931         if path <> expectedPath then
  932             let expectedPath = String.Join(".", expectedPath)
  933             let path = String.Join(".", path)
  934             errorR(Error(FSComp.SR.etProvidedTypeHasUnexpectedPath(expectedPath, path), m))
  935 
  936     /// Eagerly validate a range of conditions on a provided type, after static instantiation (if any) has occurred
  937     let ValidateProvidedTypeAfterStaticInstantiation(m, st:Tainted<ProvidedType>, expectedPath : string[], expectedName : string) = 
  938         // Do all the calling into st up front with recovery
  939         let fullName, namespaceName, usedMembers =
  940             let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name")
  941             let namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
  942             let fullName = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName) |> unmarshal
  943             ValidateExpectedName m expectedPath expectedName st
  944             // Must be able to call (GetMethods|GetEvents|GetPropeties|GetNestedTypes|GetConstructors)(bindingFlags).
  945             let usedMembers : Tainted<ProvidedMemberInfo>[] = 
  946                 // These are the members the compiler will actually use
  947                 [| for x in TryTypeMemberArray(st, fullName, "GetMethods", m, fun st -> st.GetMethods()) -> x.Coerce(m)
  948                    for x in TryTypeMemberArray(st, fullName, "GetEvents", m, fun st -> st.GetEvents()) -> x.Coerce(m)
  949                    for x in TryTypeMemberArray(st, fullName, "GetFields", m, fun st -> st.GetFields()) -> x.Coerce(m)
  950                    for x in TryTypeMemberArray(st, fullName, "GetProperties", m, fun st -> st.GetProperties()) -> x.Coerce(m)
  951                    // These will be validated on-demand
  952                    //for x in TryTypeMemberArray(st, fullName, "GetNestedTypes", m, fun st -> st.GetNestedTypes(bindingFlags)) -> x.Coerce()
  953                    for x in TryTypeMemberArray(st, fullName, "GetConstructors", m, fun st -> st.GetConstructors()) -> x.Coerce(m) |]
  954             fullName, namespaceName, usedMembers       
  955 
  956         // We scrutinize namespaces for invalid characters on open, but this provides better diagnostics
  957         ValidateNamespaceName(fullName, st.TypeProvider, m, namespaceName)
  958 
  959         ValidateAttributesOfProvidedType(m, st)
  960 
  961         // Those members must have this type.
  962         // This needs to be a *shallow* exploration. Otherwise, as in Freebase sample the entire database could be explored.
  963         for mi in usedMembers do
  964             match mi with 
  965             | Tainted.Null -> errorR(Error(FSComp.SR.etNullMember(fullName), m))  
  966             | _ -> 
  967                 let memberName = TryMemberMember(mi, fullName, "Name", "Name", m, "invalid provided type member name", fun mi -> mi.Name) |> unmarshal
  968                 if String.IsNullOrEmpty(memberName) then 
  969                     errorR(Error(FSComp.SR.etNullOrEmptyMemberName(fullName), m))  
  970                 else 
  971                     let miDeclaringType = TryMemberMember(mi, fullName, memberName, "DeclaringType", m, ProvidedType.CreateNoContext(typeof<obj>), fun mi -> mi.DeclaringType)
  972                     match miDeclaringType with 
  973                         // Generated nested types may have null DeclaringType
  974                     | Tainted.Null when (mi.OfType<ProvidedType>().IsSome) -> ()
  975                     | Tainted.Null -> 
  976                         errorR(Error(FSComp.SR.etNullMemberDeclaringType(fullName, memberName), m))   
  977                     | _ ->     
  978                         let miDeclaringTypeFullName = 
  979                             TryMemberMember(miDeclaringType, fullName, memberName, "FullName", m, "invalid declaring type full name", fun miDeclaringType -> miDeclaringType.FullName)
  980                             |> unmarshal
  981                         if not (ProvidedType.TaintedEquals (st, miDeclaringType)) then 
  982                             errorR(Error(FSComp.SR.etNullMemberDeclaringTypeDifferentFromProvidedType(fullName, memberName, miDeclaringTypeFullName), m))   
  983 
  984                     match mi.OfType<ProvidedMethodInfo>() with
  985                     | Some mi ->
  986                         let isPublic = TryMemberMember(mi, fullName, memberName, "IsPublic", m, true, fun mi->mi.IsPublic) |> unmarshal
  987                         let isGenericMethod = TryMemberMember(mi, fullName, memberName, "IsGenericMethod", m, true, fun mi->mi.IsGenericMethod) |> unmarshal
  988                         if not isPublic || isGenericMethod then
  989                             errorR(Error(FSComp.SR.etMethodHasRequirements(fullName, memberName), m))   
  990                     |   None ->
  991                     match mi.OfType<ProvidedType>() with
  992                     |   Some subType -> ValidateAttributesOfProvidedType(m, subType)
  993                     |   None ->
  994                     match mi.OfType<ProvidedPropertyInfo>() with
  995                     | Some pi ->
  996                         // Property must have a getter or setter
  997                         // TODO: Property must be public etc.
  998                         let expectRead =
  999                              match TryMemberMember(pi, fullName, memberName, "GetGetMethod", m, null, fun pi -> pi.GetGetMethod()) with 
 1000                              |  Tainted.Null -> false 
 1001                              | _ -> true
 1002                         let expectWrite = 
 1003                             match TryMemberMember(pi, fullName, memberName, "GetSetMethod", m, null, fun pi-> pi.GetSetMethod()) with 
 1004                             |   Tainted.Null -> false 
 1005                             |   _ -> true
 1006                         let canRead = TryMemberMember(pi, fullName, memberName, "CanRead", m, expectRead, fun pi-> pi.CanRead) |> unmarshal
 1007                         let canWrite = TryMemberMember(pi, fullName, memberName, "CanWrite", m, expectWrite, fun pi-> pi.CanWrite) |> unmarshal
 1008                         match expectRead, canRead with
 1009                         | false, false | true, true-> ()
 1010                         | false, true -> errorR(Error(FSComp.SR.etPropertyCanReadButHasNoGetter(memberName, fullName), m))   
 1011                         | true, false -> errorR(Error(FSComp.SR.etPropertyHasGetterButNoCanRead(memberName, fullName), m))   
 1012                         match expectWrite, canWrite with
 1013                         | false, false | true, true-> ()
 1014                         | false, true -> errorR(Error(FSComp.SR.etPropertyCanWriteButHasNoSetter(memberName, fullName), m))   
 1015                         | true, false -> errorR(Error(FSComp.SR.etPropertyHasSetterButNoCanWrite(memberName, fullName), m))   
 1016                         if not canRead && not canWrite then 
 1017                             errorR(Error(FSComp.SR.etPropertyNeedsCanWriteOrCanRead(memberName, fullName), m))   
 1018 
 1019                     | None ->
 1020                     match mi.OfType<ProvidedEventInfo>() with 
 1021                     | Some ei ->
 1022                         // Event must have adder and remover
 1023                         // TODO: Event must be public etc.
 1024                         let adder = TryMemberMember(ei, fullName, memberName, "GetAddMethod", m, null, fun ei-> ei.GetAddMethod())
 1025                         let remover = TryMemberMember(ei, fullName, memberName, "GetRemoveMethod", m, null, fun ei-> ei.GetRemoveMethod())
 1026                         match adder, remover with
 1027                         | Tainted.Null, _ -> errorR(Error(FSComp.SR.etEventNoAdd(memberName, fullName), m))   
 1028                         | _, Tainted.Null -> errorR(Error(FSComp.SR.etEventNoRemove(memberName, fullName), m))   
 1029                         | _, _ -> ()
 1030                     | None ->
 1031                     match mi.OfType<ProvidedConstructorInfo>() with
 1032                     | Some _  -> () // TODO: Constructors must be public etc.
 1033                     | None ->
 1034                     match mi.OfType<ProvidedFieldInfo>() with
 1035                     | Some _ -> () // TODO: Fields must be public, literals must have a value etc.
 1036                     | None ->
 1037                         errorR(Error(FSComp.SR.etUnsupportedMemberKind(memberName, fullName), m))   
 1038 
 1039     let ValidateProvidedTypeDefinition(m, st:Tainted<ProvidedType>, expectedPath : string[], expectedName : string) = 
 1040 
 1041         // Validate the Name, Namespace and FullName properties
 1042         let name = CheckAndComputeProvidedNameProperty(m, st, (fun st -> st.Name), "Name")
 1043         let _namespaceName = TryTypeMember(st, name, "Namespace", m, FSComp.SR.invalidNamespaceForProvidedType(), fun st -> st.Namespace) |> unmarshal
 1044         let _fullname = TryTypeMemberNonNull(st, name, "FullName", m, FSComp.SR.invalidFullNameForProvidedType(), fun st -> st.FullName)  |> unmarshal
 1045         ValidateExpectedName m expectedPath expectedName st
 1046 
 1047         ValidateAttributesOfProvidedType(m, st)
 1048 
 1049         // This excludes, for example, types with '.' in them which would not be resolvable during name resolution.
 1050         match expectedName.IndexOfAny(PrettyNaming.IllegalCharactersInTypeAndNamespaceNames) with
 1051         | -1 -> ()
 1052         | n -> errorR(Error(FSComp.SR.etIllegalCharactersInTypeName(string expectedName.[n], expectedName), m))  
 1053 
 1054         let staticParameters = st.PApplyWithProvider((fun (st, provider) -> st.GetStaticParameters(provider)), range=m) 
 1055         if staticParameters.PUntaint((fun a -> a.Length), m)  = 0 then 
 1056             ValidateProvidedTypeAfterStaticInstantiation(m, st, expectedPath, expectedName)
 1057 
 1058 
 1059     /// Resolve a (non-nested) provided type given a full namespace name and a type name. 
 1060     /// May throw an exception which will be turned into an error message by one of the 'Try' function below.
 1061     /// If resolution is successful the type is then validated.
 1062     let ResolveProvidedType (resolver:Tainted<ITypeProvider>, m, moduleOrNamespace:string[], typeName) =
 1063         let displayName = String.Join(".", moduleOrNamespace)
 1064 
 1065         // Try to find the type in the given provided namespace
 1066         let rec tryNamespace (providedNamespace: Tainted<IProvidedNamespace>) = 
 1067 
 1068             // Get the provided namespace name
 1069             let providedNamespaceName = providedNamespace.PUntaint((fun providedNamespace -> providedNamespace.NamespaceName), range=m)
 1070 
 1071             // Check if the provided namespace name is an exact match of the required namespace name
 1072             if displayName = providedNamespaceName then
 1073                 let resolvedType = providedNamespace.PApply((fun providedNamespace -> ProvidedType.CreateNoContext(providedNamespace.ResolveTypeName typeName)), range=m) 
 1074                 match resolvedType with
 1075                 |   Tainted.Null -> None
 1076                 |   result -> 
 1077                     ValidateProvidedTypeDefinition(m, result, moduleOrNamespace, typeName)
 1078                     Some result
 1079             else
 1080                 // Note: This eagerly explores all provided namespaces even if there is no match of even a prefix in the
 1081                 // namespace names. 
 1082                 let providedNamespaces = providedNamespace.PApplyArray((fun providedNamespace -> providedNamespace.GetNestedNamespaces()), "GetNestedNamespaces", range=m)
 1083                 tryNamespaces providedNamespaces
 1084 
 1085         and tryNamespaces (providedNamespaces: Tainted<IProvidedNamespace>[]) = 
 1086             providedNamespaces |> Array.tryPick tryNamespace
 1087 
 1088         let providedNamespaces = resolver.PApplyArray((fun resolver -> resolver.GetNamespaces()), "GetNamespaces", range=m)
 1089         match tryNamespaces providedNamespaces with 
 1090         | None -> resolver.PApply((fun _ -> null), m)
 1091         | Some res -> res
 1092                     
 1093     /// Try to resolve a type against the given host with the given resolution environment.
 1094     let TryResolveProvidedType(resolver:Tainted<ITypeProvider>, m, moduleOrNamespace, typeName) =
 1095         try 
 1096             match ResolveProvidedType(resolver, m, moduleOrNamespace, typeName) with
 1097             | Tainted.Null -> None
 1098             | ty -> Some ty
 1099         with e -> 
 1100             errorRecovery e m
 1101             None
 1102 
 1103     let ILPathToProvidedType  (st:Tainted<ProvidedType>, m) = 
 1104         let nameContrib (st:Tainted<ProvidedType>) = 
 1105             let typeName = st.PUntaint((fun st -> st.Name), m)
 1106             match st.PApply((fun st -> st.DeclaringType), m) with 
 1107             | Tainted.Null -> 
 1108                match st.PUntaint((fun st -> st.Namespace), m) with 
 1109                | null -> typeName
 1110                | ns -> ns + "." + typeName
 1111             | _ -> typeName
 1112 
 1113         let rec encContrib (st:Tainted<ProvidedType>) = 
 1114             match st.PApply((fun st ->st.DeclaringType), m) with 
 1115             | Tainted.Null -> []
 1116             | enc -> encContrib enc @ [ nameContrib enc ]
 1117 
 1118         encContrib st, nameContrib st
 1119 
 1120     let ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams: Tainted<ProvidedParameterInfo[]>, m) =
 1121         let defaultArgValues = 
 1122             staticParams.PApply((fun ps ->  ps |> Array.map (fun sp -> sp.Name, (if sp.IsOptional then Some (string sp.RawDefaultValue) else None ))), range=m)
 1123 
 1124         let defaultArgValues = defaultArgValues.PUntaint(id, m)
 1125         PrettyNaming.computeMangledNameWithoutDefaultArgValues(nm, staticArgs, defaultArgValues)
 1126 
 1127     /// Apply the given provided method to the given static arguments (the arguments are assumed to have been sorted into application order)
 1128     let TryApplyProvidedMethod(methBeforeArgs:Tainted<ProvidedMethodBase>, staticArgs:obj[], m:range) =
 1129         if staticArgs.Length = 0 then 
 1130             Some methBeforeArgs
 1131         else
 1132             let mangledName = 
 1133                 let nm = methBeforeArgs.PUntaint((fun x -> x.Name), m)
 1134                 let staticParams = methBeforeArgs.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParametersForMethod(resolver)), range=m) 
 1135                 let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m)
 1136                 mangledName
 1137  
 1138             match methBeforeArgs.PApplyWithProvider((fun (mb, provider) -> mb.ApplyStaticArgumentsForMethod(provider, mangledName, staticArgs)), range=m) with 
 1139             | Tainted.Null -> None
 1140             | methWithArguments -> 
 1141                 let actualName = methWithArguments.PUntaint((fun x -> x.Name), m)
 1142                 if actualName <> mangledName then 
 1143                     error(Error(FSComp.SR.etProvidedAppliedMethodHadWrongName(methWithArguments.TypeProviderDesignation, mangledName, actualName), m))
 1144                 Some methWithArguments
 1145 
 1146 
 1147     /// Apply the given provided type to the given static arguments (the arguments are assumed to have been sorted into application order
 1148     let TryApplyProvidedType(typeBeforeArguments:Tainted<ProvidedType>, optGeneratedTypePath: string list option, staticArgs:obj[], m:range) =
 1149         if staticArgs.Length = 0 then 
 1150             Some (typeBeforeArguments , (fun () -> ()))
 1151         else 
 1152             
 1153             let fullTypePathAfterArguments = 
 1154                 // If there is a generated type name, then use that
 1155                 match optGeneratedTypePath with 
 1156                 | Some path -> path
 1157                 | None -> 
 1158                     // Otherwise, use the full path of the erased type, including mangled arguments
 1159                     let nm = typeBeforeArguments.PUntaint((fun x -> x.Name), m)
 1160                     let enc, _ = ILPathToProvidedType (typeBeforeArguments, m)
 1161                     let staticParams = typeBeforeArguments.PApplyWithProvider((fun (mb, resolver) -> mb.GetStaticParameters(resolver)), range=m) 
 1162                     let mangledName = ComputeMangledNameForApplyStaticParameters(nm, staticArgs, staticParams, m)
 1163                     enc @ [ mangledName ]
 1164  
 1165             match typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, provider) -> typeBeforeArguments.ApplyStaticArguments(provider, Array.ofList fullTypePathAfterArguments, staticArgs)), range=m) with 
 1166             | Tainted.Null -> None
 1167             | typeWithArguments -> 
 1168                 let actualName = typeWithArguments.PUntaint((fun x -> x.Name), m)
 1169                 let checkTypeName() = 
 1170                     let expectedTypeNameAfterArguments = fullTypePathAfterArguments.[fullTypePathAfterArguments.Length-1]
 1171                     if actualName <> expectedTypeNameAfterArguments then 
 1172                         error(Error(FSComp.SR.etProvidedAppliedTypeHadWrongName(typeWithArguments.TypeProviderDesignation, expectedTypeNameAfterArguments, actualName), m))
 1173                 Some (typeWithArguments, checkTypeName)
 1174 
 1175     /// Given a mangled name reference to a non-nested provided type, resolve it.
 1176     /// If necessary, demangle its static arguments before applying them.
 1177     let TryLinkProvidedType(resolver:Tainted<ITypeProvider>, moduleOrNamespace:string[], typeLogicalName:string, m:range) =
 1178         
 1179         // Demangle the static parameters
 1180         let typeName, argNamesAndValues = 
 1181             try 
 1182                 PrettyNaming.demangleProvidedTypeName typeLogicalName 
 1183             with PrettyNaming.InvalidMangledStaticArg piece -> 
 1184                 error(Error(FSComp.SR.etProvidedTypeReferenceInvalidText(piece), range0)) 
 1185 
 1186         let argSpecsTable = dict argNamesAndValues
 1187         let typeBeforeArguments = ResolveProvidedType(resolver, range0, moduleOrNamespace, typeName) 
 1188 
 1189         match typeBeforeArguments with 
 1190         | Tainted.Null -> None
 1191         | _ -> 
 1192             // Take the static arguments (as strings, taken from the text in the reference we're relinking), 
 1193             // and convert them to objects of the appropriate type, based on the expected kind.
 1194             let staticParameters = typeBeforeArguments.PApplyWithProvider((fun (typeBeforeArguments, resolver) -> typeBeforeArguments.GetStaticParameters(resolver)), range=range0)
 1195 
 1196             let staticParameters = staticParameters.PApplyArray(id, "", m)
 1197             
 1198             let staticArgs = 
 1199                 staticParameters |> Array.map (fun sp -> 
 1200                       let typeBeforeArgumentsName = typeBeforeArguments.PUntaint ((fun st -> st.Name), m)
 1201                       let spName = sp.PUntaint ((fun sp -> sp.Name), m)
 1202                       match argSpecsTable.TryGetValue(spName) with
 1203                       | true, arg ->
 1204                           /// Find the name of the representation type for the static parameter
 1205                           let spReprTypeName = 
 1206                               sp.PUntaint((fun sp -> 
 1207                                   let pt = sp.ParameterType 
 1208                                   let ut = pt.RawSystemType
 1209                                   let uet = if pt.IsEnum then ut.GetEnumUnderlyingType() else ut
 1210                                   uet.FullName), m)
 1211 
 1212                           match spReprTypeName with 
 1213                           | "System.SByte" -> box (sbyte arg)
 1214                           | "System.Int16" -> box (int16 arg)
 1215                           | "System.Int32" -> box (int32 arg)
 1216                           | "System.Int64" -> box (int64 arg)
 1217                           | "System.Byte" -> box (byte arg)
 1218                           | "System.UInt16" -> box (uint16 arg)
 1219                           | "System.UInt32" -> box (uint32 arg)
 1220                           | "System.UInt64" -> box (uint64 arg)
 1221                           | "System.Decimal" -> box (decimal arg)
 1222                           | "System.Single" -> box (single arg)
 1223                           | "System.Double" -> box (double arg)
 1224                           | "System.Char" -> box (char arg)
 1225                           | "System.Boolean" -> box (arg = "True")
 1226                           | "System.String" -> box (string arg)
 1227                           | s -> error(Error(FSComp.SR.etUnknownStaticArgumentKind(s, typeLogicalName), range0))
 1228 
 1229                       | _ ->
 1230                           if sp.PUntaint ((fun sp -> sp.IsOptional), m) then 
 1231                               match sp.PUntaint((fun sp -> sp.RawDefaultValue), m) with
 1232                               | null -> error (Error(FSComp.SR.etStaticParameterRequiresAValue (spName, typeBeforeArgumentsName, typeBeforeArgumentsName, spName), range0))
 1233                               | v -> v
 1234                           else
 1235                               error(Error(FSComp.SR.etProvidedTypeReferenceMissingArgument(spName), range0)))
 1236                     
 1237 
 1238             match TryApplyProvidedType(typeBeforeArguments, None, staticArgs, range0) with 
 1239             | Some (typeWithArguments, checkTypeName) -> 
 1240                 checkTypeName() 
 1241                 Some typeWithArguments
 1242             | None -> None
 1243 
 1244     /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed.
 1245     let GetPartsOfNamespaceRecover(namespaceName:string) = 
 1246         if namespaceName=null then []
 1247         elif  namespaceName.Length = 0 then ["<NonExistentNamespace>"]
 1248         else splitNamespace namespaceName
 1249 
 1250     /// Get the parts of a .NET namespace. Special rules: null means global, empty is not allowed.
 1251     let GetProvidedNamespaceAsPath (m, resolver:Tainted<ITypeProvider>, namespaceName:string) = 
 1252         if namespaceName<>null && namespaceName.Length = 0 then
 1253             errorR(Error(FSComp.SR.etEmptyNamespaceNotAllowed(DisplayNameOfTypeProvider(resolver.TypeProvider, m)), m))  
 1254 
 1255         GetPartsOfNamespaceRecover namespaceName
 1256 
 1257     /// Get the parts of the name that encloses the .NET type including nested types. 
 1258     let GetFSharpPathToProvidedType (st:Tainted<ProvidedType>, m) = 
 1259         // Can't use st.Fullname because it may be like IEnumerable<Something>
 1260         // We want [System;Collections;Generic]
 1261         let namespaceParts = GetPartsOfNamespaceRecover(st.PUntaint((fun st -> st.Namespace), m))
 1262         let rec walkUpNestedClasses(st:Tainted<ProvidedType>, soFar) =
 1263             match st with
 1264             | Tainted.Null -> soFar
 1265             | st -> walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), soFar) @ [st.PUntaint((fun st -> st.Name), m)]
 1266 
 1267         walkUpNestedClasses(st.PApply((fun st ->st.DeclaringType), m), namespaceParts)
 1268 
 1269 
 1270     /// Get the ILAssemblyRef for a provided assembly. Do not take into account
 1271     /// any type relocations or static linking for generated types.
 1272     let GetOriginalILAssemblyRefOfProvidedAssembly (assembly:Tainted<ProvidedAssembly>, m) =
 1273         let aname = assembly.PUntaint((fun assembly -> assembly.GetName()), m)
 1274         ILAssemblyRef.FromAssemblyName aname
 1275 
 1276     /// Get the ILTypeRef for the provided type (including for nested types). Do not take into account
 1277     /// any type relocations or static linking for generated types.
 1278     let GetOriginalILTypeRefOfProvidedType (st:Tainted<ProvidedType>, m) = 
 1279         
 1280         let aref = GetOriginalILAssemblyRefOfProvidedAssembly (st.PApply((fun st -> st.Assembly), m), m)
 1281         let scoperef = ILScopeRef.Assembly aref
 1282         let enc, nm = ILPathToProvidedType (st, m)
 1283         let tref = ILTypeRef.Create(scoperef, enc, nm)
 1284         tref
 1285 
 1286     /// Get the ILTypeRef for the provided type (including for nested types). Take into account
 1287     /// any type relocations or static linking for generated types.
 1288     let GetILTypeRefOfProvidedType (st:Tainted<ProvidedType>, m) = 
 1289         match st.PUntaint((fun st -> st.TryGetILTypeRef()), m) with 
 1290         | Some ilTypeRef -> ilTypeRef
 1291         | None -> GetOriginalILTypeRefOfProvidedType (st, m)
 1292 
 1293     type ProviderGeneratedType = ProviderGeneratedType of (*ilOrigTyRef*)ILTypeRef * (*ilRenamedTyRef*)ILTypeRef * ProviderGeneratedType list
 1294 
 1295     /// The table of information recording remappings from type names in the provided assembly to type
 1296     /// names in the statically linked, embedded assembly, plus what types are nested in side what types.
 1297     type ProvidedAssemblyStaticLinkingMap = 
 1298         { ILTypeMap: System.Collections.Generic.Dictionary<ILTypeRef, ILTypeRef> }
 1299         static member CreateNew() = 
 1300             { ILTypeMap = System.Collections.Generic.Dictionary() }
 1301 
 1302     /// Check if this is a direct reference to a non-embedded generated type. This is not permitted at any name resolution.
 1303     /// We check by seeing if the type is absent from the remapping context.
 1304     let IsGeneratedTypeDirectReference (st: Tainted<ProvidedType>, m) =
 1305         st.PUntaint((fun st -> st.TryGetTyconRef() |> Option.isNone), m)
 1306 
 1307 #endif