Skip to content

Conversation

@theshadowco
Copy link
Member

Значительный рефакторинг парсера описаний

  • более точное чтение параметров и описаний методов
  • разделены типы, явно выделены Простой, ГиперСсылка и Коллекция

@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

Walkthrough

Рефакторинг системы парсинга описаний методов: замена грамматик BSLMethodDescription на BSLDescription, введение новой типизированной модели данных (TypeDescription, ParameterDescription), добавление reader-ориентированного парсинга через MethodDescriptionReader и VariableDescriptionReader, включение поддержки Lombok для неизменяемых объектов.

Changes

Cohort / File(s) Резюме
Конфигурация Gradle
build.gradle.kts
Добавлен плагин Lombok 9.1.0 с отключением задач delombok и delombokTest
ANTLR грамматики (новые)
src/main/antlr/BSLDescriptionLexer.g4, src/main/antlr/BSLDescriptionParser.g4
Новые грамматики для парсинга описаний с поддержкой ключевых слов, параметров, возвращаемых значений, примеров, директив об устаревании; замена старых BSLMethodDescription грамматик
ANTLR грамматики (удалённые)
src/main/antlr/BSLMethodDescriptionLexer.g4, src/main/antlr/BSLMethodDescriptionParser.g4
Полное удаление старых грамматик описания методов
Типы данных — интерфейсы
src/main/java/com/github/_1c_syntax/bsl/parser/description/TypeDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/SourceDefinedSymbolDescription.java
Новый интерфейс TypeDescription с вариантами SIMPLE, COLLECTION, HYPERLINK; обновлен SourceDefinedSymbolDescription (getLink → getLinks, getSimpleRange → getRange, добавлен getElements)
Типы данных — реализации
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java
Новые классы-реализации для простых, коллекционных и гиперссылочных типов с фабрик-методами create(...)
Модели данных
src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElement.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java
Новые public-записи и классы; ParameterDescription теперь record с методами isHyperlink(), link(), allElements(); Hyperlink с фабриками create(...); DescriptionElement с enum Type
Основные модели с Lombok
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java
Рефакторинг на @Value @Builder; новые фабрик-методы create(...); удалены старые методы парсинга; добавлены поля links (List), elements (lazy), keywords
Readers (новые)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/ReaderUtils.java
Новые классы для парсинга описаний методов и переменных; ReaderUtils с extractText и readLinks; поддержка visitor-паттерна на AST
Удалённые readers
src/main/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReader.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionReader.java
Полное удаление старых утилит парсинга (заменены на reader-классы в пакете reader/)
Поддержка
src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java
Преобразование из класса в record с новыми фабриками create(...) для Token; добавлены isEmpty(), contains(), length(); удалены getters
Удалённые модели
src/main/java/com/github/_1c_syntax/bsl/parser/description/support/ParameterDescription.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/support/TypeDescription.java
Удаление старых классов из support пакета (перемещены в основной пакет description с новой семантикой)
Package-info
src/main/java/com/github/_1c_syntax/bsl/parser/description/package-info.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/package-info.java, src/main/java/com/github/_1c_syntax/bsl/parser/description/support/package-info.java
Добавлены package-level аннотации @ReturnValuesAreNonnullByDefault, @ParametersAreNonnullByDefault
Tokenizer (переименован)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionTokenizer.java
Переименован из BSLMethodDescriptionTokenizer, перемещён в пакет reader, обновлены ссылки на BSLDescriptionParser/Lexer
Тесты — новые
src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionLexerTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserMatchesTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElementTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java
Новые тесты для новых лексер/парсер, новых типов, расширенное покрытие SimpleRange; обновлены существующие тесты в BSLDescriptionReaderTest
Тесты — удалённые и обновлённые
src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionLexerTest.java, src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionParserCheckSourceTest.java
Удаление старых тестов BSLMethodDescription; переименование и обновление MatchesTest на новые грамматики
Тестовые ресурсы
src/test/resources/methodDescription/example*.bsl
Незначительные правки форматирования (конечные символы новой строки), добавлена строка устаревания в example1.bsl
ANTLR прочее
src/main/antlr/BSLLexer.g4, src/main/antlr/BSLParser.g4, src/main/antlr/SDBLLexer.g4, src/main/antlr/SDBLParser.g4
Обновление года копирайта с 2018-2022 на 2018-2026 (без функциональных изменений)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

  • новая версия antlr + отказ от bsl-parser-core #330: Пересекающиеся изменения в ANTLR грамматиках (удаление/переименование BSLMethodDescription, добавление/использование BSLDescriptionLexer/Parser, обновление tokenizer-конструкторов)

Poem

🐰 Сказал кролик радостно: новая грамматика блеск!
Типы, гиперссылки, читатели — целый успех!
Lombok при помощи шьёт неизменяемый класс,
Рефакторинг смелый спасает парсер в час. ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 19.76% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок точно описывает основное изменение PR — рефакторинг парсера описаний методов и переменных с явным разделением типов.
Description check ✅ Passed Описание PR содержит релевантную информацию о целях рефакторинга: более точное чтение параметров, явное разделение типов на три категории.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 Fix all issues with AI agents
In @build.gradle.kts:
- Around line 100-106: Disabling the delombok tasks (tasks.named("delombok") and
tasks.maybeCreate("delombokTest")) will break javadoc generation because the
io.freefair.lombok plugin expects delomboked sources; either re-enable those
delombok tasks or, if you intentionally want to skip delombok, explicitly point
the javadoc/javadocJar generation to use an alternative source set (the delombok
output directory or your original sources plus generated Lombok members) and
document the decision; update the javadoc task (and the javadocJar artifact) to
use the delombok task output as its source or restore the delombok tasks so
generated Lombok members are included.

In @src/main/antlr/BSLDescriptionLexer.g4:
- Line 4: Update the copyright header string "Copyright © 2018-2022" in the
BSLDescriptionLexer.g4 file to match the project's current year range (replace
with "Copyright © 2018-2026") so it is consistent with other new files in the
PR.

In @src/main/antlr/BSLDescriptionParser.g4:
- Line 4: Update the outdated copyright year string "Copyright © 2018-2022" in
BSLDescriptionParser.g4 to "Copyright © 2018-2026"; also mirror the same change
in the corresponding lexer file where you previously updated the year to keep
headers consistent.

In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java:
- Around line 201-220: In MethodDescriptionReader.visitReturnsValue replace the
mistaken assignment of typeLevel from ctx.getText().length() with the computed
currentLevel so nesting is tracked correctly: when setting typeLevel after
calling lastReadParam.addType(...), assign typeLevel = currentLevel (not
ctx.getText().length()) to ensure subsequent return-values use the correct
level; keep the rest of the branching that builds the fallback text and calls
lastReadParam.addTypeDescription(...) unchanged.

In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java:
- Around line 53-62: The current create(...) method returns EMPTY when name and
description are empty but ignores fieldList, losing passed fields; change the
emptiness check in create to return EMPTY only when name.strip().isEmpty(),
description.strip().isEmpty() AND (fieldList == null || fieldList.isEmpty()),
i.e., make the condition null-safe and include fieldList emptiness check before
returning EMPTY, while keeping the existing construction using new
SimpleTypeDescription(name.strip().intern(), description.strip(), fieldList).

In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java:
- Around line 74-89: The current equals(Object) violates symmetry by
special-casing String and also no hashCode() override is provided; change
equals(Object) to only compare Hyperlink instances (implement the canonical
pattern: if (this == other) return true; if (!(other instanceof Hyperlink))
return false; compare link and params), add a new public boolean
equalsPresentation(String) that delegates to create(String) and compares to this
(using equals or component comparison), and implement hashCode() consistent with
equals (e.g., compute from link and params) so collections behave correctly;
update/remove the String branch in equals() and add the new
equalsPresentation(String) and hashCode() methods (referencing equals(Object),
equalsPresentation(String), create(String), and hashCode()).
- Around line 61-72: The create(String presentation) method incorrectly checks
posEnd == 0 after calling lastIndexOf(")"); lastIndexOf returns -1 when not
found, so change the condition to check posEnd < 0 (or posEnd <= pos) and handle
missing/too-early closing paren by setting posEnd = presentation.length() - 1
(or treating content as empty if pos+1 >= presentation.length()); update the
logic around pos, posEnd and the substring calls in Hyperlink.create to use the
corrected check so the label is substring(0, pos) and the target is
substring(pos+1, posEnd) only when pos+1 < posEnd, otherwise pass an empty
target to the existing create(label, target) overload.

In
@src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java:
- Around line 29-292: The test suite is missing test methods for existing
resource files example7.bsl and example8.bsl; add two new @Test methods named
testExample7() and testExample8() that mirror the style of other tests by
calling testParser.assertThatFile("methodDescription/example7.bsl") and
testParser.assertThatFile("methodDescription/example8.bsl") and chaining
appropriate containsRule(...) assertions matching the expected parse counts for
those files (use the same pattern as testExample1..testExample10 to assert
BSLDescriptionParser.RULE_* rules, ensuring method names testExample7 and
testExample8 and use testParser field and its assertThatFile(...) method).

In
@src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java:
- Around line 123-134: The test method named
testCreateFromPresentationWithUnmatchedBrackets is misleading because the
presentation string "example(param1,param2)" has matched brackets; either rename
the test to testCreateFromPresentationWithParams (or remove it if it duplicates
the existing testCreateFromPresentationWithParams) to reflect the actual
behavior being asserted (calls to Hyperlink.create and checks of
hyperlink.link() and hyperlink.params()), or if the intent was to test unmatched
brackets update the presentation to an unmatched form like
"example(param1,param2" and adjust the expected assertions for hyperlink.link()
/ hyperlink.params() accordingly.
🧹 Nitpick comments (8)
src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java (1)

252-252: TODO-комментарий требует внимания.

Комментарий // на самом деле меньше todo исправить указывает на известную проблему с подсчётом RULE_type. Рекомендуется либо исправить ожидаемое значение, либо создать issue для отслеживания.

Хотите, чтобы я создал issue для отслеживания этой задачи?

src/main/antlr/BSLDescriptionParser.g4 (1)

122-122: Опечатка в названии правила: spittersplitter?

Название правила spitter выглядит как опечатка. Возможно, подразумевалось splitter (разделитель). Если это намеренно — игнорируйте.

src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java (2)

34-51: Дублирование тестового покрытия с существующим тестом.

Новый метод testContainsRange дублирует функциональность существующего теста containsRange (строки 180-198). Хотя новый тест добавляет дополнительные граничные случаи, рекомендуется объединить оба теста в один для улучшения читаемости и сокращения дублирования кода.


174-178: Дублирование тестового покрытия с существующим тестом.

Метод testToString дублирует проверки из существующего теста toStringRange (строки 213-224). Рекомендуется объединить эти тесты для избежания избыточности.

src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)

35-45: Несоответствие использования аннотаций с родственными классами.

Поля класса помечены только @Accessors(fluent = true), в то время как аналогичные классы SimpleTypeDescription и CollectionTypeDescription используют комбинацию @Getter и @Accessors(fluent = true) для каждого поля. Хотя аннотация @Value автоматически генерирует геттеры, явное добавление @Getter обеспечит согласованность с другими реализациями TypeDescription и гарантирует корректную работу fluent-аксессоров.

♻️ Предлагаемое исправление для согласованности
  @Accessors(fluent = true)
+ @Getter
  String name;

  @Accessors(fluent = true)
+ @Getter
  String description;

  @Accessors(fluent = true)
+ @Getter
  List<ParameterDescription> fields;

  @Accessors(fluent = true)
+ @Getter
  Hyperlink hyperlink;
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (2)

203-204: Небезопасное приведение типа родительского контекста.

Приведение ctx.getParent() к BSLDescriptionParser.ReturnsValuesStringContext выполняется без проверки типа. Если структура AST изменится, это приведёт к ClassCastException.

♻️ Предлагаемое исправление с проверкой типа
   @Override
   public ParseTree visitReturnsValue(BSLDescriptionParser.ReturnsValueContext ctx) {
-    var currentLevel = ((BSLDescriptionParser.ReturnsValuesStringContext) ctx.getParent())
-      .startPart().getText().length();
+    var parent = ctx.getParent();
+    if (!(parent instanceof BSLDescriptionParser.ReturnsValuesStringContext returnsContext)) {
+      return ctx;
+    }
+    var currentLevel = returnsContext.startPart().getText().length();

470-477: Избыточная проверка на null для hyperlink.

Поле hyperlink инициализируется значением Hyperlink.EMPTY в конструкторе (строка 392), поэтому проверка hyperlink == null на строке 473 никогда не будет истинной.

♻️ Упрощение кода
         case HYPERLINK -> HyperlinkTypeDescription.create(
-          hyperlink == null ? Hyperlink.EMPTY : hyperlink,
+          hyperlink,
           description.toString(),
           fieldList
         );
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)

39-49: Избыточные аннотации @Getter при использовании @Value.

Аннотация @Value от Lombok уже включает @Getter для всех полей. Явное указание @Getter с @Accessors(fluent = true) излишне, поскольку @Value генерирует геттеры автоматически.

Для согласованности с другими классами проекта (HyperlinkTypeDescription, CollectionTypeDescription) можно оставить текущий стиль, но это технически избыточно.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 128bcd9 and 0b5361c.

📒 Files selected for processing (42)
  • build.gradle.kts
  • src/main/antlr/BSLDescriptionLexer.g4
  • src/main/antlr/BSLDescriptionParser.g4
  • src/main/antlr/BSLMethodDescriptionLexer.g4
  • src/main/antlr/BSLMethodDescriptionParser.g4
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SourceDefinedSymbolDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/TypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/package-info.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/BSLMethodDescriptionTokenizer.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/ReaderUtils.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/package-info.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/ParameterDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/TypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/package-info.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionLexerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserMatchesTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionLexerTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionParserCheckSourceTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java
  • src/test/resources/methodDescription/example1.bsl
  • src/test/resources/methodDescription/example10.bsl
  • src/test/resources/methodDescription/example2.bsl
  • src/test/resources/methodDescription/example3.bsl
  • src/test/resources/methodDescription/example4.bsl
  • src/test/resources/methodDescription/example5.bsl
  • src/test/resources/methodDescription/example6.bsl
  • src/test/resources/methodDescription/example9.bsl
💤 Files with no reviewable changes (8)
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionLexerTest.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReader.java
  • src/main/antlr/BSLMethodDescriptionParser.g4
  • src/main/antlr/BSLMethodDescriptionLexer.g4
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLMethodDescriptionParserCheckSourceTest.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/TypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/ParameterDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionReader.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-19T04:17:18.990Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-parser PR: 330
File: src/main/java/com/github/_1c_syntax/bsl/parser/BSLTokenizer.java:30-30
Timestamp: 2025-11-19T04:17:18.990Z
Learning: In BSLTokenizer, SDBLTokenizer, and BSLMethodDescriptionTokenizer constructors in the bsl-parser project, passing an empty CharStream (CharStreams.fromString("")) to the lexer is intentional. This is a lazy initialization pattern where the parent Tokenizer class properly initializes the lexer later on first AST access, rather than at tokenizer creation time.

Applied to files:

  • src/main/antlr/BSLDescriptionLexer.g4
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/BSLMethodDescriptionTokenizer.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionLexerTest.java
🧬 Code graph analysis (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (32-70)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (32-60)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (32-70)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)
  • Value (36-68)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (32-60)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)
  • Value (36-68)
src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)
  • VariableDescriptionReader (37-94)
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (1)
  • Value (37-95)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: QA
🔇 Additional comments (43)
src/main/java/com/github/_1c_syntax/bsl/parser/description/package-info.java (1)

25-31: Отличное улучшение null-безопасности!

Добавление аннотации @ReturnValuesAreNonnullByDefault последовательно применяет политику null-безопасности к пакету. В сочетании с уже существующей @ParametersAreNonnullByDefault это обеспечивает проверку на этапе компиляции и снижает риск NPE.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/package-info.java (1)

25-31: LGTM!

Изменения идентичны родительскому пакету и обеспечивают согласованность аннотаций null-безопасности во всей иерархии пакетов.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/package-info.java (1)

1-31: Отличное создание нового пакета с правильными аннотациями!

Новый пакет reader правильно настроен с обеими аннотациями null-безопасности с самого начала. Это соответствует целям PR по рефакторингу парсера и созданию читателей для более точного чтения параметров и описаний методов.

build.gradle.kts (1)

14-14: Плагин Lombok успешно добавлен.

Версия 9.1.0 является актуальной (релиз от 8 ноября 2025 г.) и соответствует другим плагинам io.freefair в проекте.

src/test/resources/methodDescription/example10.bsl (1)

34-34: Нет замечаний.

Изменение — только нормализация завершающей новой строки в конце файла. Это форматирующее изменение без функциональных последствий.

src/test/resources/methodDescription/example5.bsl (1)

331-331: Нет замечаний.

Изменение — только нормализация завершающей новой строки в конце файла. Это форматирующее изменение без функциональных последствий.

src/test/resources/methodDescription/example2.bsl (1)

8-8: Нет замечаний.

Изменение — только нормализация завершающей новой строки в конце файла. Это форматирующее изменение без функциональных последствий.

src/test/resources/methodDescription/example1.bsl (1)

76-76: Форматирование EOF согласовано с требованиями тестовых ресурсов.

Добавлена правильная концевая строка для согласованности с другими примерами в наборе тестов.

src/test/resources/methodDescription/example9.bsl (1)

50-50: EOF форматирование стандартизировано.

Добавлена явная концевая строка для согласованности с примерами тестов в наборе.

src/test/resources/methodDescription/example4.bsl (1)

11-11: EOF форматирование согласовано с набором тестов.

Добавлена явная концевая строка для единообразия со всеми примерами тестовых ресурсов.

src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionLexerTest.java (1)

1-227: Отличная работа с тестированием лексера!

Тесты всесторонне покрывают функциональность BSLDescriptionLexer: обработку пробелов, BOM, ключевых слов (SEE, Parameters, Returns, Example, Call options, Deprecate) и различных комбинаций токенов. Структура тестов чёткая, используются подходящие утверждения для проверки последовательностей токенов.

src/test/resources/methodDescription/example3.bsl (1)

24-24: Изменение форматирования выглядит корректно.

Добавление завершающей строки комментария для тестирования обработки конца файла.

src/test/resources/methodDescription/example6.bsl (1)

61-61: Изменение форматирования выглядит корректно.

Добавление завершающей строки комментария согласуется с изменениями в других тестовых ресурсах.

src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java (1)

30-122: Отличное покрытие тестами класса Hyperlink!

Тесты охватывают основные сценарии: создание с параметрами и без, обработку null/пустых значений, парсинг из строки представления, проверку равенства. Структура тестов соответствует best practices с использованием given/when/then.

Also applies to: 136-186

src/main/java/com/github/_1c_syntax/bsl/parser/description/TypeDescription.java (1)

30-67: Превосходный дизайн интерфейса TypeDescription!

Интерфейс чётко определяет контракт для описания типов с тремя явными вариантами (SIMPLE, COLLECTION, HYPERLINK), что полностью соответствует целям рефакторинга, указанным в PR. Методы хорошо документированы, API интуитивно понятен. Разделение типов через enum Variant обеспечивает типобезопасность и упрощает обработку различных категорий типов.

src/main/antlr/BSLDescriptionLexer.g4 (1)

25-55: Лексер-грамматика корректна и хорошо структурирована.

Использование caseInsensitive=true, поддержка многоязычных ключевых слов (EN/RU), Unicode-свойства для LETTER (\p{Letter}) и обработка различных типов дефисов в DASH — всё выглядит продуманно.

src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java (2)

35-43: Корректная реализация record с нормализацией данных.

Использование strip().intern() для имени параметра и Collections.unmodifiableList для защитного копирования списка типов — хорошие практики.


50-62: Методы isHyperlink() и link() работают корректно.

Логика проверки и получения гиперссылки реализована правильно. Метод link() безопасно использует результат isHyperlink() перед приведением типа.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/ReaderUtils.java (2)

49-63: Метод extractText реализован корректно.

Обработка null/empty контекста, пропуск StartPartContext и финальный strip() — логика понятна и безопасна.


65-78: Метод readLinks корректно обрабатывает гиперссылки.

Использование Trees.findAllRuleNodes для поиска узлов и null-проверки для link и linkParams — правильный подход. Возврат Collections.emptyList() вместо пустого списка экономит память.

src/main/java/com/github/_1c_syntax/bsl/parser/description/SourceDefinedSymbolDescription.java (2)

79-90: Переименование getSimpleRange()getRange() и обновлённый contains().

Корректное использование статического метода SimpleRange.containsRange() в default-реализации.


68-72: Breaking change verified: getLink()getLinks() and getSimpleRange()getRange().

The API changes correctly replace single reference accessors with list-based ones. All implementations (MethodDescription, VariableDescription) have been updated with Lombok-generated getters, and all 17+ usages in tests properly call the new methods. No orphaned references to old method names remain in the codebase.

src/main/antlr/BSLDescriptionParser.g4 (2)

31-36: Гибкая структура methodDescription с двумя альтернативами порядка блоков.

Грамматика позволяет размещать deprecateBlock как в начале, так и в конце описания метода, что обеспечивает совместимость с разными стилями документирования.


114-119: Типы хорошо структурированы: simple, collection, hyperlink, list.

Разделение на три категории типов (простой, коллекция, гиперссылка) соответствует целям PR. Правило listTypes позволяет комбинировать типы через запятую.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java (1)

43-51: Фабричный метод create(link, params) корректен.

Правильная обработка null-значений и возврат EMPTY sentinel при пустой ссылке. Использование intern() для оптимизации памяти — хорошая практика.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)

37-93: LGTM!

Реализация reader'а для описаний переменных выглядит корректно. Использован паттерн Visitor для обхода AST, правильно применен builder pattern, и обработка различных блоков описания выполнена последовательно.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/BSLMethodDescriptionTokenizer.java (1)

22-40: LGTM!

Рефакторинг токенизатора для использования новых классов BSLDescriptionLexer и BSLDescriptionParser выполнен корректно. Изменения согласованы с общей архитектурой рефакторинга парсера описаний.

На основании сохранённых знаний: передача пустого CharStream в конструктор лексера является намеренным паттерном ленивой инициализации в данном проекте.

src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)

32-70: LGTM!

Реализация CollectionTypeDescription выглядит корректно. Класс последовательно использует аннотации @Getter и @Accessors(fluent = true), правильно реализует паттерн фабричного метода, и корректно формирует имя типа с синтаксисом generics (например, Array<String>). Использование intern() для оптимизации работы со строками является хорошей практикой.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (2)

62-73: Хорошая структура парсинга с делегированием.

Код корректно разделяет создание токенизатора, посещение AST и сборку результата. Использование requireNonNull для AST — правильный подход для раннего обнаружения ошибок.


225-373: Хорошая инкапсуляция временных данных параметров.

Класс TempParameterData корректно реализует паттерн Builder для накопления данных во время парсинга. Использование intern() для имён параметров — разумная оптимизация памяти для часто повторяющихся строк.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java (3)

36-36: Отличный рефакторинг: переход на record.

Преобразование класса в record — правильное решение для неизменяемого значения-объекта. Это устраняет шаблонный код и улучшает читаемость.


81-89: Удобный фабричный метод для одиночного токена.

Новый метод create(Token token) упрощает создание диапазона для одного токена, делегируя вызов существующему методу.


132-140: Метод isEmpty() корректно определяет пустой диапазон.

Логика проверки всех координат на равенство нулю соответствует поведению create(List<Token>) для пустого списка (строка 99).

src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (2)

37-86: Хороший рефакторинг с использованием Lombok и делегированием.

Переход на @Value и @Builder с делегированием парсинга в VariableDescriptionReader следует тому же паттерну, что и MethodDescription. Это обеспечивает согласованность API и разделение ответственности.


78-78: Использование Optional для trailingDescription — корректное решение.

Optional<VariableDescription> явно выражает опциональность «висячего» комментария и предотвращает null-значения.

src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserMatchesTest.java (2)

30-37: Тесты корректно обновлены для нового парсера.

Переход на BSLDescriptionParser и BSLDescriptionLexer с использованием блочных правил (deprecateBlock, parametersBlock и т.д.) соответствует рефакторингу грамматики.


57-86: Хорошее покрытие тестами блока deprecateBlock.

Тесты проверяют различные сценарии: пустой ввод, наличие/отсутствие описания устаревания, корректность сопоставления правил. Это обеспечивает надёжность парсинга блока устаревания.

src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (2)

37-94: Отличный рефакторинг модели описания метода.

Переход на @Value и @Builder с делегированием парсинга в MethodDescriptionReader значительно упрощает класс. Использование @Singular для parameters позволяет удобно добавлять параметры через builder.


74-75: Корректное использование @Singular для списка параметров.

Аннотация @Singular позволяет добавлять параметры по одному через метод parameter() в builder, что используется в MethodDescriptionReader.

src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java (4)

39-109: Комплексные тесты для парсинга описаний методов.

Тесты parseMethodDescription проверяют все аспекты: назначение, примеры, ссылки, параметры, возвращаемые значения и диапазоны. Хорошее покрытие вложенных структур.


564-589: Хорошо спроектированные вспомогательные методы для проверок.

Методы checkParameter() и checkType() инкапсулируют логику проверок и используют новый fluent API (name(), types(), fields(), variant()). Проверка isHyperlink через type.variant() == TypeDescription.Variant.HYPERLINK — корректный подход.


336-348: Тест корректно проверяет парсинг гиперссылок в параметрах.

Тест parseMethodDescription7 валидирует сценарий, когда параметр содержит только ссылку See. Проверка через Hyperlink.create() и сравнение containsExactly обеспечивает точность.


386-403: Тесты для VariableDescription охватывают основные сценарии.

Тест parseVariableDescription проверяет создание описания переменной, включая пустые ссылки и диапазон. Это базовый сценарий для валидации нового API.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @src/main/antlr/BSLDescriptionParser.g4:
- Around line 32-36: The grammar rule methodDescription contains two redundant
alternatives allowing deprecateBlock either at the start or the end; tests and
examples only use deprecateBlock at the beginning, so remove the second
alternative and collapse the rule to a single sequence where deprecateBlock?
precedes the other optional blocks (keep references to methodDescription and
deprecateBlock and the other block names: descriptionBlock, parametersBlock,
returnsValuesBlock, examplesBlock) followed by EOF to make the intended block
order explicit and simplify the grammar.
- Line 115: Правило simpleType содержит неиспользуемый optional токен
colon=COLON? после typeName=(WORD | DOTSWORD); удалите этот фрагмент
(colon=COLON?) из правила simpleType в BS LDescriptionParser.g4 чтобы типы
парсятся как в тестах (typeName = WORD | DOTSWORD без двоеточия); если двоеточие
нужен по спецификации — вместо удаления оставьте colon=COLON? и добавьте
поясняющий комментарий над правилом simpleType, объясняющий почему двоеточие
допустимо и в каких случаях используется.

In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java:
- Around line 51-60: In SimpleTypeDescription.create, trim the inputs before
checking emptiness so names or descriptions that are only whitespace produce
EMPTY: call name = name.strip() and description = description.strip() (then
check name.isEmpty() && description.isEmpty()) and only call name.intern() when
constructing the new SimpleTypeDescription; also adjust the `if` formatting to
include a space after `if` to match Java style.
🧹 Nitpick comments (7)
src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java (2)

139-152: Рассмотрите расширение теста обработки EOF-токена.

Тест проверяет только endCharacter, но не проверяет остальные поля диапазона (startLine, startCharacter, endLine). Для полноты убедитесь, что EOF-токен не нарушает создание всего диапазона.

💡 Предлагаемое улучшение
     var range = SimpleRange.create(startToken, eofToken);
 
+    assertThat(range.startLine()).isEqualTo(1);
+    assertThat(range.startCharacter()).isEqualTo(5);
+    assertThat(range.endLine()).isEqualTo(3);
     assertThat(range.endCharacter()).isEqualTo(10);

163-172: Рассмотрите объединение тестов equals.

Новый тест testEqualsAndHashCode и существующий тест equalsRange (строки 180-190) частично пересекаются в проверке метода equals(). Можно рассмотреть консолидацию этих тестов или явное разделение ответственности (например, один тест для контракта equals/hashCode, другой для специфичных граничных случаев).

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)

50-85: Потенциально запутывающее название метода.

На строке 83 вызывается visitMethodDescription(ast) внутри класса VariableDescriptionReader. Хотя это, вероятно, корректно (если грамматика использует общую структуру для описаний переменных и методов), название может вводить в заблуждение при сопровождении кода.

💡 Рекомендация

Рассмотрите возможность добавления комментария, объясняющего, почему VariableDescriptionReader вызывает visitMethodDescription(), или создайте wrapper-метод с более понятным названием, например visitVariableDescription().

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (1)

275-287: Минимизируйте повторные вызовы методов.

На строке 282 метод fieldContext.typesBlock() вызывается дважды. Рекомендуется сохранить результат в переменную для улучшения читаемости.

♻️ Предлагаемое улучшение
       } else {
         var fld = create(fieldContext.parameterName().getText());
         fld.level = level;
-        if (fieldContext.typesBlock() != null) {
-          fld.addType(fieldContext.typesBlock().type(), fieldContext.typesBlock().typeDescription());
+        var typesBlock = fieldContext.typesBlock();
+        if (typesBlock != null) {
+          fld.addType(typesBlock.type(), typesBlock.typeDescription());
         }

         return fld;
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)

26-26: Неиспользуемый импорт.

Импорт lombok.Getter не используется, поскольку аннотация @Value уже генерирует геттеры для всех полей.

♻️ Предлагаемое исправление
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
-import lombok.Getter;
 import lombok.Value;
 import lombok.experimental.Accessors;
src/main/antlr/BSLDescriptionParser.g4 (2)

42-51: Рассмотрите упрощение сложных отрицаний для улучшения читаемости.

Правило descriptionString использует сложное отрицание на строке 47: ~(PARAMETERS_KEYWORD | RETURNS_KEYWORD | EXAMPLE_KEYWORD | DEPRECATE_KEYWORD | EOL | EOF | SPACE). Хотя это корректный паттерн ANTLR для исключения ключевых слов, такие конструкции усложняют понимание и поддержку грамматики.

Рассмотрите возможность:

  • Добавления комментария, поясняющего логику отрицания
  • Выделения часто используемых паттернов отрицания в отдельные фрагментные правила с говорящими именами

Аналогичные паттерны встречаются в строках 59 и 99.

♻️ Возможный вариант рефакторинга
+// Любой токен, который не является началом нового блока
+fragment notBlockStart: ~(PARAMETERS_KEYWORD | RETURNS_KEYWORD | EXAMPLE_KEYWORD | DEPRECATE_KEYWORD | EOL | EOF | SPACE);
+
 descriptionString:
       (startPart
-            // гиперссылка или не ключевое (ну и не конец строки)
-            (hyperlink | ~(PARAMETERS_KEYWORD | RETURNS_KEYWORD | EXAMPLE_KEYWORD | DEPRECATE_KEYWORD | EOL | EOF | SPACE))
+            (hyperlink | notBlockStart)
             (hyperlink | ~(EOL | EOF))* // любой
         EOL)
     | (startPart EOL)
     ;

121-121: Рассмотрите более структурированный разбор параметров гиперссылки.

Правило hyperlink использует паттерн linkParams=~EOL* для захвата параметров внутри скобок. Это жадный паттерн, который захватывает все токены как плоскую последовательность, что может затруднить последующую обработку параметров.

Если параметры гиперссылок имеют определённую структуру (например, список идентификаторов через запятую), рассмотрите возможность определения более специфичного правила вместо ~EOL*.

♻️ Пример более структурированного подхода

Если параметры являются списком слов через запятую:

-hyperlink: SEE_KEYWORD SPACE link=(WORD | DOTSWORD) (LPAREN linkParams=~EOL* RPAREN)?;
+hyperlink: SEE_KEYWORD SPACE link=(WORD | DOTSWORD) (LPAREN linkParams RPAREN)?;
+linkParams: (WORD | DOTSWORD) (COMMA SPACE? (WORD | DOTSWORD))*;

Применяйте только если параметры имеют чёткую структуру.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b5361c and cdc520d.

📒 Files selected for processing (16)
  • src/main/antlr/BSLDescriptionLexer.g4
  • src/main/antlr/BSLDescriptionParser.g4
  • src/main/antlr/BSLLexer.g4
  • src/main/antlr/BSLParser.g4
  • src/main/antlr/SDBLLexer.g4
  • src/main/antlr/SDBLParser.g4
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/ReaderUtils.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java
✅ Files skipped from review due to trivial changes (4)
  • src/main/antlr/BSLLexer.g4
  • src/main/antlr/SDBLParser.g4
  • src/main/antlr/SDBLLexer.g4
  • src/main/antlr/BSLParser.g4
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/ReaderUtils.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java
  • src/main/antlr/BSLDescriptionLexer.g4
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-07T08:48:47.243Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-parser PR: 349
File: src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java:53-62
Timestamp: 2026-01-07T08:48:47.243Z
Learning: In SimpleTypeDescription.java, the create() method returns EMPTY when name and description are empty without checking fieldList. This is correct because the parser logic ensures that if name and description are empty, any fields would have already been associated with the previous type's typeDescription during parsing.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
🧬 Code graph analysis (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (34-82)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (35-66)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (35-66)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)
  • Value (36-66)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: QA
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, windows-latest)
🔇 Additional comments (20)
src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java (6)

24-29: Отлично! Импорты соответствуют новым тестам.

Добавленные импорты необходимы для создания токенов ANTLR и списков в новых тестовых методах.


34-51: Отличное покрытие проверки вложенности диапазонов.

Тест корректно проверяет основные сценарии и граничные случаи, включая идентичные диапазоны и случаи, когда меньший диапазон начинается раньше большего.


53-128: Превосходное покрытие фабричных методов SimpleRange.

Тесты тщательно проверяют создание диапазонов из различных источников:

  • Из пары токенов (начальный/конечный)
  • Из одиночного токена
  • Из списка токенов (включая пустой список)
  • Из явных координат

Корректно проверяется преобразование координат и обработка граничных случаев.


130-137: LGTM! Корректная проверка пустого диапазона.

Тест покрывает оба случая: пустой и непустой диапазон.


154-161: LGTM! Базовая проверка конструктора.

Тест корректно проверяет, что все поля диапазона инициализируются переданными значениями.


174-178: Отлично! Проверка строкового представления.

Тест корректно проверяет, что toString() содержит все поля диапазона. Использование contains() делает тест устойчивым к изменениям форматирования.

src/test/java/com/github/_1c_syntax/bsl/parser/description/support/HyperlinkTest.java (1)

30-160: Тесты выглядят хорошо!

Покрытие тестами комплексное и правильно проверяет все основные сценарии работы класса Hyperlink: создание, обработку null/пустых значений, парсинг строк представления и проверку равенства.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java (3)

46-54: Корректная обработка null-значений.

Фабричный метод правильно обрабатывает null-значения и возвращает EMPTY для пустых ссылок. Использование intern() для оптимизации памяти оправдано.


64-75: Парсинг исправлен корректно.

Проверка posEnd < 0 на строке 68 правильно обрабатывает случай отсутствия закрывающей скобки (предыдущая проблема с posEnd == 0 устранена).


77-86: Контракт equals() соблюдён.

Метод equals() теперь корректно сравнивает только экземпляры Hyperlink (предыдущая проблема с нарушением симметрии при сравнении со String устранена). Автогенерируемый record'ом hashCode() будет согласован с equals(), так как оба используют link и params.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)

87-109: Логика извлечения описания корректна.

Методы visitDeprecateBlock и visitDescriptionBlock правильно обрабатывают блоки устаревания и описания, корректно собирая текстовую информацию и метаданные.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (2)

63-89: Парсинг описаний реализован корректно.

Публичный метод read() и вспомогательная логика токенизации правильно обрабатывают комментарии и строят AST для дальнейшего анализа. Использование requireNonNull обеспечивает безопасность.


217-236: Исправление отслеживания уровня вложенности.

На строке 224 теперь корректно используется typeLevel = currentLevel (предыдущая ошибка с ctx.getText().length() устранена), что обеспечивает правильное отслеживание вложенности возвращаемых значений.

src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (2)

34-58: Структура класса соответствует паттерну.

Использование Lombok аннотаций (@value, @AllArgsConstructor, @accessors) обеспечивает immutability и fluent API, что согласуется с другими классами описания типов (SimpleTypeDescription, HyperlinkTypeDescription).


59-76: Фабричный метод корректно создаёт описание коллекции.

Метод create() правильно формирует составное имя типа (например, Array<String>) и применяет стандартизацию строк через strip() и intern(), что обеспечивает согласованность с остальными классами описаний.

src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (4)

36-47: Структура класса корректна.

Использование Lombok-аннотаций (@Value, @AllArgsConstructor, @Accessors) соответствует паттерну, применяемому в родственных классах HyperlinkTypeDescription и CollectionTypeDescription.


49-49: EMPTY константа реализована корректно.

Использование Collections.emptyList() обеспечивает неизменяемость sentinel-значения.


62-65: Реализация метода variant() корректна.

Возврат Variant.SIMPLE соответствует контракту интерфейса TypeDescription.


51-60: > Likely an incorrect or invalid review comment.

src/main/antlr/BSLDescriptionParser.g4 (1)

76-76: Использование STAR для уровней вложенности является корректным.

Правило field использует токен STAR (определён в BSLDescriptionLexer.g4:40 как STAR : '*'+;) для обозначения уровней вложенности полей. Это соответствует реальному формату документации 1C и BSL, где:

  • * обозначает поле верхнего уровня структуры
  • ** обозначает вложенные поля
  • *** и далее используются для более глубокой вложенности

Подтверждено примерами из тестовых ресурсов (Module.bsl, example1.bsl, example5.bsl).

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java:
- Around line 66-77: The create(String presentation) method lacks a null check
and will NPE on presentation.indexOf(...); update Hyperlink.create to
defensively handle a null presentation by checking if presentation == null and
returning Hyperlink.EMPTY (or throwing a clear IllegalArgumentException) instead
of proceeding, and document or annotate the parameter accordingly (e.g., add
@Nullable/@NonNull as appropriate); ensure references to substring, indexOf,
lastIndexOf and the overloaded create(String, String) are preserved when
implementing the guard.
🧹 Nitpick comments (1)
src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java (1)

48-56: Непоследовательность при интернировании строк.

На строке 55 вызывается linkText.intern(), но paramsText не интернируется. Это может быть преднамеренным решением (если значения link повторяются чаще, чем params), однако такое различие не задокументировано и может привести к неоптимальному использованию памяти, если значения параметров также часто повторяются.

Рекомендуется либо интернировать обе строки для единообразия, либо документировать причину различного подхода.

♻️ Вариант с интернированием обеих строк
     if (linkText.isEmpty()) { // если ссылка пустая, то возвращаем пустой объект
       return EMPTY;
     }
-    return new Hyperlink(linkText.intern(), paramsText);
+    return new Hyperlink(linkText.intern(), paramsText.intern());
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cdc520d and c1a6d62.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-01-07T08:48:47.243Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-parser PR: 349
File: src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java:53-62
Timestamp: 2026-01-07T08:48:47.243Z
Learning: In SimpleTypeDescription.java, the create() method returns EMPTY when name and description are empty without checking fieldList. This is correct because the parser logic ensures that if name and description are empty, any fields would have already been associated with the previous type's typeDescription during parsing.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
🧬 Code graph analysis (1)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (35-66)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (34-82)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: QA
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
🔇 Additional comments (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (3)

35-48: Структура класса соответствует паттернам проекта.

Использование @Value с приватным конструктором и статической фабрикой — хорошая практика для иммутабельных объектов. Константа EMPTY с Collections.emptyList() корректно реализует Null Object паттерн.


50-59: Фабричный метод реализован корректно.

Использование isBlank() вместо isEmpty() корректно обрабатывает строки, состоящие только из пробелов. Применение intern() для имени типа — хорошая оптимизация памяти при повторяющихся именах типов.

Проверка fieldList в условии на строке 51 не требуется — логика парсера гарантирует, что при пустых name и description поля будут ассоциированы с предыдущим типом. (На основе полученных learnings.)


61-64: Реализация variant() корректна.

Метод возвращает соответствующий вариант типа, согласованный с интерфейсом TypeDescription.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/Hyperlink.java (1)

79-98: Контракт equals() и hashCode() реализован корректно.

Методы equals(), toString() и hashCode() теперь реализованы в соответствии с требованиями контракта:

  • equals() сравнивает только объекты типа Hyperlink (симметричность соблюдена)
  • hashCode() вычисляется на основе тех же полей, что и equals() (link и params)
  • toString() обеспечивает читаемое представление

Предыдущие замечания из ревью успешно устранены. ✅

@theshadowco
Copy link
Member Author

@coderabbitai
Добавь саммари по реквесту, которое можно будет потом в релизноутс вставить.

@coderabbitai
Copy link

coderabbitai bot commented Jan 7, 2026

Tip

For best results, initiate chat on the files or code changes.

@theshadowco, вот саммари для release notes:


Рефакторинг парсера описаний методов и переменных

Основные изменения

Выполнен масштабный рефакторинг системы парсинга описаний (комментариев) для методов и переменных.

Ключевые улучшения:

  • Типизация параметров: Типы параметров теперь явно разделены на три категории:

    • Простые типы (SimpleTypeDescription) — обычные типы данных
    • Коллекции (CollectionTypeDescription) — типы с вложенными элементами
    • Гиперссылки (HyperlinkTypeDescription) — ссылки на другие методы/модули
  • Улучшенная точность парсинга: Переработана логика чтения параметров, возвращаемых значений и описаний методов для более корректного извлечения информации из комментариев.

  • Поддержка гиперссылок: Добавлена полноценная поддержка гиперссылок в описаниях через новый класс Hyperlink, что позволяет точно идентифицировать ссылки на другие части кода.

  • Упрощение API:

    • Введены статические фабричные методы MethodDescription.create() и VariableDescription.create() для создания описаний
    • Применен паттерн Builder для гибкого конструирования объектов
    • SimpleRange преобразован в record для упрощения работы с диапазонами

Технические изменения:

  • Грамматики ANTLR переименованы: BSLMethodDescriptionLexer/ParserBSLDescriptionLexer/Parser
  • Добавлены новые reader-классы: MethodDescriptionReader, VariableDescriptionReader
  • Использован Lombok для сокращения boilerplate-кода
  • Обновлена иерархия классов для работы с описаниями параметров и типов

Эти изменения обеспечивают более надежный и расширяемый парсинг описаний методов и переменных, что улучшает качество анализа кода и документации.


Copy link

@coderabbitai coderabbitai bot left a comment

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 (1)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)

78-87: Использование "MethodDescription" компонентов для переменных.

Использование BSLMethodDescriptionTokenizer и visitMethodDescription для чтения описания переменных может запутать при сопровождении кода. Если грамматика действительно общая, возможно стоит рассмотреть более универсальное именование (например, BSLDescriptionTokenizer), либо добавить комментарий, поясняющий причину переиспользования.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c1a6d62 and f27280c.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: QA
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, macOS-latest)
🔇 Additional comments (3)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (3)

40-46: Хорошая структура класса.

Приватный конструктор и статические фабричные методы — правильный подход для reader-класса. Инициализация builder-а на уровне поля обеспечивает чистоту кода.


91-113: Корректная реализация visitor-методов.

Обработка блоков deprecation и description реализована правильно:

  • Корректная обработка null для deprecateDescription
  • Использование stream API для сбора строк описания
  • Возврат ctx соответствует паттерну visitor

65-73: Нет проблем — SimpleRange.create(List<Token>) явно обрабатывает пустые списки и возвращает валидный пустой диапазон.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Jan 8, 2026

Quality Gate Failed Quality Gate failed

Failed conditions
C Reliability Rating on New Code (required ≥ A)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In
@src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java:
- Around line 338-351: In MethodDescriptionReader.build() update the logic that
applies firstLineCharShift to the endCharacter: replace the condition using
range.startLine() with range.endLine() so endCharacter is shifted only when its
own line is the first (i.e., use range.endLine() == 0 for the endCharacter
adjustment); apply the same fix in TypeDescription.build() where the identical
endCharacter shift logic appears; keep construction of newRange and the rest of
the ParameterDescription/DescriptionElement creation unchanged.

In
@src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java:
- Line 771: The test assertion uses exampleString.trim() but readers
(MethodDescriptionReader and VariableDescriptionReader) and
MethodDescription.create() normalize descriptions with .strip(); update the
assertion to use exampleString.strip() so the test matches actual behavior, and
scan for other assertions (e.g., the similar one near line 364) that use trim()
and replace them with strip() for consistency.
🧹 Nitpick comments (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)

60-68: Добавьте проверку на null в фабричном методе.

Метод create() может выбросить NullPointerException, если hyperlink (строка 62) или description (строка 63) равны null. Рекомендуется добавить валидацию входных параметров или использовать Objects.requireNonNull().

♻️ Предлагаемая защита от null
+import java.util.Objects;
+
 public static TypeDescription create(Hyperlink hyperlink, DescriptionElement element, String description, List<ParameterDescription> fieldList) {
+  Objects.requireNonNull(hyperlink, "hyperlink must not be null");
+  Objects.requireNonNull(description, "description must not be null");
+  Objects.requireNonNull(element, "element must not be null");
+  Objects.requireNonNull(fieldList, "fieldList must not be null");
+
   return new HyperlinkTypeDescription(
     hyperlink.link(),
     description.strip(),
     fieldList,
     hyperlink,
     element
   );
 }
src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java (1)

44-48: Рассмотрите возможность создания защитной копии списка.

Конструктор оборачивает переданный список в Collections.unmodifiableList(), но не создаёт защитную копию. Если вызывающий код изменит исходный список после создания ParameterDescription, это отразится на содержимом record.

♻️ Предложение по улучшению
  public ParameterDescription(String name, DescriptionElement element, List<TypeDescription> types) {
    this.name = name.strip().intern();
-   this.types = Collections.unmodifiableList(types);
+   this.types = List.copyOf(types);
    this.element = element;
  }
src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java (1)

186-188: Рассмотрите добавление валидации для многострочных диапазонов.

Метод length() корректно работает только для однострочных диапазонов (когда startLine == endLine). Для многострочных диапазонов результат может быть некорректным. Рассмотрите добавление проверки или документирование этого ограничения более явно.

✨ Предлагаемое улучшение с валидацией
  /**
   * Длина области с учетом начальной и конечной позиций. Применимо только для однострочных областей
   *
   * @return Длина линейной области
+  * @throws IllegalStateException если область многострочная
   */
  public int length() {
+   if (startLine != endLine) {
+     throw new IllegalStateException("length() применим только к однострочным диапазонам");
+   }
    return Math.max(0, endCharacter - startCharacter);
  }
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (1)

113-119: Рассмотрите возврат неизменяемого списка.

Метод computeAllElements() возвращает изменяемый ArrayList. Поскольку класс помечен @Value (неизменяемый), рассмотрите возврат Collections.unmodifiableList() или List.copyOf() для обеспечения полной неизменности.

♻️ Предлагаемое улучшение
  private List<DescriptionElement> computeAllElements() {
    List<DescriptionElement> allElements = new ArrayList<>(keywords);
    parameters.forEach(parameter -> allElements.addAll(parameter.allElements()));
    returnedValue.forEach(type -> allElements.addAll(type.allElements()));

-   return allElements;
+   return List.copyOf(allElements);
  }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f27280c and f344361.

📒 Files selected for processing (19)
  • src/main/antlr/BSLDescriptionParser.g4
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SourceDefinedSymbolDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/TypeDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionTokenizer.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElement.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElementTest.java
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java
  • src/test/resources/methodDescription/example1.bsl
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/test/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRangeTest.java
  • src/test/resources/methodDescription/example1.bsl
  • src/test/java/com/github/_1c_syntax/bsl/parser/BSLDescriptionParserCheckSourceTest.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-19T04:17:18.990Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-parser PR: 330
File: src/main/java/com/github/_1c_syntax/bsl/parser/BSLTokenizer.java:30-30
Timestamp: 2025-11-19T04:17:18.990Z
Learning: In BSLTokenizer, SDBLTokenizer, and BSLMethodDescriptionTokenizer constructors in the bsl-parser project, passing an empty CharStream (CharStreams.fromString("")) to the lexer is intentional. This is a lazy initialization pattern where the parent Tokenizer class properly initializes the lexer later on first AST access, rather than at tokenizer creation time.

Applied to files:

  • src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java
  • src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionTokenizer.java
📚 Learning: 2026-01-07T08:48:47.243Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-parser PR: 349
File: src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java:53-62
Timestamp: 2026-01-07T08:48:47.243Z
Learning: In SimpleTypeDescription.java, the create() method returns EMPTY when name and description are empty without checking fieldList. This is correct because the parser logic ensures that if name and description are empty, any fields would have already been associated with the previous type's typeDescription during parsing.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java
🧬 Code graph analysis (5)
src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (1)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (1)
  • VariableDescriptionReader (41-131)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (35-91)
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (1)
  • Value (41-120)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)
  • Value (37-76)
src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (1)
  • Value (39-92)
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (2)
src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (1)
  • MethodDescriptionReader (54-555)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (36-74)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (1)
  • Value (35-91)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (36-74)
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (1)
  • Value (41-120)
src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (1)
  • Value (39-92)
src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (4)
src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (1)
  • Value (36-74)
src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (1)
  • Value (41-120)
src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (1)
  • Value (37-76)
src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (1)
  • Value (39-92)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: QA
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, windows-latest)
🔇 Additional comments (39)
src/test/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElementTest.java (1)

30-42: Тест выглядит хорошо.

Тест корректно проверяет создание и доступ к полям record-класса DescriptionElement. Структура Given-When-Then делает тест понятным.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/DescriptionElement.java (1)

24-40: Использование record для неизменяемых данных — отличное решение.

Класс DescriptionElement корректно реализован как record, что обеспечивает неизменяемость и автоматическую генерацию equals, hashCode и toString. Перечисление Type покрывает все необходимые типы элементов описания.

src/main/antlr/BSLDescriptionParser.g4 (3)

32-36: Поддержка двух вариантов порядка блоков повышает гибкость.

Правило methodDescription разрешает блок deprecateBlock как в начале, так и в конце описания, что обеспечивает совместимость с различными стилями документирования.


114-119: Типовая система охватывает все необходимые варианты.

Правила типов корректно определяют простые типы, коллекции, гиперссылки и списки типов. Поддержка DOTSWORD позволяет использовать квалифицированные имена типов.


25-29: Грамматика правильно объявлена.

Лексер BSLDescriptionLexer.g4 существует и расположен в корректной директории src/main/antlr/. Парсер корректно ссылается на него через tokenVocab = BSLDescriptionLexer. Конфигурация совместима и не требует изменений.

src/main/java/com/github/_1c_syntax/bsl/parser/description/SourceDefinedSymbolDescription.java (3)

80-87: Переименование getSimpleRange()getRange() и добавление getElements() улучшают API.

Упрощение имени метода делает API более лаконичным. Новый метод getElements() предоставляет доступ к значимым элементам описания, что поддерживает детализированный анализ.


96-98: Метод contains() корректно обновлён.

Использование нового метода getRange() вместо getSimpleRange() сохраняет логику проверки вхождения.


69-73: Изменение сигнатуры метода getLink()getLinks() полностью реализовано.

Оба класса-реализации интерфейса (VariableDescription и MethodDescription) содержат поле List<Hyperlink> links, из которого Lombok (@Value аннотация) автоматически генерирует метод getLinks(). Все вызовы обновлены на использование нового метода (исходная сигнатура полностью удалена), и тесты подтверждают корректную работу с поддержкой множественных ссылок.

src/main/java/com/github/_1c_syntax/bsl/parser/description/HyperlinkTypeDescription.java (2)

36-59: Использование Lombok для неизменяемого класса выглядит хорошо.

Аннотации @Value и @AllArgsConstructor(access = AccessLevel.PRIVATE) корректно создают неизменяемый класс с приватным конструктором. Fluent accessors через @Accessors(fluent = true) делают API удобным.


70-73: Реализация variant() корректна.

Метод правильно возвращает Variant.HYPERLINK, идентифицируя этот тип описания как гиперссылку.

src/main/java/com/github/_1c_syntax/bsl/parser/description/ParameterDescription.java (2)

55-67: Реализация методов isHyperlink() и link() корректна.

Логика проверки единственного типа с вариантом HYPERLINK и последующее безопасное приведение типа к HyperlinkTypeDescription выглядит правильно. Метод link() корректно использует isHyperlink() для проверки перед приведением типа.


74-79: Метод allElements() создаёт новый список при каждом вызове.

Это приемлемо для текущего использования, но если метод вызывается часто, можно рассмотреть кэширование результата. Однако для record это усложнит реализацию, поэтому текущий вариант допустим.

src/main/java/com/github/_1c_syntax/bsl/parser/description/SimpleTypeDescription.java (2)

37-58: Хорошо структурированная реализация с шаблоном Singleton для пустых экземпляров.

Класс использует шаблон фабричного метода и синглтон EMPTY для оптимизации памяти. Использование @Value и приватного конструктора обеспечивает неизменяемость объектов.


60-70: Фабричный метод корректно нормализует входные данные.

Логика возврата EMPTY при пустых name и description соответствует требованиям парсера. Согласно полученным learnings, поле fieldList не проверяется намеренно, так как парсер гарантирует, что поля ассоциируются с предыдущим типом.

src/main/java/com/github/_1c_syntax/bsl/parser/description/TypeDescription.java (2)

33-78: Хорошо спроектированный интерфейс с чётким контрактом.

Интерфейс TypeDescription определяет чёткий контракт для описаний типов с поддержкой трёх вариантов. Метод allElements() по умолчанию обеспечивает единообразное агрегирование элементов для всех реализаций.


83-87: Enum Variant обеспечивает типобезопасную дискриминацию.

Использование enum вместо строковых констант — хорошая практика для обеспечения типобезопасности при определении варианта типа.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionTokenizer.java (1)

29-40: Рефакторинг токенизатора выполнен корректно.

Класс переименован и перемещён в пакет reader с package-private видимостью, что обеспечивает лучшую инкапсуляцию. Передача пустого CharStream в конструктор лексера — это преднамеренный паттерн ленивой инициализации, где родительский класс Tokenizer инициализирует лексер при первом обращении к AST. Согласно learnings, это поведение ожидаемо.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/VariableDescriptionReader.java (3)

55-59: Защита от отрицательных смещений реализована корректно.

Использование Math.max(0, ...) для lineShift и firstLineCharShift предотвращает некорректные отрицательные значения при вычислении позиций.


78-86: Цепочка вызовов для trailing комментария может быть упрощена.

Текущая реализация использует trailingComment.map(List::of).map(VariableDescription::create), что создаёт промежуточный список. Это работает корректно, но выглядит немного запутанно.


104-118: Обработка блока устаревания реализована полностью.

Метод корректно устанавливает флаг deprecated, создаёт элемент описания с правильным типом и обрабатывает опциональное описание устаревания.

src/main/java/com/github/_1c_syntax/bsl/parser/description/reader/MethodDescriptionReader.java (3)

68-69: Состояние lastReadParam и typeLevel требует внимания.

Мутабельные поля уровня экземпляра для хранения промежуточного состояния парсинга работают корректно в однопоточном сценарии, но делают класс небезопасным для повторного использования. Учитывая, что экземпляр создаётся заново при каждом вызове read(), это приемлемо.


353-383: Метод addType() с обработкой списка типов реализован корректно.

Логика обработки различных вариантов типов (listTypes, hyperlinkType, simpleType, collectionType) покрывает все случаи грамматики. Первое описание применяется только к первому типу в списке, что соответствует ожидаемому поведению.


524-553: Фабричный метод build() для TempParameterTypeData хорошо структурирован.

Использование switch выражения для создания соответствующего типа описания обеспечивает полноту обработки всех вариантов. Компилятор предупредит, если будет добавлен новый вариант в enum без соответствующей обработки.

src/main/java/com/github/_1c_syntax/bsl/parser/description/CollectionTypeDescription.java (2)

35-65: Структура класса согласована с другими реализациями TypeDescription.

Класс следует тому же паттерну, что и SimpleTypeDescription и HyperlinkTypeDescription: использование @Value, @AllArgsConstructor(access = PRIVATE) и @Accessors(fluent = true). Дополнительные поля collectionName и valueType логично расширяют базовую модель для коллекций.


66-85: Фабричный метод корректно формирует составное имя типа.

Логика построения имени вида CollectionName<ValueType> ясна и соответствует общепринятому синтаксису описания обобщённых типов. Нормализация через strip().intern() согласована с SimpleTypeDescription.

src/main/java/com/github/_1c_syntax/bsl/parser/description/support/SimpleRange.java (3)

28-36: Отличное улучшение документации для record-компонентов.

Javadoc правильно документирует параметры record, что улучшает читаемость API.


76-78: Удобная фабрика для создания диапазона из одного токена.

Делегирование существующему методу create(startToken, endToken) — правильное решение для избежания дублирования.


91-107: Логика работает корректно для предназначения метода.

Метод create(Token token, int lineShift, int firstLineCharShift) предназначен для обработки одного токена и всегда создаёт одностроковый диапазон — это правильное поведение, поскольку токены ANTLR по определению охватывают одну позицию в тексте и не пересекают строки. Параметр firstLineCharShift корректно применяется только для токенов первой строки (когда startLine == 0), как документировано и подтверждено тестами. Если требуется обработка диапазона, охватывающего несколько строк, следует использовать create(Token startToken, Token endToken).

Likely an incorrect or invalid review comment.

src/main/java/com/github/_1c_syntax/bsl/parser/description/VariableDescription.java (4)

39-41: Отличное применение Lombok для неизменяемого значения.

Аннотации @Value и @Builder значительно сокращают boilerplate-код, сохраняя неизменность объекта.


52-53: Правильное использование значений по умолчанию для опциональных полей.

@Builder.Default с пустыми строками и false для опциональных полей обеспечивает согласованное поведение при использовании builder'а.

Also applies to: 58-59, 64-65


70-70: Улучшение: поддержка множественных гиперссылок.

Изменение с единственной ссылки на List<Hyperlink> повышает гибкость API, позволяя описаниям содержать несколько ссылок.


85-91: Чистое разделение ответственности через статические фабрики.

Делегирование парсинга в VariableDescriptionReader отделяет логику создания от логики парсинга, улучшая поддерживаемость кода.

src/main/java/com/github/_1c_syntax/bsl/parser/description/MethodDescription.java (3)

41-43: Корректное применение Lombok для описания метода.

Аннотации @Value и @Builder обеспечивают неизменность и удобное создание экземпляров.


96-107: Хорошее решение: скрытие внутренних элементов и ленивое вычисление.

Аннотация @Getter(AccessLevel.NONE) для keywords скрывает внутреннюю реализацию, а @Getter(lazy = true) для elements обеспечивает эффективное вычисление только при первом обращении.


109-111: Чистый API через статическую фабрику.

Делегирование в MethodDescriptionReader.read() обеспечивает единую точку входа для создания описаний методов.

src/test/java/com/github/_1c_syntax/bsl/parser/description/BSLDescriptionReaderTest.java (4)

109-130: Отличное покрытие новой функциональности элементов описания.

Тесты проверяют:

  • Наличие и количество элементов
  • Типы элементов (PARAMETERS_KEYWORD, RETURNS_KEYWORD, etc.)
  • Корректность диапазонов элементов
  • Вложенность элементов параметров и возвращаемых значений

Это обеспечивает надежную проверку новой модели элементов описания.


142-142: Правильное использование фабрики Hyperlink.

Переход на Hyperlink.create() обеспечивает единообразное создание гиперссылок и проверяет поддержку множественных ссылок в описаниях.

Also applies to: 440-440, 466-466, 482-482


731-736: Обновленная проверка параметров использует новые accessor'ы.

Методы name(), link(), types(), element().range().length() корректно работают с record-based и Lombok-based типами, проверяя согласованность данных.


744-757: Хорошая проверка полиморфизма типов и гиперссылок.

Тест проверяет:

  • Вариант типа через variant()
  • Приведение к HyperlinkTypeDescription для гиперссылок
  • Длину диапазона для коллекций vs простых типов

Это обеспечивает корректность новой типизированной модели.

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