Skip to content

Conversation

@theshadowco
Copy link
Member

Рефакторинг + notnull

 - аннотации NotNull и Nullable пропатчены для валидации при компиляции
 - мелкие фиксы
@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

Анализ pull request

Пояснение

Этот PR содержит обширные изменения для повышения качества кода, включающие преобразование класса Interval в Java record, замену прямого доступа к полям на методы-accessors, добавление аннотаций @NotNull по всей кодовой базе и удаление устаревшего класса SparseEdgeMap.

Пошаговое описание

PR преобразует класс Interval в Java record, заменяет все прямые обращения к полям на методы-accessors (a() и b()), добавляет аннотации @NotNull в сотни мест для явного определения контрактов null-безопасности, удаляет устаревший SparseEdgeMap, добавляет зависимость SpotBugs и выполняет различные рефакторинги кода.

Изменения

Когорта / Файлы Резюме изменений
Dependency Management
build.gradle.kts
Добавлена зависимость com.github.spotbugs:spotbugs-annotations:4.9.8 в блок compileOnly
Interval Record Conversion
src/main/java/org/antlr/v4/runtime/misc/Interval.java
Преобразован класс в Java record с компонентами (int a, int b). Удалены явные поля и конструктор. Обновлены equals() с использованием pattern matching и добавлена аннотация @NotNull на toString()
Interval Accessor Refactoring
src/main/java/org/antlr/v4/automata/ATNOptimizer.java, src/main/java/org/antlr/v4/automata/LexerATNFactory.java, src/main/java/org/antlr/v4/codegen/target/JavaTarget.java, src/main/java/org/antlr/v4/misc/CharSupport.java, src/main/java/org/antlr/v4/parse/ANTLRLexer.g, src/main/java/org/antlr/v4/parse/ANTLRLexer.java, src/main/java/org/antlr/v4/runtime/atn/ATNDeserializer.java, src/main/java/org/antlr/v4/runtime/atn/ATNSerializer.java, src/main/java/org/antlr/v4/runtime/TokenStreamRewriter.java, src/main/java/org/antlr/v4/runtime/misc/IntervalSet.java, src/main/java/org/antlr/v4/runtime/tree/Trees.java
Замены прямого доступа к полям Interval (a, b) на методы-accessors (a(), b()) во всех операциях сравнения, вычислениях индексов и построении переходов
Character Stream Nullability
src/main/java/org/antlr/v4/runtime/ANTLRInputStream.java, src/main/java/org/antlr/v4/runtime/CodePointCharStream.java, src/main/java/org/antlr/v4/runtime/UnbufferedCharStream.java
Добавлены аннотации @NotNull к методам getText() и getSourceName() с обновлением параметров Interval на использование accessor методов
Token Stream Nullability
src/main/java/org/antlr/v4/runtime/ANTLRFileStream.java, src/main/java/org/antlr/v4/runtime/BufferedTokenStream.java, src/main/java/org/antlr/v4/runtime/CommonTokenStream.java, src/main/java/org/antlr/v4/runtime/UnbufferedTokenStream.java
Добавлены аннотации @NotNull к getSourceName(), get(), LT(), getTokenSource() и методам getText() с обновлением сигнатур параметров
Error Strategy & Parser Nullability
src/main/java/org/antlr/v4/runtime/BailErrorStrategy.java, src/main/java/org/antlr/v4/runtime/DefaultErrorStrategy.java, src/main/java/org/antlr/v4/runtime/ConsoleErrorListener.java, src/main/java/org/antlr/v4/runtime/Parser.java, src/main/java/org/antlr/v4/runtime/tree/xpath/XPathLexerErrorListener.java
Добавлены аннотации @NotNull к параметрам методов восстановления от ошибок, обработки ошибок и слушателям парсера для обеспечения контрактов null-безопасности
ATN & Simulator Nullability
src/main/java/org/antlr/v4/runtime/atn/ATN.java, src/main/java/org/antlr/v4/runtime/atn/ParserATNSimulator.java, src/main/java/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java
Добавлены аннотации @NotNull и обновлены проверки null. В ProfilingATNSimulator добавлен параметр contextCache и используется Objects.requireNonNullElseGet для безопасных значений по умолчанию
DFA Edge Map Refactoring
src/main/java/org/antlr/v4/runtime/dfa/AbstractEdgeMap.java, src/main/java/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java, src/main/java/org/antlr/v4/runtime/dfa/EmptyEdgeMap.java, src/main/java/org/antlr/v4/runtime/dfa/HashEdgeMap.java, src/main/java/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java
Добавлены аннотации @NotNull к методам put(), remove(), clear(), toMap() и entrySet(). Обновлено поведение putAll() в ArrayEdgeMap
SparseEdgeMap Removal
src/main/java/org/antlr/v4/runtime/dfa/SparseEdgeMap.java
Полностью удалена файл с устаревшим классом SparseEdgeMap<T>
DFA Documentation
src/main/java/org/antlr/v4/runtime/dfa/DFA.java
Обновлена документация в getMaxDfaEdge() с удалением ссылки на SparseEdgeMap
Nullability Annotations Infrastructure
src/main/java/org/antlr/v4/runtime/misc/NotNull.java, src/main/java/org/antlr/v4/runtime/misc/Nullable.java
Добавлены метаннотации @javax.annotation.Nonnull/@TypeQualifierNickname для усиления null-safety контрактов
Code Generation Nullability
src/main/java/org/antlr/v4/codegen/model/LL1AltBlock.java, src/main/java/org/antlr/v4/codegen/model/LL1OptionalBlockSingleAlt.java, src/main/java/org/antlr/v4/codegen/target/JavaTarget.java
Добавлены аннотации @NotNull. Обновлены вычисления lookahead наборов в LL1OptionalBlockSingleAlt для использования decisionLOOK вместо LinearApproximator
LexerATN Nullability
src/main/java/org/antlr/v4/codegen/model/LexerATNFactory.java
Добавлены аннотации @NotNull к параметрам и возвращаемым значениям всех публичных методов с обновлением доступа к полям Interval
Grammar Parser & Tool Updates
src/main/java/org/antlr/v4/tool/GrammarParserInterpreter.java, src/main/java/org/antlr/v4/tool/ErrorType.java
Добавлена вспомогательная функция getStopTreeAt(), добавлены аннотации @NotNull. Удалена константа перечисления CIRCULAR_DEPENDENCY
Semantic Analysis Refactoring
src/main/java/org/antlr/v4/semantics/AttributeChecks.java, src/main/java/org/antlr/v4/testgen/STGroupModelAdaptor.java
Рефакторинг дублированного кода в вспомогательный метод nonLocalAttributes(). Переименован параметр в STGroupModelAdaptor
GUI & Utility Updates
src/main/java/org/antlr/v4/gui/TreeViewer.java, src/main/java/org/antlr/v4/gui/Trees.java, src/main/java/org/antlr/v4/parse/GrammarASTAdaptor.java
Оптимизирована отрисовка кривых рёбер в TreeViewer. Удалено PrintException из сигнатуры Trees.save(). Обновлены комментарии
Runtime Documentation
src/main/java/org/antlr/v4/runtime/CharStreams.java, src/main/java/org/antlr/v4/runtime/tree/ParseTreeListener.java
Обновлены Javadoc комментарии для замены URL на HTML anchor теги
Import Reordering
src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java, src/main/java/org/antlr/v4/runtime/CommonToken.java
Переупорядочены импорты с перемещением Tuple после Pair
Test Infrastructure Nullability
src/test/java/org/antlr/v4/test/tool/AbstractBaseTest.java, src/test/java/org/antlr/v4/test/tool/JavaUnicodeInputStream.java, src/test/java/org/antlr/v4/test/tool/PerformanceTest.java
Добавлены аннотации @NotNull к методам тестовых классов и слушателям с обновлением параметров Interval и RuleContext

Оценка сложности рецензирования

🎯 4 (Сложный) | ⏱️ ~60 минут

Области, требующие особого внимания:

  • Трансформация Interval в record (src/main/java/org/antlr/v4/runtime/misc/Interval.java): Это критическое изменение API, требующее проверки совместимости всех мест использования и гарантий неизменяемости.
  • Массовое добавление аннотаций @NotNull: Хотя эти изменения в основном повторяющиеся, они влияют на контракты null-безопасности более чем 40 файлов и требуют проверки консистентности.
  • Удаление SparseEdgeMap: Требуется подтверждение отсутствия регрессий в производительности DFA и корректного переключения между ArrayEdgeMap и другими реализациями.
  • Refactoring в ATNOptimizer, IntervalSet и связанных классах: Замена всех доступов к полям на методы-accessors требует тщательной проверки корректности во всех операциях с интервалами.
  • Изменения в ProfilingATNSimulator: Добавление параметра contextCache и изменение обработки null требует подтверждения совместимости с вызывающим кодом.
  • Обновление lookahead в LL1OptionalBlockSingleAlt: Переход с LinearApproximator на decisionLOOK требует проверки корректности вычислений LL(1) наборов.

Возможно связанные PR

  • Обновление из antlr + рефакторинг #19: Этот PR модифицирует многие из тех же классов (LeftRecursiveRuleAnalyzer, ATNDeserializer/ATNSerializer, LexerATNFactory, ParserATNSimulator, TreeViewer, Interval/IntervalSet и связанные runtime классы), указывая на перекрывающиеся изменения на уровне кода.
  • Рефакторинг. Часть 2 #20: Оба PR модифицируют src/main/java/org/antlr/v4/runtime/misc/IntervalSet.java — основной PR рефакторит доступ к Interval для использования accessors, а PR #20 изменяет control flow в IntervalSet.subtract().

Поэма

🐰 Прыг-скок! Интервалы теперь поют,
Accessors методы их берегут,
Record неживой — в памяти живёт,
@NotNull везде — безопасность спешит вперёд,
SparseEdgeMap ушёл в кроличий ход, 🌙✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 2 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.93% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive Заголовок на русском языке использует сокращённые и неинформативные термины, затрудняя понимание основных изменений. Используйте более описательный заголовок на английском языке, например: 'Add @NotNull annotations and refactor Interval field access to use accessor methods' для чёткого определения цели изменений.
Description check ❓ Inconclusive Описание идентично заголовку и использует неинформативные сокращения, не раскрывая суть изменений. Дополните описание конкретными деталями о добавлении @NotNull аннотаций, миграции на методы доступа Interval и удалении SparseEdgeMap для лучшего понимания.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/upd251112

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.

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
76.5% Coverage on New Code (required ≥ 80%)
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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/main/java/org/antlr/v4/codegen/model/LL1AltBlock.java (1)

28-32: Добавьте проверку на null-значения для altLookSets.

После анализа кодовой базы подтверждается, что decisionLOOK.get(decision) может вернуть null. Метод Utils.setSize() заполняет пробелы в списке значениями null, и в AnalysisPipeline.disjoint() явно обрабатываются null-значения, что подтверждает возможность получить null.

Хотя логически LL1AltBlock создаётся только для LL1-решений с непересекающимся lookahead, код не защищает себя от null. Это может привести к NullPointerException на строках 29 и 31 при вызове методов, ожидающих непустой массив.

Рекомендуется добавить проверку:

 IntervalSet[] altLookSets = factory.getGrammar().decisionLOOK.get(decision);
+if (altLookSets == null) {
+  throw new IllegalStateException("No lookahead sets found for decision " + decision);
+}
 altLook = getAltLookaheadAsStringLists(altLookSets);

Аналогичные проверки необходимы в LL1OptionalBlockSingleAlt.java (строка 35), LL1PlusBlockSingleAlt.java (строка 34) и LL1StarBlockSingleAlt.java (строка 29).

src/main/java/org/antlr/v4/runtime/UnbufferedTokenStream.java (1)

296-305: Критично: проверка окна использует tokens.length вместо фактического размера n

bufferStopIndex = bufferStartIndex + tokens.length - 1 допускает выход за заполненную часть буфера и последующий NullPointerException при конкатенации текста.

Предлагаемая правка:

-    int bufferStopIndex = bufferStartIndex + tokens.length - 1;
+    int bufferStopIndex = bufferStartIndex + n - 1;
src/test/java/org/antlr/v4/test/tool/AbstractBaseTest.java (1)

1034-1038: Критическая ошибка: аннотация @NotNull на методе, возвращающем null.

Метод getTokenSource() аннотирован @NotNull (строка 1034), но возвращает null (строка 1037). Это нарушает контракт аннотации и может привести к NullPointerException у вызывающего кода, который полагается на гарантию не-null значения.

Примените это исправление:

-    @NotNull
     @Override
     public TokenSource getTokenSource() {
       return null;
     }

Или, если метод должен возвращать реальный объект, реализуйте соответствующую логику вместо возврата null.

🧹 Nitpick comments (13)
src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java (1)

22-25: Переорганизация импортов для соответствия алфавитному порядку.

Импорт Tuple перемещён после Pair в соответствии с алфавитным порядком в пакете org.antlr.v4.runtime.misc. Оба импорта используются в коде (Pair в поле leftRecursiveRuleRefLabels на строке 59, Tuple в вызовах Tuple.create() на строках 150 и 198). Изменение не влияет на функциональность.

src/main/java/org/antlr/v4/parse/GrammarASTAdaptor.java (2)

22-22: Добавьте аннотации nullability для полей и параметров.

В соответствии с целями PR (рефакторинг + notnull), рекомендуется добавить аннотации @Nullable или @NotNull для поля input и параметров методов. На данный момент поле input может быть null, но это не задокументировано и не защищено.

Предложенное улучшение:

+ import org.jetbrains.annotations.Nullable;
+
  public class GrammarASTAdaptor extends CommonTreeAdaptor {
-   org.antlr.runtime.CharStream input;
+   @Nullable
+   org.antlr.runtime.CharStream input;
  
    public GrammarASTAdaptor() {
    }
  
    public GrammarASTAdaptor(org.antlr.runtime.CharStream input) {
      this.input = input;
    }

Это сделает контракт явным и позволит IDE/анализаторам выявить потенциальные проблемы на строке 55.

Also applies to: 27-29


43-57: Добавьте защиту от null на строке 55.

Вызов t.token.setInputStream(input) предполагает, что t.token всегда ненулевой и что input валиден. Рекомендуется добавить проверку:

  t = (GrammarAST) super.create(tokenType, text);
}
-t.token.setInputStream(input);
+if (t.token != null && input != null) {
+  t.token.setInputStream(input);
+}
return t;

Альтернативно (если input == null — это ошибка): добавьте утверждение или бросьте исключение.

src/main/java/org/antlr/v4/semantics/AttributeChecks.java (1)

227-236: Затенение переменной и отсутствие аннотаций null-safety.

Реализация вспомогательного метода корректна и успешно централизует логику разрешения нелокальных атрибутов. Однако есть два момента:

  1. Затенение переменной: Локальная переменная r на строке 228 затеняет поле класса r (строка 34), что может вызвать путаницу при чтении кода. Рекомендуется переименовать локальную переменную (например, в rule или targetRule).

  2. Отсутствие аннотаций null-safety: Заголовок PR упоминает "notnull", но аннотации типа @NotNull или @Nullable не добавлены. Если это планируется, рассмотрите добавление соответствующих аннотаций для параметров и возвращаемого значения g.getRule().

Предлагаемый рефакторинг для устранения затенения:

- private void nonLocalAttributes(String expr, Token x, Token y) {
-   var r = g.getRule(x.getText());
-   if (r == null) {
+ private void nonLocalAttributes(String expr, Token x, Token y) {
+   var rule = g.getRule(x.getText());
+   if (rule == null) {
     errMgr.grammarError(ErrorType.UNDEFINED_RULE_IN_NONLOCAL_REF,
       g.fileName, x, x.getText(), y.getText(), expr);
-   } else if (r.resolveToAttribute(y.getText(), null) == null) {
+   } else if (rule.resolveToAttribute(y.getText(), null) == null) {
     errMgr.grammarError(ErrorType.UNKNOWN_RULE_ATTRIBUTE,
       g.fileName, y, y.getText(), x.getText(), expr);
   }
 }
src/main/java/org/antlr/v4/tool/GrammarParserInterpreter.java (1)

356-358: Хороший рефакторинг для улучшения читаемости.

Извлечение логики вычисления индекса остановки в отдельный метод getStopTreeAt улучшает организацию кода и читаемость. Логика корректна:

  • Учитывает позицию первой ошибки (firstErrorTokenIndex)
  • Ограничивает результат границами исходного интервала дерева разбора
  • Использование var допустимо и типы ясны из контекста

Опционально: параметр tt можно переименовать в более описательное имя, например parseTree или context, для улучшения читаемости:

-private static int getStopTreeAt(int stopIndex, BailButConsumeErrorStrategy errorHandler, ParserRuleContext tt) {
+private static int getStopTreeAt(int stopIndex, BailButConsumeErrorStrategy errorHandler, ParserRuleContext context) {
   int stopTreeAt = stopIndex;
   if (errorHandler.firstErrorTokenIndex >= 0) {
     stopTreeAt = errorHandler.firstErrorTokenIndex; // cut off rest at first error
   }
-  Interval overallRange = tt.getSourceInterval();
+  Interval overallRange = context.getSourceInterval();
   if (stopTreeAt > overallRange.b()) {
     // If we try to look beyond range of tree, stopTreeAt must be EOF
     // for which there is no EOF ref in grammar. That means tree
     // will not have node for stopTreeAt; limit to overallRange.b
     stopTreeAt = overallRange.b();
   }
   return stopTreeAt;
 }

Also applies to: 370-383

build.gradle.kts (1)

47-47: Добавление spotbugs-annotations выглядит уместно, но проверьте применимость

  • В коде используются собственные org.antlr.v4.runtime.misc.NotNull/Nullable; spotbugs-annotations пригодится только если SpotBugs действительно анализирует проект.
  • Рекомендации:
    • Добавить testCompileOnly("com.github.spotbugs", "spotbugs-annotations", "4.9.8") для тестов.
    • При необходимости подключить/настроить плагин SpotBugs либо Sonar правила на nullability.
src/main/java/org/antlr/v4/runtime/ConsoleErrorListener.java (1)

12-13: Уточните аннотации nullability для всех параметров syntaxError

  • @NotNull для recognizer и msg — ок.
  • Практика ANTLR допускает offendingSymbol и RecognitionException e как потенциально null. Рекомендуется добавить @Nullable для них для явной коммуникации контракта.

Also applies to: 36-41

src/main/java/org/antlr/v4/parse/ANTLRLexer.g (1)

669-675: Переход на Interval.a()/b() — ок; можно унифицировать создание Interval

  • Логика перерасчёта badRange и извлечения lastChar сохранена и корректна с учётом семантики substring(start, stop) в v3.
  • Нит: используйте везде один стиль создания: либо Interval.of(...), либо конструктор, чтобы снизить когнитивную нагрузку.
src/main/java/org/antlr/v4/parse/ANTLRLexer.java (1)

2886-2897: Переход на Interval.a()/b() — поведение сохранено

Замена доступа к полям на аксессоры выглядит корректно и согласована с обновлённым API Interval. Нит: рассмотреть унификацию Interval.of(...) vs new Interval(...) для единообразия.

src/main/java/org/antlr/v4/runtime/UnbufferedCharStream.java (1)

295-316: getText(@NotNull Interval) — переход на аксессоры корректен; мелкая унификация EOF

  • Проверки границ и пересчёт индексов верны, использование interval.length() уместно.
  • Нит: в файле одновременно встречаются сравнения с (char) IntStream.EOF и Character.MAX_VALUE. Для читаемости лучше выбрать один вариант (предпочтительно (char) IntStream.EOF).
src/main/java/org/antlr/v4/runtime/UnbufferedTokenStream.java (1)

93-112: Аннотация @NotNull на LT(int i) может нарушаться при i == -1

LT(-1) возвращает lastToken, который до первого consume()null. Рассмотрите варианты:

  • ослабить контракт до @Nullable для LT (или только для i == -1 в документации),
  • либо гарантировать ненулевое значение lastToken к моменту возможного вызова (менее надёжно).
src/main/java/org/antlr/v4/runtime/BufferedTokenStream.java (1)

226-242: Закомментированный код - рассмотрите удаление.

Строка 230 содержит закомментированный код // if (k == 0) return null;. Если эта логика больше не нужна, лучше полностью удалить комментарий для чистоты кода.

Если код действительно не нужен, примените этот diff:

   @NotNull
   @Override
   public Token LT(int k) {
     lazyInit();
-//    if (k == 0) return null;
     if (k < 0) {
       return LB(-k);
     }
src/main/java/org/antlr/v4/testgen/STGroupModelAdaptor.java (1)

24-28: Добавить @NotNull или явную проверку null для параметра group

Замена Object→STGroup правильна; учитывая стиль проекта (широко используются @NotNull), пометьте параметр group аннотацией @NotNull в getProperty или добавьте раннюю проверку на null и бросьте NullPointerException (файл: src/main/java/org/antlr/v4/testgen/STGroupModelAdaptor.java).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78fc139 and 9cbd3fe.

📒 Files selected for processing (53)
  • build.gradle.kts (1 hunks)
  • src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java (1 hunks)
  • src/main/java/org/antlr/v4/automata/ATNOptimizer.java (3 hunks)
  • src/main/java/org/antlr/v4/automata/LexerATNFactory.java (11 hunks)
  • src/main/java/org/antlr/v4/codegen/model/LL1AltBlock.java (1 hunks)
  • src/main/java/org/antlr/v4/codegen/model/LL1OptionalBlockSingleAlt.java (1 hunks)
  • src/main/java/org/antlr/v4/codegen/target/JavaTarget.java (5 hunks)
  • src/main/java/org/antlr/v4/gui/TreeViewer.java (1 hunks)
  • src/main/java/org/antlr/v4/gui/Trees.java (1 hunks)
  • src/main/java/org/antlr/v4/misc/CharSupport.java (1 hunks)
  • src/main/java/org/antlr/v4/parse/ANTLRLexer.g (1 hunks)
  • src/main/java/org/antlr/v4/parse/ANTLRLexer.java (1 hunks)
  • src/main/java/org/antlr/v4/parse/GrammarASTAdaptor.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/ANTLRFileStream.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/ANTLRInputStream.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/BailErrorStrategy.java (4 hunks)
  • src/main/java/org/antlr/v4/runtime/BufferedTokenStream.java (6 hunks)
  • src/main/java/org/antlr/v4/runtime/CharStreams.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/CodePointCharStream.java (5 hunks)
  • src/main/java/org/antlr/v4/runtime/CommonToken.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/CommonTokenStream.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/ConsoleErrorListener.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/DefaultErrorStrategy.java (7 hunks)
  • src/main/java/org/antlr/v4/runtime/Parser.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/TokenStreamRewriter.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/UnbufferedCharStream.java (3 hunks)
  • src/main/java/org/antlr/v4/runtime/UnbufferedTokenStream.java (5 hunks)
  • src/main/java/org/antlr/v4/runtime/atn/ATN.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/atn/ATNDeserializer.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/atn/ATNSerializer.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/atn/ParserATNSimulator.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java (7 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/AbstractEdgeMap.java (3 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java (5 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/DFA.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/EmptyEdgeMap.java (4 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/HashEdgeMap.java (5 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java (6 hunks)
  • src/main/java/org/antlr/v4/runtime/dfa/SparseEdgeMap.java (0 hunks)
  • src/main/java/org/antlr/v4/runtime/misc/Interval.java (3 hunks)
  • src/main/java/org/antlr/v4/runtime/misc/IntervalSet.java (15 hunks)
  • src/main/java/org/antlr/v4/runtime/misc/NotNull.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/misc/Nullable.java (2 hunks)
  • src/main/java/org/antlr/v4/runtime/tree/ParseTreeListener.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/tree/Trees.java (1 hunks)
  • src/main/java/org/antlr/v4/runtime/tree/xpath/XPathLexerErrorListener.java (1 hunks)
  • src/main/java/org/antlr/v4/semantics/AttributeChecks.java (2 hunks)
  • src/main/java/org/antlr/v4/testgen/STGroupModelAdaptor.java (1 hunks)
  • src/main/java/org/antlr/v4/tool/ErrorType.java (1 hunks)
  • src/main/java/org/antlr/v4/tool/GrammarParserInterpreter.java (5 hunks)
  • src/test/java/org/antlr/v4/test/tool/AbstractBaseTest.java (3 hunks)
  • src/test/java/org/antlr/v4/test/tool/JavaUnicodeInputStream.java (1 hunks)
  • src/test/java/org/antlr/v4/test/tool/PerformanceTest.java (5 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/org/antlr/v4/runtime/dfa/SparseEdgeMap.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-12T13:02:38.990Z
Learnt from: theshadowco
Repo: 1c-syntax/antlr PR: 18
File: src/main/java/org/antlr/v4/tool/Rule.java:15-15
Timestamp: 2025-11-12T13:02:38.990Z
Learning: In repository 1c-syntax/antlr, the migration from Tuple2 to Pair in the codebase is intentional and aligns with the official ANTLR4 API (github.com/antlr/antlr4), which uses org.antlr.v4.runtime.misc.Pair instead of Tuple2. This change supports compatibility with the standard ANTLR4 runtime required for IDEA plugin functionality.

Applied to files:

  • src/main/java/org/antlr/v4/runtime/CommonToken.java
  • src/main/java/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java
  • src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java
📚 Learning: 2025-11-12T13:03:21.934Z
Learnt from: theshadowco
Repo: 1c-syntax/antlr PR: 18
File: src/main/java/org/antlr/v4/runtime/misc/RuleDependencyProcessor.java:83-91
Timestamp: 2025-11-12T13:03:21.934Z
Learning: The repository 1c-syntax/antlr is a fork that diverged from official antlr/antlr4. The Tuple2→Pair migration in PR #18 is intentional alignment with the official ANTLR4 API, which uses Pair instead of Tuple2, to support "more vanilla" ANTLR4 for IDEA plugin compatibility.

Applied to files:

  • src/main/java/org/antlr/v4/runtime/CommonToken.java
  • src/main/java/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java
  • src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java
🧬 Code graph analysis (3)
src/main/java/org/antlr/v4/runtime/CommonToken.java (1)
src/main/java/org/antlr/v4/runtime/misc/Tuple.java (1)
  • Tuple (17-36)
src/main/java/org/antlr/v4/tool/GrammarParserInterpreter.java (1)
src/main/java/org/antlr/v4/runtime/tree/Trees.java (1)
  • Trees (33-278)
src/main/java/org/antlr/v4/analysis/LeftRecursiveRuleAnalyzer.java (1)
src/main/java/org/antlr/v4/runtime/misc/Tuple.java (1)
  • Tuple (17-36)
⏰ 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: QA
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, macOS-latest)
🔇 Additional comments (83)
src/main/java/org/antlr/v4/runtime/tree/ParseTreeListener.java (1)

25-25: Улучшение документации через HTML-тег якоря.

Преобразование простой URL-ссылки в правильный HTML-тег <a> улучшает навигацию в сгенерированной Javadoc документации, обеспечивая удобный клик по ссылке.

src/main/java/org/antlr/v4/parse/GrammarASTAdaptor.java (1)

42-42: Форматирование комментария принято.

Замена Javadoc-стиля на простой однострочный комментарий уместна для этого контекста. ✓

src/main/java/org/antlr/v4/runtime/tree/Trees.java (1)

249-249: Отличное улучшение инкапсуляции!

Переход от прямого доступа к полям (range.a, range.b) к использованию методов-аксессоров (range.a(), range.b()) соответствует лучшим практикам Java и улучшает инкапсуляцию. Функциональность остаётся неизменной.

src/main/java/org/antlr/v4/runtime/CharStreams.java (1)

46-46: Оформление ссылки выглядит корректно. HTML-якорь лаконичен, соответствует стилю остального JavaDoc и не затрагивает логику.

src/main/java/org/antlr/v4/runtime/atn/ParserATNSimulator.java (1)

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

Метод dumpDeadEndConfigs предназначен только для диагностики и выводит информацию в stderr. Изменение на строке 2092 упрощает представление SetTransition, полагаясь на toString() по умолчанию для st.set. Поскольку это затрагивает только отладочный вывод и не влияет на логику работы парсера, изменение имеет минимальный риск и соответствует цели рефакторинга, указанной в PR.

src/main/java/org/antlr/v4/semantics/AttributeChecks.java (2)

172-174: Хорошая практика делегирования.

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


177-179: Корректное делегирование для setter-метода.

Делегирование в nonLocalAttributes правильно проверяет существование правила и атрибута. Параметр rhs не требуется для валидации самой ссылки на нелокальный атрибут.

src/main/java/org/antlr/v4/runtime/misc/IntervalSet.java (8)

123-187: Рефакторинг выглядит корректно.

Замена прямого доступа к полям на вызовы методов-аксессоров a() и b() выполнена правильно. Логика методов add() и addAll() не изменилась.


262-280: Логика вычитания интервалов корректна.

Использование аксессоров в методе subtract() для сравнения границ и создания новых интервалов выполнено правильно. Все операции с границами интервалов (a(), b()) соответствуют исходной логике.


400-401: Бинарный поиск работает корректно.

Использование аксессоров a() и b() в методе contains() для бинарного поиска элемента выполнено правильно.


428-460: Методы получения элементов реализованы корректно.

Использование аксессоров в методах getSingleElement(), getMaxElement() и getMinElement() выполнено правильно и соответствует их назначению.


474-476: Вычисление хеш-кода корректно.

Использование аксессоров a() и b() для вычисления хеш-кода интервалов выполнено правильно.


512-552: Методы форматирования строк работают корректно.

Использование аксессоров a() и b() в методах toString() для форматирования интервалов выполнено правильно. Формат вывода не изменился.


595-639: Методы конвертации и вычисления размера корректны.

Использование аксессоров a() и b() в методах size(), toIntegerList(), toList() и toSet() выполнено правильно. Логика вычисления размера и итерации по элементам интервалов сохранена.


650-677: Метод удаления элемента реализован корректно.

Использование аксессоров a() и b() в методе remove() выполнено правильно во всех ветвях логики:

  • Удаление интервала целиком
  • Корректировка левой границы
  • Корректировка правой границы
  • Разделение интервала на два
src/main/java/org/antlr/v4/automata/LexerATNFactory.java (2)

115-115: Аннотации @NotNull корректно применены!

Добавление аннотаций @NotNull к возвращаемым значениям и параметрам публичных методов улучшает контракт null-безопасности API. Все аннотированные методы действительно всегда возвращают ненулевые значения (объекты Handle или ATN), и параметры используются без проверок на null, что соответствует добавленным аннотациям.

Also applies to: 156-158, 163-165, 183-185, 210-212, 218-220, 250-252, 280-282, 295-297, 370-372, 399-401, 656-658


329-329: Переход на методы-аксессоры одобрен!

Замена прямого доступа к полям interval.a и interval.b на вызовы методов interval.a() и interval.b() улучшает инкапсуляцию и соответствует лучшим практикам ООП.

src/main/java/org/antlr/v4/tool/GrammarParserInterpreter.java (2)

32-32: Импорт необходим для аннотаций @NotNull.

Добавление импорта корректно и необходимо для последующих аннотаций @NotNull.


433-433: Аннотации @NotNull улучшают безопасность типов.

Добавление аннотаций @NotNull для параметров и возвращаемых значений методов recover, recoverInline и sync является правильным решением:

  • Улучшает контракты методов и документацию
  • Обеспечивает статическую проверку на null
  • Согласуется с аналогичными изменениями в родительских классах (как указано в описании PR)

Also applies to: 444-446, 456-456

src/main/java/org/antlr/v4/runtime/atn/ATNSerializer.java (1)

384-402: Рефакторинг корректен и полностью применён.

Подтверждено:

  • Interval — это Java record с автоматически генерируемыми методами-аксессорами a() и b()
  • Все изменения в ATNSerializer.java (строки 392, 393, 399, 402) корректно используют методы вместо прямого доступа к полям
  • Проверка не обнаружила оставшихся прямых обращений к полям в модуле atn
  • Рефакторинг последовательно и полностью применён
src/main/java/org/antlr/v4/codegen/model/LL1OptionalBlockSingleAlt.java (1)

34-36: Now let me examine the actual code in the repository to verify the context:

Комментарий рецензирования некорректен.

Выражаемое в комментарии беспокойство о потенциальном NPE из-за того, что Map.get() вернёт null, не применимо к этому коду. В конвейере генерации кода ANTLR AnalysisPipeline.process() выполняется до CodeGenPipeline, и AnalysisPipeline заполняет g.decisionLOOK для каждого объекта DecisionState в ATN. Для каждого состояния решения выполняется g.decisionLOOK.set(s.decision, look), что гарантирует наличие записей для всех решений перед использованием ParserFactory. Рефакторинг с переходом на получение предвычисленных наборов lookahead является обоснованной оптимизацией производительности.

src/main/java/org/antlr/v4/runtime/CommonTokenStream.java (1)

98-112: Проверка завершена: изменение поведения LT(0) безопасно и не нарушает существующий код

После тщательной проверки кодовой базы установлено:

  1. Метод LT() никогда не вызывается с аргументом 0 — во всей кодовой базе отсутствуют вызовы LT(0). Используются только LT(1), LT(-1), LT(2) и т.д.

  2. Контракт метода @NotNull — оба метода CommonTokenStream.LT() и BufferedTokenStream.LT() помечены аннотацией @NotNull, что явно гарантирует ненулевой возврат. Удаление проверки if (k == 0) return null; ИСПРАВЛЯЕТ нарушение этого контракта, а не создает его.

  3. Изменение согласовано с дизайном — метод LB() (обратный поиск) по-прежнему корректно обрабатывает k == 0 с возвратом null, что различно от поведения LT(). Это намеренное различие.

  4. Отсутствие проверок на null — в кодовой базе нет никаких охранных проверок типа if (LT(...) != null) после вызовов LT, что подтверждает, что код никогда не ожидал null от этого метода.

Вывод: Изменение улучшает корректность кода, приводя реализацию в соответствие с интерфейсным контрактом @NotNull. Для данной кодовой базы это изменение безопасно.

src/main/java/org/antlr/v4/codegen/model/LL1AltBlock.java (1)

27-27: Изменение стиля комментария корректно.

Замена Javadoc-комментария на обычный построчный комментарий соответствует соглашениям Java, так как это внутренний комментарий реализации, а не документация API.

src/main/java/org/antlr/v4/runtime/CommonToken.java (1)

16-16: Импорт Tuple переставлен — функциональных изменений нет

Ок, изменений поведения нет; использование Tuple.create(...) остаётся валидным.

src/main/java/org/antlr/v4/runtime/UnbufferedCharStream.java (1)

285-293: Контракт getSourceName() как @NotNull — ок

Возврат UNKNOWN_SOURCE_NAME при пустом name соответствует контракту и исключает null.

src/main/java/org/antlr/v4/runtime/UnbufferedTokenStream.java (1)

288-292: getSourceName() как @NotNull — ок

Возврат делегируется в tokenSource.getSourceName(), допустимо в рамках усиления контракта.

src/test/java/org/antlr/v4/test/tool/JavaUnicodeInputStream.java (1)

52-62: LGTM! Улучшение контрактов null-безопасности

Добавление аннотаций @NotNull к методам getSourceName() и getText() корректно усиливает контракты null-безопасности публичного API. Изменения соответствуют общей стратегии рефакторинга в PR.

src/main/java/org/antlr/v4/misc/CharSupport.java (1)

193-193: LGTM! Переход на методы-аксессоры

Замена прямого доступа к полям interval.a и interval.b на вызовы методов-аксессоров interval.a() и interval.b() соответствует рефакторингу класса Interval в record. Изменение сохраняет логику без изменений.

src/main/java/org/antlr/v4/runtime/TokenStreamRewriter.java (1)

416-417: LGTM! Использование аксессоров Interval

Обновление для использования методов-аксессоров interval.a() и interval.b() вместо прямого доступа к полям. Изменение соответствует рефакторингу Interval и сохраняет исходную логику.

src/main/java/org/antlr/v4/runtime/dfa/AbstractEdgeMap.java (2)

12-12: LGTM! Добавлен импорт для аннотаций

Импорт NotNull добавлен для поддержки аннотаций null-безопасности.


33-54: LGTM! Усиление контрактов null-безопасности публичного API

Добавление аннотаций @NotNull к методам put(), putAll(), clear() и remove(), а также к параметру m в методе putAll() систематически укрепляет гарантии null-безопасности для публичного API EdgeMap. Изменения не влияют на поведение.

src/main/java/org/antlr/v4/runtime/ANTLRFileStream.java (1)

43-47: LGTM! Контракт null-безопасности для getSourceName()

Добавление @NotNull к методу getSourceName() корректно, поскольку метод всегда возвращает fileName, который инициализируется в конструкторе и не может быть null.

src/main/java/org/antlr/v4/runtime/atn/ATNDeserializer.java (2)

987-987: LGTM! Использование аксессоров в цикле

Обновление для использования interval.a() и interval.b() в условии цикла соответствует рефакторингу Interval в record.


1003-1003: LGTM! Согласованное использование аксессоров

Замена matchInterval.a и matchInterval.b на matchInterval.a() и matchInterval.b() при создании RangeTransition соответствует общему паттерну рефакторинга.

src/main/java/org/antlr/v4/runtime/misc/NotNull.java (2)

12-13: LGTM! Импорты для поддержки JSR-305

Добавление импортов TypeQualifierNickname и When необходимо для интеграции с JSR-305 аннотациями.


52-53: LGTM! Улучшенная интеграция со статическим анализом

Добавление аннотаций @javax.annotation.Nonnull(when = When.ALWAYS) и @TypeQualifierNickname к определению @NotNull обеспечивает лучшую интеграцию с инструментами статического анализа, такими как SpotBugs. Это стандартный паттерн для создания пользовательских аннотаций null-безопасности на основе JSR-305.

src/main/java/org/antlr/v4/runtime/atn/ATN.java (2)

131-131: LGTM! Удаление избыточной проверки на null

Удаление проверки decisionToDFA != null из assertion корректно, поскольку поле decisionToDFA объявлено с аннотацией @NotNull (строка 93) и инициализируется как new DFA[0], что гарантирует его ненулевое значение.


223-223: LGTM! Улучшение форматирования Javadoc

Обновление ссылки в Javadoc с простого текста на HTML-якорь улучшает читаемость документации.

src/main/java/org/antlr/v4/gui/TreeViewer.java (1)

160-167: Рефакторинг выглядит хорошо.

Инлайнинг параметров метода setCurve делает код более компактным без изменения логики. Контрольные точки кубической кривой заданы корректно.

src/main/java/org/antlr/v4/runtime/tree/xpath/XPathLexerErrorListener.java (1)

15-21: Аннотации @NotNull применены корректно.

Добавление аннотаций @NotNull для параметров recognizer и msg соответствует контракту метода - эти параметры не должны быть null при нормальном использовании.

src/main/java/org/antlr/v4/automata/ATNOptimizer.java (1)

95-138: Миграция на методы-аксессоры выполнена корректно.

Изменение с прямого доступа к полям (interval.a, interval.b) на методы-аксессоры (interval.a(), interval.b()) применено последовательно во всех местах использования. Логика кода не изменилась.

src/main/java/org/antlr/v4/runtime/misc/Nullable.java (1)

12-13: Добавление JSR-305 мета-аннотаций улучшает поддержку инструментов статического анализа.

Аннотации @TypeQualifierNickname и @Nonnull(when = When.UNKNOWN) правильно применены к определению аннотации @Nullable, что позволяет инструментам анализа кода (например, SpotBugs, IntelliJ IDEA) лучше понимать контракт допустимости null-значений.

Also applies to: 52-53

src/main/java/org/antlr/v4/gui/Trees.java (1)

66-66: Исправление декларации исключений.

Удаление PrintException из объявления throws корректно - метод вызывает только writePS, который бросает IOException, но не PrintException. Это исправление ошибочной сигнатуры метода.

src/test/java/org/antlr/v4/test/tool/AbstractBaseTest.java (1)

1011-1026: Остальные аннотации @NotNull применены корректно.

Аннотации на методах getSourceName(), LT(), get() и параметрах getText() соответствуют их реализациям и контрактам.

Also applies to: 1040-1062

src/main/java/org/antlr/v4/codegen/target/JavaTarget.java (1)

16-16: Улучшения кода одобрены.

Изменения включают:

  • Использование var для локальной переменной (строка 89) - повышает читаемость
  • Добавление @NotNull к loadTemplates() (строка 199) - корректно, метод всегда возвращает не-null значение
  • Незначительное форматирование

Also applies to: 89-93, 199-199

src/main/java/org/antlr/v4/runtime/DefaultErrorStrategy.java (1)

68-68: Аннотации @NotNull применены корректно ко всем методам стратегии обработки ошибок.

Добавление аннотаций @NotNull к параметрам Parser и RecognitionException, а также к возвращаемому значению метода recoverInline() правильно отражает контракты этих методов:

  • Все методы ожидают не-null экземпляр парсера
  • Исключения не должны быть null
  • recoverInline() либо возвращает токен, либо бросает исключение (никогда null)

Also applies to: 86-86, 108-108, 132-133, 165-165, 225-225, 450-450, 452-452

src/main/java/org/antlr/v4/runtime/ANTLRInputStream.java (3)

13-13: Добавление NotNull для улучшения контрактов API.

Импорт аннотации NotNull соответствует общей стратегии обеспечения null-безопасности в кодовой базе.


214-223: Правильная миграция на record-аксессоры и добавление null-контрактов.

Изменения корректны:

  • Аннотация @NotNull на возвращаемом значении и параметре Interval усиливает контракт метода
  • Использование interval.a() и interval.b() вместо прямого доступа к полям соответствует новой структуре Interval как record
  • Логика метода сохранена без изменений

225-227: Корректная аннотация non-null контракта.

Аннотация @NotNull на getSourceName() правильна, так как метод всегда возвращает непустое значение (либо name, либо UNKNOWN_SOURCE_NAME).

src/main/java/org/antlr/v4/runtime/dfa/SingletonEdgeMap.java (4)

12-13: Добавление NotNull для соблюдения общей стратегии null-безопасности.

Импорт соответствует изменениям в других компонентах DFA.


71-88: Правильная аннотация non-null возвращаемого значения.

Метод put всегда возвращает непустое значение AbstractEdgeMap (либо this, либо новый экземпляр), поэтому аннотация @NotNull корректна.


90-108: Корректные non-null контракты для remove и clear.

Оба метода всегда возвращают непустые значения:

  • remove: EmptyEdgeMap или this
  • clear: EmptyEdgeMap или this

Аннотации @NotNull правильны.


110-124: Правильные non-null контракты для методов преобразования.

Методы toMap() и entrySet() всегда возвращают непустые коллекции (emptyMap/singletonMap и EntrySet соответственно), что делает аннотации @NotNull корректными.

src/main/java/org/antlr/v4/runtime/dfa/ArrayEdgeMap.java (4)

12-13: Добавление NotNull соответствует стратегии null-безопасности.

Импорт согласован с изменениями в других edge map реализациях.


63-82: Корректные non-null контракты для мутирующих операций.

Методы put и remove всегда возвращают this (ArrayEdgeMap), поэтому аннотации @NotNull правильны.


124-154: Правильные non-null контракты для методов доступа.

Все три метода всегда возвращают непустые значения:

  • clear(): новый EmptyEdgeMap
  • toMap(): emptyMap или LinkedHashMap
  • entrySet(): новый EntrySet

Аннотации @NotNull корректны.


84-122: Отзыв основан на неверном предположении

Проверка показала, что класса SparseEdgeMap никогда не существовало в кодовой базе:

  • Поиск по файлам и истории git не дал результатов
  • Термин "Sparse" встречается только в названиях параметров (maxSparseSize)
  • Все реализации EdgeMap в коде: HashEdgeMap, ArrayEdgeMap, SingletonEdgeMap, EmptyEdgeMap — и все они обработаны в методе putAll()

Таким образом, это не breaking change. Метод putAll() корректно обрабатывает все известные типы и выбрасывает UnsupportedOperationException для неизвестных, что является ожидаемым поведением.

Likely an incorrect or invalid review comment.

src/main/java/org/antlr/v4/runtime/dfa/HashEdgeMap.java (3)

119-167: Правильный non-null контракт для метода put.

Метод всегда возвращает непустое значение AbstractEdgeMap (this, новый HashEdgeMap или ArrayEdgeMap), аннотация @NotNull корректна.


169-181: Корректная аннотация для метода remove.

Метод всегда возвращает непустой HashEdgeMap (this или новый экземпляр), аннотация @NotNull правильна.


183-218: Правильные non-null контракты для методов доступа.

Все три метода всегда возвращают непустые значения:

  • clear(): this или EmptyEdgeMap
  • toMap(): emptyMap или TreeMap
  • entrySet(): результат toMap().entrySet()

Аннотации @NotNull корректны.

src/main/java/org/antlr/v4/runtime/BailErrorStrategy.java (4)

12-12: Добавление NotNull для усиления контрактов обработки ошибок.

Импорт поддерживает аннотации параметров в методах обработки ошибок.


51-57: Правильные non-null контракты для параметров recover.

Оба параметра (Parser и RecognitionException) не должны быть null в контексте обработки ошибок, аннотации @NotNull корректны.


63-73: Корректные аннотации для recoverInline.

Аннотации правильны:

  • @NotNull на возвращаемом типе Token соответствует контракту метода (хотя реально всегда выбрасывается исключение)
  • @NotNull на параметре Parser усиливает контракт

79-80: Правильный non-null контракт для параметра sync.

Параметр Parser не должен быть null, аннотация @NotNull корректна.

src/main/java/org/antlr/v4/runtime/misc/Interval.java (3)

14-18: Отличное преобразование в record для улучшения иммутабельности.

Преобразование Interval в record:

  • Обеспечивает иммутабельность через final поля
  • Автоматически генерирует конструктор, аксессоры, equals() и hashCode()
  • Добавлена документация для компонентов record
  • Это breaking change: прямой доступ к полям (interval.a, interval.b) больше не работает, необходимо использовать аксессоры (interval.a(), interval.b())

Изменение хорошо согласовано с обновлениями в других файлах PR, где использование полей заменено на вызовы методов.


53-61: Улучшенная реализация equals с использованием pattern matching.

Обновление equals() использует современный синтаксис pattern matching Java, сохраняя ту же семантику. Record автоматически предоставляет equals(), но эта реализация сохранена для явного контроля или совместимости.


152-155: Корректная non-null аннотация для toString.

Метод toString() всегда возвращает непустую строку, аннотация @NotNull правильна.

src/main/java/org/antlr/v4/runtime/CodePointCharStream.java (5)

13-13: Добавление NotNull для null-безопасности CharStream API.

Импорт поддерживает аннотации в методах доступа к потоку.


129-136: Правильный non-null контракт для getSourceName.

Метод всегда возвращает непустое значение (name или UNKNOWN_SOURCE_NAME), аннотация @NotNull корректна.


162-172: Правильная миграция на record-аксессоры в CodePoint8BitCharStream.

Изменения корректны:

  • @NotNull аннотации на методе и параметре усиливают контракт
  • Использование interval.a() и interval.b() вместо прямого доступа соответствует новой структуре Interval
  • Логика вычисления startIdx и len сохранена

217-230: Правильная миграция на record-аксессоры в CodePoint16BitCharStream.

Изменения идентичны CodePoint8BitCharStream и корректны: добавлены @NotNull аннотации и используются аксессоры interval.a()/interval.b().


275-284: Правильная миграция на record-аксессоры в CodePoint32BitCharStream.

Изменения согласованы с другими CharStream реализациями: @NotNull аннотации и использование interval.a()/interval.b() вместо прямого доступа к полям.

src/main/java/org/antlr/v4/runtime/BufferedTokenStream.java (5)

77-81: Правильный non-null контракт для getTokenSource.

Поле tokenSource является @NotNull, метод всегда возвращает непустое значение, аннотация корректна.


191-198: Корректная non-null аннотация для get.

Метод либо возвращает токен, либо выбрасывает IndexOutOfBoundsException, никогда не возвращает null. Аннотация @NotNull правильна.


459-463: Правильный non-null контракт для getSourceName.

Метод делегирует вызов tokenSource.getSourceName(), который также аннотирован @NotNull, аннотация корректна.


476-490: Правильная миграция на record-аксессоры в getText.

Изменения корректны:

  • @NotNull на параметре Interval усиливает контракт
  • Использование interval.a() и interval.b() вместо прямого доступа соответствует новой структуре Interval
  • Логика метода сохранена

494-496: Корректная non-null аннотация для getText(RuleContext).

Параметр RuleContext не должен быть null, аннотация @NotNull правильна и усиливает контракт API.

src/main/java/org/antlr/v4/runtime/dfa/EmptyEdgeMap.java (1)

12-12: LGTM! Аннотации @NotNull корректно применены.

Все методы класса действительно возвращают ненулевые значения, что делает эти аннотации уместными и полезными для документирования API.

Also applies to: 29-29, 40-40, 46-46, 72-72, 78-78

src/main/java/org/antlr/v4/runtime/Parser.java (1)

47-47: LGTM! Аннотации @NotNull усиливают контракты слушателей.

Аннотации корректно применены к параметрам методов TraceListener и TrimToSizeListener, документируя гарантии, предоставляемые парсером при вызове этих методов.

Also applies to: 53-53, 59-59, 63-63, 75-75, 79-79, 83-83, 87-87

src/main/java/org/antlr/v4/runtime/atn/ProfilingATNSimulator.java (3)

21-21: LGTM! Аннотации @NotNull последовательно применены к API.

Добавление аннотаций улучшает null-safety контракты без изменения поведения. Импорт java.util.Objects подготавливает почву для более чистой обработки null-значений.

Also applies to: 108-108, 114-114, 137-137, 168-171, 188-188, 202-202, 212-212


213-216: Отличный рефакторинг! Использование Objects.requireNonNullElseGet улучшает читаемость.

Замена условного оператора на Objects.requireNonNullElseGet делает код более идиоматичным и выразительным, сохраняя при этом функциональную эквивалентность.


223-223: LGTM! Упрощение обработки благодаря @NotNull.

Прямой вызов ambigAlts.nextSetBit(0) теперь безопасен, так как параметр ambigAlts аннотирован @NotNull на строке 222.

src/test/java/org/antlr/v4/test/tool/PerformanceTest.java (1)

1593-1593: LGTM! Тестовый код корректно отражает изменения в основном коде.

Аннотации @NotNull в тестовых классах StatisticsParserATNSimulator, DescriptiveErrorListener, DescriptiveLexerErrorListener и ChecksumParseTreeListener согласуются с контрактами родительских классов и интерфейсов, обеспечивая единообразие null-safety по всей кодовой базе.

Also applies to: 1607-1610, 1635-1635, 1654-1654, 1962-1962, 1968-1968, 1974-1974, 1981-1981

Comment on lines +94 to 96
@NotNull
@Override
public Token LT(int k) {
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Критическая ошибка: некорректная аннотация @NotNull.

Метод LT(int k) аннотирован @NotNull, но может вернуть null при отрицательных значениях k. На строке 100 метод вызывает LB(-k), который явно возвращает null в двух случаях (строки 80 и 90 в методе LB). Это нарушает контракт @NotNull и может привести к NullPointerException в вызывающем коде, который полагается на гарантию ненулевого значения.

Примените этот diff для исправления:

Вариант 1: Удалить @NotNull и сохранить существующее поведение

-  @NotNull
   @Override
   public Token LT(int k) {

Вариант 2: Гарантировать ненулевое возвращаемое значение

   @NotNull
   @Override
   public Token LT(int k) {
     lazyInit();
     if (k < 0) {
-      return LB(-k);
+      Token token = LB(-k);
+      if (token == null) {
+        throw new IllegalArgumentException("Cannot look back " + (-k) + " tokens");
+      }
+      return token;
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@NotNull
@Override
public Token LT(int k) {
@Override
public Token LT(int k) {
🤖 Prompt for AI Agents
In src/main/java/org/antlr/v4/runtime/CommonTokenStream.java around lines 94 to
96, the LT(int k) method is annotated @NotNull but can return null for negative
k because it delegates to LB(-k) which returns null in some branches; fix by
either removing the @NotNull annotation if you want to preserve current nullable
behavior, or ensure a non-null return by validating k and returning a non-null
Token (e.g., throw an IllegalArgumentException for invalid k or return a
sentinel/EOF token) and update LB to never return null for those cases; pick one
approach and apply consistently to LT and LB and update Javadoc and callers
accordingly.

lazyInit();
if (k == 0) return null;
if (k < 0) return LB(-k);
// if (k == 0) return null;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Удалите закомментированный код.

Закомментированный код следует полностью удалить, а не оставлять в виде комментария. Это улучшит читаемость и поддерживаемость кода.

Примените этот diff:

   lazyInit();
-//    if (k == 0) return null;
   if (k < 0) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// if (k == 0) return null;
lazyInit();
if (k < 0) {
🤖 Prompt for AI Agents
In src/main/java/org/antlr/v4/runtime/CommonTokenStream.java around line 98,
there is a commented-out line "//    if (k == 0) return null;"; remove this
commented code entirely from the file to improve readability and
maintainability, ensuring no leftover commented logic remains.

Comment on lines 199 to 203
* implementations of {@link EdgeMap} use this range to determine the best
* memory savings will be obtained from sparse storage (e.g.
* {@link SingletonEdgeMap} or {@link SparseEdgeMap}) or dense storage
* {@link SingletonEdgeMap} or dense storage
* ({@link ArrayEdgeMap}). Symbols values outside the range are supported
* during prediction, but since DFA edges are never created for these
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Исправьте незакрытую скобку в описании.

Сейчас фраза заканчивается на {@link SingletonEdgeMap} or dense storage, что оставляет первую скобку незакрытой и ломает формат JavaDoc (ссылка превращается в текст). Добавьте закрывающую ) после ссылки.

- * memory savings will be obtained from sparse storage (e.g.
- * {@link SingletonEdgeMap} or dense storage
+ * memory savings will be obtained from sparse storage (e.g.
+ * {@link SingletonEdgeMap}) or dense storage
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
* implementations of {@link EdgeMap} use this range to determine the best
* memory savings will be obtained from sparse storage (e.g.
* {@link SingletonEdgeMap} or {@link SparseEdgeMap}) or dense storage
* {@link SingletonEdgeMap} or dense storage
* ({@link ArrayEdgeMap}). Symbols values outside the range are supported
* during prediction, but since DFA edges are never created for these
* implementations of {@link EdgeMap} use this range to determine the best
* memory savings will be obtained from sparse storage (e.g.
* {@link SingletonEdgeMap}) or dense storage
* ({@link ArrayEdgeMap}). Symbols values outside the range are supported
* during prediction, but since DFA edges are never created for these
🤖 Prompt for AI Agents
In src/main/java/org/antlr/v4/runtime/dfa/DFA.java around lines 199-203 there is
an unclosed parenthesis in the JavaDoc where the text reads "({@link
SingletonEdgeMap} or dense storage ({@link ArrayEdgeMap})" — close the first
parenthesis around the {@link SingletonEdgeMap} reference by adding a ')'
immediately after that link so the phrase becomes "({@link SingletonEdgeMap}) or
dense storage ({@link ArrayEdgeMap})", restoring valid JavaDoc link syntax.

Comment on lines +1233 to 1235
// t1.g4 -> t2.g4 -> t3.g4 ->t1.g4
//CIRCULAR_DEPENDENCY(200, "your grammars contain a circular dependency and cannot be sorted into a valid build order", ErrorSeverity.ERROR),
;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Удаление CIRCULAR_DEPENDENCY ломает совместимость API

  • Константа перечисления публичная; её удаление может сломать сторонний код (source/binary).
  • Если она более не используется, целесообразно:
    • Либо оставить константу с @Deprecated и комментарием, пометив как неиспользуемую,
    • Либо явно зафиксировать это изменение в release notes и провести замену во всех внутренних вызовах до мержа.

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


🏁 Script executed:

#!/bin/bash
rg -n --hidden -S "CIRCULAR_DEPENDENCY" -g '!**/build/**' -g '!**/.gradle/**'

Length of output: 195


Требуется дополнительная проверка. Нужно убедиться:

  1. Использует ли кто-либо код ошибки 200 (связанный с CIRCULAR_DEPENDENCY)
  2. Есть ли ссылки в тестах
  3. Действительно ли ErrorType является публичным API

---

🏁 Script executed:

```shell
#!/bin/bash
# Поиск использования кода ошибки 200
echo "=== Поиск кода ошибки 200 ==="
rg -n "200" src/main/java/org/antlr/v4/tool/ErrorType.java -C 2 | head -20

# Поиск в тестах
echo -e "\n=== Поиск CIRCULAR в тестах ==="
rg -n "CIRCULAR" --type java -g '**/test/**' 2>/dev/null | head -10

# Проверка модификаторов класса ErrorType
echo -e "\n=== Модификаторы класса ErrorType ==="
rg -n "public.*class ErrorType" src/main/java/org/antlr/v4/tool/ErrorType.java

Length of output: 636


Обнаружен критический момент: код ошибки 200 переиспользуется. Требуется проверить публичный статус класса и полный анализ использования.


---

🏁 Script executed:

```shell
#!/bin/bash
# Проверка класса ErrorType (без ограничений по паттерну)
echo "=== ErrorType класс (первые 20 строк) ==="
head -30 src/main/java/org/antlr/v4/tool/ErrorType.java | grep -E "(class|public|private)"

# Полный поиск на ErrorType.CIRCULAR_DEPENDENCY
echo -e "\n=== Использование ErrorType.CIRCULAR_DEPENDENCY ==="
rg "ErrorType\.CIRCULAR_DEPENDENCY|CIRCULAR_DEPENDENCY\s*\(" -n 2>/dev/null

# Поиск импортов ErrorType
echo -e "\n=== Импорты ErrorType ==="
rg "import.*ErrorType" -n | head -10

Length of output: 1397


Подтверждено: удаление CIRCULAR_DEPENDENCY нарушает публичное API

ErrorType — это public enum, и закомментированная константа представляет собой breaking change для сторонних потребителей API. В текущем коде репозитория нет активных ссылок, однако:

  • Класс импортируется в 9+ файлах (основной код и тесты)
  • Код ошибки 200 переиспользуется на другую константу (V3_TREE_GRAMMAR), что усугубляет проблему совместимости
  • Вместо удаления требуется либо оставить константу с аннотацией @Deprecated, либо явно отметить это как breaking change в release notes

Рекомендуется заменить удаление на:

@Deprecated(forRemoval = true, since = "X.Y.Z")
CIRCULAR_DEPENDENCY(200, "...", ErrorSeverity.ERROR),
🤖 Prompt for AI Agents
In src/main/java/org/antlr/v4/tool/ErrorType.java around lines 1233-1235 the
CIRCULAR_DEPENDENCY constant was removed which is a public-API breaking change;
restore the enum constant instead of deleting it and mark it deprecated by
annotating it with @Deprecated(forRemoval = true, since = "X.Y.Z") and keep its
original numeric code, message and ErrorSeverity; if you intend to change the
numeric code that conflicts with V3_TREE_GRAMMAR, resolve the duplicate by
preserving the original code for CIRCULAR_DEPENDENCY or migrating callers and
document the breaking change in release notes if you truly intend removal.

@theshadowco theshadowco marked this pull request as draft November 13, 2025 08:46
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