查找包含给定 SyntaxNode 的 MethodDeclarationSyntax

Finding containing MethodDeclarationSyntax for a given SyntaxNode

我有以下源代码:

public void MethodAssignment_WithIndexQuery_1(Customer from1, Customer to1, decimal amount) 
{
     var customers = _customerRepository.GetWhere(to1.Age);
     Customer indexCustomer1 = customers[(from1.Age + to1.Age)* to1.Age];
}

并且我给定了索引参数中表达式的 SyntaxNode: node = from1.Age

这样做会产生空值:

MethodDeclarationSyntax callingMethod = node
                .GetLocation()
                .SourceTree
                .GetRoot()
                .FindToken(location.SourceSpan.Start)
                .Parent
                .AncestorsAndSelf()
                .OfType<MethodDeclarationSyntax>()
                .FirstOrDefault();

node.Parent.Parent returns BinaryExpressionSyntax AddExpression from1.Age * to2.Age+ to1.Age * to2.Age 并做 Parent 产生 null.

如何找到包含给定语法节点的 MethodDeclaration

A SyntaxWalker 允许您查找特定节点。这是一个如何获取所有 AddExpression 节点的示例:

public class MethodDeclarationSyntaxWalker : CSharpSyntaxWalker
{
    private readonly IList<MethodDeclarationSyntax> _matches;

    public MethodDeclarationSyntaxWalker( IList<MethodDeclarationSyntax> matches )
    {
        _matches = matches;
    }

    public override void VisitBinaryExpression( BinaryExpressionSyntax node )
    {
        if ( node.Kind() == SyntaxKind.AddExpression )
            _matches.Add( node.FirstAncestorOrSelf<MethodDeclarationSyntax>() );

        base.VisitBinaryExpression( node );
    }
}

如果您在声明语法的 Accept 函数中传递它,它将收集给定节点的匹配项。例如:

var classDeclaration = ( ClassDeclarationSyntax )analysisContext.Node;
var matches = new List<MethodDeclarationSyntax>();
classDeclaration.Accept( new MethodDeclarationSyntaxWalker( matches ) );

您可以通过Ancestors():

获取节点的封装方法
MethodDeclarationSyntax callingMethod = node
                .Ancestors()
                .OfType<MethodDeclarationSyntax>()
                .FirstOrDefault();