使用 Roslyn 查找特定方法的所有方法调用

本文关键字:有方法 调用 方法 Roslyn 查找 使用 | 更新日期: 2023-09-27 18:34:56

我正在使用Roslyn开发代码分析器,我目前的任务是查找程序集中未使用的所有内部方法。

我从一个MethodDeclarationSyntax开始,并从中得到符号。 然后我在SymbolFinder中使用 FindCallersAsync 方法,但即使我在程序集中的某个地方调用有问题的方法,它也返回一个空集合。 请参阅下面的代码。

protected override void Analyze(SyntaxNodeAnalysisContext context)
{
    NodeToAnalyze = context.Node;
    var methodDeclaration = NodeToAnalyze as MethodDeclarationSyntax;
    if (methodDeclaration == null)
        return;
    var methodSymbol = context.SemanticModel.GetDeclaredSymbol(methodDeclaration) as ISymbol;
    if (methodSymbol.DeclaredAccessibility != Accessibility.Internal)
        return;
    var solutionPath = GetSolutionPath();
    var msWorkspace = MSBuildWorkspace.Create();
    var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
    var callers = SymbolFinder.FindCallersAsync(symbol, solution).Result;  // Returns empty collection.
    ...
}

我在这里看到了类似的代码,但是在该示例中,方法符号是在InvocationExpressionSyntax上使用GetSymbolInfo获得的:

//Get the syntax node for the first invocation to M()
var methodInvocation = doc.GetSyntaxRootAsync().Result.DescendantNodes().OfType<InvocationExpressionSyntax>().First();
var methodSymbol = model.GetSymbolInfo(methodInvocation).Symbol;
//Finds all references to M()
var referencesToM = SymbolFinder.FindReferencesAsync(methodSymbol,  doc.Project.Solution).Result;

但是,就我而言,我需要从声明中找到调用(如果有的话(。 如果我首先获得调用并从GetSymbolInfo传入符号,则正确返回对该方法的调用 - 因此问题似乎出在symbol参数上,而不是solution

由于我试图获取声明的基础符号,因此我不能使用 GetSymbolInfo ,而是使用 GetDeclaredSymbol 代替(如此处建议(。

我从这篇文章中的理解是,从GetDeclaredSymbolGetSymbolInfo返回的符号应该是相同的。 但是,使用 Equals 进行简单比较false

有没有人知道返回的两个符号之间的区别是什么,以及如何获得有效的"正确"符号? 或者也许有更好的方法? 我所有的研究似乎都指向FindCallersAsync,但我就是无法让它发挥作用。

使用 Roslyn 查找特定方法的所有方法调用

我从这篇文章的理解是,从GetDeclaredSymbol和GetSymbolInfo返回的符号应该是相同的。但是,使用 Equals 的简单比较将返回 false。

这是因为它们不是同一个符号;它们来自完全不同的编译,这些编译可能不同,也可能不同。一个来自正在积极编译的编译器,一个来自MSBuildWorkspace。

从根本上说,不支持在分析器中使用 MSBuildWorkspace。完全。别这样。这不仅会非常慢,而且还存在各种正确性问题,尤其是在Visual Studio中运行分析器时。如果您的目标是在解决方案中的任何位置查找未使用的方法,那么我们也不真正支持将其作为分析器实现,因为这涉及跨项目分析。