Skip to content

fix(lsp): выставлять workspace-контекст в didClose#4283

Merged
nixel2007 merged 5 commits into
developfrom
claude/workspace-scope-error-l6erji
Jul 21, 2026
Merged

fix(lsp): выставлять workspace-контекст в didClose#4283
nixel2007 merged 5 commits into
developfrom
claude/workspace-scope-error-l6erji

Conversation

@nixel2007

@nixel2007 nixel2007 commented Jul 20, 2026

Copy link
Copy Markdown
Member

Описание

Исправляет предупреждение при textDocument/didClose:

[WARN] [pool-2-thread-1] EventPublisherAspect: Failed to publish event ServerContextDocumentClosedEvent … ScopeNotActiveException: Error creating bean with name 'scopedTarget.callStatementByReceiverIndex': Scope 'workspace' is not active for the current thread

didClose приходит с потока диспетчеризации LSP4J (pool-2-thread-1), на котором не установлен WorkspaceContextHolder. Когда ServerContext.closeDocument() через EventPublisherAspect публикует ServerContextDocumentClosedEvent, workspace-scoped @EventListener-бины (например, CallStatementByReceiverIndex) не могут зарезолвиться — рассылка падает, и все подписчики молча теряют событие: per-URI индексы не чистятся при закрытии документа и удерживают AST-узлы закрытого документа.

Инвентаризация показала, что идиома «входная точка сама выставляет workspace-контекст» соблюдается во всех ~15 местах проекта (didOpen, файловые события, MCP, CLI, вотчеры, воркеры executor'ов) — didClose был единственным пропуском.

Изменения:

  • BSLTextDocumentService.didClose — вызов serverContext.closeDocument(...) обёрнут в WorkspaceContextHolder.run(...), симметрично didOpen.
  • Регрессионный тест в CallStatementByReceiverIndexTest: закрывает документ через textDocumentService.didClose с потока без workspace-контекста и проверяет, что индекс реально сброшен. Без фикса тест воспроизводит ровно то самое предупреждение из лога и падает.
  • build.gradle.kts — экспериментальная multi-dollar interpolation ($$"…") в блоке gitVersioning заменена на стандартное экранирование "\${…}": шаблоны для плагина идентичны, но скрипт больше не требует Kotlin 2.2 и собирается более старыми Gradle.

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

Closes —

Чеклист

Общие

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

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

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

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

Рассматривался и альтернативный вариант — восполнять отсутствующий контекст централизованно в EventPublisherAspect (по workspaceUri из ServerContext-источника события); он был реализован, проверен и затем откачен в пользу идиоматичной call-site-обёртки (см. историю коммитов ветки).

В среде разработки был недоступен дистрибутив Gradle 9.6.1 (загрузка заблокирована сетевой политикой), поэтому gradlew precommit не запускался; тесты гонялись на Gradle 8.14.3: fail-first (тест падает без фикса, воспроизводя предупреждение) → с фиксом зелёные CallStatementByReceiverIndexTest и BSLTextDocumentServiceTest.

🤖 Generated with Claude Code

https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ

Summary by CodeRabbit

  • Bug Fixes

    • Improved document closing so workspace-related cleanup events are handled with the correct workspace context.
    • Ensured document shutdown behavior remains reliable while background processing is terminated.
  • Tests

    • Added regression coverage verifying workspace context availability when documents are closed.
  • Chores

    • Updated version formatting configuration to preserve consistent build version output.

claude added 2 commits July 20, 2026 07:36
… потоков без него

ServerContextDocumentClosedEvent (и другие события с source = ServerContext)
терялись, если метод-мутатор вызван с потока без установленного
WorkspaceContextHolder: рассылка падала ScopeNotActiveException при резолве
workspace-scoped @EventListener-бинов (callStatementByReceiverIndex и др.).
Так происходит в textDocument/didClose — он приходит с потока LSP4J.

EventPublisherAspect теперь выставляет workspace-контекст из workspace
источника события на время рассылки, если на потоке он не установлен.
Имя workspace берётся через новый WorkspaceContextHolder.nameForUri()
(зарегистрированное или производное от URI; логика перенесена из
ServerContextProvider).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ
…versioning

Экспериментальный синтаксис $$"…" требует Kotlin 2.2+ (Gradle 9.6) и не
парсится более старыми версиями Gradle. Обычное экранирование \$ даёт те же
литеральные плейсхолдеры ${…} для git-versioning и работает в любой версии.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Document closure now runs with the workspace context active so close-event listeners can resolve the correct workspace. A regression test verifies this behavior, and Git version templates use updated formatting syntax while preserving their existing variables.

Changes

Workspace event routing

Layer / File(s) Summary
Context-aware document close
src/main/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentService.java, src/test/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentServiceTest.java
didClose executes document closure within the workspace context, and a regression test verifies the workspace URI observed by close-event listeners.

Git version templates

Layer / File(s) Summary
Git version format updates
build.gradle.kts
Tag, branch, catch-all, and revision fallback templates use updated literal and template formatting syntax.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title clearly matches the main LSP fix: setting workspace context in didClose.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/workspace-scope-error-l6erji

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.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Test Results

 3 654 files  ±0   3 654 suites  ±0   1h 56m 29s ⏱️ + 7m 27s
 3 630 tests +1   3 612 ✅ +1   18 💤 ±0  0 ❌ ±0 
21 780 runs  +6  21 668 ✅ +6  112 💤 ±0  0 ❌ ±0 

Results for commit 9038f9f. ± Comparison against base commit 5418dd7.

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@build.gradle.kts`:
- Around line 48-51: The develop branch version template is incompatible with
Sentry’s expected develop-version format. Update the develop branch
configuration to emit the develop- prefixed distance format, preserving the
dirty suffix, and keep SentryScopeConfigurer.resolveEnvironment unchanged unless
the project’s intended contract explicitly requires the existing SNAPSHOT
format.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d031da77-581f-431d-923c-cf428f123669

📥 Commits

Reviewing files that changed from the base of the PR and between 5418dd7 and 7a207c0.

📒 Files selected for processing (5)
  • build.gradle.kts
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/aop/EventPublisherAspect.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/context/ServerContextProvider.java
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/infrastructure/WorkspaceContextHolder.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/types/index/CallStatementByReceiverIndexTest.java

Comment thread build.gradle.kts
…спекте

didClose приходит с потока диспетчеризации LSP4J без установленного
WorkspaceContextHolder — единственная входная точка без обёртки. Ставим
контекст явно, как в didOpen и остальных обработчиках, вместо
восполнения контекста на уровне EventPublisherAspect: изменения аспекта,
WorkspaceContextHolder и ServerContextProvider откачены, регрессионный
тест переведён на закрытие через BSLTextDocumentService.didClose.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ
@nixel2007 nixel2007 changed the title fix(aop): восстанавливать workspace-контекст при публикации событий с потоков без него fix(lsp): выставлять workspace-контекст в didClose Jul 20, 2026
claude added 2 commits July 20, 2026 09:54
Имя класса повторяет реализуемый LSP4J-интерфейс TextDocumentService;
стереотип @component — общепроектная конвенция (@service в проекте не
используется), переименование невозможно.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ
Тест проверяет поведение BSLTextDocumentService.didClose (доставку
ServerContextDocumentClosedEvent workspace-scoped подписчикам), поэтому
его место — рядом с didOpen-аналогом в BSLTextDocumentServiceTest, а не
в тестовом классе индекса. CallStatementByReceiverIndexTest возвращён к
исходному виду без зависимости от сервиса.

Также убрано подавление @SuppressWarnings(java:S5673): в проекте включено
правило S1309, запрещающее подавления; S5673 по @component обрабатывается
на стороне quality profile.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019dRpi5rmAfg8gXvT9ZG8wQ

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/main/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentService.java (1)

824-833: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider wrapping diagnostic publishing in the workspace context.

For consistency with didOpen (where validate() runs inside the workspace context) and to future-proof against ScopeNotActiveException if publishEmptyDiagnosticList ever interacts with workspace-scoped beans, consider moving the diagnostic clearing logic inside the WorkspaceContextHolder.run lambda block.

♻️ Proposed refactor
-    WorkspaceContextHolder.run(serverContext.getWorkspaceUri(),
-      () -> serverContext.closeDocument(documentContext));
-
-    if (!clientSupportsPullDiagnostics) {
-      diagnosticProvider.publishEmptyDiagnosticList(documentContext);
-    }
+    WorkspaceContextHolder.run(serverContext.getWorkspaceUri(), () -> {
+      serverContext.closeDocument(documentContext);
+      if (!clientSupportsPullDiagnostics) {
+        diagnosticProvider.publishEmptyDiagnosticList(documentContext);
+      }
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentService.java`
around lines 824 - 833, Move the clientSupportsPullDiagnostics check and
diagnosticProvider.publishEmptyDiagnosticList(documentContext) call inside the
WorkspaceContextHolder.run lambda in the document-close flow, keeping both
document closing and diagnostic clearing under the same workspace context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/main/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentService.java`:
- Around line 824-833: Move the clientSupportsPullDiagnostics check and
diagnosticProvider.publishEmptyDiagnosticList(documentContext) call inside the
WorkspaceContextHolder.run lambda in the document-close flow, keeping both
document closing and diagnostic clearing under the same workspace context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6beaeaed-e8e2-4595-8586-fe1062bd4f47

📥 Commits

Reviewing files that changed from the base of the PR and between 7a207c0 and 9038f9f.

📒 Files selected for processing (2)
  • src/main/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentService.java
  • src/test/java/com/github/_1c_syntax/bsl/languageserver/lsp/BSLTextDocumentServiceTest.java

@sonarqubecloud

sonarqubecloud Bot commented Jul 20, 2026

Copy link
Copy Markdown

@nixel2007
nixel2007 merged commit 5d2ee9d into develop Jul 21, 2026
38 checks passed
@nixel2007
nixel2007 deleted the claude/workspace-scope-error-l6erji branch July 21, 2026 10:20
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