From 5615b56d08b71ecc10e892dd969e6a6433a8664d Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Tue, 12 Jul 2022 15:52:05 -0700 Subject: [PATCH] Polyfill the incremental generator ForAttributeWithMetadataName from roslyn (for EventSourceGeneration). (#71662) * Polyfill the incremental generator ForAttributeWithMetadataName from roslyn (for LibraryImportGenerator). * Move common code to shared location * Polyfill the incremental generator ForAttributeWithMetadataName from roslyn (for EventSourcewGenerator). * Update src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs * Revert * Simplify --- .../gen/EventSourceGenerator.Parser.cs | 141 ++++++++---------- .../gen/EventSourceGenerator.cs | 10 +- .../System.Private.CoreLib.Generators.csproj | 15 ++ 3 files changed, 82 insertions(+), 84 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs index b13526f6a5e..43a498b589a 100644 --- a/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs +++ b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.Parser.cs @@ -4,119 +4,96 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading; using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; namespace Generators { public partial class EventSourceGenerator { - private static bool IsSyntaxTargetForGeneration(SyntaxNode node, CancellationToken cancellationToken) => - node is ClassDeclarationSyntax { AttributeLists.Count: > 0 }; - - private static EventSourceClass? GetSemanticTargetForGeneration(GeneratorSyntaxContext context, CancellationToken cancellationToken) + private static EventSourceClass? GetSemanticTargetForGeneration(GeneratorAttributeSyntaxContext context, CancellationToken cancellationToken) { - const string EventSourceAutoGenerateAttribute = "System.Diagnostics.Tracing.EventSourceAutoGenerateAttribute"; const string EventSourceAttribute = "System.Diagnostics.Tracing.EventSourceAttribute"; - var classDef = (ClassDeclarationSyntax)context.Node; - SemanticModel sm = context.SemanticModel; + var classDef = (ClassDeclarationSyntax)context.TargetNode; + NamespaceDeclarationSyntax? ns = classDef.Parent as NamespaceDeclarationSyntax; + if (ns is null) + { + if (classDef.Parent is not CompilationUnitSyntax) + { + // since this generator doesn't know how to generate a nested type... + return null; + } + } + EventSourceClass? eventSourceClass = null; + string? nspace = null; - bool autoGenerate = false; - foreach (AttributeListSyntax cal in classDef.AttributeLists) + foreach (AttributeData attribute in context.TargetSymbol.GetAttributes()) { - foreach (AttributeSyntax ca in cal.Attributes) + if (attribute.AttributeClass?.Name != "EventSourceAttribute" || + attribute.AttributeClass.ToDisplayString() != EventSourceAttribute) { - if (sm.GetSymbolInfo(ca, cancellationToken).Symbol is not IMethodSymbol caSymbol) - { - // badly formed attribute definition, or not the right attribute - continue; - } + continue; + } - string attributeFullName = caSymbol.ContainingType.ToDisplayString(); + nspace ??= ConstructNamespace(ns); - if (attributeFullName.Equals(EventSourceAutoGenerateAttribute, StringComparison.Ordinal)) - { - autoGenerate = true; - continue; - } + string className = classDef.Identifier.ValueText; + string name = className; + string guid = ""; - if (!attributeFullName.Equals(EventSourceAttribute, StringComparison.Ordinal)) - { - continue; - } + ImmutableArray> args = attribute.NamedArguments; + foreach (KeyValuePair arg in args) + { + string argName = arg.Key; + string value = arg.Value.Value?.ToString(); - string nspace = string.Empty; - NamespaceDeclarationSyntax? ns = classDef.Parent as NamespaceDeclarationSyntax; - if (ns is null) - { - if (classDef.Parent is not CompilationUnitSyntax) - { - // since this generator doesn't know how to generate a nested type... - continue; - } - } - else + switch (argName) { - nspace = ns.Name.ToString(); - while (true) - { - ns = ns.Parent as NamespaceDeclarationSyntax; - if (ns == null) - { - break; - } - - nspace = $"{ns.Name}.{nspace}"; - } + case "Guid": + guid = value; + break; + case "Name": + name = value; + break; } + } - string className = classDef.Identifier.ToString(); - string name = className; - string guid = ""; + if (!Guid.TryParse(guid, out Guid result)) + { + result = GenerateGuidFromName(name.ToUpperInvariant()); + } - SeparatedSyntaxList? args = ca.ArgumentList?.Arguments; - if (args is not null) - { - foreach (AttributeArgumentSyntax arg in args) - { - string argName = arg.NameEquals!.Name.Identifier.ToString(); - string value = sm.GetConstantValue(arg.Expression, cancellationToken).ToString(); - - switch (argName) - { - case "Guid": - guid = value; - break; - case "Name": - name = value; - break; - } - } - } + eventSourceClass = new EventSourceClass(nspace, className, name, result); + continue; + } - if (!Guid.TryParse(guid, out Guid result)) - { - result = GenerateGuidFromName(name.ToUpperInvariant()); - } + return eventSourceClass; + } - eventSourceClass = new EventSourceClass(nspace, className, name, result); - continue; - } - } + private static string? ConstructNamespace(NamespaceDeclarationSyntax? ns) + { + if (ns is null) + return string.Empty; - if (!autoGenerate) + string nspace = ns.Name.ToString(); + while (true) { - return null; + ns = ns.Parent as NamespaceDeclarationSyntax; + if (ns == null) + { + break; + } + + nspace = $"{ns.Name}.{nspace}"; } - return eventSourceClass; + return nspace; } // From System.Private.CoreLib diff --git a/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs index cebe3a5d32c..e57f11d6f4e 100644 --- a/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs +++ b/src/libraries/System.Private.CoreLib/gen/EventSourceGenerator.cs @@ -7,6 +7,7 @@ using System.Threading; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.DotnetRuntime.Extensions; namespace Generators { @@ -35,9 +36,14 @@ public partial class EventSourceGenerator : IIncrementalGenerator public void Initialize(IncrementalGeneratorInitializationContext context) { + const string EventSourceAutoGenerateAttribute = "System.Diagnostics.Tracing.EventSourceAutoGenerateAttribute"; + IncrementalValuesProvider eventSourceClasses = - context.SyntaxProvider - .CreateSyntaxProvider(IsSyntaxTargetForGeneration, GetSemanticTargetForGeneration) + context.SyntaxProvider.ForAttributeWithMetadataName( + context, + EventSourceAutoGenerateAttribute, + (node, _) => node is ClassDeclarationSyntax, + GetSemanticTargetForGeneration) .Where(x => x is not null); context.RegisterSourceOutput(eventSourceClasses, EmitSourceFile); diff --git a/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj b/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj index 41709a49982..90d6ae99bb2 100644 --- a/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj +++ b/src/libraries/System.Private.CoreLib/gen/System.Private.CoreLib.Generators.csproj @@ -12,6 +12,21 @@ + + + + + + + + + + + + + + + -- GitLab