feat(meta-compile,meta-decompile): презентации объекта (Object/List/Extended*/Explanation, ML) (v1.25/v0.10)

Раундтрип-находка: презентации мультиязычны и непусты у многих справочников (корпус: ObjectPresentation
1316/803-multi, ListPresentation 208, Explanation 101, Extended* 69/75), компилятор писал пусто.

DSL-ключи (ML, omit-on-default): objectPresentation, extendedObjectPresentation, listPresentation,
extendedListPresentation, explanation. Эмиссия через Emit-MLText во всех 8 местах (типы, где эти свойства
есть — безопасно: без ключа → self-close = прежнее поведение). Декомпилятор захватывает через Get-MLValue.

spec §7.1; тест-кейс catalog-attr-ml расширен.
Валидация: PS==PY; ObjectPresentation/ListPresentation impact 0; −17135 (70571→53436, вкл. добитый
пробельный ToolTip-остаток нормализацией); регресс 37/37; 1С-cert зелёный.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-03 16:37:39 +03:00
parent 40cdd57619
commit 1701bdac96
6 changed files with 113 additions and 83 deletions
@@ -1380,11 +1380,11 @@ function Emit-CatalogProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<CreateOnInput>DontUse</CreateOnInput>"
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
@@ -1489,11 +1489,11 @@ function Emit-DocumentProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
X "$i<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>"
@@ -1910,11 +1910,11 @@ function Emit-ExchangePlanProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<CreateOnInput>DontUse</CreateOnInput>"
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
@@ -2017,11 +2017,11 @@ function Emit-ChartOfCharacteristicTypesProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<CreateOnInput>DontUse</CreateOnInput>"
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
@@ -2155,11 +2155,11 @@ function Emit-ChartOfAccountsProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<CreateOnInput>DontUse</CreateOnInput>"
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
@@ -2272,11 +2272,11 @@ function Emit-ChartOfCalculationTypesProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<CreateOnInput>DontUse</CreateOnInput>"
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
}
@@ -2388,11 +2388,11 @@ function Emit-BusinessProcessProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
X "$i<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>"
@@ -2461,11 +2461,11 @@ function Emit-TaskProperties {
$fullTextSearch = Get-EnumProp "FullTextSearch" "fullTextSearch" "Use"
X "$i<FullTextSearch>$fullTextSearch</FullTextSearch>"
X "$i<ObjectPresentation/>"
X "$i<ExtendedObjectPresentation/>"
X "$i<ListPresentation/>"
X "$i<ExtendedListPresentation/>"
X "$i<Explanation/>"
Emit-MLText $i "ObjectPresentation" $def.objectPresentation
Emit-MLText $i "ExtendedObjectPresentation" $def.extendedObjectPresentation
Emit-MLText $i "ListPresentation" $def.listPresentation
Emit-MLText $i "ExtendedListPresentation" $def.extendedListPresentation
Emit-MLText $i "Explanation" $def.explanation
X "$i<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>"
X "$i<DataHistory>DontUse</DataHistory>"
X "$i<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>"
@@ -1319,11 +1319,11 @@ def emit_catalog_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
@@ -1406,11 +1406,11 @@ def emit_document_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>')
@@ -1762,11 +1762,11 @@ def emit_exchange_plan_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
@@ -1854,11 +1854,11 @@ def emit_chart_of_characteristic_types_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
@@ -1967,11 +1967,11 @@ def emit_chart_of_accounts_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
@@ -2059,11 +2059,11 @@ def emit_chart_of_calculation_types_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<CreateOnInput>DontUse</CreateOnInput>')
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
@@ -2156,11 +2156,11 @@ def emit_business_process_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>')
@@ -2223,11 +2223,11 @@ def emit_task_properties(indent):
X(f'{i}<DataLockControlMode>{data_lock_control_mode}</DataLockControlMode>')
full_text_search = get_enum_prop('FullTextSearch', 'fullTextSearch', 'Use')
X(f'{i}<FullTextSearch>{full_text_search}</FullTextSearch>')
X(f'{i}<ObjectPresentation/>')
X(f'{i}<ExtendedObjectPresentation/>')
X(f'{i}<ListPresentation/>')
X(f'{i}<ExtendedListPresentation/>')
X(f'{i}<Explanation/>')
emit_mltext(i, 'ObjectPresentation', defn.get('objectPresentation'))
emit_mltext(i, 'ExtendedObjectPresentation', defn.get('extendedObjectPresentation'))
emit_mltext(i, 'ListPresentation', defn.get('listPresentation'))
emit_mltext(i, 'ExtendedListPresentation', defn.get('extendedListPresentation'))
emit_mltext(i, 'Explanation', defn.get('explanation'))
X(f'{i}<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>')
X(f'{i}<DataHistory>DontUse</DataHistory>')
X(f'{i}<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>')
@@ -1,4 +1,4 @@
# meta-decompile v0.9 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.10 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -274,6 +274,15 @@ Add-EnumProp 'choiceMode' 'ChoiceMode' 'BothWays'
Add-EnumProp 'dataLockControlMode' 'DataLockControlMode' 'Automatic'
Add-EnumProp 'fullTextSearch' 'FullTextSearch' 'Use'
# Презентации (ML, компилятор пишет пусто → omit-on-empty).
foreach ($pp in @(
@('ObjectPresentation','objectPresentation'), @('ExtendedObjectPresentation','extendedObjectPresentation'),
@('ListPresentation','listPresentation'), @('ExtendedListPresentation','extendedListPresentation'),
@('Explanation','explanation'))) {
$pv = Get-MLValue ($props.SelectSingleNode("md:$($pp[0])", $nsm))
if ($null -ne $pv) { $dsl[$pp[1]] = $pv }
}
# --- StandardAttributes: блок есть ⟺ кастомизация ≥1 стандартного реквизита.
# Захватываем ОТКЛОНЕНИЯ от профиля материализованного блока (профиль компилятор восстановит сам).
# Профиль Catalog: Owner{FC=ShowError,FFV=true}, Parent{FFV=true}, Description{FC=ShowError}. ---
+5
View File
@@ -272,6 +272,11 @@ JSON DSL для описания объектов метаданных конф
| `dataLockControlMode` | `Automatic` | DataLockControlMode |
| `fullTextSearch` | `Use` | FullTextSearch |
| `owners` | `[]` | Owners |
| `objectPresentation` | пусто | ObjectPresentation (ML) |
| `extendedObjectPresentation` | пусто | ExtendedObjectPresentation (ML) |
| `listPresentation` | пусто | ListPresentation (ML) |
| `extendedListPresentation` | пусто | ExtendedListPresentation (ML) |
| `explanation` | пусто | Explanation (ML) |
| `standardAttributes` | *(ключа нет → блок опущен)* | StandardAttributes |
| `attributes` | `[]` | → Attribute в ChildObjects |
| `tabularSections` | `{}` | → TabularSection в ChildObjects |
@@ -3,6 +3,8 @@
"input": {
"type": "Catalog", "name": "Контрагенты",
"synonym": { "ru": "Контрагенты", "en": "Counterparties" },
"objectPresentation": { "ru": "Контрагент", "en": "Counterparty" },
"explanation": "Список контрагентов организации",
"attributes": [
{ "name": "ИНН", "type": "String(12)", "synonym": { "ru": "ИНН", "en": "TIN" }, "tooltip": "Идентификационный номер налогоплательщика" },
{ "name": "Комментарий", "type": "String(200)", "tooltip": { "ru": "Произвольный комментарий", "en": "Free-form comment" } }
@@ -79,11 +79,25 @@
<DataLockFields/>
<DataLockControlMode>Automatic</DataLockControlMode>
<FullTextSearch>Use</FullTextSearch>
<ObjectPresentation/>
<ObjectPresentation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Контрагент</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content>Counterparty</v8:content>
</v8:item>
</ObjectPresentation>
<ExtendedObjectPresentation/>
<ListPresentation/>
<ExtendedListPresentation/>
<Explanation/>
<Explanation>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Список контрагентов организации</v8:content>
</v8:item>
</Explanation>
<CreateOnInput>DontUse</CreateOnInput>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
<DataHistory>DontUse</DataHistory>