From 8542b45719d324207056e44c2314c699af5ac45c Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Fri, 12 Jun 2026 15:25:07 +0300 Subject: [PATCH] =?UTF-8?q?fix(form-compile):=20FixedArray=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BE=D0=B4=D0=BD=D0=BE=D1=8D=D0=BB=D0=B5=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=B7=D0=BD=D0=B0=D1=87?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5?= =?UTF-8?q?=D1=82=D1=80=D0=B0=20=D0=B2=D1=8B=D0=B1=D0=BE=D1=80=D0=B0=20(PS?= =?UTF-8?q?=20unwrap)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раундтрип терял FixedArray у choiceParameter со значением-списком из ОДНОГО элемента (напр. ВводОстатковВнеоборотныхАктивов/ФормаРедактированияСтрокиНМА: 9 из 10 FixedArray эмитились как скаляр → 45 строк LOST). Корень — классический PowerShell unwrap: Get-ElProp возвращает 1-элементный массив, но PS разворачивает его на RETURN функции (и при биндинге параметра), так что $isArray=false → значение эмитилось как одиночный вместо с одним . Фикс (только ps1): в Emit-ChoiceParameters значение читается ПРЯМЫМ member/индексер-доступом (не через Get-ElProp — его return разворачивает), массив-ность вычисляется до биндинга и передаётся в Emit-ChoiceParamValue явным флагом -isArray (foreach по развёрнутому скаляру = 1 итерация → корректный 1-элементный FixedArray). PY не затронут (Python не разворачивает списки). Системный артефакт: во многом раздувал кластер app:item>Value в раундтрипе (PS-харнесс). Верификация: таргет-форма → match (45→0; FixedArray 1→10); регресс form-compile 43/43 (ps1+py); 1С-cert input-fields (1-элементный массив-choiceParameter → FixedArray, грузится). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../form-compile/scripts/form-compile.ps1 | 23 ++++++++++++------- .../form-compile/scripts/form-compile.py | 2 +- .../cases/form-compile/input-fields.json | 1 + .../ПоляВвода/Forms/Форма/Ext/Form.xml | 11 +++++++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index d53a3d6db..b259a2582 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.134 — Compile 1C managed form from JSON or object metadata +# form-compile v1.135 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -4018,9 +4018,11 @@ function ConvertFrom-TypeLinkShorthand { # Внутреннее значение параметра выбора (FormChoiceListDesTimeValue): + . # Скаляр → один Value (через Normalize-ChoiceValue); массив → v8:FixedArray из вложенных FormChoiceListDesTimeValue. function Emit-ChoiceParamValue { - param($value, [string]$indent) + # $isArray передаётся ЯВНО из вызывающего кода: PowerShell разворачивает одноэлементный массив + # при биндинге параметра ($value становится скаляром), поэтому определять массив тут — ненадёжно + # (1-элементный список `["X"]` эмитился бы скаляром вместо FixedArray). foreach по скаляру = 1 итерация. + param($value, [string]$indent, [bool]$isArray) X "$indent" - $isArray = ($value -is [System.Array]) -or ($value -is [System.Collections.IList] -and $value -isnot [string]) if ($isArray) { X "$indent" foreach ($v in $value) { @@ -4047,13 +4049,18 @@ function Emit-ChoiceParameters { foreach ($item in @($cp)) { if ($item -is [string]) { $item = ConvertFrom-ChoiceParamShorthand $item } $name = Get-ElProp $item @('name','имя') - # Наличие ключа value (≠ значения): hashtable (shorthand) vs PSCustomObject (JSON-объект) + # Наличие ключа value (≠ значения) + ПРЯМОЙ доступ к значению (без Get-ElProp): его return + # разворачивает 1-элементный массив (PS unwrap), теряя массив-ность → FixedArray не эмитится. + # Индексер/member-доступ массив сохраняет; if-выражение/функция-return — нет. + $hasVal = $false; $val = $null if ($item -is [System.Collections.IDictionary]) { - $hasVal = $item.Contains('value') -or $item.Contains('значение') + if ($item.Contains('value')) { $hasVal = $true; $val = $item['value'] } + elseif ($item.Contains('значение')) { $hasVal = $true; $val = $item['значение'] } } else { - $hasVal = ($null -ne $item.PSObject.Properties['value']) -or ($null -ne $item.PSObject.Properties['значение']) + if ($item.PSObject.Properties['value']) { $hasVal = $true; $val = $item.PSObject.Properties['value'].Value } + elseif ($item.PSObject.Properties['значение']) { $hasVal = $true; $val = $item.PSObject.Properties['значение'].Value } } - $val = Get-ElProp $item @('value','значение') + $valIsArray = ($val -is [System.Array]) -or ($val -is [System.Collections.IList] -and $val -isnot [string]) X "$indent`t" # Параметр выбора без значения → (платформа, 13 в корпусе); # со значением (в т.ч. пустой строкой) → FormChoiceListDesTimeValue. @@ -4061,7 +4068,7 @@ function Emit-ChoiceParameters { X "$indent`t`t" } else { X "$indent`t`t" - Emit-ChoiceParamValue -value $val -indent "$indent`t`t`t" + Emit-ChoiceParamValue -value $val -indent "$indent`t`t`t" -isArray $valIsArray X "$indent`t`t" } X "$indent`t" diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 3b5280a9a..807a3308a 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.134 — Compile 1C managed form from JSON or object metadata +# form-compile v1.135 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy diff --git a/tests/skills/cases/form-compile/input-fields.json b/tests/skills/cases/form-compile/input-fields.json index 32da4b8d5..492b437c4 100644 --- a/tests/skills/cases/form-compile/input-fields.json +++ b/tests/skills/cases/form-compile/input-fields.json @@ -34,6 +34,7 @@ { "name": "Отбор.Вид", "value": "Основной" }, { "name": "Отбор.Дата", "value": "2020-01-01T00:00:00" }, { "name": "Отбор.Список", "value": ["Один", "Два"] }, + { "name": "Отбор.Одно", "value": ["Единственный"] }, { "name": "Отбор.БезЗначения" } ], "choiceParameterLinks": [ diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index e7ae7804c..19f566808 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -289,6 +289,17 @@ + + + + + + + Единственный + + + +