fix(meta-compile,meta-validate): правки по второму ревью

Три находки, все воспроизведены:

1. Счётчик членов составного типа не видел форму с локальной xmlns:
   тип из чужого пространства имён пишется как <v8:Type xmlns:mxl="…">, а
   регулярка требовала '>' сразу за именем тега. В итоге на одном и том же
   файле meta-compile молчал, а meta-validate предупреждал — навыки
   расходились в оценке одного содержимого. Радиус: оба порта.
2. Report-OK проверки 23 печатался безусловно — то есть сразу после
   собственного ERROR, и раздувал счётчик проверок в итоговой строке.
   Соседние проверки (21, 22) так не делают.
3. ToString() копировал весь буфер вывода на каждый реквизит: O(n^2) на
   крупном объекте. В файле уже есть ranged-перегрузка ровно для этого
   (Emit-TypeContent). py-порт был изначально корректен — он режет список.

Добавлен кейс на тип с локальной xmlns: без него находка 1 вернулась бы
незамеченной, потому что обычный составной тип её не показывает.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-09-20 19:28:46 +03:00
co-authored by Claude Opus 5
parent 1481e58bfc
commit 24b1aa9ee1
11 changed files with 389 additions and 6 deletions
@@ -994,8 +994,10 @@ function Emit-ValueType {
# предупреждение, а не отказ: иначе навык не собрал бы того, что поставляет 1С. Соотношение в
# корпусе erp+acc — 6500 единственных против 1 составного.
function Warn-DefinedTypeInComposite([int]$fromLength) {
$frag = $script:xml.ToString().Substring($fromLength)
$members = [regex]::Matches($frag, '<v8:(Type|TypeSet)>').Count
$frag = $script:xml.ToString($fromLength, $script:xml.Length - $fromLength)
# После имени тега — либо '>', либо пробел: тип из чужого пространства имён несёт локальную
# xmlns прямо в теге (<v8:Type xmlns:mxl="…">), и без пробела в классе он не считался членом.
$members = [regex]::Matches($frag, '<v8:(Type|TypeSet)[ >]').Count
if ($members -lt 2) { return }
$dts = @()
foreach ($m in [regex]::Matches($frag, '<v8:TypeSet>cfg:(DefinedType\.[^<]+)</v8:TypeSet>')) { $dts += $m.Groups[1].Value }
@@ -1012,7 +1014,9 @@ function Warn-DefinedTypeInComposite([int]$fromLength) {
# разъехалась бы с ним молча — ровно тот класс отказа, от которого держим гарды.
function Get-EmittedTypeSets([int]$fromLength) {
$sets = @()
$frag = $script:xml.ToString().Substring($fromLength)
# Ranged-перегрузка, как в Emit-TypeContent: ToString() целиком копировал бы весь буфер
# на каждый реквизит — это O(n^2) на крупном объекте.
$frag = $script:xml.ToString($fromLength, $script:xml.Length - $fromLength)
foreach ($m in [regex]::Matches($frag, '<v8:TypeSet>cfg:([^<]+)</v8:TypeSet>')) { $sets += $m.Groups[1].Value }
return $sets
}
@@ -1103,7 +1103,9 @@ def emit_value_type(indent, type_str):
# корпусе erp+acc — 6500 единственных против 1 составного.
def warn_defined_type_in_composite(from_index):
frag = chr(10).join(lines[from_index:])
if len(re.findall(r'<v8:(?:Type|TypeSet)>', frag)) < 2:
# После имени тега — либо '>', либо пробел: тип из чужого пространства имён несёт локальную
# xmlns прямо в теге (<v8:Type xmlns:mxl="…">), и без пробела в классе он не считался членом.
if len(re.findall(r'<v8:(?:Type|TypeSet)[ >]', frag)) < 2:
return
dts = re.findall(r'<v8:TypeSet>cfg:(DefinedType[.][^<]+)</v8:TypeSet>', frag)
if dts: