在 Roslyn 中获取 SymbolCallerInfo 的通用参数

Yng*_*sen 3 c# generics roslyn

我试图在调用该方法的解决方案中找到所有位置IBus.Publish<T>(来自 NServiceBus)。到目前为止,这是有效的:

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

这导致 aIEnumerable<SymbolCallerInfo>并且我得到了对该方法的所有正确引用。

我现在将如何去IBus.Publish调用泛型参数?我是否必须手动解析源树,或者它是否存在一些我可以利用的 Roslyn 魔法?

例子:

在我的代码中,我有:

IBus _bus;

_bus.Publish<IMyMessage>(msg => { msg.Text = "Hello world"});
Run Code Online (Sandbox Code Playgroud)

我有兴趣获得IMyMessage类型。

非常感谢您的帮助!

Qua*_*ter 5

您可以使用 aSemanticModelSyntaxNodefor 调用转到实际MethodSymbol,然后您只需读取TypeArguments属性即可获取TypeSymbol参数的s 。如果未明确指定参数,这甚至会起作用,因为SemanticModel将执行类型推断。

例如:

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)