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