Анализ кода Visual Studio — создание нового правила для подсчета количества строк в методах

ОБНОВЛЕНИЕ

Я отразил Microsoft.Cci.dll и создал свое правило. Это работает нормально. Однако у меня возникла проблема, которую я поставил здесь со всеми подробностями. Исходный код здесь . Я не хотел увеличивать длину этого вопроса, указывая все детали.

Я пытаюсь написать правило анализа кода, которое будет вызывать предупреждения для методов, содержащих более 100 строк. Я следую эту статью. Однако я не могу подсчитать количество строк, следуя API, предоставленному CodeAnalysis. Например,

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
}

Может ли кто-нибудь дать какое-то направление по этому поводу?


person Ashish Gupta    schedule 06.09.2010    source источник
comment
Хотя это не отвечает на ваш вопрос, вы можете взглянуть на инструмент NDepend (www.ndepend.com). Это коммерческий инструмент метрик кода, который имеет метрику размера метода и многое другое.   -  person Steven    schedule 06.09.2010
comment
@Стивен, спасибо за ваше время и комментарии. На самом деле Visual Studio также имеет доступную функцию Code Metrics. Однако я хотел создать правило, которому мы все можем следовать, и которое должно быть интегрировано с решением VS, как и любое другое правило анализа кода. Надеюсь, это прояснит.   -  person Ashish Gupta    schedule 06.09.2010
comment
Хорошо, теперь я начинаю походить на продавца, но вы можете интегрировать NDepend с Visual Studio и вашим автоматизированным процессом сборки. Однако иметь лицензию для каждого разработчика в команде может быть немного дороговато :-). Я хочу иметь такое правило — это хорошо, но не слишком ли много 100 строк? Я стараюсь, чтобы мои методы в среднем не превышали 10 строк кода.   -  person Steven    schedule 06.09.2010
comment
Хорошо, @Steven, продавец... :-) Я не уверен, смогу ли я убедить своего менеджера в пользу NDepend в данный момент. А 100 — это просто число. :-)   -  person Ashish Gupta    schedule 06.09.2010


Ответы (3)


Это скорее правило стиля, чем правило правильности, поэтому оно лучше подходит для правила StyleCop, чем для правила FxCop.

Тем не менее, если вы действительно хотите реализовать это с помощью FxCop, вам следует взглянуть на то, как Microsoft.FxCop.Sdk.MethodMetrics.CalculateLinesOfCode(Method) выполняет ту же задачу.

person Nicole Calinoiu    schedule 07.09.2010
comment
Я не вижу Microsoft.FxCop.Sdk.MethodMetrics, когда отображаю FxCop.dll. Не могли бы вы указать, где вы видели этот класс? - person Ashish Gupta; 07.09.2010
comment
Он находится в сборке Microsoft.Cci. - person Nicole Calinoiu; 07.09.2010
comment
@nicole - В какой версии Cci это? Я не вижу его в моем. C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\Microsoft.Cci.dll - person Maslow; 13.09.2010
comment
@Maslow: Microsoft.FxCop.Sdk.MethodMetrics.CalculateLinesOfCode(Method) присутствует как в VS2008/FxCop 1.36, так и в VS2010/FxCop 10 версиях Microsoft.Cci. Однако класс Microsoft.FxCop.Sdk.MethodMetrics имеет внутреннюю видимость, поэтому вы можете его не видеть (в зависимости от того, как вы пытаетесь его найти). - person Nicole Calinoiu; 13.09.2010
comment
@Maslow, используйте RedGate Reflector, чтобы найти метод. Вы также можете использовать дизассемблер — denisbauer.com/NETTools/FileDisassembler.aspx - person Ashish Gupta; 13.09.2010

Инструмент NDepend поддерживает метрику NbLinesOfCode на любом языке .NET. Кроме того, он интегрируется в Visual Studio 2012, 2010, 2008. Отказ от ответственности: я являюсь одним из разработчиков инструмента

Вы просите...

Создание нового правила для подсчета количества строк в методах

С помощью NDepend вы можете писать правила кода для запросов LINQ (а именно CQLinq). Следовательно, создать новое правило для подсчета количества строк в методах может быть так же просто, как написать...

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

...и сразу получите результат в Visual Studio. Просто дважды щелкнув метод в результате, вы перейдете к объявлению метода в коде:

введите здесь описание изображения

По умолчанию предлагается около 200 кодовых запросов и правил CQLinq по умолчанию.

person Patrick from NDepend team    schedule 19.10.2010
comment
Вы знаете, я бы хотел использовать NDepend. Это коммерческий продукт, и руководство может не согласиться на это, к сожалению. :-( - person Ashish Gupta; 20.10.2010
comment
Надеемся, что при цене от нескольких сотен долларов инструмент окупится менее чем за месяц. - person Patrick from NDepend team; 20.10.2010

Я искал то же самое (чтобы получить общее количество строк в методе) и нашел решение.

Ниже приведен образец:

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, чтобы получить общее количество строк методом.

person Vijay Sutaria    schedule 20.05.2013