diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index c51b5db2..b9bc4de5 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.61 — Compile 1C metadata object from JSON +# meta-compile v1.62 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -1270,6 +1270,7 @@ function Emit-StandardAttribute { $fvRaw = OvOr 'FillValue' $null if ($null -eq $fvRaw) { X "$indent`t" } elseif ($fvRaw.emptyRef -eq $true) { X "$indent`t" } + elseif ($fvRaw.typeDescription -eq $true) { X "$indent`t" } # пустое типизированное (ValueType ПВХ) else { $fvN = Normalize-ChoiceValue $fvRaw if ([string]::IsNullOrEmpty($fvN.Text)) { X "$indent`t" } @@ -1944,7 +1945,7 @@ function Emit-Command { # --- 9. TabularSection emitter --- function Emit-TabularSection { - param([string]$indent, [string]$tsName, $columns, [string]$objectType, [string]$objectName, $tsSynonymArg = $null, $tsTooltip = $null, $tsComment = $null, $tsLineNumber = $null, $tsFillChecking = $null) + param([string]$indent, [string]$tsName, $columns, [string]$objectType, [string]$objectName, $tsSynonymArg = $null, $tsTooltip = $null, $tsComment = $null, $tsLineNumber = $null, $tsFillChecking = $null, $tsUse = $null) $uuid = New-Guid-String X "$indent" @@ -1977,9 +1978,11 @@ function Emit-TabularSection { if (-not ($tsLineNumber -is [string] -and $tsLineNumber -eq '')) { Emit-TabularStandardAttributes "$indent`t`t" $tsLineNumber } - # Use=ForItem у ТЧ иерархических ссылочных типов (Catalog, ChartOfCharacteristicTypes); Document не имеет Use. + # Use у ТЧ иерархических ссылочных типов (Catalog, ChartOfCharacteristicTypes); Document не имеет Use. + # Дефолт ForItem; ForFolderAndItem/ForFolder — при явном ключе `use` объектной формы ТЧ. if ($objectType -in @("Catalog", "ChartOfCharacteristicTypes")) { - X "$indent`t`tForItem" + $use = if ($tsUse) { "$tsUse" } else { "ForItem" } + X "$indent`t`t$use" } X "$indent`t" @@ -3987,10 +3990,10 @@ if ($objType -in $typesWithAttrTS) { # Нормализуем в $tsSections[name] = @{ columns; synonym; tooltip; comment }. function New-TsEntry { param($val) if ($val -is [array] -or $val.GetType().Name -eq 'Object[]') { - return @{ columns = @($val); synonym = $null; tooltip = $null; comment = $null; lineNumber = $null; fillChecking = $null } + return @{ columns = @($val); synonym = $null; tooltip = $null; comment = $null; lineNumber = $null; fillChecking = $null; use = $null } } $cols = if ($val.attributes) { @($val.attributes) } elseif ($val.columns) { @($val.columns) } else { @() } - return @{ columns = $cols; synonym = $val.synonym; tooltip = $val.tooltip; comment = if ($val.comment) { "$($val.comment)" } else { $null }; lineNumber = $val.lineNumber; fillChecking = $val.fillChecking } + return @{ columns = $cols; synonym = $val.synonym; tooltip = $val.tooltip; comment = if ($val.comment) { "$($val.comment)" } else { $null }; lineNumber = $val.lineNumber; fillChecking = $val.fillChecking; use = $val.use } } if ($def.tabularSections -is [array] -or $def.tabularSections.GetType().Name -eq "Object[]") { foreach ($ts in $def.tabularSections) { $tsSections[$ts.name] = New-TsEntry $ts } @@ -4040,7 +4043,7 @@ if ($objType -in $typesWithAttrTS) { } foreach ($tsName in $tsSections.Keys) { $tsE = $tsSections[$tsName] - Emit-TabularSection "`t`t`t" $tsName $tsE.columns $objType $objName $tsE.synonym $tsE.tooltip $tsE.comment $tsE.lineNumber $tsE.fillChecking + Emit-TabularSection "`t`t`t" $tsName $tsE.columns $objType $objName $tsE.synonym $tsE.tooltip $tsE.comment $tsE.lineNumber $tsE.fillChecking $tsE.use } foreach ($af in $acctFlags) { Emit-Attribute "`t`t`t" $af "account-flag" "AccountingFlag" diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index c93914cb..c6bfc965 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.61 — Compile 1C metadata object from JSON +# meta-compile v1.62 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -1294,6 +1294,8 @@ def emit_standard_attribute(indent, attr_name, ov=None): X(f'{indent}\t') elif isinstance(fv_raw, dict) and fv_raw.get('emptyRef') is True: X(f'{indent}\t') + elif isinstance(fv_raw, dict) and fv_raw.get('typeDescription') is True: + X(f'{indent}\t') # пустое типизированное (ValueType ПВХ) else: fv_xt, fv_tx = normalize_choice_value(fv_raw) if fv_tx == '' or fv_tx is None: @@ -2007,7 +2009,7 @@ def emit_command(indent, cmd_name, cmd): X(f'{indent}\t') X(f'{indent}') -def emit_tabular_section(indent, ts_name, columns, object_type, object_name, ts_synonym_arg=None, ts_tooltip=None, ts_comment=None, ts_line_number=None, ts_fill_checking=None): +def emit_tabular_section(indent, ts_name, columns, object_type, object_name, ts_synonym_arg=None, ts_tooltip=None, ts_comment=None, ts_line_number=None, ts_fill_checking=None, ts_use=None): uid = new_uuid() X(f'{indent}') type_prefix = f'{object_type}TabularSection' @@ -2037,7 +2039,7 @@ def emit_tabular_section(indent, ts_name, columns, object_type, object_name, ts_ if not (isinstance(ts_line_number, str) and ts_line_number == ''): emit_tabular_standard_attributes(f'{indent}\t\t', ts_line_number) if object_type in ('Catalog', 'ChartOfCharacteristicTypes'): - X(f'{indent}\t\tForItem') + X(f'{indent}\t\t{ts_use if ts_use else "ForItem"}') X(f'{indent}\t') ts_context = 'processor-tabular' if object_type in ('DataProcessor', 'Report') else 'tabular' X(f'{indent}\t') @@ -3900,10 +3902,10 @@ if obj_type in types_with_attr_ts: # Значение ТЧ: массив колонок (синоним авто) ЛИБО объект {attributes/columns, synonym, tooltip, comment}. def new_ts_entry(val): if isinstance(val, list): - return {'columns': val, 'synonym': None, 'tooltip': None, 'comment': None, 'lineNumber': None, 'fillChecking': None} + return {'columns': val, 'synonym': None, 'tooltip': None, 'comment': None, 'lineNumber': None, 'fillChecking': None, 'use': None} cols = _as_list(val.get('attributes') or val.get('columns') or []) return {'columns': cols, 'synonym': val.get('synonym'), 'tooltip': val.get('tooltip'), - 'comment': str(val['comment']) if val.get('comment') else None, 'lineNumber': val.get('lineNumber'), 'fillChecking': val.get('fillChecking')} + 'comment': str(val['comment']) if val.get('comment') else None, 'lineNumber': val.get('lineNumber'), 'fillChecking': val.get('fillChecking'), 'use': val.get('use')} if isinstance(ts_data, list): for ts in ts_data: ts_sections[ts['name']] = new_ts_entry(ts) @@ -3955,7 +3957,7 @@ if obj_type in types_with_attr_ts: emit_attribute('\t\t\t', a, context) for ts_name in ts_order: e = ts_sections[ts_name] - emit_tabular_section('\t\t\t', ts_name, e['columns'], obj_type, obj_name, e['synonym'], e['tooltip'], e['comment'], e.get('lineNumber'), e.get('fillChecking')) + emit_tabular_section('\t\t\t', ts_name, e['columns'], obj_type, obj_name, e['synonym'], e['tooltip'], e['comment'], e.get('lineNumber'), e.get('fillChecking'), e.get('use')) for af in acct_flags: emit_attribute('\t\t\t', af, 'account-flag', 'AccountingFlag') for edf in ext_dim_flags: diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 index 50ee1fb0..e2d47a92 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 @@ -1,4 +1,4 @@ -# meta-decompile v0.52 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.53 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts, ChartOfCalculationTypes, Document, @@ -1072,6 +1072,7 @@ if ($saNode) { if ($fvN -and $fvN.GetAttribute('nil', 'http://www.w3.org/2001/XMLSchema-instance') -ne 'true') { $fvXt = $fvN.GetAttribute('type', 'http://www.w3.org/2001/XMLSchema-instance') if ($fvXt -match 'DesignTimeRef$' -and $fvN.InnerText -eq '') { $ov['fillValue'] = [ordered]@{ emptyRef = $true } } + elseif ($fvXt -match 'TypeDescription$' -and $fvN.InnerText -eq '') { $ov['fillValue'] = [ordered]@{ typeDescription = $true } } # пустое типизированное (реквизит ValueType ПВХ) ≠ xs:string else { $ov['fillValue'] = Convert-ChScalarNode $fvN } } $saCmt = $sa.SelectSingleNode('xr:Comment', $nsm); if ($saCmt -and $saCmt.InnerText) { $ov['comment'] = $saCmt.InnerText } @@ -1237,6 +1238,8 @@ if ($childObjs) { $tsCmtN = $tsp.SelectSingleNode('md:Comment', $nsm); $tsCmt = if ($tsCmtN) { $tsCmtN.InnerText } else { '' } # FillChecking ТЧ (обязательность заполнения; omit при DontCheck). $tsFcN = $tsp.SelectSingleNode('md:FillChecking', $nsm); $tsFc = if ($tsFcN -and $tsFcN.InnerText -ne 'DontCheck') { $tsFcN.InnerText } else { '' } + # Use ТЧ (иерархические Catalog/ПВХ: ForItem/ForFolder/ForFolderAndItem; omit при дефолте ForItem). + $tsUseN = $tsp.SelectSingleNode('md:Use', $nsm); $tsUse = if ($tsUseN -and $tsUseN.InnerText -ne 'ForItem') { $tsUseN.InnerText } else { '' } # TS-блок стандартных реквизитов (LineNumber). Наличие блока — пер-ТЧ артефакт (~6% ТЧ его опускают, # правило не выводимо). Faithful roundtrip: нет блока → маркер подавления `lineNumber: ""` (дом-конвенция); # есть блок → захват кастомизации LineNumber (omit-on-default по свойству), all-default → без ключа. @@ -1259,12 +1262,13 @@ if ($childObjs) { if ($lnFvT -match 'decimal$') { $lnObj['fillValue'] = if ($lnFvN.InnerText -match '^-?\d+$') { [long]$lnFvN.InnerText } else { [double]$lnFvN.InnerText } } } } - if ($tsSynCustom -or ($null -ne $tsTt) -or $tsCmt -or $tsFc -or $lnObj.Count -gt 0 -or (-not $hasBlock)) { + if ($tsSynCustom -or ($null -ne $tsTt) -or $tsCmt -or $tsFc -or $tsUse -or $lnObj.Count -gt 0 -or (-not $hasBlock)) { $to = [ordered]@{} if ($tsSynCustom) { $to['synonym'] = $tsSyn } if ($null -ne $tsTt) { $to['tooltip'] = $tsTt } if ($tsCmt) { $to['comment'] = $tsCmt } if ($tsFc) { $to['fillChecking'] = $tsFc } + if ($tsUse) { $to['use'] = $tsUse } if (-not $hasBlock) { $to['lineNumber'] = '' } elseif ($lnObj.Count -gt 0) { $to['lineNumber'] = $lnObj } $to['attributes'] = $cols $tsMap[$tsName] = $to diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.py b/.claude/skills/meta-decompile/scripts/meta-decompile.py index cfe05ca6..3357e60d 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.py +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-decompile v0.52 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.53 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Зеркало meta-decompile.ps1 (КАНОН). Структура 1:1 — те же имена функций, порядок, комментарии. @@ -1553,6 +1553,8 @@ def build_dsl(): fv_xt = _attr(fv_n, 'type', NS_XSI) if re.search(r'DesignTimeRef$', fv_xt, re.I) and _text(fv_n) == '': ov['fillValue'] = {'emptyRef': True} + elif re.search(r'TypeDescription$', fv_xt, re.I) and _text(fv_n) == '': + ov['fillValue'] = {'typeDescription': True} # пустое типизированное (реквизит ValueType ПВХ) ≠ xs:string else: ov['fillValue'] = convert_ch_scalar_node(fv_n) sa_cmt = _single(sa, 'xr:Comment') @@ -1745,6 +1747,9 @@ def build_dsl(): ts_cmt = _text(ts_cmt_n) if ts_cmt_n is not None else '' ts_fc_n = _single(tsp, 'md:FillChecking') ts_fc = _text(ts_fc_n) if (ts_fc_n is not None and _text(ts_fc_n) != 'DontCheck') else '' + # Use ТЧ (иерархические Catalog/ПВХ: ForItem/ForFolder/ForFolderAndItem; omit при дефолте ForItem). + ts_use_n = _single(tsp, 'md:Use') + ts_use = _text(ts_use_n) if (ts_use_n is not None and _text(ts_use_n) != 'ForItem') else '' # TS-блок стандартных реквизитов (LineNumber). ln_obj = {} sa_ts_node = _single(tsp, 'md:StandardAttributes') @@ -1777,7 +1782,7 @@ def build_dsl(): ln_fv_t = _attr(ln_fv_n, 'type', NS_XSI) if re.search(r'decimal$', ln_fv_t, re.I): ln_obj['fillValue'] = int(_text(ln_fv_n)) if re.match(r'^-?\d+$', _text(ln_fv_n)) else float(_text(ln_fv_n)) - if ts_syn_custom or (ts_tt is not None) or ts_cmt or ts_fc or len(ln_obj) > 0 or (not has_block): + if ts_syn_custom or (ts_tt is not None) or ts_cmt or ts_fc or ts_use or len(ln_obj) > 0 or (not has_block): to = {} if ts_syn_custom: to['synonym'] = ts_syn @@ -1787,6 +1792,8 @@ def build_dsl(): to['comment'] = ts_cmt if ts_fc: to['fillChecking'] = ts_fc + if ts_use: + to['use'] = ts_use if not has_block: to['lineNumber'] = '' elif len(ln_obj) > 0: diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index 43aae8e3..49c15a54 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -308,9 +308,9 @@ JSON-**строка** → `xsi:type="xs:string"` (напр. год `"2000"`, к } ``` -Свойства объектной формы ТЧ: `synonym` (ML; нет ключа → авто из имени), `tooltip` (ML), `comment` (строка), `attributes` (колонки; синоним `columns`), `lineNumber` (кастомизация стандартного реквизита НомерСтроки, см. ниже). +Свойства объектной формы ТЧ: `synonym` (ML; нет ключа → авто из имени), `tooltip` (ML), `comment` (строка), `fillChecking` (`DontCheck`|`ShowError`|`ShowWarning`), `use` (`ForItem`|`ForFolder`|`ForFolderAndItem`, только Catalog/ПВХ; omit при дефолте `ForItem`), `attributes` (колонки; синоним `columns`), `lineNumber` (кастомизация стандартного реквизита НомерСтроки, см. ниже). -Для Catalog добавляется `ForItem` в Properties табличной части. Для Document Use не применяется. +Для Catalog/ChartOfCharacteristicTypes в Properties ТЧ пишется `` (дефолт `ForItem`; ключ `use` объектной формы → `ForFolder`/`ForFolderAndItem`). Document `` не имеет. ### 5.1 `lineNumber` — кастомизация стандартного реквизита НомерСтроки @@ -426,6 +426,10 @@ LineNumber дефолтные. Ключ `lineNumber` на объектной ф > «Пустая ссылка» как значение заполнения (`` без содержимого) — маркер > `fillValue: {emptyRef: true}` (декомпилятор проставляет его сам; тип из строки не выводится, т.к. `DefinedType.X` > непрозрачен). Применимо к реквизиту и стандартному реквизиту (в т.ч. `lineNumber` ТЧ поддерживает `fillValue`). +> +> Пустое типизированное значение (`` без содержимого) — маркер +> `fillValue: {typeDescription: true}` (стандартный реквизит `ValueType` ПВХ: его пустое значение — пустое +> описание типов, а не пустая строка). Декомпилятор проставляет сам. **Профиль материализованного блока** (значения, которые платформа заполняет автоматически — задавать их в DSL не нужно):