feat(meta-compile,meta-decompile): состав плана обмена — Content.xml (v1.42/v0.31)

Соседний Ext/Content.xml (состав плана обмена: объекты-участники + признак
авторегистрации) был вне скоупа раундтрипа → при декомпиляции→компиляции состав
терялся (компилятор писал пустой <ExchangePlanContent/>, декомпилятор не захватывал).

DSL content/Состав: массив MDObjectRef — строка "Type.Name" (AutoRecord=Deny,
дефолт) / "Type.Name: autoRecord" (Allow; токен-признак autoRecord/АвтоРегистрация,
регистронезав.; прощающе : Allow/: Разрешить) ЛИБО объект {metadata, autoRecord:
bool|Allow/Deny/Разрешить/Запретить} (синонимы Метаданные/объект, АвтоРегистрация).
Декомпилятор пишет короткую строковую форму.

Class-2 фикс заголовка: пустой <ExchangePlanContent/> писался с 2 namespace,
реальный 1С — с 4 (+xmlns:xs/xsi); чинил и пустой шаблон.

Роундтрип 42 ЭП (acc+erp): match 39/42, TOTAL 146 без новых диффов (остаток —
известный хвост TS-LineNumber/FillValue-пробелы). Регресс 48/48 ps1+py, ps1↔py
identical. 1С-cert ✓ (пустой 4-ns корень + непустой состав); verify-snapshots
расширен: getStructuralDeps стабит объекты состава ЭП по MDObjectRef + стаб Constant.
spec §7.2a, кейс exchange-plan-content.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-06 12:55:08 +03:00
parent 126ce0bbd8
commit 11e7abfc3f
13 changed files with 567 additions and 9 deletions
+15 -1
View File
@@ -619,6 +619,20 @@ omit-on-empty. Поля пишутся частичной формой (`Standar
ключ `standardAttributes`. Опциональный легаси-реквизит `ExchangeDate` (часть планов) поддержан как «доп.» член
`standardAttributes` (эмитится по факту наличия ключа, вне фикс-списка).
**Состав плана обмена** (`content`, синоним `Состав`) — соседний `Ext/Content.xml`: список объектов-участников обмена,
у каждого признак авторегистрации изменений на узле (AutoRecord: `Deny`=запрещена, дефолт; `Allow`=разрешена). Элемент —
MDObjectRef (`Catalog.X`/`Document.Y`/`InformationRegister.Z`/`Constant.W`/…), пишется verbatim.
| Форма записи | Смысл |
|--------------|-------|
| `"Catalog.Организации"` | AutoRecord=Deny (авторегистрация выкл — дефолт) |
| `"InformationRegister.Курсы: autoRecord"` | AutoRecord=Allow — токен-признак `autoRecord`/`АвтоРегистрация` (регистронезависимо; принимается и `: Allow`/`: Разрешить`) |
| `{ "metadata": "Document.РеализацияТоваров", "autoRecord": true }` | объектная форма: `autoRecord` — boolean (`true`=Allow) ИЛИ строка `Allow`/`Deny`/`Разрешить`/`Запретить` |
Синонимы ключей объектной формы: `metadata` → `Метаданные`/`объект`, `autoRecord` → `АвтоРегистрация`. Дефолт `Deny` в
строке опускается. Пустой/отсутствующий `content` → пустой `<ExchangePlanContent/>`. Декомпилятор пишет короткую строковую
форму (`"Ref"` для Deny, `"Ref: autoRecord"` для Allow). Порядок элементов платформенно-произвольный (1С толерантна).
### 7.2b ChartOfCharacteristicTypes (План видов характеристик)
Иерархический ссылочный тип (папки+элементы, без уровней/подчинения). Общий с Catalog слой: `synonym`, `comment`,
@@ -924,7 +938,7 @@ Split-CamelCase имени.
| `tabularSections` | `{}` | → TabularSection в ChildObjects |
Модули: `Ext/ObjectModule.bsl` (пустой).
Дополнительно: `Ext/Content.xml` (пустой шаблон).
Дополнительно: `Ext/Content.xml` — состав плана обмена (ключ `content`/`Состав`, см. §7.2a; пустой, если не задан).
```json
{ "type": "ExchangePlan", "name": "ОбменССайтом", "attributes": ["АдресСервера: String(200)"] }