Visual Studio Code analysis - Creating a new rule to count number of lines in methods
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?
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.
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...
Creating a new rule to count number of lines in methods
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...
warnif count > 0
from m in JustMyCode.Methods
where m.NbLinesOfCode > 10
orderby m.NbLinesOfCode descending
select new { m, m.NbLinesOfCode }
...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.
I was looking for the same (to get total no of lines in a method) and I found solution.
Below is the sample:
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;
}
You can try method.Metrics.ClassCoupling to get the total lines a method.
精彩评论