【发布时间】:2017-06-29 19:16:29
【问题描述】:
在我的分析器的实现中,我使用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] 属性,参见here)。据我了解,我需要以某种方式从InvocationExpressionSyntax 对象到相应的IMethodSymbol,但我不知道如何。不像FieldDeclarationSyntax,它有一个属性Declarations,通过它我得到一个IFieldSymbol,就像发布的here一样,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)
{
}
【问题讨论】:
-
你能举例说明
InvocationExpressionSyntax是什么吗?你能不能解释一下为什么你需要一个符号,也许有一种方法可以不使用符号来做到这一点 -
@johnny5 查看我的编辑。我认为获得被调用方法的声明的语法节点也足够了。
-
你知道调用是对方法的实际调用,属性不会在调用上,但会在方法声明本身上
-
这就是为什么我需要声明方法的位置的语法节点。
-
所以你实际上应该寻找 MethodDeclarationSyntax 而不是 InvocationDeclarationSyntax
标签: c# roslyn roslyn-code-analysis