-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #167 from mono/better-langversion
Better defaults and handling for LangVersion
- Loading branch information
Showing
8 changed files
with
163 additions
and
112 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,9 @@ | |
} | ||
], | ||
"cSpell.words": [ | ||
"langversion", | ||
"Preprocess", | ||
"reimplementation" | ||
"reimplementation", | ||
"Xunit" | ||
] | ||
} |
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
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)) | ||
}; | ||
} |
Oops, something went wrong.