fix(form-decompile,form-compile): UUID-ссылка (N/M:GUID) в Save/UseAlways теряла/получала префикс

Поле-ссылка по UUID (1/0:GUID) обрабатывается как путь-с-точкой: компилятор НЕ
реинъектит префикс "имя." (платформа хранит её без префикса). Два места рассогласованы:

(1) Save (декомпилятор) — продолжение фикса 2abaa28f: снимали префикс "имя." и у
UUID-остатка (1/0:GUID без точки матчил [^.]+$), компилятор не возвращал → потеря.
Добавлен guard `$matches[1] -notmatch '^\d+/\d+'` → UUID-путь храним полным.

(2) UseAlways (компилятор ps1+py) — реинъектил "имя." к UUID-полю без префикса
(1/0:GUID → Объект.1/0:GUID), оригинал хранит без префикса. Добавлен guard
`-notmatch '^\d+/\d+'` (зеркало правила Save-компилятора). Корпус: 1 форма
(ПланВнутреннихПотреблений/ФормаДокумента, useAlways UUID no-prefix).

Форма → match. ps1==py байт-в-байт. Регресс 43/43.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-13 15:47:52 +03:00
parent 2abaa28f16
commit db341f2351
3 changed files with 12 additions and 9 deletions
@@ -1,4 +1,4 @@
# form-compile v1.161 — Compile 1C managed form from JSON or object metadata
# form-compile v1.162 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -5638,7 +5638,8 @@ function Emit-Attributes {
$bare = $fld.Substring(1)
if ($bare -notmatch "^$([regex]::Escape($attrName))\.") { $bare = "$attrName.$bare" }
$fld = "~$bare"
} elseif ($fld -notmatch "^$([regex]::Escape($attrName))\.") {
} elseif ($fld -notmatch "^$([regex]::Escape($attrName))\." -and $fld -notmatch '^\d+/\d+') {
# UUID-ссылка (1/0:GUID) — НЕ префиксуем (платформа хранит её без "имя.")
$fld = "$attrName.$fld"
}
if (-not $uaFields.Contains($fld)) { [void]$uaFields.Add($fld) }
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.161 — Compile 1C managed form from JSON or object metadata
# form-compile v1.162 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -5408,7 +5408,8 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None):
if not re.match(r'^' + re.escape(attr_name) + r'\.', bare):
bare = f'{attr_name}.{bare}'
fld = f'~{bare}'
elif not re.match(r'^' + re.escape(attr_name) + r'\.', fld):
elif not re.match(r'^' + re.escape(attr_name) + r'\.', fld) and not re.match(r'^\d+/\d+', fld):
# UUID-ссылка (1/0:GUID) — НЕ префиксуем (платформа хранит её без "имя.")
fld = f'{attr_name}.{fld}'
if fld not in ua_fields:
ua_fields.append(fld)
@@ -1,4 +1,4 @@
# form-decompile v0.136 — Decompile 1C managed Form.xml to JSON DSL (draft)
# form-decompile v0.137 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -2671,11 +2671,12 @@ if ($attrsNode) {
if ($flds.Count -eq 1 -and $flds[0] -eq $nm) {
$ao['save'] = $true
} elseif ($flds.Count -gt 0) {
# Снимаем префикс "имя." ТОЛЬКО когда остаток — простое подполе без точки (компилятор
# реинъектит его). Многоуровневый путь "имя.Settings.Filter" компилятор по dot-правилу
# эмитит как есть (префикс не вернёт) → храним ПОЛНЫЙ путь, иначе префикс теряется.
# Снимаем префикс "имя." ТОЛЬКО когда остаток — простое подполе, которое компилятор
# реинъектит (зеркало его условия: ≠имя, без точки, не UUID-ссылка ^N/M). Многоуровневый
# путь "имя.Settings.Filter" и UUID-ссылка "имя.1/0:GUID" компилятор эмитит как есть
# (префикс не вернёт) → храним ПОЛНЫЙ путь, иначе префикс теряется.
$stripped = @($flds | ForEach-Object {
if ($_ -match "^$([regex]::Escape($nm))\.([^.]+)$") { $matches[1] } else { $_ }
if ($_ -match "^$([regex]::Escape($nm))\.([^.]+)$" -and $matches[1] -notmatch '^\d+/\d+') { $matches[1] } else { $_ }
})
if ($stripped.Count -eq 1) { $ao['save'] = $stripped[0] } else { $ao['save'] = $stripped }
}