Описание
ReferenceIndex не очищается при ServerContext.clear(): события «контекст очищен» не существует, ReferenceIndexFiller слушает только per-document ServerContextDocumentRemovedEvent. Все occurrences очищенного контекста остаются в индексе.
Проявляется в батч-режиме сонар-плагина: BSLCoreSensor.execute обрабатывает группы source-каталогов последовательно на одном Spring-контексте (BSLLSBinding — один ServerContext/ReferenceIndex на JVM сканера), вызывая bslServerContext.clear() после каждой группы. Вторая группа анализируется поверх «осиротевших» occurrences первой.
Механизм ложных результатов
Ключ индекса — (mdoRef, moduleType, scopeName, symbolName), mdoRef конфигурационно-относительный («Справочник.Х.МодульОбъекта»). При нескольких каталогах с пересекающимися mdoRef (основная конфигурация + расширения, демо-база, копии/фикстуры в sonar.tests) ключи групп совпадают, и во второй группе getReferencesTo достаёт вперемешку свежие и осиротевшие вхождения:
- Для осиротевшего вхождения
buildReference → getFromSymbol → getDocument(uri первой группы) → null (документ удалён clear()) → .orElseThrow() → NoSuchElementException;
DiagnosticComputer перехватывает исключение per-diagnostic («Diagnostic computation error» в лог, пустой результат) ⇒ все срабатывания индексной диагностики (UnusedLocalVariable и др.) по файлу молча выпадают из скана — в SonarQube ишьюсы «закрываются», в следующем скане (набор осиротевших ключей изменился после коммита в соседний каталог) — «открываются» заново;
- Побочно: осиротевшее REFERENCE-вхождение по совпавшему ключу маскирует реально неиспользуемую переменную (false negative).
Проверяемые следствия: в логе сканера есть Diagnostic computation error … UnusedLocalVariable; мигают синхронно и другие индексные диагностики; проекты с одним source-каталогом этим механизмом не затронуты.
Предлагаемое исправление
Симметрично событийной модели: публиковать через AOP (EventPublisherAspect) событие очистки контекста сервера при вызове ServerContext.clear() и в ReferenceIndexFiller сбрасывать индекс целиком (после #4261 — также отпечатки контента filledContentFingerprints). Проверить аналогичную потребность у остальных подписчиков жизненного цикла документов (types/-индексы и т.п.).
Контекст
Разбор в обсуждении PR #4261: #4261 (comment)
Затронуты все версии с reference-индексом; проверено по v0.29.0 (бандлится в sonar-bsl-plugin-community v1.18.1) и текущему develop.
Описание
ReferenceIndexне очищается приServerContext.clear(): события «контекст очищен» не существует,ReferenceIndexFillerслушает только per-documentServerContextDocumentRemovedEvent. Все occurrences очищенного контекста остаются в индексе.Проявляется в батч-режиме сонар-плагина:
BSLCoreSensor.executeобрабатывает группы source-каталогов последовательно на одном Spring-контексте (BSLLSBinding— одинServerContext/ReferenceIndexна JVM сканера), вызываяbslServerContext.clear()после каждой группы. Вторая группа анализируется поверх «осиротевших» occurrences первой.Механизм ложных результатов
Ключ индекса —
(mdoRef, moduleType, scopeName, symbolName), mdoRef конфигурационно-относительный («Справочник.Х.МодульОбъекта»). При нескольких каталогах с пересекающимися mdoRef (основная конфигурация + расширения, демо-база, копии/фикстуры вsonar.tests) ключи групп совпадают, и во второй группеgetReferencesToдостаёт вперемешку свежие и осиротевшие вхождения:buildReference→getFromSymbol→getDocument(uri первой группы)→null(документ удалёнclear()) →.orElseThrow()→NoSuchElementException;DiagnosticComputerперехватывает исключение per-diagnostic («Diagnostic computation error» в лог, пустой результат) ⇒ все срабатывания индексной диагностики (UnusedLocalVariableи др.) по файлу молча выпадают из скана — в SonarQube ишьюсы «закрываются», в следующем скане (набор осиротевших ключей изменился после коммита в соседний каталог) — «открываются» заново;Проверяемые следствия: в логе сканера есть
Diagnostic computation error … UnusedLocalVariable; мигают синхронно и другие индексные диагностики; проекты с одним source-каталогом этим механизмом не затронуты.Предлагаемое исправление
Симметрично событийной модели: публиковать через AOP (
EventPublisherAspect) событие очистки контекста сервера при вызовеServerContext.clear()и вReferenceIndexFillerсбрасывать индекс целиком (после #4261 — также отпечатки контентаfilledContentFingerprints). Проверить аналогичную потребность у остальных подписчиков жизненного цикла документов (types/-индексы и т.п.).Контекст
Разбор в обсуждении PR #4261: #4261 (comment)
Затронуты все версии с reference-индексом; проверено по v0.29.0 (бандлится в sonar-bsl-plugin-community v1.18.1) и текущему develop.