fix(diagnostics): сбрасывать Lazy-кэш диагностик до workspace/diagnostic/refresh#4139
Conversation
…tic/refresh Pull-клиент (VSCode 1.94+) объявляет refreshSupport, мы шлём ему workspace/diagnostic/refresh, но не чистим Lazy<List<Diagnostic>>-кэш в DocumentContext. Клиент честно перезапрашивает textDocument/diagnostic, а получает закэшированное значение, посчитанное до наполнения контекста (межфайловые диагностики UnusedLocalMethod / EventHandler*, обращения к общим модулям и т.п. — все «висят» до переоткрытия файла). clearDiagnostics() теперь вызывается до выбора ветки — и для pull-, и для push-клиента. Lazy кэш сбрасывается, следующий getDiagnostics() пересчитает с актуальным реестром типов и индексом.
📝 WalkthroughWalkthrough
ChangesDiagnostic Cache Clear Refactor
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProviderTest.java (1)
242-245: ⚡ Quick winAssert ordering between cache clear and client refresh.
This test verifies both actions happened, but not that
clearDiagnostics()occurs beforerefreshDiagnostics(), which is the core behavior this PR protects.Proposed test hardening
+import org.mockito.InOrder; ... void testServerContextPopulatedClearsCachedDiagnosticsForPullClient() { @@ // then - verify(openedA, times(1)).clearDiagnostics(); - verify(openedB, times(1)).clearDiagnostics(); - verify(languageClient, times(1)).refreshDiagnostics(); + verify(openedA, times(1)).clearDiagnostics(); + verify(openedB, times(1)).clearDiagnostics(); + verify(languageClient, times(1)).refreshDiagnostics(); + + InOrder inOrder = org.mockito.Mockito.inOrder(openedA, openedB, languageClient); + inOrder.verify(openedA).clearDiagnostics(); + inOrder.verify(openedB).clearDiagnostics(); + inOrder.verify(languageClient).refreshDiagnostics(); }🤖 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/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProviderTest.java` around lines 242 - 245, The test verifies that clearDiagnostics() and refreshDiagnostics() are called but does not enforce that clearDiagnostics() occurs before refreshDiagnostics(), which is the critical behavior being tested. Replace the separate verify statements with Mockito's InOrder verifier to assert the correct execution sequence: first clearDiagnostics() on openedA and openedB, then refreshDiagnostics() on languageClient. This ensures the test validates the ordering requirement, not just the fact that both methods are called.
🤖 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/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProviderTest.java`:
- Around line 242-245: The test verifies that clearDiagnostics() and
refreshDiagnostics() are called but does not enforce that clearDiagnostics()
occurs before refreshDiagnostics(), which is the critical behavior being tested.
Replace the separate verify statements with Mockito's InOrder verifier to assert
the correct execution sequence: first clearDiagnostics() on openedA and openedB,
then refreshDiagnostics() on languageClient. This ensures the test validates the
ordering requirement, not just the fact that both methods are called.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: e4411ac7-52c1-498f-b70f-57474e8086b3
📒 Files selected for processing (2)
src/main/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProvider.javasrc/test/java/com/github/_1c_syntax/bsl/languageserver/providers/DiagnosticProviderTest.java
|



Summary
После наполнения контекста сервера (
ServerContextPopulatedEvent) межфайловые диагностики открытых документов (UnusedLocalMethod,EventHandler*, обращения к общим модулям и т.п.) могут устареть, поэтому мы шлём pull-клиенту (VSCode 1.94+ сrefreshSupport) запросworkspace/diagnostic/refresh. Однако в pull-ветке мы не сбрасывалиLazy<List<Diagnostic>>-кэш вDocumentContext. Клиент перезапрашивал черезtextDocument/diagnostic→DiagnosticProvider.getDiagnostic(...)→documentContext.getDiagnostics()→Lazy.getOrCompute()возвращал закэшированное значение, посчитанное до наполнения контекста.Симптом: диагностики «висят» в редакторе до переоткрытия файла (
didOpen→rebuildDocumentсбрасывает кэш). Раньше работало, потому что push-ветка чистила кэш — но для pull-клиента она не выполняется.clearDiagnostics()теперь вызывается до выбора ветки — кэш сбрасывается одинаково для pull- и push-клиента, refresh уходит уже после.Test plan
DiagnosticProviderTest.testServerContextPopulatedClearsCachedDiagnosticsForPullClient— проверяет что при pull-клиенте передrefreshDiagnostics()зовётсяclearDiagnostics()на каждом открытом документе.testServerContextPopulatedRequestsRefreshWhenClientSupportsRefresh/testServerContextPopulatedDoesNotRequestRefreshWhenClientDoesNotSupportRefreshостаются зелёными..bsl-файл во время индексации, дождаться завершенияpopulateContext: диагностики переактуализируются без необходимости переоткрывать файл.Summary by CodeRabbit