From 9d07b2e20f04aa2826257315aafedc4a12f966b3 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Tue, 22 Sep 2026 20:42:20 +0300 Subject: [PATCH] =?UTF-8?q?fix(form-decompile):=20=D0=BD=D0=B5=20=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D1=8F=D1=82=D1=8C=20=D0=B7=D0=B0=D0=B3=D0=BE=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=BA-=D0=BF=D1=80=D0=BE=D0=B1=D0=B5=D0=BB?= =?UTF-8?q?=20=D1=83=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80?= =?UTF-8?q?=D0=B0=20=D0=B4=D0=B8=D0=BD=D0=B0=D0=BC=D0=B8=D1=87=D0=B5=D1=81?= =?UTF-8?q?=D0=BA=D0=BE=D0=B3=D0=BE=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ветка параметра читала заголовок обычным Get-LangText, который схлопывает whitespace-only в пустую строку; ветка реквизита давно читает его через Get-LangTextWS. Заголовок-пробел — им гасят подпись — превращался в "" , а компилятор трактует пустую строку как отсутствие ключа и подставляет авто-вывод из имени: " " молча становилось «Организации ВЕТИС». Тот же класс, что и потерянный регистр, соседняя ветка той же функции. В корпусе (13891 узел dcssch:title в четырёх типовых) платформа не пишет ни пустой, ни whitespace-only заголовок, поэтому на разборе чужих выгрузок правка ничего не меняет — она чинит наш собственный раундтрип compile → decompile → compile. Кейс dl-parameter-title-case расширен вторым параметром с заголовком-пробелом; на исходной версии падает в обоих портах. Снэпшоты приняты платформой (verify-snapshots, 3/3). Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01SSyRNwSiuAAEQCLSCUGEzQ --- .../form-decompile/scripts/form-decompile.ps1 | 4 ++-- .../form-decompile/scripts/form-decompile.py | 6 ++++-- .../dl-parameter-title-case.json | 7 ++++--- .../Регистр/Forms/Форма/Ext/Form.xml | 20 ++++++++++++++++++- .../dl-parameter-title-case/draft.json | 7 +++++-- 5 files changed, 34 insertions(+), 10 deletions(-) diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 3acc5f3f5..1ad0ab5cc 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.151 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.152 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. [CmdletBinding(PositionalBinding=$false)] @@ -1494,7 +1494,7 @@ function Build-DLParameter { # title — опускаем, если совпадает с авто-выводом из имени (ru-only) $titleNode = $pNode.SelectSingleNode("dcssch:title", $ns) if ($titleNode) { - $t = Get-LangText $titleNode + $t = Get-LangTextWS $titleNode # восстановление значимого пробела: заголовком-пробелом гасят подпись if ($null -ne $t) { # Сравнение байт в байт: эталон — компилятор, он пишет заголовок как есть. -eq # регистронезависим, и заголовок, отличающийся от авто-вывода только регистром diff --git a/.claude/skills/form-decompile/scripts/form-decompile.py b/.claude/skills/form-decompile/scripts/form-decompile.py index 9fee24ec2..343505c43 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.py +++ b/.claude/skills/form-decompile/scripts/form-decompile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-decompile v0.151 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.152 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. # @@ -1677,7 +1677,9 @@ def build_dl_parameter(p_node): # title — опускаем, если совпадает с авто-выводом из имени (ru-only) title_node = p_node.find('dcssch:title', NS) if title_node is not None: - t = get_lang_text(title_node) + # get_lang_text_ws, а не get_lang_text: заголовком-пробелом гасят подпись, а обычное + # чтение схлопывает whitespace-only в '' — и компилятор подставил бы авто-вывод. + t = get_lang_text_ws(title_node) if t is not None: # Сравнение байт в байт (в ps1 — [string]::Equals(..., Ordinal)): эталон — компилятор, # он пишет заголовок как есть. Регистронезависимое сравнение теряло заголовок, diff --git a/tests/skills/cases/form-decompile/dl-parameter-title-case.json b/tests/skills/cases/form-decompile/dl-parameter-title-case.json index 258299db9..80cbd5470 100644 --- a/tests/skills/cases/form-decompile/dl-parameter-title-case.json +++ b/tests/skills/cases/form-decompile/dl-parameter-title-case.json @@ -1,5 +1,5 @@ { - "name": "Заголовок параметра динамического списка, отличающийся от авто-вывода только регистром, не теряется", + "name": "Заголовок параметра динамического списка не теряется: отличие в регистре и заголовок-пробел", "preRun": [ { "script": "meta-compile/scripts/meta-compile", @@ -20,10 +20,11 @@ "name": "Список", "type": "DynamicList", "settings": { - "query": "ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС", + "query": "ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС И 2 = &СуммаДокумента", "keyType": "RowNumber", "parameters": [ - { "name": "ОрганизацииВЕТИС", "title": "Организации ВетИС", "type": "string" } + { "name": "ОрганизацииВЕТИС", "title": "Организации ВетИС", "type": "string" }, + { "name": "СуммаДокумента", "title": " ", "type": "string" } ] } } diff --git a/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/DataProcessors/Регистр/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/DataProcessors/Регистр/Forms/Форма/Ext/Form.xml index 2c4f8dcc3..f58b0cfb1 100644 --- a/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/DataProcessors/Регистр/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/DataProcessors/Регистр/Forms/Форма/Ext/Form.xml @@ -28,7 +28,7 @@ true true - ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС + ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС И 2 = &СуммаДокумента ОрганизацииВЕТИС @@ -47,6 +47,24 @@ true + + СуммаДокумента + + + ru + + + + + xs:string + + 0 + Variable + + + + true + RowNumber diff --git a/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/draft.json b/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/draft.json index 08e03ce05..ac45fd228 100644 --- a/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/draft.json +++ b/tests/skills/cases/form-decompile/snapshots/dl-parameter-title-case/draft.json @@ -7,8 +7,11 @@ "type": "DynamicList", "settings": { "keyType": "RowNumber", - "query": "ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС", - "parameters": [{ "name": "ОрганизацииВЕТИС", "title": "Организации ВетИС", "type": "string" }] + "query": "ВЫБРАТЬ 1 КАК Поле ГДЕ 1 = &ОрганизацииВЕТИС И 2 = &СуммаДокумента", + "parameters": [ + { "name": "ОрганизацииВЕТИС", "title": "Организации ВетИС", "type": "string" }, + { "name": "СуммаДокумента", "title": " ", "type": "string" } + ] } } ]