mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-17 23:35:22 +03:00
feat(form-decompile,form-compile): системные перечисления в choiceList + footerDataPath/footerText/editMode на labelField/radio + AdditionalColumns empty self-closing
Четыре находки из rt-iter2 (формы Хозрасчётный/ФормаСчёта, СпецификацииНоменклатуры): 1. **Системные перечисления в choiceList** (ent: namespace, напр. ent:AccountType=ВидСчёта): значение несёт xsi:type="ent:AccountType", компилятор эмитил xs:string (терял тип). Per-item ключ `valueType` (как у фильтра): декомпилятор сохраняет не-примитивный не-DesignTimeRef xsi:type, компилятор эмитит его вместо авто-детекта. 2. **footerDataPath/footerText на LabelField** — были только у InputField, на поле-надписи (колонка таблицы) терялись. Добавлены (decompile + compile, позиция по корпусу). 3. **editMode у RadioButtonField** — не ловился/не эмитился (форма ВидСчёта). Добавлен. 4. **Пустая AdditionalColumns** (table-ref без колонок) — компилятор эмитил пустую пару <AdditionalColumns table="X"></...>, платформа — self-closing. Фикс: self-closing при пустых columns. Зеркало py. Обе формы → match. Кейсы radio-tumbler-strings (+ent:AccountType +editMode), picture-field (labelField-колонка +footerDataPath/footerText), additional-columns (+пустая группа) сертифицированы в 1С. Регресс 43/43 (ps1+py). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
bdd38691aa
commit
330447c95f
@@ -1,4 +1,4 @@
|
||||
# form-compile v1.123 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.124 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[string]$JsonPath,
|
||||
@@ -3895,7 +3895,15 @@ function Emit-ChoiceList {
|
||||
elseif ($item.PSObject.Properties["title"]) { $presRaw = $item.title; $hasPres = $true }
|
||||
}
|
||||
|
||||
$norm = Normalize-ChoiceValue -value $valRaw
|
||||
# valueType: явный xsi:type значения (системное перечисление ent:*, иной не-примитив) —
|
||||
# переопределяет авто-детект (Normalize-ChoiceValue вывела бы xs:string).
|
||||
$vtRaw = $null
|
||||
if ($item -is [hashtable] -or $item -is [System.Collections.IDictionary]) {
|
||||
if ($item.Contains("valueType")) { $vtRaw = "$($item["valueType"])" }
|
||||
} elseif ($item.PSObject.Properties["valueType"]) { $vtRaw = "$($item.valueType)" }
|
||||
|
||||
if ($vtRaw) { $norm = @{ XsiType = $vtRaw; Text = "$valRaw" } }
|
||||
else { $norm = Normalize-ChoiceValue -value $valRaw }
|
||||
|
||||
# авто-вывод presentation, если не задан
|
||||
if (-not $hasPres) {
|
||||
@@ -4092,6 +4100,7 @@ function Emit-Radio {
|
||||
Emit-Title -el $el -name $name -indent $inner -auto:(-not $el.path)
|
||||
Emit-CommonFlags -el $el -indent $inner
|
||||
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
Emit-TitleLocation -el $el -indent $inner -smartDefault "None"
|
||||
|
||||
# RadioButtonType: Auto | RadioButtons | Tumbler. Accept synonyms.
|
||||
@@ -4181,6 +4190,8 @@ function Emit-LabelField {
|
||||
|
||||
if ($el.titleLocation) { X "$inner<TitleLocation>$(Map-TitleLoc "$($el.titleLocation)")</TitleLocation>" }
|
||||
if ($el.editMode) { X "$inner<EditMode>$($el.editMode)</EditMode>" }
|
||||
# FooterDataPath — путь данных подвала колонки (общий cell-prop, как у input); после EditMode
|
||||
if ($el.footerDataPath) { X "$inner<FooterDataPath>$(Esc-Xml "$($el.footerDataPath)")</FooterDataPath>" }
|
||||
# PasswordMode на LabelField — платформа эмитит явный false (редко); факт. значение
|
||||
if ($null -ne $el.passwordMode) { X "$inner<PasswordMode>$(if ($el.passwordMode){'true'}else{'false'})</PasswordMode>" }
|
||||
Emit-ColumnPics -el $el -indent $inner
|
||||
@@ -4189,6 +4200,7 @@ function Emit-LabelField {
|
||||
Emit-Layout -el $el -indent $inner
|
||||
|
||||
if ($null -ne $el.warningOnEdit) { Emit-MLText -tag "WarningOnEdit" -text $el.warningOnEdit -indent $inner }
|
||||
if ($null -ne $el.footerText) { Emit-MLText -tag "FooterText" -text $el.footerText -indent $inner }
|
||||
|
||||
# Формат / формат редактирования (LocalStringType — строка или {ru,en})
|
||||
if ($el.format) { Emit-MLText -tag "Format" -text $el.format -indent $inner }
|
||||
@@ -5227,9 +5239,15 @@ function Emit-Attributes {
|
||||
}
|
||||
if ($hasAddCols) {
|
||||
foreach ($ac in @($attr.additionalColumns)) {
|
||||
$acCols = @($ac.columns)
|
||||
if ($acCols.Count -eq 0) {
|
||||
# Пустая группа доп.колонок (table-ref без колонок) → self-closing (как платформа)
|
||||
X "$inner`t<AdditionalColumns table=`"$($ac.table)`"/>"
|
||||
continue
|
||||
}
|
||||
X "$inner`t<AdditionalColumns table=`"$($ac.table)`">"
|
||||
$seenAcCols = @{} # уникальность в пределах группы AdditionalColumns
|
||||
foreach ($col in @($ac.columns)) {
|
||||
foreach ($col in $acCols) {
|
||||
Assert-UniqueName -name "$($col.name)" -seen $seenAcCols -kind "column of '$attrName'"
|
||||
Emit-AttrColumn -col $col -indent "$inner`t`t"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-compile v1.123 — Compile 1C managed form from JSON or object metadata
|
||||
# form-compile v1.124 — Compile 1C managed form from JSON or object metadata
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
import argparse
|
||||
import copy
|
||||
@@ -2120,7 +2120,13 @@ def emit_choice_list(lines, el, indent):
|
||||
has_pres = any(k in item for k in ('presentation', 'представление', 'title'))
|
||||
pres_raw = item.get('presentation', item.get('представление', item.get('title')))
|
||||
|
||||
norm = normalize_choice_value(val_raw)
|
||||
# valueType: явный xsi:type значения (системное перечисление ent:*, иной не-примитив) —
|
||||
# переопределяет авто-детект (normalize_choice_value вывела бы xs:string).
|
||||
vt_raw = item.get('valueType')
|
||||
if vt_raw:
|
||||
norm = {'xsi_type': str(vt_raw), 'text': '' if val_raw is None else str(val_raw)}
|
||||
else:
|
||||
norm = normalize_choice_value(val_raw)
|
||||
|
||||
if not has_pres:
|
||||
if norm['xsi_type'] == 'xr:DesignTimeRef':
|
||||
@@ -3817,6 +3823,8 @@ def emit_radio_button_field(lines, el, name, eid, indent):
|
||||
emit_title(lines, el, name, inner, auto=not el.get('path'))
|
||||
emit_common_flags(lines, el, inner)
|
||||
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
emit_title_location(lines, el, inner, 'None')
|
||||
|
||||
rbt = normalize_radio_button_type(el.get('radioButtonType'))
|
||||
@@ -3898,6 +3906,9 @@ def emit_label_field(lines, el, name, eid, indent):
|
||||
lines.append(f'{inner}<TitleLocation>{map_title_loc(el["titleLocation"])}</TitleLocation>')
|
||||
if el.get('editMode'):
|
||||
lines.append(f'{inner}<EditMode>{el["editMode"]}</EditMode>')
|
||||
# FooterDataPath — путь данных подвала колонки (общий cell-prop, как у input); после EditMode
|
||||
if el.get('footerDataPath'):
|
||||
lines.append(f'{inner}<FooterDataPath>{esc_xml(str(el["footerDataPath"]))}</FooterDataPath>')
|
||||
# PasswordMode на LabelField — платформа эмитит явный false (редко); факт. значение
|
||||
if el.get('passwordMode') is not None:
|
||||
lines.append(f'{inner}<PasswordMode>{"true" if el["passwordMode"] else "false"}</PasswordMode>')
|
||||
@@ -3909,6 +3920,8 @@ def emit_label_field(lines, el, name, eid, indent):
|
||||
|
||||
if el.get('warningOnEdit') is not None:
|
||||
emit_mltext(lines, inner, 'WarningOnEdit', el['warningOnEdit'])
|
||||
if el.get('footerText') is not None:
|
||||
emit_mltext(lines, inner, 'FooterText', el['footerText'])
|
||||
|
||||
# Формат / формат редактирования (LocalStringType — строка или {ru,en})
|
||||
if el.get('format'):
|
||||
@@ -4953,9 +4966,14 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None):
|
||||
emit_attr_column(lines, col, f'{inner}\t')
|
||||
if has_add_cols:
|
||||
for ac in attr['additionalColumns']:
|
||||
ac_cols = ac.get('columns') or []
|
||||
if not ac_cols:
|
||||
# Пустая группа доп.колонок (table-ref без колонок) → self-closing (как платформа)
|
||||
lines.append(f'{inner}\t<AdditionalColumns table="{ac["table"]}"/>')
|
||||
continue
|
||||
lines.append(f'{inner}\t<AdditionalColumns table="{ac["table"]}">')
|
||||
seen_ac_cols = set() # уникальность в пределах группы AdditionalColumns
|
||||
for col in (ac.get('columns') or []):
|
||||
for col in ac_cols:
|
||||
_ensure_unique(str(col['name']), seen_ac_cols, f"column of '{attr_name}'")
|
||||
emit_attr_column(lines, col, f'{inner}\t\t')
|
||||
lines.append(f'{inner}\t</AdditionalColumns>')
|
||||
|
||||
Reference in New Issue
Block a user