如何在Roslyn中获取Invoked方法名称?

Rav*_*mar 8 c# roslyn

我有这样的代码;

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将是:

  • 对于方法B:调用方法A.
  • 对于方法C:调用方法A.

我想要这样的东西:

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)


SLa*_*aks 3

您误解了语法树中这些节点的作用。

您应该使用 VS 中的 Roslyn Syntax Visualizer 来查看方法调用的节点实际上是什么样子。

简而言之:InvocationExpression公正的意思someExpression(some arguments)。该表达式可以是多种内容,例如构造函数调用、成员访问、数组访问或解析为方法或委托的任何其他表达式。
您需要检查 theKindInvocationExpressionSyntax弄清楚您希望如何处理每个可能的表达式。