mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-08-07 04:00:20 +03:00
feat(meta-compile,meta-decompile): предопределённые элементы Catalog (Ext/Predefined.xml) (v1.19/v0.5)
Раундтрип-находка (класс-3, непокрытый блок — крупнейшая категория ~56k). meta-compile вообще не генерил Ext/Predefined.xml. DSL спроектирован по данным корпуса (9309 элементов) + совместно. DSL `predefined` (массив; строка ИЛИ объект): - строка "(Код) Имя [Наименование]": Имя обяз.; Наименование — нет [..] → авто(Split-CamelCase), [] → пусто (системные/placeholder, 29% корпуса), [текст] → задано; - объект (группа/иерархия): name/code/description/isFolder/childItems + рус.синонимы имя/код/наименование/группа/подчиненные (прощающий ввод). - Код: по codeType каталога (Number→xs:decimal, String→без типа), пусто→<Code/>. meta-compile (дуал-порт): генерация Ext/Predefined.xml (root CatalogPredefinedItems + рекурсия Item). Заодно фикс: Esc-XmlText для ТЕКСТА элемента (& < > без экранирования кавычек — в тексте 1С держит raw). meta-decompile: захват predefined → компактный DSL (строка/объект). Фикс PS-ловушки распаковки одноэлементного @() из if → папки с ОДНИМ ребёнком теряли его. spec meta-dsl-spec.md v2.4 §7.1.2; тест-кейс catalog-predefined. Валидация: PS==PY паритет; predefined-категории 0 (PredefinedData/Item/ChildItems/Description/Code); полный прогон −56620 (218537→161917); регресс 36/36 (ps+py); 1С-cert зелёный (грузится в платформу). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
58bc95264e
commit
253a4fbce0
@@ -330,6 +330,11 @@ function Esc-Xml {
|
||||
param([string]$s)
|
||||
return $s.Replace('&','&').Replace('<','<').Replace('>','>').Replace('"','"')
|
||||
}
|
||||
# Эскейп ТЕКСТА элемента: только & < > (кавычки в тексте 1С держит raw, экранирование только для атрибутов).
|
||||
function Esc-XmlText {
|
||||
param([string]$s)
|
||||
return $s.Replace('&','&').Replace('<','<').Replace('>','>')
|
||||
}
|
||||
|
||||
# ML-значение: строка → один <v8:item> ru; объект {lang: content} → item на язык (в порядке ключей).
|
||||
function Emit-MLItems {
|
||||
@@ -3070,6 +3075,59 @@ $typesNoSubDir = @("DefinedType","ScheduledJob","EventSubscription")
|
||||
|
||||
# Object subdirectory: {OutputDir}/{TypePlural}/{Name}/Ext/
|
||||
$objSubDir = Join-Path $typeDir $objName
|
||||
# --- Predefined data (Ext/Predefined.xml) ---
|
||||
# Элемент DSL: строка "(Код) Имя [Наименование]" ЛИБО объект (+ русские синонимы ключей).
|
||||
# Наименование: нет [..]/ключа → авто(Split-CamelCase Имени); [] / "" → пусто; [текст]/текст → как есть.
|
||||
function Resolve-PredefItem {
|
||||
param($val)
|
||||
if ($val -is [string]) {
|
||||
$m = [regex]::Match($val, '^\s*(?:\(([^)]*)\)\s*)?(\S+)(?:\s*\[(.*)\])?\s*$')
|
||||
$name = $m.Groups[2].Value
|
||||
$code = if ($m.Groups[1].Success) { $m.Groups[1].Value } else { '' }
|
||||
$desc = if ($m.Groups[3].Success) { $m.Groups[3].Value } else { Split-CamelCase $name }
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $false; children = @() }
|
||||
}
|
||||
# Объектная форма + русские синонимы (прощающий ввод).
|
||||
$gv = { param($o, [string[]]$keys) foreach ($k in $keys) { if ($o.PSObject.Properties[$k]) { return $o.$k } } return $null }
|
||||
$name = "$(& $gv $val @('name','имя'))"
|
||||
$codeV = & $gv $val @('code','код')
|
||||
$code = if ($null -ne $codeV) { "$codeV" } else { '' }
|
||||
$hasDesc = $val.PSObject.Properties['description'] -or $val.PSObject.Properties['наименование']
|
||||
$descV = & $gv $val @('description','наименование')
|
||||
$desc = if ($hasDesc) { "$descV" } else { Split-CamelCase $name } # ключа нет → авто; '' → пусто
|
||||
$folderV = & $gv $val @('isFolder','группа')
|
||||
$isFolder = ($folderV -eq $true)
|
||||
$subs = & $gv $val @('childItems','подчиненные')
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $isFolder; children = @(if ($subs) { $subs } else { @() }) }
|
||||
}
|
||||
function Emit-PredefItem {
|
||||
param($sb, $val, [string]$indent, [string]$codeType)
|
||||
$r = Resolve-PredefItem $val
|
||||
[void]$sb.Append("$indent<Item id=`"$(New-Guid-String)`">`n")
|
||||
[void]$sb.Append("$indent`t<Name>$(Esc-XmlText $r.name)</Name>`n")
|
||||
if (-not $r.code) { [void]$sb.Append("$indent`t<Code/>`n") }
|
||||
elseif ($codeType -eq 'Number') { [void]$sb.Append("$indent`t<Code xsi:type=`"xs:decimal`">$(Esc-XmlText $r.code)</Code>`n") }
|
||||
else { [void]$sb.Append("$indent`t<Code>$(Esc-XmlText $r.code)</Code>`n") }
|
||||
if ($r.desc -eq '') { [void]$sb.Append("$indent`t<Description/>`n") }
|
||||
else { [void]$sb.Append("$indent`t<Description>$(Esc-XmlText $r.desc)</Description>`n") }
|
||||
[void]$sb.Append("$indent`t<IsFolder>$(if ($r.isFolder) { 'true' } else { 'false' })</IsFolder>`n")
|
||||
if ($r.children.Count -gt 0) {
|
||||
[void]$sb.Append("$indent`t<ChildItems>`n")
|
||||
foreach ($c in $r.children) { Emit-PredefItem $sb $c "$indent`t`t" $codeType }
|
||||
[void]$sb.Append("$indent`t</ChildItems>`n")
|
||||
}
|
||||
[void]$sb.Append("$indent</Item>`n")
|
||||
}
|
||||
function Build-PredefinedXml {
|
||||
param($items, [string]$xsiType, [string]$codeType)
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
[void]$sb.Append("<?xml version=`"1.0`" encoding=`"UTF-8`"?>`n")
|
||||
[void]$sb.Append("<PredefinedData xmlns=`"http://v8.1c.ru/8.3/xcf/predef`" xmlns:v8=`"http://v8.1c.ru/8.1/data/core`" xmlns:xr=`"http://v8.1c.ru/8.3/xcf/readable`" xmlns:xs=`"http://www.w3.org/2001/XMLSchema`" xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`" xsi:type=`"$xsiType`" version=`"$($script:formatVersion)`">`n")
|
||||
foreach ($it in $items) { Emit-PredefItem $sb $it "`t" $codeType }
|
||||
[void]$sb.Append("</PredefinedData>`n")
|
||||
return $sb.ToString()
|
||||
}
|
||||
|
||||
$extDir = Join-Path $objSubDir "Ext"
|
||||
|
||||
if (-not (Test-Path $typeDir)) {
|
||||
@@ -3168,6 +3226,16 @@ if ($objType -eq "BusinessProcess") {
|
||||
}
|
||||
}
|
||||
|
||||
# Предопределённые элементы (Ext/Predefined.xml) — пока Catalog. Пусто/нет ключа → файл не создаём.
|
||||
if ($objType -eq "Catalog" -and $def.predefined -and @($def.predefined).Count -gt 0) {
|
||||
Ensure-ExtDir
|
||||
$catCodeType = if ($def.codeType) { "$($def.codeType)" } else { 'String' }
|
||||
$predefXml = Build-PredefinedXml @($def.predefined) "CatalogPredefinedItems" $catCodeType
|
||||
$predefPath = Join-Path $extDir "Predefined.xml"
|
||||
[System.IO.File]::WriteAllText($predefPath, $predefXml, $enc)
|
||||
$modulesCreated += $predefPath
|
||||
}
|
||||
|
||||
# --- 17. Register in Configuration.xml ---
|
||||
|
||||
$configXmlPath = Join-Path $OutputDir "Configuration.xml"
|
||||
|
||||
Reference in New Issue
Block a user