如何使用C#Roslyn测量方法的嵌套级别 [英] How to measure the nesting level of method using C# Roslyn

查看:86
本文介绍了如何使用C#Roslyn测量方法的嵌套级别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我想使用Roslyn测量方法的嵌套级别":如果该方法仅包含一个表达式,则其级别为0.如果该方法包含嵌套的if(cond1) if(cond2),则其级别为1. /p>

我尝试使用Roslyn的节点,但是我不明白如何在没有条件和其他条件的情况下仅获取while或if构造体.

解决方案

您可以使用SyntaxVisitor:它递归地遍历语法树并根据每个节点的类型执行代码.

您将需要指定各种语句应如何准确地表现.例如:

  • 对于简单的语句(例如ExpressionStatementSyntax),只需返回0.
  • 对于嵌套语句(包括IfStatementSyntax和其他几个嵌套语句),返回其子语句的深度+1.您可以通过递归调用其上的Visit()来获得子深度.
  • 对于BlockSyntax,返回其子级的最大深度.

在代码中,它类似于:

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

此代码不完整,您将需要为所有其他类型的语句添加替代.

用法类似于:

MethodDeclarationSyntax method = …;
int methodNestingLevel = new NestingLevelVisitor().Visit(method);

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.

解决方案

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

这篇关于如何使用C#Roslyn测量方法的嵌套级别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆