-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Add a source generator that produces a complete implementation of the Iterator pattern for consumer-defined collections and traversals, with deterministic ordering and allocation-aware iteration.
The generator lives in PatternKit.Generators and emits self-contained, readable C# with no runtime PatternKit dependency.
Primary goals:
- Generate iterator types that encapsulate traversal logic.
- Support both
IEnumerator<T>and allocation-lightTryMoveNext(out T)shapes. - Provide common traversal patterns for composites/trees via user-supplied child selectors.
- Be deterministic and reflection-free.
Motivation / Problem
C# makes iteration easy, but the pattern matters when:
- traversal is stateful and must be encapsulated
- multiple traversal strategies exist (DFS/BFS)
- consumers should not depend on internal representation
- allocation costs from iterator state machines should be minimized in hot paths
We want a generator that produces explicit, testable iterator implementations.
Supported Targets (must-have)
The generator must support:
partial class/partial structpartial record class/partial record struct
Two primary iterator models must be supported:
- State-machine iterator (user defines step function; generator emits iterator type).
- Traversal iterator (tree/graph traversal driven by child selector).
Proposed User Experience
A) State-machine iterator (allocation-light)
[Iterator]
public partial struct TokenIterator
{
[IteratorStep]
private bool TryStep(ref IteratorState state, out Token item);
}Generated (representative shape):
public partial struct TokenIterator
{
public bool TryMoveNext(out Token item);
public Token Current { get; }
public Enumerator GetEnumerator();
public struct Enumerator : IEnumerator<Token>
{
public Token Current { get; }
public bool MoveNext();
public void Reset();
public void Dispose();
}
}B) Tree traversal iterator (DFS/BFS)
[TraversalIterator]
public static partial class CategoryTraversal
{
[DepthFirst]
public static partial IEnumerable<Category> DepthFirst(Category root);
[BreadthFirst]
public static partial IEnumerable<Category> BreadthFirst(Category root);
[TraversalChildren]
private static IEnumerable<Category> Children(Category node) => node.Children;
}Generator emits concrete iterator implementations (not compiler-generated iterator state machines) where feasible.
Attributes / Surface Area
Namespace: PatternKit.Generators.Iterator
Core
-
[Iterator]on iterator hostbool GenerateEnumerator(default: true)bool GenerateTryMoveNext(default: true)
-
[IteratorStep]on step method- expected shape:
bool TryStep(ref TState state, out T item)
- expected shape:
Traversal model (optional v1, recommended v1 if you want immediate utility):
[TraversalIterator]on static partial class[DepthFirst]/[BreadthFirst]on partial methods[TraversalChildren]on a method providing children enumeration
Semantics (must-have)
State-machine iterator
- Underlying state stored in a generated/private
Statefield. TryMoveNext(out T)calls user step method.IEnumerator<T>wrapper delegates toTryMoveNext.
Determinism:
- Step evaluation is strictly linear and controlled by
TryStep.
Allocation behavior:
- Prefer struct enumerators.
- Avoid iterator blocks (
yield return) in generated code.
Traversal iterator
-
DFS: pre-order by default; document ordering.
-
BFS: FIFO queue ordering.
-
Cycle handling:
- v1 default: no cycle detection (document).
- optional
DetectCycles=trueconfig, usingHashSet<T>with comparer.
Diagnostics (must-have)
Stable IDs, actionable:
PKIT001Type marked[Iterator]must bepartial.PKIT002No[IteratorStep]method found.PKIT003Multiple[IteratorStep]methods found.PKIT004Step method signature invalid.PKIT005Traversal iterator host must bestatic partial.PKIT006Traversal method signature invalid.PKIT007No[TraversalChildren]provider found.
Generated Code Layout
TypeName.Iterator.g.csTypeName.Traversal.g.cs(if traversal model enabled)
Determinism:
- stable ordering for emission by fully-qualified symbol name.
Testing Expectations
State-machine model:
- Happy path: produces expected sequence.
- Edge: empty sequence.
- Edge: step throws; exception bubbles.
- Diagnostics: missing step, duplicate step, invalid signature.
Traversal model:
- DFS ordering for known tree.
- BFS ordering for known tree.
- Optional: cycle detection behavior if enabled.
Acceptance Criteria
-
[Iterator]works for class/struct/record class/record struct. - Generates allocation-light
TryMoveNext(out T). - Generates
IEnumerator<T>wrapper (struct enumerator preferred). - Deterministic iteration semantics.
- Diagnostics cover missing/duplicate/invalid step definitions.
- Tests cover state-machine iteration (and traversal if enabled).