From dc186be0a922d5ce5ad053e6744cccb8c19433f6 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Sat, 20 Jun 2026 12:22:58 +0200 Subject: [PATCH] Add typed child accessors over CSharpSlotInfo GetChild/GetChildren/SetChild take a typed CSharpSlotInfo and infer the child type from the slot, delegating to the existing kind-based lookups. Call sites can pass a node's static slot (e.g. node.GetChild(PropertyDeclaration.GetterSlot)) instead of an explicit type argument plus a SlotKind. Assisted-by: Claude:claude-opus-4-8:Claude Code --- ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs b/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs index a3af4b46e..911423dc5 100644 --- a/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs +++ b/ICSharpCode.Decompiler/CSharp/Syntax/AstNode.cs @@ -308,6 +308,12 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return null; } + /// + /// Gets the first child occupying , or null if the slot is empty (or the + /// node declares no such slot). The result type is inferred from the typed slot. + /// + public T? GetChild(CSharpSlotInfo slot) where T : AstNode => GetChildByRole(slot.Kind); + public T? GetParent() where T : AstNode { return Ancestors.OfType().FirstOrDefault(); @@ -327,11 +333,17 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax return collection != null ? (AstNodeCollection)collection : new AstNodeCollection(this, kind); } + /// Gets the collection occupying ; the element type is inferred from the slot. + public AstNodeCollection GetChildren(CSharpSlotInfo slot) where T : AstNode => GetChildrenByRole(slot.Kind); + protected void SetChildByRole(SlotKind kind, T? newChild) where T : AstNode { SetChildByRoleUntyped(kind, newChild); } + /// Sets the single child occupying ; the child type is inferred from the slot. + protected void SetChild(CSharpSlotInfo slot, T? newChild) where T : AstNode => SetChildByRole(slot.Kind, newChild); + #region Slot storage contract // Each concrete node's slots form a flattened child-index space, in source-declaration order. // A single slot occupies exactly one index (even when empty, where GetChild returns null); a