Source locations were virtual, computed by recursing to the first and last
child, whose leftmost and rightmost leaves are token nodes; sequence-point
coordinates likewise came from reconstructed token nodes. Store locations as
fields assigned while printing, and derive sequence-point coordinates from the
surrounding real nodes plus the decompiler's fixed formatting, so neither
depends on token children. The using/foreach await modifier becomes a plain
bool field. Characterization gates lock the emitted locations and PDB
coordinates, which are unchanged.
Assisted-by: Claude:claude-opus-4-8:Claude Code
Each child of a C# AST node is declared as a [Slot] partial property, and the
source generator emits the accessor bodies and an ordered slot schema
(SlotCount/GetSlotRole/IsCollectionSlot) from them. Generating the schema
keeps slot order from being mis-stated by hand and lets a DEBUG invariant
check declared slot order against document order on every decompile. The node
hierarchy is converted family by family; the EntityDeclaration leaves flatten
their inherited Attributes/ReturnType/NameToken into each leaf's ordered slot
set. Storage stays the NRefactory linked list at this stage, so only the
declaration model changes and output is unchanged.
Assisted-by: Claude:claude-opus-4-8:Claude Code
The generator emits the IAstVisitor interface, the AcceptVisitor overloads,
and the null-node and pattern-placeholder nodes from [DecompilerAstNode]
declarations, so drop the hand-written equivalents across the C# AST: per-node
AcceptVisitor/DoMatch, the #region Null / #region PatternPlaceholder blocks,
IAstVisitor.cs, and now-dead usings. Also adds AccessorKind and moves
IdentifierExpressionBackreference into the PatternMatching folder.
Assisted-by: Claude:claude-opus-4-8:Claude Code
Introduce a Roslyn source generator that emits the visitor boilerplate for
the C# AST from [DecompilerAstNode]-tagged node declarations: the
IAstVisitor interface, the AcceptVisitor overloads, the pattern-placeholder
nodes, and the initial DoMatch support. AccessorKind lets an accessor's
keyword be chosen independently of its role, an early step toward shedding
the NRefactory role model.