diff --git a/src/FsAutoComplete.Core/Consts.fs b/src/FsAutoComplete.Core/Consts.fs index 423dfffd7..78d58fbc2 100644 --- a/src/FsAutoComplete.Core/Consts.fs +++ b/src/FsAutoComplete.Core/Consts.fs @@ -5,6 +5,7 @@ module ProjectLoader = let ProduceReferenceAssembly = "ProduceReferenceAssembly" let globalProperties = - [ - // For tooling we don't want to use Reference Assemblies as this doesn't play well with type checking across projects - ProduceReferenceAssembly, "false" ] + Map.ofList + [ + // For tooling we don't want to use Reference Assemblies as this doesn't play well with type checking across projects + ProduceReferenceAssembly, "false" ] diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index 824dae84e..c59bb338e 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -609,6 +609,9 @@ type NotificationsDto = { Trace: bool option TraceNamespaces: string array option } +type BuildOptionsDto = + { MsBuildProperties: Dictionary option } + type DebugDto = { DontCheckRelatedFiles: bool option CheckFileDebouncerTimeout: int option @@ -662,6 +665,7 @@ type FSharpConfigDto = InlayHints: InlayHintDto option Fsac: FSACDto option Notifications: NotificationsDto option + BuildOptions: BuildOptionsDto option Debug: DebugDto option } type FSharpConfigRequest = { FSharp: FSharpConfigDto option } @@ -726,6 +730,22 @@ type FSACConfig = member this.AddDto(dto: FSACDto) = { CachedTypeCheckCount = defaultArg dto.CachedTypeCheckCount this.CachedTypeCheckCount } +type BuildOptions = + { MsBuildProperties: Map } + + static member Default = { MsBuildProperties = Map.empty } + + static member FromDto(dto: BuildOptionsDto) : BuildOptions = + let props = dto.MsBuildProperties |> Option.map (Seq.map (|KeyValue|) >> Map.ofSeq) + + { MsBuildProperties = defaultArg props BuildOptions.Default.MsBuildProperties } + + + member this.AddDto(dto: BuildOptionsDto) : BuildOptions = + let props = dto.MsBuildProperties |> Option.map (Seq.map (|KeyValue|) >> Map.ofSeq) + + { MsBuildProperties = defaultArg props this.MsBuildProperties } + type DebugConfig = { DontCheckRelatedFiles: bool CheckFileDebouncerTimeout: int @@ -778,6 +798,7 @@ type FSharpConfig = InlineValues: InlineValuesConfig Notifications: NotificationsConfig Fsac: FSACConfig + BuildOptions: BuildOptions Debug: DebugConfig } static member Default: FSharpConfig = @@ -820,6 +841,7 @@ type FSharpConfig = InlineValues = InlineValuesConfig.Default Notifications = NotificationsConfig.Default Fsac = FSACConfig.Default + BuildOptions = BuildOptions.Default Debug = DebugConfig.Default } static member FromDto(dto: FSharpConfigDto) : FSharpConfig = @@ -893,6 +915,10 @@ type FSharpConfig = dto.Fsac |> Option.map FSACConfig.FromDto |> Option.defaultValue FSACConfig.Default + BuildOptions = + dto.BuildOptions + |> Option.map BuildOptions.FromDto + |> Option.defaultValue BuildOptions.Default Debug = match dto.Debug with | None -> DebugConfig.Default @@ -981,6 +1007,10 @@ type FSharpConfig = |> Option.map x.Notifications.AddDto |> Option.defaultValue NotificationsConfig.Default Fsac = dto.Fsac |> Option.map x.Fsac.AddDto |> Option.defaultValue FSACConfig.Default + BuildOptions = + dto.BuildOptions + |> Option.map x.BuildOptions.AddDto + |> Option.defaultValue BuildOptions.Default Debug = match dto.Debug with | None -> DebugConfig.Default diff --git a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs index 7ca88b328..ef250025b 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs @@ -54,7 +54,7 @@ type AdaptiveWorkspaceChosen = | Projs of amap, DateTime> | NotChosen -type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FSharpLspClient) = +type AdaptiveFSharpLspServer(workspaceLoader: Map -> IWorkspaceLoader, lspClient: FSharpLspClient) = let thisType = typeof @@ -509,8 +509,16 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar file |> addAValLogging logMsg - let loader = cval workspaceLoader + let loaderFactory = + cval -> Ionide.ProjInfo.IWorkspaceLoader> workspaceLoader + let loader = + aval { + let! loaderFactory = loaderFactory + and! config = config + + return loaderFactory config.BuildOptions.MsBuildProperties + } let binlogConfig = diff --git a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs index cda183565..aa71f5a1b 100644 --- a/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs +++ b/src/FsAutoComplete/LspServers/FsAutoComplete.Lsp.fs @@ -2953,7 +2953,9 @@ module FSharpLspServer = |> Map.add "fsproj/removeFile" (serverRequestHandling (fun s p -> s.FsProjRemoveFile(p))) let regularServer lspClient = - let state = State.Initial toolsPath stateStorageDir workspaceLoaderFactory + let state = + State.Initial toolsPath stateStorageDir (fun toolsPath -> workspaceLoaderFactory toolsPath Map.empty) + let originalFs = FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem FSharp.Compiler.IO.FileSystemAutoOpens.FileSystem <- FsAutoComplete.FileSystem(originalFs, state.Files.TryFind) new FSharpLspServer(state, lspClient) :> IFSharpLspServer diff --git a/src/FsAutoComplete/Parser.fs b/src/FsAutoComplete/Parser.fs index 655a3a466..e777255e5 100644 --- a/src/FsAutoComplete/Parser.fs +++ b/src/FsAutoComplete/Parser.fs @@ -130,11 +130,13 @@ module Parser = rootCommand.SetHandler( Func<_, _, _, Task>(fun projectGraphEnabled stateDirectory adaptiveLspEnabled -> let workspaceLoaderFactory = - fun toolsPath -> + fun toolsPath props -> + let props = Map.merge ProjectLoader.globalProperties props |> Map.toList + if projectGraphEnabled then - Ionide.ProjInfo.WorkspaceLoaderViaProjectGraph.Create(toolsPath, ProjectLoader.globalProperties) + Ionide.ProjInfo.WorkspaceLoaderViaProjectGraph.Create(toolsPath, props) else - Ionide.ProjInfo.WorkspaceLoader.Create(toolsPath, ProjectLoader.globalProperties) + Ionide.ProjInfo.WorkspaceLoader.Create(toolsPath, props) let dotnetPath = if diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs index 2ad51f8bd..4004711db 100644 --- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs +++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs @@ -272,6 +272,7 @@ let defaultConfigDto: FSharpConfigDto = Prefix = Some "//" } Notifications = None Fsac = None + BuildOptions = None Debug = None } let clientCaps: ClientCapabilities = diff --git a/test/FsAutoComplete.Tests.Lsp/Program.fs b/test/FsAutoComplete.Tests.Lsp/Program.fs index 1f25dcf6c..20b230e53 100644 --- a/test/FsAutoComplete.Tests.Lsp/Program.fs +++ b/test/FsAutoComplete.Tests.Lsp/Program.fs @@ -32,7 +32,9 @@ Environment.SetEnvironmentVariable("FSAC_WORKSPACELOAD_DELAY", "250") let loaders = [ - "Ionide WorkspaceLoader", (fun toolpath -> WorkspaceLoader.Create(toolpath, FsAutoComplete.Core.ProjectLoader.globalProperties)) + "Ionide WorkspaceLoader", (fun toolpath props -> + let props = FsAutoComplete.Utils.Map.merge FsAutoComplete.Core.ProjectLoader.globalProperties props |> Map.toList + WorkspaceLoader.Create(toolpath, props)) // "MSBuild Project Graph WorkspaceLoader", (fun toolpath -> WorkspaceLoaderViaProjectGraph.Create(toolpath, FsAutoComplete.Core.ProjectLoader.globalProperties)) ] @@ -195,9 +197,12 @@ let main args = args |> Array.windowed 2 |> Array.tryPick (function - | [| "--loader"; "ionide" |] as args -> Some(args, [ "Ionide WorkspaceLoader", WorkspaceLoader.Create ]) + | [| "--loader"; "ionide" |] as args -> + let (name, factory) = loaders |> Seq.find(fun (k,v) -> k = "Ionide WorkspaceLoader") + Some(args, [ name, factory ]) | [| "--loader"; "graph" |] as args -> - Some(args, [ "MSBuild Project Graph WorkspaceLoader", WorkspaceLoaderViaProjectGraph.Create ]) + let (name, factory) = loaders |> Seq.find(fun (k,v) -> k = "MSBuild Project Graph WorkspaceLoader") + Some(args, [ name, factory ]) | _ -> None) |> Option.defaultValue ([||], loaders)