Skip to content

Conversation

@theshadowco
Copy link
Member

@theshadowco theshadowco commented Dec 12, 2025

Описание

Исправление замечаний к коду

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

Closes

Чеклист

Общие

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

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

  • Описание диагностики заполнено для обоих языков (присутствуют файлы для обоих языков, для русского заполнено все подробно, перевод на английский можно опустить)

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

Summary by CodeRabbit

  • Bug Fixes & Improvements

    • Improved null-safety and defensive checks across components to reduce crashes and improve stability.
    • Centralized shutdown timeout constant for consistent service behavior.
  • UI / Editor Experience

    • Enhanced semantic token and preprocessor classification for more accurate syntax highlighting.
  • Maintenance

    • Code cleanups: constants extraction, local-type inference, minor signature adjustments, and removed unused imports.
  • Tests

    • Added and refined unit tests and assertions for better coverage and reliability.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 12, 2025

Warning

Rate limit exceeded

@nixel2007 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 24 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 4be9da8 and b7d5df3.

📒 Files selected for processing (1)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java (4 hunks)

Walkthrough

Adds nullability annotations and runtime null-safety checks, refactors some helpers/constants and local typing, reorganizes semantic token emission into helper methods, and updates tests to use fluent AssertJ and adds new unit tests.

Changes

Cohort / File(s) Summary
Nullability & suppression
src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
Added @SuppressWarnings("NullAway.Init") to self field (no behavioral change).
Diagnostics nullability
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java
Marked diagnosticRange @Nullable and added runtime null-check in addDiagnostic.
Reference index nullability
src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java
Marked currentScope as @Nullable.
Multilingual & tree utils
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java
Made context/parameter nullable; getMultilingualString accepts @Nullable and returns "" when null; getAncestorByRuleIndex accepts @Nullable and returns null early for null input.
Expression tree visitor
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java
buildExpressionTree and makeSubexpression now return @Nullable BslExpression; added null checks, error-node pushes, and selective Objects.requireNonNull usages.
Semantic tokens refactor
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java
Extracted helpers (addRegionsNamespaces, addDirectives, addOtherPreprocs, selectAndAddSemanticToken), added SPEC_LITERALS, consolidated lexical dispatch, and avoided duplicate annotation tokens.
Config/constants & static helpers
src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java, src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
Added AWAIT_CLOSE, heap/disk constants, and made several cache factory methods static.
Local var / minor refactors
src/main/java/.../diagnostics/TypoDiagnostic.java, .../hover/*SymbolMarkupContentBuilder.java, .../diagnostics/UselessTernaryOperatorDiagnostic.java
Replaced many local types with var; introduced named constants for ternary indexes; no logic changes.
Misc small edits
src/main/java/.../aop/EventPublisherAspect.java, src/main/java/.../context/DocumentChangeExecutor.java
Removed unused import; explicitly typed lambda parameters (no behavior change).
Tests: assertions & additions
src/test/java/.../infrastructure/CachePathProviderTest.java, .../references/ReferenceIndexFillerTest.java, .../utils/ModuleReferenceTest.java, .../utils/TreesTest.java, src/test/java/.../hover/Annotation*.java
Switched tests to fluent AssertJ chaining (hasToString(), isEmpty()), added TreesTest and new hover builder tests, and applied formatting tweaks.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • ExpressionTreeBuildingVisitor: nullability changes, error-node pushes, and altered return contracts.
    • SemanticTokensProvider: token classification/order and duplicate suppression logic in new helpers.
    • Trees.getAncestorByRuleIndex and other utilities: nullable input/return impacts on callers.
    • ReferenceIndexFiller.currentScope nullability and downstream usage.
    • New unit tests validating token extraction and hover builders.

Possibly related PRs

Suggested labels

hacktoberfest-accepted

Poem

🐇 I nibbled nulls and stitched each seam,

Rearranged tokens, constants, and dream.
Tiny hops of refactor, tidy and bright,
Tests now chatter, diagnostics light. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.42% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title is in Russian and uses vague generic terms ('Исправление замечаний к коду' = 'Code review fixes', 'Продолжение' = 'Continuation', 'Часть 2' = 'Part 2') that do not convey meaningful information about the specific changes made. Use a more descriptive title in English that clearly indicates the main changes (e.g., 'Add null-safety annotations and refactor semantic token handling' or similar) instead of generic continuation/part numbering.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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
Contributor

@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

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/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java (1)

60-124: Replace assert with an always-on precondition (asserts may be disabled).
assert diagnosticRange != null; (Line 122) won’t protect prod runs without -ea, and can still lead to NPE in diagnosticStorage.addDiagnostic(...).

@@
   protected void addDiagnostic(String message) {
-    assert diagnosticRange != null;
-    diagnosticStorage.addDiagnostic(diagnosticRange, message);
+    var range = java.util.Objects.requireNonNull(
+      diagnosticRange,
+      "diagnosticRange must be computed before addDiagnostic()"
+    );
+    diagnosticStorage.addDiagnostic(range, message);
   }
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java (2)

194-214: Fix likely NPE: new ErrorExpressionNode(expression) when expression == null.
Line 198-200 allows expression to be null and then passes it into ErrorExpressionNode.

@@
-      if (token == BSLLexer.LPAREN) {
-        visitParenthesis(ctx.expression(), ctx.modifier());
+      if (token == BSLLexer.LPAREN) {
+        visitParenthesis(ctx.expression(), ctx.modifier(), ctx);
       } else {
         operands.push(new ErrorExpressionNode(dispatchChild));
       }
@@
-  private void visitParenthesis(BSLParser.@Nullable ExpressionContext expression,
-                                List<? extends BSLParser.ModifierContext> modifiers) {
+  private void visitParenthesis(BSLParser.@Nullable ExpressionContext expression,
+                                List<? extends BSLParser.ModifierContext> modifiers,
+                                ParseTree representingAst) {
@@
-    if (expression == null || expression.getTokens().isEmpty()) {
-      operands.push(new ErrorExpressionNode(expression));
+    if (expression == null || expression.getTokens().isEmpty()) {
+      operands.push(new ErrorExpressionNode(representingAst));
       return;
     }

399-407: Replace assert and Objects.requireNonNull() with explicit null checks that push error recovery nodes.

makeSubexpression() returns @Nullable BslExpression, but the current code treats null returns unsafely:

  • assert expressionArg != null; (line 403) is a no-op without -ea flag and silently ignores parse errors in production.
  • Objects.requireNonNull(...) (lines 423-425) crashes the parser with NPE on recoverable parse issues instead of graceful error handling.

The codebase already establishes the recovery pattern elsewhere: check for null and push new ErrorExpressionNode(ctx) to the operands stack. Apply this consistently to both methods:

   public ParseTree visitAccessIndex(BSLParser.AccessIndexContext ctx) {
     var target = operands.pop();
     var expressionArg = makeSubexpression(ctx.expression());
-    assert expressionArg != null;
+    if (expressionArg == null) {
+      operands.push(new ErrorExpressionNode(ctx));
+      return ctx;
+    }
     var indexOperation = BinaryOperationNode.create(BslOperator.INDEX_ACCESS, target, expressionArg, ctx);
     operands.push(indexOperation);
     return ctx;
   }

   public ParseTree visitTernaryOperator(BSLParser.TernaryOperatorContext ctx) {
-    var ternary = TernaryOperatorNode.create(
-      Objects.requireNonNull(makeSubexpression(ctx.expression(0))),
-      Objects.requireNonNull(makeSubexpression(ctx.expression(1))),
-      Objects.requireNonNull(makeSubexpression(ctx.expression(2)))
-    );
-
-    ternary.setRepresentingAst(ctx);
-    operands.push(ternary);
-
-    return ctx;
+    var e0 = makeSubexpression(ctx.expression(0));
+    var e1 = makeSubexpression(ctx.expression(1));
+    var e2 = makeSubexpression(ctx.expression(2));
+    if (e0 == null || e1 == null || e2 == null) {
+      operands.push(new ErrorExpressionNode(ctx));
+      return ctx;
+    }
+    var ternary = TernaryOperatorNode.create(e0, e1, e2);
+    ternary.setRepresentingAst(ctx);
+    operands.push(ternary);
+    return ctx;
   }
🧹 Nitpick comments (2)
src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java (1)

318-548: Guard currentScope with fallback to module scope in findVariableSymbol().

The currentScope field is @Nullable and uninitialized until visitSub() runs. Since module-level visitors like visitModuleVarDeclaration() may execute before visitSub(), findVariableSymbol() can pass null to getVariableSymbol(variableName, currentScope). While SymbolTree.getVariableSymbol() handles null keys defensively via Map.getOrDefault(), this is implicit and fragile. Use Objects.requireNonNullElse() to normalize null scope to module scope, making the intent explicit.

@@
     private Optional<VariableSymbol> findVariableSymbol(String variableName) {
-      var variableSymbol = documentContext.getSymbolTree()
-        .getVariableSymbol(variableName, currentScope);
+      var symbolTree = documentContext.getSymbolTree();
+      var scope = java.util.Objects.requireNonNullElse(currentScope, symbolTree.getModule());
+      var variableSymbol = symbolTree.getVariableSymbol(variableName, scope);
 
       if (variableSymbol.isPresent()) {
         return variableSymbol;
       }
 
-      return documentContext.getSymbolTree()
-        .getVariableSymbol(variableName, documentContext.getSymbolTree().getModule());
+      return symbolTree.getVariableSymbol(variableName, symbolTree.getModule());
     }
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java (1)

156-162: Consider simplifying by removing the else block.

The null check correctly provides null safety. However, the else block is unnecessary since the if block returns early.

Apply this diff to simplify the code:

 private static String getMultilingualString(BSLParser.@Nullable GlobalMethodCallContext globalMethodCallContext) {
   if (globalMethodCallContext == null) {
     return "";
-  } else {
-    return globalMethodCallContext.doCall().callParamList().callParam(0).getText();
   }
+  return globalMethodCallContext.doCall().callParamList().callParam(0).getText();
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f11c721 and 9b14da4.

📒 Files selected for processing (6)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java (3 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java (3 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java (6 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java
**/diagnostics/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Each diagnostic should have a Java implementation class, resource bundle for localized messages, unit tests, and documentation

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java
🧠 Learnings (6)
📚 Learning: 2025-01-19T21:44:32.675Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunAllTestsCodeLensSupplier.java:47-47
Timestamp: 2025-01-19T21:44:32.675Z
Learning: В классах-наследниках AbstractRunTestsCodeLensSupplier метод getSelf() должен возвращать this вместо использования Spring-based self-reference, чтобы избежать проблем с циклическими зависимостями и timing issues при тестировании.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
📚 Learning: 2025-01-19T21:45:52.703Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunAllTestsCodeLensSupplier.java:47-47
Timestamp: 2025-01-19T21:45:52.703Z
Learning: В классах-наследниках AbstractRunTestsCodeLensSupplier метод getCodeLenses должен проверять isApplicable перед выполнением своей логики, чтобы учитывать поддержку клиента и другие условия применимости линз.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
📚 Learning: 2025-01-19T21:47:05.209Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunAllTestsCodeLensSupplier.java:47-47
Timestamp: 2025-01-19T21:47:05.209Z
Learning: В классе AbstractRunTestsCodeLensSupplier проверка поддержки клиента должна выполняться до вызова getTestIds, чтобы предотвратить выполнение лишних операций и обеспечить корректное поведение при неподдерживаемом клиенте.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
📚 Learning: 2025-02-10T17:13:41.452Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-language-server PR: 3408
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ProtectedModuleDiagnostic.java:54-58
Timestamp: 2025-02-10T17:13:41.452Z
Learning: In ProtectedModuleDiagnostic.java, the usage of `Range` field as a diagnostic target is accepted as is, despite being marked as a temporary solution in the comments.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java
📚 Learning: 2025-04-18T22:46:43.245Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3449
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java:192-203
Timestamp: 2025-04-18T22:46:43.245Z
Learning: В проекте bsl-language-server класс BSLParser.ExpressionContext наследуется от BSLParserRuleContext, а не напрямую от ParserRuleContext. При работе с ним нужно учитывать специфичные методы BSLParserRuleContext.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java
📚 Learning: 2025-02-10T17:12:56.150Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3408
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ProtectedModuleDiagnostic.java:63-66
Timestamp: 2025-02-10T17:12:56.150Z
Learning: In BSL Language Server, `documentContext.getServerContext().getConfiguration()` is guaranteed to return a non-null value, making null checks unnecessary.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java
🧬 Code graph analysis (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/SkippedCallArgumentNode.java (1)
  • SkippedCallArgumentNode (29-34)
⏰ 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). (19)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (25, ubuntu-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build
  • GitHub Check: Analyse
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (25, ubuntu-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (21, windows-latest)
🔇 Additional comments (4)
src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java (1)

130-136: Null-safe getAncestorByRuleIndex looks good.
Returning null when element is null is a sensible contract and reduces accidental NPEs.

src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java (1)

62-97: The self-injection pattern with @Autowired @Lazy is necessary and correct. The base class AbstractRunTestsCodeLensSupplier uses getSelf() to call the proxied getTestSources() method decorated with @Cacheable, which requires Spring AOP proxy-based invocation. The @SuppressWarnings("NullAway.Init") suppression appropriately handles the initialization-order analysis warning for this pattern. The framework's CodeLensProvider calls isApplicable() before invoking getCodeLenses() (line 81 filters suppliers), so no additional applicability check is needed within getCodeLenses() itself. The current implementation is correct.

src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java (2)

66-66: Good addition of @nullable annotation for static analysis.

The annotation correctly indicates that this field may be null, improving type safety documentation.


215-215: Good defensive assertion before accessing the field.

The assertion appropriately guards against potential null access if isParentTemplate() is called before parse() completes successfully. This provides runtime safety given the class's stateful API design.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 12, 2025

Test Results

2 400 files   - 273  2 400 suites   - 273   34m 59s ⏱️ - 17m 43s
1 011 tests + 10  1 011 ✅ + 10  0 💤 ±0  0 ❌ ±0 
8 088 runs   - 921  8 088 ✅  - 921  0 💤 ±0  0 ❌ ±0 

Results for commit b7d5df3. ± Comparison against base commit 3349563.

♻️ This comment has been updated with latest results.

@theshadowco theshadowco force-pushed the feature/sqfixes251212 branch from 8efb955 to 2c2eb6e Compare December 12, 2025 09:18
Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (1)

193-204: Guard against getCache(...) returning null.
If the cache wasn’t created/registered as expected, nativeCache can be null and you’ll fail later (possibly with a less clear error). Consider Objects.requireNonNull with a clear message.

   public CacheManager typoCacheManager(org.ehcache.CacheManager ehcacheManager) {
-    var nativeCache = ehcacheManager.getCache(TYPO_CACHE_NAME, String.class, WordStatus.class);
+    var nativeCache = java.util.Objects.requireNonNull(
+      ehcacheManager.getCache(TYPO_CACHE_NAME, String.class, WordStatus.class),
+      "Ehcache cache '" + TYPO_CACHE_NAME + "' was not created"
+    );
🧹 Nitpick comments (6)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (1)

130-146: var for delimiter is OK, but consider keeping final char delimiter = ',' for intent.
Purely a readability nit: var infers char here; explicit final can make the delimiter role more obvious.

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1)

54-81: Nice improvement: extracted expression count/index constants; also replace remaining exp.get(0) usages.
Right now the diagnostic payload still uses exp.get(0) (Line 72, Line 75); switching to INDEX_CONDITION keeps the refactor consistent.

-        diagnosticStorage.addDiagnostic(ctx, DiagnosticStorage.createAdditionalData(exp.get(0).getText()));
+        diagnosticStorage.addDiagnostic(ctx, DiagnosticStorage.createAdditionalData(exp.get(INDEX_CONDITION).getText()));
       } else if (trueBranch == BSLParser.FALSE && falseBranch == BSLParser.TRUE) {
         diagnosticStorage.addDiagnostic(ctx,
-          DiagnosticStorage.createAdditionalData(getAdaptedText(exp.get(0).getText())));
+          DiagnosticStorage.createAdditionalData(getAdaptedText(exp.get(INDEX_CONDITION).getText())));
       } else if (trueBranch != SKIPPED_RULE_INDEX || falseBranch != SKIPPED_RULE_INDEX) {
src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java (1)

89-95: Avoid mixing String and var in the same method unless the style guide explicitly allows it.
This is functionally safe, but the method currently uses explicit String for most sections and var only for the last two locals; consider making it consistent one way or the other. As per coding guidelines, follow docs/en/contributing/StyleGuide.md.

src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (3)

53-54: Prefer unit-specific constant names (avoid ambiguity for DISK_SIZE).
DISK_SIZE is used as MB (MemoryUnit.MB), so naming it DISK_SIZE_MB (or adding a short comment) prevents future misuse.

-  private static final long DISK_SIZE = 50;
+  private static final long DISK_SIZE_MB = 50;
-      .disk(DISK_SIZE, MemoryUnit.MB, true);
+      .disk(DISK_SIZE_MB, MemoryUnit.MB, true);

113-130: Don’t silently swallow StateTransitionException—add at least debug logging.
Right now a lock (or any state transition failure) is ignored, which makes diagnosing “why typo cache became in-memory” hard. Consider logging the instanceNumber + resolved path; and optionally log once when falling back to in-memory.

   private static org.ehcache.CacheManager createEhcacheManagerWithRetry(
     CachePathProvider cachePathProvider,
     String basePath,
     String fullPath
   ) {
     for (var instanceNumber = 0; instanceNumber < MAX_CACHE_INSTANCES; instanceNumber++) {
       try {
         var cacheDir = cachePathProvider.getCachePath(basePath, fullPath, instanceNumber);
         return createEhcacheManager(cacheDir);
       } catch (org.ehcache.StateTransitionException e) {
+        // TODO log at debug/warn: cacheDir + instanceNumber + e.getMessage()
         // This exception indicates the directory is locked by another process
         // Continue to try next instance number
       }
     }

     // If we exhausted all attempts, fall back to in-memory cache
+    // TODO log at warn: falling back to in-memory cache after MAX_CACHE_INSTANCES attempts
     return createInMemoryEhcacheManager();
   }

138-151: Make cache entry count and disk size configurable via Spring properties with sane defaults.

The constants ENTRIES_COUNT and DISK_SIZE are hard-coded, limiting flexibility across environments. Following the established pattern in the codebase (e.g., app.cache.basePath, app.cache.fullPath), consider externalizing these to application.properties with @Value injection. For example: app.cache.entriesCount=125000 and app.cache.diskSizeMb=50.

Also applies to: 161-172, 180-190

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b14da4 and 8efb955.

📒 Files selected for processing (15)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java (2 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/EventPublisherAspect.java (0 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentChangeExecutor.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (4 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/ModuleSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java (2 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (5 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (5 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java (9 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java (2 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ModuleReferenceTest.java (4 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/EventPublisherAspect.java
✅ Files skipped from review due to trivial changes (2)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/ModuleSymbolMarkupContentBuilder.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ModuleReferenceTest.java
🧰 Additional context used
📓 Path-based instructions (3)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentChangeExecutor.java
**/test/java/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use appropriate test frameworks (JUnit, AssertJ, Mockito) for testing

Files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java
**/diagnostics/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Each diagnostic should have a Java implementation class, resource bundle for localized messages, unit tests, and documentation

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java
🧠 Learnings (3)
📚 Learning: 2025-11-27T07:17:33.726Z
Learnt from: CR
Repo: 1c-syntax/bsl-language-server PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T07:17:33.726Z
Learning: Applies to **/test/java/**/*.java : Use appropriate test frameworks (JUnit, AssertJ, Mockito) for testing

Applied to files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java
📚 Learning: 2025-01-19T20:47:40.061Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/TestRunnerAdapterOptions.java:46-46
Timestamp: 2025-01-19T20:47:40.061Z
Learning: Configuration classes in the BSL Language Server project use mutable collections (HashMap, ArrayList) and Data annotation from Lombok, allowing for modification of configuration properties after initialization.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java
📚 Learning: 2025-02-10T17:12:56.150Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3408
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/ProtectedModuleDiagnostic.java:63-66
Timestamp: 2025-02-10T17:12:56.150Z
Learning: In BSL Language Server, `documentContext.getServerContext().getConfiguration()` is guaranteed to return a non-null value, making null checks unnecessary.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.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). (17)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build
  • GitHub Check: Analyse
  • GitHub Check: Analyze the repo with CodeSee
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (25, ubuntu-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (21, windows-latest)
🔇 Additional comments (25)
src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java (2)

137-137: Good extraction of the close-timeout constant (avoid magic number).


493-493: Timeout unification in didClose looks correct. awaitTermination(AWAIT_CLOSE, TimeUnit.SECONDS) matches the constant’s units and keeps behavior unchanged.

src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentChangeExecutor.java (1)

201-217: Lambda parameter typing in versionWaiters.compute is fine (behavior-neutral) and improves clarity.
No concerns with this change; the explicit types match the ConcurrentSkipListMap<Integer, CopyOnWriteArrayList<CompletableFuture<Void>>> value contract.

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (1)

180-226: var conversions in check() / fireDiagnosticOnCheckedWordsWithErrors() look safe and keep the code cleaner.
No behavior changes observed.

Also applies to: 228-241

src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java (1)

373-373: LGTM! Improved assertion style.

Replacing hasSize(0) with isEmpty() makes the assertions more readable and idiomatic. This follows AssertJ best practices for checking empty collections.

Also applies to: 455-455

src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilder.java (1)

64-70: var here is fine, but please keep style consistent with the project’s Java Style Guide.
No behavior change; both locals infer to String. If the style guide discourages var for simple types (or mixed String/var in the same method), prefer reverting these to String for consistency. As per coding guidelines, follow docs/en/contributing/StyleGuide.md.

src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilder.java (1)

81-87: LGTM; just ensure var usage matches the project conventions.
If the style guide prefers explicit types for String, revert; otherwise this is a clean, low-risk refactor. As per coding guidelines, follow docs/en/contributing/StyleGuide.md.

src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java (1)

58-74: var improves brevity here; verify it won’t conflict with style/checkstyle rules.
No functional concern—just ensure the repo’s style guide permits var for simple String locals. As per coding guidelines, follow docs/en/contributing/StyleGuide.md.

src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java (9)

93-97: LGTM! Good fluent assertion refactor.

The chained assertion style improves readability while maintaining the same verification logic for the MD5 hash format.


126-127: LGTM! Idiomatic AssertJ path assertion.

Using hasToString() instead of explicit toString() calls is the preferred AssertJ pattern for path component verification.


144-144: LGTM! Consistent path assertion style.

The refactor to hasToString() maintains consistency with other path assertions in the test class.


159-159: LGTM! Consistent refactoring pattern.

Applies the same hasToString() refactoring consistently across similar test scenarios.


189-192: LGTM! Clear fluent assertion chain.

Chaining the string assertions provides a clear, readable verification of the complete path structure.


221-223: LGTM! Logical assertion grouping.

The chained assertions effectively verify that instance number 0 produces a plain MD5 hash without suffix.


238-240: LGTM! Correct inequality chaining.

The chained assertions correctly verify that cachePath0 differs from both cachePath1 and cachePath2. Line 241 appropriately completes the verification by testing cachePath1 vs cachePath2.


257-259: LGTM! Effective transitive equality chain.

The chained isEqualTo assertions elegantly verify that all instance-numbered paths share the same parent directory through transitive equality.


275-277: LGTM! Clear equality verification.

The chained assertions effectively verify that instance number is ignored when fullPath is provided, establishing that all paths equal the custom path.

src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (8)

139-145: LGTM!

The SPEC_LITERALS constant follows the established pattern of other token type sets in this file and correctly groups the special literal tokens for keyword classification.


342-346: Clean decomposition of preprocessor handling.

The extraction into three focused helper methods improves readability and maintainability.


348-367: LGTM!

The method correctly filters out region-related preprocessor nodes and emits Macro tokens for the remaining HASH and PREPROC_* tokens. The null check on symbolicName at line 362 is properly handled.


369-386: LGTM!

The method correctly processes use and native directives with proper null guards. The inline comments clearly document the purpose of each section.


388-408: LGTM with minor observation.

The method correctly handles both region start and end nodes. The fallback to addNamespaceForPreprocessorNode at line 398 may re-fetch the preprocessor ancestor when it's already available but PREPROC_REGION() is null. This is acceptable as defensive coding since addNamespaceForPreprocessorNode handles the null case gracefully.


423-438: LGTM!

The variable renaming to hashNode and useNode improves clarity by indicating these are AST nodes.


526-534: LGTM!

The simplification delegates token type selection to the new selectAndAddSemanticToken method, keeping this loop clean and focused on iteration.


536-555: Well-structured consolidation of token type dispatch.

The method clearly organizes the token classification logic with appropriate comments. The skip for AMPERSAND and ANNOTATION_TOKENS at line 545-546 with the explanatory comment is good practice to avoid duplicate emissions.

Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (2)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1)

72-75: Complete the refactoring with INDEX_CONDITION.

Lines 72 and 75 still use hard-coded exp.get(0) instead of exp.get(INDEX_CONDITION), creating inconsistency with the constants introduced in this same change.

Apply this diff to complete the refactoring:

       if (condition != SKIPPED_RULE_INDEX) {
         diagnosticStorage.addDiagnostic(ctx);
       } else if (trueBranch == BSLParser.TRUE && falseBranch == BSLParser.FALSE) {
-        diagnosticStorage.addDiagnostic(ctx, DiagnosticStorage.createAdditionalData(exp.get(0).getText()));
+        diagnosticStorage.addDiagnostic(ctx, DiagnosticStorage.createAdditionalData(exp.get(INDEX_CONDITION).getText()));
       } else if (trueBranch == BSLParser.FALSE && falseBranch == BSLParser.TRUE) {
         diagnosticStorage.addDiagnostic(ctx,
-          DiagnosticStorage.createAdditionalData(getAdaptedText(exp.get(0).getText())));
+          DiagnosticStorage.createAdditionalData(getAdaptedText(exp.get(INDEX_CONDITION).getText())));
       } else if (trueBranch != SKIPPED_RULE_INDEX || falseBranch != SKIPPED_RULE_INDEX) {
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (1)

148-154: Guard lang → pool lookup + make acquire/release NPE-safe (avoid leaks and hard crashes).

getLanguageToolPoolMap().get(lang) can be null (bundle misconfig / new language), and if acquireLanguageTool(lang) throws, finally won’t run and a checked-out instance may leak. Consider validating lang once and releasing only when acquired.

+import java.util.Objects;
+import org.jspecify.annotations.Nullable;
...
-  private static JLanguageTool acquireLanguageTool(String lang) {
-    return getLanguageToolPoolMap().get(lang).checkOut();
-  }
+  private static JLanguageTool acquireLanguageTool(String lang) {
+    var pool = getLanguageToolPoolMap().get(lang);
+    if (pool == null) {
+      throw new IllegalArgumentException("Unsupported diagnosticLanguage: " + lang);
+    }
+    return pool.checkOut();
+  }

-  private static void releaseLanguageTool(String lang, JLanguageTool languageTool) {
-    getLanguageToolPoolMap().get(lang).checkIn(languageTool);
-  }
+  private static void releaseLanguageTool(String lang, @Nullable JLanguageTool languageTool) {
+    if (languageTool == null) {
+      return;
+    }
+    var pool = getLanguageToolPoolMap().get(lang);
+    if (pool != null) {
+      pool.checkIn(languageTool);
+    }
+  }
...
-    var languageTool = acquireLanguageTool(lang);
-
-    List<RuleMatch> matches = Collections.emptyList();
-    try {
+    List<RuleMatch> matches = Collections.emptyList();
+    JLanguageTool languageTool = null;
+    try {
+      languageTool = acquireLanguageTool(lang);
       matches = languageTool.check(
         uncheckedWordsString,
         true,
         JLanguageTool.ParagraphHandling.ONLYNONPARA
       );
     } catch (IOException e) {
       LOGGER.error(e.getMessage(), e);
     } finally {
       releaseLanguageTool(lang, languageTool);
     }

Also applies to: 183-213

🧹 Nitpick comments (5)
src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (2)

53-55: Make cache-size constants self-describing (units in the name).
DISK_SIZE is ambiguous since it’s “50 MB” only by implication at usage sites.

-  private static final long ENTRIES_COUNT = 125_000;
-  private static final long DISK_SIZE = 50;
+  private static final long HEAP_ENTRIES_COUNT = 125_000;
+  private static final long DISK_SIZE_MB = 50;

(Then update usages accordingly.)


113-130: Add logging for locked dirs and for the “fallback to in-memory” path.
Right now StateTransitionException is swallowed and the fallback is silent, which can lead to “why did my typo cache stop persisting?” debugging later.

 public class CacheConfiguration {
+  private static final org.slf4j.Logger log =
+    org.slf4j.LoggerFactory.getLogger(CacheConfiguration.class);
   ...
   private static org.ehcache.CacheManager createEhcacheManagerWithRetry(
     CachePathProvider cachePathProvider,
     String basePath,
     String fullPath
   ) {
     for (var instanceNumber = 0; instanceNumber < MAX_CACHE_INSTANCES; instanceNumber++) {
       try {
         var cacheDir = cachePathProvider.getCachePath(basePath, fullPath, instanceNumber);
         return createEhcacheManager(cacheDir);
       } catch (org.ehcache.StateTransitionException e) {
+        log.debug("Ehcache directory is locked, trying next instanceNumber={}", instanceNumber, e);
       }
     }

-    // If we exhausted all attempts, fall back to in-memory cache
+    log.warn("All ehcache directories are locked (attempts={}); falling back to in-memory cache", MAX_CACHE_INSTANCES);
     return createInMemoryEhcacheManager();
   }
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (1)

130-146: Optional: avoid producing [""] when exceptions string is empty.

Today it’s mostly harmless (later filters drop short/blank tokens), but returning an empty set here is cleaner and avoids surprising config states.

-    return Arrays.stream(exceptions.split(String.valueOf(delimiter)))
-      .collect(Collectors.toSet());
+    if (exceptions.isEmpty()) {
+      return Collections.emptySet();
+    }
+    return Arrays.stream(exceptions.split(String.valueOf(delimiter)))
+      .filter(Predicate.not(String::isBlank))
+      .collect(Collectors.toSet());
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (2)

388-408: Region token split (Namespace for #регион, Variable for region name) is a solid overlap-avoidance strategy.

Minor: the fallback addNamespaceForPreprocessorNode(entries, regionStart) can reintroduce overlap with regionName if it ever triggers for a valid regionStart; consider ensuring the “keyword-only” range is always used when regionStart.regionName() != null.


526-555: Lexical token dispatch is cleaner and reduces branching duplication.

Optional: consider a switch on tokenType for the singleton cases (DATETIME, AMPERSAND) to reduce chained else if depth.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8efb955 and 2c2eb6e.

📒 Files selected for processing (21)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java (2 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/EventPublisherAspect.java (0 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentChangeExecutor.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java (3 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java (4 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/ModuleSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java (2 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (5 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (5 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java (3 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java (6 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java (9 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java (2 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ModuleReferenceTest.java (4 hunks)
💤 Files with no reviewable changes (1)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/EventPublisherAspect.java
🚧 Files skipped from review as they are similar to previous changes (15)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/ModuleReferenceTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFillerTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/AbstractMetadataDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/MultilingualStringAnalyser.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/context/DocumentChangeExecutor.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CachePathProviderTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/VariableSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/ModuleSymbolMarkupContentBuilder.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/references/ReferenceIndexFiller.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/codelenses/RunTestCodeLensSupplier.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/BSLTextDocumentService.java
🧰 Additional context used
📓 Path-based instructions (2)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java
**/diagnostics/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Each diagnostic should have a Java implementation class, resource bundle for localized messages, unit tests, and documentation

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.java
🧠 Learnings (2)
📚 Learning: 2025-01-19T20:47:40.061Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/TestRunnerAdapterOptions.java:46-46
Timestamp: 2025-01-19T20:47:40.061Z
Learning: Configuration classes in the BSL Language Server project use mutable collections (HashMap, ArrayList) and Data annotation from Lombok, allowing for modification of configuration properties after initialization.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
📚 Learning: 2025-11-27T07:17:33.726Z
Learnt from: CR
Repo: 1c-syntax/bsl-language-server PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-27T07:17:33.726Z
Learning: Applies to docs/*/diagnostics/**/*.md : Update diagnostic documentation in both Russian and English with examples of problematic code and fixes

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/TypoDiagnostic.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). (1)
  • GitHub Check: gatekeeper
🔇 Additional comments (7)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (2)

55-58: LGTM! Clear semantic constants.

The named constants improve code readability by replacing magic numbers with meaningful identifiers.


64-67: LGTM! Consistent use of named constants.

The refactoring correctly replaces hard-coded indices with the semantic constants defined above.

src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (2)

138-143: Nice cleanup: centralized sizing constants; consider renaming + keep disk sizing consistent with comments.
Using constants here improves readability and makes tuning easier.

Also applies to: 161-165


180-190: Static helper looks good.
No behavior change; makes intent clearer (no instance state).

src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/Trees.java (1)

125-136: All call sites properly handle the nullable contract—no action needed.

A survey of 26+ call sites across the codebase confirms that callers already handle nullable inputs and returns correctly: most use explicit null checks before accessing the result, some wrap the result in Optional.ofNullable(), and others pass the result to @Nullable-annotated parameters that safely check for null. Even the cast at TimeoutsInExternalResourcesDiagnostic.java:213 is safe because the result is passed to getVariableName(), which accepts @Nullable StatementContext and checks for null before use. The API contract is sound and consistently respected.

Likely an incorrect or invalid review comment.

src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (2)

139-145: Good: explicit “special literals” classification keeps keyword handling predictable.


423-438: addNamespaceForUse: clearer node naming; token-range behavior still consistent.

Copy link
Contributor

@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

🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java (1)

38-56: Good test coverage for valid parse tree scenario.

The test correctly validates token extraction from a valid BSL procedure. The expected token count of 6 matches the grammar output, and the use of given-when-then structure with AssertJ assertions follows best practices.

Optional: Consider using var for consistency.

Line 47 uses explicit type ParseTree tree while other test methods use var tokens. For consistency, consider:

-    ParseTree tree = parser.file();
+    var tree = parser.file();
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c2eb6e and 23d7dcd.

📒 Files selected for processing (4)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java (1 hunks)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (5 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java
**/diagnostics/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Each diagnostic should have a Java implementation class, resource bundle for localized messages, unit tests, and documentation

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
**/test/java/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use appropriate test frameworks (JUnit, AssertJ, Mockito) for testing

Files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java
🧠 Learnings (2)
📚 Learning: 2025-01-19T20:47:40.061Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3388
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/configuration/codelens/TestRunnerAdapterOptions.java:46-46
Timestamp: 2025-01-19T20:47:40.061Z
Learning: Configuration classes in the BSL Language Server project use mutable collections (HashMap, ArrayList) and Data annotation from Lombok, allowing for modification of configuration properties after initialization.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java
📚 Learning: 2025-11-19T09:02:03.154Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-language-server PR: 3610
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplier.java:26-26
Timestamp: 2025-11-19T09:02:03.154Z
Learning: В проекте bsl-language-server используется кастомная версия ANTLR4 от 1c-syntax (io.github.1c-syntax:antlr4), которая включает базовый класс org.antlr.v4.runtime.Tokenizer с методами getAst() и getTokens(). SDBLTokenizer и BSLTokenizer наследуются от этого базового класса.

Applied to files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java
🧬 Code graph analysis (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/DiagnosticStorage.java (1)
  • DiagnosticStorage (50-332)
⏰ 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). (11)
  • GitHub Check: build
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (25, ubuntu-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: Analyse
🔇 Additional comments (9)
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java (1)

55-58: Nice readability win by replacing magic numbers with named constants.

src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/CacheConfiguration.java (4)

53-54: Excellent refactoring to eliminate magic numbers.

The introduction of these constants improves maintainability and makes the cache sizing configuration explicit and centralized.


113-113: LGTM: Appropriate conversion to static methods.

All four helper methods are correctly made static since they don't access instance state. This follows Java best practices for utility-style methods within a class.

Also applies to: 138-138, 161-161, 180-180


118-118: Good use of local type inference.

The type is clearly inferred from the context, and this aligns with the modern Java style used elsewhere in the file.


141-142: Consistent application of constants.

The hard-coded values have been properly replaced with the newly defined constants throughout the file, ensuring consistent cache sizing configuration.

Also applies to: 164-164

src/test/java/com/github/_1c_syntax/bsl/languageserver/utils/TreesTest.java (2)

58-65: Excellent null-safety test.

This test correctly validates that Trees.getTokens() handles null input gracefully by returning an empty list. This aligns with the PR's focus on null-safety improvements across the codebase.


67-103: Comprehensive edge case and token type verification.

Both test methods provide valuable coverage:

  • testGetTokensWithEmptyTree correctly validates that empty input produces a single EOF token.
  • testGetTokensReturnsCorrectTokenTypes verifies not just token count but also token type sequence, ensuring the parser correctly identifies BSL keywords.

The tests follow consistent structure and use AssertJ fluent assertions effectively.

src/main/java/com/github/_1c_syntax/bsl/languageserver/hover/MethodSymbolMarkupContentBuilder.java (2)

54-54: LGTM: Good use of local variable type inference.

The conversion from explicit String declarations to var is appropriate here. The types are immediately clear from the method names (getSignature, getLocation, etc.), and this reduces verbosity while maintaining readability. This follows modern Java practices for Java 17.

Also applies to: 58-58, 62-62, 66-66, 70-70, 74-74, 78-78, 81-81


42-84: Removed constants have been properly relocated to DescriptionFormatter.

All private static final String constants (PROCEDURE_KEY, FUNCTION_KEY, EXPORT_KEY, VAL_KEY, PARAMETERS_KEY, RETURNED_VALUE_KEY, EXAMPLES_KEY, CALL_OPTIONS_KEY, PARAMETER_TEMPLATE) have been successfully moved to DescriptionFormatter (lines 50-60) and are actively used throughout that class. The formatting logic has been properly delegated through descriptionFormatter method calls with no orphaned references in the codebase. Separation of concerns is maintained with formatting logic consolidated in the formatter utility class.

Comment on lines +64 to +67
if (exp != null && exp.size() >= COUNT_EXPRESSIONS) {
var condition = getBooleanToken(exp.get(INDEX_CONDITION));
var trueBranch = getBooleanToken(exp.get(INDEX_TRUE_BRANCH));
var falseBranch = getBooleanToken(exp.get(INDEX_FALSE_BRANCH));
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Harden null-safety: getBooleanToken(Optional.of(expCtx)) will NPE if any exp.get(i) is null.

If ctx.expression() can’t contain null items, it’s fine today, but given the PR’s general null-safety direction, it’d be safer to make getBooleanToken tolerate null inputs (or explicitly assert non-null at call sites).

-  private static int getBooleanToken(BSLParser.ExpressionContext expCtx) {
+  private static int getBooleanToken(@org.jetbrains.annotations.Nullable BSLParser.ExpressionContext expCtx) {
     var tmpCtx = Optional.of(expCtx)
+      // or: Optional.ofNullable(expCtx)
       .filter(ctx -> ctx.children.size() == 1)
       .map(ctx -> ctx.member(0))
       .map(ctx -> ctx.getChild(0))
       .filter(BSLParser.ConstValueContext.class::isInstance)
       .map(BSLParser.ConstValueContext.class::cast);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UselessTernaryOperatorDiagnostic.java
around lines 64 to 67, calling getBooleanToken(exp.get(...)) can NPE if any
exp.get(i) returns null; either guard each exp.get(INDEX_...) with a null check
and only call getBooleanToken when non-null (e.g., use
Optional.ofNullable(exp.get(i)) or skip/handle missing entries), or change
getBooleanToken to accept a possibly-null parameter (or Optional) and handle
null internally; update the callsite to pass a nullable/Optional value and
adjust downstream logic accordingly so no NPE occurs.

Copy link
Contributor

@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 (2)
src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilderTest.java (2)

41-56: Consider using more fluent AssertJ assertions.

The assertion at line 55 creates a new MarkupContent object for comparison. For better readability and to align with the fluent AssertJ style used in AnnotationSymbolMarkupContentBuilderTest.java, consider checking the fields separately.

Apply this diff to use more fluent assertions:

     // then
-    assertThat(result).isEqualTo(new MarkupContent(MarkupKind.MARKDOWN, ""));
+    assertThat(result.getValue()).isEmpty();
+    assertThat(result.getKind()).isEqualTo(MarkupKind.MARKDOWN);
   }

58-76: Consider using more fluent AssertJ assertions.

Similar to the previous test, the assertion at line 75 creates a new MarkupContent object for comparison. Use the same fluent style for consistency.

Apply this diff to use more fluent assertions:

     // then
-    assertThat(result).isEqualTo(new MarkupContent(MarkupKind.MARKDOWN, ""));
+    assertThat(result.getValue()).isEmpty();
+    assertThat(result.getKind()).isEqualTo(MarkupKind.MARKDOWN);
   }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 23d7dcd and 4f5354e.

📒 Files selected for processing (2)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilderTest.java (1 hunks)
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilderTest.java (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilderTest.java
**/test/java/**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use appropriate test frameworks (JUnit, AssertJ, Mockito) for testing

Files:

  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilderTest.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilderTest.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). (11)
  • GitHub Check: Analyse
  • GitHub Check: build (25, ubuntu-latest)
  • GitHub Check: build (25, macOS-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build (25, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (21, ubuntu-latest)
  • GitHub Check: build (17, windows-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build
🔇 Additional comments (4)
src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationParamSymbolMarkupContentBuilderTest.java (1)

78-89: LGTM!

The test correctly verifies that getSymbolKind() returns SymbolKind.TypeParameter. The test structure follows best practices with the given-when-then pattern.

src/test/java/com/github/_1c_syntax/bsl/languageserver/hover/AnnotationSymbolMarkupContentBuilderTest.java (3)

39-54: LGTM!

The test correctly uses fluent AssertJ assertions by checking content.getValue() and content.getKind() separately. This approach is more readable and follows AssertJ best practices. The given-when-then structure is clear and the mocking setup is appropriate.


56-70: LGTM!

Good edge case coverage for when the parent is absent. The test uses fluent AssertJ style consistently and follows the given-when-then pattern properly.


72-83: LGTM!

The test correctly verifies that getSymbolKind() returns SymbolKind.Interface. The test structure is clean and follows best practices.

}
var subExpression = makeSubexpression(typeNameArg.expression());
if (subExpression == null) {
operands.push(new ErrorExpressionNode(ctx));
Copy link
Member

Choose a reason for hiding this comment

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

Ох как страшно...

Copy link
Collaborator

Choose a reason for hiding this comment

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

А почему ExpressionTree стал Nullable?

public static <T extends ParserRuleContext> T getAncestorByRuleIndex(ParserRuleContext element, int type) {
public static <T extends ParserRuleContext> T getAncestorByRuleIndex(@Nullable ParserRuleContext element, int type) {
if (element == null) {
return null;
Copy link
Member

Choose a reason for hiding this comment

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

Может на Trees из antlr навесить jspecify аннотации и эти проверки? Тогда тут их можно будет убрать.

Copy link
Member

Choose a reason for hiding this comment

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

Не, не нравится мне Nullable в параметрах...

var result = builder.getContent(symbol);

// then
assertThat(result).isEqualTo(new MarkupContent(MarkupKind.MARKDOWN, ""));
Copy link
Member

Choose a reason for hiding this comment

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

Прям таки пустая строка? Там разве хотя бы сигнатуры и списка параметров не должно быть для зарегистрированных аннотаций?


// then
assertThat(content.getValue()).isEmpty();
assertThat(content.getKind()).isEqualTo(MarkupKind.MARKDOWN);
Copy link
Member

Choose a reason for hiding this comment

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

Было бы хорошо что-нибудь в плане содержимого тут проверить, как в соседних тестах

Copy link
Member

Choose a reason for hiding this comment

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

Вообще странно, что ты создаёшь эти тесты, я был уверен, что они есть...

String input = """
Процедура Тест()
КонецПроцедуры""";
var lexer = new BSLLexer(CharStreams.fromString(input));
Copy link
Member

Choose a reason for hiding this comment

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

Может BSLTokenizer использовать тут? Для простоты

@nixel2007 nixel2007 force-pushed the feature/sqfixes251212 branch from 9561ebd to 4be9da8 Compare December 13, 2025 08:47
Copy link
Contributor

@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

Caution

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

⚠️ Outside diff range comments (2)
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (2)

389-408: Comment mismatch: this loop doesn’t actually “exclude native/use”; it only excludes regions.
Not a functional bug (given grammar: use/preproc_native aren’t PreprocessorContext), but the comment currently implies logic that isn’t present, which can mislead future edits.

@@
-  // Other preprocessor directives: Macro for each HASH and PREPROC_* token,
-  // excluding region start/end, native, use (handled as Namespace)
+  // Other preprocessor directives (PreprocessorContext): Macro for HASH and PREPROC_* tokens.
+  // Regions are excluded here (handled in addRegionsNamespaces).
+  // Module annotations (use/preproc_native) are handled in addDirectives and are not part of PreprocessorContext.

526-555: Add tests to cover NULL literal and PREPROC_ keyword exclusion.*

The refactored logic correctly forces UNDEFINED/TRUE/FALSE/NULL to Keyword type via the new SPEC_LITERALS constant, and the keyword detection now excludes PREPROC_* tokens (handled via AST). However, test coverage is incomplete:

  • datetimeAndUndefinedTrueFalse_areHighlighted() tests UNDEFINED/TRUE/FALSE but not NULL
  • The PREPROC_* exclusion in the lexical path is not directly verified—only the AST emission path is tested

Add unit tests covering both the NULL literal classification and the explicit exclusion of PREPROC_*_KEYWORD tokens from semantic token emission to prevent regressions in token classification.

🧹 Nitpick comments (3)
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (3)

342-368: Potential overlap fallback: addNamespaceForPreprocessorNode(entries, regionStart) can include the region name.
In the “else” branch (when ancestor/PREPROC_REGION isn’t available), you may emit a Namespace range that spans into regionStart.regionName() while also emitting Variable for the region name (Line 361-363). Consider a conservative fallback to avoid overlapping types.

@@
-      } else {
-        addNamespaceForPreprocessorNode(entries, regionStart);
-      }
+      } else {
+        // Conservative fallback: avoid spanning into regionName (which is emitted as Variable below)
+        var preprocessor = Trees.<PreprocessorContext>getAncestorByRuleIndex(regionStart, BSLParser.RULE_preprocessor);
+        if (preprocessor != null && preprocessor.getStart() != null) {
+          addRange(entries, Ranges.create(preprocessor.getStart()), SemanticTokenTypes.Namespace);
+        } else {
+          addNamespaceForPreprocessorNode(entries, regionStart);
+        }
+      }

370-387: Consider emitting #native as a single Macro range when both tokens exist (fewer tokens, consistent style).
Current behavior is correct, but you can reduce output noise by joining HASH..PREPROC_NATIVE (like you do for #Использовать).

@@
-      if (hash != null) {
-        addRange(entries, Ranges.create(hash), SemanticTokenTypes.Macro);
-      }
-      if (nativeKw != null) {
-        addRange(entries, Ranges.create(nativeKw), SemanticTokenTypes.Macro);
-      }
+      if (hash != null && nativeKw != null) {
+        addRange(entries, Ranges.create(hash, nativeKw), SemanticTokenTypes.Macro);
+      } else if (hash != null) {
+        addRange(entries, Ranges.create(hash), SemanticTokenTypes.Macro);
+      } else if (nativeKw != null) {
+        addRange(entries, Ranges.create(nativeKw), SemanticTokenTypes.Macro);
+      }

423-438: addNamespaceForUse: logic is fine; trailing else { // no-op } can be dropped.
Optional cleanup to reduce dead branches.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab8f5d4 and 4be9da8.

📒 Files selected for processing (1)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (6 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.java

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.java: Follow the Style Guide provided in docs/en/contributing/StyleGuide.md
Use Lombok annotations to reduce boilerplate code and enable annotation processing in your IDE
Optimize imports before committing but do NOT optimize imports across the entire project unless specifically working on that task
Follow Java naming conventions with meaningful, descriptive names; keep class and method names concise but clear
Write JavaDoc for public APIs and include comments for complex logic
Use Target Java 17 as the language version

Files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java
🧠 Learnings (2)
📚 Learning: 2025-11-19T09:02:03.154Z
Learnt from: theshadowco
Repo: 1c-syntax/bsl-language-server PR: 3610
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/folding/QueryPackageFoldingRangeSupplier.java:26-26
Timestamp: 2025-11-19T09:02:03.154Z
Learning: В проекте bsl-language-server используется кастомная версия ANTLR4 от 1c-syntax (io.github.1c-syntax:antlr4), которая включает базовый класс org.antlr.v4.runtime.Tokenizer с методами getAst() и getTokens(). SDBLTokenizer и BSLTokenizer наследуются от этого базового класса.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java
📚 Learning: 2025-04-18T22:46:43.245Z
Learnt from: nixel2007
Repo: 1c-syntax/bsl-language-server PR: 3449
File: src/main/java/com/github/_1c_syntax/bsl/languageserver/utils/expressiontree/ExpressionTreeBuildingVisitor.java:192-203
Timestamp: 2025-04-18T22:46:43.245Z
Learning: В проекте bsl-language-server класс BSLParser.ExpressionContext наследуется от BSLParserRuleContext, а не напрямую от ParserRuleContext. При работе с ним нужно учитывать специфичные методы BSLParserRuleContext.

Applied to files:

  • src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.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 (25, windows-latest)
  • GitHub Check: build (21, macOS-latest)
  • GitHub Check: build (21, windows-latest)
  • GitHub Check: build (17, macOS-latest)
  • GitHub Check: build (17, ubuntu-latest)
  • GitHub Check: build
  • GitHub Check: Analyze the repo with CodeSee
🔇 Additional comments (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/SemanticTokensProvider.java (1)

139-145: SPEC_LITERALS → Keyword classification looks correct (undefined/true/false/null).
This makes these literals consistent with other “language-defined” atoms and avoids them falling through to “unknown”.

@sonarqubecloud
Copy link

@nixel2007 nixel2007 merged commit af962f9 into develop Dec 13, 2025
39 of 40 checks passed
@nixel2007 nixel2007 deleted the feature/sqfixes251212 branch December 13, 2025 10:10
}
var subExpression = makeSubexpression(typeNameArg.expression());
if (subExpression == null) {
operands.push(new ErrorExpressionNode(ctx));
Copy link
Collaborator

Choose a reason for hiding this comment

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

А почему ExpressionTree стал Nullable?

makeSubexpression(ctx.expression(0)),
makeSubexpression(ctx.expression(1)),
makeSubexpression(ctx.expression(2))
Objects.requireNonNull(makeSubexpression(ctx.expression(0))),
Copy link
Collaborator

Choose a reason for hiding this comment

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

Давай лучше makeSubexpression не будет возвращать null? Или в этом есть тайный смысл, который я не понял?

Пусть бы resultExpression если null, возврат ErrorNode и результат всегда не нулл, не?

Copy link
Member

Choose a reason for hiding this comment

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

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.

4 participants