From 6b882b474aab3ee401ff648024a1c5e053c3f188 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Mon, 6 Feb 2023 20:28:31 -0500 Subject: [PATCH] Avoid using `file` in generated regexes pre-C# 11 (#81726) --- .../gen/RegexGenerator.Emitter.cs | 16 +++++++++++++--- .../System.Text.RegularExpressions/gen/RegexGenerator.cs | 10 +++++----- .../FunctionalTests/RegexGeneratorHelper.netcoreapp.cs | 2 +- .../tests/FunctionalTests/RegexGeneratorParserTests.cs | 2 +- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs index ee255e4..31c5fe3 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Emitter.cs @@ -72,12 +72,22 @@ namespace System.Text.RegularExpressions.Generator /// Emits the Regex-derived type for a method where we're unable to generate custom code. private static void EmitRegexLimitedBoilerplate( - IndentedTextWriter writer, RegexMethod rm, string reason) + IndentedTextWriter writer, RegexMethod rm, string reason, LanguageVersion langVer) { - writer.WriteLine($"/// Caches a instance for the {rm.MethodName} method."); + string visibility; + if (langVer >= LanguageVersion.CSharp11) + { + visibility = "file"; + writer.WriteLine($"/// Caches a instance for the {rm.MethodName} method."); + } + else + { + visibility = "internal"; + writer.WriteLine($"/// This class supports generated regexes and should not be used by other code directly."); + } writer.WriteLine($"/// A custom Regex-derived type could not be generated because {reason}."); writer.WriteLine($"[{s_generatedCodeAttribute}]"); - writer.WriteLine($"file sealed class {rm.GeneratedName} : Regex"); + writer.WriteLine($"{visibility} sealed class {rm.GeneratedName} : Regex"); writer.WriteLine($"{{"); writer.WriteLine($" /// Cached, thread-safe singleton instance."); writer.Write($" internal static readonly Regex Instance = "); diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs index bda1f16..ada46b3 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.cs @@ -80,7 +80,7 @@ namespace System.Text.RegularExpressions.Generator // We'll still output a limited implementation that just caches a new Regex(...). if (!SupportsCodeGeneration(regexMethod, methodOrDiagnosticAndCompilationData.Right.LanguageVersion, out string? reason)) { - return (regexMethod, reason, Diagnostic.Create(DiagnosticDescriptors.LimitedSourceGeneration, regexMethod.MethodSyntax.GetLocation())); + return (regexMethod, reason, Diagnostic.Create(DiagnosticDescriptors.LimitedSourceGeneration, regexMethod.MethodSyntax.GetLocation()), methodOrDiagnosticAndCompilationData.Right); } // Generate the core logic for the regex. @@ -150,7 +150,7 @@ namespace System.Text.RegularExpressions.Generator foreach (object? result in results) { RegexMethod? regexMethod = null; - if (result is ValueTuple limitedSupportResult) + if (result is ValueTuple limitedSupportResult) { context.ReportDiagnostic(limitedSupportResult.Item3); regexMethod = limitedSupportResult.Item1; @@ -212,11 +212,11 @@ namespace System.Text.RegularExpressions.Generator writer.Indent++; foreach (object? result in results) { - if (result is ValueTuple limitedSupportResult) + if (result is ValueTuple limitedSupportResult) { if (!limitedSupportResult.Item1.IsDuplicate) { - EmitRegexLimitedBoilerplate(writer, limitedSupportResult.Item1, limitedSupportResult.Item2); + EmitRegexLimitedBoilerplate(writer, limitedSupportResult.Item1, limitedSupportResult.Item2, limitedSupportResult.Item4.LanguageVersion); writer.WriteLine(); } } @@ -273,7 +273,7 @@ namespace System.Text.RegularExpressions.Generator /// private static bool SupportsCodeGeneration(RegexMethod method, LanguageVersion languageVersion, [NotNullWhen(false)] out string? reason) { - if (languageVersion <= LanguageVersion.CSharp10) + if (languageVersion < LanguageVersion.CSharp11) { reason = "the language version must be C# 11 or higher."; return false; diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorHelper.netcoreapp.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorHelper.netcoreapp.cs index 340ed7f..bf0d331 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorHelper.netcoreapp.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorHelper.netcoreapp.cs @@ -103,7 +103,7 @@ namespace System.Text.RegularExpressions.Tests EmitResult results = comp.Emit(Stream.Null, cancellationToken: cancellationToken); ImmutableArray generatorDiagnostics = generatorResults.Diagnostics.RemoveAll(d => d.Severity <= DiagnosticSeverity.Hidden); ImmutableArray resultsDiagnostics = results.Diagnostics.RemoveAll(d => d.Severity <= DiagnosticSeverity.Hidden); - if (!results.Success || resultsDiagnostics.Length != 0 || generatorDiagnostics.Length != 0) + if (!results.Success || resultsDiagnostics.Length != 0) { throw new ArgumentException( string.Join(Environment.NewLine, resultsDiagnostics.Concat(generatorDiagnostics)) + Environment.NewLine + diff --git a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorParserTests.cs b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorParserTests.cs index fa86ca5..fcb6820 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorParserTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/FunctionalTests/RegexGeneratorParserTests.cs @@ -252,7 +252,7 @@ namespace System.Text.RegularExpressions.Tests [GeneratedRegex(""ab"")] private static partial Regex InvalidLangVersion(); } - ", langVersion: version); + ", langVersion: version, compile: true); Assert.Equal("SYSLIB1044", Assert.Single(diagnostics).Id); } -- 2.7.4