From 85e13e95f2a859fe37c9c5be70e643eac1374d85 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Wed, 1 Jul 2026 10:37:32 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-decompile):=20=D0=B7=D0=B0=D1=85?= =?UTF-8?q?=D0=B2=D0=B0=D1=82=20=D0=BA=D0=B0=D1=81=D1=82=D0=BE=D0=BC=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D1=81=D0=B8=D0=BD=D0=BE=D0=BD=D0=B8=D0=BC?= =?UTF-8?q?=D0=B0=20=D1=80=D0=B5=D0=BA=D0=B2=D0=B8=D0=B7=D0=B8=D1=82=D0=B0?= =?UTF-8?q?=20(object-=D1=84=D0=BE=D1=80=D0=BC=D0=B0)=20+=20=D1=82=D0=BE?= =?UTF-8?q?=D1=87=D0=BD=D0=BE=D0=B5=20=D0=B7=D0=B5=D1=80=D0=BA=D0=B0=D0=BB?= =?UTF-8?q?=D0=BE=20Split-CamelCase=20(v0.2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раундтрип-фикс (класс-1, декомпилятор): реквизит с синонимом ≠ авто теперь эмитится в object-форме {name, type, synonym, flags} вместо shorthand (который синоним терял). Синоним==авто → компактный shorthand как прежде. Split-CamelWords переписан байт-в-байт под Split-CamelCase компилятора (прежняя версия имела лишние правила: цифры, подряд-заглавные → риск ложных «синоним==авто»). Срез ~12k строк на полном прогоне (1640 каталогов). Пометка: predefined-эмиссия остаётся черновой; StandardAttributes-кастомизации — следующая категория (в обсуждении). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../meta-decompile/scripts/meta-decompile.ps1 | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 index 38de2fc1..564f48ac 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 @@ -1,4 +1,4 @@ -# meta-decompile v0.1 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.2 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только @@ -105,14 +105,15 @@ function Get-MLru { if ($it) { return $it.InnerText } return $null } -# Авто-синоним: CamelCase → слова (инверс Split-CamelCase). Если совпадает — ключ опускаем. +# Авто-синоним: точное зеркало Split-CamelCase из meta-compile (стр.354). Совпало → ключ опускаем. +# ВАЖНО: логика должна совпадать байт-в-байт с компилятором, иначе ложные «синоним==авто» → диффы. function Split-CamelWords { param([string]$name) - if (-not $name) { return "" } - $s = [regex]::Replace($name, '(?<=[а-яёa-z0-9])(?=[А-ЯЁA-Z])', ' ') - $s = [regex]::Replace($s, '(?<=[А-ЯЁA-Z])(?=[А-ЯЁA-Z][а-яёa-z])', ' ') - if ($s.Length -gt 1) { $s = $s.Substring(0,1) + $s.Substring(1).ToLower() } - return $s + if (-not $name) { return $name } + $result = [regex]::Replace($name, '([а-яё])([А-ЯЁ])', '$1 $2') + $result = [regex]::Replace($result, '([a-z])([A-Z])', '$1 $2') + if ($result.Length -gt 1) { $result = $result.Substring(0,1) + $result.Substring(1).ToLower() } + return $result } $objName = P 'Name' @@ -161,8 +162,9 @@ function Get-TypeShorthand { return ($parts -join ' + ') } -# --- Реквизит → shorthand "Имя: Тип | флаги" --- -function Attr-ToShorthand { +# --- Реквизит → DSL: shorthand-строка "Имя: Тип | флаги" ЛИБО object-форма при кастомном синониме. +# (Синоним ≠ авто → object {name, type, synonym, [flags]}; иначе компактный shorthand.) --- +function Attr-ToDsl { param($attrNode) $ap = $attrNode.SelectSingleNode('md:Properties', $nsm) $nm = ($ap.SelectSingleNode('md:Name', $nsm)).InnerText @@ -172,6 +174,16 @@ function Attr-ToShorthand { $ix = $ap.SelectSingleNode('md:Indexing', $nsm) 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' } + + $syn = Get-MLru ($ap.SelectSingleNode('md:Synonym', $nsm)) + # Кастомный синоним (есть и ≠ авто) → object-форма (shorthand его не выражает). + if ($syn -and $syn -ne (Split-CamelWords $nm)) { + $o = [ordered]@{ name = $nm } + if ($ts) { $o['type'] = $ts } + $o['synonym'] = $syn + if ($flags.Count -gt 0) { $o['flags'] = [System.Collections.ArrayList]@($flags) } + return $o + } $head = if ($ts) { "${nm}: $ts" } else { $nm } if ($flags.Count -gt 0) { return "$head | " + ($flags -join ', ') } return $head @@ -220,7 +232,7 @@ if ($childObjs) { $attrs = @($childObjs.SelectNodes('md:Attribute', $nsm)) if ($attrs.Count -gt 0) { $arr = [System.Collections.ArrayList]@() - foreach ($a in $attrs) { [void]$arr.Add((Attr-ToShorthand $a)) } + foreach ($a in $attrs) { [void]$arr.Add((Attr-ToDsl $a)) } $dsl['attributes'] = $arr } $tsNodes = @($childObjs.SelectNodes('md:TabularSection', $nsm)) @@ -231,7 +243,7 @@ if ($childObjs) { $tsName = ($tsp.SelectSingleNode('md:Name', $nsm)).InnerText $tco = $ts.SelectSingleNode('md:ChildObjects', $nsm) $cols = [System.Collections.ArrayList]@() - if ($tco) { foreach ($ca in @($tco.SelectNodes('md:Attribute', $nsm))) { [void]$cols.Add((Attr-ToShorthand $ca)) } } + if ($tco) { foreach ($ca in @($tco.SelectNodes('md:Attribute', $nsm))) { [void]$cols.Add((Attr-ToDsl $ca)) } } $tsMap[$tsName] = $cols } $dsl['tabularSections'] = $tsMap