diff --git a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index 166dc7976b7..dcdf91eef4a 100644 --- a/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/fcs/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -483,6 +483,9 @@ CodeGen/IlxGen.fs + + Driver\DotNetFrameworkDependencies.fs + Driver/CompileOps.fsi diff --git a/src/buildfromsource/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/buildfromsource/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj index 6be5ea1e37d..058cf0e1b61 100644 --- a/src/buildfromsource/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj +++ b/src/buildfromsource/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj @@ -454,6 +454,9 @@ + + Driver\DotNetFrameworkDependencies.fs + Driver\CompileOps.fsi diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 33216b30e5e..e14df2d3fb6 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -45,6 +45,8 @@ open FSharp.Compiler.Tast open FSharp.Compiler.Tastops open FSharp.Compiler.TcGlobals +open FSharp.Compiler.DotNetFrameworkDependencies + #if !NO_EXTENSIONTYPING open FSharp.Compiler.ExtensionTyping open Microsoft.FSharp.Core.CompilerServices @@ -1778,223 +1780,9 @@ let OutputDiagnosticContext prefix fileLineFn os err = Printf.bprintf os "%s%s\n" prefix line Printf.bprintf os "%s%s%s\n" prefix (String.make iA '-') (String.make iLen '^') -//---------------------------------------------------------------------------- - -let GetFSharpCoreLibraryName () = "FSharp.Core" - -// If necessary assume a reference to the latest .NET Framework FSharp.Core with which those tools are built. -let GetDefaultFSharpCoreReference () = typeof>.Assembly.Location - -type private TypeInThisAssembly = class end - -// Use the ValueTuple that is executing with the compiler if it is from System.ValueTuple -// or the System.ValueTuple.dll that sits alongside the compiler. (Note we always ship one with the compiler) -let GetDefaultSystemValueTupleReference () = - try - let asm = typeof>.Assembly - if asm.FullName.StartsWithOrdinal("System.ValueTuple") then - Some asm.Location - else - let location = Path.GetDirectoryName(typeof.Assembly.Location) - let valueTuplePath = Path.Combine(location, "System.ValueTuple.dll") - if File.Exists(valueTuplePath) then - Some valueTuplePath - else - None - with _ -> None - -let GetFsiLibraryName () = "FSharp.Compiler.Interactive.Settings" - -// This list is the default set of references for "non-project" files. -// -// These DLLs are -// (a) included in the environment used for all .fsx files (see service.fs) -// (b) included in environment for files 'orphaned' from a project context -// -- for orphaned files (files in VS without a project context) -// -- for files given on a command line without --noframework set -let DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) = - [ if assumeDotNetFramework then - yield "System" - yield "System.Xml" - yield "System.Runtime.Remoting" - yield "System.Runtime.Serialization.Formatters.Soap" - yield "System.Data" - yield "System.Drawing" - yield "System.Core" - - // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed - // when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers - // to FSharp.Core for profile 7, 78, 259 or .NET Standard. - yield "System.Runtime" // lots of types - yield "System.Linq" // System.Linq.Expressions.Expression - yield "System.Reflection" // System.Reflection.ParameterInfo - yield "System.Linq.Expressions" // System.Linq.IQueryable - yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken - yield "System.IO" // System.IO.TextWriter - //yield "System.Console" // System.Console.Out etc. - yield "System.Net.Requests" // System.Net.WebResponse etc. - yield "System.Collections" // System.Collections.Generic.List - yield "System.Runtime.Numerics" // BigInteger - yield "System.Threading" // OperationCanceledException - - // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources - match GetDefaultSystemValueTupleReference() with - | None -> () - | Some v -> yield v - - yield "System.Web" - yield "System.Web.Services" - yield "System.Windows.Forms" - yield "System.Numerics" - else - yield Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "mscorlib.dll") // mscorlib - yield typeof.Assembly.Location // System.Console - yield typeof.Assembly.Location // System.Collections - yield typeof.Assembly.Location // System.ObjectModel - yield typeof.Assembly.Location // System.IO.FileSystem - yield typeof.Assembly.Location // System.IO - yield typeof.Assembly.Location // System.Linq - yield typeof.Assembly.Location // System.Xml - yield typeof.Assembly.Location // System.Xml.Linq - yield typeof.Assembly.Location // System.Net.Requests - yield typeof.Assembly.Location // System.Runtime.Numerics - yield typeof.Assembly.Location // System.Net.Security - yield typeof.Assembly.Location // System.Security.Claims - yield typeof.Assembly.Location // System.Text.RegularExpressions.Regex - yield typeof.Assembly.Location // System.Threading.Tasks - yield typeof.Assembly.Location // System.Threading - yield typeof.Assembly.Location // FSharp.Core - ] - - -// A set of assemblies to always consider to be system assemblies. A common set of these can be used a shared -// resources between projects in the compiler services. Also all assembles where well-known system types exist -// referenced from TcGlobals must be listed here. -let SystemAssemblies () = - HashSet - [ yield "mscorlib" - yield "netstandard" - yield "System.Runtime" - yield GetFSharpCoreLibraryName() - yield "System" - yield "System.Xml" - yield "System.Runtime.Remoting" - yield "System.Runtime.Serialization.Formatters.Soap" - yield "System.Data" - yield "System.Deployment" - yield "System.Design" - yield "System.Messaging" - yield "System.Drawing" - yield "System.Net" - yield "System.Web" - yield "System.Web.Services" - yield "System.Windows.Forms" - yield "System.Core" - yield "System.Runtime" - yield "System.Observable" - yield "System.Numerics" - yield "System.ValueTuple" - - // Additions for coreclr and portable profiles - yield "System.Collections" - yield "System.Collections.Concurrent" - yield "System.Console" - yield "System.Diagnostics.Debug" - yield "System.Diagnostics.Tools" - yield "System.Globalization" - yield "System.IO" - yield "System.Linq" - yield "System.Linq.Expressions" - yield "System.Linq.Queryable" - yield "System.Net.Requests" - yield "System.Reflection" - yield "System.Reflection.Emit" - yield "System.Reflection.Emit.ILGeneration" - yield "System.Reflection.Extensions" - yield "System.Resources.ResourceManager" - yield "System.Runtime.Extensions" - yield "System.Runtime.InteropServices" - yield "System.Runtime.InteropServices.PInvoke" - yield "System.Runtime.Numerics" - yield "System.Text.Encoding" - yield "System.Text.Encoding.Extensions" - yield "System.Text.RegularExpressions" - yield "System.Threading" - yield "System.Threading.Tasks" - yield "System.Threading.Tasks.Parallel" - yield "System.Threading.Thread" - yield "System.Threading.ThreadPool" - yield "System.Threading.Timer" - - yield "FSharp.Compiler.Interactive.Settings" - yield "Microsoft.Win32.Registry" - yield "System.Diagnostics.Tracing" - yield "System.Globalization.Calendars" - yield "System.Reflection.Primitives" - yield "System.Runtime.Handles" - yield "Microsoft.Win32.Primitives" - yield "System.IO.FileSystem" - yield "System.Net.Primitives" - yield "System.Net.Sockets" - yield "System.Private.Uri" - yield "System.AppContext" - yield "System.Buffers" - yield "System.Collections.Immutable" - yield "System.Diagnostics.DiagnosticSource" - yield "System.Diagnostics.Process" - yield "System.Diagnostics.TraceSource" - yield "System.Globalization.Extensions" - yield "System.IO.Compression" - yield "System.IO.Compression.ZipFile" - yield "System.IO.FileSystem.Primitives" - yield "System.Net.Http" - yield "System.Net.NameResolution" - yield "System.Net.WebHeaderCollection" - yield "System.ObjectModel" - yield "System.Reflection.Emit.Lightweight" - yield "System.Reflection.Metadata" - yield "System.Reflection.TypeExtensions" - yield "System.Runtime.InteropServices.RuntimeInformation" - yield "System.Runtime.Loader" - yield "System.Security.Claims" - yield "System.Security.Cryptography.Algorithms" - yield "System.Security.Cryptography.Cng" - yield "System.Security.Cryptography.Csp" - yield "System.Security.Cryptography.Encoding" - yield "System.Security.Cryptography.OpenSsl" - yield "System.Security.Cryptography.Primitives" - yield "System.Security.Cryptography.X509Certificates" - yield "System.Security.Principal" - yield "System.Security.Principal.Windows" - yield "System.Threading.Overlapped" - yield "System.Threading.Tasks.Extensions" - yield "System.Xml.ReaderWriter" - yield "System.Xml.XDocument" - - ] - -// The set of references entered into the TcConfigBuilder for scripts prior to computing -// the load closure. -// -// REVIEW: it isn't clear if there is any negative effect -// of leaving an assembly off this list. -let BasicReferencesForScriptLoadClosure(useFsiAuxLib, assumeDotNetFramework) = - [ - if assumeDotNetFramework then - -#if COMPILER_SERVICE_ASSUMES_DOTNETCORE_COMPILATION - yield Path.Combine(Path.GetDirectoryName(typeof.Assembly.Location), "mscorlib.dll"); // mscorlib -#else - yield "mscorlib" -#endif - yield GetDefaultFSharpCoreReference() ] @ // Need to resolve these explicitly so they will be found in the reference assemblies directory which is where the .xml files are. - DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) @ - [ if useFsiAuxLib then yield GetFsiLibraryName () ] - let (++) x s = x @ [s] - //---------------------------------------------------------------------------- // General file name resolver //-------------------------------------------------------------------------- @@ -2357,11 +2145,7 @@ type TcConfigBuilder = static member Initial = { -#if COMPILER_SERVICE_ASSUMES_DOTNETCORE_COMPILATION - primaryAssembly = PrimaryAssembly.System_Runtime // defaut value, can be overridden using the command line switch -#else primaryAssembly = PrimaryAssembly.Mscorlib // defaut value, can be overridden using the command line switch -#endif light = None noFeedback = false stackReserveSize = None @@ -2771,11 +2555,11 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = // Look for an explicit reference to mscorlib and use that to compute clrRoot and targetFrameworkVersion let primaryAssemblyReference, primaryAssemblyExplicitFilenameOpt = computeKnownDllReference(data.primaryAssembly.Name) let fslibReference, fslibExplicitFilenameOpt = - let (_, fileNameOpt) as res = computeKnownDllReference(GetFSharpCoreLibraryName()) + let (_, fileNameOpt) as res = computeKnownDllReference(getFSharpCoreLibraryName) match fileNameOpt with | None -> // if FSharp.Core was not provided explicitly - use version that was referenced by compiler - AssemblyReference(range0, GetDefaultFSharpCoreReference(), None), None + AssemblyReference(range0, getDefaultFSharpCoreReference, None), None | _ -> res // If either mscorlib.dll/System.Runtime.dll/netstandard.dll or FSharp.Core.dll are explicitly specified then we require the --noframework flag. @@ -2813,7 +2597,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = #endif None, data.legacyReferenceResolver.HighestInstalledNetFrameworkVersion() - let systemAssemblies = SystemAssemblies () + let systemAssemblies = systemAssemblies // Look for an explicit reference to FSharp.Core and use that to compute fsharpBinariesDir // FUTURE: remove this, we only read the binary for the exception it raises @@ -3719,11 +3503,11 @@ type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list, let assumeDotNetFramework = primaryReference.SimpleAssemblyNameIs("mscorlib") if tcConfig.framework then - for s in DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) do + for s in defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework do yield AssemblyReference(rangeStartup, (if s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then s else s+".dll"), None) if tcConfig.useFsiAuxLib then - let name = Path.Combine(tcConfig.fsharpBinariesDir, GetFsiLibraryName() + ".dll") + let name = Path.Combine(tcConfig.fsharpBinariesDir, getFsiLibraryName + ".dll") yield AssemblyReference(rangeStartup, name, None) yield! tcConfig.referencedDLLs @@ -3817,7 +3601,7 @@ let WriteSignatureData (tcConfig: TcConfig, tcGlobals, exportRemapping, ccu: Ccu let mspec = ApplyExportRemappingToEntity tcGlobals exportRemapping mspec // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers // don't complain when they see the resource. - let rname = if ccu.AssemblyName = GetFSharpCoreLibraryName() then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName + let rname = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpSignatureDataResourceName2 else FSharpSignatureDataResourceName PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) pickleCcuInfo { mspec=mspec compileTimeWorkingDir=tcConfig.implicitIncludeDir @@ -3829,7 +3613,7 @@ let GetOptimizationData (file, ilScopeRef, ilModule, byteReader) = let WriteOptimizationData (tcGlobals, file, inMem, ccu: CcuThunk, modulInfo) = // For historical reasons, we use a different resource name for FSharp.Core, so older F# compilers // don't complain when they see the resource. - let rname = if ccu.AssemblyName = GetFSharpCoreLibraryName() then FSharpOptimizationDataResourceName2 else FSharpOptimizationDataResourceName + let rname = if ccu.AssemblyName = getFSharpCoreLibraryName then FSharpOptimizationDataResourceName2 else FSharpOptimizationDataResourceName PickleToResource inMem file tcGlobals ccu (rname+ccu.AssemblyName) Optimizer.p_CcuOptimizationInfo modulInfo //---------------------------------------------------------------------------- @@ -3942,7 +3726,13 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu if disposed then assert false static let ccuHasType (ccu: CcuThunk) (nsname: string list) (tname: string) = - match (Some ccu.Contents, nsname) ||> List.fold (fun entityOpt n -> match entityOpt with None -> None | Some entity -> entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind n) with + let matchNameSpace (entityOpt: Entity option) n = + match entityOpt with + | None -> None + | Some entity -> + entity.ModuleOrNamespaceType.AllEntitiesByCompiledAndLogicalMangledNames.TryFind n + + match (Some ccu.Contents, nsname) ||> List.fold(matchNameSpace) with | Some ns -> match Map.tryFind tname ns.ModuleOrNamespaceType.TypesByMangledName with | Some _ -> true @@ -4759,7 +4549,7 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu let fslibCcu = if tcConfig.compilingFslib then // When compiling FSharp.Core.dll, the fslibCcu reference to FSharp.Core.dll is a delayed ccu thunk fixed up during type checking - CcuThunk.CreateDelayed(GetFSharpCoreLibraryName()) + CcuThunk.CreateDelayed(getFSharpCoreLibraryName) else let fslibCcuInfo = let coreLibraryReference = tcConfig.CoreLibraryDllReference() @@ -4771,7 +4561,7 @@ type TcImports(tcConfigP: TcConfigProvider, initialResolutions: TcAssemblyResolu // Are we using a "non-canonical" FSharp.Core? match tcAltResolutions.TryFindByOriginalReference coreLibraryReference with | Some resolution -> Some resolution - | _ -> tcResolutions.TryFindByOriginalReferenceText (GetFSharpCoreLibraryName()) // was the ".dll" elided? + | _ -> tcResolutions.TryFindByOriginalReferenceText (getFSharpCoreLibraryName) // was the ".dll" elided? match resolvedAssemblyRef with | Some coreLibraryResolution -> @@ -5106,7 +4896,7 @@ module private ScriptPreprocessClosure = applyCommandLineArgs tcConfigB match basicReferences with - | None -> BasicReferencesForScriptLoadClosure(useFsiAuxLib, assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references + | None -> (basicReferencesForScriptLoadClosure useFsiAuxLib assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references | Some rs -> for m, r in rs do tcConfigB.AddReferencedAssemblyByPath(m, r) tcConfigB.resolutionEnvironment <- @@ -5116,7 +4906,7 @@ module private ScriptPreprocessClosure = | CodeContext.CompilationAndEvaluation -> ResolutionEnvironment.CompilationAndEvaluation tcConfigB.framework <- false tcConfigB.useSimpleResolution <- useSimpleResolution - // Indicates that there are some references not in BasicReferencesForScriptLoadClosure which should + // Indicates that there are some references not in basicReferencesForScriptLoadClosure which should // be added conditionally once the relevant version of mscorlib.dll has been detected. tcConfigB.implicitlyResolveAssemblies <- false TcConfig.Create(tcConfigB, validate=true) @@ -5651,3 +5441,7 @@ let TypeCheckClosedInputSet (ctok, checkForErrors, tcConfig, tcImports, tcGlobal let (tcEnvAtEndOfLastFile, topAttrs, implFiles, _), tcState = TypeCheckMultipleInputsFinish(results, tcState) let tcState, declaredImpls = TypeCheckClosedInputSetFinish (implFiles, tcState) tcState, topAttrs, declaredImpls, tcEnvAtEndOfLastFile + +// Existing public APIs delegate to newer implementations +let GetFSharpCoreLibraryName () = getFSharpCoreLibraryName +let DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework \ No newline at end of file diff --git a/src/fsharp/DotNetFrameworkDependencies.fs b/src/fsharp/DotNetFrameworkDependencies.fs new file mode 100644 index 00000000000..16d9f70f77d --- /dev/null +++ b/src/fsharp/DotNetFrameworkDependencies.fs @@ -0,0 +1,245 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +// Functions to retrieve framework dependencies + + +module internal FSharp.Compiler.DotNetFrameworkDependencies + + open System + open System.Collections.Generic + open System.IO + open System.Reflection + + type private TypeInThisAssembly = class end + + let getFSharpCoreLibraryName = "FSharp.Core" + let getFsiLibraryName = "FSharp.Compiler.Interactive.Settings" + let frameworkDir = Path.GetDirectoryName(typeof.Assembly.Location) + let getDefaultFSharpCoreReference = typeof.Assembly.Location + let getFSharpCompilerLocation = Path.GetDirectoryName(typeof.Assembly.Location) + + // Use the ValueTuple that is executing with the compiler if it is from System.ValueTuple + // or the System.ValueTuple.dll that sits alongside the compiler. (Note we always ship one with the compiler) + let getDefaultSystemValueTupleReference () = + try + let asm = typeof>.Assembly + if asm.FullName.StartsWith("System.ValueTuple", StringComparison.OrdinalIgnoreCase) then + Some asm.Location + else + let location = Path.GetDirectoryName(typeof.Assembly.Location) + let valueTuplePath = Path.Combine(location, "System.ValueTuple.dll") + if File.Exists(valueTuplePath) then + Some valueTuplePath + else + None + with _ -> None + + let getDependenciesOf assemblyReferences = + let assemblies = new Dictionary() + + // Identify path to a dll in the framework directory from a simple name + let frameworkPathFromSimpleName simpleName = + let pathDll = Path.Combine(frameworkDir, simpleName + ".dll") + if not (File.Exists(pathDll)) then + let pathExe = Path.Combine(frameworkDir, simpleName + ".exe") + if not (File.Exists(pathExe)) then + pathDll + else + pathExe + else + pathDll + + // Collect all assembly dependencies into assemblies dictionary + let rec traverseDependencies reference = + // Reference can be either path to a file on disk or a Assembly Simple Name + let referenceName, path = + try + if File.Exists(reference) then + // Reference is a path to a file on disk + Path.GetFileNameWithoutExtension(reference), reference + else + // Reference is a SimpleAssembly name + reference, frameworkPathFromSimpleName reference + + with _ -> reference, frameworkPathFromSimpleName reference + + if not (assemblies.ContainsKey(referenceName)) then + try + assemblies.Add(referenceName, path) |> ignore + if referenceName <> "System.Private.CoreLib" then + let asm = System.Reflection.Assembly.LoadFrom(path) + for reference in asm.GetReferencedAssemblies() do + // System.Private.CoreLib doesn't load with reflection + traverseDependencies reference.Name + with e -> () + + assemblyReferences |> List.iter(traverseDependencies) + assemblies + + // This list is the default set of references for "non-project" files. + // + // These DLLs are + // (a) included in the environment used for all .fsx files (see service.fs) + // (b) included in environment for files 'orphaned' from a project context + // -- for orphaned files (files in VS without a project context) + // -- for files given on a command line without --noframework set + let getDesktopDefaultReferences useFsiAuxLib = [ + yield "mscorlib" + yield "System" + yield "System.Xml" + yield "System.Runtime.Remoting" + yield "System.Runtime.Serialization.Formatters.Soap" + yield "System.Data" + yield "System.Drawing" + yield "System.Core" + yield getDefaultFSharpCoreReference + if useFsiAuxLib then yield getFsiLibraryName + + // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources + match getDefaultSystemValueTupleReference() with + | None -> () + | Some v -> yield v + + // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed + // when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers + // to FSharp.Core for profile 7, 78, 259 or .NET Standard. + yield "netstandard" + yield "System.Runtime" // lots of types + yield "System.Linq" // System.Linq.Expressions.Expression + yield "System.Reflection" // System.Reflection.ParameterInfo + yield "System.Linq.Expressions" // System.Linq.IQueryable + yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken + yield "System.IO" // System.IO.TextWriter + yield "System.Net.Requests" // System.Net.WebResponse etc. + yield "System.Collections" // System.Collections.Generic.List + yield "System.Runtime.Numerics" // BigInteger + yield "System.Threading" // OperationCanceledException + yield "System.Web" + yield "System.Web.Services" + yield "System.Windows.Forms" + yield "System.Numerics" + ] + + let fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib assumeDotNetFramework = + if assumeDotNetFramework then + getDesktopDefaultReferences useFsiAuxLib + else + // Coreclr supports netstandard assemblies only for now + (getDependenciesOf [ + yield Path.Combine(frameworkDir, "netstandard.dll"); + yield getDefaultFSharpCoreReference; + if useFsiAuxLib then yield getFsiLibraryName + ]).Values |> Seq.toList + + let defaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = + fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources false assumeDotNetFramework + + // A set of assemblies to always consider to be system assemblies. A common set of these can be used a shared + // resources between projects in the compiler services. Also all assemblies where well-known system types exist + // referenced from TcGlobals must be listed here. + let systemAssemblies = + HashSet [ + yield "mscorlib" + yield "netstandard" + yield "System.Runtime" + yield getFSharpCoreLibraryName + + yield "System" + yield "System.Xml" + yield "System.Runtime.Remoting" + yield "System.Runtime.Serialization.Formatters.Soap" + yield "System.Data" + yield "System.Deployment" + yield "System.Design" + yield "System.Messaging" + yield "System.Drawing" + yield "System.Net" + yield "System.Web" + yield "System.Web.Services" + yield "System.Windows.Forms" + yield "System.Core" + yield "System.Runtime" + yield "System.Observable" + yield "System.Numerics" + yield "System.ValueTuple" + + // Additions for coreclr and portable profiles + yield "System.Collections" + yield "System.Collections.Concurrent" + yield "System.Console" + yield "System.Diagnostics.Debug" + yield "System.Diagnostics.Tools" + yield "System.Globalization" + yield "System.IO" + yield "System.Linq" + yield "System.Linq.Expressions" + yield "System.Linq.Queryable" + yield "System.Net.Requests" + yield "System.Reflection" + yield "System.Reflection.Emit" + yield "System.Reflection.Emit.ILGeneration" + yield "System.Reflection.Extensions" + yield "System.Resources.ResourceManager" + yield "System.Runtime.Extensions" + yield "System.Runtime.InteropServices" + yield "System.Runtime.InteropServices.PInvoke" + yield "System.Runtime.Numerics" + yield "System.Text.Encoding" + yield "System.Text.Encoding.Extensions" + yield "System.Text.RegularExpressions" + yield "System.Threading" + yield "System.Threading.Tasks" + yield "System.Threading.Tasks.Parallel" + yield "System.Threading.Thread" + yield "System.Threading.ThreadPool" + yield "System.Threading.Timer" + + yield "FSharp.Compiler.Interactive.Settings" + yield "Microsoft.Win32.Registry" + yield "System.Diagnostics.Tracing" + yield "System.Globalization.Calendars" + yield "System.Reflection.Primitives" + yield "System.Runtime.Handles" + yield "Microsoft.Win32.Primitives" + yield "System.IO.FileSystem" + yield "System.Net.Primitives" + yield "System.Net.Sockets" + yield "System.Private.Uri" + yield "System.AppContext" + yield "System.Buffers" + yield "System.Collections.Immutable" + yield "System.Diagnostics.DiagnosticSource" + yield "System.Diagnostics.Process" + yield "System.Diagnostics.TraceSource" + yield "System.Globalization.Extensions" + yield "System.IO.Compression" + yield "System.IO.Compression.ZipFile" + yield "System.IO.FileSystem.Primitives" + yield "System.Net.Http" + yield "System.Net.NameResolution" + yield "System.Net.WebHeaderCollection" + yield "System.ObjectModel" + yield "System.Reflection.Emit.Lightweight" + yield "System.Reflection.Metadata" + yield "System.Reflection.TypeExtensions" + yield "System.Runtime.InteropServices.RuntimeInformation" + yield "System.Runtime.Loader" + yield "System.Security.Claims" + yield "System.Security.Cryptography.Algorithms" + yield "System.Security.Cryptography.Cng" + yield "System.Security.Cryptography.Csp" + yield "System.Security.Cryptography.Encoding" + yield "System.Security.Cryptography.OpenSsl" + yield "System.Security.Cryptography.Primitives" + yield "System.Security.Cryptography.X509Certificates" + yield "System.Security.Principal" + yield "System.Security.Principal.Windows" + yield "System.Threading.Overlapped" + yield "System.Threading.Tasks.Extensions" + yield "System.Xml.ReaderWriter" + yield "System.Xml.XDocument" + ] + + // The set of references entered into the TcConfigBuilder for scripts prior to computing the load closure. + let basicReferencesForScriptLoadClosure useFsiAuxLib assumeDotNetFramework = + fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib assumeDotNetFramework diff --git a/src/fsharp/ErrorLogger.fs b/src/fsharp/ErrorLogger.fs index 8c5aa94fc6a..cb43aded141 100755 --- a/src/fsharp/ErrorLogger.fs +++ b/src/fsharp/ErrorLogger.fs @@ -330,17 +330,25 @@ type internal CompileThreadStatic = module ErrorLoggerExtensions = open System.Reflection + // Dev15.0 shipped with a bug in diasymreader in the portable pdb symbol reader which causes an AV + // This uses a simple heuristic to detect it (the vsversion is < 16.0) + let tryAndDetectDev15 = + let vsVersion = Environment.GetEnvironmentVariable("VisualStudioVersion") + match Double.TryParse(vsVersion) with + | true, v -> v < 16.0 + | _ -> false + /// Instruct the exception not to reset itself when thrown again. let PreserveStackTrace(exn) = - try - let preserveStackTrace = typeof.GetMethod("InternalPreserveStackTrace", BindingFlags.Instance ||| BindingFlags.NonPublic) - preserveStackTrace.Invoke(exn, null) |> ignore + try + if not(tryAndDetectDev15) then + let preserveStackTrace = typeof.GetMethod("InternalPreserveStackTrace", BindingFlags.Instance ||| BindingFlags.NonPublic) + preserveStackTrace.Invoke(exn, null) |> ignore with _ -> // This is probably only the mono case. System.Diagnostics.Debug.Assert(false, "Could not preserve stack trace for watson exception.") () - /// Reraise an exception if it is one we want to report to Watson. let ReraiseIfWatsonable(exn:exn) = #if FX_REDUCED_EXCEPTIONS diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj index 2aa2ffd100f..bdfd30b0074 100644 --- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj +++ b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj @@ -494,6 +494,9 @@ + + Driver\DotNetFrameworkDependencies.fs + Driver\CompileOps.fsi diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index d061f3f75ee..c372fa2d8fc 100755 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -1785,11 +1785,8 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput tcConfigB.projectReferences <- projectReferences -#if COMPILER_SERVICE_ASSUMES_DOTNETCORE_COMPILATION - tcConfigB.useSimpleResolution <- true // turn off msbuild resolution -#else tcConfigB.useSimpleResolution <- (getSwitchValue useSimpleResolutionSwitch) |> Option.isSome -#endif + // Apply command-line arguments and collect more source files if they are in the arguments let sourceFilesNew = ApplyCommandLineArgs(tcConfigB, sourceFiles, commandLineArgs) @@ -1816,11 +1813,9 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput | None -> () let tcConfig = TcConfig.Create(tcConfigB, validate=true) - let niceNameGen = NiceNameGenerator() - let outfile, _, assemblyName = tcConfigB.DecideNames sourceFilesNew - + // Resolve assemblies and create the framework TcImports. This is done when constructing the // builder itself, rather than as an incremental task. This caches a level of "system" references. No type providers are // included in these references. diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index b51ceeb2f65..3ca94694558 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -3360,7 +3360,7 @@ type CompilerEnvironment = module CompilerEnvironment = /// These are the names of assemblies that should be referenced for .fs, .ml, .fsi, .mli files that /// are not associated with a project - let DefaultReferencesForOrphanSources(assumeDotNetFramework) = DefaultReferencesForScriptsAndOutOfProjectSources(assumeDotNetFramework) + let DefaultReferencesForOrphanSources assumeDotNetFramework = DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework /// Publish compiler-flags parsing logic. Must be fast because its used by the colorizer. let GetCompilationDefinesForEditing (parsingOptions: FSharpParsingOptions) =