feat(cfe-borrow,cfe-patch-method,cfe-validate): модули заимствованных объектов и пометка расширенного свойства

Объект заимствуют, чтобы дописать в него модуль, — теперь пустой файл модуля создаётся
навыком, а не руками. Тип с единственным модулем (CommonModule, HTTPService, WebService)
получает его без указаний, остальные — по -Module; -Module None отменяет. Существующий
файл не перезаписывается никогда.

Вместе с файлом проставляется <xr:PropertyState> со State=Extended. Замер по лестнице
платформ 8.3.20…8.5.1: элемент появился в формате 2.19 (8.3.26), ниже платформа молча
выбрасывает его при загрузке — отсюда гейт по версии формата. Имя свойства равно базовому
имени файла модуля, у заимствованной формы — Form. Правило владения одно: пометку ставит
тот, кто создал файл, поэтому её ставит и cfe-patch-method.

Заодно закрыта перезапись при повторном заимствовании: прямая ветка писала XML уже
заимствованного объекта начисто, унося собственные реквизиты расширения и регистрацию
формы, — молча, с успешным отчётом. Повторный вызов теперь безопасен и служит способом
дозаимствовать модуль.

cfe-validate сверяет «файл модуля ↔ пометка» в обе стороны (предупреждение: перекос
платформа принимает, но выгрузка Конфигуратора так не выглядит).

Проверено: полный регресс 827/0/8 (ps1) и 824/0/11 (py), гарды 5/5, сквозной раундтрип
на 8.3.26 и 8.3.27 — InternalInfo совпадает с выгрузкой платформы.

Закрывает #70. Разбор и эталоны выгрузки — Romandredan.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-17 20:59:39 +03:00
co-authored by Claude Opus 5
parent 89f65ca6a6
commit 8fe727e32f
112 changed files with 5045 additions and 38 deletions
+25
View File
@@ -662,6 +662,31 @@ Form.xml заимствованной формы — **двухчастный ф
|----------|----------|
| `Notify` | Свойство изменено расширением, платформа выводит предупреждение |
| `MultiState` | Свойство расширено (тип отличается от основной конфигурации) |
| `Extended` | Свойство расширено: у объекта появился модуль или изменена форма |
#### Extended — модули и формы заимствованных объектов
`Extended` стоит на самом заимствованном объекте (а не на реквизите) и означает, что расширение
принесло содержимое свойства. Имя свойства совпадает с **базовым именем файла модуля**:
| Файл в расширении | `xr:Property` |
|-------------------|---------------|
| `Ext/Module.bsl` (общий модуль, HTTP- и web-сервис) | `Module` |
| `Ext/ObjectModule.bsl` | `ObjectModule` |
| `Ext/ManagerModule.bsl` | `ManagerModule` |
| `Ext/RecordSetModule.bsl` | `RecordSetModule` |
| `Ext/ValueManagerModule.bsl` | `ValueManagerModule` |
| `Commands/<Имя>/Ext/CommandModule.bsl` | `CommandModule` — на вложенном `<Command>`, не у владельца |
| заимствованная форма | `Form` — в метаданных формы |
Порядок внутри `InternalInfo`: после всех `xr:GeneratedType`, сначала «объектный» модуль
(`ObjectModule` / `RecordSetModule` / `ValueManagerModule`), затем `ManagerModule`.
**Версионность.** Элемент появился в версии формата **2.19 (8.3.26)**. На 2.18 и ниже платформа
молча выбрасывает его при загрузке. Начиная с 2.19 Конфигуратор проставляет пометку сам при
выгрузке — триггером служит наличие файла модуля, даже пустого; заимствованный объект без модуля
её не получает. Расхождение (файл без пометки или пометка без файла) платформа принимает без
ошибок, но выгрузка Конфигуратора так не выглядит.
### 6.2. ExtendedProperty — расширение типа