生成来电图

问题描述 投票:0回答:1

我正在尝试漂亮地打印方法调用,直到特定的方法

例如,让我们从这个简单的随机存储库中获取“DisplayHelp”

我期待类似的事情

Shell.ctor -> GetHelp -> DisplayHelp

using Broslyn; // dotnet add package Broslyn --version 1.2.0
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;

var csproj = "./clisharp/clisharp.csproj"; // git clone https://github.com/citrus-thunder/clisharp
var methodName = "DisplayHelp";

var workspace = CSharpCompilationCapture.Build(csproj).Workspace;
var project = workspace.CurrentSolution.Projects.FirstOrDefault();
var compilation = await project.GetCompilationAsync();

var targetMethod = compilation.SyntaxTrees
    .SelectMany(tree => tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>())
    .FirstOrDefault(method => method.Identifier.ValueText == methodName);

var incomingCallGraph = new Dictionary<IMethodSymbol, List<IMethodSymbol>>();
BuildIncomingCallGraph(compilation, targetMethod, incomingCallGraph);


void BuildIncomingCallGraph(Compilation compilation, MethodDeclarationSyntax targetMethodSyntax, Dictionary<IMethodSymbol, List<IMethodSymbol>> incomingCallGraph) {
    var targetMethodSymbol = compilation.GetSemanticModel(targetMethodSyntax.SyntaxTree).GetDeclaredSymbol(targetMethodSyntax) as IMethodSymbol;

    var allMethods = compilation
        .SyntaxTrees
        .SelectMany(tree => tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>())
        .Select(methodSyntax => compilation.GetSemanticModel(methodSyntax.SyntaxTree).GetDeclaredSymbol(methodSyntax) as IMethodSymbol)
        .Where(methodSymbol => methodSymbol != null);

    foreach (var _mtd in allMethods) {
        var invocations = SymbolFinder
            .FindCallersAsync(targetMethodSymbol, workspace.CurrentSolution, cancellationToken: default).Result;
        var callers = invocations
            .Select(invocation => invocation.CallingSymbol as IMethodSymbol)
            .Where(caller => caller != null);
        foreach (var caller in callers) {
            if (!incomingCallGraph.ContainsKey(targetMethodSymbol)) {
                incomingCallGraph[targetMethodSymbol] = new List<IMethodSymbol>();
            }

            incomingCallGraph[targetMethodSymbol].Add(caller);
        }
    }
}

电流输出:

方法:DisplayHelp -> 调用者:GetHelp -> 调用者:DisplayHelp -> 调用者:GetHelp -> 调用者:DisplayHelp -> 调用者:GetHelp -> 调用者:DisplayHelp -> 调用者:GetHelp -> 调用者:DisplayHelp

c# roslyn code-analysis
1个回答
0
投票

您可以使用 NDepend 轻松生成调用图。

只需下载免费试用版,启动 VisualNDepend.exe,分析您的 .NET 解决方案,在“搜索”面板中搜索您的方法,然后右键单击“选择直接或间接使用我的方法”

这里生成了一个代码查询就是结果,然后点击导出到图表:

瞧瞧!您可以轻松更改分组,这里是按父类分组:

请参阅此处的文档

© www.soinside.com 2019 - 2024. All rights reserved.