diff --git a/.claude/skills/xdto-info/scripts/xdto-info.ps1 b/.claude/skills/xdto-info/scripts/xdto-info.ps1 index c4041857..ff281af8 100644 --- a/.claude/skills/xdto-info/scripts/xdto-info.ps1 +++ b/.claude/skills/xdto-info/scripts/xdto-info.ps1 @@ -333,6 +333,10 @@ function Get-PropRows([System.Xml.XmlElement]$type, $pkg, [int]$depth, [int]$ind $typeText = "" $children = $null $childPkg = $pkg + # Именованный вложенный тип берётся так же, как корневой; окольный путь + # через свойство владельца нужен только анонимному — имени у него нет + $objName = $null + $objNs = $null $anon = $null foreach ($c in $p.ChildNodes) { @@ -342,6 +346,7 @@ function Get-PropRows([System.Xml.XmlElement]$type, $pkg, [int]$depth, [int]$ind if ($anon) { if ($anon.GetAttribute("type", $XSI_NS) -eq "ObjectType") { $typeText = "объект (анонимный)" + $objName = "(анонимный)" $children = $anon # анонимные раскрываем всегда: смотреть отдельно негде } else { $res = Resolve-Scalar $anon $pkg @@ -363,6 +368,8 @@ function Get-PropRows([System.Xml.XmlElement]$type, $pkg, [int]$depth, [int]$ind } elseif ($target.Element.get_LocalName() -eq "objectType") { $typeText = "объект $($q.Local)" if ($target.Package.Namespace -ne $pkg.Namespace) { $typeText += " · $($target.Package.Name)" } + $objName = $q.Local + $objNs = $target.Package.Namespace $children = $target.Element $childPkg = $target.Package } else { @@ -379,6 +386,7 @@ function Get-PropRows([System.Xml.XmlElement]$type, $pkg, [int]$depth, [int]$ind [void]$rows.Add([pscustomobject]@{ Indent = $indent; Name = $pname; Type = $typeText Flags = $flags; Notes = ($notes | Where-Object { $_ }) + ObjName = $objName; ObjNs = $objNs }) if ($children) { @@ -548,6 +556,11 @@ function Show-Type($pkg, [string]$typeName) { O "Допустимые значения ($($res.Enum.Count)):" foreach ($v in $res.Enum) { O " $v" } } + O "" + O "Создание:" + # Создать(<Тип>, <Значение>) принимает именно ТипЗначенияXDTO — + # для объектного типа эта форма неприменима + O " Значение = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(`"$($pkg.Namespace)`", `"$typeName`"), Значение);" return } @@ -582,14 +595,19 @@ function Show-Type($pkg, [string]$typeName) { O " Объект = ФабрикаXDTO.Создать(Тип);" # Рецепты для вложенных и анонимных типов: имени у анонимного нет, через # ФабрикаXDTO.Тип(ns, имя) его не получить — только от свойства владельца - $nested = @($rows | Where-Object { $_.Indent -eq 0 -and $_.Type -like "объект *" } | Select-Object -First 1) - if ($nested.Count -gt 0) { - O " Вложенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить(`"$($nested[0].Name)`").Тип);" + $named = @($rows | Where-Object { $_.ObjName -and $_.ObjName -ne "(анонимный)" } | Select-Object -First 1) + if ($named.Count -gt 0) { + O " // вложенный именованный тип — так же, как корневой:" + O " $($named[0].Name) = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип(`"$($named[0].ObjNs)`", `"$($named[0].ObjName)`"));" } - $textProp = @($rows | Where-Object { $_.Flags -contains "значение элемента" } | Select-Object -First 1) - if ($textProp.Count -gt 0) { - O " // тип со значением элемента: значение задаётся при создании" - O " Узел = ФабрикаXDTO.Создать(ТипУзла, Значение);" + $anonRow = @($rows | Where-Object { $_.ObjName -eq "(анонимный)" } | Select-Object -First 1) + if ($anonRow.Count -gt 0) { + O " // у анонимного типа нет имени — только через свойство владельца:" + O " $($anonRow[0].Name) = ФабрикаXDTO.Создать(Тип.Свойства.Получить(`"$($anonRow[0].Name)`").Тип);" + } + $textRow = @($rows | Where-Object { $_.Flags -contains "значение элемента" } | Select-Object -First 1) + if ($textRow.Count -gt 0) { + O " // собственное значение узла лежит в свойстве $($textRow[0].Name)" } } diff --git a/.claude/skills/xdto-info/scripts/xdto-info.py b/.claude/skills/xdto-info/scripts/xdto-info.py index 76b5524e..c660b69b 100644 --- a/.claude/skills/xdto-info/scripts/xdto-info.py +++ b/.claude/skills/xdto-info/scripts/xdto-info.py @@ -352,12 +352,17 @@ def get_prop_rows(type_el, pkg, depth, indent, seen): type_text = "" children = None child_pkg = pkg + # Именованный вложенный тип берётся так же, как корневой; окольный путь + # через свойство владельца нужен только анонимному — имени у него нет + obj_name = None + obj_ns = None anon = next((c for c in p if isinstance(c.tag, str) and local(c) == "typeDef"), None) if anon is not None: if anon.get(f"{{{XSI_NS}}}type") == "ObjectType": type_text = "объект (анонимный)" + obj_name = "(анонимный)" children = anon # анонимные раскрываем всегда: смотреть отдельно негде else: res = resolve_scalar(anon, pkg) @@ -380,6 +385,8 @@ def get_prop_rows(type_el, pkg, depth, indent, seen): type_text = "объект " + q[1] if target[1].Namespace != pkg.Namespace: type_text += " · " + target[1].Name + obj_name = q[1] + obj_ns = target[1].Namespace children = target[0] child_pkg = target[1] else: @@ -391,7 +398,8 @@ def get_prop_rows(type_el, pkg, depth, indent, seen): notes.append("значения: " + ", ".join(res["Enum"][:8])) rows.append({"Indent": indent, "Name": pname, "Type": type_text, - "Flags": flags, "Notes": [n for n in notes if n]}) + "Flags": flags, "Notes": [n for n in notes if n], + "ObjName": obj_name, "ObjNs": obj_ns}) if children is not None: cname = children.get("name") @@ -399,7 +407,7 @@ def get_prop_rows(type_el, pkg, depth, indent, seen): is_anon = not cname if not is_anon and key in seen: rows.append({"Indent": indent + 1, "Name": "(раскрыт выше)", "Type": "", - "Flags": [], "Notes": []}) + "Flags": [], "Notes": [], "ObjName": None, "ObjNs": None}) elif is_anon or depth > 1: next_seen = set(seen) if not is_anon: @@ -549,6 +557,11 @@ def show_type(pkg, type_name): O(f'Допустимые значения ({len(res["Enum"])}):') for v in res["Enum"]: O(" " + v) + O("") + O("Создание:") + # Создать(<Тип>, <Значение>) принимает именно ТипЗначенияXDTO — + # для объектного типа эта форма неприменима + O(f' Значение = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("{pkg.Namespace}", "{type_name}"), Значение);') return hdr = f"=== Тип XDTO: {type_name} ===" @@ -585,12 +598,17 @@ def show_type(pkg, type_name): O(" Объект = ФабрикаXDTO.Создать(Тип);") # Рецепты для вложенных и анонимных типов: имени у анонимного нет, через # ФабрикаXDTO.Тип(ns, имя) его не получить — только от свойства владельца - nested = next((r for r in rows if r["Indent"] == 0 and r["Type"].startswith("объект ")), None) - if nested: - O(f' Вложенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("{nested["Name"]}").Тип);') - if any("значение элемента" in r["Flags"] for r in rows): - O(" // тип со значением элемента: значение задаётся при создании") - O(" Узел = ФабрикаXDTO.Создать(ТипУзла, Значение);") + named = next((r for r in rows if r.get("ObjName") and r.get("ObjName") != "(анонимный)"), None) + if named: + O(" // вложенный именованный тип — так же, как корневой:") + O(f' {named["Name"]} = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("{named["ObjNs"]}", "{named["ObjName"]}"));') + anon_row = next((r for r in rows if r.get("ObjName") == "(анонимный)"), None) + if anon_row: + O(" // у анонимного типа нет имени — только через свойство владельца:") + O(f' {anon_row["Name"]} = ФабрикаXDTO.Создать(Тип.Свойства.Получить("{anon_row["Name"]}").Тип);') + text_row = next((r for r in rows if "значение элемента" in r["Flags"]), None) + if text_row: + O(f' // собственное значение узла лежит в свойстве {text_row["Name"]}') def show_used_by(type_name, owner_pkg): diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt b/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt index 89eb0014..dee7993d 100644 --- a/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt @@ -14,4 +14,5 @@ Создание: Тип = ФабрикаXDTO.Тип("urn:test:uses", "Заявка"); Объект = ФабрикаXDTO.Создать(Тип); - Вложенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("Вид").Тип); + // вложенный именованный тип — так же, как корневой: + Вид = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("urn:test:common", "Справочник")); diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt index 43a48f60..9e31133b 100644 --- a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt @@ -18,6 +18,8 @@ Создание: Тип = ФабрикаXDTO.Тип("urn:test:nested", "Документ"); Объект = ФабрикаXDTO.Создать(Тип); - Вложенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("Реквизиты").Тип); - // тип со значением элемента: значение задаётся при создании - Узел = ФабрикаXDTO.Создать(ТипУзла, Значение); + // вложенный именованный тип — так же, как корневой: + Реквизиты = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("urn:test:nested", "Реквизиты")); + // у анонимного типа нет имени — только через свойство владельца: + Встроенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("Встроенный").Тип); + // собственное значение узла лежит в свойстве __content diff --git a/tests/skills/cases/xdto-info/snapshots/required-only/required-only.txt b/tests/skills/cases/xdto-info/snapshots/required-only/required-only.txt index 0272951a..0820b686 100644 --- a/tests/skills/cases/xdto-info/snapshots/required-only/required-only.txt +++ b/tests/skills/cases/xdto-info/snapshots/required-only/required-only.txt @@ -15,6 +15,8 @@ Создание: Тип = ФабрикаXDTO.Тип("urn:test:nested", "Документ"); Объект = ФабрикаXDTO.Создать(Тип); - Вложенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("Реквизиты").Тип); - // тип со значением элемента: значение задаётся при создании - Узел = ФабрикаXDTO.Создать(ТипУзла, Значение); + // вложенный именованный тип — так же, как корневой: + Реквизиты = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("urn:test:nested", "Реквизиты")); + // у анонимного типа нет имени — только через свойство владельца: + Встроенный = ФабрикаXDTO.Создать(Тип.Свойства.Получить("Встроенный").Тип); + // собственное значение узла лежит в свойстве __content diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt b/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt index b74da03c..e71a984a 100644 --- a/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt +++ b/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt @@ -6,3 +6,6 @@ Допустимые значения (2): Поручение Требование + +Создание: + Значение = ФабрикаXDTO.Создать(ФабрикаXDTO.Тип("urn:test:types", "ВидДокумента"), Значение);