fix(meta-decompile): предопределённый элемент с разделителем в значении

Сокращённая запись предопределённого элемента — "(Код) Имя [Наименование]".
Компилятор читает код как [^)]*, а имя как \S+, поэтому значение, содержащее
собственные разделители грамматики, разбор ломает: код "114 (108)" даёт
"(114 (108)) Код108", регулярка не сходится, и элемент теряет и имя, и код —
в XML уходят пустые <Name/> и <Code/>.

Декомпилятор теперь проверяет однозначность и при конфликте отдаёт объектную
форму {name, code, description}, которую компилятор поддерживает давно.
Конфликтом считаются ')' или ':' в коде, пробел/скобка/':' в имени, скобки
в наименовании.

Затронуто по 6 элементов в БП и в ERP (вычеты НДФЛ с кодами вида "117 (109)").
Пробел давний: эмиссия predefined помечена в WORKFLOW как черновая, а на УТ
таких кодов нет — вскрылось только на корпусе 2.17.

Проверка: справочники acc+erp+ut 2159/2159 (было 2157), JSON декомпилятора
побайтово совпадает у PS и py, сюиты meta-decompile 3/3 на обоих портах и
meta-compile 76/76.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-08-02 12:28:54 +03:00
co-authored by Claude Opus 5
parent a305c1bc89
commit b174ca659d
2 changed files with 13 additions and 4 deletions
@@ -1,4 +1,4 @@
# meta-decompile v0.60 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.61 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document,
@@ -1513,7 +1513,12 @@ if (Test-Path -LiteralPath $predefPath) {
# Компактная строка для плоских: без узла Type (Catalog) ИЛИ с непустым типом → "(Код) Имя [Наим]: Тип".
# Пустой <Type/> в короткую не влезает (нужен явный маркер) → object-форма с type:''.
if (-not $isFolder -and $kids.Count -eq 0 -and ($null -eq $typeStr -or $typeStr -ne '')) {
# Сокращение неоднозначно, если значение содержит собственные разделители грамматики
# "(Код) Имя [Наим]: Тип": ')' или ':' в коде, пробел/скобка/':' в имени, скобки в наименовании.
# Компилятор разбирает код как [^)]*, а имя как \S+ — на "114 (108)" разбор рассыпается,
# и элемент терял и имя, и код (6 элементов в БП и столько же в ERP).
$ambiguous = ($code -match '[):]') -or ($name -match '[\s:\[\]()]') -or ($desc -match '[\[\]]')
if (-not $isFolder -and $kids.Count -eq 0 -and ($null -eq $typeStr -or $typeStr -ne '') -and -not $ambiguous) {
$s = if ($code) { "($code) $name" } else { $name }
if ($desc -eq '') { $s = "$s []" }
elseif ($desc -cne $auto) { $s = "$s [$desc]" }
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-decompile v0.60 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.61 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Зеркало meta-decompile.ps1 (КАНОН). Структура 1:1 — те же имена функций, порядок, комментарии.
@@ -717,7 +717,11 @@ def predef_item_to_dsl(item_el):
auto = split_camel_words(name)
# Компактная строка для плоских: без узла Type (Catalog) ИЛИ с непустым типом → "(Код) Имя [Наим]: Тип".
if (not is_folder) and len(kids) == 0 and (type_str is None or type_str != ''):
# Сокращение неоднозначно, если значение содержит собственные разделители грамматики:
# ')' или ':' в коде, пробел/скобка/':' в имени, скобки в наименовании. Компилятор читает код
# как [^)]*, а имя как \S+ — на "114 (108)" разбор рассыпается и элемент терял имя и код.
ambiguous = bool(re.search(r'[):]', code or '')) or bool(re.search(r'[\s:\[\]()]', name or '')) or bool(re.search(r'[\[\]]', desc or ''))
if (not is_folder) and len(kids) == 0 and (type_str is None or type_str != '') and not ambiguous:
s = ("(%s) %s" % (code, name)) if code else name
if desc == '':
s = s + " []"