mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-07-13 22:35:16 +03:00
feat(meta-compile): отклонять имена реквизитов, совпадающие со стандартными (v1.20)
Раньше совпадение имени собственного реквизита со стандартным (Код, Наименование, Владелец, Родитель, Ссылка, Предопределённый, …) давало лишь предупреждение — теперь жёсткий отказ (платформа такое имя не примет). Проверка типозависима (reservedByContext): у справочника один набор стандартных имён, у документа — другой. Напр. «Номер» — легальный реквизит справочника, отклоняется только у документа. Прочие контексты сохраняют мягкое предупреждение по плоскому списку; реквизиты ТЧ не проверяются. Кейс catalog-object-props: «Код»→«КодНастройки» (было ложное имя). Новый негативный кейс catalog-attr-reserved-name. spec §4. Регресс 41/41 ps1+py. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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."
|
||||
}
|
||||
|
||||
@@ -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}<Attribute uuid="{uid}">')
|
||||
|
||||
@@ -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 Флаги
|
||||
|
||||
| Флаг | Действие | Применимость |
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "Ошибка: имя реквизита совпадает со стандартным",
|
||||
"input": {
|
||||
"type": "Catalog",
|
||||
"name": "Тест",
|
||||
"attributes": ["Код: String(9)"]
|
||||
},
|
||||
"expectError": "зарезервировано стандартным реквизитом"
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
"defaultListForm": "Справочник.НастройкиОбмена.Форма.ФормаСписка",
|
||||
"defaultChoiceForm": "Справочник.НастройкиОбмена.ФормаВыбора",
|
||||
"attributes": [
|
||||
"Код: String(9)"
|
||||
"КодНастройки: String(9)"
|
||||
]
|
||||
},
|
||||
"validatePath": "Catalogs/НастройкиОбмена",
|
||||
|
||||
+2
-2
@@ -89,11 +89,11 @@
|
||||
<ChildObjects>
|
||||
<Attribute uuid="UUID-012">
|
||||
<Properties>
|
||||
<Name>Код</Name>
|
||||
<Name>КодНастройки</Name>
|
||||
<Synonym>
|
||||
<v8:item>
|
||||
<v8:lang>ru</v8:lang>
|
||||
<v8:content>Код</v8:content>
|
||||
<v8:content>Код настройки</v8:content>
|
||||
</v8:item>
|
||||
</Synonym>
|
||||
<Comment/>
|
||||
|
||||
Reference in New Issue
Block a user