From 8465bbc82e7127ad4256aceb15d49f1a260ba651 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 13 Jun 2026 14:25:55 +0300 Subject: [PATCH] =?UTF-8?q?fix(form-compile,form-decompile):=20ManualQuery?= =?UTF-8?q?=3Dfalse=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B0=D0=BB=D0=B8=D1=87?= =?UTF-8?q?=D0=B8=D0=B8=20QueryText=20(=D0=BE=D1=82=D0=BA=D0=BB=D0=BE?= =?UTF-8?q?=D0=BD=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=8D=D0=B2=D1=80=D0=B8=D1=81?= =?UTF-8?q?=D1=82=D0=B8=D0=BA=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Компилятор форсил true всегда при наличии query (hasQuery → true). Но платформа изредка хранит QueryText при ManualQuery=false (корпус: 16 форм query+mainTable+manualQuery=false, против 2447 query+manualQuery=true) — список с сохранённым авто-запросом, но не в «ручном» режиме. Декомпилятор: фиксирует manualQuery ТОЛЬКО при отклонении от эвристики hasQuery (query есть, но ManualQuery=false → settings.manualQuery=false). Компилятор: явный ключ manualQuery (в т.ч. false) ПОБЕЖДАЕТ эвристику; различает present-false от absent (раньше $st.manualQuery -eq $true трактовал явный false как absent → forced true). Зеркало py. Выборка 16 форм (ОснованияЛьготПоИмущественнымНалогам/ФормаВыбора, … acc+erp): match 0→16, TOTAL→0. ps1==py байт-в-байт. Регресс 43/43. Spec обновлён. Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 7 +++++-- .claude/skills/form-compile/scripts/form-compile.py | 9 +++++++-- .claude/skills/form-decompile/scripts/form-decompile.ps1 | 9 +++++++-- docs/form-dsl-spec.md | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 8c45986c..0c43f1cd 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.156 — Compile 1C managed form from JSON or object metadata +# form-compile v1.157 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -5682,7 +5682,10 @@ function Emit-Attributes { # AutoFillAvailableFields — дефолт true; эмитим только при заданном ключе (отклонение). if ($null -ne $st.autoFillAvailableFields) { X "$si$(if ($st.autoFillAvailableFields){'true'}else{'false'})" } $hasQuery = $st.query -and "$($st.query)".Trim() - $mq = if ($hasQuery -or $st.manualQuery -eq $true) { "true" } else { "false" } + # Явный ключ manualQuery (в т.ч. false) ПОБЕЖДАЕТ эвристику hasQuery (платформа изредка + # хранит QueryText при ManualQuery=false — декомпилятор фиксирует это отклонение). + $hasMQKey = ($st.PSObject.Properties['manualQuery']) -and ($null -ne $st.manualQuery) + $mq = if ($hasMQKey) { if ($st.manualQuery) { "true" } else { "false" } } elseif ($hasQuery) { "true" } else { "false" } X "$si$mq" # DynamicDataRead: дефолт true; false только при явном отключении $ddr = if ($st.dynamicDataRead -eq $false) { "false" } else { "true" } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 0857c605..5cd24f84 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.156 — Compile 1C managed form from JSON or object metadata +# form-compile v1.157 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -5438,7 +5438,12 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None): lines.append(f'{si}{"true" if s["autoFillAvailableFields"] else "false"}') # Порядок платформы: ManualQuery, DynamicDataRead, QueryText, Field*, MainTable, ListSettings has_query = bool(s.get('query') and str(s['query']).strip()) - mq = 'true' if (has_query or s.get('manualQuery')) else 'false' + # Явный ключ manualQuery (в т.ч. False) ПОБЕЖДАЕТ эвристику has_query (платформа изредка + # хранит QueryText при ManualQuery=false — декомпилятор фиксирует отклонение). + if s.get('manualQuery') is not None: + mq = 'true' if s['manualQuery'] else 'false' + else: + mq = 'true' if has_query else 'false' lines.append(f'{si}{mq}') # DynamicDataRead: дефолт true; false только при явном отключении ddr = 'false' if s.get('dynamicDataRead') is False else 'true' diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 5f2c0858..96f59f90 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.131 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.132 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -2722,7 +2722,12 @@ if ($attrsNode) { # дефолт true → платформа эмитит отклонение). Захват факт. значения. $asus = Get-Child $setNode 'AutoSaveUserSettings'; if ($null -ne $asus) { $so['autoSaveUserSettings'] = ($asus -eq 'true') } $qtNode = $setNode.SelectSingleNode("lf:QueryText", $ns) - if ($qtNode -and $qtNode.InnerText) { $so['query'] = Maybe-ExternalizeQuery -queryText $qtNode.InnerText -listName "$($ao['name'])" } + $hasQ = [bool]($qtNode -and $qtNode.InnerText) + if ($hasQ) { $so['query'] = Maybe-ExternalizeQuery -queryText $qtNode.InnerText -listName "$($ao['name'])" } + # ManualQuery: компилятор выводит из наличия query (hasQuery → true). Платформа в редких + # случаях (корпус 16) хранит QueryText при ManualQuery=false → фиксируем отклонение от эвристики. + $mqV = Get-Child $setNode 'ManualQuery' + if ($null -ne $mqV) { $mqActual = ($mqV -eq 'true'); if ($mqActual -ne $hasQ) { $so['manualQuery'] = $mqActual } } # DynamicDataRead: дефолт true → эмитим только false if ((Get-Child $setNode 'DynamicDataRead') -eq 'false') { $so['dynamicDataRead'] = $false } # Явные поля набора (редко, ~4.5%) — захват только при наличии Field diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 6a83c677..fe0f63e2 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -956,7 +956,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и | `conditionalAppearance` | array | Условное оформление списка (грамматика как в СКД) | | `grouping` | string \| array | Группировка строк списка (см. ниже). Forgiving-синонимы: `structure`, `группировка` | -`ManualQuery` выводится из наличия `query` — отдельным ключом не задаётся. +`ManualQuery` выводится из наличия `query` (есть `query` → `true`). Редкое отклонение — список с `query`, но `ManualQuery=false` (корпус 16): ключ `manualQuery: false` побеждает эвристику (декомпилятор ставит его только при таком отклонении). Пустой блок настроек компоновщика (`ListSettings`) генерируется автоматически (каноничный полный скелет платформы — filter+order+conditionalAppearance+itemsViewMode+itemsUserSettingID, ~93% форм); указывать ничего не нужно.