diff --git a/src/fsharp/CompileOps.fs b/src/fsharp/CompileOps.fs index 39aaa7b0340dff62e41c60c479c6835306a5959c..06befe5d6732f9bd5863b48ba6a265d7462216fe 100644 --- a/src/fsharp/CompileOps.fs +++ b/src/fsharp/CompileOps.fs @@ -2213,7 +2213,7 @@ type TcConfigBuilder = useFsiAuxLib=false implicitOpens=[] includes=[] - resolutionEnvironment=ReferenceResolver.CompileTimeLike + resolutionEnvironment=ResolutionEnvironment.EditingAndCompilation false framework=true implicitlyResolveAssemblies=true referencedDLLs = [] @@ -2801,46 +2801,52 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = // This call can fail if no CLR is found (this is the path to mscorlib) member tcConfig.GetTargetFrameworkDirectories() = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter - match tcConfig.clrRoot with - | Some x -> - [tcConfig.MakePathAbsolute x] - | None -> -#if ENABLE_MONO_SUPPORT - if runningOnMono then - [ let runtimeRoot = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() - let runtimeRootWithoutSlash = runtimeRoot.TrimEnd('/', '\\') - let api = runtimeRootWithoutSlash + "-api" - let rootFacades = Path.Combine(runtimeRootWithoutSlash, "Facades") - let apiFacades = Path.Combine(api, "Facades") - match tcConfig.resolutionEnvironment with -#if !FSI_TODO_NETCORE - // For F# Interactive code we must inly reference impementation assemblies - | ReferenceResolver.RuntimeLike -> - yield runtimeRoot - if Directory.Exists(rootFacades) then - yield rootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades -#endif - | _ -> - // The default FSharp.Core is found in lib/mono/4.5 - yield runtimeRoot - if Directory.Exists(rootFacades) then - yield rootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades - // It's not clear why we would need to reference the 4.5-api directory. - if Directory.Exists(api) then - yield api - if Directory.Exists(apiFacades) then - yield apiFacades - ] - else -#endif - try - [ - match tcConfig.resolutionEnvironment with -#if !FSI_TODO_NETCORE - | ReferenceResolver.RuntimeLike -> - yield System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() -#endif - | _ -> + try + [ + // Check if we are given an explicit framework root - if so, use that + match tcConfig.clrRoot with + | Some x -> + yield tcConfig.MakePathAbsolute x + + | None -> + let runtimeRoot = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() + let runtimeRootWithoutSlash = runtimeRoot.TrimEnd('/', '\\') + let runtimeRootFacades = Path.Combine(runtimeRootWithoutSlash, "Facades") + let runtimeRootWPF = Path.Combine(runtimeRootWithoutSlash, "WPF") + + match tcConfig.resolutionEnvironment with + | ResolutionEnvironment.CompilationAndEvaluation -> + // Default compilation-and-execution-time references on .NET Framework and Mono, e.g. for F# Interactive + // + // In the current way of doing things, F# Interactive refers to implementation assemblies. + yield runtimeRoot + if Directory.Exists(runtimeRootFacades) then + yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades + if Directory.Exists(runtimeRootWPF) then + yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF + + | ResolutionEnvironment.EditingAndCompilation _ -> + if runningOnMono then + // Default compilation-time references on Mono + // + // On Mono, the default references come from the implementation assemblies. + // This is because we have had trouble reliably using MSBuild APIs to compute DotNetFrameworkReferenceAssembliesRootDirectory on Mono. + yield runtimeRoot + if Directory.Exists(runtimeRootFacades) then + yield runtimeRootFacades // System.Runtime.dll is in /usr/lib/mono/4.5/Facades + if Directory.Exists(runtimeRootWPF) then + yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF + // On Mono we also add a default reference to the 4.5-api and 4.5-api/Facades directories. + let runtimeRootApi = runtimeRootWithoutSlash + "-api" + let runtimeRootApiFacades = Path.Combine(runtimeRootApi, "Facades") + if Directory.Exists(runtimeRootApi) then + yield runtimeRootApi + if Directory.Exists(runtimeRootApiFacades) then + yield runtimeRootApiFacades + else + // Default compilation-time references on .NET Framework + // + // This is the normal case for "fsc.exe a.fs". We refer to the reference assemblies folder. let frameworkRoot = tcConfig.legacyReferenceResolver.DotNetFrameworkReferenceAssembliesRootDirectory let frameworkRootVersion = Path.Combine(frameworkRoot,tcConfig.targetFrameworkVersion) yield frameworkRootVersion @@ -2848,8 +2854,8 @@ type TcConfig private (data : TcConfigBuilder,validate:bool) = if Directory.Exists(facades) then yield facades ] - with e -> - errorRecovery e range0; [] + with e -> + errorRecovery e range0; [] member tcConfig.ComputeLightSyntaxInitialStatus(filename) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parameter @@ -4854,7 +4860,7 @@ type LoadClosure = [] type CodeContext = - | Evaluation // in fsi.exe + | CompilationAndEvaluation // in fsi.exe | Compilation // in fsc.exe | Editing // in VS @@ -4887,7 +4893,7 @@ module private ScriptPreprocessClosure = // .fsx -- EDITING + !COMPILED\INTERACTIVE let defines = match codeContext with - | CodeContext.Evaluation -> ["INTERACTIVE"] + | CodeContext.CompilationAndEvaluation -> ["INTERACTIVE"] | CodeContext.Compilation -> ["COMPILED"] | CodeContext.Editing -> "EDITING" :: (if IsScript filename then ["INTERACTIVE"] else ["COMPILED"]) let lexbuf = UnicodeLexing.StringAsLexbuf source @@ -4898,7 +4904,7 @@ module private ScriptPreprocessClosure = /// Create a TcConfig for load closure starting from a single .fsx file let CreateScriptSourceTcConfig (legacyReferenceResolver, defaultFSharpBinariesDir, filename:string, codeContext, useSimpleResolution, useFsiAuxLib, basicReferences, applyCommandLineArgs, assumeDotNetFramework) = let projectDir = Path.GetDirectoryName(filename) - let isInteractive = (codeContext = CodeContext.Evaluation) + let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation) let isInvalidationSupported = (codeContext = CodeContext.Editing) let tcConfigB = TcConfigBuilder.CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, true (* optimize for memory *), projectDir, isInteractive, isInvalidationSupported, defaultCopyFSharpCore=false) applyCommandLineArgs tcConfigB @@ -4908,12 +4914,14 @@ module private ScriptPreprocessClosure = tcConfigB.resolutionEnvironment <- match codeContext with - | CodeContext.Editing -> ReferenceResolver.DesignTimeLike + | CodeContext.Editing -> ResolutionEnvironment.EditingAndCompilation true + | CodeContext.Compilation -> ResolutionEnvironment.EditingAndCompilation false + | CodeContext.CompilationAndEvaluation -> #if FSI_TODO_NETCORE - // "RuntimeLike" assembly resolution for F# Interactive is not yet properly figured out on .NET Core - | CodeContext.Compilation | CodeContext.Evaluation -> ReferenceResolver.CompileTimeLike + // "CompilationAndEvaluation" assembly resolution for F# Interactive is not yet properly figured out on .NET Core + ResolutionEnvironment.EditingAndCompilation false #else - | CodeContext.Compilation | CodeContext.Evaluation -> ReferenceResolver.RuntimeLike + ResolutionEnvironment.CompilationAndEvaluation #endif tcConfigB.framework <- false tcConfigB.useSimpleResolution <- useSimpleResolution diff --git a/src/fsharp/CompileOps.fsi b/src/fsharp/CompileOps.fsi index 9b8634b66d75eae0ac6edbd6a4850ddf3c94d4a1..ff9bf5b12900f33ce6515e4cf029b515622a5227 100755 --- a/src/fsharp/CompileOps.fsi +++ b/src/fsharp/CompileOps.fsi @@ -761,7 +761,7 @@ val ReportWarningAsError : globalWarnLevel: int * specificWarnOff: int list * sp [] type CodeContext = - | Evaluation + | CompilationAndEvaluation | Compilation | Editing diff --git a/src/fsharp/MSBuildReferenceResolver.fs b/src/fsharp/MSBuildReferenceResolver.fs index 4b8d8fe932ae3a0f4478e840610cc608d0a41bd3..24ea56d9079097ea26f8fa3e2b280f49b7c91983 100644 --- a/src/fsharp/MSBuildReferenceResolver.fs +++ b/src/fsharp/MSBuildReferenceResolver.fs @@ -287,11 +287,12 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver let registry = sprintf "{Registry:%s,%s,%s%s}" frameworkRegistryBase targetFrameworkVersion assemblyFoldersSuffix assemblyFoldersConditions - [| // When compiling scripts, for some reason we have always historically put TargetFrameworkDirectory first - // It is unclear why. + [| // When compiling scripts using fsc.exe, for some reason we have always historically put TargetFrameworkDirectory first + // It is unclear why. This is the only place we look at the 'isdifference between ResolutionEnvironment.EditingAndCompilation and ResolutionEnvironment.EditingTime. match resolutionEnvironment with - | CompileTimeLike -> yield "{TargetFrameworkDirectory}" - | DesignTimeLike | RuntimeLike -> () + | ResolutionEnvironment.EditingAndCompilation false -> yield "{TargetFrameworkDirectory}" + | ResolutionEnvironment.EditingAndCompilation true + | ResolutionEnvironment.CompilationAndEvaluation -> () // Quick-resolve straight to filename first if allowRawFileName then @@ -301,8 +302,9 @@ module internal Microsoft.FSharp.Compiler.MSBuildReferenceResolver yield implicitIncludeDir // Usually the project directory match resolutionEnvironment with - | DesignTimeLike | RuntimeLike -> yield "{TargetFrameworkDirectory}" - | CompileTimeLike -> () + | ResolutionEnvironment.EditingAndCompilation true + | ResolutionEnvironment.CompilationAndEvaluation -> yield "{TargetFrameworkDirectory}" + | ResolutionEnvironment.EditingAndCompilation false -> () yield registry yield "{AssemblyFolders}" diff --git a/src/fsharp/ReferenceResolver.fs b/src/fsharp/ReferenceResolver.fs index 6c4255225ed4fbf691c4b63aab86e8b6d0ffca1e..3ec392ce02995c0959f0ff4e76351e7e315dca2e 100644 --- a/src/fsharp/ReferenceResolver.fs +++ b/src/fsharp/ReferenceResolver.fs @@ -10,13 +10,12 @@ module internal ReferenceResolver = exception internal ResolutionFailure + [] type ResolutionEnvironment = - /// Indicates a script or source being compiled - | CompileTimeLike - /// Indicates a script or source being interpreted - | RuntimeLike - /// Indicates a script or source being edited - | DesignTimeLike + /// Indicates a script or source being compiled. Uses reference assemblies (not implementation assemblies). + | EditingAndCompilation of isEditing: bool + /// Indicates a script or source being dynamically compiled and executed. Uses implementation assemblies. + | CompilationAndEvaluation type ResolvedFile = { /// Item specification. diff --git a/src/fsharp/SimulatedMSBuildReferenceResolver.fs b/src/fsharp/SimulatedMSBuildReferenceResolver.fs index 5a983379f89b0d7371562c0e9a07908f0487f784..4b3b0e1599a8e766d0a8189b3136bd8273a3d2d7 100644 --- a/src/fsharp/SimulatedMSBuildReferenceResolver.fs +++ b/src/fsharp/SimulatedMSBuildReferenceResolver.fs @@ -208,7 +208,7 @@ let fscoreDir = System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory() let resolve s = - SimulatedMSBuildResolver.Resolve(ResolutionEnvironment.CompileTimeLike,[| for a in s -> (a, "") |],"v4.5.1", [SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @"\v4.5.1" ],"", "", fscoreDir,[],__SOURCE_DIRECTORY__,ignore, (fun _ _ -> ()), (fun _ _-> ())) + SimulatedMSBuildResolver.Resolve(ResolutionEnvironment.EditingAndCompilation,[| for a in s -> (a, "") |],"v4.5.1", [SimulatedMSBuildResolver.DotNetFrameworkReferenceAssembliesRootDirectory + @"\v4.5.1" ],"", "", fscoreDir,[],__SOURCE_DIRECTORY__,ignore, (fun _ _ -> ()), (fun _ _-> ())) // Resolve partial name to something on search path resolve ["FSharp.Core" ] diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index 7ba61354cb0671081c6967e6a91c24a0a52b4c0d..15163416934b1d489aac36c21969065f1ec67c1e 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -1291,7 +1291,7 @@ type internal FsiDynamicCompiler let sourceFiles = sourceFiles |> List.map (fun nm -> tcConfig.ResolveSourceFile(m, nm, tcConfig.implicitIncludeDir),m) // Close the #load graph on each file and gather the inputs from the scripts. - let closure = LoadClosure.ComputeClosureOfSourceFiles(ctok, TcConfig.Create(tcConfigB,validate=false), sourceFiles, CodeContext.Evaluation,lexResourceManager=lexResourceManager) + let closure = LoadClosure.ComputeClosureOfSourceFiles(ctok, TcConfig.Create(tcConfigB,validate=false), sourceFiles, CodeContext.CompilationAndEvaluation, lexResourceManager=lexResourceManager) // Intent "[Loading %s]\n" (String.concat "\n and " sourceFiles) fsiConsoleOutput.uprintf "[%s " (FSIstrings.SR.fsiLoadingFilesPrefixText()) @@ -2459,12 +2459,12 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i let tcConfigB = TcConfigBuilder.CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir=defaultFSharpBinariesDir, optimizeForMemory=true, implicitIncludeDir=currentDirectory, isInteractive=true, isInvalidationSupported=false, defaultCopyFSharpCore=false) let tcConfigP = TcConfigProvider.BasedOnMutableBuilder(tcConfigB) - do tcConfigB.resolutionEnvironment <- ReferenceResolver.RuntimeLike // See Bug 3608 + do tcConfigB.resolutionEnvironment <- ReferenceResolver.ResolutionEnvironment.CompilationAndEvaluation // See Bug 3608 do tcConfigB.useFsiAuxLib <- fsi.UseFsiAuxLib #if FSI_TODO_NETCORE - // "RuntimeLike" assembly resolution for F# Interactive is not yet properly figured out on .NET Core - do tcConfigB.resolutionEnvironment <- ReferenceResolver.DesignTimeLike + // "CompilationAndEvaluation" assembly resolution for F# Interactive is not yet properly figured out on .NET Core + do tcConfigB.resolutionEnvironment <- ResolutionEnvironment.EditingAndCompilation false do tcConfigB.useSimpleResolution <- true do SetTargetProfile tcConfigB "netcore" // always assume System.Runtime codegen //do SetTargetProfile tcConfigB "privatecorelib" // always assume System.Private.CoreLib codegen diff --git a/src/fsharp/vs/IncrementalBuild.fs b/src/fsharp/vs/IncrementalBuild.fs index b3e7e012dadf7bd34c82d4056a76e8f62eb00d22..b5c40cdab691dd73f7a6d66ccfdbc37112542f13 100755 --- a/src/fsharp/vs/IncrementalBuild.fs +++ b/src/fsharp/vs/IncrementalBuild.fs @@ -1701,7 +1701,8 @@ type IncrementalBuilder(tcGlobals,frameworkTcImports, nonFrameworkAssemblyInputs // The following uses more memory but means we don't take read-exclusions on the DLLs we reference // Could detect well-known assemblies--ie System.dll--and open them with read-locks tcConfigB.openBinariesInMemory <- true - tcConfigB.resolutionEnvironment <- (if useScriptResolutionRules then ReferenceResolver.DesignTimeLike else ReferenceResolver.CompileTimeLike) + + tcConfigB.resolutionEnvironment <- (ReferenceResolver.ResolutionEnvironment.EditingAndCompilation true) tcConfigB.conditionalCompilationDefines <- let define = if useScriptResolutionRules then "INTERACTIVE" else "COMPILED" diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs index 743afa1dccef664777528771c8844515a4a43636..d6ab10acdcabbb348485a47f5aab97d4c1da295c 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/Project/GlobalSuppressions.cs @@ -160,7 +160,7 @@ [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#BugReportFileName", MessageId = "")] [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#CheckedArithmetic", MessageId = "")] [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#CodePage", MessageId = "")] -[assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#CompileAndExecute", MessageId = "")] +[assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#CompilationAndEvaluation", MessageId = "")] [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#DefinedPreProcessorSymbols", MessageId = "")] [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#DisplayCommandLineHelp", MessageId = "")] [assembly: SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields", Scope = "member", Target = "Microsoft.VisualStudio.Package.ProjectOptions.#EmitManifest", MessageId = "")] diff --git a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs b/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs index f789b191b53dfea3ea854472049cbb9c312dec36..a90c12e002f732329709216622dcdcb2fb67a0c5 100644 --- a/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs +++ b/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectOptions.cs @@ -71,7 +71,7 @@ public ProjectOptions(ConfigCanonicalName configCanonicalName) public string RootNamespace; - public bool CompileAndExecute; + public bool CompilationAndEvaluation; /// must be an int if not null. public object UserLocaleId;