Получение базового класса вызова метода в Roslyn

Вопрос:

Я могу идентифицировать вызовы методов и вызовы внутри методов каждого класса приложения. Однако как я могу получить, на какой класс они вызваны или вызваны?

В следующем коде, например:

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)». Что мне нужно извлечь из этого, так это то, что ADD вызывается на b1, который является экземпляром класса B. Как я могу получить этот класс B из вызовов в приведенном выше коде? Другими словами, мне нужно указать, к какому типу класса принадлежит этот метод. Как я могу это сделать?

Лучший ответ:

Спасибо вам всем! Вот решение, которое выполняет эту работу; не уверен, хотя, если это лучшее решение и элегантный:

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

Последняя строка получает имя класса вызываемого метода (как String) и выводит его.

Ответ №1

Вам нужна семантическая модель, которая позволяет вам получать информацию о типе от компилятора (дерево синтаксиса рассматривает только синтаксис в файле).

В частности, вы должны вызвать GetSymbol() в InvocationExpressionSyntax, бросить в IMethodSymbol и посмотреть на его различные свойства.

Оцените статью
TechArks.Ru
Добавить комментарий