Skip to content

ReferenceIndex не очищается при ServerContext.clear(): осиротевшие вхождения ломают индексные диагностики в батч-режиме (сонар-плагин) #4265

Description

@sfaqer

Описание

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 достаёт вперемешку свежие и осиротевшие вхождения:

  1. Для осиротевшего вхождения buildReferencegetFromSymbolgetDocument(uri первой группы)null (документ удалён clear()) → .orElseThrow()NoSuchElementException;
  2. DiagnosticComputer перехватывает исключение per-diagnostic («Diagnostic computation error» в лог, пустой результат) ⇒ все срабатывания индексной диагностики (UnusedLocalVariable и др.) по файлу молча выпадают из скана — в SonarQube ишьюсы «закрываются», в следующем скане (набор осиротевших ключей изменился после коммита в соседний каталог) — «открываются» заново;
  3. Побочно: осиротевшее 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions