feat(meta-compile,meta-decompile): закрыт empty-DTR хвост + LineNumber FillValue (v1.49/v0.41)

Последний сквозной хвост всех типов — «пустая ссылка» как значение заполнения
(<FillValue xsi:type="xr:DesignTimeRef"/> без содержимого). Декомпилятор ловил его как
xs:string → тип терялся. Не выводится из типа (DefinedType.X непрозрачен: nil vs empty-DTR
зависит от вида). Фикс: маркер fillValue:{emptyRef:true} — декомпилятор проставляет,
компилятор воспроизводит (4 точки: Emit-FillValue + Emit-StandardAttribute × захват/эмиссия).

Попутно закрыт (B)-хвост Document: FillValue НомерСтроки ТЧ (xs:decimal 0, аномалия 1/1645) —
lineNumber-кастомизация расширена ключом fillValue.

Чистый выигрыш без регресса: Catalog 52→58/58, Document 142→151/151, BusinessProcess 20→25/25,
Task 1→3/3 — все byte-exact TOTAL 0. Регресс 49/49 ps1+py, ps1==py identical (0/20 modulo GUID).
Прежнее «принято как инертный шум» снято — закрыто честно. spec §4.2/§7.1.1.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-07 13:24:49 +03:00
co-authored by Claude Opus 4.8
parent 101ca6e371
commit 8af6b9d88e
4 changed files with 29 additions and 6 deletions
@@ -1,4 +1,4 @@
# meta-compile v1.48 — Compile 1C metadata object from JSON
# meta-compile v1.49 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -738,6 +738,7 @@ function Emit-FillValue {
}
if ($null -eq $spec) { X "$indent<FillValue xsi:nil=`"true`"/>"; return } # явный nil-override
if ($spec.emptyRef -eq $true) { X "$indent<FillValue xsi:type=`"xr:DesignTimeRef`"/>"; return } # пустая ссылка (маркер декомпилятора)
if ($spec -is [bool]) {
X "$indent<FillValue xsi:type=`"xs:boolean`">$(if ($spec) { 'true' } else { 'false' })</FillValue>"; return
}
@@ -1133,6 +1134,7 @@ function Emit-StandardAttribute {
# FillValue: дефолт nil; override-значение → типизированное (Normalize-ChoiceValue: DTR-путь/строка/bool).
$fvRaw = OvOr 'FillValue' $null
if ($null -eq $fvRaw) { X "$indent`t<xr:FillValue xsi:nil=`"true`"/>" }
elseif ($fvRaw.emptyRef -eq $true) { X "$indent`t<xr:FillValue xsi:type=`"xr:DesignTimeRef`"/>" }
else {
$fvN = Normalize-ChoiceValue $fvRaw
if ([string]::IsNullOrEmpty($fvN.Text)) { X "$indent`t<xr:FillValue xsi:type=`"$($fvN.XsiType)`"/>" }
@@ -1207,6 +1209,7 @@ function Emit-TabularStandardAttributes {
if ($null -ne $lineNumber.format) { $ov['Format'] = $lineNumber.format }
if ($null -ne $lineNumber.editFormat) { $ov['EditFormat'] = $lineNumber.editFormat }
if ($lineNumber.choiceHistoryOnInput) { $ov['ChoiceHistoryOnInput'] = "$($lineNumber.choiceHistoryOnInput)" }
if ($null -ne $lineNumber.fillValue) { $ov['FillValue'] = $lineNumber.fillValue }
}
X "$indent<StandardAttributes>"
Emit-StandardAttribute "$indent`t" "LineNumber" $ov
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-compile v1.48 — Compile 1C metadata object from JSON
# meta-compile v1.49 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -769,6 +769,9 @@ def emit_fill_value(indent, type_str, spec, has_spec):
if spec is None:
X(f'{indent}<FillValue xsi:nil="true"/>') # явный nil-override
return
if isinstance(spec, dict) and spec.get('emptyRef') is True:
X(f'{indent}<FillValue xsi:type="xr:DesignTimeRef"/>') # пустая ссылка (маркер декомпилятора)
return
if isinstance(spec, bool):
X(f'{indent}<FillValue xsi:type="xs:boolean">{"true" if spec else "false"}</FillValue>')
return
@@ -1152,6 +1155,8 @@ def emit_standard_attribute(indent, attr_name, ov=None):
fv_raw = ov.get('FillValue', None)
if fv_raw is None:
X(f'{indent}\t<xr:FillValue xsi:nil="true"/>')
elif isinstance(fv_raw, dict) and fv_raw.get('emptyRef') is True:
X(f'{indent}\t<xr:FillValue xsi:type="xr:DesignTimeRef"/>')
else:
fv_xt, fv_tx = normalize_choice_value(fv_raw)
if fv_tx == '' or fv_tx is None:
@@ -1242,6 +1247,8 @@ def emit_tabular_standard_attributes(indent, line_number=None):
ov['EditFormat'] = line_number['editFormat']
if line_number.get('choiceHistoryOnInput'):
ov['ChoiceHistoryOnInput'] = str(line_number['choiceHistoryOnInput'])
if line_number.get('fillValue') is not None:
ov['FillValue'] = line_number['fillValue']
X(f'{indent}<StandardAttributes>')
emit_standard_attribute(f'{indent}\t', 'LineNumber', ov)
X(f'{indent}</StandardAttributes>')