Visual Studio代码分析 - 创建新规则以计算方法中的行数

时间:2010-09-06 10:50:40

标签: c# code-analysis

更新

我反映了Microsoft.Cci.dll并构建了我的规则。它工作正常。但是,我面临一些问题,我将here与所有细节放在一起。源代码是here。我不想通过提供所有细节来增加这个问题的长度。

我正在尝试编写一个代码分析规则,该规则会引发方法的警告 超过100行。我正在关注this文章。但是,我无法通过遵循CodeAnalysis提供的API来计算行数。例如,

public override ProblemCollection Check(Member member)
        {
            Method method = member as Method;
            if (method == null)
            {
                return null;
            }
            CheckForLOC(method);
            return Problems;
        }

以下是CheckForLOC()

private void CheckForLOC(Method method)
    {
        int startLineForMethod = method.Body.SourceContext.StartLine;
        int endLineForMethod = method.Body.SourceContext.EndLine;
        if (endLineForMethod > startLineForMethod
            && ((endLineForMethod - startLineForMethod) > constMaximumLOCforAMethod))
        {
            Resolution resolution = GetResolution(method, constMaximumLOCforAMethod);
            Problem problem = new Problem(resolution);
            Problems.Add(problem);
        }
    }

在上面的代码中,method.Body.SourceContext.StartLine和method.Body.SourceContext.EndLine返回相同的值。不知道为什么。

我也尝试过使用StatementCollection: -

private void CheckForLOC(Method method)
        {
            int LOCPerMethod = 0;

            if (method.Body.Statements.Count >= 1)
            {
                foreach (var statement in method.Body.Statements)
                {
                    LOCPerMethod += GetNumberOfLinesPerStatement(statement);
                }

            }
            if (LOCPerMethod > constMaximumLOCforAMethod)
            {
                Resolution resolution = GetResolution(method, constMaximumLOCforAMethod);
                Problem problem = new Problem(resolution);
                Problems.Add(problem);
            }
        }

        private int GetNumberOfLinesPerStatement(Statement statement)
        {
            int LOCperStatement = 0;
            if (statement.SourceContext.EndLine > statement.SourceContext.StartLine)
            {
                LOCperStatement = statement.SourceContext.EndLine - statement.SourceContext.StartLine;
            }
            return LOCperStatement;
        }

此处,Statement.SourceContext.StartLine和Statement.SourceContext.EndLine返回相同的值。我看到每个语句的StartLine是不同的,需要从前一个语句中减去一个语句的StartLine值。但是,我发现结果不稳定。例如,在方法的下面片段中,它给出了Statement1的行号作为StartLineNumber,而它应该给出StartLineNumber为If(SomeCondition): -

if(SomeCondition)
{
   Statement1
   Statement2
   Statement3
}

有人可以提供一些指导吗?

3 个答案:

答案 0 :(得分:2)

这更像是一种风格规则而不是正确性规则,因此它比Style Fop规则更适合使用StyleCop规则。

也就是说,如果你真的想通过FxCop实现它,你应该看看Microsoft.FxCop.Sdk.MethodMetrics.CalculateLinesOfCode(Method)如何完成相同的任务。

答案 1 :(得分:1)

NDepend工具支持任何.NET语言的度量标准NbLinesOfCode。此外,它集成在Visual Studio 2012,2010,2008中。免责声明:我是该工具的开发人员之一

你要求......

  

创建新规则以计算方法中的行数

使用NDepend,您可以编写Code Rules over LINQ Queries (namely CQLinq)。因此,创建一个新规则来计算方法中的行数,可以像写...一样简单。

warnif count > 0 
from m in JustMyCode.Methods
where m.NbLinesOfCode > 10
orderby m.NbLinesOfCode descending 
select new { m, m.NbLinesOfCode }

...并在Visual Studio中立即获得结果。只需双击结果中的方法,跳转到代码中的方法声明:

enter image description here

默认情况下会提出200 default CQLinq code queries and rules左右。

答案 2 :(得分:1)

我一直在寻找相同的方法(在方法中得到总线数),我找到了解决方案。

以下是样本:

public override ProblemCollection Check(Member member)
    {
        Method method = member as Method;
        if (method != null)
        {
            **if (method.Metrics.ClassCoupling > 20)**
            {
                Resolution resolu = GetResolution(new string[] { method.ToString() });
                Problems.Add(new Problem(resolu));
            }
        }
        return Problems;
    }

您可以尝试使用 method.Metrics.ClassCoupling 来获取总行数。