feat(meta-compile,meta-decompile): Characteristics — привязка ПВХ (v1.25/v0.16)

Блок «Дополнительные реквизиты и сведения»/контактная инфо. DSL `characteristics`:
массив {types:{from,key,filterField,filterValue}, values:{from,object,type,value}}
— имена зеркалят XML без xr:, -1-поля неявны. Синонимы XML-имён
(characteristicTypes/keyField/…) приняты.

Прощающий ввод (по мотивам dataPath): поля — голое→StandardAttribute.<EN>
(ссылочные Ref/Parent/Owner, RU→EN) / Attribute.<имя>, частичное Dimension.X/
Resource.X/StandardAttribute.X→+from (регистры ДопСведения), полный путь как
есть. from — рус.корни + короткая 3-сегм.→вставка TabularSection. filterValue —
голый предопределённый→+каталог из types.from.

Декомпилятор пишет короткую форму (dogfood: каждый из 212 объектов роундтрип-
тестирует резолвер). Асимметрия для безопасности: голая форма только для
Ref/Parent/Owner, прочие StandardAttribute.X — частичной формой.

remaining Characteristics=0 на ВСЕХ 212 объектах корпуса, регресс 44/44 ps1+py,
ps1↔py identical. spec §7.1.4, кейс catalog-characteristics.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-04 11:27:56 +03:00
co-authored by Claude Opus 4.8
parent e9e3323542
commit e2f019d872
10 changed files with 688 additions and 5 deletions
@@ -1,4 +1,4 @@
# meta-decompile v0.15 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.16 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -411,6 +411,52 @@ foreach ($pp in @(
if ($null -ne $pv) { $dsl[$pp[1]] = $pv }
}
# --- Characteristics (привязка ПВХ). Короткая форма: поля bare/partial, filterValue без каталога, from полный.
function Shorten-CharField { param([string]$full, [string]$from)
if ($full.StartsWith("$from.")) {
$rest = $full.Substring($from.Length + 1)
if ($rest -match '^StandardAttribute\.(Ref|Parent|Owner)$') { return $Matches[1] } # ссылочные станд. → голое
if ($rest -match '^Attribute\.(.+)$') { return $Matches[1] } # кастом → голое
return $rest # прочие StandardAttribute.X / Dimension.X / Resource.X → частичное (безопасно)
}
return $full
}
function Shorten-CharFilterValue { param([string]$full, [string]$typesFrom)
$tp = @("$typesFrom" -split '\.')
if ($tp.Count -ge 2) {
$pref = "$($tp[0]).$($tp[1])."
if ($full.StartsWith($pref)) { $tail = $full.Substring($pref.Length); if (-not $tail.Contains('.')) { return $tail } }
}
return $full
}
$charsNode = $props.SelectSingleNode('md:Characteristics', $nsm)
if ($charsNode) {
$chList = @($charsNode.SelectNodes('xr:Characteristic', $nsm))
if ($chList.Count -gt 0) {
$chArr = [System.Collections.ArrayList]@()
foreach ($ch in $chList) {
$ct = $ch.SelectSingleNode('xr:CharacteristicTypes', $nsm)
$cv = $ch.SelectSingleNode('xr:CharacteristicValues', $nsm)
$tFrom = $ct.GetAttribute('from'); $vFrom = $cv.GetAttribute('from')
$gt = { param($n, $node) $x = $node.SelectSingleNode("xr:$n", $nsm); if ($x) { $x.InnerText } else { "" } }
$types = [ordered]@{
from = $tFrom
key = Shorten-CharField (& $gt 'KeyField' $ct) $tFrom
filterField = Shorten-CharField (& $gt 'TypesFilterField' $ct) $tFrom
filterValue = Shorten-CharFilterValue (& $gt 'TypesFilterValue' $ct) $tFrom
}
$values = [ordered]@{
from = $vFrom
object = Shorten-CharField (& $gt 'ObjectField' $cv) $vFrom
type = Shorten-CharField (& $gt 'TypeField' $cv) $vFrom
value = Shorten-CharField (& $gt 'ValueField' $cv) $vFrom
}
[void]$chArr.Add([ordered]@{ types = $types; values = $values })
}
$dsl['characteristics'] = $chArr
}
}
# --- StandardAttributes: блок есть ⟺ кастомизация ≥1 стандартного реквизита.
# Захватываем ОТКЛОНЕНИЯ от профиля материализованного блока (профиль компилятор восстановит сам).
# Профиль Catalog: Owner{FC=ShowError,FFV=true}, Parent{FFV=true}, Description{FC=ShowError}. ---