From e35615cc86c48aff4e61ae56b5bc63f5f3b67485 Mon Sep 17 00:00:00 2001 From: greggyb Date: Wed, 22 May 2024 20:54:03 -0400 Subject: [PATCH 1/5] FIX: #1210; split `FSIExtraParameters` in two `FSIExtraParameters` (old) becomes `FSIExtraInteractiveParameters` and `FSIExtraSharedParameters`. Previously, `FSIExtraParameters` was passed directly to the compiler for code analysis. This is to ensure that the static analysis of a .fsx script file is congruent with the code being evaluated in the interpreter. The FSI interpreter has different parameters than the compiler, [documented here](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). When an interactive-only parameter was used, this led to compiler errors. It is intended that FSAC will learn to manage the interactive interpreter in the future, but it does not yet do so. Editor plugins manage the interpreter right now. Some plugins (at least Ionide-vim) use the config option `FSIExtraParameters` to configure that interpreter, and this makes sense. To support the current state and the future state, we split the single `FSIExtraParameters` into `FSIExtraInteractiveParameters` and `FSIExtraSharedParameters` so that the interactive interpreter can be launched with the union of these two and the compiler can receive only the shared parameters that it knows how to deal with. This allows editors to use both config options today to launch the interpreter. Today, FSAC only uses the shared parameters. In the future, when FSAC learns to manage the interactive interpreter, it can union the parameters for the interactive session and continue to pass only the shared parameters to the compiler. When this change occurs, if an editor plugin still manages the `dotnet fsi` interpreter, that will continue to work. Editor plugins can opt in to FSAC-managed interpreters at their will, and with the same configuration options the users already have set up. Additional discussion: - #1210: proximate bug: https://github.com/ionide/FsAutoComplete/issues/1210 - `dotnet fsi` readline bug, making this option very salient for editor plugins: https://github.com/dotnet/fsharp/issues/17215 --- README.md | 6 ++++-- src/FsAutoComplete/LspHelpers.fs | 17 ++++++++++++----- src/FsAutoComplete/LspHelpers.fsi | 6 ++++-- .../LspServers/AdaptiveServerState.fs | 2 +- .../CodeFixTests/Tests.fs | 2 +- .../CodeFixTests/ToInterpolatedStringTests.fs | 6 +++--- test/FsAutoComplete.Tests.Lsp/Helpers.fs | 3 ++- test/FsAutoComplete.Tests.Lsp/ScriptTests.fs | 8 ++++---- 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 06d3c8c63..d579242a6 100644 --- a/README.md +++ b/README.md @@ -199,10 +199,12 @@ Options that should be send as `initializationOptions` as part of `initialize` r * `FSharp.ResolveNamespaces` - enables resolve namespace quick fix (add `open` if symbol is from not yet opened module/namespace), recommended default value: `true` * `FSharp.EnableReferenceCodeLens` - enables reference count code lenses, recommended default value: `true` if `--background-service-enabled` is used by default, `false` otherwise * `FSharp.dotNetRoot` - sets the root path for finding dotnet SDK references. Primarily used for FSX Scripts. Default value: operating-system dependent. On windows, `C:\Program Files\dotnet`; on Unix, `/usr/local/share/dotnet` -* `FSharp.fsiExtraParameters` - an array of additional runtime arguments that are passed to FSI. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. +* `FSharp.fsiExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). +* `FSharp.fsiExtraParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). ```json - "FSharp.fsiExtraParameters": ["--langversion:preview"] + "FSharp.fsiExtraSharedParameters": ["--langversion:preview"] + "FSharp.fsiExtraInteractiveParameters": ["--readline-"] ``` #### Debug Settings diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index ece9a9ff8..f54171a35 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -673,7 +673,8 @@ type FSharpConfigDto = LineLens: LineLensConfig option UseSdkScripts: bool option DotNetRoot: string option - FSIExtraParameters: string array option + FSIExtraInteractiveParameters: string array option + FSIExtraSharedParameters: string array option FSICompilerToolLocations: string array option TooltipMode: string option GenerateBinlog: bool option @@ -815,7 +816,10 @@ type FSharpConfig = LineLens: LineLensConfig UseSdkScripts: bool DotNetRoot: string - FSIExtraParameters: string array + // for parameters only used in interactive FSI sessions; currently unused + FSIExtraInteractiveParameters: string array + // for parameters used both in the compiler and interactive FSI + FSIExtraSharedParameters: string array FSICompilerToolLocations: string array TooltipMode: string GenerateBinlog: bool @@ -864,7 +868,8 @@ type FSharpConfig = LineLens = { Enabled = "never"; Prefix = "" } UseSdkScripts = true DotNetRoot = Environment.dotnetSDKRoot.Value.FullName - FSIExtraParameters = [||] + FSIExtraInteractiveParameters = [||] + FSIExtraSharedParameters = [||] FSICompilerToolLocations = [||] TooltipMode = "full" GenerateBinlog = false @@ -920,7 +925,8 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue Environment.dotnetSDKRoot.Value.FullName - FSIExtraParameters = defaultArg dto.FSIExtraParameters FSharpConfig.Default.FSIExtraParameters + FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters + FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters FSICompilerToolLocations = defaultArg dto.FSICompilerToolLocations FSharpConfig.Default.FSICompilerToolLocations TooltipMode = defaultArg dto.TooltipMode "full" GenerateBinlog = defaultArg dto.GenerateBinlog false @@ -1029,7 +1035,8 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue FSharpConfig.Default.DotNetRoot - FSIExtraParameters = defaultArg dto.FSIExtraParameters FSharpConfig.Default.FSIExtraParameters + FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters + FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters FSICompilerToolLocations = defaultArg dto.FSICompilerToolLocations FSharpConfig.Default.FSICompilerToolLocations TooltipMode = defaultArg dto.TooltipMode x.TooltipMode GenerateBinlog = defaultArg dto.GenerateBinlog x.GenerateBinlog diff --git a/src/FsAutoComplete/LspHelpers.fsi b/src/FsAutoComplete/LspHelpers.fsi index 2296192dc..05ab6869c 100644 --- a/src/FsAutoComplete/LspHelpers.fsi +++ b/src/FsAutoComplete/LspHelpers.fsi @@ -301,7 +301,8 @@ type FSharpConfigDto = LineLens: LineLensConfig option UseSdkScripts: bool option DotNetRoot: string option - FSIExtraParameters: string array option + FSIExtraInteractiveParameters: string array option + FSIExtraSharedParameters: string array option FSICompilerToolLocations: string array option TooltipMode: string option GenerateBinlog: bool option @@ -402,7 +403,8 @@ type FSharpConfig = LineLens: LineLensConfig UseSdkScripts: bool DotNetRoot: string - FSIExtraParameters: string array + FSIExtraInteractiveParameters: string array + FSIExtraSharedParameters: string array FSICompilerToolLocations: string array TooltipMode: string GenerateBinlog: bool diff --git a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs index f4e2fdf44..b4c53b35f 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveServerState.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveServerState.fs @@ -307,7 +307,7 @@ type AdaptiveState |> Observable.subscribe (fun (config, checker, rootPath) -> toggleTraceNotification config.Notifications.Trace config.Notifications.TraceNamespaces - setFSIArgs checker config.FSICompilerToolLocations config.FSIExtraParameters + setFSIArgs checker config.FSICompilerToolLocations config.FSIExtraSharedParameters loadAnalyzers config rootPath diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs index c52390c2e..4095b0203 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/Tests.fs @@ -2333,7 +2333,7 @@ let private removeUnnecessaryReturnOrYieldTests state = let private removeUnusedBindingTests state = let config = { defaultConfigDto with - FSIExtraParameters = Some [| "--warnon:1182" |] } + FSIExtraSharedParameters = Some [| "--warnon:1182" |] } serverTestList (nameof RemoveUnusedBinding) state config None (fun server -> [ let selectRemoveUnusedBinding = CodeFix.withTitle RemoveUnusedBinding.titleBinding diff --git a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/ToInterpolatedStringTests.fs b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/ToInterpolatedStringTests.fs index 0e276a9f3..5e70b6fd4 100644 --- a/test/FsAutoComplete.Tests.Lsp/CodeFixTests/ToInterpolatedStringTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/CodeFixTests/ToInterpolatedStringTests.fs @@ -1,4 +1,4 @@ -module private FsAutoComplete.Tests.CodeFixTests.ToInterpolatedStringTests +module private FsAutoComplete.Tests.CodeFixTests.ToInterpolatedStringTests open Expecto open Helpers @@ -9,7 +9,7 @@ open FsAutoComplete.FCSPatches let langVersion60Config = { defaultConfigDto with - FSIExtraParameters = Some [| "--langversion:6.0" |] } + FSIExtraSharedParameters = Some [| "--langversion:6.0" |] } let tests state = serverTestList (nameof ToInterpolatedString) state langVersion60Config None (fun server -> @@ -356,7 +356,7 @@ let tests state = let langVersion47Config = { defaultConfigDto with - FSIExtraParameters = Some [| "--langversion:4.7" |] } + FSIExtraSharedParameters = Some [| "--langversion:4.7" |] } let unavailableTests state = serverTestList $"unavailable {(nameof ToInterpolatedString)}" state langVersion47Config None (fun server -> diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs index 43b72bd09..496bac520 100644 --- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs +++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs @@ -263,7 +263,8 @@ let defaultConfigDto: FSharpConfigDto = LineLens = None UseSdkScripts = Some true DotNetRoot = None - FSIExtraParameters = None + FSIExtraInteractiveParameters = None + FSIExtraSharedParameters = None FSICompilerToolLocations = None TooltipMode = None GenerateBinlog = Some true diff --git a/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs b/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs index be0553bd5..9b916371c 100644 --- a/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs +++ b/test/FsAutoComplete.Tests.Lsp/ScriptTests.fs @@ -24,7 +24,7 @@ let scriptPreviewTests state = serverInitialize path { defaultConfigDto with - FSIExtraParameters = Some [| "--langversion:preview" |] } + FSIExtraSharedParameters = Some [| "--langversion:preview" |] } state do! waitForWorkspaceFinishedParsing events @@ -81,7 +81,7 @@ let scriptEvictionTests state = { FSharp = Some { defaultConfigDto with - FSIExtraParameters = Some [| "--nowarn:760" |] } } + FSIExtraSharedParameters = Some [| "--nowarn:760" |] } } { Settings = Server.serialize config } @@ -115,7 +115,7 @@ let dependencyManagerTests state = let dependencyManagerEnabledConfig = { defaultConfigDto with - FSIExtraParameters = Some [| "--langversion:preview" |] } + FSIExtraSharedParameters = Some [| "--langversion:preview" |] } let! (server, events) = serverInitialize workingDir dependencyManagerEnabledConfig state do! waitForWorkspaceFinishedParsing events @@ -165,7 +165,7 @@ let scriptProjectOptionsCacheTests state = let previewEnabledConfig = { defaultConfigDto with - FSIExtraParameters = Some [| "--langversion:preview" |] } + FSIExtraSharedParameters = Some [| "--langversion:preview" |] } let! (server, events) = serverInitialize workingDir previewEnabledConfig state let options = ResizeArray() From f9cd5a62ad4f3f81f72d253330ac4a4aa8f272ad Mon Sep 17 00:00:00 2001 From: greggyb Date: Wed, 22 May 2024 21:23:57 -0400 Subject: [PATCH 2/5] fix typo in README: update `FSIExtraParameters` to `FSIExtraSharedParameters` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d579242a6..d851e7506 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ Options that should be send as `initializationOptions` as part of `initialize` r * `FSharp.EnableReferenceCodeLens` - enables reference count code lenses, recommended default value: `true` if `--background-service-enabled` is used by default, `false` otherwise * `FSharp.dotNetRoot` - sets the root path for finding dotnet SDK references. Primarily used for FSX Scripts. Default value: operating-system dependent. On windows, `C:\Program Files\dotnet`; on Unix, `/usr/local/share/dotnet` * `FSharp.fsiExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). -* `FSharp.fsiExtraParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). +* `FSharp.fsiExtraSharedParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). ```json "FSharp.fsiExtraSharedParameters": ["--langversion:preview"] From 2e1ee31b86bd609865d4da5daa6676114ec83f09 Mon Sep 17 00:00:00 2001 From: greggyb Date: Wed, 22 May 2024 21:25:52 -0400 Subject: [PATCH 3/5] fix casing on FSI parameter options --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d851e7506..159b9db9c 100644 --- a/README.md +++ b/README.md @@ -199,8 +199,8 @@ Options that should be send as `initializationOptions` as part of `initialize` r * `FSharp.ResolveNamespaces` - enables resolve namespace quick fix (add `open` if symbol is from not yet opened module/namespace), recommended default value: `true` * `FSharp.EnableReferenceCodeLens` - enables reference count code lenses, recommended default value: `true` if `--background-service-enabled` is used by default, `false` otherwise * `FSharp.dotNetRoot` - sets the root path for finding dotnet SDK references. Primarily used for FSX Scripts. Default value: operating-system dependent. On windows, `C:\Program Files\dotnet`; on Unix, `/usr/local/share/dotnet` -* `FSharp.fsiExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). -* `FSharp.fsiExtraSharedParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). +* `FSharp.FSIExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). +* `FSharp.FSIExtraSharedParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). ```json "FSharp.fsiExtraSharedParameters": ["--langversion:preview"] From 841b44980cf8e5aa0b72c160290cecd8adf50756 Mon Sep 17 00:00:00 2001 From: greggyb Date: Wed, 22 May 2024 21:35:54 -0400 Subject: [PATCH 4/5] fix formatting for build checks --- src/FsAutoComplete/LspHelpers.fs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index f54171a35..b08ff89b2 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -925,7 +925,8 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue Environment.dotnetSDKRoot.Value.FullName - FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters + FSIExtraInteractiveParameters = + defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters FSICompilerToolLocations = defaultArg dto.FSICompilerToolLocations FSharpConfig.Default.FSICompilerToolLocations TooltipMode = defaultArg dto.TooltipMode "full" @@ -1035,7 +1036,8 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue FSharpConfig.Default.DotNetRoot - FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters + FSIExtraInteractiveParameters = + defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters FSICompilerToolLocations = defaultArg dto.FSICompilerToolLocations FSharpConfig.Default.FSICompilerToolLocations TooltipMode = defaultArg dto.TooltipMode x.TooltipMode From 27343a1cfd2ecb42419885a45711a4eb55094764 Mon Sep 17 00:00:00 2001 From: greggyb Date: Wed, 22 May 2024 23:49:44 -0400 Subject: [PATCH 5/5] Preserve old `FSIExtraParameters`; pick reasonable options Bring the old `FSIExtraParameters` option back to not break existing clients. Implement logic to mimic old behavior if the old option is used, warning if the old option is mixed with either of the new. Introduce a new private helper method `AdaptiveFSharpLspServer.oldOrNewExtraParams` for use in RPC calls that parse config options: `Initialize` and `DidChangeConfiguration`. This helper ensures that any clients using the old parameter get the expected behavior from before this PR. Both RPC methods will send a warning to the client if they mix parameters. In the future, we can update warnings to support deprecation in that helper function. The signature of the helper is not the best, and to work with the CEs where the RPC happens, we need to have our message sent at the top level of the CE, so we can use `do!`. This means that we read the Dto, then break our pipeline so we can consume the message, then have a second pipeline that consumes the fixed up Dto. Given that this is in support of a to-be-deprecated option, and that upon deprecation we can remove the helper, it seems okay to have this ugliness. --- README.md | 6 +- src/FsAutoComplete/LspHelpers.fs | 7 +++ src/FsAutoComplete/LspHelpers.fsi | 2 + .../LspServers/AdaptiveFSharpLspServer.fs | 59 ++++++++++++++++++- test/FsAutoComplete.Tests.Lsp/Helpers.fs | 1 + 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 159b9db9c..c8acbd3f8 100644 --- a/README.md +++ b/README.md @@ -199,8 +199,10 @@ Options that should be send as `initializationOptions` as part of `initialize` r * `FSharp.ResolveNamespaces` - enables resolve namespace quick fix (add `open` if symbol is from not yet opened module/namespace), recommended default value: `true` * `FSharp.EnableReferenceCodeLens` - enables reference count code lenses, recommended default value: `true` if `--background-service-enabled` is used by default, `false` otherwise * `FSharp.dotNetRoot` - sets the root path for finding dotnet SDK references. Primarily used for FSX Scripts. Default value: operating-system dependent. On windows, `C:\Program Files\dotnet`; on Unix, `/usr/local/share/dotnet` -* `FSharp.FSIExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). -* `FSharp.FSIExtraSharedParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). +* Extra parameters for FSI: use only `FSharp.FSIExtraParameters` on its own *or* a combination of `FSharp.FSIExtraInteractiveParameters` and `FSharp.FSIExtraSharedParameters`. The former is expected to be deprecated in favor of the second two. See #1210 for more detail. FSAC will send a warning if you mix usage improperly. + * `FSharp.FSIExtraParameters` - an array of additional runtime arguments that are passed to FSI. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. + * `FSharp.FSIExtraInteractiveParameters` - currently unused by FSAC, but available to editor plugins for interactive `dotnet fsi` parameters that are not shared by the compiler. Future intentions are to manage the interpreter from FSAC, at which point FSAC will utilize this parameter. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). + * `FSharp.FSIExtraSharedParameters` - an array of additional runtime arguments that are passed to FSI; specifically parameters that are shared with the compiler. These are used when typechecking scripts to ensure that typechecking has the same context as your FSI instances. An example would be to set the following parameters to enable Preview features (like opening static classes) for typechecking. [Check this reference for parameters that are interactive-only or shared with the compiler](https://learn.microsoft.com/en-us/dotnet/fsharp/language-reference/fsharp-interactive-options). ```json "FSharp.fsiExtraSharedParameters": ["--langversion:preview"] diff --git a/src/FsAutoComplete/LspHelpers.fs b/src/FsAutoComplete/LspHelpers.fs index b08ff89b2..ca71444db 100644 --- a/src/FsAutoComplete/LspHelpers.fs +++ b/src/FsAutoComplete/LspHelpers.fs @@ -673,6 +673,7 @@ type FSharpConfigDto = LineLens: LineLensConfig option UseSdkScripts: bool option DotNetRoot: string option + FSIExtraParameters: string array option FSIExtraInteractiveParameters: string array option FSIExtraSharedParameters: string array option FSICompilerToolLocations: string array option @@ -816,6 +817,9 @@ type FSharpConfig = LineLens: LineLensConfig UseSdkScripts: bool DotNetRoot: string + // old, combines both shared and interactive. To be deprecated. Either use + // only this one, or some combination of the new ones. + FSIExtraParameters: string array // for parameters only used in interactive FSI sessions; currently unused FSIExtraInteractiveParameters: string array // for parameters used both in the compiler and interactive FSI @@ -868,6 +872,7 @@ type FSharpConfig = LineLens = { Enabled = "never"; Prefix = "" } UseSdkScripts = true DotNetRoot = Environment.dotnetSDKRoot.Value.FullName + FSIExtraParameters = [||] FSIExtraInteractiveParameters = [||] FSIExtraSharedParameters = [||] FSICompilerToolLocations = [||] @@ -925,6 +930,7 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue Environment.dotnetSDKRoot.Value.FullName + FSIExtraParameters = defaultArg dto.FSIExtraParameters FSharpConfig.Default.FSIExtraParameters FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters @@ -1036,6 +1042,7 @@ type FSharpConfig = dto.DotNetRoot |> Option.bind (fun s -> if String.IsNullOrEmpty s then None else Some s) |> Option.defaultValue FSharpConfig.Default.DotNetRoot + FSIExtraParameters = defaultArg dto.FSIExtraParameters FSharpConfig.Default.FSIExtraParameters FSIExtraInteractiveParameters = defaultArg dto.FSIExtraInteractiveParameters FSharpConfig.Default.FSIExtraInteractiveParameters FSIExtraSharedParameters = defaultArg dto.FSIExtraSharedParameters FSharpConfig.Default.FSIExtraSharedParameters diff --git a/src/FsAutoComplete/LspHelpers.fsi b/src/FsAutoComplete/LspHelpers.fsi index 05ab6869c..04ab54066 100644 --- a/src/FsAutoComplete/LspHelpers.fsi +++ b/src/FsAutoComplete/LspHelpers.fsi @@ -301,6 +301,7 @@ type FSharpConfigDto = LineLens: LineLensConfig option UseSdkScripts: bool option DotNetRoot: string option + FSIExtraParameters: string array option FSIExtraInteractiveParameters: string array option FSIExtraSharedParameters: string array option FSICompilerToolLocations: string array option @@ -403,6 +404,7 @@ type FSharpConfig = LineLens: LineLensConfig UseSdkScripts: bool DotNetRoot: string + FSIExtraParameters: string array FSIExtraInteractiveParameters: string array FSIExtraSharedParameters: string array FSICompilerToolLocations: string array diff --git a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs index 331aca781..4512998a4 100644 --- a/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs +++ b/src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs @@ -284,6 +284,41 @@ type AdaptiveFSharpLspServer Helpers.ignoreNotification + /// + /// Transform a config DTO to use (old FSIExtraParameters) xor (new FSIExtraInteractiveParameters and FSIExtraSharedParameters). + /// + /// + /// We expect to eventually deprecate FSIExtraParameters in favor of the two + /// new, specialized versions. For now, mimic old behavior either silently + /// or loudly, depending on the client's combination of config options. This + /// method and the consumption of it can be removed after deprecation. + /// + static member private oldOrNewExtraParams(dto: FSharpConfigDto) = + match dto.FSIExtraParameters, dto.FSIExtraInteractiveParameters, dto.FSIExtraSharedParameters with + // old-style, silent success; start warning when we plan to + // deprecate + | Some p, None, None -> + let c = + { dto with + FSIExtraSharedParameters = Some p } + + None, c + // mix old and new, warn and mimic old behavior + | Some p, Some _, _ + | Some p, _, Some _ -> + let m = + { Type = MessageType.Warning + Message = + "Do not mix usage of FSIExtraParameters and (FSIExtraInteractiveParameters or FSIExtraSharedParameters)." } + + let c = + { dto with + FSIExtraSharedParameters = Some p } + + Some m, c + // no old parameter, proceed happily + | None, _, _ -> None, dto + interface IFSharpLspServer with override x.Shutdown() = (x :> System.IDisposable).Dispose() |> async.Return @@ -295,10 +330,19 @@ type AdaptiveFSharpLspServer try logger.info (Log.setMessage "Initialize Request {p}" >> Log.addContextDestructured "p" p) - let c = + let configMessage = p.InitializationOptions |> Option.bind (fun options -> if options.HasValues then Some options else None) |> Option.map Server.deserialize + |> Option.map AdaptiveFSharpLspServer.oldOrNewExtraParams + + match Option.bind fst configMessage with + | Some message -> do! lspClient.WindowShowMessage message + | None -> () + + let c = + configMessage + |> Option.map snd |> Option.map FSharpConfig.FromDto |> Option.defaultValue FSharpConfig.Default @@ -1684,9 +1728,18 @@ type AdaptiveFSharpLspServer >> Log.addContextDestructured "params" p ) - let dto = p.Settings |> Server.deserialize + let dto = + p.Settings + |> Server.deserialize + |> (fun f -> f.FSharp) + |> Option.map AdaptiveFSharpLspServer.oldOrNewExtraParams + + match Option.bind fst dto with + | Some message -> do! lspClient.WindowShowMessage message + | None -> () - dto.FSharp + dto + |> Option.map snd |> Option.iter (fun fsharpConfig -> let c = state.Config let c = c.AddDto fsharpConfig diff --git a/test/FsAutoComplete.Tests.Lsp/Helpers.fs b/test/FsAutoComplete.Tests.Lsp/Helpers.fs index 496bac520..42ed4c770 100644 --- a/test/FsAutoComplete.Tests.Lsp/Helpers.fs +++ b/test/FsAutoComplete.Tests.Lsp/Helpers.fs @@ -263,6 +263,7 @@ let defaultConfigDto: FSharpConfigDto = LineLens = None UseSdkScripts = Some true DotNetRoot = None + FSIExtraParameters = None FSIExtraInteractiveParameters = None FSIExtraSharedParameters = None FSICompilerToolLocations = None