我正在尝试漂亮地打印方法调用,直到特定的方法
例如,让我们从这个简单的随机存储库中获取“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