未验证 提交 5615b56d 编写于 作者: C CyrusNajmabadi 提交者: GitHub

Polyfill the incremental generator ForAttributeWithMetadataName from roslyn...

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
上级 4fa27c98
......@@ -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<KeyValuePair<string, TypedConstant>> args = attribute.NamedArguments;
foreach (KeyValuePair<string, TypedConstant> 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<AttributeArgumentSyntax>? 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
......
......@@ -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<EventSourceClass> 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);
......
......@@ -12,6 +12,21 @@
<Compile Include="$(CoreLibSharedDir)\System\Runtime\CompilerServices\IsExternalInit.cs" Link="Common\System\Runtime\CompilerServices\IsExternalInit.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(CommonPath)Roslyn\GetBestTypeByMetadataName.cs" Link="Common\Roslyn\GetBestTypeByMetadataName.cs" />
<Compile Include="$(CommonPath)Roslyn\Hash.cs" Link="Common\Roslyn\Hash.cs" />
<Compile Include="$(CommonPath)Roslyn\ISyntaxHelper.cs" Link="Common\Roslyn\ISyntaxHelper.cs" />
<Compile Include="$(CommonPath)Roslyn\CSharpSyntaxHelper.cs" Link="Common\Roslyn\CSharpSyntaxHelper.cs" />
<Compile Include="$(CommonPath)Roslyn\GlobalAliases.cs" Link="Common\Roslyn\GlobalAliases.cs" />
<Compile Include="$(CommonPath)Roslyn\SyntaxNodeGrouping.cs" Link="Common\Roslyn\SyntaxNodeGrouping.cs" />
<Compile Include="$(CommonPath)Roslyn\SyntaxValueProvider.ImmutableArrayValueComparer.cs" Link="Common\Roslyn\SyntaxValueProvider.ImmutableArrayValueComparer.cs" />
<Compile Include="$(CommonPath)Roslyn\SyntaxValueProvider_ForAttributeWithMetadataName.cs" Link="Common\Roslyn\SyntaxValueProvider_ForAttributeWithMetadataName.cs" />
<Compile Include="$(CommonPath)Roslyn\SyntaxValueProvider_ForAttributeWithSimpleName.cs" Link="Common\Roslyn\SyntaxValueProvider_ForAttributeWithSimpleName.cs" />
<Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.cs" Link="Production\ValueListBuilder.cs" />
<Compile Include="$(CoreLibSharedDir)System\Collections\Generic\ValueListBuilder.Pop.cs" Link="Production\ValueListBuilder.Pop.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" Version="$(MicrosoftCodeAnalysisCSharpVersion)" />
</ItemGroup>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册