fix(skd-compile): эмитить пустые selection/filter/order/CA блоки если есть block-level meta

Раньше Emit-Selection/Filter/Order/ConditionalAppearance early-return при
пустых items, даже если decompile сохранил blockViewMode/blockUserSettingID.
Caller (settingsVariant) тоже не вызывал эти функции на пустых items.

Теперь блоки эмитятся когда есть items ИЛИ block-level meta. Реальный кейс
из ERP: <dcsset:conditionalAppearance><dcsset:viewMode>Normal</dcsset:viewMode>
</dcsset:conditionalAppearance> — пустой CA блок только с viewMode.

sample30: −84 строки (1026 → 942).
This commit is contained in:
Nick Shirokov
2026-05-23 22:00:51 +03:00
parent 53536b72f5
commit fdc8c518aa
2 changed files with 60 additions and 35 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.83 — Compile 1C DCS from JSON
# skd-compile v1.84 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -2004,7 +2004,9 @@ function Emit-SelectionItem {
function Emit-Selection {
param($items, [string]$indent, [switch]$skipAuto, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
$hasItems = $items -and $items.Count -gt 0
$hasBlockMeta = ($null -ne $blockViewMode) -or ($null -ne $blockUserSettingID)
if (-not $hasItems -and -not $hasBlockMeta) { return }
X "$indent<dcsset:selection>"
foreach ($item in $items) {
@@ -2150,7 +2152,9 @@ function Emit-FilterItem {
function Emit-Filter {
param($items, [string]$indent, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
$hasItems = $items -and $items.Count -gt 0
$hasBlockMeta = ($null -ne $blockViewMode) -or ($null -ne $blockUserSettingID)
if (-not $hasItems -and -not $hasBlockMeta) { return }
X "$indent<dcsset:filter>"
foreach ($item in $items) {
@@ -2193,7 +2197,9 @@ function Emit-Filter {
function Emit-Order {
param($items, [string]$indent, [switch]$skipAuto, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
$hasItems = $items -and $items.Count -gt 0
$hasBlockMeta = ($null -ne $blockViewMode) -or ($null -ne $blockUserSettingID)
if (-not $hasItems -and -not $hasBlockMeta) { return }
X "$indent<dcsset:order>"
foreach ($item in $items) {
@@ -2323,7 +2329,9 @@ function Emit-AppearanceValue {
function Emit-ConditionalAppearance {
param($items, [string]$indent, $blockViewMode = $null, $blockUserSettingID = $null)
if (-not $items -or $items.Count -eq 0) { return }
$hasItems = $items -and $items.Count -gt 0
$hasBlockMeta = ($null -ne $blockViewMode) -or ($null -ne $blockUserSettingID)
if (-not $hasItems -and -not $hasBlockMeta) { return }
X "$indent<dcsset:conditionalAppearance>"
foreach ($ca in $items) {
@@ -3068,24 +3076,30 @@ function Emit-SettingsVariants {
Emit-UserFields -items $s.userFields -indent "`t`t`t"
}
# Selection (Auto items only belong at group level, not top-level settings)
if ($s.selection) {
Emit-Selection -items $s.selection -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'selection') -blockUserSettingID (Get-BlockUSID 'selection')
# Selection (Auto items only belong at group level, not top-level settings).
# Эмитим даже если items пустые, но есть block-level viewMode/userSettingID
# (platform пишет такой блок как <dcsset:selection><dcsset:viewMode>.../...>).
$svm = Get-BlockVM 'selection'; $susid = Get-BlockUSID 'selection'
if ($s.selection -or $null -ne $svm -or $null -ne $susid) {
Emit-Selection -items $s.selection -indent "`t`t`t" -skipAuto -blockViewMode $svm -blockUserSettingID $susid
}
# Filter
if ($s.filter) {
Emit-Filter -items $s.filter -indent "`t`t`t" -blockViewMode (Get-BlockVM 'filter') -blockUserSettingID (Get-BlockUSID 'filter')
$fvm = Get-BlockVM 'filter'; $fusid = Get-BlockUSID 'filter'
if ($s.filter -or $null -ne $fvm -or $null -ne $fusid) {
Emit-Filter -items $s.filter -indent "`t`t`t" -blockViewMode $fvm -blockUserSettingID $fusid
}
# Order (Auto items only belong at group level, not top-level settings)
if ($s.order) {
Emit-Order -items $s.order -indent "`t`t`t" -skipAuto -blockViewMode (Get-BlockVM 'order') -blockUserSettingID (Get-BlockUSID 'order')
$ovm = Get-BlockVM 'order'; $ousid = Get-BlockUSID 'order'
if ($s.order -or $null -ne $ovm -or $null -ne $ousid) {
Emit-Order -items $s.order -indent "`t`t`t" -skipAuto -blockViewMode $ovm -blockUserSettingID $ousid
}
# ConditionalAppearance
if ($s.conditionalAppearance) {
Emit-ConditionalAppearance -items $s.conditionalAppearance -indent "`t`t`t" -blockViewMode (Get-BlockVM 'conditionalAppearance') -blockUserSettingID (Get-BlockUSID 'conditionalAppearance')
$cavm = Get-BlockVM 'conditionalAppearance'; $causid = Get-BlockUSID 'conditionalAppearance'
if ($s.conditionalAppearance -or $null -ne $cavm -or $null -ne $causid) {
Emit-ConditionalAppearance -items $s.conditionalAppearance -indent "`t`t`t" -blockViewMode $cavm -blockUserSettingID $causid
}
# OutputParameters (platform does NOT emit <viewMode> on this block)
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.83 — Compile 1C DCS from JSON
# skd-compile v1.84 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -1653,10 +1653,12 @@ def emit_selection_item(lines, item, indent):
def emit_selection(lines, items, indent, skip_auto=False, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
has_items = items and len(items) > 0
has_block_meta = block_view_mode is not None or block_user_setting_id is not None
if not has_items and not has_block_meta:
return
lines.append(f'{indent}<dcsset:selection>')
for item in items:
for item in (items or []):
if skip_auto and isinstance(item, str) and item == 'Auto':
continue
emit_selection_item(lines, item, f'{indent}\t')
@@ -1779,11 +1781,13 @@ def emit_filter_item(lines, item, indent):
def emit_filter(lines, items, indent, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
has_items = items and len(items) > 0
has_block_meta = block_view_mode is not None or block_user_setting_id is not None
if not has_items and not has_block_meta:
return
lines.append(f'{indent}<dcsset:filter>')
for item in items:
for item in (items or []):
if isinstance(item, str):
parsed = parse_filter_shorthand(item)
filter_obj = {
@@ -1812,11 +1816,13 @@ def emit_filter(lines, items, indent, block_view_mode=None, block_user_setting_i
def emit_order(lines, items, indent, skip_auto=False, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
has_items = items and len(items) > 0
has_block_meta = block_view_mode is not None or block_user_setting_id is not None
if not has_items and not has_block_meta:
return
lines.append(f'{indent}<dcsset:order>')
for item in items:
for item in (items or []):
if isinstance(item, str):
if item == 'Auto':
if not skip_auto:
@@ -1913,11 +1919,13 @@ def emit_appearance_value(lines, key, val, indent):
def emit_conditional_appearance(lines, items, indent, block_view_mode=None, block_user_setting_id=None):
if not items or len(items) == 0:
has_items = items and len(items) > 0
has_block_meta = block_view_mode is not None or block_user_setting_id is not None
if not has_items and not has_block_meta:
return
lines.append(f'{indent}<dcsset:conditionalAppearance>')
for ca in items:
for ca in (items or []):
lines.append(f'{indent}\t<dcsset:item>')
if ca.get('use') is False:
@@ -2459,21 +2467,24 @@ def emit_settings_variants(lines, defn):
if s.get('userFields'):
emit_user_fields(lines, s['userFields'], '\t\t\t')
# Selection
if s.get('selection'):
emit_selection(lines, s['selection'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('selection'), block_user_setting_id=_block_usid('selection'))
# Selection/Filter/Order/CA — эмитим даже если items пустые, но есть
# block-level viewMode/userSettingID (platform пишет такой блок как
# <dcsset:selection><dcsset:viewMode>...</dcsset:viewMode></dcsset:selection>).
svm, susid = _block_vm('selection'), _block_usid('selection')
if s.get('selection') or svm is not None or susid is not None:
emit_selection(lines, s.get('selection'), '\t\t\t', skip_auto=True, block_view_mode=svm, block_user_setting_id=susid)
# Filter
if s.get('filter'):
emit_filter(lines, s['filter'], '\t\t\t', block_view_mode=_block_vm('filter'), block_user_setting_id=_block_usid('filter'))
fvm, fusid = _block_vm('filter'), _block_usid('filter')
if s.get('filter') or fvm is not None or fusid is not None:
emit_filter(lines, s.get('filter'), '\t\t\t', block_view_mode=fvm, block_user_setting_id=fusid)
# Order
if s.get('order'):
emit_order(lines, s['order'], '\t\t\t', skip_auto=True, block_view_mode=_block_vm('order'), block_user_setting_id=_block_usid('order'))
ovm, ousid = _block_vm('order'), _block_usid('order')
if s.get('order') or ovm is not None or ousid is not None:
emit_order(lines, s.get('order'), '\t\t\t', skip_auto=True, block_view_mode=ovm, block_user_setting_id=ousid)
# ConditionalAppearance
if s.get('conditionalAppearance'):
emit_conditional_appearance(lines, s['conditionalAppearance'], '\t\t\t', block_view_mode=_block_vm('conditionalAppearance'), block_user_setting_id=_block_usid('conditionalAppearance'))
cavm, causid = _block_vm('conditionalAppearance'), _block_usid('conditionalAppearance')
if s.get('conditionalAppearance') or cavm is not None or causid is not None:
emit_conditional_appearance(lines, s.get('conditionalAppearance'), '\t\t\t', block_view_mode=cavm, block_user_setting_id=causid)
# OutputParameters (platform does NOT emit <viewMode> on this block)
if s.get('outputParameters'):