Can I get function caller/callee information from Roslyn?
-
Saturday, October 22, 2011 5:14 AM
Is it possible to use Roslyn to obtain callers/callees of a particular function? (similar to those displayed via "View Call Hierarchy" in Visual Studio IDE)
Any interface provided by Roslyn?
Thanks.
All Replies
-
Saturday, October 22, 2011 3:50 PM
Yes, you can do that using Roslyn, though it involves a bit of work:
var syntaxTree = SyntaxTree.ParseCompilationUnit(code); var semanticModel = Compilation.Create("compilation") .AddSyntaxTrees(syntaxTree) .AddReferences(new AssemblyFileReference(typeof(object).Assembly.Location)) .GetSemanticModel(syntaxTree); var baz = syntaxTree.Root .DescendentNodes() .OfType<ClassDeclarationSyntax>() .Single(m => m.Identifier.ValueText == "C1") .ChildNodes() .OfType<MethodDeclarationSyntax>() .Single(m => m.Identifier.ValueText == "Baz"); var bazSymbol = semanticModel.GetDeclaredSymbol(baz); var invocations = syntaxTree.Root .DescendentNodes() .OfType<InvocationExpressionSyntax>(); var bazInvocations = invocations .Where(i => semanticModel.GetSemanticInfo(i).Symbol == bazSymbol);
When you call that on the following code:
namespace Test { class C1 { void Bar() { Baz(); } public void Baz() { } } class C2 { void Foo() { Baz(); new C1().Baz(); } void Baz() {} } }
It will correctly report Baz() in C1.Bar and new C1().Baz() in C2.Foo, but not Baz() in C2.Foo. -
Tuesday, October 25, 2011 4:24 PMOwner
If you operate at the services level, you can MEF import an IFindReferencesService (note - this is subject to change in the future, though the functionality will still be there), and use that to find all the references to a particular method. You would need to build the filtering to calls yourself, as well as the ability to walk the graph of callers, but the "hard" part of searching is already there.

