Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Добавить расчет когнитивной и цикломатической сложностей #1117

Open
ilya2184 opened this issue Aug 13, 2022 · 12 comments · May be fixed by #1261
Assignees
Labels
bsl 1C Built-in Script Language enhancement New feature or request

Comments

@ilya2184
Copy link

Описание проблемы

Было ба не плохо если бы в проверках "по стандартам" (я понимаю что стандарта нет такого) были два пункта:
Предельное значение когнитивной сложности
Предельное значение цикломатической сложности

При превышении указанных значений добавлялась незначительная ошибка конфигурации.

Описание решения проблемы

Предлагаю сделать так как это реализовано в BSL Language Server:
Когнитивная сложность (CognitiveComplexity)
Цикломатическая сложность (CyclomaticComplexity)

Дополнительная информация

No response

@ilya2184 ilya2184 added the enhancement New feature or request label Aug 13, 2022
@marmyshev marmyshev added the bsl 1C Built-in Script Language label Aug 15, 2022
@marmyshev
Copy link
Collaborator

Исходные ссылки на Когнитивную сложность и Википедия

@marmyshev
Copy link
Collaborator

Исходные ссылки на циклометрическую сложность Википедия Википедия RU

@DmitryShvaika
Copy link
Contributor

Проверка на цикломатическую сложность есть и у Microsoft
https://learn.microsoft.com/ru-ru/dotnet/fundamentals/code-analysis/quality-rules/ca1502

@RedMammoth
Copy link
Contributor

RedMammoth commented Mar 11, 2023

Что-то у меня разошлись значения когнитивной сложности в примере2 (https://1c-syntax.github.io/bsl-language-server/diagnostics/CognitiveComplexity/):
bls-ls говорит 33, а если подсчитать по комментам, вроде как 40.
image

Поэтому решил исходить из спецификации (Приложение B) источника (https://www.sonarsource.com/docs/CognitiveComplexity.pdf)

Буду придерживаться следующего алгоритма, поправьте, если допустил ошибки:

Конструкции увеличивающие сложность:

  • Если, ИначеЕсли, Иначе
  • тренарный оператор ?(,,)
  • циклы
  • ветвь исключения в попытке
  • переход к метке
  • логические операнды И, ИЛИ
  • рекурсивный вызов

Конструкции получающие дополнительный штраф за уровень вложенности:

  • если
  • тренарный оператор
  • циклы
  • ветвь исключения в попытке

Конструкции увеличивающие уровень вложенности:

  • если, ИначеЕсли, Иначе
  • тренарный оператор
  • циклы
  • ветвь исключения в попытке
  • вложенный вызов метода

@DmitryShvaika
Copy link
Contributor

А Edt умеет подсчитывать когнитивную и цикломатическую сложность? Не подскажите где эти настройки? И можно ли выдавать ошибку при превышении заданного порога?

@RedMammoth
Copy link
Contributor

А Edt умеет подсчитывать когнитивную и цикломатическую сложность? Не подскажите где эти настройки? И можно ли выдавать ошибку при превышении заданного порога?

Нет, ещё не умеет, как раз пробую научить. На скрине VCS с плагином

@RedMammoth
Copy link
Contributor

Взял в работу

@RedMammoth
Copy link
Contributor

RedMammoth commented Mar 13, 2023

Приведенный алгоритм цикломатической сложности тоже не нравится https://1c-syntax.github.io/bsl-language-server/diagnostics/CyclomaticComplexity/

Мне кажется мы не должны увеличивать счетчик для блока Иначе, также мне кажется цикломатическая сложность не возрастает при переходах goto. Зато, скорей всего необходимо учесть директивы препроцессора

@marmyshev
Copy link
Collaborator

Блок "Иначе" - это альтернативный (ещё один) вариант условий. Т.е. человек необходимо понять все условия срабатывания в "Если" или в "Иначе если" - потом понять весь скоуп всех возможных вариантов, вычесть из них те что могли отработать выше - и понять в каких же случаях реально будет срабатывание кода в "Иначе".

Это однозначное усложнение.

@marmyshev
Copy link
Collaborator

С метками goto всё ещё хуже: человек перестаёт понимать алгоритм линейно пока читает код, ему нужно перепрыгивать в другое место чтобы понимать и переносить (в своей голове) туда весь текущий контекст код, при чем он не может опираться на тот код который видит до метки, так как этого кода в данный момент (при переходе) не существует как бы.

То есть уровень загрузки/напряга мозга сильно повышается на метках.

@RedMammoth
Copy link
Contributor

RedMammoth commented Mar 14, 2023

Блок "Иначе" - это альтернативный (ещё один) вариант условий. Т.е. человек необходимо понять все условия срабатывания в "Если" или в "Иначе если" - потом понять весь скоуп всех возможных вариантов, вычесть из них те что могли отработать выше - и понять в каких же случаях реально будет срабатывание кода в "Иначе".

Это однозначное усложнение.

У нас Если добавляет ещё одну линию, вне зависимости от наличия Иначе, просто в сокращённом случае блок Если пустой и опускается. Поэтому наличие Если третью линию не добавляет. А вот ветки ИначеЕсли каждая добавляет по новой линии

Например:

Одна линия исполнения:

Процедура Тест()
    Инструкция1();
КонецПроцедуры;

Две линии исполнения (блок Если):

Процедура Тест()
    Инструкция1();
    Если Условиие Тогда
        Инструкция2();
    КонецЕсли;
КонецПроцедуры;

1: инструкция1, инструкция2
2: инстуркция1

По-прежнему две линии исполнения (блок Если Иначе):

Процедура Тест()
    Инструкция1();
    Если Условиие Тогда
        Инструкция2();
    Иначе
        Инстуркция3();
    КонецЕсли;
КонецПроцедуры;

1: Инструкция1, Инструкция2
2: Инстуркция1, Инструкция3

@RedMammoth
Copy link
Contributor

С метками goto всё ещё хуже: человек перестаёт понимать алгоритм линейно пока читает код, ему нужно перепрыгивать в другое место чтобы понимать и переносить (в своей голове) туда весь текущий контекст код, при чем он не может опираться на тот код который видит до метки, так как этого кода в данный момент (при переходе) не существует как бы.

То есть уровень загрузки/напряга мозга сильно повышается на метках.

То что мозг напряжется согласен, но изменится ли у нас количество линий исполнения?
Если правильно понимаю смысл цикломатической проверки, она должна сказать сколько минимум тестов нужно написать на код. Для это и подсчитываются линии исполнения. Можно ли подсчитать, сколько тестов добавит наличие перехода к метке?

VAGoncharov added a commit to VAGoncharov/v8-code-style that referenced this issue Mar 14, 2023
Доработана проверка SelfReferenceCheck: добавлена опция, позволяющая
пропускать проверку для модулей объектов, наборов записей, менеджеров
значений.
marmyshev added a commit that referenced this issue Apr 17, 2023
* Доработана проверка SelfReferenceCheck: добавлена опция, позволяющая
пропускать проверку для модулей объектов, наборов записей, менеджеров
значений.
* Исключение некоторых типов модулей из проверки
Модули, в которых ключевое слово "ЭтотОбъект" не является ссылкой на
модуль/объект-владельца, исключены из проверки.

---------

Co-authored-by: Dmitriy Marmyshev <dmar@1c.ru>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bsl 1C Built-in Script Language enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants