我有这样的代码;
class abc{
void A()
{
//Some to do statements
}
void B()
{
var obj=A();
}
void C()
{
var call=B();
}
}
Run Code Online (Sandbox Code Playgroud)
我想使用roslyn找到Invoked方法名称.
像这里o/p将是:
我想要这样的东西:
root.DescendantNodes().OfType<InvocationExpressionSyntax>().Where(md => md.Identifier.ValueText.Equals(methodName)).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
但InvocationExpression不包含要访问的标识符.如何获取标识符名称
Eri*_*ert 14
我同意SLaks并会增加他的答案,如果你想要的是:
"我希望接收器语法的方法调用语法节点 - 让我强调语法 - 是一个等于某个特定字符串的单个标识符"
然后你想要的查询是这样的
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;
Run Code Online (Sandbox Code Playgroud)
但我认为这可能不是你想要的.如果您想要的是"我想确切地知道调用哪个方法,无论是否写入,A(...)或者Foo.Bar.A(...)您根本不想考虑语法.您需要使用语义分析器来获取符号关联使用调用,然后检查该符号是否标识了您感兴趣的方法.
您是否主要对句法或语义分析感兴趣?Roslyn也做了,但你只是在看你所呈现的代码中的语法.
如果你正在寻找的是语义分析,那么你想做这样的事情:
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;
Run Code Online (Sandbox Code Playgroud)
您误解了语法树中这些节点的作用。
您应该使用 VS 中的 Roslyn Syntax Visualizer 来查看方法调用的节点实际上是什么样子。
简而言之:InvocationExpression公正的意思someExpression(some arguments)。该表达式可以是多种内容,例如构造函数调用、成员访问、数组访问或解析为方法或委托的任何其他表达式。
您需要检查 theKind并InvocationExpressionSyntax弄清楚您希望如何处理每个可能的表达式。