diff --git a/src/fsharp/CompilerConfig.fs b/src/fsharp/CompilerConfig.fs index 8fd22f80ca..e7125df282 100644 --- a/src/fsharp/CompilerConfig.fs +++ b/src/fsharp/CompilerConfig.fs @@ -12,6 +12,7 @@ open System.Text open Internal.Utilities open Internal.Utilities.Filename +open Internal.Utilities.FSharpEnvironment open FSharp.Compiler open FSharp.Compiler.AbstractIL @@ -21,7 +22,6 @@ open FSharp.Compiler.AbstractIL.ILPdbWriter open FSharp.Compiler.AbstractIL.Internal open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.AbstractIL.Internal.Utils -open FSharp.Compiler.DotNetFrameworkDependencies open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features open FSharp.Compiler.Lib @@ -399,6 +399,7 @@ type TcConfigBuilder = mutable includewin32manifest: bool mutable linkResources: string list mutable legacyReferenceResolver: ReferenceResolver.Resolver + mutable fxResolver: FxResolver mutable showFullPaths: bool mutable errorStyle: ErrorStyle @@ -462,6 +463,9 @@ type TcConfigBuilder = /// When false FSI will lock referenced assemblies requiring process restart, false = disable Shadow Copy false (*default*) mutable shadowCopyReferences: bool mutable useSdkRefs: bool + + /// Override the SDK directory used by FxResolver, used for FCS only + mutable sdkDirOverride: string option /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, /// and from which we can read the metadata. Only used when metadataOnly=true. @@ -566,6 +570,7 @@ type TcConfigBuilder = includewin32manifest = true linkResources = [] legacyReferenceResolver = null + fxResolver = Unchecked.defaultof<_> showFullPaths = false errorStyle = ErrorStyle.DefaultErrors @@ -587,7 +592,7 @@ type TcConfigBuilder = deterministic = false preferredUiLang = None lcid = None - productNameForBannerText = FSharpEnvironment.FSharpProductName + productNameForBannerText = FSharpProductName showBanner = true showTimes = false showLoadedAssemblies = false @@ -605,6 +610,7 @@ type TcConfigBuilder = copyFSharpCore = CopyFSharpCoreFlag.No shadowCopyReferences = false useSdkRefs = true + sdkDirOverride = None tryGetMetadataSnapshot = (fun _ -> None) internalTestSpanStackReferring = false noConditionalErasure = false @@ -631,7 +637,7 @@ type TcConfigBuilder = } |> Seq.distinct - static member CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, reduceMemoryUsage, implicitIncludeDir, + static member CreateNew(legacyReferenceResolver, fxResolver, defaultFSharpBinariesDir, reduceMemoryUsage, implicitIncludeDir, isInteractive, isInvalidationSupported, defaultCopyFSharpCore, tryGetMetadataSnapshot) = Debug.Assert(FileSystem.IsPathRootedShim implicitIncludeDir, sprintf "implicitIncludeDir should be absolute: '%s'" implicitIncludeDir) @@ -645,6 +651,7 @@ type TcConfigBuilder = defaultFSharpBinariesDir = defaultFSharpBinariesDir reduceMemoryUsage = reduceMemoryUsage legacyReferenceResolver = legacyReferenceResolver + fxResolver = fxResolver isInteractive = isInteractive isInvalidationSupported = isInvalidationSupported copyFSharpCore = defaultCopyFSharpCore @@ -848,7 +855,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = let dllReference, fileNameOpt = computeKnownDllReference getFSharpCoreLibraryName match fileNameOpt with | Some _ -> dllReference - | None -> AssemblyReference(range0, getDefaultFSharpCoreLocation, None) + | None -> AssemblyReference(range0, getDefaultFSharpCoreLocation(), None) // clrRoot: the location of the primary assembly (mscorlib.dll or netstandard.dll or System.Runtime.dll) // @@ -877,6 +884,9 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = #endif None, data.legacyReferenceResolver.HighestInstalledNetFrameworkVersion() + let systemAssemblies = data.fxResolver.GetSystemAssemblies() + + member x.FxResolver = data.fxResolver member x.primaryAssembly = data.primaryAssembly member x.noFeedback = data.noFeedback member x.stackReserveSize = data.stackReserveSize @@ -996,6 +1006,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member x.copyFSharpCore = data.copyFSharpCore member x.shadowCopyReferences = data.shadowCopyReferences member x.useSdkRefs = data.useSdkRefs + member x.sdkDirOverride = data.sdkDirOverride member x.tryGetMetadataSnapshot = data.tryGetMetadataSnapshot member x.internalTestSpanStackReferring = data.internalTestSpanStackReferring member x.noConditionalErasure = data.noConditionalErasure @@ -1048,7 +1059,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = if Directory.Exists runtimeRootWPF then yield runtimeRootWPF // PresentationCore.dll is in C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF - match frameworkRefsPackDirectory with + match tcConfig.FxResolver.GetFrameworkRefsPackDirectory() with | Some path when Directory.Exists(path) -> yield path | _ -> () @@ -1083,7 +1094,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = let facades = Path.Combine(frameworkRootVersion, "Facades") if Directory.Exists facades then yield facades - match frameworkRefsPackDirectory with + match tcConfig.FxResolver.GetFrameworkRefsPackDirectory() with | Some path when Directory.Exists(path) -> yield path | _ -> () @@ -1155,7 +1166,7 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = FileSystem.SafeExists filename && ((tcConfig.GetTargetFrameworkDirectories() |> List.exists (fun clrRoot -> clrRoot = Path.GetDirectoryName filename)) || (systemAssemblies.Contains (fileNameWithoutExtension filename)) || - isInReferenceAssemblyPackDirectory filename) + tcConfig.FxResolver.IsInReferenceAssemblyPackDirectory filename) with _ -> false @@ -1165,6 +1176,9 @@ type TcConfig private (data: TcConfigBuilder, validate: bool) = member tcConfig.GenerateOptimizationData = tcConfig.GenerateSignatureData + member tcConfig.assumeDotNetFramework = + tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib + /// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, /// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. type TcConfigProvider = diff --git a/src/fsharp/CompilerConfig.fsi b/src/fsharp/CompilerConfig.fsi index e7ed55d43e..1d3af47a4a 100644 --- a/src/fsharp/CompilerConfig.fsi +++ b/src/fsharp/CompilerConfig.fsi @@ -213,6 +213,7 @@ type TcConfigBuilder = mutable includewin32manifest: bool mutable linkResources: string list mutable legacyReferenceResolver: ReferenceResolver.Resolver + mutable fxResolver: FxResolver mutable showFullPaths: bool mutable errorStyle: ErrorStyle mutable utf8output: bool @@ -255,6 +256,7 @@ type TcConfigBuilder = mutable copyFSharpCore: CopyFSharpCoreFlag mutable shadowCopyReferences: bool mutable useSdkRefs: bool + mutable sdkDirOverride: string option /// A function to call to try to get an object that acts as a snapshot of the metadata section of a .NET binary, /// and from which we can read the metadata. Only used when metadataOnly=true. @@ -275,6 +277,7 @@ type TcConfigBuilder = static member CreateNew: legacyReferenceResolver: ReferenceResolver.Resolver * + fxResolver: FxResolver * defaultFSharpBinariesDir: string * reduceMemoryUsage: ReduceMemoryFlag * implicitIncludeDir: string * @@ -428,6 +431,8 @@ type TcConfig = member isInteractive: bool member isInvalidationSupported: bool + member FxResolver: FxResolver + member ComputeLightSyntaxInitialStatus: string -> bool member GetTargetFrameworkDirectories: unit -> string list @@ -451,6 +456,8 @@ type TcConfig = member useSdkRefs: bool + member sdkDirOverride: string option + member legacyReferenceResolver: ReferenceResolver.Resolver member emitDebugInfoInQuotations: bool @@ -492,6 +499,9 @@ type TcConfig = /// Indicates if the compilation will result in an F# optimization data resource in the generated binary member GenerateOptimizationData: bool + /// Check if the primary assembly is mscorlib + member assumeDotNetFramework: bool + /// Represents a computation to return a TcConfig. Normally this is just a constant immutable TcConfig, /// but for F# Interactive it may be based on an underlying mutable TcConfigBuilder. [] diff --git a/src/fsharp/CompilerImports.fs b/src/fsharp/CompilerImports.fs index ba78d9bdc3..e822878bd7 100644 --- a/src/fsharp/CompilerImports.fs +++ b/src/fsharp/CompilerImports.fs @@ -12,6 +12,7 @@ open System.IO open Internal.Utilities open Internal.Utilities.Collections +open Internal.Utilities.FSharpEnvironment open FSharp.Compiler open FSharp.Compiler.AbstractIL @@ -24,7 +25,6 @@ open FSharp.Compiler.AbstractIL.Diagnostics open FSharp.Compiler.CheckDeclarations open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.CompilerConfig -open FSharp.Compiler.DotNetFrameworkDependencies open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Import open FSharp.Compiler.Lib @@ -554,7 +554,8 @@ type TcAssemblyResolutions(tcConfig: TcConfig, results: AssemblyResolution list, if found then yield asm if tcConfig.framework then - for s in defaultReferencesForScriptsAndOutOfProjectSources tcConfig.useFsiAuxLib assumeDotNetFramework tcConfig.useSdkRefs do + let references, _useDotNetFramework = tcConfig.FxResolver.GetDefaultReferences(tcConfig.useFsiAuxLib, assumeDotNetFramework) + for s in references do yield AssemblyReference(rangeStartup, (if s.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) then s else s+".dll"), None) yield! tcConfig.referencedDLLs @@ -1834,7 +1835,3 @@ let RequireDLL (ctok, tcImports: TcImports, tcEnv, thisAssemblyName, referenceRa AddCcuToTcEnv(g, amap, referenceRange, tcEnv, thisAssemblyName, asm.FSharpViewOfMetadata, asm.AssemblyAutoOpenAttributes, asm.AssemblyInternalsVisibleToAttributes) let tcEnv = (tcEnv, asms) ||> List.fold buildTcEnv tcEnv, (dllinfos, asms) - -// Existing public APIs delegate to newer implementations -let DefaultReferencesForScriptsAndOutOfProjectSources assumeDotNetFramework = - defaultReferencesForScriptsAndOutOfProjectSources (*useFsiAuxLib*)false assumeDotNetFramework (*useSdkRefs*)false diff --git a/src/fsharp/CompilerImports.fsi b/src/fsharp/CompilerImports.fsi index d6eedc6d21..1306d09fbc 100644 --- a/src/fsharp/CompilerImports.fsi +++ b/src/fsharp/CompilerImports.fsi @@ -195,6 +195,3 @@ type TcImports = /// Process #r in F# Interactive. /// Adds the reference to the tcImports and add the ccu to the type checking environment. val RequireDLL: ctok: CompilationThreadToken * tcImports: TcImports * tcEnv: TcEnv * thisAssemblyName: string * referenceRange: range * file: string -> TcEnv * (ImportedBinary list * ImportedAssembly list) - -/// This list is the default set of references for "non-project" files. -val DefaultReferencesForScriptsAndOutOfProjectSources: bool -> string list diff --git a/src/fsharp/FSComp.txt b/src/fsharp/FSComp.txt index dd5488d7ed..828dda7928 100644 --- a/src/fsharp/FSComp.txt +++ b/src/fsharp/FSComp.txt @@ -1543,6 +1543,7 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable 3381,parsEofInInterpolatedTripleQuoteString,"Incomplete interpolated triple-quote string begun at or before here" 3382,parsEmptyFillInInterpolatedString,"Invalid interpolated string. This interpolated string expression fill is empty, an expression was expected." 3383,lexRBraceInInterpolatedString,"A '}}' character must be escaped (by doubling) in an interpolated string." +3384,scriptSdkNotDetermined,"The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '%s --version' in the directory '%s' was: '%s' and the exit code was '%d'." #3501 "This construct is not supported by your version of the F# compiler" CompilerMessage(ExperimentalAttributeMessages.NotSupportedYet, 3501, IsError=true) 3390,xmlDocBadlyFormed,"This XML comment is invalid: '%s'" 3390,xmlDocMissingParameterName,"This XML comment is invalid: missing 'name' attribute for parameter or parameter reference" @@ -1550,4 +1551,4 @@ forFormatInvalidForInterpolated4,"Interpolated strings used as type IFormattable 3390,xmlDocInvalidParameterName,"This XML comment is invalid: unknown parameter '%s'" 3390,xmlDocDuplicateParameter,"This XML comment is invalid: multiple documentation entries for parameter '%s'" 3390,xmlDocUnresolvedCrossReference,"This XML comment is invalid: unresolved cross-reference '%s'" -3390,xmlDocMissingParameter,"This XML comment is incomplete: no documentation for parameter '%s'" \ No newline at end of file +3390,xmlDocMissingParameter,"This XML comment is incomplete: no documentation for parameter '%s'" diff --git a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj index e732f6fe2e..15594bda23 100644 --- a/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj +++ b/src/fsharp/FSharp.Compiler.Private/FSharp.Compiler.Private.fsproj @@ -649,8 +649,8 @@ CodeGen\IlxGen.fs - - Driver\DotNetFrameworkDependencies.fs + + Driver\FxResolver.fs Driver\CompilerConfig.fsi diff --git a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj index 6ce94b9ea9..54e879d33e 100644 --- a/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj +++ b/src/fsharp/FSharp.Compiler.Service/FSharp.Compiler.Service.fsproj @@ -8,7 +8,7 @@ $(DefineConstants);COMPILER_SERVICE_AS_DLL $(DefineConstants);COMPILER $(DefineConstants);ENABLE_MONO_SUPPORT - $(OtherFlags) --sig:all.fsi /warnon:3218 /warnon:1182 /warnon:3390 --times + $(OtherFlags) /warnon:3218 /warnon:1182 /warnon:3390 --times true true @@ -650,8 +650,8 @@ CodeGen\IlxGen.fs - - Driver\DotNetFrameworkDependencies.fs + + Driver\FxResolver.fs Driver\AssemblyResolveHandler.fsi diff --git a/src/fsharp/DotNetFrameworkDependencies.fs b/src/fsharp/FxResolver.fs similarity index 55% rename from src/fsharp/DotNetFrameworkDependencies.fs rename to src/fsharp/FxResolver.fs index cfff44efc8..8602891d7d 100644 --- a/src/fsharp/DotNetFrameworkDependencies.fs +++ b/src/fsharp/FxResolver.fs @@ -1,55 +1,197 @@ // 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.Diagnostics - open System.Globalization - open System.IO - open System.Reflection - open System.Runtime.InteropServices - open Internal.Utilities - open Internal.Utilities.FSharpEnvironment - - type private TypeInThisAssembly = class end - - let fSharpCompilerLocation = - let location = Path.GetDirectoryName(typeof.Assembly.Location) - match FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some location) with - | Some path -> path +namespace FSharp.Compiler + +open System +open System.Collections.Concurrent +open System.Collections.Generic +open System.Diagnostics +open System.Globalization +open System.IO +open System.Reflection +open System.Runtime.InteropServices +open System.Text +open Internal.Utilities +open Internal.Utilities.FSharpEnvironment +open FSharp.Compiler.AbstractIL.ILBinaryReader +open FSharp.Compiler.ErrorLogger +open FSharp.Compiler.Range + +/// Resolves the references for a chosen or currently-executing framework, for +/// - script execution +/// - script editing +/// - script compilation +/// - out-of-project sources editing +/// - default references for fsc.exe +/// - default references for fsi.exe +type internal FxResolver(assumeDotNetFramework: bool option, projectDir: string, useSdkRefs: bool, isInteractive: bool, rangeForErrors: range, sdkDirOverride: string option) = + + static let isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + + static let dotnet = + if isWindows then "dotnet.exe" else "dotnet" + + static let getDotnetDirectory() = + if isRunningOnCoreClr then + // Probe for netsdk install, dotnet. and dotnet.exe is a constant offset from the location of System.Int32 + let candidate = + let assemblyLocation = Path.GetDirectoryName(typeof.GetTypeInfo().Assembly.Location) + Path.GetFullPath(Path.Combine(assemblyLocation, "../../..")) + + if Directory.Exists(candidate) then + Some candidate + else + None + elif isWindows then + let pf = Environment.GetEnvironmentVariable("ProgramW6432") + let pf = if String.IsNullOrEmpty(pf) then Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) else pf + let candidate = Path.Combine(pf,"dotnet") + if Directory.Exists(candidate) then + Some candidate + else None + else + None + + static let getDotnetHostPath() = + match (Environment.GetEnvironmentVariable("DOTNET_HOST_PATH")) with + | value when not (String.IsNullOrEmpty(value)) -> + value // Value set externally + | _ -> + match getDotnetDirectory() with + | Some dotnetDir -> + let candidate = Path.Combine(dotnetDir, dotnet) + if File.Exists(candidate) then candidate else dotnet + | None -> dotnet + + /// We only try once for each directory (cleared on solution unload) to prevent conditions where + /// we repeatedly try to run dotnet.exe on every keystroke for a script + static let desiredDotNetSdkVersionForDirectoryCache = ConcurrentDictionary>() + + /// Find the relevant sdk version by running `dotnet --version` in the script/project location, + /// taking into account any global.json + let tryGetDesiredDotNetSdkVersionForDirectoryInfo() = + desiredDotNetSdkVersionForDirectoryCache.GetOrAdd(projectDir, (fun _ -> + let dotnetHostPath = getDotnetHostPath() + try + let psi = ProcessStartInfo(dotnetHostPath, "--version") + psi.RedirectStandardOutput <- true + psi.RedirectStandardError <- true + psi.UseShellExecute <- false + psi.CreateNoWindow <- true + psi.StandardOutputEncoding <- Encoding.UTF8 + psi.StandardErrorEncoding <- Encoding.UTF8 + if Directory.Exists(projectDir) then + psi.WorkingDirectory <- projectDir + let p = Process.Start(psi) + let stdout = p.StandardOutput.ReadToEnd() + let stderr = p.StandardError.ReadToEnd() + p.WaitForExit() + if p.ExitCode <> 0 then + Result.Error (Error(FSComp.SR.scriptSdkNotDetermined(dotnetHostPath, projectDir, stderr, p.ExitCode), rangeForErrors)) + else + Result.Ok (stdout.Trim()) + with err -> + Result.Error (Error(FSComp.SR.scriptSdkNotDetermined(dotnetHostPath, projectDir, err.Message, 1), rangeForErrors)))) + + let tryGetDesiredDotNetSdkVersionForDirectory() = + // Make sure the warning gets replayed each time we call this + match tryGetDesiredDotNetSdkVersionForDirectoryInfo() with + | Result.Ok res -> Some res + | Result.Error exn -> warning(exn); None + + /// Get the .NET Core SDK directory relevant to projectDir, used to infer the default target framework assemblies. + let tryGetSdkDir() = + // This path shouldn't be used with reflective processes + assert not isInteractive + match assumeDotNetFramework with + | Some true -> None + | _ when not useSdkRefs -> None + | _ -> + match sdkDirOverride with + | Some sdkDir -> Some sdkDir | None -> -#if DEBUG - Debug.Print(sprintf """FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some '%s') returned None Location - customized incorrectly: algorithm here: https://github.com/dotnet/fsharp/blob/03f3f1c35f82af26593d025dabca57a6ef3ea9a1/src/utils/CompilerLocationUtils.fs#L171""" - location) -#endif - // Use the location of this dll - location + let sdksDir = + match getDotnetDirectory() with + | Some dotnetDir -> + let candidate = Path.GetFullPath(Path.Combine(dotnetDir, "sdk")) + if Directory.Exists(candidate) then Some candidate else None + | None -> None + + match sdksDir with + | Some sdksDir -> + // Find the sdk version by running `dotnet --version` in the script/project location + let desiredSdkVer = tryGetDesiredDotNetSdkVersionForDirectory() + + let sdkDir = + DirectoryInfo(sdksDir).GetDirectories() + |> Array.filter (fun di -> di.Name |> Seq.forall (fun c -> Char.IsDigit(c) || c = '.')) + // Filter to the version reported by `dotnet --version` in the location, if that succeeded + |> Array.filter (fun di -> match desiredSdkVer with None -> true | Some v -> di.Name.Contains(v)) + |> Array.sortBy (fun di -> di.FullName) + |> Array.tryLast + |> Option.map (fun di -> di.FullName) + sdkDir + | _ -> + None - let inline ifEmptyUse alternative filename = if String.IsNullOrWhiteSpace filename then alternative else filename + /// Get the framework implementation directory of the currently running process + let getRunningImplementationAssemblyDir() = + let filename = Path.GetDirectoryName(typeof.Assembly.Location) + if String.IsNullOrWhiteSpace filename then getFSharpCompilerLocation() else filename + + /// Get the framework implementation directory, either of the selected SDK or the currently running process as a backup + /// F# interactive/reflective scenarios use the implementation directory of the currently running process + let getImplementationAssemblyDir() = + if isInteractive then + getRunningImplementationAssemblyDir() + else + let sdkDir = tryGetSdkDir() + match sdkDir with + | Some dir -> + let dotnetConfigFile = Path.Combine(dir, "dotnet.runtimeconfig.json") + let dotnetConfig = File.ReadAllText(dotnetConfigFile) + let pattern = "\"version\": \"" + let startPos = dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length + let endPos = dotnetConfig.IndexOf("\"", startPos) + let ver = dotnetConfig.[startPos..endPos-1] + let path = Path.GetFullPath(Path.Combine(dir, "..", "..", "shared", "Microsoft.NETCore.App", ver)) + if Directory.Exists(path) then + path + else + getRunningImplementationAssemblyDir() + | None -> + let path = getRunningImplementationAssemblyDir() + path let getFSharpCoreLibraryName = "FSharp.Core" + let getFsiLibraryName = "FSharp.Compiler.Interactive.Settings" - let getDefaultFSharpCoreLocation = Path.Combine(fSharpCompilerLocation, getFSharpCoreLibraryName + ".dll") - let getDefaultFsiLibraryLocation = Path.Combine(fSharpCompilerLocation, getFsiLibraryName + ".dll") - let implementationAssemblyDir = Path.GetDirectoryName(typeof.Assembly.Location) |> ifEmptyUse fSharpCompilerLocation + + // Use the FSharp.Core that is executing with the compiler as a backup reference + let getFSharpCoreImplementationReference() = Path.Combine(getFSharpCompilerLocation(), getFSharpCoreLibraryName + ".dll") + + // Use the FSharp.Compiler.Interactive.Settings executing with the compiler as a backup reference + let getFsiLibraryImplementationReference() = Path.Combine(getFSharpCompilerLocation(), getFsiLibraryName + ".dll") // 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 valueTuplePath = Path.Combine(fSharpCompilerLocation, "System.ValueTuple.dll") - if File.Exists(valueTuplePath) then - Some valueTuplePath + let getSystemValueTupleImplementationReference () = + let probeFile = Path.Combine(getImplementationAssemblyDir(), "System.ValueTuple.dll") + if File.Exists(probeFile) then + Some probeFile + else + try + let asm = typeof>.Assembly + if asm.FullName.StartsWith("System.ValueTuple", StringComparison.OrdinalIgnoreCase) then + Some asm.Location else - None - with _ -> None + let valueTuplePath = Path.Combine(getFSharpCompilerLocation(), "System.ValueTuple.dll") + if File.Exists(valueTuplePath) then + Some valueTuplePath + else + None + with _ -> None // Algorithm: // use implementation location of obj type, on shared frameworks it will always be in: @@ -62,24 +204,27 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // packs\Microsoft.NETCore.App.Ref\sdk-version\netcoreappn.n // we will rely on the sdk-version match on the two paths to ensure that we get the product that ships with the // version of the runtime we are executing on - // Use the reference assemblies for the highest netcoreapp tfm that we find in that location that is - // lower than or equal to the implementation version. - let zeroVersion = Version("0.0.0.0") - let version, frameworkRefsPackDirectoryRoot = + // Use the reference assemblies for the highest netcoreapp tfm that we find in that location. + let tryGetNetCoreRefsPackDirectoryRoot() = try + // Use the reference assemblies for the highest netcoreapp tfm that we find in that location that is + // lower than or equal to the implementation version. + let zeroVersion = Version("0.0.0.0") let computeVersion version = match Version.TryParse(version) with | true, v -> v | false, _ -> zeroVersion - let version = computeVersion (DirectoryInfo(implementationAssemblyDir).Name) - let microsoftNETCoreAppRef = Path.Combine(implementationAssemblyDir, "../../../packs/Microsoft.NETCore.App.Ref") + let implDir = getImplementationAssemblyDir() + let version = computeVersion (DirectoryInfo(implDir).Name) + let microsoftNETCoreAppRef = Path.Combine(implDir, "../../../packs/Microsoft.NETCore.App.Ref") if Directory.Exists(microsoftNETCoreAppRef) then - let directory = DirectoryInfo(microsoftNETCoreAppRef).GetDirectories() - |> Array.map (fun di -> computeVersion di.Name) - |> Array.sort - |> Array.filter(fun v -> v <= version) - |> Array.last + let directory = + DirectoryInfo(microsoftNETCoreAppRef).GetDirectories() + |> Array.map (fun di -> computeVersion di.Name) + |> Array.sort + |> Array.filter(fun v -> v <= version) + |> Array.last Some (directory.ToString()), Some microsoftNETCoreAppRef else None, None @@ -87,7 +232,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // Tries to figure out the tfm for the compiler instance. // On coreclr it uses the deps.json file - let netcoreTfm = + let tryGetRunningDotNetCoreTfm() = let file = try let asm = Assembly.GetEntryAssembly() @@ -116,7 +261,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies | -1, _ | _, -1 -> if isRunningOnCoreClr then - // Running on coreclr but no deps.json was deployed with the host so default to 3.0 + // Running on coreclr but no deps.json was deployed with the host so default to 3.1 Some "netcoreapp3.1" else // Running on desktop @@ -127,7 +272,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // Tries to figure out the tfm for the compiler instance on the Windows desktop. // On full clr it uses the mscorlib version number - let getWindowsDesktopTfm () = + let getRunningDotNetFrameworkTfm () = let defaultMscorlibVersion = 4,8,3815,0 let desktopProductVersionMonikers = [| // major, minor, build, revision, moniker @@ -173,38 +318,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // no TFM could be found, assume latest stable? "net48" - /// Gets the tfm E.g netcore3.0, net472 - let executionTfm = - match netcoreTfm with - | Some tfm -> tfm - | _ -> getWindowsDesktopTfm () - - // Computer valid dotnet-rids for this environment: - // https://docs.microsoft.com/en-us/dotnet/core/rid-catalog - // - // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... - let executionRid = - let processArchitecture = RuntimeInformation.ProcessArchitecture - let baseRid = - if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then "win" - elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then "osx" - else "linux" - let platformRid = - match processArchitecture with - | Architecture.X64 -> baseRid + "-x64" - | Architecture.X86 -> baseRid + "-x86" - | Architecture.Arm64 -> baseRid + "-arm64" - | _ -> baseRid + "-arm" - platformRid - - let isInReferenceAssemblyPackDirectory filename = - match frameworkRefsPackDirectoryRoot with - | Some root -> - let path = Path.GetDirectoryName(filename) - path.StartsWith(root, StringComparison.OrdinalIgnoreCase) - | _ -> false - - let frameworkRefsPackDirectory = + let tryGetSdkRefsPackDirectory() = let tfmPrefix = "netcoreapp" let tfmCompare c1 c2 = let deconstructTfmApp (netcoreApp: DirectoryInfo) = @@ -224,18 +338,19 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies | Some _, None -> 1 | _ -> 0 - match version, frameworkRefsPackDirectoryRoot with + match tryGetNetCoreRefsPackDirectoryRoot() with | Some version, Some root -> try let ref = Path.Combine(root, version, "ref") - let highestTfm = DirectoryInfo(ref).GetDirectories() - |> Array.sortWith tfmCompare - |> Array.tryLast + let highestTfm = + DirectoryInfo(ref).GetDirectories() + |> Array.sortWith tfmCompare + |> Array.tryLast match highestTfm with | Some tfm -> Some (Path.Combine(ref, tfm.Name)) | None -> None - with | _ -> None + with _ -> None | _ -> None let getDependenciesOf assemblyReferences = @@ -243,7 +358,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // Identify path to a dll in the framework directory from a simple name let frameworkPathFromSimpleName simpleName = - let root = Path.Combine(implementationAssemblyDir, simpleName) + let root = Path.Combine(getImplementationAssemblyDir(), simpleName) let pathOpt = [| ""; ".dll"; ".exe" |] |> Seq.tryPick(fun ext -> @@ -289,14 +404,22 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies assemblies.Add(referenceName, path) | _ -> try - let asm = System.Reflection.Assembly.LoadFrom(path) + let opts = + { metadataOnly = MetadataOnlyFlag.Yes // turn this off here as we need the actual IL code + reduceMemoryUsage = ReduceMemoryFlag.Yes + pdbDirPath = None + tryGetMetadataSnapshot = (fun _ -> None) (* tryGetMetadataSnapshot *) } + + let reader = OpenILModuleReader path opts assemblies.Add(referenceName, path) - for reference in asm.GetReferencedAssemblies() do + for reference in reader.ILAssemblyRefs do traverseDependencies reference.Name - with e -> () - with e -> () - assemblyReferences |> List.iter(traverseDependencies) + // There are many native assemblies which can't be cracked, raising exceptions + with _ -> () + with _ -> () + + assemblyReferences |> List.iter traverseDependencies assemblies // This list is the default set of references for "non-project" files. @@ -305,7 +428,7 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies // (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) - let getDesktopDefaultReferences useFsiAuxLib = [ + let getDotNetFrameworkDefaultReferences useFsiAuxLib = [ yield "mscorlib" yield "System" yield "System.Xml" @@ -317,10 +440,10 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies yield "System.Configuration" yield getFSharpCoreLibraryName - if useFsiAuxLib then yield getFsiLibraryName + if useFsiAuxLib then yield fsiLibraryName // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources - match getDefaultSystemValueTupleReference () with + match getSystemValueTupleImplementationReference () with | None -> () | Some v -> yield v @@ -344,38 +467,13 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies yield "System.Numerics" ] - let fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework = - let results = - if assumeDotNetFramework then - getDesktopDefaultReferences useFsiAuxLib - else - let dependencies = - let getImplementationReferences () = - // Coreclr supports netstandard assemblies only for now - (getDependenciesOf [ - yield! Directory.GetFiles(implementationAssemblyDir, "*.dll") - yield getDefaultFSharpCoreLocation - if useFsiAuxLib then yield getDefaultFsiLibraryLocation - ]).Values |> Seq.toList - - if useSdkRefs then - // Go fetch references - match frameworkRefsPackDirectory with - | Some path -> - try [ yield! Directory.GetFiles(path, "*.dll") - yield getDefaultFSharpCoreLocation - if useFsiAuxLib then yield getDefaultFsiLibraryLocation - ] - with | _ -> List.empty - | None -> - getImplementationReferences () - else - getImplementationReferences () - dependencies - results - - let defaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib assumeDotNetFramework useSdkRefs = - fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework + let getDotNetCoreImplementationReferences useFsiAuxLib = + let implDir = getImplementationAssemblyDir() + let roots = + [ yield! Directory.GetFiles(implDir, "*.dll") + yield getFSharpCoreImplementationReference() + if useFsiAuxLib then yield getFsiLibraryImplementationReference() ] + (getDependenciesOf roots).Values |> Seq.toList // 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 @@ -557,6 +655,102 @@ module internal FSharp.Compiler.DotNetFrameworkDependencies yield "WindowsBase" ] + member _.GetSystemAssemblies() = systemAssemblies + + member _.IsInReferenceAssemblyPackDirectory filename = + match tryGetNetCoreRefsPackDirectoryRoot() with + | _, Some root -> + let path = Path.GetDirectoryName(filename) + path.StartsWith(root, StringComparison.OrdinalIgnoreCase) + | _ -> false + + member _.TryGetSdkDir() = tryGetSdkDir() + + /// Gets the selected target framework moniker, e.g netcore3.0, net472, and the running rid of the current machine + member _.GetTfmAndRid() = + // Interactive processes read their own configuration to find the running tfm + + let tfm = + if isInteractive then + match tryGetRunningDotNetCoreTfm() with + | Some tfm -> tfm + | _ -> getRunningDotNetFrameworkTfm () + else + let sdkDir = tryGetSdkDir() + match sdkDir with + | Some dir -> + let dotnetConfigFile = Path.Combine(dir, "dotnet.runtimeconfig.json") + let dotnetConfig = File.ReadAllText(dotnetConfigFile) + let pattern = "\"tfm\": \"" + let startPos = dotnetConfig.IndexOf(pattern, StringComparison.OrdinalIgnoreCase) + pattern.Length + let endPos = dotnetConfig.IndexOf("\"", startPos) + let tfm = dotnetConfig.[startPos..endPos-1] + //printfn "GetTfmAndRid, tfm = '%s'" tfm + tfm + | None -> + match tryGetRunningDotNetCoreTfm() with + | Some tfm -> tfm + | _ -> getRunningDotNetFrameworkTfm () + + // Computer valid dotnet-rids for this environment: + // https://docs.microsoft.com/en-us/dotnet/core/rid-catalog + // + // Where rid is: win, win-x64, win-x86, osx-x64, linux-x64 etc ... + let runningRid = + let processArchitecture = RuntimeInformation.ProcessArchitecture + let baseRid = + if RuntimeInformation.IsOSPlatform(OSPlatform.Windows) then "win" + elif RuntimeInformation.IsOSPlatform(OSPlatform.OSX) then "osx" + else "linux" + match processArchitecture with + | Architecture.X64 -> baseRid + "-x64" + | Architecture.X86 -> baseRid + "-x86" + | Architecture.Arm64 -> baseRid + "-arm64" + | _ -> baseRid + "-arm" + + tfm, runningRid + + static member ClearStaticCaches() = + desiredDotNetSdkVersionForDirectoryCache.Clear() + + member _.GetFrameworkRefsPackDirectory() = tryGetSdkRefsPackDirectory() + + member _.TryGetDesiredDotNetSdkVersionForDirectory() = tryGetDesiredDotNetSdkVersionForDirectoryInfo() + // The set of references entered into the TcConfigBuilder for scripts prior to computing the load closure. - let basicReferencesForScriptLoadClosure useFsiAuxLib useSdkRefs assumeDotNetFramework = - fetchPathsForDefaultReferencesForScriptsAndOutOfProjectSources useFsiAuxLib useSdkRefs assumeDotNetFramework + member _.GetDefaultReferences (useFsiAuxLib, assumeDotNetFramework) = + if assumeDotNetFramework then + getDotNetFrameworkDefaultReferences useFsiAuxLib, assumeDotNetFramework + else + if useSdkRefs then + // Go fetch references + match tryGetSdkRefsPackDirectory() with + | Some path -> + try + let sdkReferences = + [ yield! Directory.GetFiles(path, "*.dll") + yield getFSharpCoreImplementationReference() + if useFsiAuxLib then yield getFsiLibraryImplementationReference() + ] + sdkReferences, false + with _ -> + if isRunningOnCoreClr then + // If running on .NET Core and something goes wrong with getting the + // .NET Core references then use .NET Core implementation assemblies for running process + getDotNetCoreImplementationReferences useFsiAuxLib, false + else + // If running on .NET Framework and something goes wrong with getting the + // .NET Core references then default back to .NET Framework and return a flag indicating this has been done + getDotNetFrameworkDefaultReferences useFsiAuxLib, true + | None -> + if isRunningOnCoreClr then + // If running on .NET Core and there is no Sdk refs pack directory + // then use .NET Core implementation assemblies for running process + getDotNetCoreImplementationReferences useFsiAuxLib, false + else + // If running on .NET Framework and there is no Sdk refs pack directory + // then default back to .NET Framework and return a flag indicating this has been done + getDotNetFrameworkDefaultReferences useFsiAuxLib, true + else + getDotNetCoreImplementationReferences useFsiAuxLib, assumeDotNetFramework + diff --git a/src/fsharp/ParseAndCheckInputs.fs b/src/fsharp/ParseAndCheckInputs.fs index 25d6a88e23..02f96a0132 100644 --- a/src/fsharp/ParseAndCheckInputs.fs +++ b/src/fsharp/ParseAndCheckInputs.fs @@ -21,7 +21,6 @@ open FSharp.Compiler.CompilerGlobalState open FSharp.Compiler.CompilerConfig open FSharp.Compiler.CompilerDiagnostics open FSharp.Compiler.CompilerImports -open FSharp.Compiler.DotNetFrameworkDependencies open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Lexhelp open FSharp.Compiler.Lib diff --git a/src/fsharp/ScriptClosure.fs b/src/fsharp/ScriptClosure.fs index e08910609e..e1ca6f51f8 100644 --- a/src/fsharp/ScriptClosure.fs +++ b/src/fsharp/ScriptClosure.fs @@ -10,11 +10,11 @@ open System.Text open FSharp.Compiler open FSharp.Compiler.AbstractIL +open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AbstractIL.Internal.Library open FSharp.Compiler.CompilerConfig open FSharp.Compiler.CompilerDiagnostics open FSharp.Compiler.CompilerImports -open FSharp.Compiler.DotNetFrameworkDependencies open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Lib open FSharp.Compiler.ParseAndCheckInputs @@ -43,6 +43,12 @@ type LoadClosure = /// The resolved pacakge references along with the ranges of the #r positions in each file. PackageReferences: (range * string list)[] + /// Whether we're decided to use .NET Framework analysis for this script + UseDesktopFramework: bool + + /// Was the SDK directory override given? + SdkDirOverride: string option + /// The list of references that were not resolved during load closure. These may still be extension references. UnresolvedReferences: UnresolvedAssemblyReference list @@ -118,24 +124,40 @@ module ScriptPreprocessClosure = filename: string, codeContext, useSimpleResolution, useFsiAuxLib, basicReferences, applyCommandLineArgs, - assumeDotNetFramework, useSdkRefs, + assumeDotNetFramework, useSdkRefs, sdkDirOverride, tryGetMetadataSnapshot, reduceMemoryUsage) = let projectDir = Path.GetDirectoryName filename let isInteractive = (codeContext = CodeContext.CompilationAndEvaluation) let isInvalidationSupported = (codeContext = CodeContext.Editing) + let rangeForErrors = mkFirstLineOfFile filename + let fxResolver = FxResolver(Some assumeDotNetFramework, projectDir, rangeForErrors=rangeForErrors, useSdkRefs=useSdkRefs, isInteractive=isInteractive, sdkDirOverride=sdkDirOverride) + let tcConfigB = TcConfigBuilder.CreateNew - (legacyReferenceResolver, defaultFSharpBinariesDir, reduceMemoryUsage, projectDir, + (legacyReferenceResolver, fxResolver, defaultFSharpBinariesDir, reduceMemoryUsage, projectDir, isInteractive, isInvalidationSupported, CopyFSharpCoreFlag.No, tryGetMetadataSnapshot) applyCommandLineArgs tcConfigB - match basicReferences with - | None -> (basicReferencesForScriptLoadClosure useFsiAuxLib useSdkRefs assumeDotNetFramework) |> List.iter(fun f->tcConfigB.AddReferencedAssemblyByPath(range0, f)) // Add script references - | Some rs -> for m, r in rs do tcConfigB.AddReferencedAssemblyByPath(m, r) + // Work out the references for the script in its location. This may produce diagnostics. + let assumeDotNetFramework, scriptDefaultReferencesDiagnostics = + + match basicReferences with + | None -> + let errorLogger = CapturingErrorLogger("ScriptDefaultReferences") + use unwindEL = PushErrorLoggerPhaseUntilUnwind (fun _ -> errorLogger) + let references, assumeDotNetFramework = fxResolver.GetDefaultReferences (useFsiAuxLib, assumeDotNetFramework) + // Add script references + for reference in references do + tcConfigB.AddReferencedAssemblyByPath(range0, reference) + assumeDotNetFramework , errorLogger.Diagnostics + | Some (rs, diagnostics) -> + for m, reference in rs do + tcConfigB.AddReferencedAssemblyByPath(m, reference) + assumeDotNetFramework, diagnostics tcConfigB.resolutionEnvironment <- match codeContext with @@ -148,8 +170,9 @@ module ScriptPreprocessClosure = // be added conditionally once the relevant version of mscorlib.dll has been detected. tcConfigB.implicitlyResolveAssemblies <- false tcConfigB.useSdkRefs <- useSdkRefs + tcConfigB.primaryAssembly <- if assumeDotNetFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime - TcConfig.Create(tcConfigB, validate=true) + TcConfig.Create(tcConfigB, validate=true), scriptDefaultReferencesDiagnostics let ClosureSourceOfFilename(filename, m, inputCodePage, parseRequired) = try @@ -227,7 +250,8 @@ module ScriptPreprocessClosure = | Directive.Include -> "i" let packageManagerTextLines = packageManagerLines |> List.map(fun l -> directive l.Directive, l.Line) - let result = dependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError, executionTfm, executionRid, tcConfig.implicitIncludeDir, mainFile, scriptName) + let tfm, rid = tcConfig.FxResolver.GetTfmAndRid() + let result = dependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError, tfm, rid, tcConfig.implicitIncludeDir, mainFile, scriptName) if result.Success then // Resolution produced no errors //Write outputs in F# Interactive and compiler @@ -307,9 +331,8 @@ module ScriptPreprocessClosure = let packageReferences = packageReferences |> Seq.map (fun kvp -> kvp.Key, kvp.Value) |> Seq.toArray sources, tcConfig, packageReferences - /// Reduce the full directive closure into LoadClosure - let GetLoadClosure(ctok, rootFilename, closureFiles, tcConfig: TcConfig, codeContext, packageReferences) = + let GetLoadClosure(ctok, rootFilename, closureFiles, tcConfig: TcConfig, codeContext, packageReferences, earlierDiagnostics) = // Mark the last file as isLastCompiland. let closureFiles = @@ -355,8 +378,8 @@ module ScriptPreprocessClosure = let loadClosureRootDiagnostics, allRootDiagnostics = match List.rev closureFiles with | ClosureFile(_, _, _, parseDiagnostics, metaDiagnostics, _) :: _ -> - (metaDiagnostics @ resolutionDiagnostics), - (parseDiagnostics @ metaDiagnostics @ resolutionDiagnostics) + (earlierDiagnostics @ metaDiagnostics @ resolutionDiagnostics), + (parseDiagnostics @ earlierDiagnostics @ metaDiagnostics @ resolutionDiagnostics) | _ -> [], [] // When no file existed. let isRootRange exn = @@ -375,6 +398,8 @@ module ScriptPreprocessClosure = { SourceFiles = List.groupBy fst sourceFiles |> List.map (map2Of2 (List.map snd)) References = List.groupBy fst references |> List.map (map2Of2 (List.map snd)) PackageReferences = packageReferences + UseDesktopFramework = (tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib) + SdkDirOverride = tcConfig.sdkDirOverride UnresolvedReferences = unresolvedReferences Inputs = sourceInputs NoWarns = List.groupBy fst globalNoWarns |> List.map (map2Of2 (List.map snd)) @@ -389,7 +414,7 @@ module ScriptPreprocessClosure = let GetFullClosureOfScriptText (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, codeContext, - useSimpleResolution, useFsiAuxLib, useSdkRefs, + useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDirOverride, lexResourceManager: Lexhelp.LexResourceManager, applyCommandLineArgs, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProvider) = @@ -398,26 +423,26 @@ module ScriptPreprocessClosure = // // This is tries to mimic the action of running the script in F# Interactive - the initial context for scripting is created // first, then #I and other directives are processed. - let references0 = - let tcConfig = + let references0, assumeDotNetFramework, scriptDefaultReferencesDiagnostics = + let tcConfig, scriptDefaultReferencesDiagnostics = CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename, codeContext, useSimpleResolution, useFsiAuxLib, None, applyCommandLineArgs, assumeDotNetFramework, - useSdkRefs, tryGetMetadataSnapshot, reduceMemoryUsage) + useSdkRefs, sdkDirOverride, tryGetMetadataSnapshot, reduceMemoryUsage) let resolutions0, _unresolvedReferences = TcAssemblyResolutions.GetAssemblyResolutionInformation(ctok, tcConfig) let references0 = resolutions0 |> List.map (fun r->r.originalReference.Range, r.resolvedPath) |> Seq.distinct |> List.ofSeq - references0 + references0, tcConfig.assumeDotNetFramework, scriptDefaultReferencesDiagnostics - let tcConfig = + let tcConfig, scriptDefaultReferencesDiagnostics = CreateScriptTextTcConfig(legacyReferenceResolver, defaultFSharpBinariesDir, filename, - codeContext, useSimpleResolution, useFsiAuxLib, Some references0, - applyCommandLineArgs, assumeDotNetFramework, useSdkRefs, + codeContext, useSimpleResolution, useFsiAuxLib, Some (references0, scriptDefaultReferencesDiagnostics), + applyCommandLineArgs, assumeDotNetFramework, useSdkRefs, sdkDirOverride, tryGetMetadataSnapshot, reduceMemoryUsage) let closureSources = [ClosureSource(filename, range0, sourceText, true)] let closureFiles, tcConfig, packageReferences = FindClosureFiles(filename, range0, closureSources, tcConfig, codeContext, lexResourceManager, dependencyProvider) - GetLoadClosure(ctok, filename, closureFiles, tcConfig, codeContext, packageReferences) + GetLoadClosure(ctok, filename, closureFiles, tcConfig, codeContext, packageReferences, scriptDefaultReferencesDiagnostics) /// Given source filename, find the full load closure /// Used from fsi.fs and fsc.fs, for #load and command line @@ -428,7 +453,7 @@ module ScriptPreprocessClosure = let mainFile, mainFileRange = List.last files let closureSources = files |> List.collect (fun (filename, m) -> ClosureSourceOfFilename(filename, m,tcConfig.inputCodePage,true)) let closureFiles, tcConfig, packageReferences = FindClosureFiles(mainFile, mainFileRange, closureSources, tcConfig, codeContext, lexResourceManager, dependencyProvider) - GetLoadClosure(ctok, mainFile, closureFiles, tcConfig, codeContext, packageReferences) + GetLoadClosure(ctok, mainFile, closureFiles, tcConfig, codeContext, packageReferences, []) type LoadClosure with /// Analyze a script text and find the closure of its references. @@ -439,14 +464,14 @@ type LoadClosure with static member ComputeClosureOfScriptText (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename: string, sourceText: ISourceText, implicitDefines, useSimpleResolution: bool, - useFsiAuxLib, useSdkRefs, lexResourceManager: Lexhelp.LexResourceManager, + useFsiAuxLib, useSdkRefs, sdkDir, lexResourceManager: Lexhelp.LexResourceManager, applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProvider) = use unwindBuildPhase = PushThreadBuildPhaseUntilUnwind BuildPhase.Parse ScriptPreprocessClosure.GetFullClosureOfScriptText (ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, - implicitDefines, useSimpleResolution, useFsiAuxLib, useSdkRefs, lexResourceManager, + implicitDefines, useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDir, lexResourceManager, applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProvider) /// Analyze a set of script files and find the closure of their references. diff --git a/src/fsharp/ScriptClosure.fsi b/src/fsharp/ScriptClosure.fsi index f5c85d2bfc..05208845c4 100644 --- a/src/fsharp/ScriptClosure.fsi +++ b/src/fsharp/ScriptClosure.fsi @@ -38,6 +38,12 @@ type LoadClosure = /// The resolved pacakge references along with the ranges of the #r positions in each file. PackageReferences: (range * string list)[] + /// Whether we're decided to use .NET Framework analysis for this script + UseDesktopFramework: bool + + /// Was the SDK directory override given? + SdkDirOverride: string option + /// The list of references that were not resolved during load closure. UnresolvedReferences: UnresolvedAssemblyReference list @@ -74,6 +80,7 @@ type LoadClosure = useSimpleResolution: bool * useFsiAuxLib: bool * useSdkRefs: bool * + sdkDir: string option * lexResourceManager: Lexhelp.LexResourceManager * applyCompilerOptions: (TcConfigBuilder -> unit) * assumeDotNetFramework: bool * diff --git a/src/fsharp/fsc.fs b/src/fsharp/fsc.fs index 411097a520..eb3b0da3d2 100644 --- a/src/fsharp/fsc.fs +++ b/src/fsharp/fsc.fs @@ -178,6 +178,16 @@ let TypeCheck (ctok, tcConfig, tcImports, tcGlobals, errorLogger: ErrorLogger, a exiter.Exit 1 /// Check for .fsx and, if present, compute the load closure for of #loaded files. +/// +/// This is the "script compilation" feature that has always been present in the F# compiler, that allows you to compile scripts +/// and get the load closure and references from them. This applies even if the script is in a project (with 'Compile' action), for example. +/// +/// Any DLL references implied by package references are also retrieved from the script. +/// +/// When script compilation is invoked, the outputs are not necessarily a functioning application - the referenced DLLs are not +/// copied to the output folder, for example (except perhaps FSharp.Core.dll). +/// +/// NOTE: there is similar code in IncrementalBuilder.fs and this code should really be reconciled with that let AdjustForScriptCompile(ctok, tcConfigB: TcConfigBuilder, commandLineSourceFiles, lexResourceManager, dependencyProvider) = let combineFilePath file = @@ -191,10 +201,11 @@ let AdjustForScriptCompile(ctok, tcConfigB: TcConfigBuilder, commandLineSourceFi commandLineSourceFiles |> List.map combineFilePath + // Script compilation is active if the last item being compiled is a script and --noframework has not been specified let mutable allSources = [] - + let tcConfig = TcConfig.Create(tcConfigB, validate=false) - + let AddIfNotPresent(filename: string) = if not(allSources |> List.contains filename) then allSources <- filename :: allSources @@ -206,17 +217,27 @@ let AdjustForScriptCompile(ctok, tcConfigB: TcConfigBuilder, commandLineSourceFi (ctok, tcConfig, [filename, rangeStartup], CodeContext.Compilation, lexResourceManager, dependencyProvider) - // Record the references from the analysis of the script. The full resolutions are recorded as the corresponding #I paths used to resolve them - // are local to the scripts and not added to the tcConfigB (they are added to localized clones of the tcConfigB). + // Record the new references (non-framework) references from the analysis of the script. (The full resolutions are recorded + // as the corresponding #I paths used to resolve them are local to the scripts and not added to the tcConfigB - they are + // added to localized clones of the tcConfigB). let references = closure.References |> List.collect snd |> List.filter (fun r -> not (Range.equals r.originalReference.Range range0) && not (Range.equals r.originalReference.Range rangeStartup)) references |> List.iter (fun r -> tcConfigB.AddReferencedAssemblyByPath(r.originalReference.Range, r.resolvedPath)) + + // Also record the other declarations from the script. closure.NoWarns |> List.collect (fun (n, ms) -> ms|>List.map(fun m->m, n)) |> List.iter (fun (x,m) -> tcConfigB.TurnWarningOff(x, m)) closure.SourceFiles |> List.map fst |> List.iter AddIfNotPresent closure.AllRootFileDiagnostics |> List.iter diagnosticSink + + // If there is a target framework for the script then push that as a requirement into the overall compilation and add all the framework references implied + // by the script too. + tcConfigB.primaryAssembly <- (if closure.UseDesktopFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) + if tcConfigB.framework then + let references = closure.References |> List.collect snd + references |> List.iter (fun r -> tcConfigB.AddReferencedAssemblyByPath(r.originalReference.Range, r.resolvedPath)) else AddIfNotPresent filename @@ -422,10 +443,12 @@ let main1(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, let tryGetMetadataSnapshot = (fun _ -> None) + let fxResolver = FxResolver(None, directoryBuildingFrom, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(FSharpEnvironment.tryCurrentDomain()).Value let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, + TcConfigBuilder.CreateNew(legacyReferenceResolver, fxResolver, defaultFSharpBinariesDir, reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=directoryBuildingFrom, isInteractive=false, isInvalidationSupported=false, defaultCopyFSharpCore=defaultCopyFSharpCore, @@ -459,6 +482,9 @@ let main1(ctok, argv, legacyReferenceResolver, bannerAlreadyPrinted, delayForFlagsLogger.ForwardDelayedDiagnostics tcConfigB exiter.Exit 1 + let assumeDotNetFramework = (tcConfigB.primaryAssembly = PrimaryAssembly.Mscorlib) + tcConfigB.fxResolver <- FxResolver(Some assumeDotNetFramework, directoryBuildingFrom, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + tcConfigB.conditionalCompilationDefines <- "COMPILED" :: tcConfigB.conditionalCompilationDefines // Display the banner text, if necessary @@ -603,11 +629,15 @@ let main1OfAst let tryGetMetadataSnapshot = (fun _ -> None) + let directoryBuildingFrom = Directory.GetCurrentDirectory() + + let fxResolver = FxResolver(None, directoryBuildingFrom, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let defaultFSharpBinariesDir = FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(FSharpEnvironment.tryCurrentDomain()).Value let tcConfigB = - TcConfigBuilder.CreateNew(legacyReferenceResolver, defaultFSharpBinariesDir, - reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=Directory.GetCurrentDirectory(), + TcConfigBuilder.CreateNew(legacyReferenceResolver, fxResolver, defaultFSharpBinariesDir, + reduceMemoryUsage=reduceMemoryUsage, implicitIncludeDir=directoryBuildingFrom, isInteractive=false, isInvalidationSupported=false, defaultCopyFSharpCore=CopyFSharpCoreFlag.No, tryGetMetadataSnapshot=tryGetMetadataSnapshot) diff --git a/src/fsharp/fsi/fsi.fs b/src/fsharp/fsi/fsi.fs index 8040fd64b7..7a562ba569 100644 --- a/src/fsharp/fsi/fsi.fs +++ b/src/fsharp/fsi/fsi.fs @@ -36,7 +36,6 @@ open FSharp.Compiler.CompilerConfig open FSharp.Compiler.CompilerDiagnostics open FSharp.Compiler.CompilerImports open FSharp.Compiler.CompilerGlobalState -open FSharp.Compiler.DotNetFrameworkDependencies open FSharp.Compiler.ErrorLogger open FSharp.Compiler.Features open FSharp.Compiler.IlxGen @@ -624,6 +623,7 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, let mutable fsiServerName = "" let mutable interact = true let mutable explicitArgs = [] + let mutable writeReferencesAndExit = None let mutable inputFilesAcc = [] @@ -692,6 +692,7 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, PublicOptions(FSIstrings.SR.fsiAdvanced(),[]); PrivateOptions( [// Make internal fsi-server* options. Do not print in the help. They are used by VFSI. + CompilerOption("fsi-server-report-references","", OptionString (fun s -> writeReferencesAndExit <- Some s), None, None); CompilerOption("fsi-server","", OptionString (fun s -> fsiServerName <- s), None, None); // "FSI server mode on given named channel"); CompilerOption("fsi-server-input-codepage","",OptionInt (fun n -> fsiServerInputCodePage <- Some(n)), None, None); // " Set the input codepage for the console"); CompilerOption("fsi-server-output-codepage","",OptionInt (fun n -> fsiServerOutputCodePage <- Some(n)), None, None); // " Set the output codepage for the console"); @@ -828,6 +829,7 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, member __.FsiServerInputCodePage = fsiServerInputCodePage member __.FsiServerOutputCodePage = fsiServerOutputCodePage member __.FsiLCID with get() = fsiLCID and set v = fsiLCID <- v + member __.UseServerPrompt = isInteractiveServer() member __.IsInteractiveServer = isInteractiveServer() member __.ProbeToSeeIfConsoleWorks = probeToSeeIfConsoleWorks member __.EnableConsoleKeyProcessing = enableConsoleKeyProcessing @@ -837,7 +839,10 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, member __.SourceFiles = sourceFiles member __.Gui = gui + member _.WriteReferencesAndExit = writeReferencesAndExit + member _.DependencyProvider = dependencyProvider + member _.FxResolver = tcConfigB.fxResolver /// Set the current ui culture for the current thread. let internal SetCurrentUICultureForThread (lcid : int option) = @@ -897,7 +902,7 @@ type internal FsiConsolePrompt(fsiOptions: FsiCommandLineOptions, fsiConsoleOutp let mutable dropPrompt = 0 // NOTE: SERVER-PROMPT is not user displayed, rather it's a prefix that code elsewhere // uses to identify the prompt, see service\FsPkgs\FSharp.VS.FSI\fsiSessionToolWindow.fs - let prompt = if fsiOptions.IsInteractiveServer then "SERVER-PROMPT>\n" else "> " + let prompt = if fsiOptions.UseServerPrompt then "SERVER-PROMPT>\n" else "> " member __.Print() = if dropPrompt = 0 then fsiConsoleOutput.uprintf "%s" prompt else dropPrompt <- dropPrompt - 1 member __.PrintAhead() = dropPrompt <- dropPrompt + 1; fsiConsoleOutput.uprintf "%s" prompt @@ -933,7 +938,7 @@ type internal FsiConsoleInput(fsi: FsiEvaluationSessionHostConfig, fsiOptions: F if fsiOptions.PeekAheadOnConsoleToPermitTyping then (new Thread(fun () -> match consoleOpt with - | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.IsInteractiveServer -> + | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.UseServerPrompt -> if List.isEmpty fsiOptions.SourceFiles then if progress then fprintfn outWriter "first-line-reader-thread reading first line..."; firstLine <- Some(console()); @@ -1490,7 +1495,8 @@ type internal FsiDynamicCompiler packageManagerLines |> List.map (fun line -> directive line.Directive, line.Line) try - let result = fsiOptions.DependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError m, executionTfm, executionRid, tcConfigB.implicitIncludeDir, "stdin.fsx", "stdin.fsx") + let tfm, rid = fsiOptions.FxResolver.GetTfmAndRid() + let result = fsiOptions.DependencyProvider.Resolve(dependencyManager, ".fsx", packageManagerTextLines, reportError m, tfm, rid, tcConfigB.implicitIncludeDir, "stdin.fsx", "stdin.fsx") if result.Success then for line in result.StdOut do Console.Out.WriteLine(line) for line in result.StdError do Console.Error.WriteLine(line) @@ -2031,7 +2037,7 @@ type internal FsiStdinLexerProvider member __.CreateStdinLexer (errorLogger) = let lexbuf = match fsiConsoleInput.TryGetConsole() with - | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.IsInteractiveServer -> + | Some console when fsiOptions.EnableConsoleKeyProcessing && not fsiOptions.UseServerPrompt -> LexbufFromLineReader fsiStdinSyphon (fun () -> match fsiConsoleInput.TryGetFirstLine() with | Some firstLine -> firstLine @@ -2750,8 +2756,14 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i | None -> SimulatedMSBuildReferenceResolver.getResolver() | Some rr -> rr + // We know the target framework up front + let assumeDotNetFramework = not FSharpEnvironment.isRunningOnCoreClr + + let fxResolver = FxResolver(Some assumeDotNetFramework, currentDirectory, rangeForErrors=range0, useSdkRefs=true, isInteractive=true, sdkDirOverride=None) + let tcConfigB = TcConfigBuilder.CreateNew(legacyReferenceResolver, + fxResolver, defaultFSharpBinariesDir=defaultFSharpBinariesDir, reduceMemoryUsage=ReduceMemoryFlag.Yes, implicitIncludeDir=currentDirectory, @@ -2767,7 +2779,7 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i #if NETSTANDARD do tcConfigB.useSdkRefs <- true do tcConfigB.useSimpleResolution <- true - do SetTargetProfile tcConfigB "netcore" // always assume System.Runtime codegen + do if FSharpEnvironment.isRunningOnCoreClr then SetTargetProfile tcConfigB "netcore" // always assume System.Runtime codegen #endif // Preset: --optimize+ -g --tailcalls+ (see 4505) @@ -2795,6 +2807,16 @@ type FsiEvaluationSession (fsi: FsiEvaluationSessionHostConfig, argv:string[], i let fsiOptions = FsiCommandLineOptions(fsi, argv, tcConfigB, fsiConsoleOutput) + do + match fsiOptions.WriteReferencesAndExit with + | Some outFile -> + let tcConfig = tcConfigP.Get(ctokStartup) + let references, _unresolvedReferences = TcAssemblyResolutions.GetAssemblyResolutionInformation(ctokStartup, tcConfig) + let lines = [ for r in references -> r.resolvedPath ] + File.WriteAllLines(outFile, lines) + exit 0 + | _ -> () + let fsiConsolePrompt = FsiConsolePrompt(fsiOptions, fsiConsoleOutput) do diff --git a/src/fsharp/pars.fsy b/src/fsharp/pars.fsy index 2f22918350..6e0745abf1 100644 --- a/src/fsharp/pars.fsy +++ b/src/fsharp/pars.fsy @@ -627,7 +627,8 @@ interactiveSeparator: /* A #directive in a module, namespace or an interaction */ hashDirective: | HASH IDENT hashDirectiveArgs - { ParsedHashDirective ($2, $3, lhs parseState) } + { let m = match $3 with [] -> rhs2 parseState 1 2 | _ -> rhs2 parseState 1 3 + ParsedHashDirective ($2, $3, m) } /* The arguments to a #directive */ diff --git a/src/fsharp/range.fs b/src/fsharp/range.fs index b20cee5c3b..75828ed16a 100755 --- a/src/fsharp/range.fs +++ b/src/fsharp/range.fs @@ -385,4 +385,16 @@ module Range = member _.Equals(x1, x2) = equals x1 x2 member _.GetHashCode o = o.GetHashCode() } - +let mkFirstLineOfFile (file: string) = + try + let lines = File.ReadLines(file) |> Seq.indexed + let nonWhiteLine = lines |> Seq.tryFind (fun (_,s) -> not (String.IsNullOrWhiteSpace s)) + match nonWhiteLine with + | Some (i,s) -> mkRange file (mkPos (i+1) 0) (mkPos (i+1) s.Length) + | None -> + let nonEmptyLine = lines |> Seq.tryFind (fun (_,s) -> not (String.IsNullOrEmpty s)) + match nonEmptyLine with + | Some (i,s) -> mkRange file (mkPos (i+1) 0) (mkPos (i+1) s.Length) + | None -> mkRange file (mkPos 1 0) (mkPos 1 80) + with _ -> + mkRange file (mkPos 1 0) (mkPos 1 80) diff --git a/src/fsharp/range.fsi b/src/fsharp/range.fsi index 172ad32c10..5cb8aa3739 100755 --- a/src/fsharp/range.fsi +++ b/src/fsharp/range.fsi @@ -102,6 +102,10 @@ val mkFileIndexRange : FileIndex -> pos -> pos -> range /// This view hides the use of file indexes and just uses filenames val mkRange : string -> pos -> pos -> range +/// Make a range for the first non-whitespace line of the file if any. Otherwise use line 1 chars 0-80. +/// This involves reading the file. +val mkFirstLineOfFile : string -> range + val equals : range -> range -> bool /// Reduce a range so it only covers a line diff --git a/src/fsharp/service/FSharpCheckerResults.fs b/src/fsharp/service/FSharpCheckerResults.fs index e862f4abc0..a9e837c254 100644 --- a/src/fsharp/service/FSharpCheckerResults.fs +++ b/src/fsharp/service/FSharpCheckerResults.fs @@ -2156,7 +2156,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, let backgroundDiagnostics = [| |] let reduceMemoryUsage = ReduceMemoryFlag.Yes - let assumeDotNetFramework = tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib + let assumeDotNetFramework = (tcConfig.primaryAssembly = PrimaryAssembly.Mscorlib) let applyCompilerOptions tcConfigB = let fsiCompilerOptions = CompilerOptions.GetCoreFsiCompilerOptions tcConfigB @@ -2166,7 +2166,7 @@ type FsiInteractiveChecker(legacyReferenceResolver, LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, defaultFSharpBinariesDir, filename, sourceText, CodeContext.Editing, tcConfig.useSimpleResolution, tcConfig.useFsiAuxLib, - tcConfig.useSdkRefs, new Lexhelp.LexResourceManager(), + tcConfig.useSdkRefs, tcConfig.sdkDirOverride, new Lexhelp.LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot=(fun _ -> None), reduceMemoryUsage=reduceMemoryUsage, diff --git a/src/fsharp/service/IncrementalBuild.fs b/src/fsharp/service/IncrementalBuild.fs index 2ece0502cf..a99985e272 100755 --- a/src/fsharp/service/IncrementalBuild.fs +++ b/src/fsharp/service/IncrementalBuild.fs @@ -6,6 +6,7 @@ namespace FSharp.Compiler open System open System.Collections.Generic open System.IO +open System.Runtime.InteropServices open System.Threading open FSharp.Compiler @@ -1301,9 +1302,22 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput | Some idx -> Some(commandLineArgs.[idx].Substring(switchString.Length)) | _ -> None + let assumeDotNetFramework = + match loadClosureOpt with + | None -> None + | Some loadClosure -> Some loadClosure.UseDesktopFramework + + let sdkDirOverride = + match loadClosureOpt with + | None -> None + | Some loadClosure -> loadClosure.SdkDirOverride + + let fxResolver = FxResolver(assumeDotNetFramework, projectDirectory, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=sdkDirOverride) + // see also fsc.fs: runFromCommandLineToImportingAssemblies(), as there are many similarities to where the PS creates a tcConfigB let tcConfigB = TcConfigBuilder.CreateNew(legacyReferenceResolver, + fxResolver, defaultFSharpBinariesDir, implicitIncludeDir=projectDirectory, reduceMemoryUsage=ReduceMemoryFlag.Yes, @@ -1330,6 +1344,10 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput tcConfigB, sourceFilesNew + // If this is a builder for a script, re-apply the settings inferred from the + // script and its load closure to the configuration. + // + // NOTE: it would probably be cleaner and more accurate to re-run the load closure at this point. match loadClosureOpt with | Some loadClosure -> let dllReferences = @@ -1341,6 +1359,7 @@ type IncrementalBuilder(tcGlobals, frameworkTcImports, nonFrameworkAssemblyInput yield AssemblyReference(closureReference.originalReference.Range, resolved, None) | None -> yield reference] tcConfigB.referencedDLLs <- [] + tcConfigB.primaryAssembly <- (if loadClosure.UseDesktopFramework then PrimaryAssembly.Mscorlib else PrimaryAssembly.System_Runtime) // Add one by one to remove duplicates dllReferences |> List.iter (fun dllReference -> tcConfigB.AddReferencedAssemblyByPath(dllReference.Range, dllReference.Text)) diff --git a/src/fsharp/service/service.fs b/src/fsharp/service/service.fs index 244f4d7e0a..4335f83f7a 100644 --- a/src/fsharp/service/service.fs +++ b/src/fsharp/service/service.fs @@ -856,7 +856,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC member bc.ParseAndCheckProject(options, userOpName) = reactor.EnqueueAndAwaitOpAsync(userOpName, "ParseAndCheckProject", options.ProjectFileName, fun ctok -> bc.ParseAndCheckProjectImpl(options, ctok, userOpName)) - member __.GetProjectOptionsFromScript(filename, sourceText, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib: bool option, useSdkRefs: bool option, assumeDotNetFramework: bool option, extraProjectInfo: obj option, optionsStamp: int64 option, userOpName) = + member __.GetProjectOptionsFromScript(filename, sourceText, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib: bool option, useSdkRefs: bool option, sdkDirOverride: string option, assumeDotNetFramework: bool option, extraProjectInfo: obj option, optionsStamp: int64 option, userOpName) = + reactor.EnqueueAndAwaitOpAsync (userOpName, "GetProjectOptionsFromScript", filename, fun ctok -> cancellable { use errors = new ErrorScope() @@ -889,12 +890,12 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC let loadClosure = LoadClosure.ComputeClosureOfScriptText(ctok, legacyReferenceResolver, FSharpCheckerResultsSettings.defaultFSharpBinariesDir, filename, sourceText, - CodeContext.Editing, useSimpleResolution, useFsiAuxLib, useSdkRefs, new Lexhelp.LexResourceManager(), + CodeContext.Editing, useSimpleResolution, useFsiAuxLib, useSdkRefs, sdkDirOverride, new Lexhelp.LexResourceManager(), applyCompilerOptions, assumeDotNetFramework, tryGetMetadataSnapshot, reduceMemoryUsage, dependencyProviderForScripts) let otherFlags = - [| yield "--noframework"; yield "--warn:3"; + [| yield "--noframework"; yield "--warn:3"; yield! otherFlags for r in loadClosure.References do yield "-r:" + fst r for (code,_) in loadClosure.NoWarns do yield "--nowarn:" + code @@ -916,7 +917,8 @@ type BackgroundCompiler(legacyReferenceResolver, projectCacheSize, keepAssemblyC Stamp = optionsStamp } scriptClosureCache.Set(AnyCallerThread, options, loadClosure) // Save the full load closure for later correlation. - return options, errors.Diagnostics + let diags = loadClosure.LoadClosureRootFileDiagnostics |> List.map (fun (exn, isError) -> FSharpErrorInfo.CreateFromException(exn, isError, range.Zero, false)) + return options, (diags @ errors.Diagnostics) }) member bc.InvalidateConfiguration(options : FSharpProjectOptions, startBackgroundCompileIfAlreadySeen, userOpName) = @@ -1236,6 +1238,7 @@ type FSharpChecker(legacyReferenceResolver, System.GC.Collect() System.GC.WaitForPendingFinalizers() backgroundCompiler.CompleteAllQueuedOps() // flush AsyncOp + FxResolver.ClearStaticCaches() /// This function is called when the configuration is known to have changed for reasons not encoded in the ProjectOptions. /// For example, dependent references may have been deleted or created. @@ -1290,9 +1293,9 @@ type FSharpChecker(legacyReferenceResolver, backgroundCompiler.GetSemanticClassificationForFile(filename, options, userOpName) /// For a given script file, get the ProjectOptions implied by the #load closure - member __.GetProjectOptionsFromScript(filename, source, ?previewEnabled, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?useSdkRefs, ?assumeDotNetFramework, ?extraProjectInfo: obj, ?optionsStamp: int64, ?userOpName: string) = + member __.GetProjectOptionsFromScript(filename, source, ?previewEnabled, ?loadedTimeStamp, ?otherFlags, ?useFsiAuxLib, ?useSdkRefs, ?assumeDotNetFramework, ?sdkDirOverride, ?extraProjectInfo: obj, ?optionsStamp: int64, ?userOpName: string) = let userOpName = defaultArg userOpName "Unknown" - backgroundCompiler.GetProjectOptionsFromScript(filename, source, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib, useSdkRefs, assumeDotNetFramework, extraProjectInfo, optionsStamp, userOpName) + backgroundCompiler.GetProjectOptionsFromScript(filename, source, previewEnabled, loadedTimeStamp, otherFlags, useFsiAuxLib, useSdkRefs, sdkDirOverride, assumeDotNetFramework, extraProjectInfo, optionsStamp, userOpName) member __.GetProjectOptionsFromCommandLineArgs(projectFileName, argv, ?loadedTimeStamp, ?extraProjectInfo: obj) = let loadedTimeStamp = defaultArg loadedTimeStamp DateTime.MaxValue // Not 'now', we don't want to force reloading @@ -1396,9 +1399,13 @@ type CompilerEnvironment = /// Information about the compilation environment [] 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 + + // Legacy entry point, no longer used by FSharp.Editor + let DefaultReferencesForOrphanSources assumeDotNetFramework = + let currentDirectory = Directory.GetCurrentDirectory() + let fxResolver = FxResolver(Some assumeDotNetFramework, currentDirectory, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let references, _ = fxResolver.GetDefaultReferences (useFsiAuxLib=false, assumeDotNetFramework=assumeDotNetFramework) + references /// Publish compiler-flags parsing logic. Must be fast because its used by the colorizer. let GetCompilationDefinesForEditing (parsingOptions: FSharpParsingOptions) = diff --git a/src/fsharp/service/service.fsi b/src/fsharp/service/service.fsi index 09d6469860..b1ec16de41 100755 --- a/src/fsharp/service/service.fsi +++ b/src/fsharp/service/service.fsi @@ -223,12 +223,13 @@ type public FSharpChecker = /// Add a default reference to the FSharp.Compiler.Interactive.Settings library. /// Use the implicit references from the .NET SDK. /// Set up compilation and analysis for .NET Framework scripts. + /// Override the .NET SDK used for default references. /// An extra data item added to the returned FSharpProjectOptions. /// An optional unique stamp for the options. /// An optional string used for tracing compiler operations associated with this request. member GetProjectOptionsFromScript: filename: string * source: ISourceText * ?previewEnabled:bool * ?loadedTimeStamp: DateTime * - ?otherFlags: string[] * ?useFsiAuxLib: bool * ?useSdkRefs: bool * ?assumeDotNetFramework: bool * + ?otherFlags: string[] * ?useFsiAuxLib: bool * ?useSdkRefs: bool * ?assumeDotNetFramework: bool * ?sdkDirOverride: string * ?extraProjectInfo: obj * ?optionsStamp: int64 * ?userOpName: string -> Async diff --git a/src/fsharp/utils/CompilerLocationUtils.fs b/src/fsharp/utils/CompilerLocationUtils.fs index 5bff0b5930..c4e44f00ac 100644 --- a/src/fsharp/utils/CompilerLocationUtils.fs +++ b/src/fsharp/utils/CompilerLocationUtils.fs @@ -14,6 +14,8 @@ open Microsoft.FSharp.Core module internal FSharpEnvironment = + type private TypeInThisAssembly = class end + /// The F# version reported in the banner let FSharpBannerVersion = UtilsStrings.SR.fSharpBannerVersion(FSharp.BuildProperties.fsProductVersion, FSharp.BuildProperties.fsLanguageVersion) @@ -340,3 +342,23 @@ module internal FSharpEnvironment = let getCompilerToolsDesignTimeAssemblyPaths compilerToolPaths = searchToolPaths None compilerToolPaths + + let getFSharpCoreLibraryName = "FSharp.Core" + let fsiLibraryName = "FSharp.Compiler.Interactive.Settings" + + let getFSharpCompilerLocation() = + let location = Path.GetDirectoryName(typeof.Assembly.Location) + match BinFolderOfDefaultFSharpCompiler (Some location) with + | Some path -> path + | None -> + #if DEBUG + Debug.Print(sprintf """FSharpEnvironment.BinFolderOfDefaultFSharpCompiler (Some '%s') returned None Location + customized incorrectly: algorithm here: https://github.com/dotnet/fsharp/blob/03f3f1c35f82af26593d025dabca57a6ef3ea9a1/src/utils/CompilerLocationUtils.fs#L171""" + location) + #endif + // Use the location of this dll + location + + let getDefaultFSharpCoreLocation() = Path.Combine(getFSharpCompilerLocation(), getFSharpCoreLibraryName + ".dll") + let getDefaultFsiLibraryLocation() = Path.Combine(getFSharpCompilerLocation(), fsiLibraryName + ".dll") + diff --git a/src/fsharp/utils/CompilerLocationUtils.fsi b/src/fsharp/utils/CompilerLocationUtils.fsi index 3301f19f93..c044f82f2c 100644 --- a/src/fsharp/utils/CompilerLocationUtils.fsi +++ b/src/fsharp/utils/CompilerLocationUtils.fsi @@ -39,4 +39,14 @@ module internal FSharpEnvironment = raiseError:(string option -> exn -> System.Reflection.Assembly option) -> System.Reflection.Assembly option - val getCompilerToolsDesignTimeAssemblyPaths: compilerToolPaths:seq -> seq \ No newline at end of file + val getFSharpCompilerLocation: unit -> string + + val getDefaultFSharpCoreLocation: unit -> string + + val getDefaultFsiLibraryLocation: unit -> string + + val getCompilerToolsDesignTimeAssemblyPaths: compilerToolPaths:seq -> seq + + val fsiLibraryName: string + + val getFSharpCoreLibraryName: string diff --git a/src/fsharp/xlf/FSComp.txt.cs.xlf b/src/fsharp/xlf/FSComp.txt.cs.xlf index 979f2af287..9a39a4c95d 100644 --- a/src/fsharp/xlf/FSComp.txt.cs.xlf +++ b/src/fsharp/xlf/FSComp.txt.cs.xlf @@ -312,6 +312,11 @@ Registrovaní správci PackageManagers nepodporují #i. + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Tato funkce se v této verzi jazyka F# nepodporuje. Abyste mohli tuto funkci používat, možná bude nutné přidat /langversion:preview. diff --git a/src/fsharp/xlf/FSComp.txt.de.xlf b/src/fsharp/xlf/FSComp.txt.de.xlf index 56bb041273..7f61d7dc8c 100644 --- a/src/fsharp/xlf/FSComp.txt.de.xlf +++ b/src/fsharp/xlf/FSComp.txt.de.xlf @@ -312,6 +312,11 @@ #i wird von den registrierten PackageManagers nicht unterstützt. + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Dieses Feature wird in dieser Version von F# nicht unterstützt. Möglicherweise müssen Sie "/langversion:preview" hinzufügen, um dieses Feature zu verwenden. diff --git a/src/fsharp/xlf/FSComp.txt.es.xlf b/src/fsharp/xlf/FSComp.txt.es.xlf index 96391a29ad..3c4a43eab4 100644 --- a/src/fsharp/xlf/FSComp.txt.es.xlf +++ b/src/fsharp/xlf/FSComp.txt.es.xlf @@ -312,6 +312,11 @@ Los elementos PackageManager registrados no admiten #i + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Esta versión de F# no admite esta característica. Es posible que tenga que agregar /langversion:preview para usarla. diff --git a/src/fsharp/xlf/FSComp.txt.fr.xlf b/src/fsharp/xlf/FSComp.txt.fr.xlf index 8668557aa3..5adced0a99 100644 --- a/src/fsharp/xlf/FSComp.txt.fr.xlf +++ b/src/fsharp/xlf/FSComp.txt.fr.xlf @@ -312,6 +312,11 @@ #i n'est pas pris en charge par les PackageManagers inscrits + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Cette fonctionnalité n'est pas prise en charge dans cette version de F#. Vous devrez peut-être ajouter /langversion:preview pour pouvoir utiliser cette fonctionnalité. diff --git a/src/fsharp/xlf/FSComp.txt.it.xlf b/src/fsharp/xlf/FSComp.txt.it.xlf index 9f703a7cb8..3d03869441 100644 --- a/src/fsharp/xlf/FSComp.txt.it.xlf +++ b/src/fsharp/xlf/FSComp.txt.it.xlf @@ -312,6 +312,11 @@ #i non è supportato dagli elementi PackageManager registrati + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Questa funzionalità non è supportata in questa versione di F#. Per usare questa funzionalità, potrebbe essere necessario aggiungere /langversion:preview. diff --git a/src/fsharp/xlf/FSComp.txt.ja.xlf b/src/fsharp/xlf/FSComp.txt.ja.xlf index ba1d0417d0..c6de2f62af 100644 --- a/src/fsharp/xlf/FSComp.txt.ja.xlf +++ b/src/fsharp/xlf/FSComp.txt.ja.xlf @@ -312,6 +312,11 @@ 登録された PackageManager によって、#i はサポートされていません + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. この機能は、このバージョンの F# ではサポートされていません。この機能を使用するには、/langversion:preview の追加が必要な場合があります。 @@ -617,6 +622,11 @@ '--pdb' オプションでは '--debug' オプションを使用する必要があります + + Invalid directive. Expected '#load \"<file>\" ... \"<file>\"'. + Invalid directive. Expected '#load \"<file>\" ... \"<file>\"'. + + The search directory '{0}' is invalid 検索ディレクトリ '{0}' が無効です @@ -717,11 +727,6 @@ ディレクティブが無効です。'#r \"<file-or-assembly>\"' という形式で指定する必要があります。 - - Invalid directive. Expected '#load \"<file>\" ... \"<file>\"'. - ディレクティブが無効です。'#load \"<file>\" ... \"<file>\"' が必要でした。 - - Invalid directive. Expected '#time', '#time \"on\"' or '#time \"off\"'. ディレクティブが無効です。'#time'、'#time \"on\"'、または '#time \"off\"' という形式で指定する必要があります。 @@ -3492,6 +3497,11 @@ 継承された型はオブジェクト モデル型ではありません + + Output messages with fully qualified paths + Output messages with fully qualified paths + + Object construction expressions (i.e. record expressions with inheritance specifications) may only be used to implement constructors in object model types. Use 'new ObjectType(args)' to construct instances of object model types outside of constructors オブジェクト構築式 (つまり、継承の指定があるレコード式) は、オブジェクト モデル型のコンストラクターを実装する場合にのみ使用できます。コンストラクターの外側でオブジェクト モデル型のインスタンスを構築するには、'new ObjectType(args)' を使用してください。 @@ -3542,6 +3552,11 @@ シーケンス式で、複数の結果は 'yield!' を使用して生成されます + + The command-line option '{0}' is for test purposes only + The command-line option '{0}' is for test purposes only + + Invalid assignment 割り当てが無効です @@ -4717,11 +4732,6 @@ UTF-8 エンコードでメッセージを出力します - - Output messages with fully qualified paths - 完全修飾パスを含むメッセージを出力します - - Specify a directory for the include path which is used to resolve source files and assemblies (Short form: -I) ソース ファイルおよびアセンブリの解決に使用する include パスのディレクトリを指定します (短い形式: -I) @@ -4842,11 +4852,6 @@ 認識されないプラットフォーム '{0}'。有効な値は 'x86'、'x64'、'Itanium'、'anycpu32bitpreferred'、および 'anycpu' です。 - - The command-line option '{0}' is for test purposes only - コマンド ライン オプション '{0}' はテスト目的でのみ使用できます - - The command-line option '{0}' has been deprecated コマンド ライン オプション '{0}' は使用されなくなりました diff --git a/src/fsharp/xlf/FSComp.txt.ko.xlf b/src/fsharp/xlf/FSComp.txt.ko.xlf index bf8d6b3cbd..94811a157c 100644 --- a/src/fsharp/xlf/FSComp.txt.ko.xlf +++ b/src/fsharp/xlf/FSComp.txt.ko.xlf @@ -312,6 +312,11 @@ #i는 등록된 PackageManagers에서 지원하지 않습니다. + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. 이 기능은 이 F# 버전에서 지원되지 않습니다. 이 기능을 사용하기 위해 /langversion:preview를 추가해야 할 수도 있습니다. diff --git a/src/fsharp/xlf/FSComp.txt.pl.xlf b/src/fsharp/xlf/FSComp.txt.pl.xlf index 3027e6cc40..80d8dbcb56 100644 --- a/src/fsharp/xlf/FSComp.txt.pl.xlf +++ b/src/fsharp/xlf/FSComp.txt.pl.xlf @@ -312,6 +312,11 @@ Element #i nie jest obsługiwany przez zarejestrowanych menedżerów pakietów + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Ta funkcja nie jest obsługiwana w tej wersji języka F#. Aby korzystać z tej funkcji, może być konieczne dodanie parametru /langversion:preview. diff --git a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf index 48e18e83cc..c6a77375b2 100644 --- a/src/fsharp/xlf/FSComp.txt.pt-BR.xlf +++ b/src/fsharp/xlf/FSComp.txt.pt-BR.xlf @@ -312,6 +312,11 @@ O PackageManagers registrado não dá suporte a #i + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Este recurso não tem suporte nesta versão do F#. Talvez seja necessário adicionar /langversion:preview para usar este recurso. diff --git a/src/fsharp/xlf/FSComp.txt.ru.xlf b/src/fsharp/xlf/FSComp.txt.ru.xlf index 63ec608688..3ccd9d1a9e 100644 --- a/src/fsharp/xlf/FSComp.txt.ru.xlf +++ b/src/fsharp/xlf/FSComp.txt.ru.xlf @@ -312,6 +312,11 @@ #i не поддерживается зарегистрированными диспетчерами пакетов + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Эта функция не поддерживается в данной версии F#. Возможно, потребуется добавить/langversion:preview, чтобы использовать эту функцию. diff --git a/src/fsharp/xlf/FSComp.txt.tr.xlf b/src/fsharp/xlf/FSComp.txt.tr.xlf index 70484967db..6f29c319df 100644 --- a/src/fsharp/xlf/FSComp.txt.tr.xlf +++ b/src/fsharp/xlf/FSComp.txt.tr.xlf @@ -312,6 +312,11 @@ #i, kayıtlı PackageManagers tarafından desteklenmiyor + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. Bu özellik, bu F# sürümünde desteklenmiyor. Bu özelliği kullanabilmeniz için /langversion:preview eklemeniz gerekebilir. diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf index e5b0a72a97..daf850cea0 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hans.xlf @@ -312,6 +312,11 @@ 注册的 PackageManager 不支持 #i + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. 此版本的 F# 不支持此功能。你可能需要添加 /langversion:preview 才可使用此功能。 diff --git a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf index 95ddbdce3f..a466dbe4ee 100644 --- a/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/fsharp/xlf/FSComp.txt.zh-Hant.xlf @@ -312,6 +312,11 @@ 註冊的 PackageManagers 不支援 #i + + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' then ensure the relevant .NET SDK is installed. The output from '{0} --version' in the directory '{1}' was: '{2}' and the exit code was '{3}'. + + This feature is not supported in this version of F#. You may need to add /langversion:preview to use this feature. 此版本的 F# 不支援此功能。您可能需要新增 /langversion:preview 才能使用此功能。 diff --git a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs index 8deed2f994..6d2287ad3f 100644 --- a/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs +++ b/tests/FSharp.Compiler.Private.Scripting.UnitTests/FSharpScriptTests.fs @@ -143,7 +143,7 @@ System.Configuration.ConfigurationManager.AppSettings.Item "Environment" <- "LOC [] [] + "input.fsx (1,1)-(1,3) interactive warning Invalid directive '#i '")>] member _.``Script with more #i syntax errors fail``(code, error0, error1) = use script = new FSharpScript() let result, errors = script.Eval(code) diff --git a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs index 332d43328a..a2926d82e8 100644 --- a/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs +++ b/tests/FSharp.Compiler.Service.Tests/SurfaceArea.netstandard.fs @@ -20243,6 +20243,7 @@ FSharp.Compiler.Range: FSharp.Compiler.Range+Range FSharp.Compiler.Range: FSharp.Compiler.Range+pos FSharp.Compiler.Range: FSharp.Compiler.Range+range FSharp.Compiler.Range: Int32 fileIndexOfFile(System.String) +FSharp.Compiler.Range: range mkFirstLineOfFile(System.String) FSharp.Compiler.Range: System.Collections.Generic.IComparer`1[FSharp.Compiler.Range+pos] get_posOrder() FSharp.Compiler.Range: System.Collections.Generic.IComparer`1[FSharp.Compiler.Range+pos] posOrder FSharp.Compiler.Range: System.Collections.Generic.IComparer`1[FSharp.Compiler.Range+range] get_rangeOrder() @@ -21510,7 +21511,7 @@ FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FShar FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.SourceCodeServices.FSharpErrorInfo[],System.Int32]] Compile(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.SourceCodeServices.FSharpParseFileResults,FSharp.Compiler.SourceCodeServices.FSharpCheckFileAnswer]] ParseAndCheckFileInProject(System.String, Int32, FSharp.Compiler.Text.ISourceText, FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.SourceCodeServices.FSharpParseFileResults,FSharp.Compiler.SourceCodeServices.FSharpCheckFileResults]] GetBackgroundCheckResultsForFileInProject(System.String, FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) -FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.SourceCodeServices.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SourceCodeServices.FSharpErrorInfo]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Object], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) +FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`2[FSharp.Compiler.SourceCodeServices.FSharpProjectOptions,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SourceCodeServices.FSharpErrorInfo]]] GetProjectOptionsFromScript(System.String, FSharp.Compiler.Text.ISourceText, Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.DateTime], Microsoft.FSharp.Core.FSharpOption`1[System.String[]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Object], Microsoft.FSharp.Core.FSharpOption`1[System.Int64], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`3[FSharp.Compiler.SourceCodeServices.FSharpErrorInfo[],System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.Assembly]]] CompileToDynamicAssembly(Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.SyntaxTree+ParsedInput], System.String, Microsoft.FSharp.Collections.FSharpList`1[System.String], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.IO.TextWriter,System.IO.TextWriter]], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.Boolean], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.Tuple`3[FSharp.Compiler.SourceCodeServices.FSharpErrorInfo[],System.Int32,Microsoft.FSharp.Core.FSharpOption`1[System.Reflection.Assembly]]] CompileToDynamicAssembly(System.String[], Microsoft.FSharp.Core.FSharpOption`1[System.Tuple`2[System.IO.TextWriter,System.IO.TextWriter]], Microsoft.FSharp.Core.FSharpOption`1[System.String]) FSharp.Compiler.SourceCodeServices.FSharpChecker: Microsoft.FSharp.Control.FSharpAsync`1[System.ValueTuple`2[FSharp.Compiler.Range+range,FSharp.Compiler.SourceCodeServices.SemanticClassificationType][]] GetBackgroundSemanticClassificationForFile(System.String, FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, Microsoft.FSharp.Core.FSharpOption`1[System.String]) diff --git a/tests/FSharp.Test.Utilities/CompilerAssert.fs b/tests/FSharp.Test.Utilities/CompilerAssert.fs index debabd9ab0..eac815d47e 100644 --- a/tests/FSharp.Test.Utilities/CompilerAssert.fs +++ b/tests/FSharp.Test.Utilities/CompilerAssert.fs @@ -196,7 +196,7 @@ let main argv = 0""" raise (new Exception (sprintf "An error occurred getting netcoreapp references: %A" e)) finally if cleanUp then - try Directory.Delete(projectDirectory) with | _ -> () + try Directory.Delete(projectDirectory, recursive=true) with | _ -> () #if FX_NO_APP_DOMAINS static let executeBuiltApp assembly deps = diff --git a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl index 3253446641..4ae32a6ed0 100644 --- a/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.1000.stderr.bsl @@ -1,6 +1,6 @@ #blaaaaaa // blaaaaaa is not a known command;; - ^ + ^^^^^^^^^ stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' diff --git a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl index 3253446641..4ae32a6ed0 100644 --- a/tests/fsharp/core/printing/z.output.test.200.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.200.stderr.bsl @@ -1,6 +1,6 @@ #blaaaaaa // blaaaaaa is not a known command;; - ^ + ^^^^^^^^^ stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' diff --git a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl index 3253446641..4ae32a6ed0 100644 --- a/tests/fsharp/core/printing/z.output.test.default.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.default.stderr.bsl @@ -1,6 +1,6 @@ #blaaaaaa // blaaaaaa is not a known command;; - ^ + ^^^^^^^^^ stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' diff --git a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl index 3253446641..4ae32a6ed0 100644 --- a/tests/fsharp/core/printing/z.output.test.off.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.off.stderr.bsl @@ -1,6 +1,6 @@ #blaaaaaa // blaaaaaa is not a known command;; - ^ + ^^^^^^^^^ stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' diff --git a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl b/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl index 3253446641..4ae32a6ed0 100644 --- a/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl +++ b/tests/fsharp/core/printing/z.output.test.quiet.stderr.bsl @@ -1,6 +1,6 @@ #blaaaaaa // blaaaaaa is not a known command;; - ^ + ^^^^^^^^^ stdin(220,1): warning FS3353: Invalid directive '#blaaaaaa ' diff --git a/tests/service/ScriptOptionsTests.fs b/tests/service/ScriptOptionsTests.fs index 9ceae471bd..2e5dececfd 100644 --- a/tests/service/ScriptOptionsTests.fs +++ b/tests/service/ScriptOptionsTests.fs @@ -11,6 +11,7 @@ open NUnit.Framework open System.IO open FSharp.Compiler.Service.Tests.Common open FSharp.Compiler.Text +open FSharp.Compiler.Range // Add additional imports/constructs into this script text to verify that common scenarios // for FCS script typechecking can be supported @@ -36,22 +37,58 @@ let ``can generate options for different frameworks regardless of execution envi [] [] [] -let ``all default assembly references are system assemblies``(assumeNetFx, useSdk, flags) = - let path = Path.GetTempPath() - let file = Path.GetTempFileName() - let tempFile = Path.Combine(path, file) +let ``all default assembly references are system assemblies``(assumeNetFx, useSdkRefs, flags) = + let tempFile = Path.GetTempFileName() + ".fsx" let (options, errors) = - checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdk, otherFlags = flags) + checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = assumeNetFx, useSdkRefs = useSdkRefs, otherFlags = flags) |> Async.RunSynchronously match errors with | [] -> () - | errors -> failwithf "Error while parsing script with assumeDotNetFramework:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdk flags errors + | errors -> failwithf "Error while parsing script with assumeNetFx:%b, useSdkRefs:%b, and otherFlags:%A:\n%A" assumeNetFx useSdkRefs flags errors for r in options.OtherOptions do if r.StartsWith("-r:") then let ref = Path.GetFullPath(r.[3..]) let baseName = Path.GetFileNameWithoutExtension(ref) - if not (FSharp.Compiler.DotNetFrameworkDependencies.systemAssemblies.Contains(baseName)) then + let projectDir = System.Environment.CurrentDirectory + if not (FSharp.Compiler.FxResolver(Some assumeNetFx, projectDir, rangeForErrors=range0, useSdkRefs=useSdkRefs, isInteractive=false, sdkDirOverride=None).GetSystemAssemblies().Contains(baseName)) then printfn "Failing, printing options from GetProjectOptionsFromScript..." for opt in options.OtherOptions do printfn "option: %s" opt - failwithf "expected FSharp.Compiler.DotNetFrameworkDependencies.systemAssemblies to contain '%s' because '%s' is a default reference for a script, (assumeNetFx, useSdk, flags) = %A" baseName ref (assumeNetFx, useSdk, flags) \ No newline at end of file + failwithf "expected FSharp.Compiler.DotNetFrameworkDependencies.systemAssemblies to contain '%s' because '%s' is a default reference for a script, (assumeNetFx, useSdk, flags) = %A" baseName ref (assumeNetFx, useSdkRefs, flags) + +// This test atempts to use a bad SDK number 666.666.666 +// +// It's disabled because on CI server the SDK is still being resolved to 5.0.101 by `dotnet --version`. +// +// This must be because of some setting in the CI build scripts - e.g. an environment variable +// that allows SDK resolution to be overriden. I've tried to track this down by looking through +// https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet resolution rules +// and the F# and CI settings but can't find the setting that is causing this. +// +// Because of this the test has been manually verified by running locally. +//[] +let ``sdk dir with dodgy global json gives warning``() = + let tempFile = Path.GetTempFileName() + ".fsx" + let tempPath = Path.GetDirectoryName(tempFile) + let globalJsonPath = Path.Combine(tempPath, "global.json") + File.WriteAllText(globalJsonPath, """{ "sdk": { "version": "666.666.666" } }""") + let (options, errors) = + checker.GetProjectOptionsFromScript(tempFile, SourceText.ofString scriptSource, assumeDotNetFramework = false, useSdkRefs = true, otherFlags = [| |]) + |> Async.RunSynchronously + File.Delete(globalJsonPath) + match errors with + | [] -> + printfn "Failure!" + printfn "tempPath = %A" tempPath + printfn "options = %A" options + let fxResolver = FSharp.Compiler.FxResolver(Some false, tempPath, rangeForErrors=range0, useSdkRefs=true, isInteractive=false, sdkDirOverride=None) + let result = fxResolver.TryGetDesiredDotNetSdkVersionForDirectory() + printfn "sdkVersion = %A" result + + printfn "options = %A" options + failwith "Expected error while parsing script" + | errors -> + for error in errors do + // {C:\Users\Administrator\AppData\Local\Temp\tmp6F0F.tmp.fsx (0,1)-(0,1) The .NET SDK for this script could not be determined. If the script is in a directory using a 'global.json' ensure the relevant .NET SDK is installed. The output from 'C:\Program Files\dotnet\dotnet.exe --version' in the script directory was: ' 2.1.300 [C:\Program Files\dotnet\sdk] + Assert.AreEqual(3384, error.ErrorNumber) + Assert.AreEqual(tempFile, error.FileName) diff --git a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs index 2c09f05df3..86b9af904e 100644 --- a/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs +++ b/vsintegration/src/FSharp.Editor/LanguageService/FSharpProjectOptionsManager.fs @@ -98,7 +98,14 @@ type private FSharpProjectOptionsReactor (workspace: Workspace, settings: Editor match singleFileCache.TryGetValue(document.Id) with | false, _ -> let! sourceText = document.GetTextAsync(ct) |> Async.AwaitTask - let! scriptProjectOptions, _ = checkerProvider.Checker.GetProjectOptionsFromScript(document.FilePath, sourceText.ToFSharpSourceText(), SessionsProperties.fsiPreview, userOpName=userOpName) + + let! scriptProjectOptions, _ = + checkerProvider.Checker.GetProjectOptionsFromScript(document.FilePath, + sourceText.ToFSharpSourceText(), + SessionsProperties.fsiPreview, + assumeDotNetFramework=not SessionsProperties.fsiUseNetCore, + userOpName=userOpName) + let projectOptions = if isScriptFile document.FilePath then scriptProjectOptions diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct b/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct index 4a95e4cfcf..b1e215a3db 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/MenusAndCommands.vsct @@ -47,6 +47,9 @@ + + + @@ -126,6 +129,14 @@ DynamicVisibility | DefaultInvisible + + + + + + @@ -375,6 +390,7 @@ + diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml b/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml deleted file mode 100644 index c2837d0a6d..0000000000 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/Overview.xml +++ /dev/null @@ -1,257 +0,0 @@ - - - - - ../../../Common - - true - false - true - true - true - true - true - true - true - true - true - - - - C# Example.FSharpProject - FSharp Project - Integrating a project type for FSharp. - - - - This sample is a component of FSharp integration inside Visual Studio and it demostrates how to create a project type and a winforms designer. - The sample is based on the Project Framework and references the source code installed with the VSSDK. - Support is also included for the WPF designer. - The main goals of this sample are: - - Creating a Visual Studio project type for building Windows Forms applications using Iron FSharp - Creating a Visual Studio project type for building Web Application Projects using Iron FSharp - Creating a Visual Studio project type for building Web Site Projects using Iron FSharp - Creating a Visual Studio project type for building WPF Applications using Iron FSharp - Project.jpg - - - - - Example - 3 - Project.jpg - Iron FSharp - C# - VisualStudioIntegration\Samples\FSharpIntegration\ - Project\FSharpProject.sln - VisualStudioIntegration\Samples\FSharpIntegration\Project\TDD\ - FSharpProject.UnitTest.sln - - - Iron FSharp - Project - - - - - Open the FSharpProject.sln solution. - - - Press F5 to build the sample, register it in the experimental hive, and launch Visual Studio from the experimental hive. - - - - - - To see the sample's functionality... - - - On the File menu, click New Project to display the New Project dialog box. - - - Create a new FSharpProject Console Application. - The new solution appears in Solution Explorer, the file Program.py appears in the code editor, and the project - properties appear in the Properties Browser. - - - Right-click the project node and click Properties. - - - The Property Pages dialog box appears and displays the common and configuration properties. - - - Close the dialog box. Press F5 to build and run the FSharp program Program.py. - A console window opens, displays "Hello VSIP!", and closes. - - - - - - Visual Studio SDK Website - http://msdn.microsoft.com/vstudio/extend - - - - - Create an instance and make sure the instance implements IVsPackage. - - - Make sure that the project can add a reference. - - - - - Make sure that the project can add new FSharp items. - - - Make sure that the project can add a reference. - - - - - Automation.cs - - Contains a number of classes that enables automation of the FSharp project and py files in the Iron FSharp Project. Especially the project object enables the CodeModel - - - - ConfigurationPropertyPages.cs - - Contains a definition for the build property page in the Project Designer. - - - - EditorFactory.cs - - Contains a definition for the editor factory that creates the editor for editting iron python code files in code/design view - - - - Enums.cs - - Contains enumerations defined for the Iron FSharp Project. - - - - Guids.cs - - Defines the Package and Project guids. - - - - PkgCmd.vsct - - Defines the layout for Iron FSharp specific commands. - - - - ProjectDocumentsListenerForMainFileUpdates.cs - Implements a project listener that updates the mainfile project property in the iron python project whenever files are renamed/added/deleted - - - PropertyPages.cs - Contains the implementation for the General Tab in the Projct Designer - - - FSharpConfigProvider.cs - Enables the Any CPU Platform name for Iron FSharp Projects - - - FSharpFileNode.cs - Contains Iron FSharp specific implementation details of FileNode - - - FSharpFileNodeProperties.cs - Contains a definition of the Iron FSharp specific Node properties. The class derives from SingleFileNodeProperties which means that a Custom Tool can be associated with a py file. - - - FSharpMenus.cs - - Defines CommandIDs matching the commands defined symbols in PkgCmd.vsct. - - - - FSharpProjectFactory.cs - - Defines the Iron FSharp project factory. - - - - FSharpProjectFileConstants.cs - - Defines constants used by the Iron FSharp project file. - - - - FSharpProjectNode.cs - - Contains the implementation for the project node in the Iron FSharp Project. - - - - FSharpProjectNodeProperties.cs - Defines Iron FSharp specific Node Properties for the ProjectNode object - - - FSharpPrjectPackage.cs - - Defines the package object for Iron FSharp project package. - - - - FSharpProjectReferenceNode.cs - - Defines Iron FSharp Project specific requirements for project to project references. - - - - FSharpReferenceContainerNode.cs - - Defines the reference container node for Iron FSharp projects. - - - - SelectionElementValueChangedListener.cs - Defines a Selection changed listener that enables the RunGenerator on a python file node to be triggered when focus is removed from an active iron python document window - - - VSMDFSharpProvider.cs - Contains the definition of the FSharp CodeDOM Provider. The provider listen for reference event in order to stay in sync with list of references in the FSharp project - - - WPFProviders\FSharpEventBindingProvider.cs - Contains the FSharpEventBindingProvider which provides the communication between the WPF designer and the associated code file for adding and navigating to event handlers. - - - WPFProviders\FSharpRuntimeNameProvider.cs - Contains the FSharpRuntimeNameFactory which contains logic to generate uniquely named code fields for WPF designer scenarios. - - - WPFProviders\FSharpWPFFlavor.cs - - Contains the definition of the Iron FSharp project flavor of the WPFFlavor. - - - - WPFProviders\FSharpWPFProjectFactory.cs - - Defines the factory object for the Iron FSharp project flavor of the WPFFlavor. - - - - - - 2005-11-21 - Created this sample for the Visual Studio SDK. - - - 2007-07-19 - Added support for WPF Applications. - - - 2007-10-10 - Fixed bugs related to references. - - - \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf index 02128b8f00..e78a05c293 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.cs.xlf @@ -247,6 +247,16 @@ Nová &složka + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf index 74b69acd48..599aef2e63 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.de.xlf @@ -247,6 +247,16 @@ &Neuer Ordner + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf index 5f286a9569..93c89dde5d 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.es.xlf @@ -247,6 +247,16 @@ N&ueva carpeta + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf index 2e8a0c0045..06d8792de9 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.fr.xlf @@ -247,6 +247,16 @@ Nouveau &dossier + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf index 5b59a67af8..bfb7b0ecba 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.it.xlf @@ -247,6 +247,16 @@ &Nuova cartella + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf index 4266774b23..ba367c1f98 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ja.xlf @@ -247,6 +247,16 @@ 新しいフォルダー(&D) + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf index 1d311984ca..9ef00ff657 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ko.xlf @@ -247,6 +247,16 @@ 새 폴더(&D) + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf index 0b59a2dd7d..fda1699bef 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pl.xlf @@ -247,6 +247,16 @@ Nowy fol&der + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf index e2a2158cf9..1270adfb53 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.pt-BR.xlf @@ -247,6 +247,16 @@ Nova pa&sta + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf index 77e44dc54e..1ecdebb84d 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.ru.xlf @@ -247,6 +247,16 @@ &Создать папку + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf index 4ac66f5451..501c04fae1 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.tr.xlf @@ -247,6 +247,16 @@ Yeni &Klasör + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf index 853138f9a5..9c758e3176 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hans.xlf @@ -247,6 +247,16 @@ 新建文件夹(&D) + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf index 918c882429..5aeb25fd03 100644 --- a/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf +++ b/vsintegration/src/FSharp.ProjectSystem.FSharp/xlf/MenusAndCommands.vsct.zh-Hant.xlf @@ -247,6 +247,16 @@ 新增資料夾(&D) + + Quit F# Interactive Process + Quit F# Interactive Process + + + + FSharp.Interactive.QuitProcess + FSharp.Interactive.QuitProcess + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/Properties.resx b/vsintegration/src/FSharp.VS.FSI/Properties.resx index bf0ca9896e..ca594efbb3 100644 --- a/vsintegration/src/FSharp.VS.FSI/Properties.resx +++ b/vsintegration/src/FSharp.VS.FSI/Properties.resx @@ -157,5 +157,11 @@ Enable preview language features + + Use .NET Core Scripting + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt b/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt index 59f9615fff..0e1e7979c8 100644 --- a/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt +++ b/vsintegration/src/FSharp.VS.FSI/VFSIstrings.txt @@ -4,9 +4,10 @@ cannotCreateToolWindow,"Cannot create window F# Interactive ToolWindow" exceptionRaisedWhenCreatingRemotingClient,"Exception raised when creating remoting client for launched fsi.exe\n%s" exceptionRaisedWhenRequestingToolWindow,"Exception raised when requesting FSI ToolWindow.\n%s" couldNotObtainFSharpLS,"Could not load F# language service" -sessionTerminationDetected,"Session termination detected. Press Enter to restart." +sessionTerminationDetected,"Session termination detected." fsharpInteractive,"F# Interactive" couldNotFindFsiExe,"Could not find fsi.exe, the F# Interactive executable.\nThis file does not exist:\n\n%s\n" killingProcessRaisedException,"Killing process raised exception:\n%s" sessionIsNotDebugFriendly,"The current F# Interactive session is not configured for debugging. For the best experience, enable debugging in F# Interactive settings, then reset the session.\n\nAttempt debugging with current settings?" doNotShowWarningInFuture,"Don't show this warning again" +sessionInitialMessageNetCore,"Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings." diff --git a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs index c0ef2546c6..8e4d397476 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiBasis.fs @@ -1,36 +1,12 @@ // Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. namespace Microsoft.VisualStudio.FSharp.Interactive -#if DESIGNER -#r "FSharp.Compiler.Server.Shared.dll" -#I @"C:\Program Files\Microsoft Visual Studio 2008 SDK\VisualStudioIntegration\Common\Assemblies" -#I @"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5" -#r "System.Core.dll" -#r "system.windows.forms.dll" -#r "Microsoft.VisualStudio.OLE.Interop.dll" -#r "Microsoft.VisualStudio.Package.LanguageService.9.0.dll" -#r "Microsoft.VisualStudio.Shell.9.0.dll" -#r "Microsoft.VisualStudio.Shell.Interop.dll" -#r "Microsoft.VisualStudio.Shell.Interop.8.0.dll" -#r "Microsoft.VisualStudio.Shell.Interop.9.0.dll" -#r "Microsoft.VisualStudio.TextManager.Interop.dll" -#r "Microsoft.VisualStudio.TextManager.Interop.8.0.dll" -#endif - open System -open System.IO -open System.Diagnostics -open System.Globalization open System.Text.RegularExpressions -open System.Windows.Forms open System.Runtime.InteropServices -open System.ComponentModel.Design open Microsoft.Win32 -open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.OLE.Interop -open Microsoft.VisualStudio.Shell -open Microsoft.VisualStudio.TextManager.Interop module internal AssemblyAttributes = [] diff --git a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs index 581eafdd28..160b7a204f 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiLanguageService.fs @@ -3,18 +3,11 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.IO -open System.Diagnostics -open System.Globalization -open System.Windows.Forms open System.Runtime.InteropServices -open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.FSharp.Interactive open Microsoft.VisualStudio.OLE.Interop open Microsoft.VisualStudio.Shell -open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.Package open Microsoft.VisualStudio.TextManager.Interop open System.ComponentModel.Composition @@ -63,6 +56,11 @@ type FsiPropertyPage() = [] member this.FsiPreview with get() = SessionsProperties.fsiPreview and set (x:bool) = SessionsProperties.fsiPreview <- x + [] + [] + [] + member this.FsiUseNetCore with get() = SessionsProperties.fsiUseNetCore and set (x:bool) = SessionsProperties.fsiUseNetCore <- x + // CompletionSet type internal FsiCompletionSet(imageList,source:Source) = inherit CompletionSet(imageList, source) diff --git a/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs b/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs index bbe816faf9..446c425a9c 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiPackageHooks.fs @@ -3,18 +3,12 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.Diagnostics -open System.Globalization -open System.Runtime.InteropServices open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop -open Microsoft.VisualStudio.OLE.Interop open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.TextManager.Interop open Util -open EnvDTE module internal Hooks = let fsiServiceCreatorCallback(package:Package) = diff --git a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs index eae479ef9e..9928875e16 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiSessionToolWindow.fs @@ -4,10 +4,8 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System open System.Diagnostics -open System.Globalization open System.Runtime.InteropServices open System.ComponentModel.Design -open Microsoft.Win32 open Microsoft.VisualStudio open Microsoft.VisualStudio.Shell.Interop open Microsoft.VisualStudio.OLE.Interop @@ -19,7 +17,6 @@ open EnvDTE open Microsoft.VisualStudio.ComponentModelHost open Microsoft.VisualStudio.Editor open Microsoft.VisualStudio.Text.Editor -open Microsoft.VisualStudio.Text open Microsoft.VisualStudio.Utilities type VSStd2KCmdID = VSConstants.VSStd2KCmdID // nested type @@ -39,12 +36,12 @@ module internal Locals = let defaultVSRegistryRoot = @"Software\Microsoft\VisualStudio\15.0" let settingsRegistrySubKey = @"General" let debugPromptRegistryValue = "FSharpHideScriptDebugWarning" + // Prompts come through as "SERVER-PROMPT>\n" (when in "server mode"). + // In fsi.exe, the newline is needed to get the output send through to VS. + // Here the reverse mapping is applied. + let prompt = "SERVER-PROMPT>" let fixServerPrompt (str:string) = - // Prompts come through as "SERVER-PROMPT>\n" (when in "server mode"). - // In fsi.exe, the newline is needed to get the output send through to VS. - // Here the reverse mapping is applied. - let prompt = "SERVER-PROMPT>" in (* Replace 'prompt' by ">" throughout string, add newline, unless ending in prompt *) let str = if str.EndsWith(prompt) then str + " " else str + Environment.NewLine let str = str.Replace(prompt,">") @@ -197,14 +194,18 @@ type internal FsiToolWindow() as this = let history = HistoryBuffer() let sessions = Session.FsiSessions() do fsiLangService.Sessions <- sessions - let writeTextAndScroll (str:string) = + + let writeText scroll (str:string) = if str <> null && textLines <> null then lock textLines (fun () -> textStream.DirectWrite(fixServerPrompt str) - setScrollToEndOfBuffer() // I'm not convinced that users want jump to end on output. - ) // IP sample did it. Previously, VFSI did not. - // What if there is scrolling output on a timer and a user wants to look over it?? - // Maybe, if already at the end, then stay at the end? + if scroll then + setScrollToEndOfBuffer() + ) + + let writeTextAndScroll (str:string) = writeText true str + + let writeTextNoScroll (str:string) = writeText false str // Merge stdout/stderr events prior to buffering. Paired with StdOut/StdErr keys so we can split them afterwards. let responseE = Observable.merge (Observable.map (pair StdOut) sessions.Output) (Observable.map (pair StdErr) sessions.Error) @@ -222,19 +223,27 @@ type internal FsiToolWindow() as this = | StdErr,strs -> writeTextAndScroll (String.concat Environment.NewLine strs) // later: hence keep them split. do responseBufferE.Add(fun keyStrings -> let keyChunks : (Response * string list) list = chunkKeyValues keyStrings List.iter writeKeyChunk keyChunks) + let showInitialMessageNetCore scroll = + if Session.SessionsProperties.fsiUseNetCore then + writeText scroll ((VFSIstrings.SR.sessionInitialMessageNetCore()+Environment.NewLine+prompt)) // Write message on a session termination. Should be called on Gui thread. let recordTermination () = if not sessions.Alive then // check is likely redundant synchronizationContext.Post( System.Threading.SendOrPostCallback( - fun _ -> writeTextAndScroll ((VFSIstrings.SR.sessionTerminationDetected())+Environment.NewLine) + fun _ -> + writeTextAndScroll ((VFSIstrings.SR.sessionTerminationDetected())+Environment.NewLine) + showInitialMessageNetCore true ), null) do sessions.Exited.Add(fun _ -> recordTermination()) - - // finally, start the session - do sessions.Restart() + + // For .NET Core the session doesn't start automatically. Rather it may optionally be started by an Alt-Enter from a script, + // or else by pressing Enter in the REPL window. + do showInitialMessageNetCore false + if not Session.SessionsProperties.fsiUseNetCore then + sessions.Restart(null) let clearUndoStack (textLines:IVsTextLines) = // Clear the UNDO stack. let undoManager = textLines.GetUndoManager() |> throwOnFailure1 @@ -291,19 +300,15 @@ type internal FsiToolWindow() as this = strHandle.Free() ) - let executeTextNoHistory (text:string) = + let executeTextNoHistory sourceFile (text:string) = + sessions.Ensure(sourceFile) textStream.DirectWriteLine() sessions.SendInput(text) setCursorAtEndOfBuffer() - let executeText (text:string) = - textStream.DirectWriteLine() - history.Add(text) - sessions.SendInput(text) - setCursorAtEndOfBuffer() - let executeUserInput() = if isCurrentPositionInInputArea() then + sessions.Ensure(null) let text = getInputAreaText() textStream.ExtendReadOnlyMarker() textStream.DirectWriteLine() @@ -317,7 +322,8 @@ type internal FsiToolWindow() as this = let supportWhenInInputArea (sender:obj) (args:EventArgs) = let command = sender :?> MenuCommand if null <> command then // are these null checks needed? - command.Supported <- not source.IsCompletorActive && isCurrentPositionInInputArea() + let enabled = not source.IsCompletorActive && isCurrentPositionInInputArea() + command.Supported <- enabled /// Support command except when completion is active. let supportUnlessCompleting (sender:obj) (args:EventArgs) = @@ -333,13 +339,13 @@ type internal FsiToolWindow() as this = let supportWhenAtStartOfInputArea (sender:obj) (e:EventArgs) = let command = sender :?> MenuCommand if command <> null then - command.Supported <- isCurrentPositionAtStartOfInputArea() + command.Supported <- not source.IsCompletorActive && isCurrentPositionInInputArea() /// Support when at the start of the input area AND no-selection (e.g. to enable NoAction on BACKSPACE). let supportWhenAtStartOfInputAreaAndNoSelection (sender:obj) (e:EventArgs) = let command = sender :?> MenuCommand if command <> null then - command.Supported <- isCurrentPositionAtStartOfInputArea() && not (haveTextViewSelection()) + command.Supported <- isCurrentPositionAtStartOfInputArea() let supportWhenSelectionIntersectsWithReadonlyOrNoSelection (sender:obj) (_:EventArgs) = let command = sender :?> MenuCommand @@ -414,13 +420,15 @@ type internal FsiToolWindow() as this = textLines.ReplaceLines(0, 0, lastLine, lastColumn, IntPtr.Zero, 0, null) |> throwOnFailure0 ) clearUndoStack textLines // The reset clear should not be undoable. - sessions.Restart() + showInitialMessageNetCore true + if not Session.SessionsProperties.fsiUseNetCore then + sessions.Restart(null) /// Handle RETURN, unless Intelisense completion is in progress. let onReturn (sender:obj) (e:EventArgs) = lock textLines (fun () -> if not sessions.Alive then - sessions.Restart() + sessions.Restart(null) else if isCurrentPositionInInputArea() then executeUserInput() @@ -520,10 +528,10 @@ type internal FsiToolWindow() as this = showNoActivate() let directiveC = sprintf "# 1 \"stdin\"" (* stdin line number reset code *) let text = "\n" + text + "\n" + directiveC + "\n;;\n" - executeTextNoHistory text + executeTextNoHistory null text with _ -> () - let executeInteraction dbgBreak dir filename topLine text = + let executeInteraction dbgBreak dir (filename: string) topLine text = // Preserving previous functionality, including the #directives... let interaction = "\n" @@ -534,7 +542,7 @@ type internal FsiToolWindow() as this = + "# 1 \"stdin\"" + "\n" (* stdin line number reset code *) + ";;" + "\n" - executeTextNoHistory interaction + executeTextNoHistory filename interaction let sendSelectionToFSI action = let dbgBreak,selectLine = diff --git a/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs b/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs index 6bcac8c608..a5e3128e87 100644 --- a/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs +++ b/vsintegration/src/FSharp.VS.FSI/fsiTextBufferStream.fs @@ -3,22 +3,8 @@ namespace Microsoft.VisualStudio.FSharp.Interactive open System -open System.IO -open System.Diagnostics -open System.Globalization -open System.Windows.Forms -open System.Runtime.InteropServices -open System.ComponentModel.Design -open Microsoft.Win32 -open Microsoft.VisualStudio -open Microsoft.VisualStudio.Shell.Interop -open Microsoft.VisualStudio.OLE.Interop -open Microsoft.VisualStudio.Shell open Microsoft.VisualStudio.TextManager.Interop -open Util -open Microsoft.VisualStudio.Editor open Microsoft.VisualStudio.Text -open Microsoft.VisualStudio.Text.Editor open Microsoft.VisualStudio.Utilities // This type wraps the IVsTextLines which contains the FSI session (output and input). diff --git a/vsintegration/src/FSharp.VS.FSI/sessions.fs b/vsintegration/src/FSharp.VS.FSI/sessions.fs index c91b9ef66a..b8649fa7fb 100644 --- a/vsintegration/src/FSharp.VS.FSI/sessions.fs +++ b/vsintegration/src/FSharp.VS.FSI/sessions.fs @@ -2,15 +2,12 @@ module internal Microsoft.VisualStudio.FSharp.Interactive.Session -open FSharp.Compiler open System open System.IO open System.Text open System.Diagnostics open System.Runtime.Remoting open System.Runtime.Remoting.Lifetime -open System.Windows.Forms -open Internal.Utilities #nowarn "52" // The value has been copied to ensure the original is not mutated by this operation @@ -67,6 +64,7 @@ let timeoutApp descr timeoutMS (f : 'a -> 'b) (arg:'a) = module SessionsProperties = let mutable useAnyCpuVersion = true // 64-bit by default + let mutable fsiUseNetCore = false let mutable fsiArgs = "--optimize" let mutable fsiShadowCopy = true let mutable fsiDebugMode = false @@ -130,37 +128,48 @@ let catchAll trigger x = try trigger x with err -> System.Windows.Forms.MessageBox.Show(err.ToString()) |> ignore -let fsiExeName () = - if SessionsProperties.useAnyCpuVersion then "fsiAnyCpu.exe" else "fsi.exe" - -// Use the VS-extension-installed development path if available, relative to the location of this assembly -let determineFsiRelativePath1 () = - let thisAssemblyDirectory = typeof.Assembly.Location |> Path.GetDirectoryName - Path.Combine(thisAssemblyDirectory,fsiExeName() ) - -// This path is relative to the location of "FSharp.Compiler.Interactive.Settings.dll" -let determineFsiRelativePath2 () = - let thisAssembly : System.Reflection.Assembly = typeof.Assembly - let thisAssemblyDirectory = thisAssembly.Location |> Path.GetDirectoryName - // Use the quick-development path if available - Path.Combine(thisAssemblyDirectory,fsiExeName() ) - let determineFsiPath () = - // Choose VS extension path, if it exists (for developers) - let fsiRelativePath1 = determineFsiRelativePath1() - if File.Exists fsiRelativePath1 then fsiRelativePath1 else - - // Choose relative path, if it exists (for developers), otherwise, the installed path. - let fsiRelativePath2 = determineFsiRelativePath2() - if File.Exists fsiRelativePath2 then fsiRelativePath2 else - - // Try the registry key - let fsbin = match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None) with Some(s) -> s | None -> "" - let fsiRegistryPath = Path.Combine(fsbin, fsiExeName() ) - if File.Exists(fsiRegistryPath) then fsiRegistryPath else - - // Otherwise give up - raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath)) + if SessionsProperties.fsiUseNetCore then + let pf = Environment.GetEnvironmentVariable("ProgramW6432") + let pf = if String.IsNullOrEmpty(pf) then Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) else pf + let exe = Path.Combine(pf,"dotnet","dotnet.exe") + let arg = "fsi" + if not (File.Exists exe) then + raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe exe)) + exe, arg, false, false + else + let fsiExeName () = + if SessionsProperties.useAnyCpuVersion then "fsiAnyCpu.exe" else "fsi.exe" + + // Use the VS-extension-installed development path if available, relative to the location of this assembly + let determineFsiRelativePath1 () = + let thisAssemblyDirectory = typeof.Assembly.Location |> Path.GetDirectoryName + Path.Combine(thisAssemblyDirectory,fsiExeName() ) + + // This path is relative to the location of "FSharp.Compiler.Interactive.Settings.dll" + let determineFsiRelativePath2 () = + let thisAssembly : System.Reflection.Assembly = typeof.Assembly + let thisAssemblyDirectory = thisAssembly.Location |> Path.GetDirectoryName + // Use the quick-development path if available + Path.Combine(thisAssemblyDirectory,fsiExeName() ) + + let fsiExe = + // Choose VS extension path, if it exists (for developers) + let fsiRelativePath1 = determineFsiRelativePath1() + if File.Exists fsiRelativePath1 then fsiRelativePath1 else + + // Choose relative path, if it exists (for developers), otherwise, the installed path. + let fsiRelativePath2 = determineFsiRelativePath2() + if File.Exists fsiRelativePath2 then fsiRelativePath2 else + + // Try the registry key + let fsbin = match Internal.Utilities.FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None) with Some(s) -> s | None -> "" + let fsiRegistryPath = Path.Combine(fsbin, fsiExeName() ) + if File.Exists(fsiRegistryPath) then fsiRegistryPath else + + // Otherwise give up + raise (SessionError (VFSIstrings.SR.couldNotFindFsiExe fsiRegistryPath)) + fsiExe, "", true, true let readLinesAsync (reader: StreamReader) trigger = let buffer = StringBuilder(1024) @@ -206,9 +215,9 @@ let readLinesAsync (reader: StreamReader) trigger = } Async.StartImmediate (read 0) -let fsiStartInfo channelName = +let fsiStartInfo channelName sourceFile = let procInfo = new ProcessStartInfo() - let fsiPath = determineFsiPath () + let fsiPath, fsiFirstArgs, fsiSupportsServer, fsiSupportsShadowcopy = determineFsiPath () procInfo.FileName <- fsiPath // Mismatched encoding on I/O streams between VS addin and it's FSI session. @@ -217,29 +226,23 @@ let fsiStartInfo channelName = // We also need to send fsi.exe the locale of the VS process let inCP,outCP = Encoding.UTF8.CodePage,Encoding.UTF8.CodePage - let addBoolOption name value args = sprintf "%s --%s%s" args name (if value then "+" else "-") - let addStringOption name value args = sprintf "%s --%s:%O" args name value + let addBoolOption b name value args = if b then sprintf "%s --%s%s" args name (if value then "+" else "-") else args + let addStringOption b name value args = if b then sprintf "%s --%s:%O" args name value else args let procArgs = - "" - |> addStringOption "fsi-server-output-codepage" outCP - |> addStringOption "fsi-server-input-codepage" inCP - |> addStringOption "fsi-server-lcid" System.Threading.Thread.CurrentThread.CurrentUICulture.LCID - |> addStringOption "fsi-server" channelName + fsiFirstArgs + |> addStringOption true "fsi-server-output-codepage" outCP + |> addStringOption true "fsi-server-input-codepage" inCP + |> addStringOption true "fsi-server-lcid" System.Threading.Thread.CurrentThread.CurrentUICulture.LCID + //|> addStringOption true "fsi-server-association-file" sourceFile + |> addStringOption true "fsi-server" channelName |> (fun s -> s + sprintf " %s" SessionsProperties.fsiArgs) - |> addBoolOption "shadowcopyreferences" SessionsProperties.fsiShadowCopy - |> (fun args -> - // for best debug experience, need optimizations OFF and debug info ON - // tack these on the the end, they will override whatever comes earlier - if SessionsProperties.fsiDebugMode then - args |> addBoolOption "optimize" false |> addBoolOption "debug" true - else - args) - |> (fun args -> - if SessionsProperties.fsiPreview then - args |> addStringOption "langversion" "preview" - else - args) + |> addBoolOption fsiSupportsShadowcopy "shadowcopyreferences" SessionsProperties.fsiShadowCopy + // For best debug experience, need optimizations OFF and debug info ON + // tack these on the the end, they will override whatever comes earlier + |> addBoolOption SessionsProperties.fsiDebugMode "optimize" false + |> addBoolOption SessionsProperties.fsiDebugMode "debug" true + |> addStringOption SessionsProperties.fsiPreview "langversion" "preview" procInfo.Arguments <- procArgs procInfo.CreateNoWindow <- true @@ -249,16 +252,20 @@ let fsiStartInfo channelName = procInfo.RedirectStandardOutput <- true procInfo.StandardOutputEncoding <- Encoding.UTF8 procInfo.StandardErrorEncoding <- Encoding.UTF8 - let tmpPath = Path.GetTempPath() - if Directory.Exists(tmpPath) then - procInfo.WorkingDirectory <- tmpPath - procInfo + + let initialPath = + match sourceFile with + | path when path <> null && Directory.Exists(Path.GetDirectoryName(path)) -> Path.GetDirectoryName(path) + | _ -> Path.GetTempPath() + if Directory.Exists(initialPath) then + procInfo.WorkingDirectory <- initialPath + procInfo, fsiSupportsServer let nonNull = function null -> false | (s:string) -> true /// Represents an active F# Interactive process to which Visual Studio is connected via stdin/stdout/stderr and a remoting channel -type FsiSession() = +type FsiSession(sourceFile: string) = let randomSalt = System.Random() let channelName = let pid = System.Diagnostics.Process.GetCurrentProcess().Id @@ -266,7 +273,7 @@ type FsiSession() = let salt = randomSalt.Next() sprintf "FSIChannel_%d_%d_%d" pid tick salt - let procInfo = fsiStartInfo channelName + let procInfo, fsiSupportsServer = fsiStartInfo channelName sourceFile let cmdProcess = new Process(StartInfo=procInfo) let fsiOutput = Event<_>() let fsiError = Event<_>() @@ -293,9 +300,12 @@ type FsiSession() = do cmdProcess.EnableRaisingEvents <- true - let client = - try FSharp.Compiler.Server.Shared.FSharpInteractiveServer.StartClient(channelName) - with e -> raise (SessionError (VFSIstrings.SR.exceptionRaisedWhenCreatingRemotingClient(e.ToString()))) + let clientConnection = + if fsiSupportsServer then + try Some (FSharp.Compiler.Server.Shared.FSharpInteractiveServer.StartClient(channelName)) + with e -> raise (SessionError (VFSIstrings.SR.exceptionRaisedWhenCreatingRemotingClient(e.ToString()))) + else + None /// interrupt timeout in miliseconds let interruptTimeoutMS = 1000 @@ -316,10 +326,13 @@ type FsiSession() = // Create session object member x.Interrupt() = - checkLeaseStatus client - match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with - | Some () -> true - | None -> false + match clientConnection with + | None -> false + | Some client -> + checkLeaseStatus client + match timeoutApp "VFSI interrupt" interruptTimeoutMS (fun () -> client.Interrupt()) () with + | Some () -> true + | None -> false member x.SendInput (str: string) = inputQueue.Post(str) @@ -331,6 +344,8 @@ type FsiSession() = member x.Alive = not cmdProcess.HasExited + member x.SupportsInterrupt = not cmdProcess.HasExited && clientConnection.IsSome // clientConnection not on .NET Core + member x.ProcessID = cmdProcess.Id member x.ProcessArgs = procInfo.Arguments @@ -367,10 +382,10 @@ type FsiSessions() = // clearing sessionR before kill() means session.Exited is ignored below session.Kill()) - let restart() = + let restart(sourceFile) = kill() try - let session = FsiSession() + let session = FsiSession(sourceFile) sessionR <- Some session // All response callbacks are guarded by checks that "session" is still THE ACTIVE session. session.Output.Add(fun s -> if isCurrentSession session then fsiOut.Trigger s) @@ -379,6 +394,9 @@ type FsiSessions() = with SessionError text -> fsiError.Trigger text + let ensure(sourceFile) = + if sessionR.IsNone then restart(sourceFile) + member x.Interrupt() = sessionR |> Option.forall (fun session -> session.Interrupt()) @@ -392,6 +410,9 @@ type FsiSessions() = member x.Alive = sessionR |> Option.exists (fun session -> session.Alive) + member x.SupportsInterrupt = + sessionR |> Option.exists (fun session -> session.SupportsInterrupt) + member x.ProcessID = match sessionR with | None -> -1 (* -1 assumed to never be a valid process ID *) @@ -403,5 +424,9 @@ type FsiSessions() = | Some session -> session.ProcessArgs member x.Kill() = kill() - member x.Restart() = restart() + + member x.Ensure(sourceFile) = ensure(sourceFile) + + member x.Restart(sourceFile) = restart(sourceFile) + member x.Exited = fsiExited.Publish diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf index e639f36873..b7bbc72117 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.cs.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64bitový F# Interactive + 64bitový F# Interactive If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - V případě nastavení na true a za předpokladu, že aktuální počítač je 64bitový, se F# Interactive spustí jako 64bitový proces. (V opačném případě je F# Interactive 32bitový proces.) + V případě nastavení na true a za předpokladu, že aktuální počítač je 64bitový, se F# Interactive spustí jako 64bitový proces. (V opačném případě je F# Interactive 32bitový proces.) + + + + Misc + Misc @@ -22,11 +27,6 @@ Další argumenty příkazového řádku předané F# Interactive a spustitelné v sadě Visual Studio. (Pokud se povolí ladění skriptů, ignorují se příznaky optimalizace a ladění.) - - Misc - Různé - - FSI Preview FSI Preview @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Povolit vyvíjené funkce jazyka ve verzi Preview v jazyce F# Interactive + Povolit vyvíjené funkce jazyka ve verzi Preview v jazyce F# Interactive @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Znemožňuje zamknutí odkazovaných sestavení procesem F# Interactive. + Znemožňuje zamknutí odkazovaných sestavení procesem F# Interactive. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Povolit ladění skriptů F# (může ovlivnit výkon skriptů, vyžaduje restartování F# Interactive) + Povolit ladění skriptů F# (může ovlivnit výkon skriptů, vyžaduje restartování F# Interactive) @@ -67,6 +67,16 @@ Ladění + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf index 76d0e5a44b..dbf4d73635 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.de.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64-Bit-Version von F# Interactive + 64-Bit-Version von F# Interactive If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Wenn diese Einstellung auf "True" gesetzt ist und der aktuelle Computer eine 64-Bit-Version ist, müssen Sie F# Interactive als einen 64-Bit-Prozess ausführen (Andernfalls ist F# Interactive ein 32-Bit-Prozess). + Wenn diese Einstellung auf "True" gesetzt ist und der aktuelle Computer eine 64-Bit-Version ist, müssen Sie F# Interactive als einen 64-Bit-Prozess ausführen (Andernfalls ist F# Interactive ein 32-Bit-Prozess). + + + + Misc + Misc @@ -22,11 +27,6 @@ Die an die ausführbare F# Interactive-Datei von Visual Studio übergebenen zusätzlichen Befehlszeilenargumente. (Optimierungs- und Debugflags werden bei aktiviertem Skriptdebuggen ignoriert.) - - Misc - Verschiedene - - FSI Preview FSI-Vorschau @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Vorschau der in Entwicklung befindlichen Sprachfeatures in F# Interactive aktivieren + Vorschau der in Entwicklung befindlichen Sprachfeatures in F# Interactive aktivieren @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Verhindert, dass referenzierte Assemblys vom F# Interactive-Prozess gesperrt werden. + Verhindert, dass referenzierte Assemblys vom F# Interactive-Prozess gesperrt werden. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Debuggen von F#-Skripts aktivieren (kann die Skriptleistung beeinträchtigen, erfordert das Zurücksetzen von F# Interactive) + Debuggen von F#-Skripts aktivieren (kann die Skriptleistung beeinträchtigen, erfordert das Zurücksetzen von F# Interactive) @@ -67,6 +67,16 @@ Debuggen + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf index 8ac14c069a..77a63b6c3c 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.es.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - F# interactivo de 64 bits + F# interactivo de 64 bits If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Si se establece en True y la máquina actual es de 64 bits, F# interactivo se ejecuta como proceso de 64 bits; de lo contrario, se ejecuta como proceso de 32 bits. + Si se establece en True y la máquina actual es de 64 bits, F# interactivo se ejecuta como proceso de 64 bits; de lo contrario, se ejecuta como proceso de 32 bits. + + + + Misc + Misc @@ -22,11 +27,6 @@ Argumentos de la línea de comandos adicional pasados al archivo ejecutable de F# interactivo por Visual Studio. (se prescinde de las marcas de optimización y depuración si la depuración de scripts está habilitada) - - Misc - Varios - - FSI Preview Versión preliminar de FSI @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Habilita la versión preliminar de las características del lenguaje en desarrollo de F# interactivo. + Habilita la versión preliminar de las características del lenguaje en desarrollo de F# interactivo. @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Impide que el proceso de F# interactivo bloquee los ensamblados a los que se hace referencia. + Impide que el proceso de F# interactivo bloquee los ensamblados a los que se hace referencia. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Habilitar depuración de scripts F# (puede afectar al rendimiento de los scripts y requiere restablecer F# interactivo) + Habilitar depuración de scripts F# (puede afectar al rendimiento de los scripts y requiere restablecer F# interactivo) @@ -67,6 +67,16 @@ Depuración + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf index 30b049287c..921fc5ffd7 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.fr.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - F# Interactive 64 bits + F# Interactive 64 bits If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Si la valeur est true et que l'ordinateur actuel est de type 64 bits, exécutez F# Interactive en tant que processus 64 bits. (Sinon, F# Interactive est un processus 32 bits.) + Si la valeur est true et que l'ordinateur actuel est de type 64 bits, exécutez F# Interactive en tant que processus 64 bits. (Sinon, F# Interactive est un processus 32 bits.) + + + + Misc + Misc @@ -22,11 +27,6 @@ Arguments supplémentaires de la ligne de commande passés à l'exécutable F# Interactive par Visual Studio. (les indicateurs d'optimisation et de débogage sont ignorés si le débogage de script est activé) - - Misc - Divers - - FSI Preview Préversion FSI @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Activer la préversion des fonctionnalités de langage en développement dans F# Interactive + Activer la préversion des fonctionnalités de langage en développement dans F# Interactive @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Empêche le blocage des assemblys référencés par le processus de F# Interactive. + Empêche le blocage des assemblys référencés par le processus de F# Interactive. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Activer le débogage des scripts F# (peut avoir un impact sur la performance des scripts, requiert une réinitialisation de F# Interactive) + Activer le débogage des scripts F# (peut avoir un impact sur la performance des scripts, requiert une réinitialisation de F# Interactive) @@ -67,6 +67,16 @@ Débogage + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf index dda750479d..864f565057 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.it.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - F# Interactive a 64 bit + F# Interactive a 64 bit If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Se impostato su true, e il computer corrente è a 64 bit, eseguire F# Interactive come processo a 64 bit. In caso contrario, F# Interactive è un processo a 32 bit. + Se impostato su true, e il computer corrente è a 64 bit, eseguire F# Interactive come processo a 64 bit. In caso contrario, F# Interactive è un processo a 32 bit. + + + + Misc + Misc @@ -22,11 +27,6 @@ Argomenti aggiuntivi della riga di comando passati all'eseguibile F# Interactive da Visual Studio. Se è abilitato il debug di script, i flag di ottimizzazione e debug vengono ignorati. - - Misc - Varie - - FSI Preview Anteprima FSI @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Abilita l'anteprima delle funzionalità del linguaggio in fase di sviluppo in F# Interactive + Abilita l'anteprima delle funzionalità del linguaggio in fase di sviluppo in F# Interactive @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Impedisce che assembly di riferimento vengano bloccati dal processo F# Interactive. + Impedisce che assembly di riferimento vengano bloccati dal processo F# Interactive. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Abilita il debug di script F#. Può influire sulle prestazioni degli script e richiede la reimpostazione di F# Interactive. + Abilita il debug di script F#. Può influire sulle prestazioni degli script e richiede la reimpostazione di F# Interactive. @@ -67,6 +67,16 @@ Debug + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf index 292872a5ee..8eece9052d 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ja.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64 ビット F# インタラクティブ + 64 ビット F# インタラクティブ If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - true に設定されていて、現在のコンピューターが 64 ビットである場合は、F# インタラクティブを 64 ビット プロセスで実行してください (そうしないと、F# インタラクティブは 32 ビット プロセスになります)。 + true に設定されていて、現在のコンピューターが 64 ビットである場合は、F# インタラクティブを 64 ビット プロセスで実行してください (そうしないと、F# インタラクティブは 32 ビット プロセスになります)。 + + + + Misc + Misc @@ -22,11 +27,6 @@ 追加のコマンド ライン引数が Visual Studio によって F# インタラクティブ実行可能ファイルに渡されました。(スクリプト デバッグが有効な場合、最適化とデバッグのフラグは無視されます) - - Misc - その他 - - FSI Preview FSI プレビュー @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - F# インタラクティブの開発中の言語機能についてプレビューを有効にします + F# インタラクティブの開発中の言語機能についてプレビューを有効にします @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - 参照アセンブリを F# インタラクティブ プロセスによってロックされないようにします。 + 参照アセンブリを F# インタラクティブ プロセスによってロックされないようにします。 @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - F# スクリプトのデバッグを有効にする (スクリプトのパフォーマンスに影響を与える可能性があります。F# インタラクティブのリセットが必要です) + F# スクリプトのデバッグを有効にする (スクリプトのパフォーマンスに影響を与える可能性があります。F# インタラクティブのリセットが必要です) @@ -67,6 +67,16 @@ デバッグ中 + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf index beb4244148..17aebccc17 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ko.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64비트 F# 대화형 + 64비트 F# 대화형 If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - true로 설정하는 경우 현재 컴퓨터가 64비트이면 F# 대화형을 64비트 프로세스로 실행하고, 그렇지 않으면 F# 대화형이 32비트 프로세스로 실행됩니다. + true로 설정하는 경우 현재 컴퓨터가 64비트이면 F# 대화형을 64비트 프로세스로 실행하고, 그렇지 않으면 F# 대화형이 32비트 프로세스로 실행됩니다. + + + + Misc + Misc @@ -22,11 +27,6 @@ Visual Studio에서 F# 대화형 실행 파일로 전달되는 추가 명령줄 인수입니다. 스크립트 디버깅을 사용하도록 설정한 경우 최적화 및 디버그 플래그는 무시됩니다. - - Misc - 기타 - - FSI Preview FSI 미리 보기 @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - F# Interactive에서 개발 중인 언어 기능의 미리 보기를 사용하도록 설정합니다. + F# Interactive에서 개발 중인 언어 기능의 미리 보기를 사용하도록 설정합니다. @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - 참조된 어셈블리가 F# 대화형 프로세스에 의해 잠기지 않도록 합니다. + 참조된 어셈블리가 F# 대화형 프로세스에 의해 잠기지 않도록 합니다. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - F# 스크립트 디버깅 사용(스크립트 성능에 영향을 주고, F# 대화형을 다시 설정해야 할 수 있음) + F# 스크립트 디버깅 사용(스크립트 성능에 영향을 주고, F# 대화형을 다시 설정해야 할 수 있음) @@ -67,6 +67,16 @@ 디버깅 + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf index 7d4a0e1046..4ba4f276b9 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pl.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64-bitowe narzędzie F# Interactive + 64-bitowe narzędzie F# Interactive If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Jeśli ustawiono wartość true i obecnie jest używany komputer 64-bitowy, należy uruchomić narzędzie F# Interactive jako proces 64-bitowy. W przeciwnym razie narzędzie F# Interactive zostanie uruchomione jako proces 32-bitowy. + Jeśli ustawiono wartość true i obecnie jest używany komputer 64-bitowy, należy uruchomić narzędzie F# Interactive jako proces 64-bitowy. W przeciwnym razie narzędzie F# Interactive zostanie uruchomione jako proces 32-bitowy. + + + + Misc + Misc @@ -22,11 +27,6 @@ Argumenty wiersza polecenia przekazywane do pliku wykonywalnego narzędzia F# Interactive przez program Visual Studio. (Flagi optymalizacji i debugowania są ignorowane, jeśli włączone jest debugowanie skryptów). - - Misc - Różne - - FSI Preview FSI (wersja zapoznawcza) @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Włącz wersje zapoznawcze funkcji języka w trakcie opracowywania w oknie F# Interactive + Włącz wersje zapoznawcze funkcji języka w trakcie opracowywania w oknie F# Interactive @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Uniemożliwia blokowanie zestawów występujących w odwołaniach przez proces narzędzia F# Interactive. + Uniemożliwia blokowanie zestawów występujących w odwołaniach przez proces narzędzia F# Interactive. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Włącz debugowanie skryptów w języku F# (może to mieć wpływ na wydajność skryptów, wymaga zresetowania narzędzia F# Interactive) + Włącz debugowanie skryptów w języku F# (może to mieć wpływ na wydajność skryptów, wymaga zresetowania narzędzia F# Interactive) @@ -67,6 +67,16 @@ Debugowanie + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf index cc7367e86e..6155113182 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.pt-BR.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - F# Interativo de 64 bits + F# Interativo de 64 bits If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Se estiver definido como true, e o computador atual for 64 bits, execute o F# Interativo como um processo de 64 bits. (Caso contrário, o F# Interactive será um processo de 32 bits.) + Se estiver definido como true, e o computador atual for 64 bits, execute o F# Interativo como um processo de 64 bits. (Caso contrário, o F# Interactive será um processo de 32 bits.) + + + + Misc + Misc @@ -22,11 +27,6 @@ Argumentos da linha de comando adicionais passados para o executável do F# Interativo pelo Visual Studio (sinalizadores de depuração e otimização são ignorados se a depuração do script estiver habilitada) - - Misc - Diversos - - FSI Preview Versão prévia do FSI @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Habilitar as versões prévias de recursos de linguagem em desenvolvimento no F# Interativo + Habilitar as versões prévias de recursos de linguagem em desenvolvimento no F# Interativo @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Impede que os assemblies referenciados sejam bloqueados pelo processo do F# Interativo. + Impede que os assemblies referenciados sejam bloqueados pelo processo do F# Interativo. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Habilitar depuração de scripts do F# (pode impactar o desempenho do script; requer reinicialização do F# Interativo) + Habilitar depuração de scripts do F# (pode impactar o desempenho do script; requer reinicialização do F# Interativo) @@ -67,6 +67,16 @@ Depurando + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf index 10a8b7753d..35c9b8e2f6 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.ru.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - F# Interactive, 64-разрядная версия + F# Interactive, 64-разрядная версия If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - Если задано значение true и текущий компьютер является 64-разрядным, F# Interactive запускается как 64-разрядный процесс. (В остальных случая F# Interactive является 32-разрядным процессом.) + Если задано значение true и текущий компьютер является 64-разрядным, F# Interactive запускается как 64-разрядный процесс. (В остальных случая F# Interactive является 32-разрядным процессом.) + + + + Misc + Misc @@ -22,11 +27,6 @@ Дополнительные аргументы командной строки, передаваемые исполняемому файлу F# Interactive из Visual Studio. Оптимизация и флаги отладки игнорируются, если включена отладка скриптов. - - Misc - Прочее - - FSI Preview Предварительная версия FSI @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - Включить предварительный просмотр функций языка, находящихся в разработке, в F# Interactive + Включить предварительный просмотр функций языка, находящихся в разработке, в F# Interactive @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Предотвращает блокировку сборок, на которые указаны ссылки, интерактивным процессом F#. + Предотвращает блокировку сборок, на которые указаны ссылки, интерактивным процессом F#. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - Включение отладки скриптов F# (может повлиять на их производительность, необходим сброс F# Interactive). + Включение отладки скриптов F# (может повлиять на их производительность, необходим сброс F# Interactive). @@ -67,6 +67,16 @@ Отладка + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf index 85078fa5e2..5312333b39 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.tr.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64 bit F# Etkileşimli + 64 bit F# Etkileşimli If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - True olarak ayarlanırsa ve geçerli makine 64 bit ise F# Etkileşimli'yi 64 bit işlem olarak çalıştırın. (Aksi takdirde F# Etkileşimli 32 bit işlemdir.) + True olarak ayarlanırsa ve geçerli makine 64 bit ise F# Etkileşimli'yi 64 bit işlem olarak çalıştırın. (Aksi takdirde F# Etkileşimli 32 bit işlemdir.) + + + + Misc + Misc @@ -22,11 +27,6 @@ Visual Studio tarafından çalıştırılabilen F# Etkileşimli'ye geçirilmiş ek komut satırı bağımsız değişkenleri. (Betik hata ayıklaması etkinleştirilmişse en iyi duruma getirme ve hata ayıklama bayrakları yok sayılır.) - - Misc - Çeşitli - - FSI Preview FSI Önizleme @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - F# Interactive'deki geliştirme aşamasında olan dil özelliklerinin önizlemesini etkinleştir + F# Interactive'deki geliştirme aşamasında olan dil özelliklerinin önizlemesini etkinleştir @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - Başvurulan bütünleştirilmiş kodların F# Etkileşimli işlemi tarafından kilitlenmesini engeller. + Başvurulan bütünleştirilmiş kodların F# Etkileşimli işlemi tarafından kilitlenmesini engeller. @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - F# betiklerinde hata ayıklamayı etkinleştir (betik performansını etkileyebilir, F# Etkileşimli'nin sıfırlanmasını gerektirir) + F# betiklerinde hata ayıklamayı etkinleştir (betik performansını etkileyebilir, F# Etkileşimli'nin sıfırlanmasını gerektirir) @@ -67,6 +67,16 @@ Hata Ayıklama + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf index f1759dcf7c..8cbfee6b99 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hans.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64 位 F# 交互窗口 + 64 位 F# 交互窗口 If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - 如果设为 true,且当前计算机是 64 位的,则将 F# 交互窗口作为 64 位进程运行。(否则,F# 交互为 32 位进程。) + 如果设为 true,且当前计算机是 64 位的,则将 F# 交互窗口作为 64 位进程运行。(否则,F# 交互为 32 位进程。) + + + + Misc + Misc @@ -22,11 +27,6 @@ 其他命令行参数传递到 Visual Studio 执行的 F# 交互窗口可执行文件。(若已启动脚本调试,则忽略优化和调试标志) - - Misc - 杂项 - - FSI Preview FSI 预览 @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - 在 F# 交互中启用开发中语言功能的预览 + 在 F# 交互中启用开发中语言功能的预览 @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - 防止被引用的程序集被 F# 交互窗口进程锁定。 + 防止被引用的程序集被 F# 交互窗口进程锁定。 @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - 启用 F# 脚本的调试(可能会影响脚本性能,需要重置 F# 交互窗口) + 启用 F# 脚本的调试(可能会影响脚本性能,需要重置 F# 交互窗口) @@ -67,6 +67,16 @@ 正在调试 + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf index ed8368b0bc..9ddffb5864 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/Properties.zh-Hant.xlf @@ -4,12 +4,17 @@ 64-bit F# Interactive - 64 位元 F# 互動 + 64 位元 F# 互動 If set to true, and the current machine is 64-bit, then run F# Interactive as a 64-bit process. (Otherwise, F# Interactive is a 32-bit process.) - 如果設為 true,並且目前電腦為 64 位元,則 F# 互動會當做 64 位元處理序來執行 (反之,F# 互動則為 32 位元處理序)。 + 如果設為 true,並且目前電腦為 64 位元,則 F# 互動會當做 64 位元處理序來執行 (反之,F# 互動則為 32 位元處理序)。 + + + + Misc + Misc @@ -22,11 +27,6 @@ 由 Visual Studio 額外傳遞給 F# 互動可執行檔的命令列引數。(若啟用指令碼偵錯,則會忽略最佳化及偵錯旗標) - - Misc - 其他 - - FSI Preview FSI 預覽 @@ -39,7 +39,7 @@ Enable preview of in-development language features in F# Interactive - 在 F# Interactive 中啟用開發中語言功能的預覽 + 在 F# Interactive 中啟用開發中語言功能的預覽 @@ -49,7 +49,7 @@ Prevents referenced assemblies from being locked by the F# Interactive process. - 避免參考的組件遭 F# 互動處理序封鎖。 + 避免參考的組件遭 F# 互動處理序封鎖。 @@ -59,7 +59,7 @@ Enable debugging of F# scripts (may impact script performance, requires reset of F# Interactive) - 啟用 F# 指令碼偵錯 (可能會影響指令碼效能,必須重設 F# 互動) + 啟用 F# 指令碼偵錯 (可能會影響指令碼效能,必須重設 F# 互動) @@ -67,6 +67,16 @@ 偵錯 + + Use .NET Core Scripting + Use .NET Core Scripting + + + + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + Enable .NET Core script editing and execution for all F# scripts and the F# Interactive window + + \ No newline at end of file diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf index b79b747fad..44a6cb6d1d 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.cs.xlf @@ -22,9 +22,14 @@ Nepovedlo se načíst službu jazyka F#. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Zjistilo se ukončení relace. Pokračovat můžete stisknutím klávesy Enter. + Session termination detected. + Zjistilo se ukončení relace. Pokračovat můžete stisknutím klávesy Enter. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf index e8dabd63d6..4f34e4ec1b 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.de.xlf @@ -22,9 +22,14 @@ Der F#-Sprachendienst konnte nicht geladen werden. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Es wurde eine Beendigung der Sitzung erkannt. Drücken Sie die EINGABETASTE, um neu zu starten. + Session termination detected. + Es wurde eine Beendigung der Sitzung erkannt. Drücken Sie die EINGABETASTE, um neu zu starten. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf index 8fafdfe73d..2c497a4a45 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.es.xlf @@ -22,9 +22,14 @@ No se pudo cargar el servicio del lenguaje F#. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Se detectó una terminación de sesión. Presione Entrar para reiniciar. + Session termination detected. + Se detectó una terminación de sesión. Presione Entrar para reiniciar. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf index 14025011c1..024c05dd2e 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.fr.xlf @@ -22,9 +22,14 @@ Impossible de charger le service de langage F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Fin de session détectée. Appuyez sur Entrée pour redémarrer. + Session termination detected. + Fin de session détectée. Appuyez sur Entrée pour redémarrer. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf index 5f2b1b679c..92c260f4bd 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.it.xlf @@ -22,9 +22,14 @@ Non è stato possibile caricare il servizio di linguaggio F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Rilevata terminazione di sessione. Premere INVIO per riavviare. + Session termination detected. + Rilevata terminazione di sessione. Premere INVIO per riavviare. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf index 34c5ae7317..1e9f067e5c 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ja.xlf @@ -22,9 +22,14 @@ F# 言語サービスを読み込めませんでした + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - セッションの終了が検出されました。再開する場合は Enter キーを押してください。 + Session termination detected. + セッションの終了が検出されました。再開する場合は Enter キーを押してください。 diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf index a4aa68732a..e6ba7ef67c 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ko.xlf @@ -22,9 +22,14 @@ F# 언어 서비스를 로드할 수 없습니다. + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - 세션 종료가 검색되었습니다. 다시 시작하려면 <Enter> 키를 누르세요. + Session termination detected. + 세션 종료가 검색되었습니다. 다시 시작하려면 <Enter> 키를 누르세요. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf index 34a6486541..b7e91e1838 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pl.xlf @@ -22,9 +22,14 @@ Nie można załadować usługi języka F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Wykryto zakończenie sesji. Naciśnij klawisz Enter, aby uruchomić ją ponownie. + Session termination detected. + Wykryto zakończenie sesji. Naciśnij klawisz Enter, aby uruchomić ją ponownie. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf index a3d2f3edb3..681fc0ebb1 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.pt-BR.xlf @@ -22,9 +22,14 @@ Não foi possível carregar o serviço de linguagem F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Encerramento da sessão detectado. Pressione a tecla Enter para reiniciar. + Session termination detected. + Encerramento da sessão detectado. Pressione a tecla Enter para reiniciar. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf index c0b711f3b8..cbc3d37122 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.ru.xlf @@ -22,9 +22,14 @@ Не удалось загрузить службу языка F# + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Обнаружено прекращение сеанса. Нажмите клавишу ВВОД для перезапуска. + Session termination detected. + Обнаружено прекращение сеанса. Нажмите клавишу ВВОД для перезапуска. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf index 6d80fb6bee..d1d66f7e9a 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.tr.xlf @@ -22,9 +22,14 @@ F# dil hizmeti yüklenemedi + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - Oturum sonlandırma algılandı. Yeniden başlatmak için Enter'a basın. + Session termination detected. + Oturum sonlandırma algılandı. Yeniden başlatmak için Enter'a basın. diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf index f4789a477c..978b616be4 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hans.xlf @@ -22,9 +22,14 @@ 未能加载 F# 语言服务 + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - 检测到会话已终止。请按 Enter 重新启动会话。 + Session termination detected. + 检测到会话已终止。请按 Enter 重新启动会话。 diff --git a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf index ba06ff3281..bd18289603 100644 --- a/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf +++ b/vsintegration/src/FSharp.VS.FSI/xlf/VFSIstrings.txt.zh-Hant.xlf @@ -22,9 +22,14 @@ 無法載入 F# 語言服務 + + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + Welcome to F# Interactive for .NET Core in Visual Studio. To execute code, either\n 1. Use 'Send to Interactive' (Alt-Enter or right-click) from an F# script. The F# Interactive process will\n use any global.json settings associated with that script.\n 2. Press 'Enter' to start. The F# Interactive process will use default settings. + + - Session termination detected. Press Enter to restart. - 偵測到工作階段終止。請按 Enter 重新啟動。 + Session termination detected. + 偵測到工作階段終止。請按 Enter 重新啟動。