0

我有一个简单的源生成器定义为

[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()每个受影响的语法节点运行一次,即,让它在每个部分类中运行一次?

4

1 回答 1

2

您可以像这样更改您的接收器:

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);
  }
}

然后在源生成器的 Execute 方法中,您可以在您收集的所有节点上循环。我从一个内容丰富的视频中得到了这种方法

https://www.youtube.com/watch?v=P9Pv5IdinMU

这是演示文稿中带有演示的 github,我从这些示例中学到了这一点:

https://github.com/JasonBock/SourceGeneratorDemos

于 2021-03-28T11:14:49.280 回答