我试图静态地构建C#解决方案的调用层次结构,或者换句话说,试图找出解决方案中每个方法调用的方法。
我稍微修改了另一个问题的代码片段,但它没有完全削减它:
每当调用基类方法时,链就会被破坏,而该方法又会调用在子类中实现的抽象或虚方法。
var syntaxTree = SyntaxTree.ParseText(Code);
var compilation = Compilation.Create("name").AddSyntaxTrees(syntaxTree);
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var methods = syntaxTree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var method in methods)
{
var invocations = method.DescendantNodes().OfType<InvocationExpressionSyntax>();
foreach (var syntax in invocations)
Debug.WriteLine(semanticModel.GetDeclaredSymbol(method) + " calls method " +
semanticModel.GetSymbolInfo(syntax).Symbol);
}
以下是一些示例代码来说明问题。基类方法Bar调用在C2中实现的抽象方法Baz。
class Program2
{
void Main()
{
new C2().Bar();
}
}
abstract class C1
{
public void Bar()
{
Baz();
}
public abstract void Baz();
}
class C2 : C1
{
public override void Baz() { }
}
然而,当在示例代码上运行顶部代码片段时,它认为调用是C1.Baz():
Program2.Main() calls method C1.Bar()
C1.Bar() calls method C1.Baz()
我们如何使用语义模型来确定它实际上会执行C2.Baz()?