如何从调用方法的InvocationExpressionSyntax节点获取IMethodSymbol或方法声明的语法节点?

在我的分析器的实现中,我在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(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通过它我得到一个像这里发布的IFieldSymbolInvocationExpressionSyntax没有,我试过的以下代码为符号产生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; }