feat(meta-compile,meta-decompile): батч object-свойств реквизита (консистентно с form) (v1.21/v0.6)

Раундтрип-кластер extra-свойств реквизита. Компилятор хардкодил дефолты, реальные значения
варьируются (корпус 32642 реквизита): FullTextSearch DontUse 10531, Comment 7993, Mask 1489,
Format/EditFormat 684/686, Use ForFolderAndItem 1299, CreateOnInput/QuickChoice/FillFromFillingValue/
DataHistory. По философии DSL — в объектную форму (shorthand несёт только частое: req/index/multiline).

Object-ключи (omit-on-default), имена согласованы с form-compile где применимо: comment, fullTextSearch,
mask, format/editFormat (ML), use, createOnInput, quickChoice, dataHistory, fillFromFillingValue,
passwordMode, choiceHistoryOnInput. Прощающий ввод: fillCheck→fillChecking (bool true→ShowError),
quickChoice bool (true→Use/false→DontUse). Emit-Attribute параметризован; декомпилятор переключается
на object-форму при любом непокрытом свойстве.

spec v2.6 §4.2 (полная таблица ключей); тест-кейс catalog-attr-props.
Валидация: PS==PY паритет; категории батча 0 (FullTextSearch/Comment/Mask/Format/Use/...);
полный прогон −68458 (161917→93459); регресс 37/37 (ps+py); 1С-cert зелёный.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-03 13:46:14 +03:00
co-authored by Claude Opus 4.8
parent 53ed8c4489
commit 5f53c3f02e
10 changed files with 610 additions and 29 deletions
@@ -1,4 +1,4 @@
# meta-decompile v0.5 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.6 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -195,18 +195,37 @@ function Attr-ToDsl {
if ($ix) { if ($ix.InnerText -eq 'Index') { $flags += 'index' } elseif ($ix.InnerText -eq 'IndexWithAdditionalOrder') { $flags += 'indexAdditional' } }
$ml = $ap.SelectSingleNode('md:MultiLine', $nsm); if ($ml -and $ml.InnerText -eq 'true') { $flags += 'multiline' }
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}). Кастомный синоним ИЛИ наличие подсказки → object-форма.
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}).
$synVal = Get-MLValue ($ap.SelectSingleNode('md:Synonym', $nsm))
$synCustom = $false
if ($synVal -is [string]) { if ($synVal -ne (Split-CamelWords $nm)) { $synCustom = $true } }
elseif ($null -ne $synVal) { $synCustom = $true } # {ru,en} = всегда кастом
$ttVal = Get-MLValue ($ap.SelectSingleNode('md:ToolTip', $nsm))
if ($synCustom -or ($null -ne $ttVal)) {
# Extra-свойства реквизита (omit-on-default). Наличие любого → object-форма.
# $en(tag) → InnerText узла или $null.
$en = { param($tag) $n = $ap.SelectSingleNode("md:$tag", $nsm); if ($n) { $n.InnerText } else { $null } }
$extra = [ordered]@{}
$v = & $en 'Comment'; if ($v) { $extra['comment'] = $v }
$v = & $en 'FullTextSearch'; if ($v -and $v -ne 'Use') { $extra['fullTextSearch'] = $v }
$v = & $en 'FillFromFillingValue'; if ($v -eq 'true') { $extra['fillFromFillingValue'] = $true }
$v = & $en 'CreateOnInput'; if ($v -and $v -ne 'Auto') { $extra['createOnInput'] = $v }
$v = & $en 'QuickChoice'; if ($v -and $v -ne 'Auto') { $extra['quickChoice'] = $v }
$v = & $en 'DataHistory'; if ($v -and $v -ne 'Use') { $extra['dataHistory'] = $v }
$v = & $en 'Use'; if ($v -and $v -ne 'ForItem') { $extra['use'] = $v }
$v = & $en 'PasswordMode'; if ($v -eq 'true') { $extra['passwordMode'] = $true }
$v = & $en 'Mask'; if ($v) { $extra['mask'] = $v }
$v = & $en 'ChoiceHistoryOnInput'; if ($v -and $v -ne 'Auto') { $extra['choiceHistoryOnInput'] = $v }
$v = & $en 'FillChecking'; if ($v -eq 'ShowWarning') { $extra['fillChecking'] = 'ShowWarning' }
$fmtV = Get-MLValue ($ap.SelectSingleNode('md:Format', $nsm)); if ($null -ne $fmtV) { $extra['format'] = $fmtV }
$efmtV = Get-MLValue ($ap.SelectSingleNode('md:EditFormat', $nsm)); if ($null -ne $efmtV) { $extra['editFormat'] = $efmtV }
if ($synCustom -or ($null -ne $ttVal) -or $extra.Count -gt 0) {
$o = [ordered]@{ name = $nm }
if ($ts) { $o['type'] = $ts }
if ($synCustom) { $o['synonym'] = $synVal }
if ($null -ne $ttVal) { $o['tooltip'] = $ttVal }
foreach ($k in $extra.Keys) { $o[$k] = $extra[$k] }
if ($flags.Count -gt 0) { $o['flags'] = [System.Collections.ArrayList]@($flags) }
return $o
}