diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 3cd428e07..9b3d9da6b 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -988,11 +988,12 @@ function Emit-ValueType { X "$indent" } -# Определяемый тип Конфигуратор даёт выбрать только ЕДИНСТВЕННЫМ, не одним из составного. -# Загрузчик такое принимает, и в типовой ERP один такой реквизит есть -# (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы — два определяемых типа подряд), поэтому -# предупреждение, а не отказ: иначе навык не собрал бы того, что поставляет 1С. Соотношение в -# корпусе erp+acc — 6500 единственных против 1 составного. +# Определяемый тип и характеристику Конфигуратор даёт выбрать только ЕДИНСТВЕННЫМ, не одним из +# составного (характеристику — даже вместе с другой характеристикой). Загрузчик такое принимает, +# и в типовой ERP один такой реквизит есть (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы — +# два определяемых типа подряд), поэтому предупреждение, а не отказ: иначе навык не собрал бы +# того, что поставляет 1С. Соотношение в корпусе erp+acc — 6500 определяемых единственным против +# 1 составного и 1741 характеристика единственным против 0 составных. function Warn-DefinedTypeInComposite([int]$fromLength) { $frag = $script:xml.ToString($fromLength, $script:xml.Length - $fromLength) # После имени тега — либо '>', либо пробел: тип из чужого пространства имён несёт локальную @@ -1000,12 +1001,12 @@ function Warn-DefinedTypeInComposite([int]$fromLength) { $members = [regex]::Matches($frag, ']').Count if ($members -lt 2) { return } $dts = @() - foreach ($m in [regex]::Matches($frag, 'cfg:(DefinedType\.[^<]+)')) { $dts += $m.Groups[1].Value } + foreach ($m in [regex]::Matches($frag, 'cfg:((?:DefinedType|Characteristic)\.[^<]+)')) { $dts += $m.Groups[1].Value } if ($dts.Count -gt 0) { # Прямо в stderr, а не Write-Warning: в PS 5.1 предупреждение уходит не в тот поток # (см. cf-init) и до expect.stderrContains не доезжает. - [Console]::Error.WriteLine("WARNING: Составной тип содержит определяемый тип (" + ($dts -join ', ') + - "). Конфигуратор даёт выбрать определяемый тип только единственным — собрать такое руками не получится. Платформа загрузит.") + [Console]::Error.WriteLine("WARNING: Составной тип содержит (" + ($dts -join ', ') + + "). Конфигуратор даёт выбрать определяемый тип и характеристику только единственным — собрать такое руками не получится. Платформа загрузит.") } } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 5e5561a95..1357bd1d3 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1096,22 +1096,23 @@ def emit_value_type(indent, type_str): warn_defined_type_in_composite(mark) X(f'{indent}') -# Определяемый тип Конфигуратор даёт выбрать только ЕДИНСТВЕННЫМ, не одним из составного. -# Загрузчик такое принимает, и в типовой ERP один такой реквизит есть -# (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы — два определяемых типа подряд), поэтому -# предупреждение, а не отказ: иначе навык не собрал бы того, что поставляет 1С. Соотношение в -# корпусе erp+acc — 6500 единственных против 1 составного. +# Определяемый тип и характеристику Конфигуратор даёт выбрать только ЕДИНСТВЕННЫМ, не одним из +# составного (характеристику — даже вместе с другой характеристикой). Загрузчик такое принимает, +# и в типовой ERP один такой реквизит есть (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы — +# два определяемых типа подряд), поэтому предупреждение, а не отказ: иначе навык не собрал бы +# того, что поставляет 1С. Соотношение в корпусе erp+acc — 6500 определяемых единственным против +# 1 составного и 1741 характеристика единственным против 0 составных. def warn_defined_type_in_composite(from_index): frag = chr(10).join(lines[from_index:]) # После имени тега — либо '>', либо пробел: тип из чужого пространства имён несёт локальную # xmlns прямо в теге (), и без пробела в классе он не считался членом. if len(re.findall(r']', frag)) < 2: return - dts = re.findall(r'cfg:(DefinedType[.][^<]+)', frag) + dts = re.findall(r'cfg:((?:DefinedType|Characteristic)[.][^<]+)', frag) if dts: - print("WARNING: Составной тип содержит определяемый тип (" + ', '.join(dts) + - "). Конфигуратор даёт выбрать определяемый тип только единственным — собрать такое " - "руками не получится. Платформа загрузит.", file=sys.stderr) + print("WARNING: Составной тип содержит (" + ', '.join(dts) + + "). Конфигуратор даёт выбрать определяемый тип и характеристику только единственным — " + "собрать такое руками не получится. Платформа загрузит.", file=sys.stderr) # Что из только что записанного фрагмента ушло МНОЖЕСТВОМ. Спрашиваем сам эмиттер, а не повторяем # его регулярки: список видов, дающих v8:TypeSet, живёт в emit_type_content, и вторая копия diff --git a/.claude/skills/meta-validate/scripts/meta-validate.ps1 b/.claude/skills/meta-validate/scripts/meta-validate.ps1 index 9784d7d44..40ba67f73 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.ps1 +++ b/.claude/skills/meta-validate/scripts/meta-validate.ps1 @@ -1733,8 +1733,8 @@ if ($badGrammar.Count -eq 0 -and $notStorable.Count -eq 0 -and $unknownVocab.Cou # WARN — голый метатип в типе значения ПВХ: загрузка проходит, но Конфигуратор такой тип не # предлагает (в дереве выбора это папка без флажка), а ЛюбаяСсылка на выгрузке # возвращается как ЛюбаяСсылкаИБ; -# WARN — определяемый тип одним из составного: Конфигуратор даёт выбрать его только -# единственным. В корпусе erp+acc 6500 единственных против 1 составного — и этот один +# WARN — определяемый тип или характеристика одним из составного: Конфигуратор даёт +# выбрать их только единственными (характеристику — даже с другой характеристикой). В корпусе erp+acc 6500 единственных против 1 составного — и этот один # лежит в типовой ERP (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы), поэтому не ошибка. $typeBlocks23 = @($xmlDoc.SelectNodes("//md:Type | //md:ValueType", $ns)) $dtSetsSeen = 0 @@ -1756,9 +1756,9 @@ foreach ($tb in $typeBlocks23) { $dtSetsBad = $true Report-Warn "23. План видов характеристик '$objName': тип значения '$raw' Конфигуратор не предлагает (в дереве выбора это папка без флажка); ЛюбаяСсылка на выгрузке вернётся как ЛюбаяСсылкаИБ" } - if ($members -gt 1 -and $raw -match '^DefinedType\.') { + if ($members -gt 1 -and $raw -match '^(DefinedType|Characteristic)\.') { $dtSetsBad = $true - Report-Warn "23. Составной тип содержит определяемый тип '$raw' — Конфигуратор даёт выбрать его только единственным; платформа загрузит" + Report-Warn "23. Составной тип содержит '$raw' — Конфигуратор даёт выбрать определяемый тип и характеристику только единственным; платформа загрузит" } } } diff --git a/.claude/skills/meta-validate/scripts/meta-validate.py b/.claude/skills/meta-validate/scripts/meta-validate.py index 5d4079d9a..1881127c1 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.py +++ b/.claude/skills/meta-validate/scripts/meta-validate.py @@ -1674,8 +1674,8 @@ if not bad_grammar and not not_storable and not unknown_vocab and types_seen: # WARN — голый метатип в типе значения ПВХ: загрузка проходит, но Конфигуратор такой тип не # предлагает (в дереве выбора это папка без флажка), а ЛюбаяСсылка на выгрузке # возвращается как ЛюбаяСсылкаИБ; -# WARN — определяемый тип одним из составного: Конфигуратор даёт выбрать его только -# единственным. В корпусе erp+acc 6500 единственных против 1 составного — и этот один +# WARN — определяемый тип или характеристика одним из составного: Конфигуратор даёт +# выбрать их только единственными (характеристику — даже с другой характеристикой). В корпусе erp+acc 6500 единственных против 1 составного — и этот один # лежит в типовой ERP (Документ.НачислениеИСписаниеБонусныхБаллов.Баллы), поэтому не ошибка. dt_sets_seen = 0 dt_sets_bad = False @@ -1696,9 +1696,9 @@ for tb in root.xpath("//md:Type | //md:ValueType", namespaces=NS): if owner_kind == "ChartOfCharacteristicTypes" and not re.match(r'^DefinedType[.]', raw): dt_sets_bad = True report_warn(f"23. План видов характеристик '{obj_name}': тип значения '{raw}' Конфигуратор не предлагает (в дереве выбора это папка без флажка); ЛюбаяСсылка на выгрузке вернётся как ЛюбаяСсылкаИБ") - if members > 1 and re.match(r'^DefinedType[.]', raw): + if members > 1 and re.match(r'^(DefinedType|Characteristic)[.]', raw): dt_sets_bad = True - report_warn(f"23. Составной тип содержит определяемый тип '{raw}' — Конфигуратор даёт выбрать его только единственным; платформа загрузит") + report_warn(f"23. Составной тип содержит '{raw}' — Конфигуратор даёт выбрать определяемый тип и характеристику только единственным; платформа загрузит") if dt_sets_seen and not dt_sets_bad: report_ok(f"23. Type sets: {dt_sets_seen} block(s) checked") diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index 786756aac..f6e1afc12 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -150,7 +150,7 @@ JSON DSL для описания объектов метаданных конф |-----------|-----------|------------------------| | `DefinedType` (состав) | только конкретные типы | «Недопустимый тип» и файл не грузится — на `AnyRef`, голый `CatalogRef`, `Characteristic.Xxx` и вложенный `DefinedType.Xxx`; контрольный `CatalogRef.Xxx` принят | | ПВХ (`Type`/тип значения) | из множеств — только `DefinedType.Xxx` | остальное тоже грузится, но Конфигуратор не предлагает: голого метатипа и `AnyRef` в дереве выбора нет вовсе, `Characteristic.Xxx` — тоже (тип значения характеристики не может быть значением характеристики). `AnyRef` возвращается с выгрузки как `AnyIBRef`. В корпусе erp+acc ни один из 24 ПВХ множеств в типе значения не использует | -| любой составной тип | `DefinedType.Xxx` только ЕДИНСТВЕННЫМ | одним из составного Конфигуратор выбрать не даёт, но загрузчик принимает: в корпусе erp+acc 6500 единственных против 1 составного, и этот один — в типовой ERP (`Документ.НачислениеИСписаниеБонусныхБаллов.Баллы`) | +| любой составной тип | `DefinedType.Xxx` и `Characteristic.Xxx` — только ЕДИНСТВЕННЫМ | одним из составного Конфигуратор выбрать не даёт (характеристику — даже вместе с другой характеристикой), но загрузчик принимает: в корпусе erp+acc 6500 определяемых единственным против 1 составного (и этот один — в типовой ERP, `Документ.НачислениеИСписаниеБонусныхБаллов.Баллы`), 1741 характеристика единственным против 0 составных. Голые метатипы это НЕ затрагивает: `DocumentRef + CatalogRef` — обычный составной тип, 525 вхождений в поставке | Отсюда разная строгость проверок: состав определяемого типа — ошибка, остальные два — предупреждение. diff --git a/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Catalogs/Аналитика.xml b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Catalogs/Аналитика.xml new file mode 100644 index 000000000..c7daff60e --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Catalogs/Аналитика.xml @@ -0,0 +1,133 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Аналитика + + + ru + Аналитика + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.Аналитика.StandardAttribute.Description + Catalog.Аналитика.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + Субконто + + + ru + Субконто + + + + + cfg:Characteristic.ВидыСубконто + cfg:Characteristic.Прочие + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Catalogs/Аналитика/Ext/ObjectModule.bsl b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Catalogs/Аналитика/Ext/ObjectModule.bsl new file mode 100644 index 000000000..e69de29bb diff --git a/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Configuration.xml new file mode 100644 index 000000000..f493adaa4 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Аналитика + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Ext/ClientApplicationInterface.xml new file mode 100644 index 000000000..3c1161b2d --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Languages/Русский.xml new file mode 100644 index 000000000..37c60d786 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/warn-composite-characteristic/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/warn-composite-characteristic.json b/tests/skills/cases/meta-compile/warn-composite-characteristic.json new file mode 100644 index 000000000..5788f6dbf --- /dev/null +++ b/tests/skills/cases/meta-compile/warn-composite-characteristic.json @@ -0,0 +1,16 @@ +{ + "name": "Предупреждение: характеристика в составном типе — даже вместе с другой характеристикой нельзя", + "input": { + "type": "Catalog", + "name": "Аналитика", + "attributes": [ + "Субконто: Characteristic.ВидыСубконто + Characteristic.Прочие" + ] + }, + "expect": { + "stderrContains": [ + "Составной тип содержит (Characteristic.ВидыСубконто, Characteristic.Прочие)", + "определяемый тип и характеристику только единственным" + ] + } +} diff --git a/tests/skills/cases/meta-compile/warn-composite-defined-type-ns.json b/tests/skills/cases/meta-compile/warn-composite-defined-type-ns.json index 7d6727162..e16a00374 100644 --- a/tests/skills/cases/meta-compile/warn-composite-defined-type-ns.json +++ b/tests/skills/cases/meta-compile/warn-composite-defined-type-ns.json @@ -9,7 +9,7 @@ }, "expect": { "stderrContains": [ - "Составной тип содержит определяемый тип (DefinedType.Сумма)" + "Составной тип содержит (DefinedType.Сумма)" ] } } diff --git a/tests/skills/cases/meta-compile/warn-composite-defined-type.json b/tests/skills/cases/meta-compile/warn-composite-defined-type.json index 57760a7dd..62e520454 100644 --- a/tests/skills/cases/meta-compile/warn-composite-defined-type.json +++ b/tests/skills/cases/meta-compile/warn-composite-defined-type.json @@ -9,7 +9,7 @@ }, "expect": { "stderrContains": [ - "Составной тип содержит определяемый тип (DefinedType.Сумма)", + "Составной тип содержит (DefinedType.Сумма)", "только единственным" ] } diff --git a/tests/skills/cases/meta-validate/warn-composite-defined-type.json b/tests/skills/cases/meta-validate/warn-composite-defined-type.json index c67459634..1e576d607 100644 --- a/tests/skills/cases/meta-validate/warn-composite-defined-type.json +++ b/tests/skills/cases/meta-validate/warn-composite-defined-type.json @@ -6,7 +6,7 @@ }, "expect": { "stdoutContains": [ - "23. Составной тип содержит определяемый тип 'DefinedType.Сумма'", + "23. Составной тип содержит 'DefinedType.Сумма'", "только единственным" ] }