From 8ac0dfefd051a9a774b2016db71acbd3f55bea58 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 8 Jun 2026 18:52:46 +0300 Subject: [PATCH] =?UTF-8?q?feat(form-decompile,form-compile):=20valueType?= =?UTF-8?q?=20=E2=80=94=20=D0=BF=D1=83=D1=81=D1=82=D0=BE=D0=B9=20Settings?= =?UTF-8?q?=20(=D1=81=D0=BF=D0=B8=D1=81=D0=BE=D0=BA=20=D0=B1=D0=B5=D0=B7?= =?UTF-8?q?=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D1=82=D0=B8=D0=BF=D0=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Пустой у ValueList (список без ограничения типа) — частый случай (в корпусе пустых 1893 vs непустых 864). Три состояния valueType: нет ключа → нет Settings; "" → пустой ; тип → с типом. Компилятор эмитит по присутствию ключа (включая ""); декомпилятор для пустого Settings пишет маркер "". (ValueList без Settings вовсе — 58%, без ключа valueType.) Зеркало py. Кейс attributes-types: + СписокЛюбой с valueType:"" (пустой Settings), сертифицирован в 1С. Регресс 39/39 ps1+py. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../skills/form-compile/scripts/form-compile.ps1 | 9 +++++---- .../skills/form-compile/scripts/form-compile.py | 11 +++++++---- .../form-decompile/scripts/form-decompile.ps1 | 5 +++-- docs/form-dsl-spec.md | 2 +- .../cases/form-compile/attributes-types.json | 1 + .../DataProcessors/Типы/Forms/Форма/Ext/Form.xml | 14 +++++++++++++- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index ecbc6a28..07e6c700 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.78 — Compile 1C managed form from JSON or object metadata +# form-compile v1.79 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -4398,11 +4398,12 @@ function Emit-Attributes { } # valueType: уточнение типа значений ValueList → # (та же грамматика типа, что и Type, включая составной "A | B"). Forgiving-синонимы. - $vtSpec = $null + # Три состояния: нет ключа → нет Settings; "" → пустой ; тип → с типом. + $vtSpec = $null; $hasVt = $false foreach ($k in @('valueType','typeDescription','описаниеТипов','типЗначений')) { - if ($attr.PSObject.Properties[$k] -and $attr.$k) { $vtSpec = $attr.$k; break } + if ($attr.PSObject.Properties[$k]) { $vtSpec = $attr.$k; $hasVt = $true; break } } - if ($vtSpec) { + if ($hasVt) { Emit-Type -typeStr "$vtSpec" -indent $inner -tag "Settings" -tagAttrs ' xsi:type="v8:TypeDescription"' } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 6a976c30..907f2445 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.78 — Compile 1C managed form from JSON or object metadata +# form-compile v1.79 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -4122,13 +4122,16 @@ def emit_attributes(lines, attrs, indent): lines.append(f'{inner}') # valueType: ОписаниеТипов значений ValueList → # (та же грамматика типа, включая составной "A | B"). Forgiving-синонимы. + # Три состояния: нет ключа → нет Settings; "" → пустой ; тип → с типом. vt_spec = None + has_vt = False for k in ('valueType', 'typeDescription', 'описаниеТипов', 'типЗначений'): - if attr.get(k): + if k in attr: vt_spec = attr[k] + has_vt = True break - if vt_spec: - emit_type(lines, str(vt_spec), inner, tag="Settings", tag_attrs=' xsi:type="v8:TypeDescription"') + if has_vt: + emit_type(lines, '' if vt_spec is None else str(vt_spec), inner, tag="Settings", tag_attrs=' xsi:type="v8:TypeDescription"') if attr.get('main') is True: lines.append(f'{inner}true') diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index a3d2aa28..b8aa34b5 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.54 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.55 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -1676,7 +1676,8 @@ if ($attrsNode) { # (та же грамматика типа). Дин-список Settings (xsi:type="DynamicList") обрабатывается отдельно. $setNode = $a.SelectSingleNode("lf:Settings", $ns) if ($setNode -and $setNode.GetAttribute("type", $NS_XSI) -match 'TypeDescription$') { - $vt = Decompile-Type $setNode; if ($vt) { $ao['valueType'] = $vt } + $vt = Decompile-Type $setNode + $ao['valueType'] = if ($vt) { $vt } else { '' } # пустой Settings → маркер "" } if ((Get-Child $a 'MainAttribute') -eq 'true') { $ao['main'] = $true } $vw = Decompile-XrFlag $a 'View'; if ($null -ne $vw) { $ao['view'] = $vw } diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 38e52e18..48351db8 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -740,7 +740,7 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs | `edit` | bool/object | Редактирование по ролям (``). См. §4.1c | | `functionalOptions` | array | Функциональные опции (`FunctionalOption.X…`). Массив имён; forgiving: `"X"`/`"FunctionalOption.X"`. Также у колонок (`columns[*]`) и команд (§7) | | `useAlways` | array | Поля, всегда читаемые (`Имя.Поле…`). Массив коротких имён полей (forgiving: с/без префикса `Имя.`). **Две формы**: этот массив на реквизите ИЛИ `useAlways: true` на колонке (`columns[*]`) — компилятор сливает. Для дин-списка — только массив (колонки не эмитятся, но формируют ``) | -| `valueType` | string | Тип значений у реквизита типа `ValueList` (``). Грамматика — как у `type`, включая составной `A \| B`. Forgiving-синонимы: `typeDescription` (≈1С «ОписаниеТипов» / XML), `описаниеТипов`, `типЗначений`. Пример: `"valueType": "CatalogRef.Контрагенты"` | +| `valueType` | string | Тип значений у реквизита типа `ValueList` (``). Грамматика — как у `type`, включая составной `A \| B`. **Три состояния**: нет ключа → нет ``; `""` → пустой `` (список без ограничения типа); тип → с типом. Forgiving-синонимы: `typeDescription` (≈1С «ОписаниеТипов» / XML), `описаниеТипов`, `типЗначений`. Пример: `"valueType": "CatalogRef.Контрагенты"` | | `savedData` | bool | Сохраняемые данные (``) | | `save` | bool/string/array | Сохранение значения в пользовательских настройках (`…`). `true` → `имя`; строка/массив строк → под-поля с авто-префиксом `имя.` (путь с точкой / UUID `1/0:…` / совпадающее с именем — берётся как есть). Нет ключа или `false` → не эмитится. Пример периода: `["Период","EndDate","StartDate","Variant"]` | | `fillChecking` | string | `Show`, `DontShow` | diff --git a/tests/skills/cases/form-compile/attributes-types.json b/tests/skills/cases/form-compile/attributes-types.json index 8ea29a99..b3efecf7 100644 --- a/tests/skills/cases/form-compile/attributes-types.json +++ b/tests/skills/cases/form-compile/attributes-types.json @@ -29,6 +29,7 @@ { "name": "Булево", "type": "boolean" }, { "name": "Период", "type": "СтандартныйПериод", "save": ["Период", "EndDate", "StartDate", "Variant"] }, { "name": "СписокЗначений", "type": "ValueList", "valueType": "string(50) | decimal(10,2)" }, + { "name": "СписокЛюбой", "type": "ValueList", "valueType": "" }, { "name": "Идентификатор", "type": "v8:UUID" } ] } diff --git a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml index 30bdade6..b3ef7859 100644 --- a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml @@ -140,7 +140,19 @@ - + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Список любой</v8:content> + </v8:item> + + + v8:ValueListType + + + + <v8:item> <v8:lang>ru</v8:lang>