From ec576b9c399ec4ae76f2f2aed57f721c53e1eeb1 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Wed, 29 Sep 2021 22:25:43 -0400 Subject: [PATCH 1/2] Update Regex source generator to use new GetBestTypeByMetadataName method --- .../gen/RegexGenerator.Parser.cs | 6 +-- ...m.Text.RegularExpressions.Generator.csproj | 11 +++-- .../RegexGeneratorParserTests.cs | 48 ++++++++++++++++++- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Parser.cs b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Parser.cs index d3285435f26a96..38b613c762752b 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Parser.cs +++ b/src/libraries/System.Text.RegularExpressions/gen/RegexGenerator.Parser.cs @@ -4,6 +4,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; using System; using System.Collections; using System.Collections.Generic; @@ -46,9 +47,8 @@ private static bool IsSyntaxTargetForGeneration(SyntaxNode node) => // Returns null if nothing to do, Diagnostic if there's an error to report, or RegexType if the type was analyzed successfully. private static object? GetRegexTypeToEmit(Compilation compilation, MethodDeclarationSyntax methodSyntax, CancellationToken cancellationToken) { - // TODO: Use https://github.com/dotnet/runtime/pull/59092 - INamedTypeSymbol? regexSymbol = compilation.GetTypeByMetadataName(RegexName); - INamedTypeSymbol? regexGeneratorAttributeSymbol = compilation.GetTypeByMetadataName(RegexGeneratorAttributeName); + INamedTypeSymbol? regexSymbol = compilation.GetBestTypeByMetadataName(RegexName); + INamedTypeSymbol? regexGeneratorAttributeSymbol = compilation.GetBestTypeByMetadataName(RegexGeneratorAttributeName); if (regexSymbol is null || regexGeneratorAttributeSymbol is null) { // Required types aren't available diff --git a/src/libraries/System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj b/src/libraries/System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj index 3bb6655e92ad2b..cb7e816f76f4c5 100644 --- a/src/libraries/System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj +++ b/src/libraries/System.Text.RegularExpressions/gen/System.Text.RegularExpressions.Generator.csproj @@ -20,11 +20,14 @@ - - - - + + + + + + + diff --git a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs index 8d0b6b6a3d3608..2445333f259ce1 100644 --- a/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs +++ b/src/libraries/System.Text.RegularExpressions/tests/System.Text.RegularExpressions.Generators.Tests/RegexGeneratorParserTests.cs @@ -475,13 +475,34 @@ public partial struct E ", compile: true)); } + [Fact] + public async Task MultipleTypeDefinitions_DoesntBreakGeneration() + { + byte[] referencedAssembly = CreateAssemblyImage(@" + namespace System.Text.RegularExpressions; + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] + internal sealed class RegexGeneratorAttribute : Attribute + { + public RegexGeneratorAttribute(string pattern){} + }", "TestAssembly"); + + Assert.Empty(await RunGenerator(@" + using System.Text.RegularExpressions; + partial class C + { + [RegexGenerator(""abc"")] + private static partial Regex Valid(); + }", compile: true, additionalRefs: new[] { MetadataReference.CreateFromImage(referencedAssembly) })); + } + private async Task> RunGenerator( - string code, bool compile = false, LanguageVersion langVersion = LanguageVersion.Preview, CancellationToken cancellationToken = default) + string code, bool compile = false, LanguageVersion langVersion = LanguageVersion.Preview, MetadataReference[]? additionalRefs = null, CancellationToken cancellationToken = default) { var proj = new AdhocWorkspace() .AddSolution(SolutionInfo.Create(SolutionId.CreateNewId(), VersionStamp.Create())) .AddProject("RegexGeneratorTest", "RegexGeneratorTest.dll", "C#") - .WithMetadataReferences(s_refs) + .WithMetadataReferences(additionalRefs is not null ? s_refs.Concat(additionalRefs) : s_refs) .WithCompilationOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary) .WithNullableContextOptions(NullableContextOptions.Enable)) .WithParseOptions(new CSharpParseOptions(langVersion)) @@ -513,10 +534,33 @@ private async Task> RunGenerator( return generatorResults.Diagnostics.Concat(results.Diagnostics).Where(d => d.Severity != DiagnosticSeverity.Hidden).ToArray(); } + private static byte[] CreateAssemblyImage(string source, string assemblyName) + { + CSharpCompilation compilation = CSharpCompilation.Create( + assemblyName, + new[] { CSharpSyntaxTree.ParseText(source, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.Preview)) }, + s_refs.ToArray(), + new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + var ms = new MemoryStream(); + if (compilation.Emit(ms).Success) + { + return ms.ToArray(); + } + + throw new InvalidOperationException(); + } + private static readonly MetadataReference[] s_refs = CreateReferences(); private static MetadataReference[] CreateReferences() { + if (PlatformDetection.IsBrowser) + { + // These tests that use Roslyn don't work well on browser wasm today + return new MetadataReference[0]; + } + string corelibPath = typeof(object).Assembly.Location; return new[] { From e50a68d9d42e851edf97f505b1220678d7be4068 Mon Sep 17 00:00:00 2001 From: Stephen Toub Date: Tue, 5 Oct 2021 23:35:53 -0400 Subject: [PATCH 2/2] Disable tests in tests.proj --- src/libraries/tests.proj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/tests.proj b/src/libraries/tests.proj index aefca41a35b6b5..b3a8575c047362 100644 --- a/src/libraries/tests.proj +++ b/src/libraries/tests.proj @@ -212,6 +212,10 @@ + + + +