在 rosyln 中,如何获取给定位置的语法节点?

In rosyln, how to get the syntaxnode with a location given?

我目前正在学习 roslyn 源代码生成器。我打算制作的是一个源代码生成器,当类型为 interit 接口但未实现相应成员时,它会自动实现接口 属性 成员。自动实现的成员默认为 auto属性。

到目前为止我做了什么:

    [Generator]
    public class AutoImplementInterfaceGenerator : ISourceGenerator {
        public void Initialize(GeneratorInitializationContext context) {
            context.RegisterForSyntaxNotifications(() => new MySyntaxContextReceiver());
            
        }

        public void Execute(GeneratorExecutionContext context) {
            List<Location> Locations = new List<Location>();
            foreach (Diagnostic diagnostic in context.Compilation.GetDeclarationDiagnostics()) {
                if (diagnostic.Id == "CS0535" && !Locations.Contains(diagnostic.Location)) {
                    Locations.Add(diagnostic.Location);
                }
            }
            foreach (Location location in Locations) {
                SymbolFinder.FindSymbolAtPositionAsync()
            }
        }
    }

如您所见,我一直在寻找 SyntaxNode of where Compiler Error CS0535 occur, which is represented by Diagnostic.Location(See here). An alternative I found was SymbolFinder.FindSymbolAtPositionAsync(See here) 方法,但它需要 DocumentWorkspace。我不知道如何在与源生成器相关的 API 中获取它的实例。

位置类型引用了位置来自的语法树。您需要获取“根”节点(树中的第一个节点),然后在根上调用 FindNode 以获取给定范围内最近的子节点。应该看起来像这样:

foreach (Location location in Locations) {
    SyntaxNode rootNode = location.SourceTree.GetRoot();
    SyntaxNode nodeAtLocation = rootNode.FindNode(location.SourceSpan);
}