Frage

I want to measure a "nesting level" of a method using Roslyn, for example: if the method contains only one expression its level is 0. If the method contains nested if(cond1) if(cond2) its level is 1.

I try to use Roslyn's nodes, but I don't understand how to get only the body of the while or the if construction without it's condition and other things.

War es hilfreich?

Lösung

You can use SyntaxVisitor for this: it recursively walks the syntax tree and executes your code for each node, depending on its type.

You will need to specify how exactly should various kinds of statements behave. For example:

  • For simple statements (like ExpressionStatementSyntax) just return 0.
  • For nesting statements (including IfStatementSyntax and several others), return the depth of its child statement + 1. You get the depth of the child by recursively calling Visit() on it.
  • For BlockSyntax, return the maximum depth of its children.

In code, that would look something like:

class NestingLevelVisitor : SyntaxVisitor<int>
{
    public override int DefaultVisit(SyntaxNode node)
    {
        throw new NotSupportedException();
    }

    public override int VisitMethodDeclaration(MethodDeclarationSyntax node)
    {
        return Visit(node.Body);
    }

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

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

    public override int VisitIfStatement(IfStatementSyntax node)
    {
        int result = Visit(node.Statement);

        if (node.Else != null)
        {
            int elseResult = Visit(node.Else.Statement);
            result = Math.Max(result, elseResult);
        }

        return result + 1;
    }
}

This code is incomplete, you will need to add overrides for all the other kinds of statements.

Usage is something like:

MethodDeclarationSyntax method = …;
int methodNestingLevel = new NestingLevelVisitor().Visit(method);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top