在 Roslyn 中获取方法调用的基础 class

Getting base class of a method invocation in Roslyn

我可以在应用程序的每个 class 的方法中识别方法调用和调用。但是,我怎样才能知道它们被调用或调用的 class?

在下面的代码中,例如:

var methodDeclarations = classitem.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{

    var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
    foreach (InvocationExpressionSyntax invoc in varInvocations)
    {
        Console.WriteLine("---- Invocations---");
        Console.WriteLine(invoc.Expression);  // output: b1.ADD
        Console.WriteLine(invoc.Expression.Parent.GetText()); // output: b1.ADD(2)
    }
}

我可以得到,例如,作为输出 "b1.ADD" 和 "b1.ADD(2)"。我需要从中提取的是在 b1 上调用 ADD,它是 class B 的一个实例。如何从上面代码中的调用中获取此 B class?换句话说,我需要告诉这个方法属于哪个 class 类型。我该怎么做?

您需要语义模型,它允许您从编译器访问类型信息(语法树只查看文件中的语法)。

具体来说,您应该在 InvocationExpressionSyntax 上调用 GetSymbol(),转换为 IMethodSymbol,并查看其各种属性。

谢谢大家!这是完成这项工作的解决方案;不确定它是否是最佳解决方案和优雅的解决方案:

var model = compilation.GetSemanticModel(tree);
var methodDeclarations = classitem.DescendantNodes().OfType<MethodDeclarationSyntax>();
foreach (var memmeth in methodDeclarations)
{

    var varInvocations = memmeth.DescendantNodes().OfType<InvocationExpressionSyntax>();
    foreach (InvocationExpressionSyntax invoc in varInvocations)
    {
        Console.WriteLine("---- Invocations---");
        Console.WriteLine(invoc.Expression);  // output: b1.ADD
        Console.WriteLine(invoc.Expression.Parent.GetText()); // output: b1.ADD(2)
        var invokedSymbol = model.GetSymbolInfo(invoc).Symbol;
        Console.WriteLine(invokedSymbol.ToString()); //AppTest.B.ADD(int)
        Console.WriteLine(invokedSymbol.ContainingSymbol); //AppTest.B
        Console.WriteLine(invokedSymbol.ContainingSymbol.Name); //B  
    }
}

最后一行获取调用方法的 class 名称(作为字符串)并将其打印出来。