Как найти типы аргументов метода при вызове метода? - PullRequest
0 голосов
/ 16 апреля 2020

Предположим, у нас есть следующая базовая модель:

public class Base
{
   ...
}

и M 1 , ..., M n моделей, полученных из этой.

У нас есть интерфейс со следующей структурой:

public interface IExampleInterface
{
    void DoSomething(Base input);
}

И предположим, у нас есть простая реализация для этого класса, например, такая:

public class Example : IExampleInterface
{
   void DoSomething(Base input) 
   {
       System.Console.WriteLine("Please help me!!");
   }
}

Там Есть много вызовов IExampleInterface.DoSomething метода с различными входными аргументами в решении.

var ex = new Example();
var m = new M();
ex.DoSometing(m);

, где M может быть любого типа от M 1 , ..., M n .

Мне удалось найти интерфейс из дерева синтаксиса, его реализацию и параметр типы, даже больше я нашел вызывающих, но у меня проблемы с поиском типа передаваемых аргументов в вызовах IExampleInterface.DoSomething .

Вот код:

var interfaceName = "IExampleInterface";
var returnType = "Void";
var methodName = "DoSomething";
var arg = "Base";

var exInterface = compilations
        .SelectMany(compilation => compilation.SyntaxTrees.Select(syntaxTree => compilation.GetSemanticModel(syntaxTree)))
        .SelectMany(
            semanticModel => semanticModel
                .SyntaxTree
                .GetRoot()
                .DescendantNodes()
                .OfType<InterfaceDeclarationSyntax>()
                .Select(interfaceDeclarationSyntax => semanticModel.GetDeclaredSymbol(interfaceDeclarationSyntax)))
        .Where(s => s.Name == interfaceName)
        .FirstOrDefault();

var implementations = await SymbolFinder.FindImplementationsAsync(exInterface, solution);
var implementation = implementations.FirstOrDefault() as ITypeSymbol;
var method = exInterface
        .GetMembers(methodName)
        .Where(m => m.Kind == SymbolKind.Method)
        .Cast<IMethodSymbol>()
        .FirstOrDefault(m =>
            m.Parameters != null &&
            m.Parameters.Length == 1 &&
            m.Parameters[0].Type.Name == arg &&
            m.ReturnType.Name == returnType);

var callers = await SymbolFinder.FindCallersAsync(method, solution);

На данный момент я застрял. Я относительно новичок в Рослин . У меня вопрос, как найти тип аргументов, передаваемых на IExampleInterface.DoSomething вызовов?

1 Ответ

0 голосов
/ 27 апреля 2020

Я на самом деле решил проблему, получив semanti c модель компиляций.

Во-первых, после нахождения всех абонентов нам нужно найти InvocationExpression узлов с помощью CallingSymbol из SymbolCallerInfo .

Во-вторых, мы должны получить интересующий нас аргумент из ArgumentList свойство InvocationExpression .

Предположим, что arg является желаемым аргументом, а compilation является экземпляром Compilation, где arg от.

var type = compilation
      .GetSemanticModel(arg.SyntaxTree)
      .GetTypeInfo(arg.ChildNodes().First());
...