From 56f20c81e90f837a494d775388a48de55045a491 Mon Sep 17 00:00:00 2001 From: Mikayla Hutchinson Date: Fri, 26 Jan 2024 00:20:42 -0500 Subject: [PATCH] Separate csc and runtime C# versions --- .../RoslynCodeCompiler.cs | 3 +- .../CSharpLangVersionHelper.cs | 2 +- .../RuntimeInfo.cs | 91 ++++++++++++++----- 3 files changed, 68 insertions(+), 28 deletions(-) diff --git a/Mono.TextTemplating.Roslyn/RoslynCodeCompiler.cs b/Mono.TextTemplating.Roslyn/RoslynCodeCompiler.cs index b3323d5..bc888a3 100644 --- a/Mono.TextTemplating.Roslyn/RoslynCodeCompiler.cs +++ b/Mono.TextTemplating.Roslyn/RoslynCodeCompiler.cs @@ -71,14 +71,13 @@ CodeCompilerResult CompileFileInternal ( // features depend on new APIs that aren't available on the current runtime. // If the runtime is an unknown version, its MaxSupportedLangVersion will default // to "latest" so new runtime versions will work before we explicitly add support for them. - if (LanguageVersionFacts.TryParse (CSharpLangVersionHelper.ToString (runtime.MaxSupportedLangVersion), out var runtimeSupportedLangVersion)) { + if (LanguageVersionFacts.TryParse (CSharpLangVersionHelper.ToString (runtime.RuntimeLangVersion), out var runtimeSupportedLangVersion)) { parseOptions = parseOptions.WithLanguageVersion (runtimeSupportedLangVersion); } else { // if Roslyn did not recognize the runtime's default lang version, it's newer than // this version of Roslyn supports, so default to the latest supported version parseOptions = parseOptions.WithLanguageVersion (LanguageVersion.Latest); } - } var syntaxTrees = new List (); diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersionHelper.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersionHelper.cs index bca005f..347233c 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersionHelper.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/CSharpLangVersionHelper.cs @@ -42,7 +42,7 @@ public static bool IsLangVersionArg (string arg) => // 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.CscMaxLangVersion)}"; + return $"-langversion:{ToString (runtime.RuntimeLangVersion)}"; } //https://docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-version-history diff --git a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs index 07d7385..3a00fac 100644 --- a/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs +++ b/Mono.TextTemplating/Mono.TextTemplating.CodeCompilation/RuntimeInfo.cs @@ -39,27 +39,51 @@ enum RuntimeKind class RuntimeInfo { - RuntimeInfo (RuntimeKind kind) => Kind = kind; + RuntimeInfo (RuntimeKind kind, string error) + { + Kind = kind; + Error = error; + } - static RuntimeInfo FromError (RuntimeKind kind, string error) => new (kind) { Error = error }; + RuntimeInfo (RuntimeKind kind, string runtimeDir, Version runtimeVersion, string refAssembliesDir, string runtimeFacadesDir, string cscPath, CSharpLangVersion cscMaxLangVersion, CSharpLangVersion runtimeLangVersion) + { + Kind = kind; + RuntimeVersion = runtimeVersion; + RuntimeDir = runtimeDir; + RefAssembliesDir = refAssembliesDir; + RuntimeFacadesDir = runtimeFacadesDir; + CscPath = cscPath; + CscMaxLangVersion = cscMaxLangVersion; + RuntimeLangVersion = runtimeLangVersion; + } - public RuntimeKind Kind { get; private set; } - public string Error { get; private set; } - public string RuntimeDir { get; private set; } + static RuntimeInfo FromError (RuntimeKind kind, string error) => new (kind, error); + + public RuntimeKind Kind { get; } + public string Error { get; } + public string RuntimeDir { get; } // may be null, as this is not a problem when the optional in-process compiler is used - public string CscPath { get; private set; } + public string CscPath { get; } /// /// Maximum C# language version supported by C# compiler in . /// - public CSharpLangVersion CscMaxLangVersion { get; private set; } + public CSharpLangVersion CscMaxLangVersion { get; } + + /// + /// The C# version fully supported by the runtime, which is the default when targeting this runtime. + /// + /// + /// Using newer C# language versions is possible but some features may not work if they depend on runtime changes. + /// + public CSharpLangVersion RuntimeLangVersion { get; } public bool IsValid => Error == null; - public Version Version { get; private set; } + public Version RuntimeVersion { get; } - public string RefAssembliesDir { get; private set; } - public string RuntimeFacadesDir { get; internal set; } + public string RefAssembliesDir { get; } + public string RuntimeFacadesDir { get; } public static RuntimeInfo GetRuntime () { @@ -85,15 +109,18 @@ static RuntimeInfo GetMonoRuntime () return FromError (RuntimeKind.Mono, "Could not find csc in host Mono installation" ); } - return new RuntimeInfo (RuntimeKind.Mono) { - CscPath = csc, - RuntimeDir = runtimeDir, - RuntimeFacadesDir = Path.Combine (runtimeDir, "Facades"), + return new RuntimeInfo ( + RuntimeKind.Mono, + runtimeDir: runtimeDir, // we don't really care about the version if it's not .net core - Version = new Version ("4.7.2"), + runtimeVersion: new Version ("4.7.2"), + refAssembliesDir: null, + runtimeFacadesDir: Path.Combine (runtimeDir, "Facades"), + cscPath: csc, //if mono has csc at all, we know it at least supports 6.0 - CscMaxLangVersion = CSharpLangVersion.v6_0 - }; + cscMaxLangVersion: CSharpLangVersion.v6_0, + runtimeLangVersion: CSharpLangVersion.v5_0 + ); } static RuntimeInfo GetNetFrameworkRuntime () @@ -103,14 +130,17 @@ static RuntimeInfo GetNetFrameworkRuntime () if (!File.Exists (csc)) { return FromError (RuntimeKind.NetFramework, "Could not find csc in host .NET Framework installation"); } - return new RuntimeInfo (RuntimeKind.NetFramework) { - CscPath = csc, - RuntimeDir = runtimeDir, - RuntimeFacadesDir = runtimeDir, + return new RuntimeInfo ( + RuntimeKind.NetFramework, + runtimeDir: runtimeDir, // we don't really care about the version if it's not .net core - Version = new Version ("4.7.2"), - CscMaxLangVersion = CSharpLangVersion.v5_0 - }; + runtimeVersion: new Version ("4.7.2"), + refAssembliesDir: null, + runtimeFacadesDir: runtimeDir, + cscPath: csc, + cscMaxLangVersion: CSharpLangVersion.v5_0, + runtimeLangVersion: CSharpLangVersion.v5_0 + ); } static RuntimeInfo GetDotNetCoreSdk () @@ -163,7 +193,18 @@ static RuntimeInfo GetDotNetCoreSdk () out _ ); - return new RuntimeInfo (RuntimeKind.NetCore) { RuntimeDir = runtimeDir, RefAssembliesDir = refAssembliesDir, CscPath = MakeCscPath (sdkDir), CscMaxLangVersion = maxCSharpVersion, Version = hostVersion }; + + + return new RuntimeInfo ( + RuntimeKind.NetCore, + runtimeDir: runtimeDir, + runtimeVersion: hostVersion, + refAssembliesDir: refAssembliesDir, + runtimeFacadesDir: null, + cscPath: MakeCscPath (sdkDir), + cscMaxLangVersion: maxCSharpVersion, + runtimeLangVersion: CSharpLangVersionHelper.FromNetCoreSdkVersion (sdkVersion) + ); } static string FindHighestVersionedDirectory (string parentFolder, Func validate, out SemVersion bestVersion)