如何从调用方法的 InvocationExpressionSyntax 节点获取 IMethodSymbol 或方法声明的语法节点?
How do I get a IMethodSymbol or the syntax node of the method declaration from a InvocationExpressionSyntax node which calls the method?
在我的分析器的实现中,我在 AnalyzeSymbol
方法中:
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(location.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]
属性,请参阅 ). 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 , InvocationExpressionSyntax
没有,我尝试的以下代码为符号生成 null:
var model = context.Compilation.GetSemanticModel(ies.SyntaxTree);
var symbol = model.GetDeclaredSymbol(ies.Expression);
我做错了什么?
我的分析器应该分析的示例代码是:
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
获取 InvocationExpressionSyntax
的声明符号
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;
}
在我的分析器的实现中,我在 AnalyzeSymbol
方法中:
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(location.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
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 InvocationExpressionSyntax
没有,我尝试的以下代码为符号生成 null:
var model = context.Compilation.GetSemanticModel(ies.SyntaxTree);
var symbol = model.GetDeclaredSymbol(ies.Expression);
我做错了什么?
我的分析器应该分析的示例代码是:
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
InvocationExpressionSyntax
的声明符号
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;
}