diff --git a/.claude/skills/form-validate/scripts/form-validate.ps1 b/.claude/skills/form-validate/scripts/form-validate.ps1 index 7ef4f3f6..94b03e4c 100644 --- a/.claude/skills/form-validate/scripts/form-validate.ps1 +++ b/.claude/skills/form-validate/scripts/form-validate.ps1 @@ -1,4 +1,4 @@ -# form-validate v1.4 — Validate 1C managed form +# form-validate v1.5 — Validate 1C managed form # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -370,9 +370,40 @@ if (-not $stopped) { # Extract root segment of path, strip array indices like [0] $cleanPath = $dataPath -replace '\[\d+\]', '' + # Strip leading '~' (current row of DynamicList: ~Список.Поле) + if ($cleanPath.StartsWith('~')) { $cleanPath = $cleanPath.Substring(1) } $segments = $cleanPath -split '\.' $rootAttr = $segments[0] + # Resolve Items..CurrentData.... — table element, not attribute + if ($rootAttr -eq 'Items') { + if ($segments.Count -lt 3 -or $segments[2] -ne 'CurrentData') { + Report-Warn "[$tag] '$elName': DataPath='$dataPath' — unknown Items.* shape, expected Items..CurrentData.*" + continue + } + $tableName = $segments[1] + $tableEl = $null + foreach ($candidate in $allElements) { + if ($candidate.Tag -eq 'Table' -and $candidate.Name -eq $tableName) { + $tableEl = $candidate + break + } + } + if (-not $tableEl) { + Report-Error "[$tag] '$elName': DataPath='$dataPath' — table element '$tableName' not found" + $pathErrors++ + continue + } + $tableDpNode = $tableEl.Node.SelectSingleNode("f:DataPath", $nsMgr) + if (-not $tableDpNode -or -not $tableDpNode.InnerText.Trim()) { + # Table without DataPath — can't resolve further, accept silently + continue + } + $tableDp = $tableDpNode.InnerText.Trim() -replace '\[\d+\]', '' + if ($tableDp.StartsWith('~')) { $tableDp = $tableDp.Substring(1) } + $rootAttr = ($tableDp -split '\.')[0] + } + if (-not $attrMap.ContainsKey($rootAttr)) { Report-Error "[$tag] '$elName': DataPath='$dataPath' — attribute '$rootAttr' not found" $pathErrors++ diff --git a/.claude/skills/form-validate/scripts/form-validate.py b/.claude/skills/form-validate/scripts/form-validate.py index 5a42b17a..478b1e95 100644 --- a/.claude/skills/form-validate/scripts/form-validate.py +++ b/.claude/skills/form-validate/scripts/form-validate.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-validate v1.4 — Validate 1C managed form +# form-validate v1.5 — Validate 1C managed form # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -379,9 +379,35 @@ def main(): path_checked += 1 clean_path = re.sub(r'\[\d+\]', '', data_path) + # Strip leading '~' (current row of DynamicList: ~\u0421\u043f\u0438\u0441\u043e\u043a.\u041f\u043e\u043b\u0435) + if clean_path.startswith('~'): + clean_path = clean_path[1:] segments = clean_path.split(".") root_attr = segments[0] + # Resolve Items..CurrentData.... \u2014 table element, not attribute + if root_attr == 'Items': + if len(segments) < 3 or segments[2] != 'CurrentData': + report_warn(f"[{tag}] '{el_name}': DataPath='{data_path}' \u2014 unknown Items.* shape, expected Items.
.CurrentData.*") + continue + table_name = segments[1] + table_el = None + for candidate in all_elements: + if candidate["Tag"] == 'Table' and candidate["Name"] == table_name: + table_el = candidate + break + if table_el is None: + report_error(f"[{tag}] '{el_name}': DataPath='{data_path}' \u2014 table element '{table_name}' not found") + path_errors += 1 + continue + table_dp_node = table_el["Node"].find(f"{{{F_NS}}}DataPath") + if table_dp_node is None or not (table_dp_node.text or "").strip(): + continue + table_dp = re.sub(r'\[\d+\]', '', (table_dp_node.text or "").strip()) + if table_dp.startswith('~'): + table_dp = table_dp[1:] + root_attr = table_dp.split(".")[0] + if root_attr not in attr_map: report_error(f"[{tag}] '{el_name}': DataPath='{data_path}' \u2014 attribute '{root_attr}' not found") path_errors += 1 diff --git a/tests/skills/cases/form-validate/datapath-currentdata.json b/tests/skills/cases/form-validate/datapath-currentdata.json new file mode 100644 index 00000000..d0aba745 --- /dev/null +++ b/tests/skills/cases/form-validate/datapath-currentdata.json @@ -0,0 +1,5 @@ +{ + "name": "DataPath с Items.
.CurrentData и ~Атрибут не вызывают ложных ошибок", + "setup": "fixture:datapath-currentdata", + "params": { "formPath": "DataProcessors/Spec/Forms/Форма" } +} diff --git a/tests/skills/cases/form-validate/fixtures/datapath-currentdata/DataProcessors/Spec/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-validate/fixtures/datapath-currentdata/DataProcessors/Spec/Forms/Форма/Ext/Form.xml new file mode 100644 index 00000000..efb26b78 --- /dev/null +++ b/tests/skills/cases/form-validate/fixtures/datapath-currentdata/DataProcessors/Spec/Forms/Форма/Ext/Form.xml @@ -0,0 +1,45 @@ + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Тест</v8:content> + </v8:item> + + + +
+ Список + + + + + + + + Список.Ссылка + + + + +
+ + Items.Список.CurrentData.Ссылка + + + + + ~Список.Ссылка + + + + + + + + cfg:DynamicList + + true + + +