【问题标题】:Roslyn Get Method Declaration from InvocationExpressionRoslyn 从 InvocationExpression 获取方法声明
【发布时间】:2017-07-27 21:59:18
【问题描述】:

我正在制作一个 roslyn 演示,用于从属性生成编译器警告

我有一个分析器来分析方法调用,如下所示:

public override void Initialize(AnalysisContext context)
{
    context.RegisterSyntaxNodeAction(AnalyzerInvocation, SyntaxKind.InvocationExpression);
}

private static void AnalyzerInvocation(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;
}

我正在研究如何获取方法声明,我知道我可以使用SymbolFinder 来搜索方法声明

var model = compilation.GetSemanticModel(tree);

//Looking at the first method symbol
var methodSyntax = tree.GetRoot().DescendantNodes().OfType<MethodDeclarationSyntax>()
   .First(/*TODO: Execute Find for related symbol */);

这个选项既昂贵又烦人,而且它留下了出错的可能性,因为如果你的调用方法来自程序集怎么办。

从 InvocationExpressionSyntax 获取方法声明的最简单方法是什么?我应该只使用符号查找器,如果它失败,请使用搜索导入的程序集还是有更简单更好的方法?

【问题讨论】:

  • 我建议你结合使用_semanticModel.GetDeclaredSymbol(...)和SymbolFinder.FindSourceDefinitionAsync。如果源文件中不存在声明,则最后一个方法返回 null,第一个方法可以通过调用节点检索声明。

标签: c# roslyn


【解决方案1】:

如果你需要你正在调用的方法的声明,你可以得到如下。

在第一步中,您会找出正在调用的方法:

var methodSymbol = context
    .SemanticModel
    .GetSymbolInfo(invocation, context.CancellationToken)
    .Symbol as IMethodSymbol;

请记住,methodSymbol 可能为 null 的原因有多种(例如,您调用的是委托,而不是方法),因此请对此进行测试。

然后就可以找到声明语法引用了,取第一个:

var syntaxReference = methodSymbol
    .DeclaringSyntaxReferences
    .FirstOrDefault();

这也可以为空,例如当您从另一个程序集调用方法时,请对此进行测试。

最后:

var declaration = syntaxReference.GetSyntax(context.CancellationToken);

这为您提供了语法。如果您需要该声明的语义模型,您可以使用

var semanticModel = context.Compilation.GetSemanticModel(declaration.SyntaxTree);

【讨论】:

  • 这很好,我明天上班时测试一下
  • 上下文在AnalysisContext还是SyntaxNodeAnalysisContext的哪个对象中
  • @KarthicG 请参阅 OP 的问题以了解 context 和 invocation 的声明。
  • OP 的?没明白
  • “OP”是“原创海报”的缩写。看看那里的方法void AnalyzerInvocation(SyntaxNodeAnalysisContext context)。
猜你喜欢
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多