From 5243bd6797ec4b528a45625e5bea186295802741 Mon Sep 17 00:00:00 2001 From: Julien Couvreur Date: Fri, 16 Jun 2017 20:39:54 -0700 Subject: [PATCH] List supported language versions (#20153) --- docs/compilers/CSharp/CommandLine.md | 3 +- docs/compilers/Visual Basic/CommandLine.md | 3 +- .../Portable/CSharpResources.Designer.cs | 11 +++- .../CSharp/Portable/CSharpResources.resx | 12 +++-- .../CommandLine/CSharpCommandLineParser.cs | 6 +++ .../Portable/CommandLine/CSharpCompiler.cs | 22 ++++++++ .../CSharp/Portable/Errors/MessageID.cs | 1 + .../Test/CommandLine/CommandLineTests.cs | 53 ++++++++++++------- .../CommandLine/CommonCommandLineArguments.cs | 6 +++ .../Portable/CommandLine/CommonCompiler.cs | 7 +++ .../Core/Portable/PublicAPI.Unshipped.txt | 1 + .../VisualBasicCommandLineParser.vb | 9 ++-- .../CommandLine/VisualBasicCompiler.vb | 16 ++++++ .../VisualBasic/Portable/Errors/Errors.vb | 2 +- .../Portable/VBResources.Designer.vb | 11 +++- .../VisualBasic/Portable/VBResources.resx | 11 ++-- .../Test/CommandLine/CommandLineTests.vb | 26 ++++----- 17 files changed, 151 insertions(+), 49 deletions(-) diff --git a/docs/compilers/CSharp/CommandLine.md b/docs/compilers/CSharp/CommandLine.md index 83d77bd2be7..354bdfed8b3 100644 --- a/docs/compilers/CSharp/CommandLine.md +++ b/docs/compilers/CSharp/CommandLine.md @@ -50,7 +50,8 @@ | `/checked`{`+`|`-`} | Generate overflow checks | `/unsafe`{`+`|`-`} | Allow 'unsafe' code | `/define:`*symbol list* | Define conditional compilation symbol(s) (Short form: `/d`) -| `/langversion`:*string* | Specify language version mode: `ISO-1`, `ISO-2`, `3`, `4`, `5`, `6`, `7`, `7.1`, `7.2`, `Default` (latest major version), or `Latest` (latest version, including minor versions) +| `/langversion:?` | Display the allowed values for language version +| `/langversion`:*string* | Specify language version such as `default` (latest major version), or `latest` (latest version, including minor versions) | **SECURITY** | `/delaysign`{`+`|`-`} | Delay-sign the assembly using only the public portion of the strong name key | `/keyfile:`*file* | Specify a strong name key file diff --git a/docs/compilers/Visual Basic/CommandLine.md b/docs/compilers/Visual Basic/CommandLine.md index 04a90adc833..0a195967613 100644 --- a/docs/compilers/Visual Basic/CommandLine.md +++ b/docs/compilers/Visual Basic/CommandLine.md @@ -52,7 +52,8 @@ | **LANGUAGE** | `/define:`*symbol_list* | Declare global conditional compilation symbol(s). *symbol_list* is *name*`=`*value*`,`... (Short form: `/d`) | `/imports:`*import_list* | Declare global Imports for namespaces in referenced metadata files. *import_list* is *namespace*`,`... -| `/langversion:`*number* | Specify language version: `9`|`9.0`|`10`|`10.0`|`11`|`11.0`|`12`|`12.0`|`13`|`13.0`|`14`|`14.0`|`15`|`15.0`|`15.3`|`15.6`. The default is `15` and the latest is `15.6`. +| `/langversion:?` | Display the allowed values for language version +| `/langversion`:*string* | Specify language version such as `default` (latest major version), or `latest` (latest version, including minor versions) | `/optionexplicit`{`+`|`-`} | Require explicit declaration of variables. | `/optioninfer`{`+`|`-`} | Allow type inference of variables. | `/rootnamespace`:*string* | Specifies the root Namespace for all top-level type declarations. diff --git a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs index 64d26b535d5..37095317bf9 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs +++ b/src/Compilers/CSharp/Portable/CSharpResources.Designer.cs @@ -1241,7 +1241,7 @@ internal class CSharpResources { } /// - /// Looks up a localized string similar to Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.2.. + /// Looks up a localized string similar to Invalid option '{0}' for /langversion. Use '/langversion:?' to list supported values.. /// internal static string ERR_BadCompatMode { get { @@ -10457,6 +10457,15 @@ internal class CSharpResources { } } + /// + /// Looks up a localized string similar to Supported language versions:. + /// + internal static string IDS_LangVersions { + get { + return ResourceManager.GetString("IDS_LangVersions", resourceCulture); + } + } + /// /// Looks up a localized string similar to LIB environment variable. /// diff --git a/src/Compilers/CSharp/Portable/CSharpResources.resx b/src/Compilers/CSharp/Portable/CSharpResources.resx index 565cd44db52..6d04f774f26 100644 --- a/src/Compilers/CSharp/Portable/CSharpResources.resx +++ b/src/Compilers/CSharp/Portable/CSharpResources.resx @@ -2711,7 +2711,7 @@ A catch() block after a catch (System.Exception e) block can catch non-CLS excep This warning occurs if the assembly attributes AssemblyKeyFileAttribute or AssemblyKeyNameAttribute found in source conflict with the /keyfile or /keycontainer command line option or key file name or key container specified in the Project Properties. - Invalid option '{0}' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.2. + Invalid option '{0}' for /langversion. Use '/langversion:?' to list supported values. Cannot create delegate with '{0}' because it or a method it overrides has a Conditional attribute @@ -4392,6 +4392,9 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ Copyright (C) Microsoft Corporation. All rights reserved. + + Supported language versions: + Visual C# Compiler Options @@ -4477,8 +4480,11 @@ To remove the warning, you can use /reference instead (set the Embed Interop Typ /unsafe[+|-] Allow 'unsafe' code /define:<symbol list> Define conditional compilation symbol(s) (Short form: /d) - /langversion:<string> Specify language version mode: ISO-1, ISO-2, 3, - 4, 5, 6, 7.0, 7.1, 7.2, Default, or Latest + /langversion:? Display the allowed values for language version + /langversion:<string> Specify language version such as + `default` (latest major version), or + `latest` (latest version, including minor versions), + or specific versions like `6` or `7.1` - SECURITY - /delaysign[+|-] Delay-sign the assembly using only the public diff --git a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs index 0b4fff47f65..d38c407c847 100644 --- a/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs +++ b/src/Compilers/CSharp/Portable/CommandLine/CSharpCommandLineParser.cs @@ -55,6 +55,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable args, string bas bool displayLogo = true; bool displayHelp = false; bool displayVersion = false; + bool displayLangVersions = false; bool optimize = false; bool checkOverflow = false; bool allowUnsafe = false; @@ -837,6 +838,10 @@ public new CSharpCommandLineArguments Parse(IEnumerable args, string bas // treat them as identifiers (behaviour in native compiler). This error helps users identify that breaking change. AddDiagnostic(diagnostics, ErrorCode.ERR_LanguageVersionCannotHaveLeadingZeroes, value); } + else if (value == "?") + { + displayLangVersions = true; + } else if (!value.TryParse(out languageVersion)) { AddDiagnostic(diagnostics, ErrorCode.ERR_BadCompatMode, value); @@ -1347,6 +1352,7 @@ public new CSharpCommandLineArguments Parse(IEnumerable args, string bas DisplayLogo = displayLogo, DisplayHelp = displayHelp, DisplayVersion = displayVersion, + DisplayLangVersions = displayLangVersions, ManifestResources = managedResources.AsImmutable(), CompilationOptions = options, ParseOptions = parseOptions, diff --git a/src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs b/src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs index 8db22234c09..c8bfdfb187f 100644 --- a/src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs +++ b/src/Compilers/CSharp/Portable/CommandLine/CSharpCompiler.cs @@ -267,6 +267,28 @@ public override void PrintLogo(TextWriter consoleOutput) consoleOutput.WriteLine(); } + public override void PrintLangVersions(TextWriter consoleOutput) + { + consoleOutput.WriteLine(ErrorFacts.GetMessage(MessageID.IDS_LangVersions, Culture)); + var defaultVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion(); + var latestVersion = LanguageVersion.Latest.MapSpecifiedToEffectiveVersion(); + foreach (LanguageVersion v in Enum.GetValues(typeof(LanguageVersion))) + { + if (v == defaultVersion) + { + consoleOutput.WriteLine($"{v.ToDisplayString()} (default)"); + } + else if (v == latestVersion) + { + consoleOutput.WriteLine($"{v.ToDisplayString()} (latest)"); + } + else + { + consoleOutput.WriteLine(v.ToDisplayString()); + } + } + consoleOutput.WriteLine(); + } internal override Type Type { diff --git a/src/Compilers/CSharp/Portable/Errors/MessageID.cs b/src/Compilers/CSharp/Portable/Errors/MessageID.cs index fc13210b8b1..76b4586312f 100644 --- a/src/Compilers/CSharp/Portable/Errors/MessageID.cs +++ b/src/Compilers/CSharp/Portable/Errors/MessageID.cs @@ -131,6 +131,7 @@ internal enum MessageID IDS_FeatureInferredTupleNames = MessageBase + 12719, IDS_FeatureGenericPatternMatching = MessageBase + 12720, IDS_FeatureAsyncMain = MessageBase + 12721, + IDS_LangVersions = MessageBase + 12722, } // Message IDs may refer to strings that need to be localized. diff --git a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 8764f4d7e3e..e0958249e6d 100644 --- a/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -1110,6 +1110,12 @@ public void ArgumentParsing() Assert.True(parsedArgs.DisplayVersion); Assert.False(parsedArgs.SourceFiles.Any()); + parsedArgs = CSharpCommandLineParser.ScriptRunner.Parse(new[] { "/langversion:?" }, _baseDirectory, s_defaultSdkDirectory); + parsedArgs.Errors.Verify( + // error CS2007: Unrecognized option: '/langversion:?' + Diagnostic(ErrorCode.ERR_BadSwitch).WithArguments("/langversion:?").WithLocation(1, 1) + ); + parsedArgs = CSharpCommandLineParser.ScriptRunner.Parse(new[] { "/version", "c.csx" }, _baseDirectory, s_defaultSdkDirectory); parsedArgs.Errors.Verify(); Assert.True(parsedArgs.DisplayVersion); @@ -1268,8 +1274,9 @@ public void LangVersion_NoValueSpecified() public void LangVersion_BadVersion(string value) { DefaultParse(new[] { $"/langversion:{value}", "a.cs" }, _baseDirectory).Errors.Verify( - // error CS1617: Invalid option 'XXX' for /langversion; must be ISO-1, ISO-2, Default, Latest or a valid version in range 1 to 7.1. - Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments(value).WithLocation(1, 1)); + // error CS1617: Invalid option 'XXX' for /langversion. Use '/langversion:?' to list supported values. + Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments(value).WithLocation(1, 1) + ); } [Theory] @@ -1295,6 +1302,19 @@ public void LangVersion_NoVersion(string option) Diagnostic(ErrorCode.ERR_SwitchNeedsString).WithArguments("", "/langversion:").WithLocation(1, 1)); } + [Fact] + public void LangVersion_LangVersions() + { + var args = DefaultParse(new[] { "/langversion:?" }, _baseDirectory); + args.Errors.Verify( + // warning CS2008: No source files specified. + Diagnostic(ErrorCode.WRN_NoSources).WithLocation(1, 1), + // error CS1562: Outputs without source must have the /out option specified + Diagnostic(ErrorCode.ERR_OutputNeedsName).WithLocation(1, 1) + ); + Assert.True(args.DisplayLangVersions); + } + [Fact] public void LanguageVersionAdded_Canary() { @@ -1392,29 +1412,26 @@ public void LanguageVersion_TryParseDisplayString(string input, bool success, La } [Fact] - public void LanguageVersion_CommandLineUsage() + public void LangVersion_ListLangVersions() { + var dir = Temp.CreateDirectory(); + var outWriter = new StringWriter(CultureInfo.InvariantCulture); + var csc = new MockCSharpCompiler(null, dir.Path, new[] { "/langversion:?" }); + int exitCode = csc.Run(outWriter); + Assert.Equal(0, exitCode); + var expected = Enum.GetValues(typeof(LanguageVersion)).Cast() - .Where(v => v != LanguageVersion.CSharp1 && v != LanguageVersion.CSharp2) .Select(v => v.ToDisplayString()); - string help = CSharpResources.IDS_CSCHelp; - - var rangeStart = help.IndexOf("/langversion"); - var rangeEnd = help.IndexOf("/delaysign"); - Assert.True(rangeEnd > rangeStart); - string helpRange = help.Substring(rangeStart, rangeEnd - rangeStart).ToLowerInvariant(); - var acceptableSurroundingChar = new[] { '\r', '\n', ',' , ' '}; + var actual = outWriter.ToString(); + var acceptableSurroundingChar = new[] { '\r', '\n', '(' , ')', ' '}; foreach (var version in expected) { - var foundIndex = helpRange.IndexOf(version); + var foundIndex = actual.IndexOf(version); Assert.True(foundIndex > 0, $"Missing version '{version}'"); - Assert.True(Array.IndexOf(acceptableSurroundingChar, helpRange[foundIndex - 1]) >= 0); - Assert.True(Array.IndexOf(acceptableSurroundingChar, helpRange[foundIndex + version.Length]) >= 0); + Assert.True(Array.IndexOf(acceptableSurroundingChar, actual[foundIndex - 1]) >= 0); + Assert.True(Array.IndexOf(acceptableSurroundingChar, actual[foundIndex + version.Length]) >= 0); } - - // The canary check is a reminder that this test needs to be updated when a language version is added - LanguageVersionAdded_Canary(); } [Fact] @@ -9369,7 +9386,7 @@ public void CompilingCodeWithInvalidLanguageVersionShouldProvideDiagnostics() { var parsedArgs = DefaultParse(new[] { "/langversion:1000", "a.cs" }, _baseDirectory); parsedArgs.Errors.Verify( - // error CS1617: Invalid option '1000' for /langversion; must be ISO-1, ISO-2, Default or an integer in range 1 to 6. + // error CS1617: Invalid option '1000' for /langversion. Use '/langversion:?' to list supported values. Diagnostic(ErrorCode.ERR_BadCompatMode).WithArguments("1000").WithLocation(1, 1)); } diff --git a/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs b/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs index c21420500df..a9c6cc861c9 100644 --- a/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs +++ b/src/Compilers/Core/Portable/CommandLine/CommonCommandLineArguments.cs @@ -183,6 +183,12 @@ public abstract class CommandLineArguments /// public bool DisplayVersion { get; internal set; } + /// + /// If true, prepend the compiler-supported language versions during + /// + /// + public bool DisplayLangVersions { get; internal set; } + /// /// The path to a Win32 resource. /// diff --git a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs index ea344207b1e..65cb80dc79a 100644 --- a/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs +++ b/src/Compilers/Core/Portable/CommandLine/CommonCompiler.cs @@ -78,6 +78,7 @@ internal abstract partial class CommonCompiler public abstract Compilation CreateCompilation(TextWriter consoleOutput, TouchedFileLogger touchedFilesLogger, ErrorLogger errorLoggerOpt); public abstract void PrintLogo(TextWriter consoleOutput); public abstract void PrintHelp(TextWriter consoleOutput); + public abstract void PrintLangVersions(TextWriter consoleOutput); /// /// Print compiler version @@ -520,6 +521,12 @@ private int RunCore(TextWriter consoleOutput, ErrorLogger errorLogger, Cancellat return Succeeded; } + if (Arguments.DisplayLangVersions) + { + PrintLangVersions(consoleOutput); + return Succeeded; + } + if (Arguments.DisplayLogo) { PrintLogo(consoleOutput); diff --git a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt index 22ed4041a45..b5228099788 100644 --- a/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt +++ b/src/Compilers/Core/Portable/PublicAPI.Unshipped.txt @@ -913,3 +913,4 @@ virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.Vi virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitWhileUntilLoopStatement(Microsoft.CodeAnalysis.Semantics.IWhileUntilLoopStatement operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitWithStatement(Microsoft.CodeAnalysis.Semantics.IWithStatement operation, TArgument argument) -> TResult virtual Microsoft.CodeAnalysis.Semantics.OperationVisitor.VisitYieldBreakStatement(Microsoft.CodeAnalysis.Semantics.IReturnStatement operation, TArgument argument) -> TResult +Microsoft.CodeAnalysis.CommandLineArguments.DisplayLangVersions.get -> bool diff --git a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb index 3008914600b..6fa83114af9 100644 --- a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb +++ b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCommandLineParser.vb @@ -87,6 +87,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Dim displayLogo As Boolean = True Dim displayHelp As Boolean = False Dim displayVersion As Boolean = False + Dim displayLangVersions As Boolean = False Dim outputLevel As OutputLevel = OutputLevel.Normal Dim optimize As Boolean = False Dim checkOverflow As Boolean = True @@ -822,13 +823,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Case "langversion" value = RemoveQuotesAndSlashes(value) - If value Is Nothing Then - AddDiagnostic(diagnostics, ERRID.ERR_ArgumentRequired, "langversion", ":") - Continue For - End If - If String.IsNullOrEmpty(value) Then AddDiagnostic(diagnostics, ERRID.ERR_ArgumentRequired, "langversion", ":") + ElseIf value = "?" Then + displayLangVersions = True Else If Not value.TryParse(languageVersion) Then AddDiagnostic(diagnostics, ERRID.ERR_InvalidSwitchValue, "langversion", value) @@ -1408,6 +1406,7 @@ lVbRuntimePlus: .DisplayLogo = displayLogo, .DisplayHelp = displayHelp, .DisplayVersion = displayVersion, + .DisplayLangVersions = displayLangVersions, .ManifestResources = managedResources.AsImmutable(), .CompilationOptions = options, .ParseOptions = parseOptions, diff --git a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb index d196e1d8e4f..af4cc7a0a25 100644 --- a/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb +++ b/src/Compilers/VisualBasic/Portable/CommandLine/VisualBasicCompiler.vb @@ -203,6 +203,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_VBCHelp, Culture)) End Sub + Public Overrides Sub PrintLangVersions(consoleOutput As TextWriter) + consoleOutput.WriteLine(ErrorFactory.IdToString(ERRID.IDS_LangVersions, Culture)) + Dim defaultVersion = LanguageVersion.Default.MapSpecifiedToEffectiveVersion() + Dim latestVersion = LanguageVersion.Latest.MapSpecifiedToEffectiveVersion() + For Each v As LanguageVersion In System.Enum.GetValues(GetType(LanguageVersion)) + If v = defaultVersion Then + consoleOutput.WriteLine($"{v.ToDisplayString()} (default)") + ElseIf v = latestVersion Then + consoleOutput.WriteLine($"{v.ToDisplayString()} (latest)") + Else + consoleOutput.WriteLine(v.ToDisplayString()) + End If + Next + consoleOutput.WriteLine() + End Sub + Protected Overrides Function TryGetCompilerDiagnosticCode(diagnosticId As String, ByRef code As UInteger) As Boolean Return CommonCompiler.TryGetCompilerDiagnosticCode(diagnosticId, "BC", code) End Function diff --git a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb index 280b5b2d4c9..5e7db875982 100644 --- a/src/Compilers/VisualBasic/Portable/Errors/Errors.vb +++ b/src/Compilers/VisualBasic/Portable/Errors/Errors.vb @@ -1977,7 +1977,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic IDS_LogoLine1 = 56007 IDS_LogoLine2 = 56008 IDS_VBCHelp = 56009 - ' available: 56010 + IDS_LangVersions = 56010 IDS_ToolName = 56011 ' Feature codes diff --git a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb index 1d20363f1ca..0a3b2b83af3 100644 --- a/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb +++ b/src/Compilers/VisualBasic/Portable/VBResources.Designer.vb @@ -23,7 +23,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic ''' ''' A strongly-typed resource class, for looking up localized strings, etc. ''' - _ @@ -12243,6 +12243,15 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End Get End Property + ''' + ''' Looks up a localized string similar to Supported language versions:. + ''' + Friend ReadOnly Property IDS_LangVersions() As String + Get + Return ResourceManager.GetString("IDS_LangVersions", resourceCulture) + End Get + End Property + ''' ''' Looks up a localized string similar to {0} version {1}. ''' diff --git a/src/Compilers/VisualBasic/Portable/VBResources.resx b/src/Compilers/VisualBasic/Portable/VBResources.resx index 87badda1d06..79f8a874efe 100644 --- a/src/Compilers/VisualBasic/Portable/VBResources.resx +++ b/src/Compilers/VisualBasic/Portable/VBResources.resx @@ -5045,6 +5045,9 @@ Copyright (C) Microsoft Corporation. All rights reserved. + + Supported language versions: + Visual Basic Compiler Options @@ -5130,9 +5133,11 @@ /imports:<import_list> Declare global Imports for namespaces in referenced metadata files. import_list:namespace,... -/langversion:<number> Specify language version: - 9|9.0|10|10.0|11|11.0|12|12.0|14|14.0|15| - 15.0|15.3|15.6|default|latest +/langversion:? Display the allowed values for language version +/langversion:<string> Specify language version such as + `default` (latest major version), or + `latest` (latest version, including minor versions), + or specific versions like `14` or `15.3` /optionexplicit[+|-] Require explicit declaration of variables. /optioninfer[+|-] Allow type inference of variables. /rootnamespace:<string> Specifies the root Namespace for all type diff --git a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb index 87d1459aeb0..2df03c9739f 100644 --- a/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb +++ b/src/Compilers/VisualBasic/Test/CommandLine/CommandLineTests.vb @@ -1703,26 +1703,22 @@ End Module").Path End Sub - Public Sub LanguageVersion_CommandLineUsage() - Dim expected = [Enum].GetValues(GetType(LanguageVersion)).Cast(Of LanguageVersion)().Select(Function(v) v.ToDisplayString()) - Dim help = VBResources.IDS_VBCHelp - - Dim rangeStart = help.IndexOf("/langversion") - Dim rangeEnd = help.IndexOf("/optionexplicit") - Assert.True(rangeEnd > rangeStart) + Public Sub LanguageVersion_ListLangVersions() + Dim dir = Temp.CreateDirectory() + Dim outWriter As New StringWriter() + Dim exitCode As Integer = New MockVisualBasicCompiler(Nothing, dir.ToString(), {"/langversion:?"}).Run(outWriter, Nothing) + Assert.Equal(0, exitCode) - Dim helpRange = help.Substring(rangeStart, rangeEnd - rangeStart).ToLowerInvariant() - Dim acceptableSurroundingChar = {CChar(vbCr), CChar(vbLf), "|"c, " "c} + Dim actual = outWriter.ToString() + Dim expected = [Enum].GetValues(GetType(LanguageVersion)).Cast(Of LanguageVersion)().Select(Function(v) v.ToDisplayString()) + Dim acceptableSurroundingChar = {CChar(vbCr), CChar(vbLf), "("c, ")"c, " "c} For Each v In expected - Dim foundIndex = helpRange.IndexOf(v) + Dim foundIndex = actual.IndexOf(v) Assert.True(foundIndex > 0, $"Missing version '{v}'") - Assert.True(Array.IndexOf(acceptableSurroundingChar, helpRange(foundIndex - 1)) >= 0) - Assert.True(Array.IndexOf(acceptableSurroundingChar, helpRange(foundIndex + v.Length)) >= 0) + Assert.True(Array.IndexOf(acceptableSurroundingChar, actual(foundIndex - 1)) >= 0) + Assert.True(Array.IndexOf(acceptableSurroundingChar, actual(foundIndex + v.Length)) >= 0) Next - - ' The canary check is a reminder that this test needs to be updated when a language version is added - LanguageVersionAdded_Canary() End Sub -- GitLab