使用Roslyn查找特定方法的所有方法调用 [英] Find all method calls for a specific method using Roslyn

查看:54
本文介绍了使用Roslyn查找特定方法的所有方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Roslyn在代码分析器上工作,我的当前任务是查找程序集中未使用的所有内部方法.

I am working on a code analyser using Roslyn and my current task is to find all internal methods which are unused in the assembly.

我从 MethodDeclarationSyntax 开始,并从中获取符号.然后,我在 SymbolFinder 中使用了 FindCallersAsync 方法,但是即使我在程序集中某处调用该方法时,它也会返回一个空集合.请参见下面的代码.

I start with a MethodDeclarationSyntax and get the symbol from that. I then use the FindCallersAsync method in SymbolFinder, but it returns an empty collection even when I am making a call to the method in question somewhere in the assembly. See the code below.

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 获得的:

I have seen similar code here, but in that example the method symbol is obtained using GetSymbolInfo on an InvocationExpressionSyntax:

//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 参数而不是<代码>解决方案.

However, in my case, I need to find the invocations (if any) from a declaration. If I do get the invocation first and pass in the symbol from GetSymbolInfo the calls to the method are returned correctly - so the issue seems to be with the symbol parameter and not solution.

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

Since I am trying to get the underlying symbol of a declaration, I cannot use GetSymbolInfo, but use GetDeclaredSymbol instead (as suggested here).

My understanding from this article is that the symbols returned from GetDeclaredSymbol and GetSymbolInfo should be the same. However, a simple comparison using Equals returns false.

有人知道返回的两个符号之间的区别是什么,如何获得能正常工作的正确"符号吗?还是完全有更好的方法?我所有的研究似乎都指向 FindCallersAsync ,但是我无法使其正常工作.

Does anyone have any idea of what the difference is between the two symbols returned and how I can get the 'correct' one which works? Or perhaps there is a better approach entirely? All my research seems to point to FindCallersAsync, but I just can't get it to work.

推荐答案

根据本文的理解,从GetDeclaredSymbol和GetSymbolInfo返回的符号应该相同.但是,使用Equals进行的简单比较将返回false.

My understanding from this article is that the symbols returned from GetDeclaredSymbol and GetSymbolInfo should be the same. However, a simple comparison using Equals returns false.

这是因为它们不是相同的符号;它们来自完全不同的编译,可能相同也可能不同.一种来自主动编译的编译器,另一种来自MSBuildWorkspace.

This is because they're not the same symbol; they are coming from entirely different compilations which might or might not be different. One is coming from the compiler that is actively compiling, one is coming from MSBuildWorkspace.

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

Fundamentally, using MSBuildWorkspace in an analyzer is unsupported. Completely. Don't do that. Not only would that be really slow, but it also has various correctness issues, especially if you're running your analyzer in Visual Studio. If your goal is to find unused methods anywhere in a solution, that's something we don't really support implementing as an analyzer either, since that involves cross-project analysis.

这篇关于使用Roslyn查找特定方法的所有方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆