From 72d6d474541f4ca41e51d638d1e845284e626ae5 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Fri, 3 Jul 2026 14:58:00 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-compile,meta-decompile):=20=D0=BC?= =?UTF-8?q?=D1=83=D0=BB=D1=8C=D1=82=D0=B8=D1=8F=D0=B7=D1=8B=D1=87=D0=BD?= =?UTF-8?q?=D1=8B=D0=B9=20=D1=81=D0=B8=D0=BD=D0=BE=D0=BD=D0=B8=D0=BC=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=B0=20+=20=D1=82=D0=B5?= =?UTF-8?q?=D1=80=D0=BC=D0=B8=D0=BD=D0=BE=D0=BB=D0=BE=D0=B3=D0=B8=D1=8F=20?= =?UTF-8?q?spec=20(v1.22/v0.7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раундтрип-находка: синоним САМОГО объекта (уровня справочника) мультиязычен у 950 справочников корпуса (все erp: ru+en), но компилятор стрингифаил его ($synonym → ru-only), декомпилятор брал Get-MLru (ru-only) → потеря en. - meta-compile (дуал-порт): $synonym/synonym пробрасывается без стрингификации (строка ИЛИ {ru,en}) → Emit-MLText (уже мультиязычный). Гард на плоском Description-fallback (ScheduledJob) для не-строки. - meta-decompile: синоним объекта через Get-MLValue (строка ru | {ru,en}). - spec: терминология «каталог» → «справочник» (тип Catalog = Справочник; файловая директория не тронута). Валидация: PS==PY; byte-match erp-справочника; −3772 (93459→89687); регресс 37/37; 1С-cert зелёный. Остаток item/ToolTip того уровня — синоним/подсказка ТЧ + xr:ToolTip станд. реквизита (следующие заходы). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/meta-compile/scripts/meta-compile.ps1 | 7 ++++--- .claude/skills/meta-compile/scripts/meta-compile.py | 6 ++++-- .claude/skills/meta-decompile/scripts/meta-decompile.ps1 | 8 +++++--- docs/meta-dsl-spec.md | 6 +++--- tests/skills/cases/meta-compile/catalog-attr-ml.json | 1 + .../snapshots/catalog-attr-ml/Catalogs/Контрагенты.xml | 4 ++++ 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 6db2c78d..aaecc5f4 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -382,8 +382,8 @@ function Split-CamelCase { return $result } -# Auto-synonym -$synonym = if ($def.synonym) { "$($def.synonym)" } else { Split-CamelCase $objName } +# Auto-synonym. Проброс без стрингификации (строка ИЛИ {ru,en} — мультиязычный синоним объекта). +$synonym = if ($null -ne $def.synonym) { $def.synonym } else { Split-CamelCase $objName } $comment = if ($def.comment) { "$($def.comment)" } else { "" } # --- 4. Type system --- @@ -1755,7 +1755,8 @@ function Emit-ScheduledJobProperties { } X "$i$(Esc-Xml $methodName)" - $description = if ($def.description) { "$($def.description)" } else { $synonym } + # $synonym может быть {ru,en}; здесь Description — плоская строка, берём ru-текст. + $description = if ($def.description) { "$($def.description)" } elseif ($synonym -is [string]) { $synonym } else { "" } X "$i$(Esc-Xml $description)" $key = if ($def.key) { "$($def.key)" } else { "" } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 424d2bf1..6bdb6ad0 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -426,7 +426,8 @@ if not defn.get('name'): obj_name = str(defn['name']) # Auto-synonym -synonym = str(defn['synonym']) if defn.get('synonym') else split_camel_case(obj_name) +# Проброс без стрингификации (строка ИЛИ {ru,en} — мультиязычный синоним объекта). +synonym = defn['synonym'] if defn.get('synonym') is not None else split_camel_case(obj_name) comment = str(defn['comment']) if defn.get('comment') else '' # --------------------------------------------------------------------------- @@ -1619,7 +1620,8 @@ def emit_scheduled_job_properties(indent): if method_name and not method_name.startswith('CommonModule.'): method_name = f'CommonModule.{method_name}' X(f'{i}{esc_xml(method_name)}') - description = str(defn['description']) if defn.get('description') else synonym + # synonym может быть {ru,en}; Description — плоская строка, берём ru-текст. + description = str(defn['description']) if defn.get('description') else (synonym if isinstance(synonym, str) else '') X(f'{i}{esc_xml(description)}') key = str(defn['key']) if defn.get('key') else '' X(f'{i}{esc_xml(key)}') diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 index cbf6e1ac..83d8a92a 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 @@ -1,4 +1,4 @@ -# meta-decompile v0.6 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.7 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только @@ -237,8 +237,10 @@ function Attr-ToDsl { # === Сборка DSL === $dsl = [ordered]@{ type = 'Catalog'; name = $objName } -$syn = Get-MLru ($props.SelectSingleNode('md:Synonym', $nsm)) -if ($syn -and $syn -ne (Split-CamelWords $objName)) { $dsl['synonym'] = $syn } +# Синоним объекта: строка ru-only ИЛИ {ru,en} (мультиязычно). Кастом → эмитим. +$synVal = Get-MLValue ($props.SelectSingleNode('md:Synonym', $nsm)) +if ($synVal -is [string]) { if ($synVal -ne (Split-CamelWords $objName)) { $dsl['synonym'] = $synVal } } +elseif ($null -ne $synVal) { $dsl['synonym'] = $synVal } $cmt = P 'Comment'; if ($cmt) { $dsl['comment'] = $cmt } # Свойства Catalog (omit-on-default). Порядок ключей — как удобно DSL. diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index 87de4782..0b95aeaf 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -149,7 +149,7 @@ JSON DSL для описания объектов метаданных конф | `createOnInput` | CreateOnInput | Auto | Auto/Use/DontUse | | `quickChoice` | QuickChoice | Auto | Auto/Use/DontUse. Прощаем bool (форм-стиль): `true`→Use, `false`→DontUse | | `dataHistory` | DataHistory | Use | Use/DontUse | -| `use` | Use | ForItem | ForItem/ForFolderAndItem/ForFolder (иерарх. каталог) | +| `use` | Use | ForItem | ForItem/ForFolderAndItem/ForFolder (иерарх. справочник) | | `passwordMode` | PasswordMode | false | bool | | `mask` | Mask | пусто | строка маски | | `format` / `editFormat` | Format / EditFormat | пусто | строка/`{ru,en}` (ML, форматная строка 1С) | @@ -268,7 +268,7 @@ JSON DSL для описания объектов метаданных конф Блок `` платформа материализует **только когда пользователь кастомизировал хотя бы один стандартный реквизит** (Наименование/Код/Владелец/…). Ни иерархия, ни владелец, ни предопределённые сами по себе блок не создают. В DSL это выражается **наличием ключа `standardAttributes`**: -- **Ключа нет** → блок не эмитится (обычный каталог: Наименование, Код, Владелец и т.д. остаются платформенными по умолчанию). +- **Ключа нет** → блок не эмитится (обычный справочник: Наименование, Код, Владелец и т.д. остаются платформенными по умолчанию). - **Ключ есть** (даже пустой `{}`) → эмитится полный блок из всех стандартных реквизитов с **профилем материализованного блока**, поверх которого накладываются заданные переопределения. Формат: `standardAttributes` — объект `{ ИмяРеквизита: { переопределения } }`. Имена реквизитов — как в XML: `PredefinedDataName`, `Predefined`, `Ref`, `DeletionMark`, `IsFolder`, `Owner`, `Parent`, `Description`, `Code`. @@ -334,7 +334,7 @@ JSON DSL для описания объектов метаданных конф "childItems": [ "Факс", "(7) Скайп [Скайп]" ] } ``` -Тип кода в XML определяется свойством каталога `codeType`: `Number` → ``, `String` → `` (без типа); пустой код → ``. +Тип кода в XML определяется свойством справочника `codeType`: `Number` → ``, `String` → `` (без типа); пустой код → ``. > Пока поддержано для **Catalog** (`CatalogPredefinedItems`). ChartOf*/ПВХ — при их проработке. diff --git a/tests/skills/cases/meta-compile/catalog-attr-ml.json b/tests/skills/cases/meta-compile/catalog-attr-ml.json index 51bb479b..10f1a04d 100644 --- a/tests/skills/cases/meta-compile/catalog-attr-ml.json +++ b/tests/skills/cases/meta-compile/catalog-attr-ml.json @@ -2,6 +2,7 @@ "name": "Справочник с ML-синонимом и подсказкой реквизита", "input": { "type": "Catalog", "name": "Контрагенты", + "synonym": { "ru": "Контрагенты", "en": "Counterparties" }, "attributes": [ { "name": "ИНН", "type": "String(12)", "synonym": { "ru": "ИНН", "en": "TIN" }, "tooltip": "Идентификационный номер налогоплательщика" }, { "name": "Комментарий", "type": "String(200)", "tooltip": { "ru": "Произвольный комментарий", "en": "Free-form comment" } } diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-attr-ml/Catalogs/Контрагенты.xml b/tests/skills/cases/meta-compile/snapshots/catalog-attr-ml/Catalogs/Контрагенты.xml index cf2a78f2..aabf9db8 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-attr-ml/Catalogs/Контрагенты.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-attr-ml/Catalogs/Контрагенты.xml @@ -30,6 +30,10 @@ ru Контрагенты + + en + Counterparties + false