有没有办法在 Roslyn 中可视化 SemanticModel

Is there a way to visualize the SemanticModel in Roslyn

在许多不同的情况下,我使用 Roslyn 在 SemanticModel 中搜索符号但找不到它。

var sm = compilation.GetSemanticModel(tree);
sm.GetSymbolInfo(node);
sm.GetDeclaredSymbol(node);

所以我想检查语义模型。

这对调试有帮助。

编辑

按照 Dudi Keleti 的方法,这段代码非常有效:

return tree.GetRoot().DescendantNodesAndSelf()
         .Where(node => node as ClassDeclarationSyntax != null || node as InterfaceDeclarationSyntax != null)
         .Select(node => new KeyValuePair<SyntaxNode, ISymbol>(node, model.GetSymbolInfo(node).Symbol ?? model.GetDeclaredSymbol(node)));

我不知道可视化工具,但你可以这样做:

static IEnumerable<ISymbol> GetTeeSymbols(SyntaxTree tree, SemanticModel model)
{
    return tree.GetRoot().
             DescendantNodesAndSelf().
             Select(node => model.GetSymbolInfo(node).Symbol ?? model.GetDeclaredSymbol(node)).Where(info => info != null);
}

您可以将其作为树上的扩展方法并发送语义模型或​​语义模型的扩展并发送 IEnumerable<SyntaxTree> 而不是遍历每个方法并执行 LINQ

我不知道它是否完美,但它让您了解发生了什么。 在我的编译中它看起来像这样:

有了它,您可以构建自己的可视化工具,或者创建一个 VISX 以在 Visual Studio 中显示它。

更新

我写完后,发现一个sample code in Roslyn编译中枚举符号

同时检查 GetAllFieldAndMethodSymbolsInACompilation and TraverseAllExpressionsInASyntaxTreeUsingAWalker。 请记住,对于完整的解决方案,您还需要跟踪引用的程序集。

SemanticModel 只是语法和符号之间的桥梁,它允许您查询部分语法中的符号。然而,这些符号都可以从 Compilation 中获得。 Compilation.GetTypeByMetadataName 在这方面是你的朋友。