mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-10 08:04:56 +03:00
fix(skd-decompile): убрать падения на ERP-отчётах с dataSetLink и StandardPeriod без companions
Два бага PS-версии, незаметно роняли 9/30 отчётов sample30 в decompile-fail:
1. Get-Text без xpath → SelectSingleNode("", $ns) с .NET XPathException
"Результатом выражения должен быть NodeSet". Шесть call-sites в
dataSetLinks (sourceDataSet/destinationDataSet/sourceExpression/...)
передавали уже-выбранный узел без второго аргумента; [string]$xpath
дефолтился в "". Фикс: Get-Text возвращает $node.InnerText, если
xpath пустой.
2. $paramByName[$startMatch] при $startMatch=$null → "индекс массива
вычислен как NULL". Возникает на StandardPeriod-параметре, для
которого в отчёте нет companion expressions. Фикс: guard через if.
Python-порт #2 уже был защищён .get(); по #1 в py был обходной костыль
inline-через-inner_text — заменён на единый get_text(node) после
обновления сигнатуры до get_text(node, xpath=None).
verify-roundtrip sample30: 9 bit-perfect + 20 with-diff + 1 ring3 = 30
(до фикса 9 silently падали как decompile-fail, сумма не сходилась).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# skd-decompile v0.88 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||
# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -248,6 +248,7 @@ function ConvertTo-CompactJson {
|
||||
function Get-Text {
|
||||
param($node, [string]$xpath)
|
||||
if (-not $node) { return $null }
|
||||
if ([string]::IsNullOrEmpty($xpath)) { return $node.InnerText }
|
||||
$n = $node.SelectSingleNode($xpath, $ns)
|
||||
if ($n) { return $n.InnerText } else { return $null }
|
||||
}
|
||||
@@ -2713,8 +2714,8 @@ foreach ($p in $paramsRaw) {
|
||||
# Также НЕ сворачиваем если companions имеют availableAsField=false — compile
|
||||
# auto-gen не передаёт этот атрибут (ERP-стиль без него; БСП-стиль с ним —
|
||||
# вариативность не выразима через @autoDates флаг, пусть companions останутся явными).
|
||||
$beginP = $paramByName[$startMatch]
|
||||
$endP = $paramByName[$endMatch]
|
||||
$beginP = if ($startMatch) { $paramByName[$startMatch] } else { $null }
|
||||
$endP = if ($endMatch) { $paramByName[$endMatch] } else { $null }
|
||||
$hasNotAField = ($beginP -and $beginP.notAField) -or ($endP -and $endP.notAField)
|
||||
if ($startMatch -eq 'НачалоПериода' -and $endMatch -eq 'КонецПериода' -and -not $hasNotAField) {
|
||||
$p['autoDates'] = $true
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# skd-decompile v0.88 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||
# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import os
|
||||
@@ -449,9 +449,11 @@ def convert_to_compact_json(obj, depth=0, indent_unit=' ', line_limit=400):
|
||||
return convert_string_to_json_literal(str(obj))
|
||||
|
||||
|
||||
def get_text(node, xpath):
|
||||
def get_text(node, xpath=None):
|
||||
if not node:
|
||||
return None
|
||||
if not xpath:
|
||||
return node.inner_text
|
||||
n = node.select_single_node(xpath)
|
||||
if n:
|
||||
return n.inner_text
|
||||
@@ -2760,16 +2762,10 @@ def run(root):
|
||||
dsl_nodes = root.select_nodes("r:dataSetLink")
|
||||
for dsl_node in dsl_nodes:
|
||||
link = {}
|
||||
link['sourceDataSet'] = get_text(dsl_node.select_single_node("r:sourceDataSet"), '.') if False else (dsl_node.select_single_node("r:sourceDataSet").inner_text if dsl_node.select_single_node("r:sourceDataSet") else None)
|
||||
# PS code uses Get-Text $node (without xpath) — for our wrapper, just read inner_text
|
||||
s_n = dsl_node.select_single_node("r:sourceDataSet")
|
||||
d_n = dsl_node.select_single_node("r:destinationDataSet")
|
||||
se_n = dsl_node.select_single_node("r:sourceExpression")
|
||||
de_n = dsl_node.select_single_node("r:destinationExpression")
|
||||
link['sourceDataSet'] = s_n.inner_text if s_n else None
|
||||
link['destinationDataSet'] = d_n.inner_text if d_n else None
|
||||
link['sourceExpression'] = se_n.inner_text if se_n else None
|
||||
link['destinationExpression'] = de_n.inner_text if de_n else None
|
||||
link['sourceDataSet'] = get_text(dsl_node.select_single_node("r:sourceDataSet"))
|
||||
link['destinationDataSet'] = get_text(dsl_node.select_single_node("r:destinationDataSet"))
|
||||
link['sourceExpression'] = get_text(dsl_node.select_single_node("r:sourceExpression"))
|
||||
link['destinationExpression'] = get_text(dsl_node.select_single_node("r:destinationExpression"))
|
||||
p_node = dsl_node.select_single_node("r:parameter")
|
||||
if p_node:
|
||||
link['parameter'] = p_node.inner_text
|
||||
|
||||
Reference in New Issue
Block a user