3

例如:

SqlCommand command = new SqlCommand();
SqlDataReader datareader = command.ExecuteReader();

这里的调用节点是command.ExecuteReader()。如何使用 roslyncommand从调用节点获取变量标识符令牌/节点?假设该调用节点之前可以有许多其他方法调用,例如classA.methodA().methodB().classB.methodC(command.ExecuteReader()),因此获取标识符node.DescendantNodes可能没有用。我想到的解决方案是首先获取 SpanStart ExecuteReader,然后command通过调用SymbolFinder.FindSymbolAtPosition的位置来获取符号ExecuteReader.SpanStart - 2。但是我不确定这个解决方案是否可以处理每一种情况。我正在开发的应用程序是一个静态代码分析器。

4

1 回答 1

6

当您有一个调用节点时,您可以查看其表达式是否为成员访问。如果调用是针对语句“DoThis()”,则没有成员访问权限,但如果调用是针对“x.DoThis()”,则存在成员访问权限,因为正在针对引用调用“DoThis” X”。

一旦您确认有成员访问,您就可以获得目标引用的表达式——这是正在访问其成员的引用。这个表达式可能是一个简单的名称标识符(例如“command”)或者它可能是另一个成员访问(例如“x.command”)或者它可能是另一个调用(例如“GetCommand()”)或者它可能是这些的组合。

用代码来说明 -

private static void AnalyseInvocation(SyntaxNodeAnalysisContext context)
{
    var invocation = (InvocationExpressionSyntax)context.Node;
    var memberAccess = invocation.Expression as MemberAccessExpressionSyntax;
    if ((memberAccess == null) || (memberAccess.Name.Identifier.ValueText != "ExecuteReader"))
        return;

    if (memberAccess.Expression is IdentifierNameSyntax)
    {
        // The target is a simple identifier, the code being analysed is of the form
        // "command.ExecuteReader()" and memberAccess.Expression is the "command"
        // node
    }
    else if (memberAccess.Expression is InvocationExpressionSyntax)
    {
        // The target is another invocation, the code being analysed is of the form
        // "GetCommand().ExecuteReader()" and memberAccess.Expression is the
        // "GetCommand()" node
    }
    else if (memberAccess.Expression is MemberAccessExpressionSyntax)
    {
        // The target is a member access, the code being analysed is of the form
        // "x.Command.ExecuteReader()" and memberAccess.Expression is the "x.Command"
        // node
    }
}
于 2016-06-24T11:08:02.433 回答