提交 f125901a 编写于 作者: V vladima

merged with upstream


Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2012
# Visual Studio 2013
VisualStudioVersion = 12.0.30110.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D78E3B57-DAD1-4FE1-9DC8-84F7847B0C77}"
ProjectSection(SolutionItems) = preProject
fsharp-compiler-build.proj = fsharp-compiler-build.proj
......@@ -35,46 +37,44 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.Build.0 = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2E4D67B4-522D-4CF7-97E4-BA940F0B18F3}.Release|Any CPU.Build.0 = Release|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.Build.0 = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.Build.0 = Release|Any CPU
{702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{702A7979-BCF9-4C41-853E-3ADFC9897890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{702A7979-BCF9-4C41-853E-3ADFC9897890}.Release|Any CPU.Build.0 = Release|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C94C257C-3C0A-4858-B5D8-D746498D1F08}.Release|Any CPU.Build.0 = Release|Any CPU
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|x86
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.Build.0 = Debug|x86
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|x86
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.Build.0 = Release|x86
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D0E98C0D-490B-4C61-9329-0862F6E87645}.Release|Any CPU.Build.0 = Release|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{649FA588-F02E-457C-9FCF-87E46407481E}.Release|Any CPU.Build.0 = Release|Any CPU
{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5870CF0-ED51-4CBC-B3D7-6F56DA84AC06}.Release|Any CPU.Build.0 = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DED3BBD7-53F4-428A-8C9F-27968E768605}.Release|Any CPU.Build.0 = Release|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88E2D422-6852-46E3-A740-83E391DC7973}.Release|Any CPU.Build.0 = Release|Any CPU
{CB7D20C4-6506-406D-9144-5342C3595F03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB7D20C4-6506-406D-9144-5342C3595F03}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB7D20C4-6506-406D-9144-5342C3595F03}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB7D20C4-6506-406D-9144-5342C3595F03}.Release|Any CPU.Build.0 = Release|Any CPU
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|Any CPU.Build.0 = Release|Any CPU
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Debug|Any CPU.ActiveCfg = Debug|x86
{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}.Release|Any CPU.ActiveCfg = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......
......@@ -1910,16 +1910,11 @@ and ArgsMustSubsumeOrConvert
(callerArg: CallerArg<'T>) =
let g = csenv.g
let amap = csenv.amap
let m = callerArg.Range
let calledArgTy = AdjustCalledArgType csenv.InfoReader isConstraint calledArg callerArg
SolveTypSubsumesTypWithReport csenv ndeep m trace calledArgTy callerArg.Type ++ (fun () ->
if calledArg.IsParamArray &&
isAppTy g calledArgTy &&
(let _,tinstf = destAppTy g calledArgTy
tinstf.Length = 1 &&
TypesFeasiblyEquiv ndeep g amap m (List.head tinstf) callerArg.Type)
if calledArg.IsParamArray && (isArray1DTy g calledArgTy) && not (isArray1DTy g callerArg.Type)
then
ErrorD(Error(FSComp.SR.csMethodExpectsParams(),m))
else
......
......@@ -20,10 +20,20 @@ open Microsoft.FSharp.Compiler.ErrorLogger
open Microsoft.FSharp.Compiler.ExtensionTyping
#endif
/// Represents an interface to some of the functionality of TcImports, for loading assemblies
/// and accessing information about generated provided assemblies.
type AssemblyLoader =
/// Resolve an Abstract IL assembly reference to a Ccu
abstract LoadAssembly : range * ILAssemblyRef -> CcuResolutionResult
#if EXTENSIONTYPING
/// Get a flag indicating if an assembly is a provided assembly, plus the
/// table of information recording remappings from type names in the provided assembly to type
/// names in the statically linked, embedded assembly.
abstract GetProvidedAssemblyInfo : range * Tainted<ProvidedAssembly> -> bool * ProvidedAssemblyStaticLinkingMap option
/// Record a root for a [<Generate>] type to help guide static linking & type relocation
abstract RecordGeneratedTypeRoot : ProviderGeneratedType -> unit
#endif
......@@ -33,8 +43,14 @@ type AssemblyLoader =
// Import an IL types as F# types.
//-------------------------------------------------------------------------
/// This is the context used for converting AbstractIL .NET and provided types to F# internal compiler data structures.
/// We currently cache the conversion of AbstractIL ILTypeRef nodes, based on hashes of these.
/// Represents a context used by the import routines that convert AbstractIL types and provided
/// types to F# internal compiler data structures.
///
/// Also caches the conversion of AbstractIL ILTypeRef nodes, based on hashes of these.
///
/// There is normally only one ImportMap for any assembly compilation, though additional instances can be created
/// using tcImports.GetImportMap() if needed, and it is not harmful if multiple instances are used. The object
/// serves as an interface through to the tables stored in the primary TcImports structures defined in build.fs.
[<Sealed>]
type ImportMap(g:TcGlobals,assemblyLoader:AssemblyLoader) =
let typeRefToTyconRefCache = new System.Collections.Generic.Dictionary<ILTypeRef,TyconRef>()
......@@ -42,6 +58,7 @@ type ImportMap(g:TcGlobals,assemblyLoader:AssemblyLoader) =
member this.assemblyLoader = assemblyLoader
member this.ILTypeRefToTyconRefCache = typeRefToTyconRefCache
/// Import a reference to a type definition, given the AbstractIL data for the type reference
let ImportTypeRefData (env:ImportMap) m (scoref,path,typeName) =
let ccu =
match scoref with
......@@ -76,7 +93,7 @@ let ImportTypeRefData (env:ImportMap) m (scoref,path,typeName) =
| Some tcref -> tcref
/// Import an IL type ref as an F# type constructor.
/// Import a reference to a type definition, given an AbstractIL ILTypeRef, without caching
//
// Note, the type names that flow to the point include the "mangled" type names used for static parameters for provided types.
// For example,
......@@ -95,24 +112,25 @@ let ImportILTypeRefUncached (env:ImportMap) m (tref:ILTypeRef) =
ImportTypeRefData (env:ImportMap) m (tref.Scope,path,typeName)
/// Import a reference to a type definition, given an AbstractIL ILTypeRef, with caching
let ImportILTypeRef (env:ImportMap) m (tref:ILTypeRef) =
if env.ILTypeRefToTyconRefCache.ContainsKey(tref) then
env.ILTypeRefToTyconRefCache.[tref]
else
let tcref = ImportILTypeRefUncached env m tref
env.ILTypeRefToTyconRefCache.[tref] <- tcref;
env.ILTypeRefToTyconRefCache.[tref] <- tcref
tcref
/// Import a type, given an AbstractIL ILTypeRef and an F# type instantiation.
///
/// Prefer the F# abbreviation for some built-in types, e.g. 'string' rather than
/// 'System.String', since we prefer the F# abbreviation to the .NET equivalents.
let ImportTyconRefApp (env:ImportMap) tcref tyargs =
// 'better_tcref_map' prefers the F# abbreviation for some built-in types, e.g. 'string' rather than
// 'System.String', since users prefer the F# abbreviation to the .NET equivalents. Also on import
// we decompile uses of FSharpFunc and Tuple.
match env.g.better_tcref_map tcref tyargs with
| Some res -> res
| None -> TType_app (tcref,tyargs)
/// Import an IL type as an F# type
/// - The F# type check does the job of making the "void" into a "unit" value, whatever the repr. of "unit" is.
/// Import an IL type as an F# type.
let rec ImportILType (env:ImportMap) m tinst typ =
match typ with
| ILType.Void ->
......@@ -141,6 +159,7 @@ let rec ImportILType (env:ImportMap) m tinst typ =
#if EXTENSIONTYPING
/// Import a provided type reference as an F# type TyconRef
let ImportProvidedNamedType (env:ImportMap) (m:range) (st:Tainted<ProvidedType>) =
// See if a reverse-mapping exists for a generated/relocated System.Type
match st.PUntaint((fun st -> st.TryGetTyconRef()),m) with
......@@ -149,6 +168,7 @@ let ImportProvidedNamedType (env:ImportMap) (m:range) (st:Tainted<ProvidedType>)
let tref = ExtensionTyping.GetILTypeRefOfProvidedType (st,m)
ImportILTypeRef env m tref
/// Import a provided type as an AbstractIL type
let rec ImportProvidedTypeAsILType (env:ImportMap) (m:range) (st:Tainted<ProvidedType>) =
if st.PUntaint ((fun x -> x.IsVoid),m) then ILType.Void
elif st.PUntaint((fun st -> st.IsGenericParameter),m) then
......@@ -184,6 +204,7 @@ let rec ImportProvidedTypeAsILType (env:ImportMap) (m:range) (st:Tainted<Provide
else
mkILBoxedType tspec
/// Import a provided type as an F# type.
let rec ImportProvidedType (env:ImportMap) (m:range) (* (tinst:TypeInst) *) (st:Tainted<ProvidedType>) =
let g = env.g
......@@ -246,6 +267,7 @@ let rec ImportProvidedType (env:ImportMap) (m:range) (* (tinst:TypeInst) *) (st:
ImportTyconRefApp env tcref genericArgs
/// Import a provided method reference as an Abstract IL method reference
let ImportProvidedMethodBaseAsILMethodRef (env:ImportMap) (m:range) (mbase: Tainted<ProvidedMethodBase>) =
let tref = ExtensionTyping.GetILTypeRefOfProvidedType (mbase.PApply((fun mbase -> mbase.DeclaringType),m), m)
......@@ -322,7 +344,11 @@ let ImportProvidedMethodBaseAsILMethodRef (env:ImportMap) (m:range) (mbase: Tain
//--------------------------------------------------------------------------
// tinst gives the type parameters for the enclosing type when converting the type parameters of a generic method
/// Import a set of Abstract IL generic parameter specifications as a list of new
/// F# generic parameters.
///
/// Fixup the constrants so that any references to the generic parameters
/// in the constraints now refer to the new generic parameters.
let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs) =
match gps with
| [] -> []
......@@ -341,6 +367,10 @@ let ImportILGenericParameters amap m scoref tinst (gps: ILGenericParameterDefs)
tps
/// Given a list of items each keyed by an ordered list of keys, apply 'nodef' to the each group
/// with the same leading key. Apply 'tipf' to the elements where the keylist is empty, and return
/// the overall results. Used to bucket types, so System.Char and System.Collections.Generic.List
/// both get initially bucketed under 'System'.
let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) =
// Find all the items with an empty key list and call 'tipf'
let tips =
......@@ -361,9 +391,10 @@ let multisetDiscriminateAndMap nodef tipf (items: ('Key list * 'Value) list) =
[ for (KeyValue(key,items)) in buckets -> nodef key items ]
tips,nodes
tips @ nodes
/// Import an IL type definition as a new F# TAST Entity node.
let rec ImportILTypeDef amap m scoref cpath enc nm (tdef:ILTypeDef) =
let lazyModuleOrNamespaceTypeForNestedTypes =
lazy
......@@ -380,44 +411,47 @@ let rec ImportILTypeDef amap m scoref cpath enc nm (tdef:ILTypeDef) =
lazyModuleOrNamespaceTypeForNestedTypes
/// Import a list of (possibly nested) IL types as a new ModuleOrNamespaceType node
/// containing new entities, bucketing by namespace along the way.
and ImportILTypeDefList amap m cpath enc items =
// Split into the ones with namespaces and without
// This is a non-trivial function.
// Add the ones with namespaces in buckets
// That is, multi-set discriminate based in the first element of the namespace list (e.g. "System")
// and for each bag resulting from the discrimination fold-in a lazy computation to add the types under that bag
let rec add cpath items =
let tycons,namespaceModules =
items
|> multisetDiscriminateAndMap
// nodef - called for each bucket, where 'n' is the head element of the namespace used
// as a key in the discrimination, tgs is the remaining descriptors. We create a sub-module for 'n'
(fun n tgs ->
let modty = lazy (add (mkNestedCPath cpath n Namespace) tgs)
let mspec = NewModuleOrNamespace (Some cpath) taccessPublic (mkSynId m n) XmlDoc.Empty [] modty
mspec)
// tipf - called if there are no namespace items left to discriminate on.
(fun (n,info:Lazy<_>) ->
//Note: this scoref looks like it will always be identical to 'scoref'
let (scoref2,_,lazyTypeDef:Lazy<ILTypeDef>) = info.Force()
ImportILTypeDef amap m scoref2 cpath enc n (lazyTypeDef.Force()))
let kind = match enc with [] -> Namespace | _ -> ModuleOrType
NewModuleOrNamespaceType kind (tycons@namespaceModules) []
// Split into the ones with namespaces and without. Add the ones with namespaces in buckets.
// That is, discriminate based in the first element of the namespace list (e.g. "System")
// and, for each bag, fold-in a lazy computation to add the types under that bag .
//
// nodef - called for each bucket, where 'n' is the head element of the namespace used
// as a key in the discrimination, tgs is the remaining descriptors. We create an entity for 'n'.
//
// tipf - called if there are no namespace items left to discriminate on.
let entities =
items
|> multisetDiscriminateAndMap
(fun n tgs ->
let modty = lazy (ImportILTypeDefList amap m (mkNestedCPath cpath n Namespace) enc tgs)
NewModuleOrNamespace (Some cpath) taccessPublic (mkSynId m n) XmlDoc.Empty [] modty)
(fun (n,info:Lazy<_>) ->
let (scoref2,_,lazyTypeDef:Lazy<ILTypeDef>) = info.Force()
ImportILTypeDef amap m scoref2 cpath enc n (lazyTypeDef.Force()))
let kind = match enc with [] -> Namespace | _ -> ModuleOrType
NewModuleOrNamespaceType kind entities []
add cpath items
/// Import a table of IL types as a ModuleOrNamespaceType.
///
and ImportILTypeDefs amap m scoref cpath enc (tdefs: ILTypeDefs) =
// We be very careful not to force a read of the type defs here
tdefs.AsListOfLazyTypeDefs
|> List.map (fun (ns,n,attrs,lazyTypeDef) -> (ns,(n,notlazy(scoref,attrs,lazyTypeDef))))
|> ImportILTypeDefList amap m cpath enc
/// Import the main type definitions in an IL assembly.
///
/// Example: for a collection of types "System.Char", "System.Int32" and "Library.C"
/// the return ModuleOrNamespaceType will contain namespace entities for "System" and "Library", which in turn contain
/// type definition entities for ["Char"; "Int32"] and ["C"] respectively.
let ImportILAssemblyMainTypeDefs amap m scoref modul =
modul.TypeDefs |> ImportILTypeDefs amap m scoref (CompPath(scoref,[])) []
/// Read the "exported types" table for multi-module assemblies.
/// Import the "exported types" table for multi-module assemblies.
let ImportILAssemblyExportedType amap m auxModLoader (scoref:ILScopeRef) (exportedType:ILExportedTypeOrForwarder) =
// Forwarders are dealt with separately in the ref->def dereferencing logic in tast.fs as they effectively give rise to type equivalences
if exportedType.IsForwarder then
......@@ -438,18 +472,20 @@ let ImportILAssemblyExportedType amap m auxModLoader (scoref:ILScopeRef) (export
let ns,n = splitILTypeName exportedType.Name
[ ImportILTypeDefList amap m (CompPath(scoref,[])) [] [(ns,(n,info))] ]
/// Read the "exported types" table for multi-module assemblies.
/// Import the "exported types" table for multi-module assemblies.
let ImportILAssemblyExportedTypes amap m auxModLoader scoref (exportedTypes: ILExportedTypesAndForwarders) =
[ for exportedType in exportedTypes.AsList do
yield! ImportILAssemblyExportedType amap m auxModLoader scoref exportedType ]
/// Import both the main type definitions and the "exported types" table, i.e. all the
/// types defined in an IL assembly.
let ImportILAssemblyTypeDefs (amap, m, auxModLoader, aref, mainmod:ILModuleDef) =
let scoref = ILScopeRef.Assembly aref
let mtypsForExportedTypes = ImportILAssemblyExportedTypes amap m auxModLoader scoref mainmod.ManifestOfAssembly.ExportedTypes
let mainmod = ImportILAssemblyMainTypeDefs amap m scoref mainmod
combineModuleOrNamespaceTypeList [] m (mainmod :: mtypsForExportedTypes)
// Read the type forwarder table for an assembly
/// Import the type forwarder table for an IL assembly
let ImportILAssemblyTypeForwarders (amap, m, exportedTypes:ILExportedTypesAndForwarders) =
// Note 'td' may be in another module or another assembly!
// Note: it is very important that we call auxModLoader lazily
......@@ -470,6 +506,7 @@ let ImportILAssemblyTypeForwarders (amap, m, exportedTypes:ILExportedTypesAndFor
] |> Map.ofList
/// Import an IL assembly as a new TAST CCU
let ImportILAssembly(amap:(unit -> ImportMap),m,auxModuleLoader,sref,sourceDir,filename,ilModule:ILModuleDef,invalidateCcu:IEvent<string>) =
invalidateCcu |> ignore
let aref =
......
......@@ -11,38 +11,66 @@ open Microsoft.FSharp.Compiler.ExtensionTyping
/// Represents an interface to some of the functionality of TcImports, for loading assemblies
/// and accessing information about generated provided assemblies.
type AssemblyLoader =
/// Resolve an Abstract IL assembly reference to a Ccu
abstract LoadAssembly : range * ILAssemblyRef -> CcuResolutionResult
#if EXTENSIONTYPING
/// Get a flag indicating if an assembly is a provided assembly, plus the
/// table of information recording remappings from type names in the provided assembly to type
/// names in the statically linked, embedded assembly.
abstract GetProvidedAssemblyInfo : range * Tainted<ProvidedAssembly> -> bool * ProvidedAssemblyStaticLinkingMap option
/// Record a root for a [<Generate>] type to help guide static linking & type relocation
abstract RecordGeneratedTypeRoot : ProviderGeneratedType -> unit
#endif
[<SealedAttribute ()>]
/// This is the context used for converting AbstractIL .NET and provided types to F# internal compiler data structures.
/// We currently cache the conversion of AbstractIL ILTypeRef nodes, based on hashes of these.
/// Represents a context used for converting AbstractIL .NET and provided types to F# internal compiler data structures.
/// Also cache the conversion of AbstractIL ILTypeRef nodes, based on hashes of these.
///
/// There is normally only one ImportMap for any assembly compilation, though additional instances can be created
/// using tcImports.GetImportMap() if needed, and it is not harmful if multiple instances are used. The object
/// serves as an interface through to the tables stored in the primary TcImports structures defined in build.fs.
[<SealedAttribute>]
type ImportMap =
new : g:Env.TcGlobals * assemblyLoader:AssemblyLoader -> ImportMap
/// The AssemblyLoader for the import context
member assemblyLoader : AssemblyLoader
/// The TcGlobals for the import context
member g : Env.TcGlobals
/// Import a reference to a type definition, given an AbstractIL ILTypeRef, with caching
val internal ImportILTypeRef : ImportMap -> range -> ILTypeRef -> TyconRef
/// Import an IL type as an F# type.
val internal ImportILType : ImportMap -> range -> TType list -> ILType -> TType
#if EXTENSIONTYPING
/// Import a provided type as an F# type.
val internal ImportProvidedType : ImportMap -> range -> (* TType list -> *) Tainted<ProvidedType> -> TType
/// Import a provided type reference as an F# type TyconRef
val internal ImportProvidedNamedType : ImportMap -> range -> (* TType list -> *) Tainted<ProvidedType> -> TyconRef
/// Import a provided type as an AbstractIL type
val internal ImportProvidedTypeAsILType : ImportMap -> range -> Tainted<ProvidedType> -> ILType
/// Import a provided method reference as an Abstract IL method reference
val internal ImportProvidedMethodBaseAsILMethodRef : ImportMap -> range -> Tainted<ProvidedMethodBase> -> ILMethodRef
#endif
/// Import a set of Abstract IL generic parameter specifications as a list of new F# generic parameters.
val internal ImportILGenericParameters : (unit -> ImportMap) -> range -> ILScopeRef -> TType list -> ILGenericParameterDef list -> Typar list
/// Import an IL assembly as a new TAST CCU
val internal ImportILAssembly : (unit -> ImportMap) * range * (ILScopeRef -> ILModuleDef) * ILScopeRef * sourceDir:string * filename: string option * ILModuleDef * IEvent<string> -> CcuThunk
/// Import the type forwarder table for an IL assembly
val internal ImportILAssemblyTypeForwarders : (unit -> ImportMap) * range * ILExportedTypesAndForwarders -> Map<(string array * string), Lazy<EntityRef>>
此差异已折叠。
此差异已折叠。
......@@ -3,9 +3,7 @@
module internal Microsoft.FSharp.Compiler.Nameres
open Microsoft.FSharp.Compiler
open Microsoft.FSharp.Compiler.Lib
open Microsoft.FSharp.Compiler.Ast
open Microsoft.FSharp.Compiler.ErrorLogger
open Microsoft.FSharp.Compiler.Infos
open Microsoft.FSharp.Compiler.Range
open Microsoft.FSharp.Compiler.Import
......@@ -13,14 +11,12 @@ open Microsoft.FSharp.Compiler.Outcome
open Microsoft.FSharp.Compiler.Tast
open Microsoft.FSharp.Compiler.Tastops
open Microsoft.FSharp.Compiler.Env
open Microsoft.FSharp.Compiler.AbstractIL
open Microsoft.FSharp.Compiler.AbstractIL.IL
open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
open Microsoft.FSharp.Compiler.PrettyNaming
/// A NameResolver primarily holds an InfoReader
/// A NameResolver is a context for name resolution. It primarily holds an InfoReader.
type NameResolver =
new : g:TcGlobals * amap:ImportMap * infoReader:InfoReader * instantiationGenerator:(range -> Typars -> TypeInst) -> NameResolver
member InfoReader : InfoReader
......@@ -28,16 +24,17 @@ type NameResolver =
member g : TcGlobals
[<NoEquality; NoComparison; RequireQualifiedAccess>]
/// Represents the item with which a named argument is associated.
type ArgumentContainer =
/// The named argument is an argument of a method
| Method of MethInfo
/// The named argument is a static parameter to a provided type or a parameter to an F# exception constructor
| Type of TyconRef
/// The named argument is a static parameter to a union case constructor
| UnionCase of UnionCaseInfo
//---------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
[<NoEquality; NoComparison; RequireQualifiedAccess>]
/// Represents an item that results from name resolution
type Item =
// These exist in the "eUnqualifiedItems" List.map in the type environment.
| Value of ValRef
......@@ -71,12 +68,12 @@ type Item =
member DisplayName : TcGlobals -> string
[<Sealed>]
/// Information about an extension member held in the name resolution environment
[<Sealed>]
type ExtensionMember
[<NoEquality; NoComparison>]
/// The environment of information used to resolve names
[<NoEquality; NoComparison>]
type NameResolutionEnv =
{eDisplayEnv: DisplayEnv
eUnqualifiedItems: LayeredMap<string,Item>
......@@ -102,43 +99,74 @@ type FullyQualifiedFlag =
[<RequireQualifiedAccess>]
type BulkAdd = Yes | No
/// Add extra items to the environment for Visual Studio, e.g. static members
val internal AddFakeNamedValRefToNameEnv : string -> NameResolutionEnv -> ValRef -> NameResolutionEnv
/// Add some extra items to the environment for Visual Studio, e.g. record members
val internal AddFakeNameToNameEnv : string -> NameResolutionEnv -> Item -> NameResolutionEnv
/// Add a single F# value to the environment.
val internal AddValRefToNameEnv : NameResolutionEnv -> ValRef -> NameResolutionEnv
/// Add active pattern result tags to the environment.
val internal AddActivePatternResultTagsToNameEnv : ActivePatternInfo -> NameResolutionEnv -> TType -> range -> NameResolutionEnv
/// Add a list of type definitions to the name resolution environment
val internal AddTyconRefsToNameEnv : BulkAdd -> bool -> TcGlobals -> ImportMap -> range -> bool -> NameResolutionEnv -> TyconRef list -> NameResolutionEnv
/// Add an F# exception definition to the name resolution environment
val internal AddExceptionDeclsToNameEnv : BulkAdd -> NameResolutionEnv -> TyconRef -> NameResolutionEnv
/// Add a module abbreviation to the name resolution environment
val internal AddModuleAbbrevToNameEnv : Ident -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv
/// Add a list of module or namespace to the name resolution environment, including any sub-modules marked 'AutoOpen'
val internal AddModuleOrNamespaceRefsToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv
/// Add a single modules or namespace to the name resolution environment
val internal AddModuleOrNamespaceRefToNameEnv : TcGlobals -> ImportMap -> range -> bool -> AccessorDomain -> NameResolutionEnv -> ModuleOrNamespaceRef -> NameResolutionEnv
/// Add a list of modules or namespaces to the name resolution environment
val internal AddModulesAndNamespacesContentsToNameEnv : TcGlobals -> ImportMap -> AccessorDomain -> range -> NameResolutionEnv -> ModuleOrNamespaceRef list -> NameResolutionEnv
/// A flag which indicates if it is an error to have two declared type parameters with identical names
/// in the name resolution environment.
type CheckForDuplicateTyparFlag =
| CheckForDuplicateTypars
| NoCheckForDuplicateTypars
/// Add some declared type parameters to the name resolution environment
val internal AddDeclaredTyparsToNameEnv : CheckForDuplicateTyparFlag -> NameResolutionEnv -> Typar list -> NameResolutionEnv
/// Qualified lookup of type names in the environment
val internal LookupTypeNameInEnvNoArity : FullyQualifiedFlag -> string -> NameResolutionEnv -> TyconRef list
/// Indicates whether we are resolving type names to type definitions or to constructor methods.
type TypeNameResolutionFlag =
/// Indicates we are resolving type names to constructor methods.
| ResolveTypeNamesToCtors
/// Indicates we are resolving type names to type definitions
| ResolveTypeNamesToTypeRefs
[<Sealed>]
[<NoEquality; NoComparison>]
/// Represents information about the generic argument count of a type name when resolving it.
///
/// In some situations we resolve "List" to any type definition with that name regardless of the number
/// of generic arguments. In others, we know precisely how many generic arguments are needed.
[<Sealed;NoEquality; NoComparison>]
type TypeNameResolutionStaticArgsInfo =
/// Indicates definite knowledge of empty type arguments, i.e. the logical equivalent of name< >
static member DefiniteEmpty : TypeNameResolutionStaticArgsInfo
/// Deduce definite knowledge of type arguments
static member FromTyArgs : numTyArgs:int -> TypeNameResolutionStaticArgsInfo
/// Represents information which guides name resolution of types.
[<NoEquality; NoComparison>]
type TypeNameResolutionInfo =
| TypeNameResolutionInfo of TypeNameResolutionFlag * TypeNameResolutionStaticArgsInfo
static member Default : TypeNameResolutionInfo
static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo
/// Represents the kind of the occurence when reporting a name in name resolution
[<RequireQualifiedAccess>]
type internal ItemOccurence =
| Binding = 0
......@@ -147,30 +175,51 @@ type internal ItemOccurence =
| UseInAttribute = 3
| Pattern = 4
/// An abstract type for reporting the results of name resolution and type checking
type ITypecheckResultsSink =
abstract NotifyEnvWithScope : range * NameResolutionEnv * AccessorDomain -> unit
abstract NotifyExprHasType : pos * TType * DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit
abstract NotifyNameResolution : pos * Item * Item * ItemOccurence * DisplayEnv * NameResolutionEnv * AccessorDomain * range -> unit
/// An abstract type for reporting the results of name resolution and type checking, and which allows
/// temporary suspension and/or redirection of reporting.
type TcResultsSink =
{ mutable CurrentSink : ITypecheckResultsSink option }
static member NoSink : TcResultsSink
static member WithSink : ITypecheckResultsSink -> TcResultsSink
/// Temporarily redirect reporting of name resolution and type checking results
val internal WithNewTypecheckResultsSink : ITypecheckResultsSink * TcResultsSink -> System.IDisposable
/// Temporarily suspend reporting of name resolution and type checking results
val internal TemporarilySuspendReportingTypecheckResultsToSink : TcResultsSink -> System.IDisposable
/// Report the active name resolution environment for a source range
val internal CallEnvSink : TcResultsSink -> range * NameResolutionEnv * AccessorDomain -> unit
/// Report a specific name resolution at a source range
val internal CallNameResolutionSink : TcResultsSink -> range * NameResolutionEnv * Item * Item * ItemOccurence * DisplayEnv * AccessorDomain -> unit
/// Report a specific name resolution at a source range
val internal CallExprHasTypeSink : TcResultsSink -> range * NameResolutionEnv * TType * DisplayEnv * AccessorDomain -> unit
/// Get all the available properties of a type (both intrinsic and extension)
val internal AllPropInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> PropInfo list
/// Get the available methods of a type (both declared and inherited)
val internal AllMethInfosOfTypeInScope : InfoReader -> NameResolutionEnv -> string option * AccessorDomain -> FindMemberFlag -> range -> TType -> MethInfo list
/// Used to report an error condition where name resolution failed due to an indeterminate type
exception internal IndeterminateType of range
/// Used to report a warning condition for the use of upper-case identifiers in patterns
exception internal UpperCaseIdentifierInPattern of range
/// Generate a new reference to a record field with a fresh type instantiation
val FreshenRecdFieldRef :NameResolver -> Range.range -> Tast.RecdFieldRef -> Item
/// Indicates the kind of lookup being performed. Note, this type should be made private to nameres.fs.
[<RequireQualifiedAccess>]
type LookupKind =
| RecdField
| Pattern
......@@ -179,43 +228,74 @@ type LookupKind =
| Ctor
/// Indicates if a warning should be given for the use of upper-case identifiers in patterns
type WarnOnUpperFlag =
| WarnOnUpperCase
| AllIdsOK
[<RequireQualifiedAccess>]
/// Indicates whether we permit a direct reference to a type generator. Only set when resolving the
/// right-hand-side of a [<Generate>] declaration.
[<RequireQualifiedAccess>]
type PermitDirectReferenceToGeneratedType =
| Yes
| No
/// Resolve a long identifier to a namespace or module.
val internal ResolveLongIndentAsModuleOrNamespace : Import.ImportMap -> range -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> ResultOrException<(int * ModuleOrNamespaceRef * ModuleOrNamespaceType) list >
/// Resolve a long identifer to an object constructor.
val internal ResolveObjectConstructor : NameResolver -> DisplayEnv -> range -> AccessorDomain -> TType -> ResultOrException<Item>
/// Resolve a long identifer using type-qualified name resolution.
val internal ResolveLongIdentInType : TcResultsSink -> NameResolver -> NameResolutionEnv -> LookupKind -> range -> AccessorDomain -> Ident list -> FindMemberFlag -> TypeNameResolutionInfo -> TType -> Item * Ident list
/// Resolve a long identifier when used in a pattern.
val internal ResolvePatternLongIdent : TcResultsSink -> NameResolver -> WarnOnUpperFlag -> bool -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item
/// Resolve a long identifier representing a type name
val internal ResolveTypeLongIdentInTyconRef : TcResultsSink -> NameResolver -> NameResolutionEnv -> TypeNameResolutionInfo -> AccessorDomain -> range -> ModuleOrNamespaceRef -> Ident list -> TyconRef
/// Resolve a long identifier to a type definition
val internal ResolveTypeLongIdent : TcResultsSink -> NameResolver -> ItemOccurence -> FullyQualifiedFlag -> NameResolutionEnv -> AccessorDomain -> Ident list -> TypeNameResolutionStaticArgsInfo -> PermitDirectReferenceToGeneratedType -> ResultOrException<TyconRef>
/// Resolve a long identifier to a field
val internal ResolveField : NameResolver -> NameResolutionEnv -> AccessorDomain -> TType -> Ident list * Ident -> RecdFieldRef list
/// Resolve a long identifier occurring in an expression position
val internal ResolveExprLongIdent : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * Ident list
/// Resolve a (possibly incomplete) long identifier to a loist of possible class or record fields
val internal ResolvePartialLongIdentToClassOrRecdFields : NameResolver -> NameResolutionEnv -> range -> AccessorDomain -> string list -> bool -> Item list
/// Return the fields for the given class or record
val internal ResolveRecordOrClassFieldsOfType : NameResolver -> range -> AccessorDomain -> TType -> bool -> Item list
/// An adjustment to perform to the name resolution results if overload resolution fails.
/// If overload resolution succeeds, the specific overload resolution is reported. If it fails, the
/// set of possibile overlods is reported via this adjustment.
type IfOverloadResolutionFails = IfOverloadResolutionFails of (unit -> unit)
// Specifies if overload resolution needs to notify Language Service of overload resolution
/// Specifies if overload resolution needs to notify Language Service of overload resolution
[<RequireQualifiedAccess>]
type AfterOverloadResolution =
// Notfication is not needed
/// Notfication is not needed
| DoNothing
// Notfy the sink
/// Notfy the sink
| SendToSink of (Item -> unit) * IfOverloadResolutionFails // overload resolution failure fallback
// Find override among given overrides and notify the sink
// 'Item' contains the candidate overrides.
/// Find override among given overrides and notify the sink. The 'Item' contains the candidate overrides.
| ReplaceWithOverrideAndSendToSink of Item * (Item -> unit) * IfOverloadResolutionFails // overload resolution failure fallback
/// Resolve a long identifier occurring in an expression position.
val internal ResolveLongIdentAsExprAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TypeNameResolutionInfo -> Ident list -> Item * range * Ident list * AfterOverloadResolution
/// Resolve a long identifier occurring in an expression position, qualified by a type.
val internal ResolveExprDotLongIdentAndComputeRange : TcResultsSink -> NameResolver -> range -> AccessorDomain -> NameResolutionEnv -> TType -> Ident list -> FindMemberFlag -> bool -> Item * range * Ident list * AfterOverloadResolution
/// A generator of type instantiations used when no more specific type instantiation is known.
val FakeInstantiationGenerator : range -> Typar list -> TType list
/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions.
val ResolvePartialLongIdent : NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> range -> AccessorDomain -> string list -> bool -> Item list
/// Resolve a (possibly incomplete) long identifier to a set of possible resolutions, qualified by type.
val ResolveCompletionsInType : NameResolver -> NameResolutionEnv -> (MethInfo -> TType -> bool) -> Range.range -> Infos.AccessorDomain -> bool -> TType -> Item list
......@@ -12,12 +12,6 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
let success a = Result a
let raze (b:exn) = Exception b
// bind
let (||?>) res f =
match res with
| Result x -> f x
| Exception err -> Exception err
// map
let (|?>) res f =
match res with
......
......@@ -6,7 +6,6 @@ open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
val success : 'T -> ResultOrException<'T>
val raze : exn -> ResultOrException<'T>
val ( ||?> ) : ResultOrException<'T> -> ('T -> ResultOrException<'U>) -> ResultOrException<'U>
val ( |?> ) : ResultOrException<'T> -> ('T -> 'U) -> ResultOrException<'U>
val ForceRaise : ResultOrException<'T> -> 'T
val otherwise : (unit -> ResultOrException<'T>) -> ResultOrException<'T> -> ResultOrException<'T>
......@@ -9618,7 +9618,7 @@ and TcAttribute cenv (env: TcEnv) attrTgt (synAttr: SynAttribute) =
namedCallerArgs |> List.map (fun (CallerNamedArg(id,CallerArg(argtyv,m,isOpt,expr))) ->
if isOpt then error(Error(FSComp.SR.tcOptionalArgumentsCannotBeUsedInCustomAttribute(),m))
let m = expr.Range
let setterItem, _ = ResolveLongIdentInType cenv.tcSink cenv.nameResolver env.NameEnv Nameres.LookupKind.Expr m ad [id] IgnoreOverrides TypeNameResolutionInfo.Default ty
let setterItem, _ = ResolveLongIdentInType cenv.tcSink cenv.nameResolver env.NameEnv LookupKind.Expr m ad [id] IgnoreOverrides TypeNameResolutionInfo.Default ty
let nm, isProp, argty =
match setterItem with
| Item.Property (_,[pinfo]) ->
......
......@@ -11,13 +11,13 @@ exit /b 1
:ok
msbuild fsharpqa\testenv\src\ILComparer\ILComparer.fsproj /p:Configuration=%1 /t:Build
xcopy /Y fsharpqa\testenv\src\ILComparer\bin\%1\* fsharpqa\testenv\bin
msbuild %~dp0\fsharpqa\testenv\src\ILComparer\ILComparer.fsproj /p:Configuration=%1 /t:Build
xcopy /Y %~dp0\fsharpqa\testenv\src\ILComparer\bin\%1\* %~dp0\fsharpqa\testenv\bin
msbuild fsharpqa\testenv\src\HostedCompilerServer\HostedCompilerServer.fsproj /p:Configuration=%1 /t:Build
xcopy /Y fsharpqa\testenv\src\HostedCompilerServer\bin\%1\* fsharpqa\testenv\bin
msbuild %~dp0\fsharpqa\testenv\src\HostedCompilerServer\HostedCompilerServer.fsproj /p:Configuration=%1 /t:Build
xcopy /Y %~dp0\fsharpqa\testenv\src\HostedCompilerServer\bin\%1\* %~dp0\fsharpqa\testenv\bin
if exist ..\%1\net40\bin (
xcopy /Y ..\%1\net40\bin\FSharp.Core.sigdata fsharpqa\testenv\bin
xcopy /Y ..\%1\net40\bin\FSharp.Core.optdata fsharpqa\testenv\bin
if exist %~dp0\..\%1\net40\bin (
xcopy /Y %~dp0\..\%1\net40\bin\FSharp.Core.sigdata fsharpqa\testenv\bin
xcopy /Y %~dp0\..\%1\net40\bin\FSharp.Core.optdata fsharpqa\testenv\bin
)
\ No newline at end of file
......@@ -2,44 +2,44 @@
del 3.exe 2>nul 1>nul
type 1.fsx 2.fsx 3.fsx
echo Test 1=================================================
%FSC% 3.fsx --nologo
"%FSC%" 3.fsx --nologo
3.exe
del 3.exe
echo Test 2=================================================
%FSI% 3.fsx
"%FSI%" 3.fsx
echo Test 3=================================================
%FSI% --nologo < pipescr
"%FSI%" --nologo < pipescr
echo.
echo Test 4=================================================
%FSI% usesfsi.fsx
"%FSI%" usesfsi.fsx
echo Test 5=================================================
%FSC% usesfsi.fsx --nologo
"%FSC%" usesfsi.fsx --nologo
echo Test 6=================================================
%FSC% usesfsi.fsx --nologo -r FSharp.Compiler.Interactive.Settings
"%FSC%" usesfsi.fsx --nologo -r FSharp.Compiler.Interactive.Settings
echo Test 7=================================================
%FSI% 1.fsx 2.fsx 3.fsx
"%FSI%" 1.fsx 2.fsx 3.fsx
echo Test 8=================================================
%FSI% 3.fsx 2.fsx 1.fsx
"%FSI%" 3.fsx 2.fsx 1.fsx
echo Test 9=================================================
%FSI% multiple-load-1.fsx
"%FSI%" multiple-load-1.fsx
echo Test 10=================================================
%FSI% multiple-load-2.fsx
"%FSI%" multiple-load-2.fsx
echo Test 11=================================================
%FSC% FlagCheck.fs --nologo
"%FSC%" FlagCheck.fs --nologo
FlagCheck.exe
del FlagCheck.exe
echo Test 12=================================================
%FSC% FlagCheck.fsx --nologo
"%FSC%" FlagCheck.fsx --nologo
FlagCheck.exe
del FlagCheck.exe
echo Test 13=================================================
%FSI% load-FlagCheckFs.fsx
"%FSI%" load-FlagCheckFs.fsx
echo Test 14=================================================
%FSI% FlagCheck.fsx
"%FSI%" FlagCheck.fsx
echo Test 15=================================================
%FSI% ProjectDriver.fsx
"%FSI%" ProjectDriver.fsx
echo Test 16=================================================
%FSC% ProjectDriver.fsx --nologo
"%FSC%" ProjectDriver.fsx --nologo
ProjectDriver.exe
del ProjectDriver.exe
echo Done ==================================================
......@@ -7,29 +7,22 @@ if EXIST build.ok DEL /f /q build.ok
call %~d0%~p0..\..\..\config.bat
if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" (
ECHO Skipping test for FSI.EXE
goto Skip
)
rem fsc.exe building
"%FSC%" %fsc_flags% -o:test.exe -g test.fsx
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% -o:test.exe -g test.fsx
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" test.exe
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" test.exe
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" test--optimize.exe
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" test--optimize.exe
@if ERRORLEVEL 1 goto Error
call ..\..\single-neg-test.bat negativetest
@if ERRORLEVEL 1 goto Error
call ..\..\single-neg-test.bat negativetest
@if ERRORLEVEL 1 goto Error
:Ok
echo Built fsharp %~f0 ok.
......
@if "%_echo%"=="" echo off
setlocal
REM Configure the sample, i.e. where to find the F# compiler and C# compiler.
if EXIST build.ok DEL /f /q build.ok
call %~d0%~p0..\..\..\config.bat
......@@ -9,44 +8,24 @@ call %~d0%~p0..\..\..\config.bat
"%PEVERIFY%" "%FSCOREDLLPATH%"
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\FSharp.Build.dll
"%PEVERIFY%" "%FSCOREDLL20PATH%"
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" "%FSCOREDLLPORTABLEPATH%"
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" "%FSCBinPath%\FSharp.Build.dll"
@if ERRORLEVEL 1 goto Error
if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" (
REM Use /MD because this contains some P/Invoke code
"%PEVERIFY%" /MD %FSCBinPath%\FSharp.Compiler.dll
@if ERRORLEVEL 1 goto Error
REM Use /MD because this contains some P/Invoke code
"%PEVERIFY%" /MD %FSCBinPath%\FSharp.LanguageService.dll
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\FSharp.ProjectSystem.Base.dll
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\FSharp.ProjectSystem.dll
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\fsi.exe
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\FSharp.Compiler.Server.Shared.dll
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" %FSCBinPath%\FSharp.Compiler.Interactive.Settings.dll
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" /MD %FSCBinPath%\FSharp.VisualStudio.Session.dll
@if ERRORLEVEL 1 goto Error
REM Use /MD because this contains some P/Invoke code
"%PEVERIFY%" /MD "%FSCBinPath%\FSharp.Compiler.dll"
@if ERRORLEVEL 1 goto Error
REM Skipping remainder of test for FSI.EXE
goto Ok
"%PEVERIFY%" "%FSCBinPath%\fsi.exe"
@if ERRORLEVEL 1 goto Error
)
"%PEVERIFY%" "%FSCBinPath%\FSharp.Compiler.Interactive.Settings.dll"
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% -o:xmlverify.exe -g xmlverify.fs
@if ERRORLEVEL 1 goto Error
......@@ -60,18 +39,16 @@ call :SetFSCoreXMLPath "%FSCOREDLLPATH%"
%CLIX% xmlverify.exe "%FSHARPCOREXML%"
@if ERRORLEVEL 1 goto Error
:Ok
echo Passed fsharp %~f0 ok.
echo > build.ok
endlocal
exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
:SetFSCoreXMLPath
set FSHARPCOREXML=%~dpn1.xml
goto :EOF
goto :EOF
\ No newline at end of file
......@@ -7,8 +7,10 @@ if errorlevel 1 (
set ERRORMSG=%ERRORMSG% config.bat failed;
goto :ERROR
)
call :check "%FSC%"
if not "%ERRORMSG%"=="" goto :ERROR
if not exist "%FSC%" (
set ERRORMSG=Could not find FSC at path "%FSC%"
goto :ERROR
)
%FSDIFF% %~f0 %~f0
@if ERRORLEVEL 1 (
......@@ -99,10 +101,3 @@ set NonexistentErrorLevel 2> nul
goto Error
goto :EOF
:Check
for /f %%i in ("%1") do (
dir %%i > NUL 2>&1 || (
set ERRORMSG=%ERRORMSG% %1 was not found;
)
)
goto :EOF
......@@ -14,15 +14,14 @@ if errorlevel 1 (
goto :ERROR
)
REM NOTE: There is an expectation here that the full path to FSC, FSi and other tools be given.
REM This is reasonable for testing, because you want to know exactly which binary you are running.
REM Ideally we would use 'where' here, but WinXP does not support that.
REM Trying do define my own WHERE
call :WHERE %FSC%
if errorlevel 1 goto :ERROR
call :WHERE %FSI%
if errorlevel 1 goto :ERROR
if not exist "%FSC%" (
set ERRORMSG=%ERRORMSG% fsc.exe not found at the location "%FSC%"
goto :ERROR
)
if not exist "%FSI%" (
set ERRORMSG=%ERRORMSG% fsi.exe not found at the location "%FSI%"
goto :ERROR
)
set sources=
if exist testlib.fsi (set sources=%sources% testlib.fsi)
......@@ -315,10 +314,4 @@ if NOT EXIST dont.use.wrapper.namespace (
)
)
)
goto :EOF
:WHERE
for /f %%i in ("%~1") do set _WHERE=%%~$PATH:i
if not defined _WHERE set ERRORMSG=%ERRORMSG% %~1 not found;
set _WHERE > NUL 2>&1
goto :EOF
goto :EOF
\ No newline at end of file
......@@ -7,28 +7,25 @@ call %~d0%~p0\..\..\config.bat
if EXIST provided.dll del provided.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided.dll -a ..\helloWorld\provided.fs
"%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST providedJ.dll del providedJ.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedJ.dll -a ..\helloWorld\providedJ.fs
"%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
if errorlevel 1 goto :Error
if EXIST providedK.dll del providedK.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedK.dll -a ..\helloWorld\providedK.fs
"%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
if errorlevel 1 goto :Error
if EXIST provider.dll del provider.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provider.dll -a provider.fsx
"%FSC%" --out:provider.dll -a provider.fsx
if ERRORLEVEL 1 goto :Error
call %~d0%~p0..\single-test-build.bat
......@@ -39,9 +36,6 @@ echo. > build.ok
endlocal
exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
@if "%_echo%"=="" echo off
call %~d0%~p0..\..\..\config.bat
call %~d0%~p0..\..\..\..\config.bat
IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
echo Test not supported except on Ultimate
......
......@@ -7,10 +7,10 @@ call %~d0%~p0\..\..\..\config.bat
if EXIST provider.dll del provider.dll
if errorlevel 1 goto :Error
%FSC% --out:provided.dll -a ..\helloWorld\provided.fs
"%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
%FSC% --out:provider.dll -a ..\helloWorld\provider.fsx
"%FSC%" --out:provider.dll -a ..\helloWorld\provider.fsx
if errorlevel 1 goto :Error
"%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test1.dll -a test1.fsx
......@@ -32,6 +32,4 @@ exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
......@@ -10,40 +10,40 @@ if ERRORLEVEL 1 goto :Error
if EXIST provided1.dll del provided1.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided1.dll -g -a ..\helloWorld\provided.fs
"%FSC%" --out:provided1.dll -g -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST provided2.dll del provided2.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided2.dll -g -a ..\helloWorld\provided.fs
"%FSC%" --out:provided2.dll -g -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST provided3.dll del provided3.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided3.dll -g -a ..\helloWorld\provided.fs
"%FSC%" --out:provided3.dll -g -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST provided4.dll del provided4.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided4.dll -g -a ..\helloWorld\provided.fs
"%FSC%" --out:provided4.dll -g -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST providedJ.dll del providedJ.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedJ.dll -g -a ..\helloWorld\providedJ.fs
"%FSC%" --out:providedJ.dll -g -a ..\helloWorld\providedJ.fs
if errorlevel 1 goto :Error
if EXIST providedK.dll del providedK.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedK.dll -g -a ..\helloWorld\providedK.fs
"%FSC%" --out:providedK.dll -g -a ..\helloWorld\providedK.fs
if errorlevel 1 goto :Error
%FSC% --out:providedNullAssemblyName.dll -g -a ..\helloWorld\providedNullAssemblyName.fsx
"%FSC%" --out:providedNullAssemblyName.dll -g -a ..\helloWorld\providedNullAssemblyName.fsx
if errorlevel 1 goto :Error
call %~d0%~p0\..\build-typeprovider-test.bat
......@@ -58,10 +58,10 @@ xcopy /y ..\*.dll .
if errorlevel 1 goto :Error
%FSC% -g -a -o:test_lib.dll -r:provider.dll ..\test.fsx
"%FSC%" -g -a -o:test_lib.dll -r:provider.dll ..\test.fsx
if ERRORLEVEL 1 goto :Error
%FSC% -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
"%FSC%" -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
if ERRORLEVEL 1 goto :Error
popd
......@@ -72,26 +72,24 @@ xcopy /y ..\bincompat1\*.dll .
REM overwrite provider.dll
%FSC% --define:ADD_AN_OPTIONAL_STATIC_PARAMETER --out:provider.dll -g -a ..\provider.fsx
"%FSC%" --define:ADD_AN_OPTIONAL_STATIC_PARAMETER --out:provider.dll -g -a ..\provider.fsx
if ERRORLEVEL 1 goto :Error
REM This is the important part of the binary compatibility part of the test: the new provider is being used, but
REM with a binary that was generated w.r.t. the old provider. The new provider can still resolve the references
REM generated by the old provider which are stored in the F# metadata for test_lib.dll
%FSC% --define:ADD_AN_OPTIONAL_STATIC_PARAMETER -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
"%FSC%" --define:ADD_AN_OPTIONAL_STATIC_PARAMETER -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
if ERRORLEVEL 1 goto :Error
%PEVERIFY% provider.dll
"%PEVERIFY%" provider.dll
if ERRORLEVEL 1 goto :Error
%PEVERIFY% test_lib.dll
"%PEVERIFY%" test_lib.dll
if ERRORLEVEL 1 goto :Error
%PEVERIFY% testlib_client.exe
"%PEVERIFY%" testlib_client.exe
if ERRORLEVEL 1 goto :Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
......@@ -7,7 +7,7 @@ call %~d0%~p0\..\..\..\config.bat
if EXIST magic.dll del magic.dll
if errorlevel 1 goto :Error
%FSC% --out:magic.dll -a magic.fs --keyfile:magic.snk
"%FSC%" --out:magic.dll -a magic.fs --keyfile:magic.snk
if errorlevel 1 goto :Error
REM == If we are running this test on a lab machine, we may not be running from an elev cmd prompt
......@@ -18,15 +18,14 @@ if errorlevel 1 goto :Error
if EXIST provider.dll del provider.dll
if ERRORLEVEL 1 goto :Error
%CSC% /out:provider.dll /target:library /r:"%FSCOREDLLPATH%" /r:magic.dll provider.cs
%CSC% /out:provider.dll /target:library "/r:%FSCOREDLLPATH%" /r:magic.dll provider.cs
if ERRORLEVEL 1 goto :Error
%GACUTIL% /if magic.dll
"%GACUTIL%" /if magic.dll
"%FSC%" %fsc_flags% /debug+ /r:provider.dll /optimize- test.fsx
if ERRORLEVEL 1 goto Error
:Ok
echo. > build.ok
endlocal
......@@ -34,6 +33,4 @@ exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
......@@ -8,43 +8,43 @@ call %~d0%~p0..\..\..\config.bat
if EXIST provided.dll del provided.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provided.dll -a ..\helloWorld\provided.fs
"%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST providedJ.dll del providedJ.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedJ.dll -a ..\helloWorld\providedJ.fs
"%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
if errorlevel 1 goto :Error
if EXIST providedK.dll del providedK.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:providedK.dll -a ..\helloWorld\providedK.fs
"%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
if errorlevel 1 goto :Error
if EXIST provider.dll del provider.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:provider.dll -a provider.fsx
"%FSC%" --out:provider.dll -a provider.fsx
if ERRORLEVEL 1 goto :Error
%FSC% --out:provider_providerAttributeErrorConsume.dll -a providerAttributeError.fsx
"%FSC%" --out:provider_providerAttributeErrorConsume.dll -a providerAttributeError.fsx
if ERRORLEVEL 1 goto :Error
%FSC% --out:provider_ProviderAttribute_EmptyConsume.dll -a providerAttribute_Empty.fsx
"%FSC%" --out:provider_ProviderAttribute_EmptyConsume.dll -a providerAttribute_Empty.fsx
if ERRORLEVEL 1 goto :Error
if EXIST helloWorldProvider.dll del helloWorldProvider.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:helloWorldProvider.dll -a ..\helloWorld\provider.fsx
"%FSC%" --out:helloWorldProvider.dll -a ..\helloWorld\provider.fsx
if ERRORLEVEL 1 goto :Error
if EXIST MostBasicProvider.dll del MostBasicProvider.dll
if ERRORLEVEL 1 goto :Error
%FSC% --out:MostBasicProvider.dll -a MostBasicProvider.fsx
"%FSC%" --out:MostBasicProvider.dll -a MostBasicProvider.fsx
if ERRORLEVEL 1 goto :Error
set FAILURES=
......@@ -104,7 +104,7 @@ exit /b 0
:RunTestWithDefine
%FSC% --define:%1 --out:provider_%1.dll -a provider.fsx
"%FSC%" --define:%1 --out:provider_%1.dll -a provider.fsx
if ERRORLEVEL 1 goto :Error
:RunTest
......@@ -121,6 +121,6 @@ set FAILURES=%FAILURES% %1
GOTO :EOF
:Preprocess
fsi --exec sed.fsx "<ASSEMBLY>" "%~d0%~p0provider_%1.dll" < %~1.%~2bslpp | fsi --exec sed.fsx "<URIPATH>" "file:///%CD%\\" > %~1.%~2bsl
"%FSI%" --exec sed.fsx "<ASSEMBLY>" "%~d0%~p0provider_%1.dll" < %~1.%~2bslpp | fsi --exec sed.fsx "<URIPATH>" "file:///%CD%\\" > %~1.%~2bsl
goto :EOF
goto :EOF
\ No newline at end of file
......@@ -5,11 +5,10 @@ REM Configure the sample, i.e. where to find the F# compiler and C# compiler.
call %~d0%~p0..\..\..\config.bat
%FSC% --out:provider.dll -a provider.fs
"%FSC%" --out:provider.dll -a provider.fs
if errorlevel 1 goto :Error
%FSC% --out:providerDesigner.dll -a providerDesigner.fsx
"%FSC%" --out:providerDesigner.dll -a providerDesigner.fsx
call %~d0%~p0..\..\single-test-build.bat
goto :Ok
......@@ -19,8 +18,6 @@ echo. > build.ok
endlocal
exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
......@@ -10,24 +10,22 @@ if errorlevel 1 goto :Error
if EXIST provided.dll del provided.dll
if errorlevel 1 goto :Error
%FSC% --out:provided.dll -a ..\helloWorld\provided.fs
"%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
if errorlevel 1 goto :Error
if EXIST providedJ.dll del providedJ.dll
if errorlevel 1 goto :Error
%FSC% --out:providedJ.dll -a ..\helloWorld\providedJ.fs
"%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
if errorlevel 1 goto :Error
if EXIST providedK.dll del providedK.dll
if errorlevel 1 goto :Error
%FSC% --out:providedK.dll -a ..\helloWorld\providedK.fs
"%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
if errorlevel 1 goto :Error
%FSC% --out:provider.dll -a ..\helloWorld\provider.fsx
"%FSC%" --out:provider.dll -a ..\helloWorld\provider.fsx
if errorlevel 1 goto :Error
"%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2a.dll -a test2a.fs
......@@ -57,7 +55,6 @@ if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test3-with-sig-restricted.exe --define:SIGS_RESTRICTED test3.fsx
if ERRORLEVEL 1 goto Error
:Ok
echo. > build.ok
endlocal
......@@ -65,6 +62,4 @@ exit /b 0
:Error
endlocal
exit /b %ERRORLEVEL%
exit /b %ERRORLEVEL%
\ No newline at end of file
......@@ -17,6 +17,15 @@ call ..\..\single-neg-test.bat neg91
pos15.exe
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% --target:exe -o:pos14.exe pos14.fs
@if ERRORLEVEL 1 goto Error
"%PEVERIFY%" pos14.exe
@if ERRORLEVEL 1 goto Error
pos14.exe
@if ERRORLEVEL 1 goto Error
"%FSC%" %fsc_flags% --target:exe -o:pos13.exe pos13.fs
@if ERRORLEVEL 1 goto Error
......
open System
type A<'T>() = static member M([<ParamArray>] args: 'T[]) = args
let m (args: 'T[]) = A<'T>.M(args)
......@@ -16,20 +16,41 @@ type Foo() =
[<AttributeWithParamArray([| ("foo" :> obj); ("bar" :> obj) |])>]
override this.ToString() = "Stuff"
let callCSGenericMethod (a: 't[]) = CSParamArray.Method(a)
[<assembly:AttributeWithParamArray ([| |])>]
do
let testPassed =
let getTestAttribute (t : Type) =
let tyAttributes = t.GetCustomAttributes(false)
let attrib = tyAttributes |> Array.find (fun attrib -> match attrib with :? AttributeWithParamArray -> true | _ -> false)
(attrib :?> AttributeWithParamArray)
let tyFoo = typeof<Foo>
let testAtt = getTestAttribute tyFoo
if testAtt.Parameters <> [| (0 :> obj) |] then
false
else
true
if not testPassed then exit 1
let getTestAttribute (t : Type) =
let tyAttributes = t.GetCustomAttributes(false)
let attrib = tyAttributes |> Array.find (fun attrib -> match attrib with :? AttributeWithParamArray -> true | _ -> false)
(attrib :?> AttributeWithParamArray)
let tyFoo = typeof<Foo>
let testAtt = getTestAttribute tyFoo
if testAtt.Parameters <> [| (0 :> obj) |] then
printfn "Attribute parameters not as expected"
exit 1
let directCallWorks =
CSParamArray.Method(9, 8, 7) + CSParamArray.Method(1, 2) + CSParamArray.Method() = (9 + 8 + 7) + (1 + 2)
if not directCallWorks then
printfn "Calling C# param array method gave unexpected result"
exit 1
let callParamArray (x : int array) = CSParamArray.Method(x)
let asArrayCallWorks = (callParamArray [| 9; 8; 7 |]) = (9 + 8 + 7)
if not asArrayCallWorks then
printfn "Calling C# param array method, passing args as an array, gave unexpected result"
exit 1
if callCSGenericMethod [|"1";"2";"3"|] <> 3 then
printfn "Calling C# generic param array method gave unexpected result"
exit 1
if CSParamArray.Method("1", "2", "3") <> CSParamArray.Method([|"1"; "2"; "3"|]) then
printfn "Calling C# generic param array in normal and expanded method gave unexpected result"
exit 1
exit 0
\ No newline at end of file
......@@ -12,7 +12,7 @@ module NativeMethods =
type EnumResourceNamesCallback = delegate of IntPtr * IntPtr * IntPtr * IntPtr -> bool
[<DllImport("kernel32.dll")>]
extern IntPtr LoadLibrary(char[] lpFileName)
extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, uint32 dwFlags)
[<DllImport("kernel32.dll")>]
extern bool EnumResourceNames(IntPtr hModule, int dwID, EnumResourceNamesCallback lpEnumFunc, IntPtr lParam)
......@@ -31,6 +31,9 @@ module NativeMethods =
// ID of the manifest win32 resource type
let RT_MANIFEST = 24
// dwFlags to indicate that we are only loading binaries to read data, not to execute
let LOAD_LIBRARY_AS_DATAFILE = 2u
/// extracts the win32 manifest of the specified assembly
let getManifest (path:string) =
......@@ -51,8 +54,12 @@ let getManifest (path:string) =
true
)
let hLib = NativeMethods.LoadLibrary(path.ToCharArray())
NativeMethods.EnumResourceNames(hLib, NativeMethods.RT_MANIFEST, callback, IntPtr.Zero) |> ignore
let hLib = NativeMethods.LoadLibraryEx(path, IntPtr.Zero, NativeMethods.LOAD_LIBRARY_AS_DATAFILE)
if hLib = IntPtr.Zero then
printfn "Error loading library %s" path
exit 1
else
NativeMethods.EnumResourceNames(hLib, NativeMethods.RT_MANIFEST, callback, IntPtr.Zero) |> ignore
!manifest
let exePath = System.Reflection.Assembly.GetExecutingAssembly().Location
......
......@@ -2,38 +2,32 @@
namespace CSharpAssembly
{
[AttributeUsage(AttributeTargets.All)]
public class AttributeWithParamArray : Attribute
{
public object[] Parameters;
[AttributeUsage(AttributeTargets.All)]
public class AttributeWithParamArray : Attribute
{
public object[] Parameters;
public AttributeWithParamArray(params object[] x)
{
public AttributeWithParamArray(params object[] x)
{
Parameters = x;
}
}
Parameters = x;
}
}
public class Foo
{
static int Main(string[] args)
{
Console.WriteLine(Foo.Method());
Console.WriteLine(Foo.Method(1));
Console.WriteLine(Foo.Method(1, 2));
Console.WriteLine(Foo.Method(1, 2, 3));
Console.WriteLine(Foo.Method(1, 2, 3, 4));
public class CSParamArray
{
public static int Method(params int[] allArgs)
{
int total = 0;
foreach (int i in allArgs)
total += i;
return 0;
}
return total;
}
static int Method(params int[] allArgs)
{
int total = 0;
foreach (int i in allArgs)
total += i;
return total;
}
}
public static int Method<T>(params T[] args)
{
return args.Length;
}
}
}
\ No newline at end of file
SOURCE=ConsumeParamArray.fsscript # ConsumeParamArray.fsscript
SOURCE=E_ConsumeParamArray.fsscript # E_ConsumeParamArray.fsscript
PRECMD="\$CSC_PIPE /target:library ParamArray.cs" SOURCE=ConsumeParamArray.fsscript # ConsumeParamArray.fsscript
PRECMD="\$CSC_PIPE /target:library ParamArray.cs" SOURCE=E_ConsumeParamArray.fsscript # E_ConsumeParamArray.fsscript
SOURCE=E_productioncoverage01.fs # E_productioncoverage01.fs
SOURCE=E_productioncoverage02.fs # E_productioncoverage02.fs
......@@ -18,7 +18,7 @@
# Apparently, 'GetManifestResourceInfo' does not exist on Mono -> disabling
NOMONO SOURCE=WhetherEmbededManifest.fs # WhetherEmbededManifest.fs
PRECMD="\$FSC_PIPE -a DefaultManifest_dll.fs" SCFLAGS="-r:DefaultManifest_dll.dll" SOURCE=DefaultManifest.fs # DefaultManifest.fs
PRECMD="\$FSC_PIPE \$ISCFLAGS -a DefaultManifest_dll.fs" SCFLAGS="-r:DefaultManifest_dll.dll" SOURCE=DefaultManifest.fs # DefaultManifest.fs
SOURCE=UserCodeSnippet01.fs SCFLAGS=-a # UserCodeSnippet01.fs
......
......@@ -6,17 +6,17 @@ goto :Label%2 %1
:LabelYYY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
%FSC% -g -a --define:VER1111 --keyfile:keyfile2.snk MyTPDesignTime.fs
"%FSC%" -g -a --define:VER1111 --keyfile:keyfile2.snk MyTPDesignTime.fs
goto :EOF
:LabelYYN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
del MyTPDesignTime.dll
goto :EOF
......@@ -24,8 +24,8 @@ goto :EOF
:LabelYNY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
goto :EOF
......@@ -33,8 +33,8 @@ goto :EOF
:LabelYNN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:WITHDLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
del MyTPDesignTime.dll
goto :EOF
......@@ -43,16 +43,16 @@ goto :EOF
:LabelNFYY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
goto :EOF
:LabelNFYN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
del MyTPDesignTime.dll
goto :EOF
......@@ -61,16 +61,16 @@ goto :EOF
:LabelNFNY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
goto :EOF
:LabelNFNN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:FULLNAME -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
del MyTPDesignTime.dll
goto :EOF
......@@ -79,18 +79,18 @@ goto :EOF
:LabelNYY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
%FSC% -g -a --define:VER1111 --keyfile:keyfile2.snk MyTPDesignTime.fs
"%FSC%" -g -a --define:VER1111 --keyfile:keyfile2.snk MyTPDesignTime.fs
goto :EOF
REM == bug 381797
:LabelNYN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /if MyTPDesignTime.dll
del MyTPDesignTime.dll
goto :EOF
......@@ -98,16 +98,16 @@ goto :EOF
:LabelNNY
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
goto :EOF
:LabelNNN
set FSC=%~1
%FSC% -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
%FSC% -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
"%FSC%" -g -a --keyfile:keyfile.snk MyTPDesignTime.fs
"%FSC%" -g -a --keyfile:keyfile.snk --define:NODLLEXT -r:MyTPDesignTime.dll MyTPRuntime.fs
%GACUTIL% /uf MyTPDesignTime
del MyTPDesignTime.dll
goto :EOF
......
......@@ -155,6 +155,7 @@ if (exists($ENV{PRECMD})) {
s/^\$FSC_PIPE/$FSC_PIPE/;
s/^\$FSI_PIPE/$FSI_PIPE/;
s/^\$FSI32_PIPE/$FSI32_PIPE/;
s/\$ISCFLAGS/$ISCFLAGS/;
s/^\$CSC_PIPE/$CSC_PIPE/;
RunExit(TEST_FAIL, "Fail to execute the PRECMD" . @CommandOutput . "\n") if RunCommand("PRECMD",$_ ,1);
}
......
......@@ -59,7 +59,7 @@
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Private>True</Private>
</Reference>
<Reference Include="FSharp.Compiler.dll, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Reference Include="..\..\bin\FSharp.Compiler.dll">
<Private>True</Private>
</Reference>
</ItemGroup>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册