在 DiagnosticAnalyzer 的操作回调中,如何获取从中派生 SyntaxNode 的文档或项目?

In a DiagnosticAnalyzer's action callback, how do I get the Document or Project from which the SyntaxNode was derived?

我正在编写一个 DiagnosticAnalyzer,并为 SyntaxKind.Attribute 注册一个 SyntaxNode 操作。该属性命名了项目中的其他一些文件。

例如,正在分析的代码可能包括

[RelatedFile("otherFileName.foo")] interface Whatever {...}

在我的分析回调中,我希望能够从正在分析的项目的角度访问相关文件的内容。所以,我需要:

  1. SyntaxNode中提取文件名。这个我可以。
  2. 获取描述包含正在分析的代码的文档的对象。 我不知道该怎么做。
  3. 获取描述包含正在分析的代码的项目的对象。 我不知道该怎么做。
  4. 查明项目是否包含指定名称的文档。这个我可以。
  5. 打开并解析或更新该文件的内容。我觉得我可以做到。

我卡在了步骤 (2) 和 (3) 上。 (是的,我可能不需要严格执行第 2 步,但我仍然想知道如何操作。)

SyntaxNodeAnalysisContext 参数中,我可以得到 Workspace 对象,从中得到 Solution 对象,从中得到 Project 对象的集合。但我看不出有什么方法可以将特定的 SyntaxNode 与它所来自的 ProjectDocument 联系起来。

任何有关如何执行此操作的想法都将不胜感激。

我找到了:

Workspace workspace = ...;
SyntaxNode node = ...;
Document document = workspace.Solution.GetDocument(node.SyntaxTree);
Project project = document.Project;

我不知道为什么我没有早点看到。 编辑:我现在知道为什么我没有早点看到它。获得 Workspace 需要使用 AnalyzerOptions.

的非 public 属性

您可以通过...

SyntaxNodeAnalysisContext 获得 Workspace
SyntaxNodeAnalysisContext context = ...;
AnalyzerOptions options = context.Options;
Workspace workspace = (Workspace)
    (options.GetType().GetRuntimeProperty("Workspace").GetValue(options));

它不是很漂亮,但是很管用。我希望有更好的方法。