Tamas Ionut
Tamas Ionut

Reputation: 4410

Finding containing MethodDeclarationSyntax for a given SyntaxNode

I have the following source code:

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];
}

and I have as a given the SyntaxNode: node = from1.Age of the expression in the index argument.

Doing this yields null:

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

Doing node.Parent.Parent returns BinaryExpressionSyntax AddExpression from1.Age * to2.Age+ to1.Age * to2.Age and doing Parent of that yields null.

How can I find the MethodDeclaration that encloses the given syntax node?

Upvotes: 3

Views: 476

Answers (2)

Ray
Ray

Reputation: 192186

You can retrieve the node's enclosing method via Ancestors():

MethodDeclarationSyntax callingMethod = node
                .Ancestors()
                .OfType<MethodDeclarationSyntax>()
                .FirstOrDefault();

Upvotes: 0

Sievajet
Sievajet

Reputation: 3513

A SyntaxWalker allows you to find specific nodes. Here is an example how you fetch all the AddExpression nodes:

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 );
    }
}

If you pass this in the Accept function of a declarationsyntax and it will collect the matches the given node. For example:

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

Upvotes: 3

Related Questions