Fix preferreduilang switch leaking into fsi.CommandLineArgs
Description
The --preferreduilang and /preferreduilang switches were appearing in fsi.CommandLineArgs when positioned after the script file, breaking script argument contracts and causing MSBuild-invoked FSI sessions to leak implementation details.
Changes
Core Implementation (src/Compiler/Interactive/fsi.fs)
- Modified script argument handler to filter and consume
preferreduilangswitches regardless of position - Extracts culture value, sets
tcConfigB.preferredUiLangandThread.CurrentThread.CurrentUICulture - Validates argument format and handles invalid cultures gracefully with specific exception catching
Tests (tests/FSharp.Compiler.ComponentTests/Scripting/PreferredUiLangTests.fs)
- Added 6 regression tests covering switch positions (before/after script), both forms (
--//), culture application, and error handling
Example
// Before: switch leaked into CommandLineArgs
// dotnet fsi script.fsx --preferreduilang:es-ES arg1
// fsi.CommandLineArgs = ["script.fsx"; "--preferreduilang:es-ES"; "arg1"]
// After: switch consumed, culture set
// dotnet fsi script.fsx --preferreduilang:es-ES arg1
// fsi.CommandLineArgs = ["script.fsx"; "arg1"]
// Thread.CurrentThread.CurrentUICulture.Name = "es-ES"
Checklist
- [x] Test cases added
- [ ] Performance benchmarks added in case of performance changes
- [x] Release notes entry updated
Original prompt
Implement proper handling of the
preferreduilangswitch in FSI and add regression tests.Scope:
Consume and apply
--preferreduilang//preferreduilangin FSI option parsing so it does not surface infsi.CommandLineArgs, and set localization accordingly.
- Add a recognized option in
src/Compiler/Interactive/fsi.fs(option table nearOptionGeneral("script.fsx arg1 arg2 ...")).- Support both
/preferreduilang:<culture>and--preferreduilang:<culture>.- On parse: set
tcConfigB.lcidandThread.CurrentThread.CurrentUICulture(and possiblyCurrentCulture) to the parsed culture; if parsing fails, warn and ignore.- Ensure this happens before
ReportUserCommandLineArgsso the switch is consumed and not forwarded to scripts.Add tests for argument separation and localization.
- CLI regression tests (new folder
tests/fsharp/core/interactive-args/or extend existingtests/fsharpqa/Source/InteractiveSession/Misc/CommandLineArgs01*.fs): a)dotnet fsi --preferreduilang:en-US --exec script.fsx a→fsi.CommandLineArgs = ["script.fsx"; "a"](switch consumed). b)dotnet fsi script.fsx --preferreduilang:en-US a→fsi.CommandLineArgs = ["script.fsx"; "a"](even after script). c) Localization:dotnet fsi --preferreduilang:es-ES --exec script.fsxwhere the script triggers a warning/error; assert the culture is set (CurrentUICulture.Namestarts withes-ES) and the message is localized or falls back if resources are missing. Consider a second locale (e.g., fr-FR).MSBuild-path regression test.
- Add a sample project under
tests/projects/FSI/PreferreduilangRepro/that runs a script printingfsi.CommandLineArgsandCurrentUICulture.Name.- Invoke via
dotnet msbuild(or existing VS integration harness) so the ToolTask-injected/preferreduilangis present.- Assert the switch is not in
CommandLineArgsand the culture is applied.Notes/guardrails:
- Do not leak
preferreduilangintoexplicitArgs/CommandLineArgsregardless of position relative to the script token.- If culture parsing fails, warn but do not treat it as a script arg.
- Keep behavior consistent between CLI and MSBuild paths.
References:
- Option parsing & script arg handling:
src/Compiler/Interactive/fsi.fs(option table around ~1053–1108; finalReportUserCommandLineArgsaround ~1208–1222).- Public contract for
fsi.CommandLineArgs:src/Compiler/Interactive/fsi.fsi(~397–412).- MSBuild host that may inject
/preferreduilang:src/FSharp.Build/Fsi.fs(ToolTask; captured args around ~421–424).
This pull request was created as a result of the following prompt from Copilot chat.
Implement proper handling of the
preferreduilangswitch in FSI and add regression tests.Scope:
Consume and apply
--preferreduilang//preferreduilangin FSI option parsing so it does not surface infsi.CommandLineArgs, and set localization accordingly.
- Add a recognized option in
src/Compiler/Interactive/fsi.fs(option table nearOptionGeneral("script.fsx arg1 arg2 ...")).- Support both
/preferreduilang:<culture>and--preferreduilang:<culture>.- On parse: set
tcConfigB.lcidandThread.CurrentThread.CurrentUICulture(and possiblyCurrentCulture) to the parsed culture; if parsing fails, warn and ignore.- Ensure this happens before
ReportUserCommandLineArgsso the switch is consumed and not forwarded to scripts.Add tests for argument separation and localization.
- CLI regression tests (new folder
tests/fsharp/core/interactive-args/or extend existingtests/fsharpqa/Source/InteractiveSession/Misc/CommandLineArgs01*.fs): a)dotnet fsi --preferreduilang:en-US --exec script.fsx a→fsi.CommandLineArgs = ["script.fsx"; "a"](switch consumed). b)dotnet fsi script.fsx --preferreduilang:en-US a→fsi.CommandLineArgs = ["script.fsx"; "a"](even after script). c) Localization:dotnet fsi --preferreduilang:es-ES --exec script.fsxwhere the script triggers a warning/error; assert the culture is set (CurrentUICulture.Namestarts withes-ES) and the message is localized or falls back if resources are missing. Consider a second locale (e.g., fr-FR).MSBuild-path regression test.
- Add a sample project under
tests/projects/FSI/PreferreduilangRepro/that runs a script printingfsi.CommandLineArgsandCurrentUICulture.Name.- Invoke via
dotnet msbuild(or existing VS integration harness) so the ToolTask-injected/preferreduilangis present.- Assert the switch is not in
CommandLineArgsand the culture is applied.Notes/guardrails:
- Do not leak
preferreduilangintoexplicitArgs/CommandLineArgsregardless of position relative to the script token.- If culture parsing fails, warn but do not treat it as a script arg.
- Keep behavior consistent between CLI and MSBuild paths.
References:
- Option parsing & script arg handling:
src/Compiler/Interactive/fsi.fs(option table around ~1053–1108; finalReportUserCommandLineArgsaround ~1208–1222).- Public contract for
fsi.CommandLineArgs:src/Compiler/Interactive/fsi.fsi(~397–412).- MSBuild host that may inject
/preferreduilang:src/FSharp.Build/Fsi.fs(ToolTask; captured args around ~421–424).
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.