-
Notifications
You must be signed in to change notification settings - Fork 104
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for C# 11 and newer versions
If a langversion is explicitly provided, use it verbatim. The compiler will check validity and emit and error if needed. Otherwise, use the C# language version known to be supported by the current runtime, as we may be using csc/Roslyn from a newer runtime where the "latest" language features depend on new APIs that aren't available on the current runtime. If we do not have a language version mapping for the runtime, use "latest" so all its language features are available until we add the version mapping. Fix #166 - Support for C# 11
- Loading branch information
Showing
5 changed files
with
153 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersion.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
#if NETFRAMEWORK | ||
#nullable enable annotations | ||
#else | ||
#nullable enable | ||
#endif | ||
|
||
namespace Mono.TextTemplating.CodeCompilation; | ||
|
||
enum CSharpLangVersion | ||
{ | ||
v5_0, | ||
v6_0, | ||
v7_0, | ||
v7_1, | ||
v7_2, | ||
v7_3, | ||
v8_0, | ||
v9_0, | ||
v10_0, | ||
v11_0, | ||
v12_0, | ||
Latest = 1024 // make sure value doesn't change as we add new C# versions | ||
} |
141 changes: 65 additions & 76 deletions
141
Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersionHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,90 +1,79 @@ | ||
// Copyright (c) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
||
#if NETFRAMEWORK | ||
#nullable enable annotations | ||
#else | ||
#nullable enable | ||
#endif | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
|
||
namespace Mono.TextTemplating.CodeCompilation | ||
{ | ||
enum CSharpLangVersion | ||
{ | ||
v5_0, | ||
v6_0, | ||
v7_0, | ||
v7_1, | ||
v7_2, | ||
v7_3, | ||
v8_0, | ||
v9_0, | ||
Latest | ||
} | ||
|
||
static class CSharpLangVersionHelper | ||
{ | ||
public static CSharpLangVersion GetBestSupportedLangVersion (RuntimeInfo runtime, CSharpLangVersion? compilerLangVersion = null) | ||
=> (CSharpLangVersion)Math.Min ((int)(compilerLangVersion ?? runtime.MaxSupportedLangVersion), (int) (runtime switch { | ||
{ Kind: RuntimeKind.NetCore, Version.Major: > 5 } => CSharpLangVersion.Latest, | ||
{ Kind: RuntimeKind.NetCore, Version.Major: 5 } => CSharpLangVersion.v9_0, | ||
{ Kind: RuntimeKind.NetCore, Version.Major: 3 } => CSharpLangVersion.v8_0, | ||
_ => CSharpLangVersion.v7_3, | ||
})); | ||
|
||
static bool HasLangVersionArg (string args) => | ||
!string.IsNullOrEmpty(args) | ||
&& (args.IndexOf ("langversion", StringComparison.OrdinalIgnoreCase) > -1) | ||
&& ProcessArgumentBuilder.TryParse (args, out var parsedArgs) | ||
&& parsedArgs.Any (a => a.IndexOf ("langversion", StringComparison.OrdinalIgnoreCase) == 1); | ||
namespace Mono.TextTemplating.CodeCompilation; | ||
|
||
static string ToString (CSharpLangVersion version) => version switch { | ||
CSharpLangVersion.v5_0 => "5", | ||
CSharpLangVersion.v6_0 => "6", | ||
CSharpLangVersion.v7_0 => "7", | ||
CSharpLangVersion.v7_1 => "7.1", | ||
CSharpLangVersion.v7_2 => "7.2", | ||
CSharpLangVersion.v7_3 => "7.3", | ||
CSharpLangVersion.v8_0 => "8.0", | ||
CSharpLangVersion.v9_0 => "9.0", | ||
CSharpLangVersion.Latest => "latest", | ||
_ => throw new ArgumentException ($"Not a valid value: '{version}'", nameof (version)) | ||
}; | ||
|
||
public static string GetLangVersionArg (CodeCompilerArguments arguments, RuntimeInfo runtime) | ||
{ | ||
if (!string.IsNullOrWhiteSpace (arguments.LangVersion)) { | ||
return $"-langversion:{arguments.LangVersion}"; | ||
} | ||
static class CSharpLangVersionHelper | ||
{ | ||
public static bool HasLangVersionArg (string args) => | ||
!string.IsNullOrEmpty(args) | ||
&& (args.IndexOf ("langversion", StringComparison.OrdinalIgnoreCase) > -1) | ||
&& ProcessArgumentBuilder.TryParse (args, out var parsedArgs) | ||
&& parsedArgs.Any (IsLangVersionArg); | ||
|
||
if (HasLangVersionArg (arguments.AdditionalArguments)) { | ||
return null; | ||
} | ||
public static bool IsLangVersionArg (string arg) => | ||
(arg[0] == '-' || arg[0] == '/') | ||
&& arg.IndexOf ("langversion", StringComparison.OrdinalIgnoreCase) == 1; | ||
|
||
return $"-langversion:{ToString(GetBestSupportedLangVersion(runtime))}"; | ||
public static string? GetLangVersionArg (CodeCompilerArguments arguments, RuntimeInfo runtime) | ||
{ | ||
// Arguments.LangVersion takes precedence over -langversion in arguments.AdditionalArguments. | ||
// This behavior should match that of CscCodeCompiler.CompileFile and RoslynCodeCompiler.CompileFileInternal | ||
if (!string.IsNullOrWhiteSpace (arguments.LangVersion)) { | ||
return $"-langversion:{arguments.LangVersion}"; | ||
} | ||
|
||
public static CSharpLangVersion? FromRoslynPackageVersion (string roslynPackageVersion) | ||
=> SemVersion.TryParse (roslynPackageVersion, out var version) | ||
? version switch { | ||
{ Major: > 3 } => CSharpLangVersion.v9_0, | ||
{ Major: 3, Minor: >= 8 } => CSharpLangVersion.v9_0, | ||
{ Major: 3, Minor: >= 3 } => CSharpLangVersion.v8_0, | ||
// ignore 8.0 preview support in 3.0-3.2 | ||
{ Major: 2, Minor: >= 8 } => CSharpLangVersion.v7_3, | ||
{ Major: 2, Minor: >= 6 } => CSharpLangVersion.v7_2, | ||
{ Major: 2, Minor: >= 3 } => CSharpLangVersion.v7_1, | ||
{ Major: 2 } => CSharpLangVersion.v7_0, | ||
_ => CSharpLangVersion.v6_0 | ||
} | ||
: null; | ||
if (HasLangVersionArg (arguments.AdditionalArguments)) { | ||
return null; | ||
} | ||
|
||
//https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history | ||
public static CSharpLangVersion FromNetCoreSdkVersion (SemVersion sdkVersion) | ||
=> sdkVersion switch { | ||
{ Major: >= 5 } => CSharpLangVersion.v9_0, | ||
{ Major: 3 } => CSharpLangVersion.v8_0, | ||
{ Major: 2, Minor: >= 1 } => CSharpLangVersion.v7_3, | ||
{ Major: 2, Minor: >= 0 } => CSharpLangVersion.v7_1, | ||
_ => CSharpLangVersion.v7_0 | ||
}; | ||
// Default to the highest language version supported by the runtime | ||
// as we may be using a csc from a newer runtime where "latest" language | ||
// features depend on new APIs that aren't available on the current runtime. | ||
// If we were unable to determine the supported language version for the runtime, | ||
// its MaxSupportedLangVersion will default to "Latest" so its language features | ||
// are available before we add a language version mapping for that runtime version. | ||
return $"-langversion:{ToString (runtime.MaxSupportedLangVersion)}"; | ||
} | ||
|
||
//https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history | ||
public static CSharpLangVersion FromNetCoreSdkVersion (SemVersion sdkVersion) | ||
=> sdkVersion switch { | ||
{ Major: 8 } => CSharpLangVersion.v12_0, | ||
{ Major: 7 } => CSharpLangVersion.v11_0, | ||
{ Major: 6 } => CSharpLangVersion.v10_0, | ||
{ Major: 5 } => CSharpLangVersion.v9_0, | ||
{ Major: 3 } => CSharpLangVersion.v8_0, | ||
{ Major: 2, Minor: >= 1 } => CSharpLangVersion.v7_3, | ||
{ Major: 2, Minor: >= 0 } => CSharpLangVersion.v7_1, | ||
{ Major: 1 } => CSharpLangVersion.v7_1, | ||
// for unknown versions, always fall through to "Latest" so we don't break the | ||
// ability to use new C# versions as they are released | ||
_ => CSharpLangVersion.Latest | ||
}; | ||
|
||
public static string ToString (CSharpLangVersion version) => version switch { | ||
CSharpLangVersion.v5_0 => "5", | ||
CSharpLangVersion.v6_0 => "6", | ||
CSharpLangVersion.v7_0 => "7", | ||
CSharpLangVersion.v7_1 => "7.1", | ||
CSharpLangVersion.v7_2 => "7.2", | ||
CSharpLangVersion.v7_3 => "7.3", | ||
CSharpLangVersion.v8_0 => "8.0", | ||
CSharpLangVersion.v9_0 => "9.0", | ||
CSharpLangVersion.v10_0 => "10.0", | ||
CSharpLangVersion.v11_0 => "11.0", | ||
CSharpLangVersion.v12_0 => "12.0", | ||
CSharpLangVersion.Latest => "latest", | ||
_ => throw new ArgumentException ($"Not a valid value: '{version}'", nameof (version)) | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters