diff --git a/src/Compiler/Driver/CompilerOptions.fs b/src/Compiler/Driver/CompilerOptions.fs index c2e89e7c2c2..7bbecb8916b 100644 --- a/src/Compiler/Driver/CompilerOptions.fs +++ b/src/Compiler/Driver/CompilerOptions.fs @@ -59,7 +59,7 @@ type OptionSpec = | OptionStringList of (string -> unit) | OptionStringListSwitch of (string -> OptionSwitch -> unit) | OptionUnit of (unit -> unit) - | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" + | OptionConsoleOnly of (CompilerOptionBlock list -> unit) | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) and CompilerOption = @@ -95,7 +95,7 @@ let compilerOptionUsage (CompilerOption (s, tag, spec, _, _)) = | OptionUnit _ | OptionSet _ | OptionClear _ - | OptionHelp _ -> sprintf "--%s" s + | OptionConsoleOnly _ -> sprintf "--%s" s | OptionStringList _ -> sprintf "--%s:%s" s tag | OptionIntList _ -> sprintf "--%s:%s" s tag | OptionSwitch _ -> sprintf "--%s[+|-]" s @@ -186,7 +186,7 @@ let dumpCompilerOption prefix (CompilerOption (str, _, spec, _, _)) = | OptionUnit _ -> printf "OptionUnit" | OptionSet _ -> printf "OptionSet" | OptionClear _ -> printf "OptionClear" - | OptionHelp _ -> printf "OptionHelp" + | OptionConsoleOnly _ -> printf "OptionConsoleOnly" | OptionStringList _ -> printf "OptionStringList" | OptionIntList _ -> printf "OptionIntList" | OptionSwitch _ -> printf "OptionSwitch" @@ -347,7 +347,7 @@ let ParseCompilerOptions (collectOtherArgument: string -> unit, blocks: Compiler let rec attempt l = match l with - | CompilerOption (s, _, OptionHelp f, d, _) :: _ when optToken = s && argString = "" -> + | CompilerOption (s, _, OptionConsoleOnly f, d, _) :: _ when optToken = s && argString = "" -> reportDeprecatedOption d f blocks t @@ -1990,13 +1990,13 @@ let displayVersion tcConfigB = let miscFlagsBoth tcConfigB = [ CompilerOption("nologo", tagNone, OptionUnit(fun () -> tcConfigB.showBanner <- false), None, Some(FSComp.SR.optsNologo ())) - CompilerOption("version", tagNone, OptionUnit(fun () -> displayVersion tcConfigB), None, Some(FSComp.SR.optsVersion ())) + CompilerOption("version", tagNone, OptionConsoleOnly(fun _ -> displayVersion tcConfigB), None, Some(FSComp.SR.optsVersion ())) ] let miscFlagsFsc tcConfigB = miscFlagsBoth tcConfigB @ [ - CompilerOption("help", tagNone, OptionHelp(fun blocks -> displayHelpFsc tcConfigB blocks), None, Some(FSComp.SR.optsHelp ())) + CompilerOption("help", tagNone, OptionConsoleOnly(fun blocks -> displayHelpFsc tcConfigB blocks), None, Some(FSComp.SR.optsHelp ())) CompilerOption("@", tagNone, OptionUnit ignore, None, Some(FSComp.SR.optsResponseFile ())) ] @@ -2052,7 +2052,7 @@ let abbreviatedFlagsFsc tcConfigB = CompilerOption( "?", tagNone, - OptionHelp(fun blocks -> displayHelpFsc tcConfigB blocks), + OptionConsoleOnly(fun blocks -> displayHelpFsc tcConfigB blocks), None, Some(FSComp.SR.optsShortFormOf ("--help")) ) @@ -2060,7 +2060,7 @@ let abbreviatedFlagsFsc tcConfigB = CompilerOption( "help", tagNone, - OptionHelp(fun blocks -> displayHelpFsc tcConfigB blocks), + OptionConsoleOnly(fun blocks -> displayHelpFsc tcConfigB blocks), None, Some(FSComp.SR.optsShortFormOf ("--help")) ) @@ -2068,7 +2068,7 @@ let abbreviatedFlagsFsc tcConfigB = CompilerOption( "full-help", tagNone, - OptionHelp(fun blocks -> displayHelpFsc tcConfigB blocks), + OptionConsoleOnly(fun blocks -> displayHelpFsc tcConfigB blocks), None, Some(FSComp.SR.optsShortFormOf ("--help")) ) @@ -2110,7 +2110,7 @@ let PostProcessCompilerArgs (abbrevArgs: string Set) (args: string[]) = let testingAndQAFlags _tcConfigB = [ - CompilerOption("dumpAllCommandLineOptions", tagNone, OptionHelp(fun blocks -> DumpCompilerOptionBlocks blocks), None, None) // "Command line options") + CompilerOption("dumpAllCommandLineOptions", tagNone, OptionConsoleOnly(fun blocks -> DumpCompilerOptionBlocks blocks), None, None) // "Command line options") ] // Core compiler options, overview @@ -2168,14 +2168,14 @@ let GetCoreFscCompilerOptions (tcConfigB: TcConfigBuilder) = ] /// The core/common options used by the F# VS Language Service. -/// Filter out OptionHelp which does printing then exit. This is not wanted in the context of VS!! +/// Filter out OptionConsoleOnly which do printing then exit (e.g --help or --version). This is not wanted in the context of VS! let GetCoreServiceCompilerOptions (tcConfigB: TcConfigBuilder) = - let isHelpOption = + let isConsoleOnlyOption = function - | CompilerOption (_, _, OptionHelp _, _, _) -> true + | CompilerOption (_, _, OptionConsoleOnly _, _, _) -> true | _ -> false - List.map (FilterCompilerOptionBlock(isHelpOption >> not)) (GetCoreFscCompilerOptions tcConfigB) + List.map (FilterCompilerOptionBlock(isConsoleOnlyOption >> not)) (GetCoreFscCompilerOptions tcConfigB) /// The core/common options used by fsi.exe. [note, some additional options are added in fsi.fs]. let GetCoreFsiCompilerOptions (tcConfigB: TcConfigBuilder) = diff --git a/src/Compiler/Driver/CompilerOptions.fsi b/src/Compiler/Driver/CompilerOptions.fsi index e5951fa66e8..983a38f5182 100644 --- a/src/Compiler/Driver/CompilerOptions.fsi +++ b/src/Compiler/Driver/CompilerOptions.fsi @@ -28,7 +28,7 @@ type OptionSpec = | OptionStringList of (string -> unit) | OptionStringListSwitch of (string -> OptionSwitch -> unit) | OptionUnit of (unit -> unit) - | OptionHelp of (CompilerOptionBlock list -> unit) // like OptionUnit, but given the "options" + | OptionConsoleOnly of (CompilerOptionBlock list -> unit) | OptionGeneral of (string list -> bool) * (string list -> string list) // Applies? * (ApplyReturningResidualArgs) and CompilerOption = diff --git a/src/Compiler/Interactive/fsi.fs b/src/Compiler/Interactive/fsi.fs index 08453ef34bb..32a8ad40592 100644 --- a/src/Compiler/Interactive/fsi.fs +++ b/src/Compiler/Interactive/fsi.fs @@ -948,12 +948,12 @@ type internal FsiCommandLineOptions(fsi: FsiEvaluationSessionHostConfig, ]); PublicOptions(FSComp.SR.optsHelpBannerMisc(), [ CompilerOption("help", tagNone, - OptionHelp (displayHelpFsi tcConfigB), None, Some (FSIstrings.SR.fsiHelp())) + OptionConsoleOnly (displayHelpFsi tcConfigB), None, Some (FSIstrings.SR.fsiHelp())) ]); PrivateOptions( - [ CompilerOption("?", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); - CompilerOption("help", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); - CompilerOption("full-help", tagNone, OptionHelp (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); + [ CompilerOption("?", tagNone, OptionConsoleOnly (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); + CompilerOption("help", tagNone, OptionConsoleOnly (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); + CompilerOption("full-help", tagNone, OptionConsoleOnly (displayHelpFsi tcConfigB), None, None); // "Short form of --help"); ]); PublicOptions(FSComp.SR.optsHelpBannerAdvanced(), [CompilerOption("exec", "", OptionUnit (fun () -> interact <- false), None, Some (FSIstrings.SR.fsiExec())) diff --git a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj index 743c0da36fa..491a5e9afa0 100644 --- a/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj +++ b/tests/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj @@ -38,6 +38,7 @@ Symbols.fs + SyntaxTree\TypeTests.fs diff --git a/tests/FSharp.Compiler.Service.Tests/VisualStudioVersusConsoleContextTests.fs b/tests/FSharp.Compiler.Service.Tests/VisualStudioVersusConsoleContextTests.fs new file mode 100644 index 00000000000..9d37644e892 --- /dev/null +++ b/tests/FSharp.Compiler.Service.Tests/VisualStudioVersusConsoleContextTests.fs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +module FSharp.Compiler.Service.Tests.VisualStudioVersusConsoleContextTests + +open FSharp.Compiler.Text +open NUnit.Framework +open System.IO +open FSharp.Compiler.CompilerConfig +open FSharp.Compiler.CompilerOptions +open Internal.Utilities +open FSharp.Compiler.AbstractIL.ILBinaryReader + +// copypasted from the CompilerOptions code, +// not worth changing that code's accessibility just for this test +let private getOptionsFromOptionBlocks blocks = + let GetOptionsOfBlock block = + match block with + | PublicOptions (_, opts) -> opts + | PrivateOptions opts -> opts + + List.collect GetOptionsOfBlock blocks + +[] // controls https://github.com/dotnet/fsharp/issues/13549 +let ``Console-only options are filtered out for fsc in the VS context`` () = + // just a random thing to make things work + let builder = TcConfigBuilder.CreateNew( + null, + FSharpEnvironment.BinFolderOfDefaultFSharpCompiler(None).Value, + ReduceMemoryFlag.Yes, + Directory.GetCurrentDirectory(), + false, + false, + CopyFSharpCoreFlag.No, + (fun _ -> None), + None, + Range.Zero) + + let blocks = GetCoreServiceCompilerOptions builder + let options = getOptionsFromOptionBlocks blocks + + // this is a very whitebox testing but arguably better than nothing + Assert.IsFalse( + options + |> List.exists (function + | CompilerOption (_, _, OptionConsoleOnly _, _, _) -> true + | _ -> false)) + + // and a couple of shots in the dark + Assert.False( + options + |> List.exists (function + // ignore deprecated options + // one of them actually allows specifying the compiler version + | CompilerOption (name, _, _, None, _) -> name = "version" + | _ -> false)) + + Assert.False( + options + |> List.exists (function + | CompilerOption (name, _, _, _, _) -> name = "help")) diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs index 23432c4bb50..7b2bcd451e1 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fs @@ -32,7 +32,7 @@ //section='- LANGUAGE - ' ! option=define kind=OptionString //section='- LANGUAGE - ' ! option=mlcompatibility kind=OptionUnit //section='- MISCELLANEOUS - ' ! option=nologo kind=OptionUnit -//section='- MISCELLANEOUS - ' ! option=help kind=OptionHelp +//section='- MISCELLANEOUS - ' ! option=help kind=OptionConsoleOnly //section='- ADVANCED - ' ! option=codepage kind=OptionInt //section='- ADVANCED - ' ! option=utf8output kind=OptionUnit //section='- ADVANCED - ' ! option=fullpaths kind=OptionUnit @@ -99,9 +99,8 @@ //section='NoSection ' ! option=I kind=OptionStringList //section='NoSection ' ! option=o kind=OptionString //section='NoSection ' ! option=a kind=OptionUnit -//section='NoSection ' ! option=\? kind=OptionHelp -//section='NoSection ' ! option=help kind=OptionHelp -//section='NoSection ' ! option=full-help kind=OptionHelp +//section='NoSection ' ! option=help kind=OptionConsoleOnly +//section='NoSection ' ! option=full-help kind=OptionConsoleOnly //section='NoSection ' ! option=light kind=OptionUnit //section='NoSection ' ! option=indentation-syntax kind=OptionUnit //section='NoSection ' ! option=no-indentation-syntax kind=OptionUnit @@ -114,7 +113,6 @@ //section='NoSection ' ! option=compiling-fslib kind=OptionUnit //section='NoSection ' ! option=compiling-fslib-20 kind=OptionString //section='NoSection ' ! option=compiling-fslib-40 kind=OptionUnit -//section='NoSection ' ! option=version kind=OptionString //section='NoSection ' ! option=local-optimize kind=OptionUnit //section='NoSection ' ! option=no-local-optimize kind=OptionUnit //section='NoSection ' ! option=cross-optimize kind=OptionUnit @@ -130,7 +128,7 @@ //section='NoSection ' ! option=Ooff kind=OptionUnit //section='NoSection ' ! option=ml-keywords kind=OptionUnit //section='NoSection ' ! option=gnu-style-errors kind=OptionUnit -//section='NoSection ' ! option=dumpAllCommandLineOptions kind=OptionHelp +//section='NoSection ' ! option=dumpAllCommandLineOptions kind=OptionConsoleOnly // The following ones are for FSI.EXE only diff --git a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx index 7d9f0b0f5c0..2f22ee0d2a0 100644 --- a/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx +++ b/tests/fsharpqa/Source/CompilerOptions/fsc/dumpAllCommandLineOptions/dummy.fsx @@ -85,12 +85,11 @@ //section='NoSection ' ! option=light kind=OptionUnit //section='NoSection ' ! option=indentation-syntax kind=OptionUnit //section='NoSection ' ! option=no-indentation-syntax kind=OptionUnit -//section='NoSection ' ! option=dumpAllCommandLineOptions kind=OptionHelp +//section='NoSection ' ! option=dumpAllCommandLineOptions kind=OptionConsoleOnly //section='- INPUT FILES - ' ! option=-- kind=OptionRest -//section='- MISCELLANEOUS - ' ! option=help kind=OptionHelp -//section='NoSection ' ! option=\? kind=OptionHelp -//section='NoSection ' ! option=help kind=OptionHelp -//section='NoSection ' ! option=full-help kind=OptionHelp +//section='- MISCELLANEOUS - ' ! option=help kind=OptionConsoleOnly +//section='NoSection ' ! option=help kind=OptionConsoleOnly +//section='NoSection ' ! option=full-help kind=OptionConsoleOnly //section='- ADVANCED - ' ! option=exec kind=OptionUnit //section='- ADVANCED - ' ! option=gui kind=OptionSwitch //section='- ADVANCED - ' ! option=quiet kind=OptionUnit @@ -137,6 +136,8 @@ //section='NoSection ' ! option=no-jit-tracking kind=OptionUnit //section='NoSection ' ! option=progress kind=OptionUnit //section='NoSection ' ! option=compiling-fslib kind=OptionUnit +//section='NoSection ' ! option=compiling-fslib-20 kind=OptionString +//section='NoSection ' ! option=version kind=OptionConsoleOnly //section='NoSection ' ! option=compiling-fslib-20 kind=OptionString //section='NoSection ' ! option=version kind=OptionString //section='NoSection ' ! option=local-optimize kind=OptionUnit