在 Roslyn 分析器中分析 post-预处理器代码

Analyze post-preprocessor code in Roslyn analyzer

我正在编写一个 Roslyn 分析器(实际上是源代码生成器,但它们在很大程度上共享相同的 API),我希望它只分析 post-处理器代码。例如,如果我有使用#if/#else 排除的代码,我希望我的分析器不处理该代码。同样,我希望#beginregion/#endregion 之类的东西不要出现在我的分析器中。

有没有办法从 Roslyn 获得 post 预处理的编译或语法树?我可以做类似下面的事情,但它会丢弃我所有的原始位置信息,我猜我的编译语义模型对新生成的语法树一无所知:

var preprocessorSymbols = candidate.SyntaxTree.Options.PreprocessorSymbolNames;
var parseOptions = CSharpParseOptions.Default.WithPreprocessorSymbols(preprocessorSymbols);
var newSyntaxTree = CSharpSyntaxTree.ParseText(candidate.SyntaxTree.ToString(), parseOptions);

Roslyn 解析器已经跳过了#if/#else 中不活动的代码,因为解析器本身就是处理这些代码的。跳过的文本在树中仍然表示为 trivia,这是附加到语法节点的数据,但根本没有常规语法节点。因此,您的分析器不会偶然发现表示禁用 #if 内部代码的语法节点,因为它一开始就不存在。

另一方面,对于#regions,这些并不特别;语法树包含额外的琐事;如果你想排除其中的代码,你可以走这些并找到它们。如果您需要更多详细信息,则必须更具体地满足您的需求。