Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting generic arguments for SymbolCallerInfo in Roslyn

I'm attempting to find all locations in a solution that calls the method IBus.Publish<T> (from NServiceBus). So far this is working:

IMethodSymbol method = ... [IBus.Publish methodsymbol resolved];
var callers = method.FindCallers(solution, new CancellationToken());

This results in a IEnumerable<SymbolCallerInfo> and I get all the correct references to this method.

How would I now go about to get the generic argument IBus.Publish was called with? Do I have to parse the sourcetree manually, or does it exist some Roslyn magic I can leverage?

Example:

In my code I have:

IBus _bus;

_bus.Publish<IMyMessage>(msg => { msg.Text = "Hello world"});

I'm interested in getting the IMyMessage type.

Greatly appreciate the help!

like image 271
Yngve B-Nilsen Avatar asked Sep 04 '25 17:09

Yngve B-Nilsen


1 Answers

You can use a SemanticModel to go from the SyntaxNode for the call to the actual MethodSymbol, and then you can just read the TypeArguments property to get the TypeSymbols for the arguments. That will even work if the arguments aren't specified explicitly, since the SemanticModel will perform type inference.

For example:

var callers = method.FindCallers(solution, CancellationToken.None);
foreach (var caller in callers)
{
    foreach (var location in caller.Locations)
    {
        if (location.IsInSource)
        {
            var callerSemanticModel = solution
                .GetDocument(location.SourceTree)
                .GetSemanticModel();
            var node = location.SourceTree.GetRoot()
                .FindToken(location.SourceSpan.Start)
                .Parent;
            var symbolInfo = callerSemanticModel.GetSymbolInfo(node);
            var calledMethod = symbolInfo.Symbol as IMethodSymbol;
            if (calledMethod != null)
            {
                var arguments = calledMethod.TypeArguments;
            }
        }
    }
}
like image 183
Quartermeister Avatar answered Sep 07 '25 13:09

Quartermeister



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!