From b4d48ca656a70351abfe8aaf2669d0dee07ff138 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Fri, 3 Jul 2026 19:07:55 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-compile):=20=D0=BE=D1=82=D0=BA=D0=BB?= =?UTF-8?q?=D0=BE=D0=BD=D1=8F=D1=82=D1=8C=20=D0=B8=D0=BC=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D1=80=D0=B5=D0=BA=D0=B2=D0=B8=D0=B7=D0=B8=D1=82=D0=BE=D0=B2?= =?UTF-8?q?,=20=D1=81=D0=BE=D0=B2=D0=BF=D0=B0=D0=B4=D0=B0=D1=8E=D1=89?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=81=D0=BE=20=D1=81=D1=82=D0=B0=D0=BD=D0=B4?= =?UTF-8?q?=D0=B0=D1=80=D1=82=D0=BD=D1=8B=D0=BC=D0=B8=20(v1.20)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Раньше совпадение имени собственного реквизита со стандартным (Код, Наименование, Владелец, Родитель, Ссылка, Предопределённый, …) давало лишь предупреждение — теперь жёсткий отказ (платформа такое имя не примет). Проверка типозависима (reservedByContext): у справочника один набор стандартных имён, у документа — другой. Напр. «Номер» — легальный реквизит справочника, отклоняется только у документа. Прочие контексты сохраняют мягкое предупреждение по плоскому списку; реквизиты ТЧ не проверяются. Кейс catalog-object-props: «Код»→«КодНастройки» (было ложное имя). Новый негативный кейс catalog-attr-reserved-name. spec §4. Регресс 41/41 ps1+py. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../meta-compile/scripts/meta-compile.ps1 | 20 ++++++++++-- .../meta-compile/scripts/meta-compile.py | 32 +++++++++++++++++-- docs/meta-dsl-spec.md | 10 ++++++ .../catalog-attr-reserved-name.json | 9 ++++++ .../meta-compile/catalog-object-props.json | 2 +- .../Catalogs/НастройкиОбмена.xml | 4 +-- 6 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 tests/skills/cases/meta-compile/catalog-attr-reserved-name.json diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 6c6189b7..08e6f3bb 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -1,4 +1,4 @@ -# meta-compile v1.19 — Compile 1C metadata object from JSON +# meta-compile v1.20 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1129,11 +1129,27 @@ $script:reservedAttrNames = @{ "Account"="Счет"; "ValueType"="ТипЗначения"; "ActionPeriodIsBasic"="ПериодДействияБазовый" } +# Стандартные реквизиты по типу объекта (ключи из reservedAttrNames). Имя реквизита, совпадающее +# с ними (англ. ИЛИ рус.), платформа не позволит — жёсткий отказ. Контексты вне карты → мягкое предупреждение. +$script:reservedByContext = @{ + "catalog" = @("Ref","DeletionMark","Predefined","PredefinedDataName","Code","Description","Owner","Parent","IsFolder") + "document" = @("Ref","DeletionMark","Date","Number","Posted") +} + function Emit-Attribute { param([string]$indent, $parsed, [string]$context) # $context: "catalog", "document", "object", "processor", "tabular", "processor-tabular", "register" $attrName = $parsed.name - if ($context -notin @("tabular", "processor-tabular") -and + $ctxReserved = $script:reservedByContext[$context] + if ($ctxReserved) { + foreach ($en in $ctxReserved) { + $ru = $script:reservedAttrNames[$en] + if (($attrName -ieq $en) -or ($ru -and $attrName -ieq $ru)) { + Write-Error "Имя реквизита '$attrName' зарезервировано стандартным реквизитом ($en/$ru) объекта '$context'. Выберите другое имя." + exit 1 + } + } + } elseif ($context -notin @("tabular", "processor-tabular") -and ($script:reservedAttrNames.ContainsKey($attrName) -or $script:reservedAttrNames.ContainsValue($attrName))) { Write-Warning "Attribute '$attrName' conflicts with a standard attribute name. This may cause errors when loading into 1C." } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 76c7dff1..5163c8de 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-compile v1.19 — Compile 1C metadata object from JSON +# meta-compile v1.20 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -1156,9 +1156,37 @@ RESERVED_ATTR_NAMES_RU = { '\u041f\u0435\u0440\u0438\u043e\u0434\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0411\u0430\u0437\u043e\u0432\u044b\u0439', } +# Стандартные реквизиты по типу объекта (EN + RU). Совпадение имени реквизита с ними платформа +# не позволит — жёсткий отказ. Контексты вне карты → мягкое предупреждение по плоскому списку. +RESERVED_BY_CONTEXT = { + 'catalog': { + 'ref', 'ссылка', # Ссылка + 'deletionmark', 'пометкаудаления', # ПометкаУдаления + 'predefined', 'предопределенный', # Предопределенный + 'predefineddataname', 'имяпредопределенныхданных', # ИмяПредопределенныхДанных + 'code', 'код', # Код + 'description', 'наименование', # Наименование + 'owner', 'владелец', # Владелец + 'parent', 'родитель', # Родитель + 'isfolder', 'этогруппа', # ЭтоГруппа + }, + 'document': { + 'ref', 'ссылка', # Ссылка + 'deletionmark', 'пометкаудаления', # ПометкаУдаления + 'date', 'дата', # Дата + 'number', 'номер', # Номер + 'posted', 'проведен', # Проведен + }, +} + def emit_attribute(indent, parsed, context): attr_name = parsed['name'] - if context not in ('tabular', 'processor-tabular') and (attr_name in RESERVED_ATTR_NAMES or attr_name in RESERVED_ATTR_NAMES_RU): + ctx_reserved = RESERVED_BY_CONTEXT.get(context) + if ctx_reserved is not None: + if attr_name.lower() in ctx_reserved: + print(f"meta-compile: имя реквизита '{attr_name}' зарезервировано стандартным реквизитом объекта '{context}'. Выберите другое имя.", file=sys.stderr) + sys.exit(1) + elif context not in ('tabular', 'processor-tabular') and (attr_name in RESERVED_ATTR_NAMES or attr_name in RESERVED_ATTR_NAMES_RU): print(f"WARNING: Attribute '{attr_name}' conflicts with a standard attribute name. This may cause errors when loading into 1C.", file=sys.stderr) uid = new_uuid() X(f'{indent}') diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index ec87aecb..6fdc0372 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -194,6 +194,16 @@ JSON DSL для описания объектов метаданных конф Раздельная форма эквивалентна `String(100)`, `Number(15,2)`, `Number(15,2,nonneg)`. Если `type` уже содержит скобки — `length`/`precision` игнорируются. +**Зарезервированные имена.** Имя собственного реквизита не должно совпадать со стандартным реквизитом объекта +(англ. или рус., регистронезависимо) — платформа такое не примет. Компилятор отклоняет с ошибкой: +- **Catalog**: `Ref`/`Ссылка`, `DeletionMark`/`ПометкаУдаления`, `Predefined`/`Предопределенный`, + `PredefinedDataName`/`ИмяПредопределенныхДанных`, `Code`/`Код`, `Description`/`Наименование`, `Owner`/`Владелец`, + `Parent`/`Родитель`, `IsFolder`/`ЭтоГруппа`. +- **Document**: `Ref`/`Ссылка`, `DeletionMark`/`ПометкаУдаления`, `Date`/`Дата`, `Number`/`Номер`, `Posted`/`Проведен`. + +Проверка **типозависима**: напр. `Номер` — легальное имя реквизита справочника (стандартный он только у документа). +Реквизиты табличных частей проверке не подлежат (там зарезервирован лишь `НомерСтроки`). + ### 4.3 Флаги | Флаг | Действие | Применимость | diff --git a/tests/skills/cases/meta-compile/catalog-attr-reserved-name.json b/tests/skills/cases/meta-compile/catalog-attr-reserved-name.json new file mode 100644 index 00000000..d8610793 --- /dev/null +++ b/tests/skills/cases/meta-compile/catalog-attr-reserved-name.json @@ -0,0 +1,9 @@ +{ + "name": "Ошибка: имя реквизита совпадает со стандартным", + "input": { + "type": "Catalog", + "name": "Тест", + "attributes": ["Код: String(9)"] + }, + "expectError": "зарезервировано стандартным реквизитом" +} diff --git a/tests/skills/cases/meta-compile/catalog-object-props.json b/tests/skills/cases/meta-compile/catalog-object-props.json index ea8f8365..8c694f29 100644 --- a/tests/skills/cases/meta-compile/catalog-object-props.json +++ b/tests/skills/cases/meta-compile/catalog-object-props.json @@ -16,7 +16,7 @@ "defaultListForm": "Справочник.НастройкиОбмена.Форма.ФормаСписка", "defaultChoiceForm": "Справочник.НастройкиОбмена.ФормаВыбора", "attributes": [ - "Код: String(9)" + "КодНастройки: String(9)" ] }, "validatePath": "Catalogs/НастройкиОбмена", diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-object-props/Catalogs/НастройкиОбмена.xml b/tests/skills/cases/meta-compile/snapshots/catalog-object-props/Catalogs/НастройкиОбмена.xml index 54e9a15c..62739aa9 100644 --- a/tests/skills/cases/meta-compile/snapshots/catalog-object-props/Catalogs/НастройкиОбмена.xml +++ b/tests/skills/cases/meta-compile/snapshots/catalog-object-props/Catalogs/НастройкиОбмена.xml @@ -89,11 +89,11 @@ - Код + КодНастройки ru - Код + Код настройки