如何解决Roslyn-查找对方法的所有引用以及调用详细信息具体的泛型参数
假设我有一个带有一些通用方法的接口,说这个:
public interface IService
{
Task DoGenericAsync<T>();
}
然后我对一些项目有一些解决方案,并且我有以下参考文献:
class SomeDomainService
{
private readonly IService _service;
public Task Process()
=> _service.DoGenericAsync<A>();
}
现在的目标是找到此方法的所有调用,更重要的是-具体的泛型参数是什么。在这种情况下,我想发现IService.DoGenericAsync<T>()
是用通用参数<A>
调用的。
因此,按照下面的几个教程和问题,我可以通过找到接口方法声明的ISymbol
然后调用SymbolFinder.FindReferencesAsync
来获取所有使用Roslyn对目标方法的引用。参考。
这很好用,我可以得到正确的调用位置(ReferencedSymbol
实例的集合,但是这些结果的Definition
属性仅向我返回该符号的一般信息(嗯,确切地是: )),那么如何找出实际的参数呢?
解决方法
因此,ReferenceLocation
具有两个属性,Document
和Location
。该文档使您可以获取SyntaxTree
和SemanticModel
。当您拥有SyntaxTree
时,可以调用FindNode并传入Location.SourceSpan
,这将为您带来调用节点。从那里可以调用SemanticModel.GetSymbolInfo
,这将为您提供一个包含方法符号的结构,从那里可以查看类型参数。
免责声明:不幸的是,我还没有完成这个宠物项目,但这是我根据公认的答案编写的代码示例:
foreach (var reference in references)
{
foreach (var location in reference.Locations)
{
var syntaxTree = await location.Document.GetSyntaxTreeAsync();
var root = await syntaxTree.GetRootAsync();
var syntaxNode = root.FindNode(location.Location.SourceSpan);
var compilation = compilations.First(x => x.ContainsSyntaxTree(syntaxTree));
var semanticModel = compilation.GetSemanticModel(syntaxTree);
var symbolInfo = semanticModel.GetSymbolInfo(syntaxNode);
var methodSymbol = (symbolInfo.Symbol ?? symbolInfo.CandidateSymbols.First()) as IMethodSymbol;
var typeSymbol = methodSymbol.TypeArguments.First();
// then use 'typeSymbol' to find the actual type etc
}
}
在这种情况下,references
是ReferencedSymbol
的集合(我在问题中正在谈论的那个);和compilations
-是我正在分析的已加载解决方案中所有项目的Compilation
的集合。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。