使用roslyn检测外部api调用

问题描述 投票:0回答:2

我想知道如何检测例如InvocationExpressionSyntax是来自我的代码还是来自外部代码。

我试图找到怎么做,但没有成功。

例。:

public async Task MyMethodAsync1()
{
   await MyMethodAsync2(); // How to know that this 'InvocationExpressionSyntax' is mine using roslyn ?
}

public async Task MyMethodAsync2()
{
  await Task.Delay(1); // How to know that this 'InvocationExpressionSyntax' is NOT mine using roslyn ?
}

谢谢

c# roslyn roslyn-code-analysis
2个回答
1
投票

为了实现你可以检查DeclaringSyntaxReferences下收到的ISymbol中的InvocationExpressionSyntax是空的。为了更清楚,您还可以通过检查IsImplicitlyDeclared是否为false来确保编译器不生成此符号

  public static bool IsDeclareInMetadata(this SemanticModel semanticModel, SyntaxNode node)
  {
    var info = semanticModel.GetSymbolInfo(node);
    return !(info.Symbol is null) && info.Symbol.DeclaringSyntaxReferences.IsDefaultOrEmpty && !info.Symbol.IsImplicitlyDeclared;
  }

0
投票

当你说“我的代码”或“外部代码”时,你需要定义你的意思。

假设“我的代码”意味着“编译到当前程序集中的代码”而外部代码意味着“来自引用程序集的代码”,最简单的方法是找出它来比较程序集。

假设你有一个SyntaxNodeAnalysisContext context和一个InvocationExpressionSyntax node,你会发现你调用的方法的符号如下:

var symbol = context.SemanticModel.GetSymbolInfo(node, context.Cancellationtoken);

请记住,符号可能为空,因此请测试。

您现在可以比较组件:

bool fromSameAssembly = context.Compilation.Assembly.Equals(symbol.ContainingAssembly);

另一种选择是查看符号的位置:

bool isInMetadata = symbol.Locations.Any(loc => loc.IsInMetadata);
bool isInSource = symbol.Locations.Any(loc => loc.IsInSource);
© www.soinside.com 2019 - 2024. All rights reserved.