【问题标题】:Getting one Roslyn syntax receiver per class每个类获得一个 Roslyn 语法接收器
【发布时间】:2021-03-28 04:15:51
【问题描述】:

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

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

【问题讨论】:

    标签: c# roslyn sourcegenerators


    【解决方案1】:

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

    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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-26
      • 2020-03-05
      • 2020-01-22
      相关资源
      最近更新 更多