【问题标题】:Roslyn - find all references to method with invocation details (concrete generic arguments)Roslyn - 查找对具有调用详细信息的方法的所有引用(具体的通用参数)
【发布时间】:2020-10-23 09:08:32
【问题描述】:

假设我有一个带有一些通用方法的接口,比如说这个:

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

然后我有一堆项目的一些解决方案,我有以下参考资料:

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

现在的目标是找到这个方法的所有调用以及更重要的——具体的泛型参数是什么。在这种特殊情况下,我想发现 IService.DoGenericAsync&lt;T&gt;() 是使用泛型参数 &lt;A&gt; 调用的。

因此,按照那里的几个教程和问题,我可以使用 Roslyn 找到对目标方法的所有引用,方法是找到我的接口方法声明的 ISymbol,然后调用 SymbolFinder.FindReferencesAsync 以获取所有引用。

这很好用,我得到了正确的调用位置(ReferencedSymbol 实例的集合,但是这些结果的Definition 属性只返回了符号的一般信息(嗯,完全是定义:)),所以我如何找出实际的论点是什么?

【问题讨论】:

    标签: c# generics roslyn roslyn-code-analysis


    【解决方案1】:

    所以ReferenceLocation 有两个属性,一个Document 和一个Location。该文档允许您获取SyntaxTreeSemanticModel。当您拥有SyntaxTree 时,您可以调用 FindNode 并传入Location.SourceSpan,这样您就可以获得调用节点。从那里您可以调用SemanticModel.GetSymbolInfo,这将为您提供一个包含方法符号的结构,然后您可以从那里查看类型参数。

    【讨论】:

      【解决方案2】:

      免责声明:很遗憾,我还没有完成这个宠物项目,但这是我根据接受的答案编写的代码示例:

      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
          }
      }
      

      在这种情况下,referencesReferencedSymbol 的集合(我在问题中所说的那个); compilations - 是 Compilation 的集合,用于我正在分析的已加载解决方案中的所有项目。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        • 2016-10-24
        • 1970-01-01
        相关资源
        最近更新 更多