Find all method calls for a specific method using Roslyn

I am working on a code analyzer using Roslyn, and my current task is to find all the internal methods that are not used in the assembly.

I start with MethodDeclarationSyntax and get a character from this. Then I use the FindCallersAsync method in SymbolFinder , but it returns an empty collection, even when I make a call to the method in question somewhere in the assembly. See 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. ... } 

I saw similar code here , but in this example the method symbol is obtained using GetSymbolInfo on 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; 

However, in my case, I need to find the calls (if any) from the ad. If I first receive a call and pass a character from GetSymbolInfo , the method calls return correctly, so the problem seems to be with the symbol parameter, not the solution .

Since I'm trying to get the base character of an ad, I cannot use GetSymbolInfo , but use GetSymbolInfo instead (as suggested here ).

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

Does anyone have any idea what the difference is between the two returned characters and how can I get the β€œcorrect” one that works? Or maybe there is a better approach? All my research seems to point to FindCallersAsync , but I just can't get it to work.

+1
source share
1 answer

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

This is because they are not the same symbol; they come from completely different compilations, which may or may not be different. One comes from a compiler that is actively compiling, one from MSBuildWorkspace.

In principle, the use of MSBuildWorkspace in the analyzer is not supported. Completely. Do not do this. This will not only be very slow, but also has various problems with correctness, especially if you use the analyzer in Visual Studio. If your goal is to find unused methods anywhere in the solution, this is something we really don’t support as an analyzer, as this includes cross-project analysis.

+3
source

All Articles