Skip to content

Feature/dead code improve#1770

Merged
nixel2007 merged 4 commits into
1c-syntax:developfrom
EvilBeaver:feature/dead-code-improve
Aug 25, 2025
Merged

Feature/dead code improve#1770
nixel2007 merged 4 commits into
1c-syntax:developfrom
EvilBeaver:feature/dead-code-improve

Conversation

@EvilBeaver

@EvilBeaver EvilBeaver commented Aug 31, 2021

Copy link
Copy Markdown
Collaborator

Описание

Предыдущий вариант UnreachableCode не отлавливал досрочный выход из процедуры

Если А Тогда
    Возврат 1;
Иначе
    Возврат 2;
КонецЕсли;

ТутОшибка = Истина; // <- недостижимый код

Связанные задачи

нет связанной задачи

Чеклист

Общие

  • Ветка PR обновлена из develop
  • Отладочные, закомментированные и прочие, не имеющие смысла участки кода удалены
  • Изменения покрыты тестами
  • Обязательные действия перед коммитом выполнены (запускал команду gradlew precommit)

Для диагностик

  • Описание диагностики заполнено для обоих языков (перевод на английский не обязателен)

Дополнительно

на голом Cfg сделать не удалось, т.е. UnreachableCode детектирует повторные недостижимые участки на уровне блока кода, а в текущей реализации Cfg нет информации о блоках кода. Диагностика работает по предыдущему алгоритму, затем строит CFG для мертвого кода, и те узлы, которые уже обнаружил старый алгоритм - фильтрует. Оставшиеся после фильра недостижимые узлы - это будут те, которые нашел только CFG, но не старая диагностика.

@coderabbitai

coderabbitai Bot commented Aug 19, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Публичен конструктор ControlFlowGraph. В UnreachableCodeDiagnostic добавлен анализ недостижимого кода на основе CFG при обходе файлового и подблочного кода. Обновлены тесты: ожидаемые диапазоны и добавлен новый кейс с ранним возвратом.

Changes

Cohort / File(s) Summary
CFG API exposure
src/main/java/.../cfg/ControlFlowGraph.java
Конструктор ControlFlowGraph изменён на public; логика инициализации без изменений.
Unreachable code via CFG
src/main/java/.../diagnostics/UnreachableCodeDiagnostic.java
Добавлены visitFileCodeBlock/visitSubCodeBlock; построение CFG через CfgBuildingParseTreeVisitor; вычисление вершин без входящих рёбер (кроме Entry/Exit) и регистрация диапазонов недостижимого кода с дедупликацией.
Tests: expectations
src/test/java/.../UnreachableCodeDiagnosticTest.java
Изменено ожидаемое число диагностик (15 → 17); обновлены и упорядочены проверяемые диапазоны.
Tests: fixtures
src/test/resources/diagnostics/UnreachableCodeDiagnostic.bsl
Добавлена функция ДосрочныйВыход() с ранними Возврат и последующим недостижимым оператором; незначительные правки форматирования.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Client as Analyzer (BSL LS)
  participant Diag as UnreachableCodeDiagnostic
  participant CFGV as CfgBuildingParseTreeVisitor
  participant CFG as ControlFlowGraph
  participant Store as DiagnosticStorage

  Client->>Diag: visitFileCodeBlock()/visitSubCodeBlock(ctx)
  activate Diag
  Diag->>CFGV: configure(producePreprocessorConditions, produceLoopIterations=false, determineAdjacentDeadCode=false)
  Diag->>CFGV: build(ctx.codeBlock)
  CFGV-->>Diag: ControlFlowGraph
  Diag->>CFG: collect vertices with in-degree=0<br/>(exclude Entry, ExitVertex)
  Diag->>Diag: map vertices->AST->ranges<br/>sort, deduplicate
  Diag->>Store: register unreachable code ranges
  deactivate Diag
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

В графе путей нашёлся тёмный лес,
Где входа нет — и кода тоже нет окрест.
Я, кролик, лапкой узелки развёл,
Недостижимый стих в диапазоны свёл.
Прыг-скок по рёбрам — и баг уловлён! 🐇✨

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@EvilBeaver
EvilBeaver force-pushed the feature/dead-code-improve branch from 0410b3e to 1c7beae Compare August 21, 2025 07:03
@sonarqubecloud

Copy link
Copy Markdown

@EvilBeaver EvilBeaver changed the title WIP: Feature/dead code improve Feature/dead code improve Aug 21, 2025
@EvilBeaver
EvilBeaver marked this pull request as ready for review August 21, 2025 07:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (6)
src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraph.java (1)

36-40: Публичный конструктор: оценить необходимость расширения API

Смена видимости конструктора на public расширяет поверхность API и допускает произвольное создание графа вне пакета. Если прямой инстанс ControlFlowGraph вне cfg не требуется (в текущем PR используется CfgBuildingParseTreeVisitor#buildGraph), лучше сохранить пакетную видимость, либо добавить явную JavaDoc/аннотацию (например, «Intended for external consumers») с описанием инвариантов (наличие exitPoint, поведение entryPoint). Это снизит риск неправильного использования и облегчит сопровождение публичного контракта.

src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnosticTest.java (1)

54-59: Стабилизировать проверку нового кейса раннего выхода отдельным тестом

Текущие жестко прошитые координаты остаются чувствительными к правкам тестового BSL-файла. Рекомендую вынести сценарий «раннего выхода» в отдельный метод-тест с более локальными проверками (например, по границам внутри функции или по уникальной метке-комментарию), чтобы уменьшить хрупкость набора координат.

Готов предложить заготовку теста с более устойчивой проверкой при необходимости.

src/test/resources/diagnostics/UnreachableCodeDiagnostic.bsl (2)

124-127: Опечатки в комментарии

Небольшие опечатки в пользовательском (пусть и тестовом) комментарии — лучше поправить для читаемости.

Предлагаемый патч:

-    #КонецЕсли
-
-    Метод2();   // <-- Ошибка: ренее были Возврат и Вызватьисключение, ка не ловим
+    #КонецЕсли
+
+    Метод2();   // <-- Ошибка: ранее были Возврат и ВызватьИсключение, но не ловим

157-165: Новый кейс «ДосрочныйВыход» — удачно покрывает ранний возврат

Добавленная функция хорошо валидирует недостижимость кода после возврата из обеих веток. В качестве расширения можно добавить аналогичный кейс с цепочкой ИначеЕсли и/или с препроцессором внутри веток, чтобы проверить устойчивость анализа на составных ветвлениях.

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnostic.java (2)

132-146: CFG: улучшить точность фильтра и порядок сортировки

  • Для исключения узла выхода лучше использовать instanceof, а не сравнение классов (на будущее, если появятся наследники):
-      .filter(vertex -> vertex != graph.getEntryPoint() && vertex.getClass() != ExitVertex.class)
+      .filter(vertex -> vertex != graph.getEntryPoint() && !(vertex instanceof ExitVertex))
  • Сортировку стоит детализировать по позиции в строке — так стабильнее при нескольких узлах на одной строке:
-      .sorted(Comparator.comparingInt(bslParserRuleContext -> bslParserRuleContext.getStart().getLine()))
+      .sorted(
+        Comparator.comparingInt((BSLParserRuleContext r) -> r.getStart().getLine())
+                  .thenComparingInt(r -> r.getStart().getCharPositionInLine())
+      )
  • Метод выделяет только вершины с inDegree == 0. Это гарантированно включает «корневые» куски недостижимого кода, но может пропустить узлы, достижимые только из уже недостижимых (например, тело цикла/условия, расположенное после точки отсечения). В перспективе можно рассмотреть подход «все вершины − достижимые из entry» (поиск в ширину/глубину от entryPoint) — он даст полный набор недостижимых узлов. Это необязательная доработка в рамках «chill»-ревью, текущий подход решает заявленную проблему раннего выхода.

148-166: Дедупликация: учесть пересечения и среди «новых» диапазонов; обновлять кэш

Сейчас проверка исключает только диапазоны, уже обнаруженные старым алгоритмом. При нескольких узлах в одном BasicBlock возможны дубли/пересечения внутри deadCode. Предлагаю:

  • дедуплицировать также по уже отобранным «новым» диапазонам;
  • после регистрации добавить их в errorRanges для симметрии и защиты от повторной регистрации в соседних обходах.

Патч:

-    var newRanges = new ArrayList<Range>();
+    var acceptedRanges = new ArrayList<Range>();
     for (var range : deadCode) {
       var alreadyDetected = false;
       for (Range detectedRange : errorRanges) {
         var pos = new Position(range.getStart().getLine(), range.getStart().getCharacter());
         if (Ranges.containsPosition(detectedRange, pos)) {
           alreadyDetected = true;
           break;
         }
       }
-      if(!alreadyDetected) {
-        newRanges.add(range);
+      if (!alreadyDetected) {
+        // проверим пересечения и с уже принятыми новыми диапазонами
+        for (Range accepted : acceptedRanges) {
+          var pos = new Position(range.getStart().getLine(), range.getStart().getCharacter());
+          if (Ranges.containsPosition(accepted, pos)) {
+            alreadyDetected = true;
+            break;
+          }
+        }
+      }
+      if (!alreadyDetected) {
+        acceptedRanges.add(range);
       }
     }
 
-    for (var range : newRanges) {
+    // обновим кэш для последующих проверок
+    errorRanges.addAll(acceptedRanges);
+
+    for (var range : acceptedRanges) {
       diagnosticStorage.addDiagnostic(range);
     }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9b7df1a and 1c7beae.

📒 Files selected for processing (4)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ControlFlowGraph.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnostic.java (3 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnosticTest.java (2 hunks)
  • src/test/resources/diagnostics/UnreachableCodeDiagnostic.bsl (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnostic.java (2)
src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/CfgBuildingParseTreeVisitor.java (1)
  • CfgBuildingParseTreeVisitor (34-643)
src/main/java/com/github/_1c_syntax/bsl/languageserver/cfg/ExitVertex.java (1)
  • ExitVertex (24-29)
🔇 Additional comments (5)
src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnosticTest.java (1)

41-41: Обновление ожидаемого количества диагностик — выглядит корректно

Увеличение с 15 до 17 согласуется с добавленным кейсом раннего выхода и расширенным покрытием CFG.

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UnreachableCodeDiagnostic.java (4)

24-26: Импорты для CFG-анализа — уместно

Новые импорты (CfgBuildingParseTreeVisitor, ExitVertex, Comparator) соответствуют добавленной логике и выглядят корректно.

Also applies to: 42-42


116-122: Порядок вызовов и очистка кэша — ок

Очистка errorRanges перед super.visitSubCodeBlock(ctx) и последующий вызов appendUnreachableCode обеспечивает дедупликацию «новых» находок относительно «старого» алгоритма. Логика вызовов выглядит правильной.


124-130: Аналогично для FileCodeBlock — выглядит консистентно

Та же последовательность шагов для файлового блока поддерживает единое поведение.


169-251: Совместимость с препроцессором и кэшированием — поведение согласовано

Проверка на вхождение в ранее зафиксированные диапазоны, а также учет препроцессорных блоков при вычислении конца текущего блока выглядят корректно и совместимы с новой веткой CFG-анализа.

@nixel2007
nixel2007 merged commit 1fd31a5 into 1c-syntax:develop Aug 25, 2025
22 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Nov 20, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants