Question

I tried to parse code and count a nesting, but i have a problems with lambda Expression and anonymous methods. I tried to use VisitSimpleLambdaExpression() and VisitAnonymousMethodExpression() but it didn't help me. Tell me anyone another idea for counting nesting of Lambda Expressions and anonymous methods? My current code:

class NestingLevelVisitor : SyntaxVisitor<int>
{
    public override int VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        return Visit(node.Body);
    }

    public override int VisitBlock(BlockSyntax node)
    {
        if (node.Statements.Select(Visit).Count() == 0)
            return 0;
        return node.Statements.Select(Visit).Max();
    }

    public override int VisitExpressionStatement(ExpressionStatementSyntax node)
    {
        return 0;
    }

    public override int VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node)
    {
        int result = Visit(node.Block);
        return result + 1;  //dont works
    }

    public override int VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
    {
        Console.WriteLine(node.Body);
        int result = Visit(node.Body);
        return result + 1;  //dont works
    }
}

UPD: this example demonstrate a lambda expression with braces:

class Program
{
    static void Main()
    {
        int m = 0;
        document =>
        {
            return new InsertRequest(nominalType, document);
        };
    }
}

and nesting = 1

but if i use construction like this:

bool f2()
         {
                int a = 1;
                Func< bool, bool> not = b =>!b;
                return 1;
         }

nesting is not changing

this method contains a anonymous method and nesting of this method = 1:

static void Main()
{
    Printer p = delegate(string j)
    {
        System.Console.WriteLine(j);
    };
    p("The delegate using the anonymous method is called.");
    p = new Printer(TestClass.DoWork);
    p("The delegate using the named method is called.");
}
Was it helpful?

Solution

When the syntax visitor encounter a node kind that doesn't have overridden Visit method, it simply returns 0.

And you don't override VisitLocalDeclarationStatement, so that's exactly what happens, no matter what expression is inside that statement.

What you need to handle complex expressions inside local declarations is something like:

public override int VisitLocalDeclarationStatement(
    LocalDeclarationStatementSyntax node)
{
    return node.Declaration.Variables.Select(Visit).Max();
}

public override int VisitVariableDeclarator(VariableDeclaratorSyntax node)
{
    if (node.Initializer == null)
        return 0;

    return Visit(node.Initializer.Value);
}

You will also need similar code for all cases when a lambda can appear inside another expression.

This is the reason why my original NestingLevelVisitor throws an exception is DefaultVisit: this way, you can detect node kinds that you don't handle yet and you are forced to explicitly specify how to handle them (instead of defaulting everything to “return 0”).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top