feat(meta-compile,meta-validate): проверки на тип-множество там, где его не принимают

Запрет неочевидный, а отказ платформы приходит поздно и одной строкой из
Конфигуратора. Три уровня строгости, все замерены загрузкой в базу на
8.3.24.1691, а не выведены из документации:

- ОШИБКА — множество в составе определяемого типа. Платформа отвергает файл
  целиком («ОпределяемыйТип.<Имя> - Недопустимый тип»); проверено на
  ОпределяемыйТип, Характеристика, ЛюбаяСсылка и голых ссылках, контрольный
  вариант с обычным CatalogRef.<Имя> принят. Отсюда и ноль таких узлов в
  корпусе — это запрет, а не совпадение.
- ПРЕДУПРЕЖДЕНИЕ — голый метатип в типе значения ПВХ. Загрузка проходит, но
  Конфигуратор такой тип не предлагает: в дереве выбора СправочникСсылка и
  ДокументСсылка — папки без флажка, а ЛюбаяСсылки там нет вовсе. Плюс AnyRef
  раундтрипом возвращается как AnyIBRef, то есть молча меняется.
- ПРЕДУПРЕЖДЕНИЕ — определяемый тип одним из составного. Конфигуратор даёт
  выбрать его только единственным, но отказывать нельзя: в корпусе erp+acc
  6500 единственных против 1 составного, и этот один лежит в типовой ERP
  (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы — два определяемых типа
  подряд). Навык не вправе отказаться собрать то, что поставляет 1С.

В meta-compile состав множеств берётся опросом самого эмиттера, а не второй
копией его регулярок: список видов живёт в Emit-TypeContent, и копия
разъехалась бы с ним молча.

Развёртка по 3428 объектам ERP: ровно 2 срабатывания, оба на том самом
реальном составном реквизите. Ложных нет.

Предупреждения пишутся прямо в stderr, а не через Write-Warning: в PS 5.1 тот
уходит не в тот поток (конвенция из cf-init), и до проверки они не доезжали.

Оба кейса-предупреждения проверены платформой — она эти конфигурации грузит,
что и подтверждает выбор «предупреждение, а не отказ».

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-09-20 18:45:16 +03:00
co-authored by Claude Opus 5
parent 079a177cf4
commit 1481e58bfc
67 changed files with 4022 additions and 9 deletions
@@ -1,4 +1,4 @@
# meta-validate v1.28 — Validate 1C metadata object structure
# meta-validate v1.29 — Validate 1C metadata object structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
[CmdletBinding(PositionalBinding=$false)]
param(
@@ -1725,6 +1725,41 @@ if ($badGrammar.Count -eq 0 -and $notStorable.Count -eq 0 -and $unknownVocab.Cou
Report-OK "22. Type names: $typesSeen checked"
}
# --- Check 23: тип-множество там, где его не принимают ---
# Три уровня строгости, все замерены загрузкой в базу на 8.3.24.1691:
# ERROR — множество в составе определяемого типа: платформа отвергает файл целиком
# («ОпределяемыйТип.<Имя> - Недопустимый тип»), проверено на ОпределяемыйТип,
# Характеристика, ЛюбаяСсылка и голых ссылках;
# WARN — голый метатип в типе значения ПВХ: загрузка проходит, но Конфигуратор такой тип не
# предлагает (в дереве выбора это папка без флажка), а ЛюбаяСсылка на выгрузке
# возвращается как ЛюбаяСсылкаИБ;
# WARN — определяемый тип одним из составного: Конфигуратор даёт выбрать его только
# единственным. В корпусе erp+acc 6500 единственных против 1 составного — и этот один
# лежит в типовой ERP (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы), поэтому не ошибка.
$typeBlocks23 = @($xmlDoc.SelectNodes("//md:Type | //md:ValueType", $ns))
$dtSetsSeen = 0
foreach ($tb in $typeBlocks23) {
$sets = @($tb.SelectNodes("v8:TypeSet", $ns))
if ($sets.Count -eq 0) { continue }
$dtSetsSeen++
$members = $tb.SelectNodes("v8:Type", $ns).Count + $sets.Count
$ownerKind = $tb.ParentNode.ParentNode.get_LocalName() # <Type> → <Properties> → <DefinedType>/…
foreach ($st in $sets) {
$raw = $st.InnerText.Trim() -replace '^(?:cfg|d\d+p\d+):', ''
if ($ownerKind -eq "DefinedType") {
Report-Error "23. Определяемый тип '$objName': в составе тип-множество '$raw' — платформа не загрузит такой файл («Недопустимый тип»). Состав определяемого типа — только конкретные типы"
continue
}
if ($ownerKind -eq "ChartOfCharacteristicTypes" -and $raw -notmatch '^(DefinedType|Characteristic)\.') {
Report-Warn "23. План видов характеристик '$objName': тип значения '$raw' Конфигуратор не предлагает (в дереве выбора это папка без флажка); ЛюбаяСсылка на выгрузке вернётся как ЛюбаяСсылкаИБ"
}
if ($members -gt 1 -and $raw -match '^DefinedType\.') {
Report-Warn "23. Составной тип содержит определяемый тип '$raw' — Конфигуратор даёт выбрать его только единственным; платформа загрузит"
}
}
}
if ($dtSetsSeen -gt 0) { Report-OK "23. Type sets: $dtSetsSeen block(s) checked" }
# --- Check 18: свойства, появившиеся в новых версиях формата ---
# Реестр «тег → минимальная версия формата». Служит двум целям: (1) поймать свойство в файле со
# слишком старым штампом — при сборке на старой платформе оно будет молча отброшено (платформа