Обнаружение внешних вызовов API, используя Roslyn - PullRequest
0 голосов
/ 20 апреля 2019

Я хотел бы знать, как определить, например, 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 ?
}

Спасибо

Ответы [ 2 ]

1 голос
/ 20 апреля 2019

Чтобы добиться того, чтобы вы могли проверить, что 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 голосов
/ 25 апреля 2019

Вам нужно определить, что именно вы имеете в виду, когда говорите «мой код» или «внешний код».

Предполагается, что «мой код» означает «код, скомпилированный в текущую сборку», а внешний код означает«код из ссылочной сборки», самый простой способ найти его для сравнения сборок.

Если у вас есть 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);
...