I have a code like this;
class abc{
void A()
{
//Some to do statements
}
void B()
{
var obj=A();
}
void C()
{
var call=B();
}
}
I want to find the Invoked method name using roslyn.
like here o/p will be:
i want something like this:
root.DescendantNodes().OfType<InvocationExpressionSyntax>().Where(md => md.Identifier.ValueText.Equals(methodName)).FirstOrDefault();
but InvocationExpression doesn't contain Identifier to access. How to get identifier name
I agree with SLaks and would add to his answer, if what you want is:
"I want the method invocation syntax nodes where the receiver syntax -- let me emphasize SYNTAX -- is a single identifier equal to some particular string"
then the query you want is something like
var root = tree.GetRoot();
var nodes = from node in root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
let id = node.Expression as IdentifierNameSyntax
where id != null
where id.Identifier.ValueText == methodName
select node;
But I think that is maybe not what you want. If what you want is "I want to know exactly which method is invoked regardless of whether it is written A(...)
or Foo.Bar.A(...)
then you don't want to be considering the syntax at all. You'll need to use the semantic analyzer to get the symbol associated with the invocation, and then check whether that symbol identifies the method you're interested in.
Are you primarily interested in a syntactic or a semantic analysis here? Roslyn does either, but you're only looking at syntax in the code you've presented.
If what you're looking for is a semantic analysis then you want to do something like this:
var tree = CSharpSyntaxTree.ParseText(code);
var c = CSharpCompilation.Create("asm.dll");
c = c.AddSyntaxTrees(tree);
var model = c.GetSemanticModel(tree);
string methodName = "A";
var root = tree.GetRoot();
var symbols = from node in root.DescendantNodes()
.OfType<InvocationExpressionSyntax>()
let symbol = model.GetSymbolInfo(node.Expression).Symbol as IMethodSymbol
where symbol != null
where symbol.Name = methodName
select symbol;
The reason InvocationExpressionSyntax does not have Identifier because it may have with this case var obj = this.A()
so it's reason why InvocationExpressionSyntax will contain property Expression with type ExpressionSyntax (which may be IdentifierNameSyntax type),
1.So simple answer for your case is you can access property Expression like this.
foreach (var item in root.DescendantNodes()
.OfType<InvocationExpressionSyntax>())
{
var expr = item.Expression;
if (expr is IdentifierNameSyntax)
{
IdentifierNameSyntax identifierName = r as IdentifierNameSyntax; // identifierName is your method name
}
if (expr is MemberAccessExpressionSyntax)
{
MemberAccessExpressionSyntax memberAccessExpressionSyntax = r as MemberAccessExpressionSyntax;
//memberAccessExpressionSyntax.Name is your method name
}
}
2.but for exact lookup the invocation method is the same with method you declared you have to use Semantic information as in this example in Roslyn project
https://github.com/dotnet/roslyn/wiki/FAQ#how-do-i-find-all-calls-in-a-compilation-into-a-particular-namespace
You're misunderstanding the role of these nodes in the syntax tree.
You should use the Roslyn Syntax Visualizer in VS to see what the nodes for a method call actually look like.
In short: An InvocationExpression
just means someExpression(some arguments)
. That expression can be a number of things, such as a constructor call, a member access, an array access, or any other expression that resolves to a method or delegate.
You need to check the Kind
of the InvocationExpressionSyntax
and figure out how you want to handle every possible expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With