mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-09-24 19:25:54 +03:00
fix(form-decompile): не терять заголовок, отличающийся от авто-вывода только регистром
Заголовок реквизита формы и параметра динамического списка опускается, если равен авто-выводу из имени: компилятор восстановит его сам. Сравнение было регистронезависимым (в ps1 -eq/-ne, в py зеркалящий их _ps_ieq), поэтому «Организации ВетИС» при имени ОрганизацииВЕТИС считался равным авто-выводу «Организации ВЕТИС», выпадал из DSL, и обратная сборка молча меняла текст на форме. Эталон сравнения — не PowerShell, а компилятор: он пишет заголовок как есть, значит опускать можно только при побайтовом совпадении. В ps1 этого не даёт и -ceq — он культурный, мягкий перенос и NFD-разложение для него ничего не весят, и порты разошлись бы между собой. Сравнение идёт через [string]::Equals(..., Ordinal), что и есть зеркало питоновского ==. _ps_ieq больше не нужен и удалён. Два регресс-кейса: реквизит формы (регистр + невидимый мягкий перенос) и параметр динамического списка. Оба падают на исходной версии в обоих портах. Найдено на типовой конфигурации: Документ.ИсходящаяТранспортнаяОперацияВЕТИС.ФормаСписка. Co-Authored-By: Шпаков Антон Александрович <shpakov.anton.job@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSyRNwSiuAAEQCLSCUGEzQ
This commit is contained in:
co-authored by
Шпаков Антон Александрович
Claude Opus 5
parent
38c26f319d
commit
cf02c69ff5
@@ -1,4 +1,4 @@
|
||||
# form-decompile v0.150 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.151 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
[CmdletBinding(PositionalBinding=$false)]
|
||||
@@ -1493,8 +1493,13 @@ function Build-DLParameter {
|
||||
if ($titleNode) {
|
||||
$t = Get-LangText $titleNode
|
||||
if ($null -ne $t) {
|
||||
# Сравнение байт в байт: эталон — компилятор, он пишет заголовок как есть. -eq
|
||||
# регистронезависим, и заголовок, отличающийся от авто-вывода только регистром
|
||||
# («Организации ВетИС» при авто «Организации ВЕТИС»), терялся молча. Даже -ceq мало:
|
||||
# он культурный, мягкий перенос и NFD-разложение для него — ноль. Нужен Ordinal,
|
||||
# он же и есть зеркало питоновского ==.
|
||||
$auto = Title-FromName -name $name
|
||||
if (-not (($t -is [string]) -and ($t -eq $auto))) { $o['title'] = $t }
|
||||
if (-not (($t -is [string]) -and [string]::Equals($t, $auto, [StringComparison]::Ordinal))) { $o['title'] = $t }
|
||||
}
|
||||
}
|
||||
# valueType
|
||||
@@ -2691,7 +2696,10 @@ if ($attrsNode) {
|
||||
if ($tNode) {
|
||||
$t = Get-LangTextWS $tNode # восстановление значимого пробела (whitespace-заголовок реквизита)
|
||||
if ($null -ne $t) {
|
||||
if ($isMain -or -not ($t -is [string]) -or $t -ne (Title-FromName $ao['name'])) { $ao['title'] = $t }
|
||||
# Ordinal, а не -ne/-ceq: заголовок опускаем только при ТОЧНОМ, побайтовом совпадении
|
||||
# с авто-выводом — компилятор восстановит его как есть, значим и регистр, и мягкий
|
||||
# перенос, и форма нормализации.
|
||||
if ($isMain -or -not ($t -is [string]) -or -not [string]::Equals($t, (Title-FromName $ao['name']), [StringComparison]::Ordinal)) { $ao['title'] = $t }
|
||||
}
|
||||
} elseif (-not $isMain) {
|
||||
$ao['title'] = ''
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# form-decompile v0.150 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# form-decompile v0.151 — Decompile 1C managed Form.xml to JSON DSL (draft)
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
|
||||
#
|
||||
@@ -618,12 +618,6 @@ def _ps_truthy(v):
|
||||
return True
|
||||
|
||||
|
||||
# Зеркало PowerShell -eq/-ne для строк: регистронезависимое сравнение (PS по умолчанию ignore-case).
|
||||
# Нужно там, где сравниваются произвольно-регистровые строки (заголовок vs авто-вывод из имени).
|
||||
def _ps_ieq(a, b):
|
||||
return a.lower() == b.lower()
|
||||
|
||||
|
||||
# Зеркало PowerShell "$v" (строковая интерполяция): bool→True/False, float без хвостового .0,
|
||||
# $null→'', иначе str(). Используется везде, где канон делает "$value".
|
||||
def _ps_str(v):
|
||||
@@ -1689,8 +1683,12 @@ def build_dl_parameter(p_node):
|
||||
if title_node is not None:
|
||||
t = get_lang_text(title_node)
|
||||
if t is not None:
|
||||
# Сравнение байт в байт (в ps1 — [string]::Equals(..., Ordinal)): эталон — компилятор,
|
||||
# он пишет заголовок как есть. Регистронезависимое сравнение теряло заголовок,
|
||||
# отличающийся от авто-вывода только регистром («Организации ВетИС» при авто
|
||||
# «Организации ВЕТИС»).
|
||||
auto = title_from_name(name)
|
||||
if not (isinstance(t, str) and _ps_ieq(t, auto)):
|
||||
if not (isinstance(t, str) and t == auto):
|
||||
o['title'] = t
|
||||
vt_node = p_node.find('dcssch:valueType', NS)
|
||||
type_val = None
|
||||
@@ -3333,7 +3331,10 @@ def main():
|
||||
if t_node is not None:
|
||||
t = get_lang_text_ws(t_node)
|
||||
if t is not None:
|
||||
if is_main or not isinstance(t, str) or not _ps_ieq(t, title_from_name(ao['name'])):
|
||||
# Заголовок опускаем только при ТОЧНОМ, побайтовом совпадении с авто-выводом
|
||||
# (в ps1 — [string]::Equals(..., Ordinal)): компилятор восстановит его как есть,
|
||||
# значим и регистр, и мягкий перенос, и форма нормализации.
|
||||
if is_main or not isinstance(t, str) or t != title_from_name(ao['name']):
|
||||
ao['title'] = t
|
||||
elif not is_main:
|
||||
ao['title'] = ''
|
||||
|
||||
Reference in New Issue
Block a user