From 7cf910396beff2436fe9c4fd8e7e2446c8079d1f Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Fri, 3 Jul 2026 21:46:14 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-compile):=20=D0=BA=D0=BE=D1=80=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=D1=8F=20=D0=B7=D0=B0=D0=BF=D0=B8=D1=81=D1=8C?= =?UTF-8?q?=20dataPath=20=D0=B2=20linkByType/choiceParameterLinks=20(v1.23?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dataPath ссылается на реквизит самого объекта — прощающий ввод (компилятор разворачивает по $objType/$objName): • стандартный (Ссылка/Ref, Наименование/Description, Владелец/Owner, …) → <Тип>.<Имя>.StandardAttribute. (RU→EN); • обычный (Свойство) → <Тип>.<Имя>.Attribute.Свойство; • частичное StandardAttribute.X/Attribute.X → +префикс; полный путь → verbatim. Только компилятор (декомпилятор пишет полный путь) → роундтрип не затронут (remaining=0 сохраняется). Кейсы choice-params/typeset-linkbytype переведены на короткую запись (снэпшоты идентичны). Регресс 43/43 ps1+py, ps1↔py identical. spec §4.2. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../meta-compile/scripts/meta-compile.ps1 | 34 +++++++++++++++- .../meta-compile/scripts/meta-compile.py | 39 ++++++++++++++++++- docs/meta-dsl-spec.md | 6 +++ .../catalog-attr-choice-params.json | 4 +- .../catalog-attr-typeset-linkbytype.json | 4 +- 5 files changed, 79 insertions(+), 8 deletions(-) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index a754317c..5951d508 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -1,4 +1,4 @@ -# meta-compile v1.22 — Compile 1C metadata object from JSON +# meta-compile v1.23 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1138,6 +1138,35 @@ $script:reservedByContext = @{ "document" = @("Ref","DeletionMark","Date","Number","Posted") } +# Стандартный реквизит текущего типа по имени (EN/RU) → EN-имя, либо $null (обычный/неизвестный). +function Resolve-StdAttrEn { + param([string]$name) + $ctx = switch ("$objType") { 'Catalog' { 'catalog' } 'Document' { 'document' } default { $null } } + if (-not $ctx) { return $null } + $stdSet = $script:reservedByContext[$ctx] + foreach ($en in $stdSet) { + $ru = $script:reservedAttrNames[$en] + if (($name -ieq $en) -or ($ru -and $name -ieq $ru)) { return $en } + } + return $null +} + +# Прощающий ввод пути к реквизиту САМОГО объекта (dataPath в linkByType/choiceParameterLinks): +# "Ссылка"/"Ref"/станд. → <Тип>.<Имя>.StandardAttribute.; обычное имя → <Тип>.<Имя>.Attribute.<Имя>; +# частичное "StandardAttribute.X"/"Attribute.X" → префикс <Тип>.<Имя>; полный путь → verbatim. +function Expand-DataPath { + param([string]$dp) + if (-not $dp) { return $dp } + $s = "$dp" + if ($s -match '^(StandardAttribute|Attribute)\.') { return "$objType.$objName.$s" } + if (-not $s.Contains('.')) { + $en = Resolve-StdAttrEn $s + if ($en) { return "$objType.$objName.StandardAttribute.$en" } + return "$objType.$objName.Attribute.$s" + } + return $s +} + # (связь по типу — тип значения реквизита-Характеристики определяется другим реквизитом). # Структура как формы: DataPath + LinkItem. DSL `linkByType`: {dataPath, linkItem?} ИЛИ строка-путь. # Нет ключа → (пусто). @@ -1150,6 +1179,7 @@ function Emit-LinkByType { $li = if ($null -ne $spec.linkItem) { $spec.linkItem } elseif ($null -ne $spec.элементСвязи) { $spec.элементСвязи } else { 0 } } if (-not $dp) { X "$indent"; return } + $dp = Expand-DataPath $dp X "$indent" X "$indent`t$(Esc-Xml "$dp")" X "$indent`t$li" @@ -1264,7 +1294,7 @@ function Emit-ChoiceParameterLinks { foreach ($lk in @($cpl)) { if ($lk -is [string]) { $lk = ConvertFrom-ChLinkShorthand $lk } $name = Get-ChElProp $lk @('name','имя') - $dp = Get-ChElProp $lk @('dataPath','path','путь') + $dp = Expand-DataPath (Get-ChElProp $lk @('dataPath','path','путь')) $vcRaw = Get-ChElProp $lk @('valueChange','режимИзменения') $vc = 'Clear' if ($vcRaw) { diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 010b4944..1389eb8c 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-compile v1.22 — Compile 1C metadata object from JSON +# meta-compile v1.23 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -1180,6 +1180,40 @@ RESERVED_BY_CONTEXT = { }, } +# Стандартные реквизиты по типу для разворота dataPath: [(EN, RU), ...]. +STD_ATTR_BY_TYPE = { + 'Catalog': [('Ref', 'Ссылка'), ('DeletionMark', 'ПометкаУдаления'), ('Predefined', 'Предопределенный'), + ('PredefinedDataName', 'ИмяПредопределенныхДанных'), ('Code', 'Код'), ('Description', 'Наименование'), + ('Owner', 'Владелец'), ('Parent', 'Родитель'), ('IsFolder', 'ЭтоГруппа')], + 'Document': [('Ref', 'Ссылка'), ('DeletionMark', 'ПометкаУдаления'), ('Date', 'Дата'), ('Number', 'Номер'), + ('Posted', 'Проведен')], +} + +def resolve_std_attr_en(name): + pairs = STD_ATTR_BY_TYPE.get(obj_type) + if not pairs: + return None + low = name.lower() + for en, ru in pairs: + if low == en.lower() or low == ru.lower(): + return en + return None + +def expand_data_path(dp): + """Путь к реквизиту самого объекта: "Ссылка"→<Тип>.<Имя>.StandardAttribute.Ref; обычное имя→.Attribute.имя; + частичное StandardAttribute.X/Attribute.X→префикс; полный путь→verbatim.""" + if not dp: + return dp + s = str(dp) + if re.match(r'^(StandardAttribute|Attribute)\.', s): + return f'{obj_type}.{obj_name}.{s}' + if '.' not in s: + en = resolve_std_attr_en(s) + if en: + return f'{obj_type}.{obj_name}.StandardAttribute.{en}' + return f'{obj_type}.{obj_name}.Attribute.{s}' + return s + def emit_link_by_type(indent, spec): """ (связь по типу): DataPath + LinkItem. spec — {dataPath, linkItem?} или строка-путь; нет → .""" if not spec: @@ -1197,6 +1231,7 @@ def emit_link_by_type(indent, spec): if not dp: X(f'{indent}') return + dp = expand_data_path(dp) X(f'{indent}') X(f'{indent}\t{esc_xml(str(dp))}') X(f'{indent}\t{li}') @@ -1311,7 +1346,7 @@ def emit_choice_parameter_links(indent, cpl): if isinstance(lk, str): lk = convert_from_ch_link_shorthand(lk) name = ch_el_prop(lk, ['name', 'имя']) - dp = ch_el_prop(lk, ['dataPath', 'path', 'путь']) + dp = expand_data_path(ch_el_prop(lk, ['dataPath', 'path', 'путь'])) vc_raw = ch_el_prop(lk, ['valueChange', 'режимИзменения']) vc = 'Clear' if vc_raw: diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index fd74f360..35d406c5 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -152,6 +152,12 @@ JSON DSL для описания объектов метаданных конф | `fillValue` | FillValue | по типу (см. ниже) | значение заполнения — bool/число/строка/дата/DTR-путь; `null` → nil | | `linkByType` | LinkByType | пусто | связь по типу: `{dataPath, linkItem?}` ИЛИ строка-путь (linkItem=0). Тип значения реквизита-Характеристики берётся из реквизита по `dataPath` | | `choiceParameterLinks` | ChoiceParameterLinks | пусто | связи параметров выбора: массив `{name, dataPath, valueChange?}` ИЛИ строк `"name=dataPath[:DontChange]"`. valueChange по умолч. `Clear` | + +`dataPath` (в `linkByType` и `choiceParameterLinks`) ссылается на реквизит **самого объекта** — прощающий ввод: +- стандартный реквизит: `Ссылка`/`Ref`, `Наименование`/`Description`, `Код`/`Code`, `Владелец`/`Owner`, … → + `<Тип>.<Имя>.StandardAttribute.`; +- обычный реквизит: имя (`Свойство`) → `<Тип>.<Имя>.Attribute.Свойство`; +- частичное `StandardAttribute.X` / `Attribute.X` → добавит префикс `<Тип>.<Имя>`; полный путь — как есть. | `choiceParameters` | ChoiceParameters | пусто | параметры выбора: массив `{name, value?}` ИЛИ строк `"name=value"`. value — bool/число/строка/DTR-путь ИЛИ массив (→ FixedArray); без value → nil | | `createOnInput` | CreateOnInput | Auto | Auto/Use/DontUse | | `quickChoice` | QuickChoice | Auto | Auto/Use/DontUse. Прощаем bool (форм-стиль): `true`→Use, `false`→DontUse | diff --git a/tests/skills/cases/meta-compile/catalog-attr-choice-params.json b/tests/skills/cases/meta-compile/catalog-attr-choice-params.json index 5daa3130..e233dc14 100644 --- a/tests/skills/cases/meta-compile/catalog-attr-choice-params.json +++ b/tests/skills/cases/meta-compile/catalog-attr-choice-params.json @@ -5,13 +5,13 @@ "name": "ТестВыбора", "attributes": [ { "name": "Счет", "type": "CatalogRef.БанковскиеСчета", - "choiceParameterLinks": [ { "name": "Отбор.Владелец", "dataPath": "Catalog.ТестВыбора.StandardAttribute.Ref", "valueChange": "Clear" } ] }, + "choiceParameterLinks": [ { "name": "Отбор.Владелец", "dataPath": "Ссылка", "valueChange": "Clear" } ] }, { "name": "Партнер", "type": "CatalogRef.Партнеры", "choiceParameters": "Отбор.ЭтоГруппа=false" }, { "name": "ТипТТН", "type": "CatalogRef.ВидыТранспорта", "choiceParameters": [ { "name": "Отбор.Тип", "value": ["Enum.ТипыВЕТИС.EmptyRef", "Enum.ТипыВЕТИС.EnumValue.ТТН"] } ] }, { "name": "Валюта", "type": "CatalogRef.Валюты", - "choiceParameterLinks": "Отбор.Владелец=Catalog.ТестВыбора.StandardAttribute.Ref" } + "choiceParameterLinks": "Отбор.Владелец=Ссылка" } ] }, "validatePath": "Catalogs/ТестВыбора", diff --git a/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json b/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json index aa893268..d35a7df2 100644 --- a/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json +++ b/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json @@ -6,10 +6,10 @@ "attributes": [ { "name": "Свойство", "type": "ChartOfCharacteristicTypesRef.ДополнительныеРеквизиты" }, { "name": "Значение", "type": "Characteristic.ДополнительныеРеквизиты", - "linkByType": { "dataPath": "Catalog.ТестХарактеристик.Attribute.Свойство", "linkItem": 1 } }, + "linkByType": { "dataPath": "Свойство", "linkItem": 1 } }, { "name": "ЗначениеОпредТип", "type": "DefinedType.Сумма" }, { "name": "СвязьСтрокой", "type": "Characteristic.ВидыСубконто", - "linkByType": "Catalog.ТестХарактеристик.Attribute.Свойство" } + "linkByType": "Свойство" } ] }, "validatePath": "Catalogs/ТестХарактеристик",