mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(meta-compile,meta-decompile): короткая запись типа предопределённых ПВХ (v1.36/v0.25)
Предопределённые виды характеристик несут тип значения на элемент. Раньше это требовало объектной формы; теперь тип выражается короткой строкой после ':' — как в полях СКД/реквизитах: "(Код) Имя [Наименование]: Тип" (тип составной через '+') Правило: нет ':' → без блока Type (Catalog-стиль); непустой тип → короткая строка; пустой <Type/> / папки / с детьми → объектная форма (ключ type). Разбор зеркалит Parse-CalcShorthand: сначала вынуть [Наим] (может содержать ':'), затем отделить тип по ':'. Компилятор принимает обе формы, декомпилятор пишет короткую для плоских элементов. На ВидыСубконтоХозрасчетные все 63 предопределённых из объектов стали компактными строками. Роундтрип/вывод XML не меняется (52 TOTAL). Регресс 47/47 ps1+py, ps1↔py identical. spec §7.2b, кейс chart-of-characteristic-types. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.35 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.36 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -3761,11 +3761,16 @@ $objSubDir = Join-Path $typeDir $objName
|
||||
function Resolve-PredefItem {
|
||||
param($val)
|
||||
if ($val -is [string]) {
|
||||
$m = [regex]::Match($val, '^\s*(?:\(([^)]*)\)\s*)?(\S+)(?:\s*\[(.*)\])?\s*$')
|
||||
# Грамматика "(Код) Имя [Наименование]: Тип" (тип — как в полях СКД/реквизитах). Порядок разбора зеркалит
|
||||
# Parse-CalcShorthand: сначала вынуть [Наим] (может содержать ':'), затем отделить тип по ':'.
|
||||
$s = "$val"; $type = $null; $descRaw = $null; $hasDesc = $false
|
||||
if ($s -match '\[(.*)\]') { $descRaw = $Matches[1]; $hasDesc = $true; $s = $s -replace '\s*\[.*\]', '' }
|
||||
if ($s.Contains(':')) { $p = $s -split ':', 2; $s = $p[0]; $type = $p[1].Trim() } # '' → пустой <Type/>
|
||||
$m = [regex]::Match($s.Trim(), '^\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 = @(); type = $null }
|
||||
$desc = if ($hasDesc) { $descRaw } else { Split-CamelCase $name }
|
||||
return @{ name = $name; code = $code; desc = $desc; isFolder = $false; children = @(); type = $type }
|
||||
}
|
||||
# Объектная форма + русские синонимы (прощающий ввод).
|
||||
$gv = { param($o, [string[]]$keys) foreach ($k in $keys) { if ($o.PSObject.Properties[$k]) { return $o.$k } } return $null }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.35 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.36 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -3583,11 +3583,25 @@ if obj_type in types_with_module:
|
||||
# Наименование: нет [..]/ключа → авто(Split-CamelCase); [] / "" → пусто; [текст]/текст → как есть.
|
||||
def resolve_predef_item(val):
|
||||
if isinstance(val, str):
|
||||
m = re.match(r'^\s*(?:\(([^)]*)\)\s*)?(\S+)(?:\s*\[(.*)\])?\s*$', val)
|
||||
# Грамматика "(Код) Имя [Наименование]: Тип": сначала вынуть [Наим] (может содержать ':'), затем тип по ':'.
|
||||
s = val
|
||||
ptype = None
|
||||
desc_raw = None
|
||||
has_desc = False
|
||||
md = re.search(r'\[(.*)\]', s)
|
||||
if md:
|
||||
desc_raw = md.group(1)
|
||||
has_desc = True
|
||||
s = re.sub(r'\s*\[.*\]', '', s)
|
||||
if ':' in s:
|
||||
left, right = s.split(':', 1)
|
||||
s = left
|
||||
ptype = right.strip() # '' → пустой <Type/>
|
||||
m = re.match(r'^\s*(?:\(([^)]*)\)\s*)?(\S+)\s*$', s.strip())
|
||||
name = m.group(2)
|
||||
code = m.group(1) if m.group(1) is not None else ''
|
||||
desc = m.group(3) if m.group(3) is not None else split_camel_case(name)
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': False, 'children': [], 'type': None}
|
||||
desc = desc_raw if has_desc else split_camel_case(name)
|
||||
return {'name': name, 'code': code, 'desc': desc, 'isFolder': False, 'children': [], 'type': ptype}
|
||||
def gv(keys):
|
||||
for k in keys:
|
||||
if k in val:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# meta-decompile v0.24 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# meta-decompile v0.25 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
#
|
||||
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes. Инверс meta-compile (omit-on-default: ключ эмитим только
|
||||
@@ -732,11 +732,13 @@ if (Test-Path -LiteralPath $predefPath) {
|
||||
$typeStr = if ($typeEl) { Get-TypeShorthand $typeEl } else { $null }
|
||||
$auto = Split-CamelWords $name
|
||||
|
||||
if (-not $isFolder -and $kids.Count -eq 0 -and $null -eq $typeEl) {
|
||||
# Плоский без типа → компактная строка.
|
||||
# Компактная строка для плоских: без узла Type (Catalog) ИЛИ с непустым типом → "(Код) Имя [Наим]: Тип".
|
||||
# Пустой <Type/> в короткую не влезает (нужен явный маркер) → object-форма с type:''.
|
||||
if (-not $isFolder -and $kids.Count -eq 0 -and ($null -eq $typeStr -or $typeStr -ne '')) {
|
||||
$s = if ($code) { "($code) $name" } else { $name }
|
||||
if ($desc -eq '') { $s = "$s []" }
|
||||
elseif ($desc -ne $auto) { $s = "$s [$desc]" }
|
||||
if ($typeStr) { $s = "${s}: $typeStr" }
|
||||
return $s
|
||||
}
|
||||
# Группа/иерархия/с типом → объект.
|
||||
|
||||
+11
-3
@@ -641,9 +641,17 @@ omit-on-empty. Поля пишутся частичной формой (`Standar
|
||||
Стандартные реквизиты ПВХ: PredefinedDataName, Predefined, Ref, DeletionMark, Description, Code, Parent, ValueType
|
||||
(профиль: Наименование → FillChecking=ShowError, Родитель → FillFromFillingValue=true). Блок **условный** (`standardAttributes`).
|
||||
|
||||
**Предопределённые виды** несут **тип значения на элемент** — ключ `type` в объектной форме `predefined`-элемента
|
||||
(строка `"A + B"` или массив; `""` → пустой `<Type/>`; отсутствие ключа → без блока). Пример:
|
||||
`{"name": "Цвет", "code": "000001", "type": "CatalogRef.Цвета"}`.
|
||||
**Предопределённые виды** несут **тип значения на элемент**. Короткая запись — как в полях СКД/реквизитах, тип после `:`:
|
||||
`"(Код) Имя [Наименование]: Тип"` (тип составной через `+`). Объектная форма — ключ `type` (строка/массив; `""` → пустой
|
||||
`<Type/>`). Правило: нет `:`/ключа → без блока Type; непустой тип → короткая строка; пустой `<Type/>` / папки / с детьми →
|
||||
объектная форма. Примеры:
|
||||
```json
|
||||
"predefined": [
|
||||
"(000001) Цвет: CatalogRef.Цвета",
|
||||
"(000002) Размер [Размер одежды]: String(50) + Number(3,0)",
|
||||
{ "name": "Группа", "isFolder": true, "type": "" }
|
||||
]
|
||||
```
|
||||
|
||||
### 7.3 Enum
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
"standardAttributes": { "Description": { "synonym": "Свойство" } },
|
||||
"attributes": ["НаборСвойств: String(100)"],
|
||||
"predefined": [
|
||||
{ "name": "Цвет", "code": "000001", "type": "CatalogRef.ЗначенияСвойств" },
|
||||
{ "name": "Размер", "code": "000002", "type": "String(50) + Number(3,0)" },
|
||||
"(000001) Цвет: CatalogRef.ЗначенияСвойств",
|
||||
"(000002) Размер [Размер одежды]: String(50) + Number(3,0)",
|
||||
{ "name": "Группа", "code": "000003", "isFolder": true, "type": "" }
|
||||
]
|
||||
},
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@
|
||||
<Item id="UUID-002">
|
||||
<Name>Размер</Name>
|
||||
<Code>000002</Code>
|
||||
<Description>Размер</Description>
|
||||
<Description>Размер одежды</Description>
|
||||
<Type>
|
||||
<v8:Type>xs:string</v8:Type>
|
||||
<v8:StringQualifiers>
|
||||
|
||||
Reference in New Issue
Block a user