Search code examples
c#genericsroslynroslyn-code-analysis

Roslyn - find all references to method with invocation details (concrete generic arguments)


Suppose I have an interface with some generic method, say this one:

public interface IService
{
    Task DoGenericAsync<T>();
}

Then I have some solution with a bunch of projects and I have the following references:

class SomeDomainService
{
    private readonly IService _service;
    
    public Task Process()
        => _service.DoGenericAsync<A>();
}

Now the goal is to find all invocations of this method and what is more important - what is the concrete generic argument. In this particular case I want to find that IService.DoGenericAsync<T>() was called with generic parameter <A>.

So following several tutorials and questions out there, I'm able to find all references to the target method using Roslyn by finding the ISymbol of my interface method declaration and then calling SymbolFinder.FindReferencesAsync to get all references.

This works great and I get correct locations of invocations (a collection of ReferencedSymbol instances, however the Definition property of those results returns me only the general info on the symbol (well, exactly definition :) ), so how do I find out what's the actual arguments were?


Solution

  • So the ReferenceLocation has two properties, a Document and a Location. The document lets you fetch the SyntaxTree and SemanticModel. When you have the SyntaxTree, you can call FindNode and pass in Location.SourceSpan, and that should get you the invocation node. From there you can call SemanticModel.GetSymbolInfo and that will give you a struct that contains the method symbol, and from there you can take a look at the type arguments.