C# 每个类获得一个Roslyn语法接收器
我有一个简单的源代码生成器,定义为C# 每个类获得一个Roslyn语法接收器,c#,roslyn,sourcegenerators,C#,Roslyn,Sourcegenerators,我有一个简单的源代码生成器,定义为 [Generator] public class NestedObjectGenerator : ISourceGenerator { public void Initialize(GeneratorInitializationContext context) { context.RegisterForSyntaxNotifications(() => new MySyntaxReceiver()); } public void
[Generator]
public class NestedObjectGenerator : ISourceGenerator
{
public void Initialize(GeneratorInitializationContext context)
{
context.RegisterForSyntaxNotifications(() => new MySyntaxReceiver());
}
public void Execute(GeneratorExecutionContext context)
{
var recv = (MySyntaxReceiver)context.SyntaxReceiver;
ClassDeclarationSyntax cds = recv?.Class;
if (cds is null) return;
// use cds here
}
private class MySyntaxReceiver : ISyntaxReceiver
{
public ClassDeclarationSyntax Class { get; private set; }
public void OnVisitSyntaxNode(SyntaxNode node)
{
if (node is ClassDeclarationSyntax cds &&
cds.Modifiers.Any(SyntaxKind.PartialKeyword))
Class = cds;
}
}
}
我在一个文件上运行这个生成器,该文件中有几个分部类。但是,似乎只调用了一次Execute()
,并且包含的Class
是具有Main()
方法的类,即使文件中还有其他类
因此,我的问题是:如何让
Execute()
在每个受影响的语法节点上运行一次,即在每个部分类上运行一次?您可以这样更改接收器:
private class MySyntaxReceiver : ISyntaxReceiver
{
public List<ClassDeclarationSyntax> ClassCandidates { get; } = new();
public void OnVisitSyntaxNode(SyntaxNode node)
{
if (node is ClassDeclarationSyntax cds && cds.Modifiers.Any(SyntaxKind.PartialKeyword))
ClassCandidates.Add(cds);
}
}
私有类MySyntaxReceiver:ISyntaxReceiver
{
公共列表类候选对象{get;}=new();
在VisitSyntaxNode(SyntaxNode节点)上的公共无效
{
if(节点为ClassDeclarationSyntax cds&&cds.Modifiers.Any(SyntaxKind.PartialKeyword))
添加(CD);
}
}
然后在源生成器的Execute方法中,您可以在收集的所有节点上循环。
我是从一个信息丰富的视频中得到这个方法的
下面是演示中的github和演示,我从以下示例中学到了这一点:
您可以这样更改接收器:
private class MySyntaxReceiver : ISyntaxReceiver
{
public List<ClassDeclarationSyntax> ClassCandidates { get; } = new();
public void OnVisitSyntaxNode(SyntaxNode node)
{
if (node is ClassDeclarationSyntax cds && cds.Modifiers.Any(SyntaxKind.PartialKeyword))
ClassCandidates.Add(cds);
}
}
私有类MySyntaxReceiver:ISyntaxReceiver
{
公共列表类候选对象{get;}=new();
在VisitSyntaxNode(SyntaxNode节点)上的公共无效
{
if(节点为ClassDeclarationSyntax cds&&cds.Modifiers.Any(SyntaxKind.PartialKeyword))
添加(CD);
}
}
然后在源生成器的Execute方法中,您可以在收集的所有节点上循环。
我是从一个信息丰富的视频中得到这个方法的
下面是演示中的github和演示,我从以下示例中学到了这一点: