fix(form-decompile): Save Field — многоуровневый путь теряет префикс реквизита

Реквизит с <Save><Field>имя.Settings.Filter</Field> (напр. SettingsComposer):
декомпилятор снимал префикс "имя." ВСЕГДА (regex `(.+)`) → "Settings.Filter", но
компилятор реинъектит префикс ТОЛЬКО для полей без точки (dot-правило: путь с точкой =
полный, как есть). Рассогласование → префикс реквизита терялся при раундтрипе.

Фикс (декомпилятор): снимаем префикс "имя." только когда остаток — простое под-поле
без точки (`([^.]+)$`); многоуровневый путь "имя.X.Y" храним ПОЛНЫМ → компилятор
по dot-правилу эмитит как есть. Period-кейс (одноуровневые EndDate/StartDate/Variant)
не затронут.

Корпус 8.3.24: 366 многоуровневых Save-полей в 89 формах. Выборка 40 форм: match 40/40,
0 регрессий (включая Period). Декомпилятор-only. Регресс 43/43. Spec обновлён.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-13 15:30:26 +03:00
co-authored by Claude Opus 4.8
parent 03720d93ed
commit 2abaa28f16
2 changed files with 6 additions and 3 deletions
@@ -1,4 +1,4 @@
# form-decompile v0.135 — Decompile 1C managed Form.xml to JSON DSL (draft)
# form-decompile v0.136 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -2671,8 +2671,11 @@ if ($attrsNode) {
if ($flds.Count -eq 1 -and $flds[0] -eq $nm) {
$ao['save'] = $true
} elseif ($flds.Count -gt 0) {
# Снимаем префикс "имя." ТОЛЬКО когда остаток — простое подполе без точки (компилятор
# реинъектит его). Многоуровневый путь "имя.Settings.Filter" компилятор по dot-правилу
# эмитит как есть (префикс не вернёт) → храним ПОЛНЫЙ путь, иначе префикс теряется.
$stripped = @($flds | ForEach-Object {
if ($_ -match "^$([regex]::Escape($nm))\.(.+)$") { $matches[1] } else { $_ }
if ($_ -match "^$([regex]::Escape($nm))\.([^.]+)$") { $matches[1] } else { $_ }
})
if ($stripped.Count -eq 1) { $ao['save'] = $stripped[0] } else { $ao['save'] = $stripped }
}