Supernova
Supernova

Reputation: 147

Getting base class of a method invocation in Roslyn

I can identify method calls and invocations inside the methods of each class of an application. However, how can I get on which class they are called or invoked?

In the following code, for instance:

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)
    }
}

I can get, for example, as output "b1.ADD" and "b1.ADD(2)". What I need to extract from this is that ADD is called on b1 which is an instance of class B. How can I get this B class from the invocations in the code above? In other words, I need to tell to which class type this method belongs. How can I do that?

Upvotes: 2

Views: 1591

Answers (2)

Supernova
Supernova

Reputation: 147

Thank you all! Here is the solution that does the job; not sure though if it is the best solution and an elegant one:

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  
    }
}

The last line gets the class name of the invoked method (as String) and prints it out.

Upvotes: 0

SLaks
SLaks

Reputation: 888203

You need the Semantic Model, which allows you to access type information from the compiler (the syntax tree only looks at syntax in a file).

Specifically, you should call GetSymbol() on the InvocationExpressionSyntax, cast to IMethodSymbol, and look at its various properties.

Upvotes: 1

Related Questions