diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 6ea04904..b29353d0 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.51 — Compile 1C managed form from JSON or object metadata +# form-compile v1.52 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -1955,6 +1955,9 @@ $script:formTypeSynonyms["планобменассылка"] = "Exc $script:formTypeSynonyms["бизнеспроцессссылка"] = "BusinessProcessRef" $script:formTypeSynonyms["задачассылка"] = "TaskRef" $script:formTypeSynonyms["определяемыйтип"] = "DefinedType" +$script:formTypeSynonyms["характеристика"] = "Characteristic" +$script:formTypeSynonyms["любаяссылка"] = "AnyRef" +$script:formTypeSynonyms["любаяссылкаиб"] = "AnyIBRef" # Known invalid types (runtime/UI types that don't exist in XDTO schema) $script:knownInvalidTypes = @{ @@ -2110,6 +2113,17 @@ function Emit-SingleType { return } + # TypeSet (набор типов) → : определяемый тип / характеристика (именованные) + # + «любая ссылка вида» (голый ref-вид без .Имя). Развязка с обычным типом — по наличию точки. + if ($typeStr -match '^(DefinedType|Characteristic)\.') { + X "$indentcfg:$typeStr" + return + } + if ($typeStr -match '^(AnyRef|AnyIBRef|CatalogRef|DocumentRef|EnumRef|ExchangePlanRef|TaskRef|BusinessProcessRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef)$') { + X "$indentcfg:$typeStr" + return + } + # cfg: references (CatalogRef.XXX, DocumentObject.XXX, etc.) if ($typeStr -match '^(CatalogRef|CatalogObject|DocumentRef|DocumentObject|EnumRef|ChartOfAccountsRef|ChartOfAccountsObject|ChartOfCharacteristicTypesRef|ChartOfCharacteristicTypesObject|ChartOfCalculationTypesRef|ChartOfCalculationTypesObject|ExchangePlanRef|ExchangePlanObject|BusinessProcessRef|BusinessProcessObject|TaskRef|TaskObject|InformationRegisterRecordSet|InformationRegisterRecordManager|AccumulationRegisterRecordSet|AccountingRegisterRecordSet|ConstantsSet|DataProcessorObject|ReportObject)\.') { X "$indentcfg:$typeStr" diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index faa9ceb7..6ddc0363 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.51 — Compile 1C managed form from JSON or object metadata +# form-compile v1.52 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -2345,6 +2345,9 @@ _FORM_TYPE_SYNONYMS = { "бизнеспроцессссылка": "BusinessProcessRef", "задачассылка": "TaskRef", "определяемыйтип": "DefinedType", + "характеристика": "Characteristic", + "любаяссылка": "AnyRef", + "любаяссылкаиб": "AnyIBRef", } @@ -2432,6 +2435,15 @@ def emit_single_type(lines, type_str, indent): lines.append(f'{indent}cfg:DynamicList') return + # TypeSet (набор типов) → : определяемый тип / характеристика (именованные) + # + «любая ссылка вида» (голый ref-вид без .Имя). Развязка с обычным типом — по наличию точки. + if re.match(r'^(DefinedType|Characteristic)\.', type_str): + lines.append(f'{indent}cfg:{type_str}') + return + if re.match(r'^(AnyRef|AnyIBRef|CatalogRef|DocumentRef|EnumRef|ExchangePlanRef|TaskRef|BusinessProcessRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef)$', type_str): + lines.append(f'{indent}cfg:{type_str}') + return + # cfg: references if CFG_REF_PATTERN.match(type_str): lines.append(f'{indent}cfg:{type_str}') diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 133956df..74f5b087 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.33 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.34 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -855,6 +855,13 @@ function Decompile-Type { } [void]$parts.Add($short) } + # TypeSet (набор типов): определяемый тип / характеристика / «любая ссылка вида». + # Префикс cfg:/v8: снимаем — обратный роутинг в компиляторе по форме токена. + foreach ($ts in @($typeNode.SelectNodes("v8:TypeSet", $ns))) { + $raw = $ts.InnerText.Trim() + $short = $raw -replace '^(v8ui|v8|cfg):', '' + [void]$parts.Add($short) + } if ($parts.Count -eq 0) { return $null } if ($parts.Count -eq 1) { return $parts[0] } return ($parts -join ' | ') diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 14462b5b..172a4f29 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -742,12 +742,27 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs | `"Picture"` | `v8ui:Picture` | | `"DynamicList"` | `cfg:DynamicList` | +### Наборы типов (TypeSet → ``) + +«Набор типов» вместо конкретного типа. Развязка с обычным типом — по наличию `.Имя`: + +| DSL | XML | Смысл | +|-----|-----|-------| +| `"DefinedType.ДенежнаяСумма"` | `cfg:DefinedType.ДенежнаяСумма` | определяемый тип (синоним `ОпределяемыйТип.X`) | +| `"Characteristic.Номенклатура"` | `cfg:Characteristic.Номенклатура` | характеристика (синоним `Характеристика.X`) | +| `"AnyRef"` | `cfg:AnyRef` | любая ссылка (синоним `ЛюбаяСсылка`) | +| `"AnyIBRef"` | `cfg:AnyIBRef` | любая ссылка ИБ | +| `"CatalogRef"` (голый, без `.Имя`) | `cfg:CatalogRef` | любая ссылка справочника (аналогично `DocumentRef`, `EnumRef`, `ExchangePlanRef`, `TaskRef`, `BusinessProcessRef`, `ChartOf*Ref`) | + +`CatalogRef.Валюты` (с `.Имя`) → обычный ``; `CatalogRef` (голый) → ``. + ### Составные типы -Разделитель `" | "`: +Разделитель `" | "` (или `+`). Каждая часть независимо роутится в `` или `` (можно смешивать): ```json "type": "CatalogRef.Организации | CatalogRef.ИндивидуальныеПредприниматели" +"type": "CatalogRef.Контрагенты | DefinedType.ДенежнаяСумма" ``` --- diff --git a/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml index 2ae76856..0971f54f 100644 --- a/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/table/DataProcessors/Таблица/Forms/Форма/Ext/Form.xml @@ -134,11 +134,21 @@ + + + cfg:AnyRef + + + + + cfg:CatalogRef + + - + <v8:item> <v8:lang>ru</v8:lang> diff --git a/tests/skills/cases/form-compile/table.json b/tests/skills/cases/form-compile/table.json index b6eb0e0c..d4931af8 100644 --- a/tests/skills/cases/form-compile/table.json +++ b/tests/skills/cases/form-compile/table.json @@ -38,7 +38,9 @@ { "name": "Данные", "type": "ValueTable", "columns": [ { "name": "Дата", "type": "date" }, { "name": "Сумма", "type": "decimal(15,2)" }, - { "name": "Комментарий", "type": "string(200)" } + { "name": "Комментарий", "type": "string(200)" }, + { "name": "Объект", "type": "AnyRef" }, + { "name": "Источник", "type": "CatalogRef" } ]} ], "commands": [