Roslyn получает метод декларации от Invocation

Я делаю Roslyn демо для генерации предупреждений компилятора из атрибутов

У меня есть анализатор для анализа вызовов методов, который выглядит так:

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzerInvocation, SyntaxKind.InvocationExpression);
}

private static void AnalyzerInvocation(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;
}

Я пытаюсь выяснить, как получить объявление метода, я знаю, что могу использовать SymbolFinder искать объявление метода

var model = compilation.GetSemanticModel(tree);

//Looking at the first method symbol
var methodSyntax = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>()
   .First(/*TODO: Execute Find for related symbol */);

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

Какой самый простой способ получить объявление метода из InvocationExpressionSyntax? Должен ли я просто использовать поиск символов и, если он не работает, использовать чистку импортированных сборок или есть более простой способ?

1 ответ

Решение

Если вам нужно объявление метода, который вы вызываете, вы можете получить его следующим образом.

На первом этапе вы узнаете, какой метод вызывается:

var methodSymbol = context
    .SemanticModel
    .GetSymbolInfo(invocation, context.CancellationToken)
    .Symbol as IMethodSymbol;

Помните, что существуют разные причины, по которым methodSymbol может иметь значение null (например, вы вызывали делегат, а не метод), поэтому проверьте это.

Затем вы можете найти объявления синтаксиса и взять первый:

var syntaxReference = methodSymbol
    .DeclaringSyntaxReferences
    .FirstOrDefault();

Это также может быть нулевым, например, когда вы вызывали метод из другой сборки, так что проверьте это.

В заключение:

var declaration = syntaxReference.GetSyntax(context.CancellationToken);

Это дает вам синтаксис. Если вам нужна семантическая модель для этого объявления, вы можете получить это, используя

var semanticModel = context.Compilation.GetSemanticModel(declaration.SyntaxTree);
Другие вопросы по тегам