From f9ae24a6788eebe629d16e2165a2cf93f8fd08a2 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 7 Jun 2026 22:27:04 +0300 Subject: [PATCH] =?UTF-8?q?fix(form-compile):=20=D0=BF=D1=83=D1=81=D1=82?= =?UTF-8?q?=D0=B0=D1=8F=20=D1=81=D1=82=D1=80=D0=BE=D0=BA=D0=B0-=D0=B7?= =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20self-closing=20+?= =?UTF-8?q?=20Enum.X.EmptyRef=20=D0=B1=D0=B5=D0=B7=20EnumValue?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Два общих бага value (всплыли на полном прогоне 2.17, чинят и choiceList, и параметры выбора): - Пустое строковое значение эмитилось вместо самозакрывающегося . Введён хелпер Get-ChoiceValueTag (3 места: choiceList scalar + choiceParam scalar + FixedArray inner). Форма АктивныеПользователи теперь round-trip match. - Enum.X.EmptyRef нормализатор ломал вставкой .EnumValue. → EnumValue.EmptyRef (EmptyRef — пустая ссылка перечисления, не значение). Фикс в Normalize- ChoiceValue (Enum-ветка): EmptyRef сохраняется как есть. Зеркало py. Кейсы: input-fields (пустая строка в choiceList), radio-auto-enum (Enum.X.EmptyRef) — оба сертифицированы загрузкой в 1С. Регресс 36/36 ps1+py. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../form-compile/scripts/form-compile.ps1 | 20 +++++++++++++------ .../form-compile/scripts/form-compile.py | 20 ++++++++++++++----- .../cases/form-compile/input-fields.json | 1 + .../cases/form-compile/radio-auto-enum.json | 3 ++- .../ПоляВвода/Forms/Форма/Ext/Form.xml | 13 ++++++++++++ .../ТестРадио/Forms/Форма/Ext/Form.xml | 13 ++++++++++++ 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 3dc23c8e..957010de 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.70 — Compile 1C managed form from JSON or object metadata +# form-compile v1.71 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -3070,8 +3070,9 @@ function Normalize-ChoiceValue { if ($parts.Count -eq 2) { # "Enum.X" alone — not a value, treat as string } elseif ($parts.Count -eq 3) { - # "Enum.X.Y" — insert .EnumValue. - $normalized = "Enum.$typeName.EnumValue.$($parts[2])" + # "Enum.X.Y" — insert .EnumValue. ("EmptyRef" — пустая ссылка, БЕЗ вставки) + if ($parts[2] -eq 'EmptyRef') { $normalized = "Enum.$typeName.EmptyRef" } + else { $normalized = "Enum.$typeName.EnumValue.$($parts[2])" } } else { # "Enum.X..Y..." — replace member with EnumValue (handles ЗначениеПеречисления too) $member = $parts[2] @@ -3131,6 +3132,13 @@ function Emit-ChoicePresentation { X "$indent" } +# для choiceList/choiceParameters: пустой текст → самозакрывающийся тег (зеркало платформы). +function Get-ChoiceValueTag { + param($norm) + if ([string]::IsNullOrEmpty($norm.Text)) { return "" } + return "$(Esc-Xml $norm.Text)" +} + # Emit (список выбора) — у RadioButtonField и InputField. # Элемент: { value, presentation?/title? } (+ рус. синонимы значение/представление). function Emit-ChoiceList { @@ -3180,7 +3188,7 @@ function Emit-ChoiceList { X "$valIndent0" X "$valIndent" Emit-ChoicePresentation -pres $presRaw -indent "$valIndent`t" - X "$valIndent`t$(Esc-Xml $norm.Text)" + X "$valIndent`t$(Get-ChoiceValueTag $norm)" X "$valIndent" X "$itemIndent" } @@ -3262,13 +3270,13 @@ function Emit-ChoiceParamValue { $norm = Normalize-ChoiceValue -value $v X "$indent`t" X "$indent`t`t" - X "$indent`t`t$(Esc-Xml $norm.Text)" + X "$indent`t`t$(Get-ChoiceValueTag $norm)" X "$indent`t" } X "$indent" } else { $norm = Normalize-ChoiceValue -value $value - X "$indent$(Esc-Xml $norm.Text)" + X "$indent$(Get-ChoiceValueTag $norm)" } } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index f1e11265..826cb63c 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.70 — Compile 1C managed form from JSON or object metadata +# form-compile v1.71 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -1928,7 +1928,10 @@ def normalize_choice_value(value): type_name = parts[1] normalized = None if canon_root == "Enum": - if len(parts) == 3: + if len(parts) == 3 and parts[2] == 'EmptyRef': + # "Enum.X.EmptyRef" — пустая ссылка, НЕ значение перечисления (без .EnumValue.) + normalized = f"Enum.{type_name}.EmptyRef" + elif len(parts) == 3: normalized = f"Enum.{type_name}.EnumValue.{parts[2]}" elif len(parts) >= 4: member = parts[2] @@ -1970,6 +1973,13 @@ def emit_choice_presentation(lines, pres, indent): lines.append(f"{indent}") +def choice_value_tag(norm): + # для choiceList/choiceParameters: пустой текст → самозакрывающийся тег (зеркало платформы). + if not norm["text"]: + return f'' + return f'{esc_xml(norm["text"])}' + + def emit_choice_list(lines, el, indent): # — у RadioButtonField и InputField. Элемент: { value, presentation?/title? }. choice_list = el.get('choiceList') or [] @@ -1999,7 +2009,7 @@ def emit_choice_list(lines, el, indent): lines.append(f'{val_indent}0') lines.append(f'{val_indent}') emit_choice_presentation(lines, pres_raw, f'{val_indent}\t') - lines.append(f'{val_indent}\t{esc_xml(norm["text"])}') + lines.append(f'{val_indent}\t{choice_value_tag(norm)}') lines.append(f'{val_indent}') lines.append(f'{item_indent}') lines.append(f'{indent}') @@ -2075,12 +2085,12 @@ def emit_choice_param_value(lines, value, indent): norm = normalize_choice_value(v) lines.append(f'{indent}\t') lines.append(f'{indent}\t\t') - lines.append(f'{indent}\t\t{esc_xml(norm["text"])}') + lines.append(f'{indent}\t\t{choice_value_tag(norm)}') lines.append(f'{indent}\t') lines.append(f'{indent}') else: norm = normalize_choice_value(value) - lines.append(f'{indent}{esc_xml(norm["text"])}') + lines.append(f'{indent}{choice_value_tag(norm)}') def emit_choice_parameters(lines, el, indent): diff --git a/tests/skills/cases/form-compile/input-fields.json b/tests/skills/cases/form-compile/input-fields.json index f7b169d8..197e6386 100644 --- a/tests/skills/cases/form-compile/input-fields.json +++ b/tests/skills/cases/form-compile/input-fields.json @@ -22,6 +22,7 @@ { "input": "ПолеПароля", "path": "ПолеПароля", "passwordMode": true, "title": "Пароль" }, { "input": "ПолеСКнопками", "path": "ПолеСКнопками", "choiceButton": true, "clearButton": true, "title": "Выбор" }, { "input": "ПолеСписокВыбора", "path": "ПолеСписокВыбора", "title": "Список выбора", "choiceList": [ + { "value": "", "presentation": "Все" }, { "value": "Первый" }, { "value": "Второй", "presentation": "Второй вариант" } ]}, diff --git a/tests/skills/cases/form-compile/radio-auto-enum.json b/tests/skills/cases/form-compile/radio-auto-enum.json index b9389c1b..3cf34518 100644 --- a/tests/skills/cases/form-compile/radio-auto-enum.json +++ b/tests/skills/cases/form-compile/radio-auto-enum.json @@ -37,7 +37,8 @@ "columnsCount": 1, "choiceList": [ { "value": "Enum.СпособыКурса.EnumValue.Авто", "presentation": { "ru": "Автоматически", "en": "Automatic" } }, - { "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" } + { "value": "Enum.СпособыКурса.EnumValue.Ручной", "presentation": "вручную" }, + { "value": "Enum.СпособыКурса.EmptyRef", "presentation": "(не задан)" } ] } ] 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 c0764df1..f7d01670 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 @@ -91,6 +91,19 @@ + + + 0 + + + + ru + Все + + + + + 0 diff --git a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml index 31d5522f..7473dd47 100644 --- a/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/radio-auto-enum/DataProcessors/ТестРадио/Forms/Форма/Ext/Form.xml @@ -51,6 +51,19 @@ Enum.СпособыКурса.EnumValue.Ручной + + + 0 + + + + ru + (не задан) + + + Enum.СпособыКурса.EmptyRef + +