简体   繁体   English

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

[英]How to get Invoked method name in Roslyn?

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. 我想使用roslyn找到Invoked方法名称。

like here o/p will be: 像这里o / p将是:

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

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. 但InvocationExpression不包含要访问的标识符。 How to get identifier name 如何获取标识符名称

I agree with SLaks and would add to his answer, if what you want is: 我同意SLaks并会增加他的答案,如果你想要的是:

"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. 如果你想要的是“我想确切地知道调用哪个方法,无论它是写成A(...)还是Foo.Bar.A(...)那么你不想考虑语法所有。您需要使用语义分析器来获取与调用关联的符号 ,然后检查该符号是否标识了您感兴趣的方法。

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. Roslyn也做了,但你只是在看你所呈现的代码中的语法。

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), InvocationExpressionSyntax没有Identifier的原因,因为它可能有这个案例var obj = this.A()所以这就是为什么InvocationExpressionSyntax将包含类型为ExpressionSyntax的属性Expression(可能是IdentifierNameSyntax类型),

1.So simple answer for your case is you can access property Expression like this. 1.对于您的案例,简单的答案就是您可以像这样访问属性Expression。

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 2.但是对于精确查找,调用方法与您声明必须使用语义信息的方法相同,如Roslyn项目中的示例
https://github.com/dotnet/roslyn/wiki/FAQ#how-do-i-find-all-calls-in-a-compilation-into-a-particular-namespace 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. 您应该在VS中使用Roslyn语法Visualizer来查看方法调用的节点实际上是什么样的。

In short: An InvocationExpression just means someExpression(some arguments) . 简而言之: InvocationExpression只是表示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. 您需要检查InvocationExpressionSyntaxKind ,并弄清楚如何处理每个可能的表达式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM