如何从调用方法的 InvocationExpressionSyntax 节点获取 IMethodSymbol 或方法声明的语法节点? [英] How do I get a IMethodSymbol or the syntax node of the method declaration from a InvocationExpressionSyntax node which calls the method?

查看:75
本文介绍了如何从调用方法的 InvocationExpressionSyntax 节点获取 IMethodSymbol 或方法声明的语法节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的分析器的实现中,我在 AnalyzeSymbol 方法中:

In the implementation of my analyzer I am in the AnalyzeSymbol method:

public override void Initialize(AnalysisContext context)
{
  context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method);
}

private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
  // here I look through the syntax of the method body in order to find invocations.
  var methodSymbol = context.Symbol as IMethodSymbol;
  var location = methodSymbol.Locations.FirstOrDefault();
  var methodNode = location.SourceTree.GetCompilationUnitRoot().FindNode(locati‌​on.SourceSpan);
  var blockNode = methodNode.ChildNodes().FirstOrDefault(s => s is BlockSyntax);
  var invocations = blockNode.DescendantNodes()
    .Select(s => s as InvocationExpressionSyntax)
    .Where(s => s != null)

  foreach(InvocationExpressionSyntax i in invocations i)
  {
    // look at the signature of the method which is invoked
    // in order to figure out if the arguments are attributed
  }
}

对于我找到的每个 InvocationExpressionSyntax 节点,我需要检查参数在调用调用的声明方法的签名中声明的属性(即我的 [ReadOnly] 属性参见此处).根据我的理解,我需要以某种方式从 InvocationExpressionSyntax 对象获取到相应的 IMethodSymbol,但我无法弄清楚如何.与 FieldDeclarationSyntax 不同,它有一个属性 Declarations,我通过它得到一个 IFieldSymbol 就像发布的 此处InvocationExpressionSyntax 没有,我尝试的以下代码为符号产生 null:

For each InvocationExpressionSyntax node I find, I need to check with which attributes the arguments are declared in the signature of the declaring method the invocation calls (namely my [ReadOnly] attribute see here). In my understanding I need to get somehow from the InvocationExpressionSyntax object to the corresponding IMethodSymbol, but I cannot figure out how. Unlike FieldDeclarationSyntax which has a property Declarations by which I get an IFieldSymbol like posted here, InvocationExpressionSyntax doesn't and the following code I tried yields null for the symbol:

var model = context.Compilation.GetSemanticModel(ies.SyntaxTree);
var symbol = model.GetDeclaredSymbol(ies.Expression);

我做错了什么?

我的分析器应该分析的示例代码是:

Example code of what my analyzer should analyze is:

void Foo()
{
  int i = 42;

  // coming from this InvocationExpressionSyntax node I want to find out that i is an parameter for an argument which has an [ReadOnly] attribute
  Bar(i);

  // coming from this InvocationExpressionSyntax node I want to find out that i is an parameter for an argument which has NOT an [ReadOnly] attribute
  Baz(i);
}

void Bar([ReadOnly] int i)
{
}

void Baz(int i)
{
}

推荐答案

您可以使用 SymbolFinder

Workspace workspace;
Workspace.TryGetWorkspace(location.SourceTree.GetText().Container, out workspace);
if (workspace != null)
{
    var invocMethodSymbol = model.GetSymbolInfo(ies.Expression).Symbol;
    // Await this task if you can
    var declarationMethodSymbol = SymbolFinder.FindSourceDefinitionAsync(invocMethodSymbol, workspace.CurrentSolution).Result;
}

这篇关于如何从调用方法的 InvocationExpressionSyntax 节点获取 IMethodSymbol 或方法声明的语法节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆