Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Roslyn Get Method Declaration from InvocationExpression

Tags:

c#

roslyn

I'm making a roslyn demo for generating compiler warnings from attributes

I have an analyzer to analyze Method Invocations which looks like so:

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

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

I'm trying to figure out how to get the method declaration, I know I can use the SymbolFinder to search for the method declaration

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

This options is expensive and annoying, and it leaves open the possiblity for error because what if your invoking method is coming from an assembly.

What is the easiest way to get the method declaration from an InvocationExpressionSyntax? Should I just be using the symbol finder and if it fails use scour the imported assemblies or is there an easier better way?

like image 287
johnny 5 Avatar asked Jul 27 '17 21:07

johnny 5


1 Answers

If you need the declaration of the method that you are calling, you can get that as follows.

In the first step, you find out what method it is that is being called:

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

Remember that there are various reasons why the methodSymbol may be null (e.g. you were invoking a delegate, not a method), so test for that.

Then you can find the declaring syntax references, and take the first one:

var syntaxReference = methodSymbol
    .DeclaringSyntaxReferences
    .FirstOrDefault();

This can be null as well, e.g. when you were calling a method from another assembly, so test for that.

Finally:

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

That gives you the syntax. Should you need a semantic model for that declaration, you can get that using

var semanticModel = context.Compilation.GetSemanticModel(declaration.SyntaxTree);
like image 190
Kris Vandermotten Avatar answered Oct 30 '22 03:10

Kris Vandermotten