3

例えば:

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

ここでの呼び出しノードはcommand.ExecuteReader(). roslyn を使用しcommandて、呼び出しノードからの変数識別子トークン/ノードを取得するにはどうすればよいですか? この呼び出しノードの前に他の多くのメソッド呼び出しがある可能性があると仮定すると、たとえばclassA.methodA().methodB().classB.methodC(command.ExecuteReader())、識別子を取得するnode.DescendantNodesことは役に立たない可能性があります。私が考えた解決策は、最初に の SpanStart を取得し、次にの位置で呼び出してExecuteReaderのシンボルを取得することでした。ただし、このソリューションがすべての状況を処理できるかどうかはわかりません。私が取り組んでいるアプリケーションは、静的コード アナライザーです。commandSymbolFinder.FindSymbolAtPositionExecuteReader.SpanStart - 2

4

1 に答える 1

6

呼び出しノードがある場合、その式がメンバー アクセスであるかどうかを確認できます。呼び出しがステートメント「DoThis()」に対するものである場合、メンバー アクセスはありませんが、呼び出しが「x.DoThis()」に対するものである場合、参照に対して「DoThis」が呼び出されているため、メンバー アクセスがありますバツ"。

メンバー アクセスがあることを確認すると、ターゲット参照の式を取得できます。これは、メンバーがアクセスされている参照です。この式は、単純な名前識別子 (例: "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 に答える