Class AssignToReadOnlyPropertyDiagnostic

All Implemented Interfaces:
BSLDiagnostic, BSLParserVisitor<ParseTree>, ParseTreeVisitor<ParseTree>

@DiagnosticMetadata(type=ERROR, severity=MAJOR, minutesToFix=5, tags=SUSPICIOUS) public class AssignToReadOnlyPropertyDiagnostic extends AbstractVisitorDiagnostic
Подсвечивает присваивание значению в свойство, у которого режим доступа — AccessMode.READ.

Источник информации о режиме доступа — синтакс-помощник платформы 1С (через bsl-context) или JSON-fallback. Метаданные пробрасываются платформенным провайдером в MemberDescriptor.metadata() и индексируются TypeRegistry.indexMemberMetadata(TypeRef, Collection) как пары (тип-владелец, имя свойства), что позволяет быстро отфильтровать безопасные присваивания.

Поток:

  1. TypeRegistry.hasAnyReadOnlyMember() — глобальный гейт. Без HBK / без accessMode-данных диагностика моментально no-op.
  2. TypeService.memberAt(com.github._1c_syntax.bsl.languageserver.context.DocumentContext, Position) — точный резолв member'а с учётом инференции типа ресивера (глобальное свойство, локальная переменная, цепочка аксессоров). Резолв bilingual: read-only находится независимо от того, на каком языке (ru/en) записано имя свойства.
  3. Финальная проверка member.metadata().accessMode() == READ.

Pre-filter по имени свойства намеренно отсутствует: одно и то же имя (например, Ссылка) может быть read-only на одном типе и read-write на другом, поэтому решение принимается только по резолвленному member'у конкретного типа-владельца.

Lock contention. Раньше шаг 3 (memberAt → ExpressionTypeInferencer → ReferenceResolver → ServerContextProvider.getDocument) брал per-document RWLock и конкурировал с populateContext (там WRITE). Сейчас reference-finder'ы переведены на getDocumentNoLock (см. com.github._1c_syntax.bsl.languageserver.references), поэтому диагностика безопасно работает в фазу populate.