From c3bfce8c3571d88e19f4371fb12b617d739295c3 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Sun, 3 Mar 2019 01:07:25 +0100 Subject: [PATCH 1/3] use Dotnet.ProjInfo.Workspace.FCS - use workspace loader to parse projects - remove projectcracker - drop project.json support - buildtools not needed anymore - remove nofsharpcore support - use Dotnet.ProjInfo.Workspace.ProjectViewer to render source files --- appveyor.yml | 4 - paket.dependencies | 4 +- paket.lock | 16 +- src/FsAutoComplete.Core/Commands.fs | 71 ++++- .../CompilerServiceInterface.fs | 77 +---- src/FsAutoComplete.Core/Environment.fs | 87 +----- .../FsAutoComplete.Core.fsproj | 5 +- src/FsAutoComplete.Core/FscArguments.fs | 31 -- .../NETFrameworkInfoProvider.fs | 162 +--------- src/FsAutoComplete.Core/Project.fs | 2 +- .../ProjectCrackerDotnetSdk.fs | 293 ------------------ .../ProjectCrackerProjectJson.fs | 43 --- .../ProjectCrackerTypes.fs | 52 +--- .../ProjectCrackerVerbose.fs | 104 ------- src/FsAutoComplete.Core/Utils.fs | 15 +- src/FsAutoComplete.Core/Workspace.fs | 101 +++--- src/FsAutoComplete.Core/paket.references | 2 +- .../JsonSerializer.fs | 6 +- src/FsAutoComplete/CommandResponse.fs | 18 +- src/FsAutoComplete/FsAutoComplete.fsproj | 11 - src/FsAutoComplete/JsonSerializer.fs | 6 +- src/FsAutoComplete/paket.references | 1 - .../NoFSharpCoreReference/FileTwo.fs | 14 - .../NoFSharpCoreReference/Program.fs | 15 - .../NoFSharpCoreReference/Runner.fsx | 21 -- .../NoFSharpCoreReference/Script.fsx | 6 - .../NoFSharpCoreReference/Test1.fsproj | 74 ----- .../NoFSharpCoreReference/output.json | 30 -- .../OldSdk/invalidprojectfile.json | 2 +- .../OldSdk/invalidprojectfile.netcore.json | 2 +- .../UncompiledReferencedProjects/output.json | 4 +- 31 files changed, 176 insertions(+), 1103 deletions(-) delete mode 100644 src/FsAutoComplete.Core/ProjectCrackerDotnetSdk.fs delete mode 100644 src/FsAutoComplete.Core/ProjectCrackerProjectJson.fs delete mode 100644 src/FsAutoComplete.Core/ProjectCrackerVerbose.fs delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/FileTwo.fs delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Program.fs delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Runner.fsx delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Script.fsx delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj delete mode 100644 test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/output.json diff --git a/appveyor.yml b/appveyor.yml index 589e48c15..1d8f75af6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,6 @@ image: - Visual Studio 2017 -install: - - ps: Invoke-WebRequest -Uri "https://download.microsoft.com/download/9/B/B/9BB1309E-1A8F-4A47-A6C5-ECF76672A3B3/BuildTools_Full.exe" -OutFile "BuildTools_Full.exe" - - BuildTools_Full.exe /Quiet /Silent /Full - build_script: - cmd: build.cmd All diff --git a/paket.dependencies b/paket.dependencies index 6a054b389..c8827841f 100644 --- a/paket.dependencies +++ b/paket.dependencies @@ -8,8 +8,8 @@ github Microsoft/visualfsharp:Visual-Studio-2017-Version-15.4 src/fsharp/FSharp. nuget Argu ~> 5.2.0 nuget FSharp.Compiler.Service ~> 29.0 -nuget FSharp.Compiler.Service.ProjectCracker ~> 29.0 framework:net461, condition:net461 -nuget Dotnet.ProjInfo ~> 0.31.0 +nuget Dotnet.ProjInfo ~> 0.35.0 +nuget Dotnet.ProjInfo.Workspace.FCS ~> 0.35.0 nuget FSharp.Data 3.0.1 nuget ICSharpCode.Decompiler 3.2.0.3856 nuget Sln ~> 0.3.0 diff --git a/paket.lock b/paket.lock index 6611c7b82..0493628f3 100644 --- a/paket.lock +++ b/paket.lock @@ -10,9 +10,17 @@ NUGET System.Data.SqlClient (>= 4.4) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0) System.Reflection.Emit.Lightweight (>= 4.3) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0) System.Reflection.TypeExtensions (>= 4.4) - restriction: || (&& (== net461) (< net451)) (== netcoreapp2.1) (== netstandard2.0) - Dotnet.ProjInfo (0.31) - FSharp.Core (>= 4.3.4) + Dotnet.ProjInfo (0.35) + FSharp.Core (>= 4.6.2) System.ValueTuple (>= 4.4) + Dotnet.ProjInfo.Workspace (0.35) + Dotnet.ProjInfo (>= 0.35) + FSharp.Core (>= 4.6.2) + Sln (>= 0.3) + Dotnet.ProjInfo.Workspace.FCS (0.35) + Dotnet.ProjInfo.Workspace (>= 0.35) + FSharp.Compiler.Service (>= 29.0) + FSharp.Core (>= 4.6.2) FParsec (1.0.3) FSharp.Core (>= 4.0.0.1) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net40)) (&& (== netstandard2.0) (>= net40)) FSharp.Core (>= 4.2.3) - restriction: || (&& (== net461) (< net40) (>= netstandard1.6)) (== netcoreapp2.1) (== netstandard2.0) @@ -31,10 +39,6 @@ NUGET System.Runtime.Loader (>= 4.0) - restriction: || (== netcoreapp2.1) (== netstandard2.0) System.Security.Cryptography.Algorithms (>= 4.3) - restriction: || (== netcoreapp2.1) (== netstandard2.0) System.ValueTuple (>= 4.4) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461)) - FSharp.Compiler.Service.ProjectCracker (29.0) - condition: net461, restriction: == net461 - FSharp.Compiler.Service (>= 29.0) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461)) - FSharp.Core (>= 4.6.2) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461)) - System.ValueTuple (>= 4.4) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net461)) (&& (== netstandard2.0) (>= net461)) FSharp.Core (4.6.2) - redirects: force FSharp.Data (3.0.1) FSharp.Core (>= 4.0.0.1) - restriction: || (== net461) (&& (== netcoreapp2.1) (>= net45)) (&& (== netstandard2.0) (>= net45)) diff --git a/src/FsAutoComplete.Core/Commands.fs b/src/FsAutoComplete.Core/Commands.fs index 839149d20..106693bcd 100644 --- a/src/FsAutoComplete.Core/Commands.fs +++ b/src/FsAutoComplete.Core/Commands.fs @@ -19,7 +19,7 @@ type CoreResponse = | ErrorRes of text: string | HelpText of name: string * tip: FSharpToolTipText * additionalEdit: (string * int * int * string) option | HelpTextSimple of name: string * tip: string - | Project of projectFileName: ProjectFilePath * projectFiles: List * outFileOpt : string option * references : ProjectFilePath list * logMap : Map * extra: ExtraProjectInfoData * additionals : Map + | Project of projectFileName: ProjectFilePath * projectFiles: List * outFileOpt : string option * references : ProjectFilePath list * logMap : Map * extra: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData * additionals : Map | ProjectError of errorDetails: GetProjectOptionsErrors | ProjectLoading of projectFileName: ProjectFilePath | WorkspacePeek of found: WorkspacePeek.Interesting list @@ -245,6 +245,11 @@ type Commands (serialize : Serializer) = |> parseFilesInTheBackground |> Async.Start + let workspaceBinder () = + let config = Dotnet.ProjInfo.Workspace.LoaderConfig.Default Environment.msbuildLocator + let loader = Dotnet.ProjInfo.Workspace.Loader.Create(config) + loader, checker.CreateFCSBinder(NETFrameworkInfoProvider.netFWInfo, loader) + member __.Notify = notify.Publish member __.WorkspaceReady = workspaceReady.Publish @@ -415,15 +420,8 @@ type Commands (serialize : Serializer) = return [CoreResponse.Errors ([||], "") ] } - member private __.ToProjectCache (opts, extraInfo, projectFiles, logMap) = - let outFileOpt = - match extraInfo.ProjectSdkType with - | ProjectSdkType.Verbose v -> - Some (v.TargetPath) - | ProjectSdkType.ProjectJson -> - FscArguments.outputFile (Path.GetDirectoryName(opts.ProjectFileName)) (opts.OtherOptions |> List.ofArray) - | ProjectSdkType.DotnetSdk v -> - Some (v.TargetPath) + member private __.ToProjectCache (opts, extraInfo: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData, projectFiles, logMap) = + let outFileOpt = Some (extraInfo.TargetPath) let references = FscArguments.references (opts.OtherOptions |> List.ofArray) let projectFiles = projectFiles |> List.map (Path.GetFullPath >> Utils.normalizePath) @@ -438,7 +436,7 @@ type Commands (serialize : Serializer) = (opts.ProjectFileName, cached) - member x.Project projectFileName verbose onChange = async { + member x.Project projectFileName _verbose onChange = async { let projectFileName = Path.GetFullPath projectFileName let project = match state.Projects.TryFind projectFileName with @@ -447,12 +445,19 @@ type Commands (serialize : Serializer) = let proj = new Project(projectFileName, onChange) state.Projects.[projectFileName] <- proj proj + + let workspaceBinder = workspaceBinder () + let projResponse = match project.Response with | Some response -> Result.Ok (projectFileName, response) | None -> - match projectFileName |> Workspace.parseProject verbose |> Result.map (x.ToProjectCache) with + let projectCached = + projectFileName + |> Workspace.parseProject workspaceBinder + |> Result.map (fun (opts, optsDPW, projectFiles, logMap) -> x.ToProjectCache(opts, optsDPW.ExtraProjectInfo, projectFiles, logMap) ) + match projectCached with | Result.Ok (projectFileName, response) -> project.Response <- Some response Result.Ok (projectFileName, response) @@ -961,7 +966,7 @@ type Commands (serialize : Serializer) = onProjectLoaded projectFileName response - let rec onLoaded p = + let onLoaded p = match p with | WorkspaceProjectState.Loading projectFileName -> CoreResponse.ProjectLoading projectFileName @@ -990,7 +995,45 @@ type Commands (serialize : Serializer) = do! Async.Sleep(Environment.workspaceLoadDelay().TotalMilliseconds |> int) | _ -> () - do! Workspace.loadInBackground onLoaded false (projects |> List.map snd) + let loader, fcsBinder = workspaceBinder () + + let projViewer = Dotnet.ProjInfo.Workspace.ProjectViewer () + + let bindNewOnloaded (n: Dotnet.ProjInfo.Workspace.WorkspaceProjectState) : WorkspaceProjectState option = + match n with + | Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Loading (path, _) -> + Some (WorkspaceProjectState.Loading path) + | Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Loaded (opts, logMap) -> + match fcsBinder.GetProjectOptions(opts.ProjectFileName) with + | Some fcsOpts -> + match Workspace.extractOptionsDPW fcsOpts with + | Ok optsDPW -> + let view = projViewer.Render optsDPW + let projectFiles = + view.Items + |> List.map (fun item -> + match item with + | Dotnet.ProjInfo.Workspace.ProjectViewerItem.Compile path -> path) + + Some (WorkspaceProjectState.Loaded (fcsOpts, optsDPW.ExtraProjectInfo, projectFiles, logMap)) + | Error _ -> + None //TODO not ignore the error + | None -> + //TODO notify C# project too + None + | Dotnet.ProjInfo.Workspace.WorkspaceProjectState.Failed (path, e) -> + let error = + match e with + | Dotnet.ProjInfo.Workspace.GetProjectOptionsErrors.ProjectNotRestored s -> + GetProjectOptionsErrors.ProjectNotRestored s + | Dotnet.ProjInfo.Workspace.GetProjectOptionsErrors.GenericError (a, b) -> + GetProjectOptionsErrors.GenericError (a,b) + Some (WorkspaceProjectState.Failed (path, error)) + + loader.Notifications.Add(fun (_, arg) -> + arg |> bindNewOnloaded |> Option.iter onLoaded ) + + do! Workspace.loadInBackground onLoaded (loader, fcsBinder) (projects |> List.map snd) CoreResponse.WorkspaceLoad true |> NotificationEvent.Workspace diff --git a/src/FsAutoComplete.Core/CompilerServiceInterface.fs b/src/FsAutoComplete.Core/CompilerServiceInterface.fs index b953d5a33..ce7c11813 100644 --- a/src/FsAutoComplete.Core/CompilerServiceInterface.fs +++ b/src/FsAutoComplete.Core/CompilerServiceInterface.fs @@ -403,45 +403,6 @@ type ParseAndCheckResults type Version = int -module FSharpCompilerServiceCheckerHelper = - - let isFSharpCore (s : string) = s.EndsWith "FSharp.Core.dll" - - let ensureCorrectFSharpCore (options: string[]) = - let fsharpCores, others = Array.partition isFSharpCore options - - // ensure that there is only one fsharpcore ref provided - let fsharpCoreRef = - match fsharpCores with - | [||] -> sprintf "-r:%s" Environment.fsharpCore - | [| ref |] -> ref - | refs -> Array.head refs - - [| yield fsharpCoreRef - yield! others |] - -#if SCRIPT_REFS_FROM_MSBUILD -#else - let ensureCorrectVersions (options: string[]) = - if Utils.runningOnMono then options - else - match Environment.referenceAssembliesPath (), NETFrameworkInfoProvider.netReferencesAssembliesTFMLatest () with - | _, None -> options - | Some referenceAssembliesPath, Some version -> - let oldRef = referenceAssembliesPath "v4.0" - let newRef = referenceAssembliesPath version - - let fsharpCoreRef = options |> Seq.find isFSharpCore - - let newOptions = - options - |> Seq.filter (not << isFSharpCore) - |> Seq.map (fun (s : string) -> s.Replace(oldRef, newRef) ) - [| yield fsharpCoreRef - yield! newOptions |] - | None, _ -> options -#endif - type FSharpCompilerServiceChecker() = let checker = FSharpChecker.Create( @@ -468,11 +429,15 @@ type FSharpCompilerServiceChecker() = let clearProjectReferecnes (opts: FSharpProjectOptions) = if disableInMemoryProjectReferences then {opts with ReferencedProjects = [||]} else opts - let logDebug fmt = + let fsxBinder = Dotnet.ProjInfo.Workspace.FCS.FsxBinder(NETFrameworkInfoProvider.netFWInfo, checker) + let logDebug fmt = if Debug.verbose then Debug.print "[FSharpChecker] Current Queue Length: %d" checker.CurrentQueueLength Debug.print fmt + member __.CreateFCSBinder(netFwInfo: Dotnet.ProjInfo.Workspace.NetFWInfo, loader: Dotnet.ProjInfo.Workspace.Loader) = + Dotnet.ProjInfo.Workspace.FCS.FCSBinder(netFwInfo, loader, checker) + member __.DisableInMemoryProjectReferences with get() = disableInMemoryProjectReferences and set(value) = disableInMemoryProjectReferences <- value @@ -488,37 +453,11 @@ type FSharpCompilerServiceChecker() = ]) member __.GetProjectOptionsFromScript(file, source) = async { - let source = SourceText.ofString source -#if SCRIPT_REFS_FROM_MSBUILD - - let targetFramework = NETFrameworkInfoProvider.netReferencesAssembliesTFMLatest () - - let additionaRefs = - NETFrameworkInfoProvider.additionalArgumentsBy targetFramework - |> Array.ofList - - let! (rawOptions, _) = checker.GetProjectOptionsFromScript(file, source, otherFlags = additionaRefs, assumeDotNetFramework = true) - - let opts = - rawOptions.OtherOptions - |> FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore - - let opts = - opts - |> Array.distinct - - return { rawOptions with OtherOptions = opts } -#else - let! (rawOptions, _) = checker.GetProjectOptionsFromScript(file, source) - - let opts = - rawOptions.OtherOptions - |> FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore - |> FSharpCompilerServiceCheckerHelper.ensureCorrectVersions + let targetFramework = NETFrameworkInfoProvider.latestInstalledNETVersion () - return { rawOptions with OtherOptions = opts } -#endif + let! projOptions = fsxBinder.GetProjectOptionsFromScriptBy(targetFramework, file, source) + return projOptions } diff --git a/src/FsAutoComplete.Core/Environment.fs b/src/FsAutoComplete.Core/Environment.fs index a91e2234b..3e9831008 100644 --- a/src/FsAutoComplete.Core/Environment.fs +++ b/src/FsAutoComplete.Core/Environment.fs @@ -6,8 +6,22 @@ open Utils #if NETSTANDARD2_0 open System.Runtime.InteropServices #endif +open Dotnet.ProjInfo.Workspace module Environment = + + let msbuildLocator = MSBuildLocator() + + let msbuild = + let msbuildPath = msbuildLocator.LatestInstalledMSBuild() + + match msbuildPath with + | Dotnet.ProjInfo.Inspect.MSBuildExePath.Path path -> + Some path + | Dotnet.ProjInfo.Inspect.MSBuildExePath.DotnetMsbuild p -> + // failwithf "expected msbuild, not 'dotnet %s'" p + None + let private environVar v = Environment.GetEnvironmentVariable v let private programFilesX86 = @@ -22,40 +36,9 @@ module Environment = // Below code slightly modified from FAKE MSBuildHelper.fs - let private tryFindFile dirs file = - let files = - dirs - |> Seq.map (fun (path : string) -> - try - let path = - if path.StartsWith("\"") && path.EndsWith("\"") - then path.Substring(1, path.Length - 2) - else path - let dir = new DirectoryInfo(path) - if not dir.Exists then "" - else - let fi = new FileInfo(dir.FullName file) - if fi.Exists then fi.FullName - else "" - with - | _ -> "") - |> Seq.filter ((<>) "") - |> Seq.cache - if not (Seq.isEmpty files) then Some(Seq.head files) - else None - - let private tryFindPath backupPaths tool = - let paths = Environment.GetEnvironmentVariable "PATH" |> String.split Path.PathSeparator - tryFindFile (paths @ backupPaths) tool - - let private findPath backupPaths tool = - match tryFindPath backupPaths tool with - | Some file -> file - | None -> tool - let private vsSkus = ["Community"; "Professional"; "Enterprise"; "BuildTools"] let private vsVersions = ["2017"; "2019"] - let cartesian a b = + let private cartesian a b = [ for a' in a do for b' in b do yield a', b' ] @@ -64,25 +47,6 @@ module Environment = cartesian vsVersions vsSkus |> List.map (fun (version, sku) -> programFilesX86 "Microsoft Visual Studio" version sku) - let msbuild = - if Utils.runningOnMono || not Utils.isWindows then Some "msbuild" // we're way past 5.0 now, time to get updated - else - let legacyPaths = - [ programFilesX86 @"\MSBuild\14.0\Bin" - programFilesX86 @"\MSBuild\12.0\Bin" - programFilesX86 @"\MSBuild\12.0\Bin\amd64" - @"c:\Windows\Microsoft.NET\Framework\v4.0.30319" - @"c:\Windows\Microsoft.NET\Framework\v4.0.30128" - @"c:\Windows\Microsoft.NET\Framework\v3.5" ] - - let sideBySidePaths = - vsRoots - |> List.map (fun root -> root "MSBuild" "15.0" "bin" ) - - let ev = Environment.GetEnvironmentVariable "MSBuild" - if not (String.IsNullOrEmpty ev) then Some ev - else tryFindPath (sideBySidePaths @ legacyPaths) "MsBuild.exe" - /// these are the single-instance installation paths on windows from FSharp versions < 4.5 let private legacyFSharpInstallationPaths = ["10.1"; "4.1"; "4.0"; "3.1"; "3.0"] @@ -99,13 +63,13 @@ module Environment = let fsi = // on netcore on non-windows we just deflect to fsharpi as usual - if Utils.runningOnMono || not Utils.isWindows then Some "fsharpi" + if Utils.runningOnMono || not FsAutoComplete.Utils.isWindows then Some "fsharpi" else // if running on windows, non-mono we can't yet send paths to the netcore version of fsi.exe so use the one from full-framework fsharpInstallationPath |> Option.map (fun root -> root "fsi.exe") let fsc = - if Utils.runningOnMono || not Utils.isWindows then Some "fsharpc" + if Utils.runningOnMono || not FsAutoComplete.Utils.isWindows then Some "fsharpc" else // if running on windows, non-mono we can't yet send paths to the netcore version of fsc.exe so use the one from full-framework fsharpInstallationPath |> Option.map (fun root -> root "fsc.exe") @@ -114,23 +78,6 @@ module Environment = let dir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) dir "FSharp.Core.dll" -#if SCRIPT_REFS_FROM_MSBUILD -#else - let referenceAssembliesPath () = - Some (programFilesX86 @"Reference Assemblies\Microsoft\Framework\.NETFramework") - - let dotNetVersions () = - match referenceAssembliesPath () |> Option.filter Directory.Exists with - | Some path -> - Directory.EnumerateDirectories path - |> Seq.filter (fun s -> not(s.EndsWith(".X"))) //may contain only xml files, not assemblies - |> Seq.sort - |> Seq.toArray - |> Array.rev - | None -> - Array.empty -#endif - let workspaceLoadDelay () = match System.Environment.GetEnvironmentVariable("FSAC_WORKSPACELOAD_DELAY") with | delayMs when not (String.IsNullOrWhiteSpace(delayMs)) -> diff --git a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj index 1350190bd..696933948 100644 --- a/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj +++ b/src/FsAutoComplete.Core/FsAutoComplete.Core.fsproj @@ -11,7 +11,7 @@ - NO_EXTENSIONTYPING;NO_PROJECTCRACKER;SCRIPT_REFS_FROM_MSBUILD;SUAVE_2;$(DefineConstants);DOTNET_SPAWN + NO_EXTENSIONTYPING;$(DefineConstants);DOTNET_SPAWN @@ -30,9 +30,6 @@ - - - diff --git a/src/FsAutoComplete.Core/FscArguments.fs b/src/FsAutoComplete.Core/FscArguments.fs index 3fcc80afb..1e8f2fdb8 100644 --- a/src/FsAutoComplete.Core/FscArguments.fs +++ b/src/FsAutoComplete.Core/FscArguments.fs @@ -7,44 +7,13 @@ open System.IO module FscArguments = - let outType rsp = - match List.tryPick (chooseByPrefix "--target:") rsp with - | Some "library" -> ProjectOutputType.Library - | Some "exe" -> ProjectOutputType.Exe - | Some v -> ProjectOutputType.Custom v - | None -> ProjectOutputType.Exe // default if arg is not passed to fsc - - let private outputFileArg = ["--out:"; "-o:"] - - let private makeAbs projDir (f: string) = - if Path.IsPathRooted f then f else Path.Combine(projDir, f) - - let outputFile projDir rsp = - rsp - |> List.tryPick (chooseByPrefix2 outputFileArg) - |> Option.map (makeAbs projDir) - let isCompileFile (s:string) = s.EndsWith(".fs") || s.EndsWith (".fsi") - let compileFiles = - //TODO filter the one without initial - - List.filter isCompileFile - let references = //TODO valid also --reference: List.choose (chooseByPrefix "-r:") - let useFullPaths projDir (s: string) = - match s |> splitByPrefix2 outputFileArg with - | Some (prefix, v) -> - prefix + (v |> makeAbs projDir) - | None -> - if isCompileFile s then - s |> makeAbs projDir |> Path.GetFullPath - else - s - (* Microsoft (R) F# Compiler version 4.1 diff --git a/src/FsAutoComplete.Core/NETFrameworkInfoProvider.fs b/src/FsAutoComplete.Core/NETFrameworkInfoProvider.fs index 4a52d1a81..8b5cd89d4 100644 --- a/src/FsAutoComplete.Core/NETFrameworkInfoProvider.fs +++ b/src/FsAutoComplete.Core/NETFrameworkInfoProvider.fs @@ -1,163 +1,19 @@ namespace FsAutoComplete -module DotnetProjInfoInspectHelpers = - - let msbuildPropBool (s: string) = - match s.Trim() with - | "" -> None - | Dotnet.ProjInfo.Inspect.MSBuild.ConditionEquals "True" -> Some true - | _ -> Some false - - let msbuildPropStringList (s: string) = - match s.Trim() with - | "" -> [] - | Dotnet.ProjInfo.Inspect.MSBuild.StringList list -> list - | _ -> [] - module NETFrameworkInfoProvider = open System open System.IO - open DotnetProjInfoInspectHelpers - - let private getInfoFromMsbuild getArgs additionalProps = - let file = Dotnet.ProjInfo.NETFrameworkInfoFromMSBuild.createEnvInfoProj () - - let result, log = - let loggedMessages = System.Collections.Concurrent.ConcurrentQueue() - - let msbuildExec = - let runCmd exePath args = - Utils.runProcess loggedMessages.Enqueue (Path.GetDirectoryName file) exePath (args |> String.concat " ") - - let msbuildPath = - let path = - match Environment.msbuild with - | Some msbuildPath -> msbuildPath - | None -> "msbuild" - Dotnet.ProjInfo.Inspect.MSBuildExePath.Path path - - - Dotnet.ProjInfo.Inspect.msbuild msbuildPath runCmd - - let infoResult = - let additionalArgs = additionalProps |> List.map Dotnet.ProjInfo.Inspect.MSBuild.Property - - file - |> Dotnet.ProjInfo.Inspect.getProjectInfo loggedMessages.Enqueue msbuildExec getArgs additionalArgs - - infoResult, (loggedMessages.ToArray() |> Array.toList) - - match result with - | Ok (r) -> - r, log - | Error x -> - match x with - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.MSBuildSkippedTarget -> - failwithf "Unexpected MSBuild result, all targets skipped" - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.UnexpectedMSBuildResult(r) -> - failwithf "Unexpected MSBuild result %s" r - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.MSBuildFailed(exitCode, (workDir, exePath, args)) -> - let logMsg = [ yield "Log: "; yield! log ] |> String.concat (Environment.NewLine) - let msbuildErrorMsg = - [ sprintf "MSBuild failed with exitCode %i" exitCode - sprintf "Working Directory: '%s'" workDir - sprintf "Exe Path: '%s'" exePath - sprintf "Args: '%s'" args ] - |> String.concat " " - - failwithf "%s%s%s" msbuildErrorMsg (Environment.NewLine) logMsg - - let private getInstalledNETVersions () = - let result, _ = getInfoFromMsbuild (Dotnet.ProjInfo.NETFrameworkInfoFromMSBuild.installedNETFrameworks) [] - match result with - | Dotnet.ProjInfo.Inspect.GetResult.InstalledNETFw fws -> - fws - | r -> - failwithf "error getting msbuild info: unexpected %A" r - - let private installedNETVersionsLazy = lazy (getInstalledNETVersions ()) - - let installedNETVersions () = installedNETVersionsLazy.Force() - - let private defaultReferencesForNonProjectFiles () = - // ref https://github.com/fsharp/FSharp.Compiler.Service/blob/1f497ef86fd5d0a18e5a935f3d16984fda91f1de/src/fsharp/CompileOps.fs#L1801 - // This list is the default set of references for "non-project" files - - // TODO make somehow this list public on FCS and use that directly instead of hardcode it in FSAC - - let GetDefaultSystemValueTupleReference () = - //TODO check by tfm - None - - // from https://github.com/fsharp/FSharp.Compiler.Service/blob/1f497ef86fd5d0a18e5a935f3d16984fda91f1de/src/fsharp/CompileOps.fs#L1803-L1832 - [ - yield "System" - yield "System.Xml" - yield "System.Runtime.Remoting" - yield "System.Runtime.Serialization.Formatters.Soap" - yield "System.Data" - yield "System.Drawing" - yield "System.Core" - // These are the Portable-profile and .NET Standard 1.6 dependencies of FSharp.Core.dll. These are needed - // when an F# sript references an F# profile 7, 78, 259 or .NET Standard 1.6 component which in turn refers - // to FSharp.Core for profile 7, 78, 259 or .NET Standard. - yield "System.Runtime" // lots of types - yield "System.Linq" // System.Linq.Expressions.Expression - yield "System.Reflection" // System.Reflection.ParameterInfo - yield "System.Linq.Expressions" // System.Linq.IQueryable - yield "System.Threading.Tasks" // valuetype [System.Threading.Tasks]System.Threading.CancellationToken - yield "System.IO" // System.IO.TextWriter - //yield "System.Console" // System.Console.Out etc. - yield "System.Net.Requests" // System.Net.WebResponse etc. - yield "System.Collections" // System.Collections.Generic.List - yield "System.Runtime.Numerics" // BigInteger - yield "System.Threading" // OperationCanceledException - // always include a default reference to System.ValueTuple.dll in scripts and out-of-project sources - match GetDefaultSystemValueTupleReference() with - | None -> () - | Some v -> yield v - - yield "System.Web" - yield "System.Web.Services" - yield "System.Windows.Forms" - yield "System.Numerics" - ] - - let private getAdditionalArgumentsBy targetFramework = - let refs = - let allRefs = defaultReferencesForNonProjectFiles () - let props = targetFramework |> Option.map (fun tfm -> "TargetFrameworkVersion", tfm) |> Option.toList - let result, _ = getInfoFromMsbuild (fun () -> Dotnet.ProjInfo.NETFrameworkInfoFromMSBuild.getReferencePaths allRefs) props - match result with - | Dotnet.ProjInfo.Inspect.GetResult.ResolvedNETRefs resolvedRefs -> - resolvedRefs - | r -> - failwithf "error getting msbuild info: unexpected %A" r - [ yield "--simpleresolution" - yield "--noframework" - yield! refs |> List.map (sprintf "-r:%s") ] - - let private additionalArgsByTfm = System.Collections.Concurrent.ConcurrentDictionary() + open Dotnet.ProjInfo.Workspace - let additionalArgumentsBy targetFramework = - //memoize because expensive - let f tfm = getAdditionalArgumentsBy (if String.IsNullOrEmpty(tfm) then None else Some tfm) - let key = targetFramework |> Option.getOrElse "" - additionalArgsByTfm.GetOrAdd(key, f) + let netFWInfo = + let config = NetFWInfoConfig.Default Environment.msbuildLocator + let netFwInfo = NetFWInfo.Create(config) + netFwInfo - let netReferencesAssembliesTFM () = -#if SCRIPT_REFS_FROM_MSBUILD - installedNETVersions () - |> Array.ofList -#else - Environment.dotNetVersions () - |> Array.map Path.GetFileName -#endif + let installedNETVersions () = + netFWInfo.InstalledNetFws() - let netReferencesAssembliesTFMLatest () = - netReferencesAssembliesTFM () - |> Array.sortWith (fun x y -> StringComparer.OrdinalIgnoreCase.Compare(x, y)) - |> Array.rev - |> Array.tryHead + let latestInstalledNETVersion () = + netFWInfo.LatestVersion() diff --git a/src/FsAutoComplete.Core/Project.fs b/src/FsAutoComplete.Core/Project.fs index 959a26c21..8f2952e8d 100644 --- a/src/FsAutoComplete.Core/Project.fs +++ b/src/FsAutoComplete.Core/Project.fs @@ -11,7 +11,7 @@ type ProjectCrackerCache = { OutFile : string option References : string list Log : Map - ExtraInfo: ExtraProjectInfoData + ExtraInfo: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData } type private ProjectPersistentCacheMessage = diff --git a/src/FsAutoComplete.Core/ProjectCrackerDotnetSdk.fs b/src/FsAutoComplete.Core/ProjectCrackerDotnetSdk.fs deleted file mode 100644 index eb5de2ec5..000000000 --- a/src/FsAutoComplete.Core/ProjectCrackerDotnetSdk.fs +++ /dev/null @@ -1,293 +0,0 @@ -namespace FsAutoComplete - -open System -open System.IO - -open FSharp.Compiler.SourceCodeServices - -module MSBuildPrj = Dotnet.ProjInfo.Inspect - -exception ProjectInspectException of GetProjectOptionsErrors - -type NavigateProjectSM = - | NoCrossTargeting of NoCrossTargetingData - | CrossTargeting of string list -and NoCrossTargetingData = { FscArgs: string list; P2PRefs: MSBuildPrj.ResolvedP2PRefsInfo list; Properties: Map } - -module MSBuildKnownProperties = - let TargetFramework = "TargetFramework" - -module ProjectCrackerDotnetSdk = - - open DotnetProjInfoInspectHelpers - - let msbuildPropProjectOutputType (s: string) = - match s.Trim() with - | MSBuildPrj.MSBuild.ConditionEquals "Exe" -> ProjectOutputType.Exe - | MSBuildPrj.MSBuild.ConditionEquals "Library" -> ProjectOutputType.Library - | x -> ProjectOutputType.Custom x - - let getExtraInfo targetPath props = - let msbuildPropBool prop = - props |> Map.tryFind prop |> Option.bind msbuildPropBool - let msbuildPropStringList prop = - props |> Map.tryFind prop |> Option.map msbuildPropStringList - let msbuildPropString prop = - props |> Map.tryFind prop - - { ProjectSdkTypeDotnetSdk.IsTestProject = msbuildPropBool "IsTestProject" |> Option.getOrElse false - Configuration = msbuildPropString "Configuration" |> Option.getOrElse "" - IsPackable = msbuildPropBool "IsPackable" |> Option.getOrElse false - TargetFramework = msbuildPropString MSBuildKnownProperties.TargetFramework |> Option.getOrElse "" - TargetFrameworkIdentifier = msbuildPropString "TargetFrameworkIdentifier" |> Option.getOrElse "" - TargetFrameworkVersion = msbuildPropString "TargetFrameworkVersion" |> Option.getOrElse "" - TargetPath = targetPath - - MSBuildAllProjects = msbuildPropStringList "MSBuildAllProjects" |> Option.getOrElse [] - MSBuildToolsVersion = msbuildPropString "MSBuildToolsVersion" |> Option.getOrElse "" - - ProjectAssetsFile = msbuildPropString "ProjectAssetsFile" |> Option.getOrElse "" - RestoreSuccess = msbuildPropBool "RestoreSuccess" |> Option.getOrElse false - - Configurations = msbuildPropStringList "Configurations" |> Option.getOrElse [] - TargetFrameworks = msbuildPropStringList "TargetFrameworks" |> Option.getOrElse [] - - RunArguments = msbuildPropString "RunArguments" - RunCommand = msbuildPropString "RunCommand" - - IsPublishable = msbuildPropBool "IsPublishable" } - - type private ProjectParsingSdk = DotnetSdk | VerboseSdk - - type ParsedProject = string * FSharpProjectOptions * ((string * string) list) - type ParsedProjectCache = Collections.Concurrent.ConcurrentDictionary - - let private getProjectOptionsFromProjectFile notifyState (cache: ParsedProjectCache) parseAsSdk (file : string) = - - let rec projInfoOf additionalMSBuildProps (file: string) : ParsedProject = - let projDir = Path.GetDirectoryName file - - notifyState (WorkspaceProjectState.Loading file) - - match parseAsSdk with - | ProjectParsingSdk.DotnetSdk -> - let projectAssetsJsonPath = Path.Combine(projDir, "obj", "project.assets.json") - if not(File.Exists(projectAssetsJsonPath)) then - raise (ProjectInspectException (ProjectNotRestored file)) - | ProjectParsingSdk.VerboseSdk -> - () - - let getFscArgs = - match parseAsSdk with - | ProjectParsingSdk.DotnetSdk -> - Dotnet.ProjInfo.Inspect.getFscArgs - | ProjectParsingSdk.VerboseSdk -> - let asFscArgs props = - let fsc = Microsoft.FSharp.Build.Fsc() - Dotnet.ProjInfo.FakeMsbuildTasks.getResponseFileFromTask props fsc - Dotnet.ProjInfo.Inspect.getFscArgsOldSdk (asFscArgs >> Ok) - - let getP2PRefs = Dotnet.ProjInfo.Inspect.getResolvedP2PRefs - let additionalInfo = //needed for extra - [ "OutputType" - "IsTestProject" - "Configuration" - "IsPackable" - MSBuildKnownProperties.TargetFramework - "TargetFrameworkIdentifier" - "TargetFrameworkVersion" - "MSBuildAllProjects" - "ProjectAssetsFile" - "RestoreSuccess" - "Configurations" - "TargetFrameworks" - "RunArguments" - "RunCommand" - "IsPublishable" - ] - let gp () = Dotnet.ProjInfo.Inspect.getProperties (["TargetPath"; "IsCrossTargetingBuild"; "TargetFrameworks"] @ additionalInfo) - - let results, log = - let loggedMessages = System.Collections.Concurrent.ConcurrentQueue() - - let runCmd exePath args = Utils.runProcess loggedMessages.Enqueue projDir exePath (args |> String.concat " ") - - let msbuildExec = - let msbuildPath = - match parseAsSdk with - | ProjectParsingSdk.DotnetSdk -> - Dotnet.ProjInfo.Inspect.MSBuildExePath.DotnetMsbuild "dotnet" - | ProjectParsingSdk.VerboseSdk -> - Dotnet.ProjInfo.Inspect.MSBuildExePath.Path "msbuild" - Dotnet.ProjInfo.Inspect.msbuild msbuildPath runCmd - - let additionalArgs = additionalMSBuildProps |> List.map (Dotnet.ProjInfo.Inspect.MSBuild.MSbuildCli.Property) - - let inspect = - match parseAsSdk with - | ProjectParsingSdk.DotnetSdk -> - Dotnet.ProjInfo.Inspect.getProjectInfos - | ProjectParsingSdk.VerboseSdk -> - Dotnet.ProjInfo.Inspect.getProjectInfos - - let infoResult = - file - |> inspect loggedMessages.Enqueue msbuildExec [getFscArgs; getP2PRefs; gp] additionalArgs - - infoResult, (loggedMessages.ToArray() |> Array.toList) - - let todo = - match results with - | Ok [getFscArgsResult; getP2PRefsResult; gpResult] -> - match getFscArgsResult, getP2PRefsResult, gpResult with - | Error(MSBuildPrj.MSBuildSkippedTarget), Error(MSBuildPrj.MSBuildSkippedTarget), Ok (MSBuildPrj.GetResult.Properties props) -> - // Projects with multiple target frameworks, fails if the target framework is not choosen - let prop key = props |> Map.ofList |> Map.tryFind key - - match prop "IsCrossTargetingBuild", prop "TargetFrameworks" with - | Some (MSBuildPrj.MSBuild.ConditionEquals "true"), Some (MSBuildPrj.MSBuild.StringList tfms) -> - CrossTargeting tfms - | _ -> - failwithf "error getting msbuild info: some targets skipped, found props: %A" props - | Ok (MSBuildPrj.GetResult.FscArgs fa), Ok (MSBuildPrj.GetResult.ResolvedP2PRefs p2p), Ok (MSBuildPrj.GetResult.Properties p) -> - NoCrossTargeting { FscArgs = fa; P2PRefs = p2p; Properties = p |> Map.ofList } - | r -> - failwithf "error getting msbuild info: %A" r - | Ok r -> - failwithf "error getting msbuild info: internal error, more info returned than expected %A" r - | Error r -> - match r with - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.MSBuildSkippedTarget -> - failwithf "Unexpected MSBuild result, all targets skipped" - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.UnexpectedMSBuildResult(r) -> - failwithf "Unexpected MSBuild result %s" r - | Dotnet.ProjInfo.Inspect.GetProjectInfoErrors.MSBuildFailed(exitCode, (workDir, exePath, args)) -> - let logMsg = [ yield "Log: "; yield! log ] |> String.concat (Environment.NewLine) - let msbuildErrorMsg = - [ sprintf "MSBuild failed with exitCode %i" exitCode - sprintf "Working Directory: '%s'" workDir - sprintf "Exe Path: '%s'" exePath - sprintf "Args: '%s'" args ] - |> String.concat " " - - failwithf "%s%s%s" msbuildErrorMsg (Environment.NewLine) logMsg - - match todo with - | CrossTargeting (tfm :: _) -> - // Atm setting a preferenece is not supported in FSAC - // As workaround, lets choose the first of the target frameworks and use that - file |> projInfo [MSBuildKnownProperties.TargetFramework, tfm] - | CrossTargeting [] -> - failwithf "Unexpected, found cross targeting but empty target frameworks list" - | NoCrossTargeting { FscArgs = rsp; P2PRefs = p2ps; Properties = props } -> - - //TODO cache projects info of p2p ref - let p2pProjects = - p2ps - // do not follow others lang project, is not supported by FCS anyway - |> List.filter (fun p2p -> p2p.ProjectReferenceFullPath.ToLower().EndsWith(".fsproj")) - |> List.map (fun p2p -> - let followP2pArgs = - p2p.TargetFramework - |> Option.map (fun tfm -> MSBuildKnownProperties.TargetFramework, tfm) - |> Option.toList - p2p.ProjectReferenceFullPath |> projInfo followP2pArgs ) - - let tar = - match props |> Map.tryFind "TargetPath" with - | Some t -> t - | None -> failwith "error, 'TargetPath' property not found" - - let rspNormalized = - //workaround, arguments in rsp can use relative paths - rsp |> List.map (FscArguments.useFullPaths projDir) - - let sdkTypeData, log = - match parseAsSdk with - | ProjectParsingSdk.DotnetSdk -> - let extraInfo = getExtraInfo tar props - ProjectSdkType.DotnetSdk(extraInfo), [] - | ProjectParsingSdk.VerboseSdk -> - //compatibility with old behaviour, so output is exactly the same - let mergedLog = - [ yield (file, "") - yield! p2pProjects |> List.collect (fun (_,_,x) -> x) ] - ProjectSdkType.Verbose { TargetPath = tar }, mergedLog - - let po = - { - ProjectId = Some file - ProjectFileName = file - SourceFiles = [||] - OtherOptions = rspNormalized |> Array.ofList - ReferencedProjects = p2pProjects |> List.map (fun (x,y,_) -> (x,y)) |> Array.ofList - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime.Now - UnresolvedReferences = None - OriginalLoadReferences = [] - Stamp = None - ExtraProjectInfo = - Some (box { - ExtraProjectInfoData.ProjectSdkType = sdkTypeData - ExtraProjectInfoData.ProjectOutputType = FscArguments.outType rspNormalized - }) - } - - tar, po, log - - and projInfo additionalMSBuildProps file : ParsedProject = - let key = sprintf "%s;%A" file additionalMSBuildProps - match cache.TryGetValue(key) with - | true, alreadyParsed -> - alreadyParsed - | false, _ -> - let p = file |> projInfoOf additionalMSBuildProps - cache.AddOrUpdate(key, p, fun _ _ -> p) - - - let _, po, log = projInfo [] file - po, log - - let private (|ProjectExtraInfoBySdk|_|) po = - match po.ExtraProjectInfo with - | None -> None - | Some x -> - match x with - | :? ExtraProjectInfoData as extraInfo -> - Some extraInfo - | _ -> None - - let private loadBySdk notifyState (cache: ParsedProjectCache) parseAsSdk file = - try - let po, log = getProjectOptionsFromProjectFile notifyState cache parseAsSdk file - - let compileFiles = - let sources = FscArguments.compileFiles (po.OtherOptions |> List.ofArray) - match po with - | ProjectExtraInfoBySdk extraInfo -> - match extraInfo.ProjectSdkType with - | ProjectSdkType.Verbose _ -> - //compatibility with old behaviour (projectcracker), so test output is exactly the same - //the temp source files (like generated assemblyinfo.fs) are not added to sources - let isTempFile (name: string) = - let tempPath = Path.GetTempPath() - let s = name.ToLower() - s.StartsWith(tempPath.ToLower()) - sources - |> List.filter (not << isTempFile) - | ProjectSdkType.ProjectJson - | ProjectSdkType.DotnetSdk _ -> - sources - | _ -> sources - - Ok (po, Seq.toList compileFiles, (log |> Map.ofList)) - with - | ProjectInspectException d -> Error d - | e -> Error (GenericError(file, e.Message)) - - let load notifyState (cache: ParsedProjectCache) file = - loadBySdk notifyState cache ProjectParsingSdk.DotnetSdk file - - let loadVerboseSdk notifyState (cache: ParsedProjectCache) file = - loadBySdk notifyState cache ProjectParsingSdk.VerboseSdk file diff --git a/src/FsAutoComplete.Core/ProjectCrackerProjectJson.fs b/src/FsAutoComplete.Core/ProjectCrackerProjectJson.fs deleted file mode 100644 index 55577ff5e..000000000 --- a/src/FsAutoComplete.Core/ProjectCrackerProjectJson.fs +++ /dev/null @@ -1,43 +0,0 @@ -namespace FsAutoComplete - -open System -open System.IO - -open FSharp.Compiler.SourceCodeServices - -module ProjectCrackerProjectJson = - - let getProjectOptionsFromResponseFile (file : string) = - let projDir = Path.GetDirectoryName file - let rsp = - Directory.GetFiles(projDir, "dotnet-compile-fsc.rsp", SearchOption.AllDirectories) - |> Seq.head - |> File.ReadAllLines - |> Array.map Utils.normalizePath - |> Array.filter((<>) "--nocopyfsharpcore") - - { - ProjectId = Some file - ProjectFileName = file - SourceFiles = [||] - OtherOptions = rsp - ReferencedProjects = [||] - IsIncompleteTypeCheckEnvironment = false - UseScriptResolutionRules = false - LoadTime = DateTime.Now - UnresolvedReferences = None - Stamp = None - OriginalLoadReferences = [] - ExtraProjectInfo = Some (box { - ExtraProjectInfoData.ProjectSdkType = ProjectSdkType.ProjectJson - ExtraProjectInfoData.ProjectOutputType = rsp |> List.ofArray |> FscArguments.outType - }) - } - - let load file = - try - let po = getProjectOptionsFromResponseFile file - let compileFiles = FscArguments.compileFiles (po.OtherOptions |> List.ofArray) - Ok (po, Seq.toList compileFiles, Map([||])) - with e -> - Error (GenericError(file, e.Message)) diff --git a/src/FsAutoComplete.Core/ProjectCrackerTypes.fs b/src/FsAutoComplete.Core/ProjectCrackerTypes.fs index 00b4c0c45..2139cb81f 100644 --- a/src/FsAutoComplete.Core/ProjectCrackerTypes.fs +++ b/src/FsAutoComplete.Core/ProjectCrackerTypes.fs @@ -3,63 +3,13 @@ namespace FsAutoComplete open System open System.IO -[] -type ProjectSdkType = - | Verbose of ProjectSdkTypeVerbose - | ProjectJson - | DotnetSdk of ProjectSdkTypeDotnetSdk -and ProjectSdkTypeVerbose = - { - TargetPath: string - } -and ProjectSdkTypeDotnetSdk = - { - IsTestProject: bool - Configuration: string // Debug - IsPackable: bool // true - TargetFramework: string // netcoreapp1.0 - TargetFrameworkIdentifier: string // .NETCoreApp - TargetFrameworkVersion: string // v1.0 - - MSBuildAllProjects: FilePath list //;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\FSharp.NET.Sdk\Sdk\Sdk.props;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.props;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.props;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.props;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.SupportedTargetFrameworks.props;e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\obj\c1.fsproj.nuget.g.props;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\FSharp.NET.Sdk\Sdk\Sdk.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\Sdk\Sdk.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.BeforeCommon.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.DefaultAssemblyInfo.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.DefaultOutputPaths.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.TargetFrameworkInference.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.RuntimeIdentifierInference.targets;C:\Users\e.sada\.nuget\packages\fsharp.net.sdk\1.0.5\build\FSharp.NET.Core.Sdk.targets;e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\c1.fsproj;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Microsoft.Common.CurrentVersion.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\NuGet.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\15.0\Microsoft.Common.targets\ImportAfter\Microsoft.TestPlatform.ImportAfter.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Microsoft.TestPlatform.targets;e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\obj\c1.fsproj.nuget.g.targets;e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\obj\c1.fsproj.proj-info.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.Common.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Sdk.DefaultItems.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.DisableStandardFrameworkResolution.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.GenerateAssemblyInfo.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.Publish.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.PreserveCompilationContext.targets;C:\dotnetcli\dotnet-dev-win-x64.1.0.4\sdk\1.0.4\Sdks\NuGet.Build.Tasks.Pack\build\NuGet.Build.Tasks.Pack.targets - MSBuildToolsVersion: string // 15.0 - - ProjectAssetsFile: FilePath // e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\obj\project.assets.json - RestoreSuccess: bool // True - - Configurations: string list // Debug;Release - TargetFrameworks: string list // netcoreapp1.0;netstandard1.6 - - TargetPath: string - - //may not exists - RunArguments: string option // exec "e:\github\DotnetNewFsprojTestingSamples\sdk1.0\sample1\c1\bin\Debug\netcoreapp1.0\c1.dll" - RunCommand: string option // dotnet - - //from 2.0 - IsPublishable: bool option // true - - } - -type ExtraProjectInfoData = - { - ProjectOutputType: ProjectOutputType - ProjectSdkType: ProjectSdkType - } -and ProjectOutputType = - | Library - | Exe - | Custom of string - - type GetProjectOptionsErrors = | ProjectNotRestored of string | GenericError of string * string - type [] WorkspaceProjectState = | Loading of string - | Loaded of FSharp.Compiler.SourceCodeServices.FSharpProjectOptions * ExtraProjectInfoData * string list * Map + | Loaded of FSharp.Compiler.SourceCodeServices.FSharpProjectOptions * Dotnet.ProjInfo.Workspace.ExtraProjectInfoData * string list * Map | Failed of string * GetProjectOptionsErrors module ProjectRecognizer = diff --git a/src/FsAutoComplete.Core/ProjectCrackerVerbose.fs b/src/FsAutoComplete.Core/ProjectCrackerVerbose.fs deleted file mode 100644 index cb3c745a4..000000000 --- a/src/FsAutoComplete.Core/ProjectCrackerVerbose.fs +++ /dev/null @@ -1,104 +0,0 @@ -namespace FsAutoComplete - -open System -open System.IO - -open FSharp.Compiler.SourceCodeServices - -module ProjectCrackerVerbose = - - // interesting things: - // 1 - if fsharp.core.dll is not referenced, add it from ensureCorrectFSharpCore - // 2 - fsi are compile files - // varie: - // - search delle cose e' fatto con EndsWith, doesnt check if is an argument like -r - // - riarrangia i files fsi per po.SourceFiles in modo che siano prima del proprio file .fs **e lo toglie da project options** - // - po.SourceFiles e' ritonato come snd, a questi files viene appicciata la po (FSharpProjectOptions), quindi importante - // di filtrarli corretamente altrimenti non sarebbero parsabili - // - let po = { po with SourceFiles = po.SourceFiles |> Array.map normalizeDirSeparators } - - let load notifyState ensureCorrectFSharpCore file verbose = - try - notifyState (WorkspaceProjectState.Loading file) - - let po, logMap = - let p, logMap = - try - ProjectCracker.GetProjectOptionsFromProjectFileLogged(file, enableLogging=verbose) - with - | e -> - //HACK - Project cracker is failing to correctly deserialize cracking results - // if there was some additional content in MsBuild's stdout. As a result it returns - //whole stdout in error message. This checks if the error message contains correct JSON object - //reporesenting FSharpProjectOptions - if e.Message.Contains """{"Error@":null""" then - let startIndex = e.Message.IndexOf("""{"Error@":null""") - let endIndex = e.Message.IndexOf("stderr was:") - let msg = e.Message.Substring(startIndex, endIndex-startIndex) - let ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof) - let stringBytes = System.Text.Encoding.Unicode.GetBytes msg - use ms = new MemoryStream(stringBytes) - let opts = ser.ReadObject(ms) :?> ProjectCrackerTool.ProjectOptions - Utils.Convert DateTime.Now opts - else - raise e - match p.SourceFiles, p.OtherOptions, logMap |> Map.isEmpty with - | [| |], [| |], false -> - //HACK project cracker has failed - // ref https://github.com/fsharp/FSharp.Compiler.Service/issues/804 - // the ProjectCracker.GetProjectOptionsFromProjectFileLogged doesnt throw, just return an - // uninitalized FSharpProjectOptions and some log, who contains the exception - let logs = - logMap - |> Map.toArray - |> Array.map (fun (k,v) -> sprintf "%s: %s" k v) - |> fun a -> String.Join(Environment.NewLine, a) - failwithf "Failed parsing project file: %s" logs - | _ -> () - - let opts = - if not (Seq.exists (fun (s: string) -> s.Contains "FSharp.Core.dll") p.OtherOptions) then - ensureCorrectFSharpCore p.OtherOptions - else - p.OtherOptions - { p with OtherOptions = opts }, logMap - - let po = - match po.SourceFiles with - | [||] -> - let compileFiles, otherOptions = - po.OtherOptions |> Array.partition (FscArguments.isCompileFile) - { po with SourceFiles = compileFiles; OtherOptions = otherOptions } - | _ -> - //HACK ref https://github.com/fsharp/FSharp.Compiler.Service/issues/803 - // the ProjectCracker.GetProjectOptionsFromProjectFileLogged doesnt return the .fsi files inside - // the SourceFiles property, but are instead inside OtherOptions - // this workaround moving these **before** the corrisponding .fs file (.fsi file must precede the .fs) - let fsiFiles, otherOptions = - po.OtherOptions |> Array.partition (fun (s:string) -> FscArguments.isCompileFile s && s.EndsWith(".fsi")) - let fileNames = - po.SourceFiles - |> Array.fold (fun acc e -> - match fsiFiles |> Array.tryFind ((=) (e + "i")) with - | Some fsi -> - [| yield! acc; yield fsi; yield e |] - | None -> [| yield! acc; yield e |] ) [||] - - { po with SourceFiles = fileNames ; OtherOptions = otherOptions } - - let rec setExtraInfo po = - let outPath = - match FscArguments.outputFile (Path.GetDirectoryName(po.ProjectFileName)) (po.OtherOptions |> List.ofArray) with - | Some path -> path - | None -> failwithf "Cannot find output argument (-o, --out) in project '%s' with args %A" po.ProjectFileName po - { po with - SourceFiles = po.SourceFiles |> Array.map normalizeDirSeparators - ExtraProjectInfo = Some (box { - ExtraProjectInfoData.ProjectSdkType = ProjectSdkType.Verbose { TargetPath = outPath } - ProjectOutputType = po.OtherOptions |> List.ofArray |> FscArguments.outType - }) - ReferencedProjects = po.ReferencedProjects |> Array.map (fun (path,p2p) -> path, (setExtraInfo p2p)) } - - Ok (setExtraInfo po, Array.toList po.SourceFiles, logMap) - with e -> - Error (GenericError(file, e.Message)) diff --git a/src/FsAutoComplete.Core/Utils.fs b/src/FsAutoComplete.Core/Utils.fs index b4b5ede32..39056048e 100644 --- a/src/FsAutoComplete.Core/Utils.fs +++ b/src/FsAutoComplete.Core/Utils.fs @@ -31,7 +31,7 @@ let isAScript (fileName: string) = /// Determines if the current system is an Unix system. /// See http://www.mono-project.com/docs/faq/technical/#how-to-detect-the-execution-platform let isUnix = -#if NETSTANDARD1_6 +#if NETSTANDARD2_0 System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( System.Runtime.InteropServices.OSPlatform.Linux) || System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( @@ -42,7 +42,7 @@ let isUnix = /// Determines if the current system is a MacOs system let isMacOS = -#if NETSTANDARD1_6 +#if NETSTANDARD2_0 System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( System.Runtime.InteropServices.OSPlatform.OSX) #else @@ -53,7 +53,7 @@ let isMacOS = /// Determines if the current system is a Linux system let isLinux = -#if NETSTANDARD1_6 +#if NETSTANDARD2_0 System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( System.Runtime.InteropServices.OSPlatform.Linux) #else @@ -62,7 +62,7 @@ let isLinux = /// Determines if the current system is a Windows system let isWindows = -#if NETSTANDARD1_6 +#if NETSTANDARD2_0 System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform( System.Runtime.InteropServices.OSPlatform.Windows) #else @@ -71,13 +71,6 @@ let isWindows = | _ -> false #endif -let runningOnNetCore = -#if NETSTANDARD1_6 - true -#else - false -#endif - let runningOnMono = try not << isNull <| Type.GetType "Mono.Runtime" with _ -> false diff --git a/src/FsAutoComplete.Core/Workspace.fs b/src/FsAutoComplete.Core/Workspace.fs index bb7c0658c..1525274aa 100644 --- a/src/FsAutoComplete.Core/Workspace.fs +++ b/src/FsAutoComplete.Core/Workspace.fs @@ -3,84 +3,71 @@ module FsAutoComplete.Workspace open ProjectRecognizer open System.IO -let getProjectOptions notifyState (cache: ProjectCrackerDotnetSdk.ParsedProjectCache) verbose (projectFileName: SourceFilePath) = +type DPW_ProjectOptions = Dotnet.ProjInfo.Workspace.ProjectOptions +type DPW_ProjectSdkType = Dotnet.ProjInfo.Workspace.ProjectSdkType +type DPW_ProjectOutputType = Dotnet.ProjInfo.Workspace.ProjectOutputType +type DPW_ExtraProjectInfoData = Dotnet.ProjInfo.Workspace.ExtraProjectInfoData + +let private getProjectOptions (loader: Dotnet.ProjInfo.Workspace.Loader, fcsBinder: Dotnet.ProjInfo.Workspace.FCS.FCSBinder) (projectFileName: SourceFilePath) = if not (File.Exists projectFileName) then Error (GenericError(projectFileName, sprintf "File '%s' does not exist" projectFileName)) else match projectFileName with - | NetCoreProjectJson -> ProjectCrackerProjectJson.load projectFileName - | NetCoreSdk -> ProjectCrackerDotnetSdk.load notifyState cache projectFileName - | FSharpNetSdk -> Error (GenericError(projectFileName, (sprintf "Project file '%s' using FSharp.NET.Sdk not supported" projectFileName))) -#if NO_PROJECTCRACKER - | Net45 -> ProjectCrackerDotnetSdk.loadVerboseSdk notifyState cache projectFileName - | Unsupported -> Error (GenericError(projectFileName, (sprintf "Project file '%s' not supported" projectFileName))) -#else - | Net45 -> ProjectCrackerVerbose.load notifyState FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore projectFileName verbose - | Unsupported -> ProjectCrackerVerbose.load notifyState FSharpCompilerServiceCheckerHelper.ensureCorrectFSharpCore projectFileName verbose -#endif + | Net45 + | NetCoreSdk -> + loader.LoadProjects [projectFileName] + + match fcsBinder.GetProjectOptions (projectFileName) with + | Some po -> + // same useless log to remain compatible with tests baseline + let logMap = [ projectFileName, "" ] |> Map.ofList -let private bindExtraOptions (opts: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, projectFiles, logMap) = + Result.Ok (po, List.ofArray po.SourceFiles, logMap) + | None -> + Error (GenericError(projectFileName, (sprintf "Project file '%s' parsing failed" projectFileName))) + | NetCoreProjectJson -> + Error (GenericError(projectFileName, (sprintf "Project file '%s' format project.json not supported" projectFileName))) + | FSharpNetSdk -> + Error (GenericError(projectFileName, (sprintf "Project file '%s' using FSharp.NET.Sdk not supported" projectFileName))) + | Unsupported -> + Error (GenericError(projectFileName, (sprintf "Project file '%s' not supported" projectFileName))) + +let extractOptionsDPW (opts: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions) = match opts.ExtraProjectInfo with | None -> Error (GenericError(opts.ProjectFileName, "expected ExtraProjectInfo after project parsing, was None")) | Some x -> match x with - | :? ExtraProjectInfoData as extraInfo -> - Ok (opts, extraInfo, projectFiles, logMap) + | :? DPW_ProjectOptions as poDPW -> + Ok poDPW | x -> Error (GenericError(opts.ProjectFileName, (sprintf "expected ExtraProjectInfo after project parsing, was %A" x))) -let private deduplicateReferences (opts: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, projectFiles, logMap) = - let projs = - opts.ReferencedProjects |> Array.map fst - - let references = - opts.OtherOptions - |> Array.choose (fun n -> if n.StartsWith "-r:" then Some (n.Substring(3)) else None) - |> Array.groupBy (Path.GetFullPathSafe) - |> Array.map (fun (_,lst) -> - match lst |> Array.tryFind (fun n -> projs |> Array.contains n) with - | Some s -> s - | None -> Array.head lst ) - - let oos = [| - yield! (opts.OtherOptions |> Array.filter (fun n -> not (n.StartsWith "-r:"))) - yield! (references |> Array.map (sprintf "-r:%s")) - |] - let opts = {opts with OtherOptions = oos} - opts, projectFiles, logMap - -let private removeDeprecatedArgs (opts: FSharp.Compiler.SourceCodeServices.FSharpProjectOptions, projectFiles, logMap) = - let oos = opts.OtherOptions |> Array.filter (fun n -> n <> "--times" && n <> "--no-jit-optimize") - let opts = {opts with OtherOptions = oos} - opts, projectFiles, logMap +let private parseProject' (loader, fcsBinder) projectFileName = + projectFileName + |> getProjectOptions (loader, fcsBinder) + |> Result.bind (fun (fcsOpts, projectFiles, logMap) -> + match extractOptionsDPW fcsOpts with + | Ok optsDPW -> Ok (fcsOpts, optsDPW, projectFiles, logMap) + | Error x -> Error x) -let parseProject verbose projectFileName = - let projsCache = new ProjectCrackerDotnetSdk.ParsedProjectCache() +let parseProject (loader, fcsBinder) projectFileName = projectFileName - |> getProjectOptions ignore projsCache verbose - |> Result.map deduplicateReferences - |> Result.map removeDeprecatedArgs - |> Result.bind bindExtraOptions + |> parseProject' (loader, fcsBinder) -let loadInBackground onLoaded verbose (projects: Project list) = async { - let projsCache = new ProjectCrackerDotnetSdk.ParsedProjectCache() +let loadInBackground onLoaded (loader, fcsBinder) (projects: Project list) = async { - projects - |> List.iter(fun project -> + for project in projects do match project.Response with | Some res -> onLoaded (WorkspaceProjectState.Loaded (res.Options, res.ExtraInfo, res.Files, res.Log)) | None -> project.FileName - |> getProjectOptions onLoaded projsCache verbose - |> Result.map deduplicateReferences - |> Result.map removeDeprecatedArgs - |> Result.bind bindExtraOptions + |> parseProject' (loader, fcsBinder) |> function - | Ok (opts, extraInfo, projectFiles, logMap) -> - onLoaded (WorkspaceProjectState.Loaded (opts, extraInfo, projectFiles, logMap)) - | Error error -> - onLoaded (WorkspaceProjectState.Failed (project.FileName, error)) - ) + | Ok (opts, optsDPW, projectFiles, logMap) -> + onLoaded (WorkspaceProjectState.Loaded (opts, optsDPW.ExtraProjectInfo, projectFiles, logMap)) + | Error error -> + onLoaded (WorkspaceProjectState.Failed (project.FileName, error)) + } diff --git a/src/FsAutoComplete.Core/paket.references b/src/FsAutoComplete.Core/paket.references index 73e3f625c..b1edc638b 100644 --- a/src/FsAutoComplete.Core/paket.references +++ b/src/FsAutoComplete.Core/paket.references @@ -1,8 +1,8 @@ FSharp.Compiler.Service -FSharp.Compiler.Service.ProjectCracker condition:net461 FSharpLint.Core Sln Dotnet.ProjInfo +Dotnet.ProjInfo.Workspace.FCS Newtonsoft.Json OptimizedPriorityQueue ICSharpCode.Decompiler diff --git a/src/FsAutoComplete.SymbolCache/JsonSerializer.fs b/src/FsAutoComplete.SymbolCache/JsonSerializer.fs index 68b622495..0e413552f 100644 --- a/src/FsAutoComplete.SymbolCache/JsonSerializer.fs +++ b/src/FsAutoComplete.SymbolCache/JsonSerializer.fs @@ -55,9 +55,9 @@ module private JsonSerializerConverters = let projectOutputTypeWriter (writer: JsonWriter) value (serializer : JsonSerializer) = let s = match value with - | ProjectOutputType.Library -> "lib" - | ProjectOutputType.Exe -> "exe" - | ProjectOutputType.Custom(x) -> x.ToLower() + | CommandResponse.ProjectOutputType.Library -> "lib" + | CommandResponse.ProjectOutputType.Exe -> "exe" + | CommandResponse.ProjectOutputType.Custom(x) -> x.ToLower() serializer.Serialize(writer, s) diff --git a/src/FsAutoComplete/CommandResponse.fs b/src/FsAutoComplete/CommandResponse.fs index ecaf1d594..428edc2dc 100644 --- a/src/FsAutoComplete/CommandResponse.fs +++ b/src/FsAutoComplete/CommandResponse.fs @@ -128,6 +128,10 @@ module CommandResponse = Info: ProjectResponseInfo AdditionalInfo: Map } + and ProjectOutputType = + | Library + | Exe + | Custom of string type OverloadDescription = { @@ -430,14 +434,12 @@ module CommandResponse = let data = [[{OverloadDescription.Signature = name; Comment = tip}]] serialize {Kind = "helptext"; Data = {HelpTextResponse.Name = name; Overloads = data; AdditionalEdit = None} } - let project (serialize : Serializer) (projectFileName, projectFiles, outFileOpt, references, logMap, (extra: ExtraProjectInfoData), additionals) = + let project (serialize : Serializer) (projectFileName, projectFiles, outFileOpt, references, logMap, (extra: Dotnet.ProjInfo.Workspace.ExtraProjectInfoData), additionals) = let projectInfo = match extra.ProjectSdkType with - | ProjectSdkType.Verbose _ -> + | Dotnet.ProjInfo.Workspace.ProjectSdkType.Verbose _ -> ProjectResponseInfo.Verbose - | ProjectSdkType.ProjectJson -> - ProjectResponseInfo.ProjectJson - | ProjectSdkType.DotnetSdk info -> + | Dotnet.ProjInfo.Workspace.ProjectSdkType.DotnetSdk info -> ProjectResponseInfo.DotnetSdk { IsTestProject = info.IsTestProject Configuration = info.Configuration @@ -460,7 +462,11 @@ module CommandResponse = Output = match outFileOpt with Some x -> x | None -> "null" References = List.sortBy IO.Path.GetFileName references Logs = logMap - OutputType = extra.ProjectOutputType + OutputType = + match extra.ProjectOutputType with + | Dotnet.ProjInfo.Workspace.ProjectOutputType.Library -> Library + | Dotnet.ProjInfo.Workspace.ProjectOutputType.Exe -> Exe + | Dotnet.ProjInfo.Workspace.ProjectOutputType.Custom outType -> Custom outType Info = projectInfo AdditionalInfo = additionals } serialize { Kind = "project"; Data = projectData } diff --git a/src/FsAutoComplete/FsAutoComplete.fsproj b/src/FsAutoComplete/FsAutoComplete.fsproj index 3a87eb66b..23abae159 100644 --- a/src/FsAutoComplete/FsAutoComplete.fsproj +++ b/src/FsAutoComplete/FsAutoComplete.fsproj @@ -51,17 +51,6 @@ - - - - - - - diff --git a/src/FsAutoComplete/JsonSerializer.fs b/src/FsAutoComplete/JsonSerializer.fs index c282bac80..52be5287a 100644 --- a/src/FsAutoComplete/JsonSerializer.fs +++ b/src/FsAutoComplete/JsonSerializer.fs @@ -99,9 +99,9 @@ module private JsonSerializerConverters = let projectOutputTypeWriter (writer: JsonWriter) value (serializer : JsonSerializer) = let s = match value with - | ProjectOutputType.Library -> "lib" - | ProjectOutputType.Exe -> "exe" - | ProjectOutputType.Custom(x) -> x.ToLower() + | CommandResponse.ProjectOutputType.Library -> "lib" + | CommandResponse.ProjectOutputType.Exe -> "exe" + | CommandResponse.ProjectOutputType.Custom(x) -> x.ToLower() serializer.Serialize(writer, s) diff --git a/src/FsAutoComplete/paket.references b/src/FsAutoComplete/paket.references index d6a2b19e1..04a3201cf 100644 --- a/src/FsAutoComplete/paket.references +++ b/src/FsAutoComplete/paket.references @@ -1,6 +1,5 @@ System.ValueTuple condition:net461 FSharp.Compiler.Service -FSharp.Compiler.Service.ProjectCracker condition:net461 Argu Newtonsoft.Json Suave diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/FileTwo.fs b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/FileTwo.fs deleted file mode 100644 index 105081bdb..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/FileTwo.fs +++ /dev/null @@ -1,14 +0,0 @@ -module FileTwo - -type Foo = - | Bar - | Qux - -let addition x y = x + y - -let add x y = x + y - -type NewObjectType() = - - member x.Terrific (y : int) : int = - y diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Program.fs b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Program.fs deleted file mode 100644 index 60181db4e..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Program.fs +++ /dev/null @@ -1,15 +0,0 @@ -module X = - let func x = x + 1 - -let testval = FileTwo.NewObjectType() - -let val2 = X.func 2 - -let val3 = testval.Terrific val2 - -let val4 : FileTwo.NewObjectType = testval - -[] -let main args = - printfn "Hello %d" val2 - 0 diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Runner.fsx b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Runner.fsx deleted file mode 100644 index 6bec7d15c..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Runner.fsx +++ /dev/null @@ -1,21 +0,0 @@ -#load "../TestHelpers.fsx" -open TestHelpers -open System.IO -open System - -(* - * This test is a simple sanity check of a basic run of the program. - * A few completions, files and script. - *) - -Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ -File.Delete "output.json" - -let p = new FsAutoCompleteWrapper() - - -p.project "Test1.fsproj" -p.quit() -p.finalOutput () -|> writeNormalizedOutput "output.json" - diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Script.fsx b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Script.fsx deleted file mode 100644 index eea456da4..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Script.fsx +++ /dev/null @@ -1,6 +0,0 @@ - - -module XA = - let funky x = x + 1 - -let val99 = XA.funky 21 diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj deleted file mode 100644 index 6d2231ca1..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj +++ /dev/null @@ -1,74 +0,0 @@ - - - - Debug - x86 - 8.0.30703 - 2.0 - {116cc2f9-f987-4b3d-915a-34cac04a73da} - Exe - Test1 - Test1 - Test1 - False - - - Program.fs - - - v4.5 - 4.3.0.0 - 11 - - - True - full - False - False - bin\Debug\ - DEBUG;TRACE - 3 - x86 - bin\Debug\Test1.XML - - - pdbonly - True - True - bin\Release\ - TRACE - 3 - x86 - bin\Release\Test1.XML - False - - - - - - - - - - - - - - $(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets - - - - - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets - - - - - - diff --git a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/output.json b/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/output.json deleted file mode 100644 index 03627515e..000000000 --- a/test/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/output.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "Kind": "project", - "Data": { - "Project": "/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj", - "Files": [ - "/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/FileTwo.fs", - "/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Program.fs" - ], - "Output": "/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/bin/Debug/Test1.exe", - "References": [ - "/FSharp.Core.dll", - "/System.Core.dll", - "/System.dll", - "/mscorlib.dll" - ], - "Logs": { - "/FsAutoComplete.IntegrationTests/NoFSharpCoreReference/Test1.fsproj": "" - }, - "OutputType": "exe", - "Info": { - "SdkType": "verbose", - "Data": {} - }, - "AdditionalInfo": {} - } -} -{ - "Kind": "info", - "Data": "quitting..." -} diff --git a/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.json b/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.json index 139fe388f..e056ade15 100644 --- a/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.json +++ b/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.json @@ -2,7 +2,7 @@ "Kind": "error", "Data": { "Code": 101, - "Message": "Could not load project /FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj in ProjectCollection. Available tools: [] Message: The project file could not be loaded. '>' is an unexpected token. The expected token is '='. Line 7, position 21. StackTrace: at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.projectInstanceFromFullPath@76(FSharpList`1 properties, ProjectCollection engine, String fsprojFullPath)\n at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.CrackProjectUsingNewBuildAPI[a](String fsprojFile, FSharpList`1 properties, FSharpOption`1 logOpt)\n at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.FSharpProjectFileInfo..ctor(String fsprojFileName, FSharpOption`1 properties, FSharpOption`1 enableLogging)\n at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.getOptions@396(Boolean enableLogging, FSharpList`1 properties, Dictionary`2 cache, String file)\n at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.getOptions(String file, Boolean enableLogging, FSharpList`1 properties)\n at FSharp.Compiler.SourceCodeServices.ProjectCrackerTool.ProjectCrackerTool.crackOpen(String[] argv)", + "Message": "Project file '/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj' parsing failed", "AdditionalData": { "Project": "/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj" } diff --git a/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.netcore.json b/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.netcore.json index 1bcc2f8d9..e056ade15 100644 --- a/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.netcore.json +++ b/test/FsAutoComplete.IntegrationTests/OldSdk/invalidprojectfile.netcore.json @@ -2,7 +2,7 @@ "Kind": "error", "Data": { "Code": 101, - "Message": "MSBuild failed with exitCode 1 Working Directory: '/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1' Exe Path: 'msbuild' Args: '/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj /p:CopyBuildOutputToOutputDirectory=false /p:UseCommonOutputDirectory=true /p:BuildingInsideVisualStudio=true /p:ShouldUnsetParentConfigurationAndPlatform=true /t:Build /p:_Inspect_CoreCompilePropsOldSdk_OutFile=/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/obj/Test1.fsproj.proj-info.targets'.\nwriting helper target file in '/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj(7,21): error MSB4025: The project file could not be loaded. '>' is an unexpected token. The expected token is '='. Line 7, position 21.\n\n", + "Message": "Project file '/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj' parsing failed", "AdditionalData": { "Project": "/FsAutoComplete.IntegrationTests/OldSdk/sample3/l1/Test1.fsproj" } diff --git a/test/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/output.json b/test/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/output.json index 5126d298f..92a8eae3c 100644 --- a/test/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/output.json +++ b/test/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/output.json @@ -15,9 +15,7 @@ "/mscorlib.dll" ], "Logs": { - "/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/MultiProject1.fsproj": "", - "/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/Project1A.fsproj": "", - "/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/Project1B.fsproj": "" + "/FsAutoComplete.IntegrationTests/UncompiledReferencedProjects/MultiProject1.fsproj": "" }, "OutputType": "exe", "Info": { From 606666971b66b867562438456cda76ddeec0809d Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Wed, 15 May 2019 11:28:34 +0200 Subject: [PATCH 2/3] add stdio debugger --- .vscode/launch.json | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 0459c9c21..d9b011929 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -38,6 +38,30 @@ "console": "integratedTerminal", "stopAtEntry": false, }, + { + "name": ".NET Core mode stdio (debug)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build_debug_netcore", + "program": "${workspaceFolder}/src/FsAutoComplete/bin/Debug/netcoreapp2.1/fsautocomplete.dll", + "args": ["--mode", "stdio", "-v"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "stopAtEntry": false, + "internalConsoleOptions": "openOnSessionStart" + }, + { + "name": ".NET mode stdio (debug)", + "type": "clr", + "request": "launch", + "preLaunchTask": "build_debug_net", + "program": "${workspaceFolder}/src/FsAutoComplete/bin/Debug/net461/fsautocomplete.exe", + "args": ["--mode", "stdio", "-v"], + "cwd": "${workspaceFolder}", + "console": "integratedTerminal", + "stopAtEntry": false, + "internalConsoleOptions": "openOnSessionStart" + }, { "name": ".NET Core Attach", "type": "coreclr", From fb242ce047ea4c45f9f2834f07ff7afd83349f42 Mon Sep 17 00:00:00 2001 From: Enrico Sada Date: Mon, 20 May 2019 22:53:10 +0200 Subject: [PATCH 3/3] remove unused json converters --- src/FsAutoComplete.SymbolCache/JsonSerializer.fs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/FsAutoComplete.SymbolCache/JsonSerializer.fs b/src/FsAutoComplete.SymbolCache/JsonSerializer.fs index 0e413552f..8cb04ea0e 100644 --- a/src/FsAutoComplete.SymbolCache/JsonSerializer.fs +++ b/src/FsAutoComplete.SymbolCache/JsonSerializer.fs @@ -52,15 +52,6 @@ module private JsonSerializerConverters = writer.WriteValue(range.EndLine) writer.WriteEndObject() - let projectOutputTypeWriter (writer: JsonWriter) value (serializer : JsonSerializer) = - let s = - match value with - | CommandResponse.ProjectOutputType.Library -> "lib" - | CommandResponse.ProjectOutputType.Exe -> "exe" - | CommandResponse.ProjectOutputType.Custom(x) -> x.ToLower() - serializer.Serialize(writer, s) - - let internal jsonConverters = let writeOnlyConverter (f: JsonWriter -> 'T -> JsonSerializer -> unit) (canConvert: Type -> Type -> bool) = @@ -90,8 +81,7 @@ module private JsonSerializerConverters = [| writeOnlyConverter fsharpErrorSeverityWriter (=) writeOnlyConverter rangeWriter (=) - OptionConverter() :> JsonConverter - writeOnlyConverter projectOutputTypeWriter sameDU |] + OptionConverter() :> JsonConverter |] module JsonSerializer =