feat(skd): multi-orderExpression на dataSet field

На одном поле может быть несколько <orderExpression> (multi-sort fallback).
decompile сохраняет массив (single → object back-compat), compile принимает оба.

sample30: −30 строк, +2 отчёта в bit-perfect (27 with-diff).
This commit is contained in:
Nick Shirokov
2026-05-23 12:54:53 +03:00
parent 9b4bb3d9b8
commit a66246095c
3 changed files with 54 additions and 35 deletions
@@ -1,4 +1,4 @@
# skd-compile v1.63 — Compile 1C DCS from JSON
# skd-compile v1.64 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -948,17 +948,26 @@ function Emit-Field {
X "$indent`t</role>"
}
# OrderExpression — после role, до valueType
# OrderExpression — после role, до valueType. Допустим массив (multi-sort).
if ($f["orderExpression"]) {
$oe = $f["orderExpression"]
$expr = if ($oe.expression) { "$($oe.expression)" } else { '' }
$oType = if ($oe.orderType) { "$($oe.orderType)" } else { 'Asc' }
$autoOrder = if ($null -ne $oe.autoOrder) { $(if ($oe.autoOrder) { 'true' } else { 'false' }) } else { 'false' }
X "$indent`t<orderExpression>"
X "$indent`t`t<dcscom:expression>$(Esc-Xml $expr)</dcscom:expression>"
X "$indent`t`t<dcscom:orderType>$oType</dcscom:orderType>"
X "$indent`t`t<dcscom:autoOrder>$autoOrder</dcscom:autoOrder>"
X "$indent`t</orderExpression>"
$oeRaw = $f["orderExpression"]
if ($oeRaw -is [System.Collections.IDictionary]) {
$oeList = @($oeRaw)
} elseif ($oeRaw -is [System.Collections.IList]) {
$oeList = $oeRaw
} else {
$oeList = @($oeRaw)
}
foreach ($oe in $oeList) {
$expr = if ($oe.expression) { "$($oe.expression)" } else { '' }
$oType = if ($oe.orderType) { "$($oe.orderType)" } else { 'Asc' }
$autoOrder = if ($null -ne $oe.autoOrder) { $(if ($oe.autoOrder) { 'true' } else { 'false' }) } else { 'false' }
X "$indent`t<orderExpression>"
X "$indent`t`t<dcscom:expression>$(Esc-Xml $expr)</dcscom:expression>"
X "$indent`t`t<dcscom:orderType>$oType</dcscom:orderType>"
X "$indent`t`t<dcscom:autoOrder>$autoOrder</dcscom:autoOrder>"
X "$indent`t</orderExpression>"
}
}
# ValueType
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.63 — Compile 1C DCS from JSON
# skd-compile v1.64 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -726,16 +726,18 @@ def emit_field(lines, field_def, indent):
# OrderExpression — после role, до valueType
if f.get('orderExpression'):
oe = f['orderExpression']
expr = str(oe.get('expression', ''))
o_type = str(oe.get('orderType', 'Asc'))
auto = oe.get('autoOrder', False)
auto_str = 'true' if auto else 'false'
lines.append(f'{indent}\t<orderExpression>')
lines.append(f'{indent}\t\t<dcscom:expression>{esc_xml(expr)}</dcscom:expression>')
lines.append(f'{indent}\t\t<dcscom:orderType>{o_type}</dcscom:orderType>')
lines.append(f'{indent}\t\t<dcscom:autoOrder>{auto_str}</dcscom:autoOrder>')
lines.append(f'{indent}\t</orderExpression>')
oe_raw = f['orderExpression']
oe_list = oe_raw if isinstance(oe_raw, list) else [oe_raw]
for oe in oe_list:
expr = str(oe.get('expression', ''))
o_type = str(oe.get('orderType', 'Asc'))
auto = oe.get('autoOrder', False)
auto_str = 'true' if auto else 'false'
lines.append(f'{indent}\t<orderExpression>')
lines.append(f'{indent}\t\t<dcscom:expression>{esc_xml(expr)}</dcscom:expression>')
lines.append(f'{indent}\t\t<dcscom:orderType>{o_type}</dcscom:orderType>')
lines.append(f'{indent}\t\t<dcscom:autoOrder>{auto_str}</dcscom:autoOrder>')
lines.append(f'{indent}\t</orderExpression>')
# ValueType
if f.get('type'):
@@ -1,4 +1,4 @@
# skd-decompile v0.47 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# skd-decompile v0.48 — Decompile 1C DCS Template.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -523,19 +523,27 @@ function Build-Field {
param($fieldNode, [string]$loc)
# inputParameters теперь поддерживается в DSL — читается ниже в needsObject
$inputParameters = Read-InputParameters -parentNode $fieldNode
# orderExpression теперь поддерживается в DSL — читается ниже в needsObject
$orderExprNode = $fieldNode.SelectSingleNode("r:orderExpression", $ns)
# orderExpression теперь поддерживается в DSL — читается ниже в needsObject.
# На одном поле может быть несколько <orderExpression> (multi-sort fallback),
# в этом случае сохраняем массив; единичный — как объект (back-compat).
$orderExprNodes = $fieldNode.SelectNodes("r:orderExpression", $ns)
$orderExpression = $null
if ($orderExprNode) {
$oeExpr = Get-Text $orderExprNode "dcscom:expression"
$oeType = Get-Text $orderExprNode "dcscom:orderType"
$oeAuto = Get-Text $orderExprNode "dcscom:autoOrder"
$orderExpression = [ordered]@{}
if ($oeExpr) { $orderExpression['expression'] = $oeExpr }
if ($oeType) { $orderExpression['orderType'] = $oeType }
# autoOrder=false — это дефолт; emit'им только если true (или явно записан false)
if ($oeAuto -eq 'true') { $orderExpression['autoOrder'] = $true }
elseif ($oeAuto -eq 'false') { $orderExpression['autoOrder'] = $false }
$orderExpressionList = @()
foreach ($oeN in $orderExprNodes) {
$oeExpr = Get-Text $oeN "dcscom:expression"
$oeType = Get-Text $oeN "dcscom:orderType"
$oeAuto = Get-Text $oeN "dcscom:autoOrder"
$oe = [ordered]@{}
if ($oeExpr) { $oe['expression'] = $oeExpr }
if ($oeType) { $oe['orderType'] = $oeType }
if ($oeAuto -eq 'true') { $oe['autoOrder'] = $true }
elseif ($oeAuto -eq 'false') { $oe['autoOrder'] = $false }
$orderExpressionList += ,$oe
}
if ($orderExpressionList.Count -eq 1) {
$orderExpression = $orderExpressionList[0]
} elseif ($orderExpressionList.Count -gt 1) {
$orderExpression = $orderExpressionList
}
$dataPath = Get-Text $fieldNode "r:dataPath"
$fieldName = Get-Text $fieldNode "r:field"