Visual Studio 代码分析 - 创建新规则来计算方法中的行数
更新
我反映了 Microsoft.Cci.dll 并构建了我的规则。效果很好。但是,我遇到了一些问题,我把 此处包含所有详细信息。源代码是 这里。我不想通过添加所有细节来增加这个问题的长度。
我正在尝试编写一个代码分析规则,该规则会对具有以下特征的方法发出警告: 超过100行。我正在关注 这篇文章。但是,我无法按照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 值中减去一个语句的 StartLine 值。但是,我发现结果不稳定。例如,在下面的方法片段中,它给出了 Statement1 的行号作为 StartLineNumber,而它应该给出 If(SomeCondition) 的 StartLineNumber:-
if(SomeCondition)
{
Statement1
Statement2
Statement3
}
有人可以对此提供一些指导吗?
UPDATE
I reflected Microsoft.Cci.dll and build my rule. It works fine. However, I am facing some problem which I put here with all the details. Source code is here. I didn't want to increase the length of this question by putting all the details.
I am trying to write a code analysis rule which would raise warnings for methods having
more than 100 lines. I am following this article. However, I am unable to count the number of lines by following the API provided by CodeAnalysis. for example,
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method == null)
{
return null;
}
CheckForLOC(method);
return Problems;
}
Following is the 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);
}
}
In the above code, method.Body.SourceContext.StartLine and method.Body.SourceContext.EndLine return the same value. Not sure why.
I also tried using the 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;
}
Here also, Statement.SourceContext.StartLine and Statement.SourceContext.EndLine return the same value. I see that the StartLine for each statement is different and one needs to substract the StartLine value of the one statement from its previous one's. However, I see that result is erratic. For example, in the below snippet in a method, It gives me the line number of Statement1 as StartLineNumber whereas It should give the StartLineNumber of If(SomeCondition):-
if(SomeCondition)
{
Statement1
Statement2
Statement3
}
Could anybody provide some direction on this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这更像是一种样式规则,而不是正确性规则,因此它比 FxCop 规则更适合 StyleCop 规则。
也就是说,如果您确实想通过 FxCop 实现它,您应该看看 Microsoft.FxCop.Sdk.MethodMetrics.CalculateLinesOfCode(Method) 如何完成相同的任务。
This is more of a style rule than a correctness rule, so it would be a better candidate for a StyleCop rule than an FxCop rule.
That said, if you really want to implement it via FxCop, you should take a look at how the Microsoft.FxCop.Sdk.MethodMetrics.CalculateLinesOfCode(Method) accomplishes the same task.
NDepend 工具支持任何 .NET 语言的指标 NbLinesOfCode。此外,它还集成在 Visual Studio 2012、2010、2008 中。免责声明:我是该工具的开发人员之一
您要求...
使用 NDepend,您可以编写 基于 LINQ 查询的代码规则 (即CQLinq)。因此,创建一个新规则来计算方法中的行数,可以像编写...一样简单
,并在 Visual Studio 中立即获得结果。只需双击结果中的方法即可跳转到代码中的方法声明:
周围 默认建议 200 个默认 CQLinq 代码查询和规则。
The tool NDepend supports the metric NbLinesOfCode on any .NET language. Also, it integrates in Visual Studio 2012, 2010, 2008. Disclaimer: I am one of the developers of the tool
You are asking for...
With NDepend you can write Code Rules over LINQ Queries (namely CQLinq). Hence creating a new rule to count number of lines in methods, can be as simple as writing...
...and get an immediate result in Visual Studio. Just by double-clicking a method in the result jumps to the method declaration in code:
Around 200 default CQLinq code queries and rules are proposed by default.
我一直在寻找相同的方法(以获取方法中的总行数),并且找到了解决方案。
下面是示例:
您可以尝试 method.Metrics.ClassCoupling 来获取方法的总行数。
I was looking for the same (to get total no of lines in a method) and I found solution.
Below is the sample:
You can try method.Metrics.ClassCoupling to get the total lines a method.