-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
Add a source generator that produces boilerplate-free, GoF-consistent Composite pattern scaffolding for tree-like object graphs, including generated node/leaf base types, child management helpers, and optional traversal helpers.
The generator lives in PatternKit.Generators and emits self-contained C# with no runtime PatternKit dependency.
Primary goals:
- Provide a consistent, typed composite model (Component / Composite / Leaf).
- Generate child collection handling and safe defaults.
- Enable deterministic traversal helpers (DFS/BFS) optionally.
- Keep implementations readable and debuggable.
Motivation / Problem
Composite implementations frequently repeat:
- base component contract
- child management API (Add/Remove/Clear)
- safe iteration, null handling, and invariants
- traversal helpers
We want a generator that emits the standard scaffolding so consumers can focus on domain behavior.
Supported Targets (must-have)
The generator must support:
partial interface/partial abstract classas the component contract- user-provided leaf/composite types (partial) or generator-emitted defaults
Two models:
- Contract-first composite: annotate the component contract; generator emits base + helpers.
- Type-first composite: annotate a root type and infer component type.
V1 can focus on contract-first.
Proposed User Experience
A) Contract-first composite
[CompositeComponent]
public partial interface ICategory
{
string Name { get; }
}Generated (representative shape):
public abstract partial class CategoryComponentBase : ICategory
{
public abstract string Name { get; }
public virtual bool IsLeaf => true;
public virtual IReadOnlyList<ICategory> Children => Array.Empty<ICategory>();
public virtual void Add(ICategory child) => throw new NotSupportedException();
public virtual bool Remove(ICategory child) => throw new NotSupportedException();
public virtual void Clear() => throw new NotSupportedException();
}
public abstract partial class CategoryCompositeBase : CategoryComponentBase
{
public override bool IsLeaf => false;
public override IReadOnlyList<ICategory> Children { get; }
public override void Add(ICategory child);
public override bool Remove(ICategory child);
public override void Clear();
}Consumers implement leaf/composite behavior by inheriting appropriate base.
B) Optional traversal helpers
public static class CategoryTraversal
{
public static IEnumerable<ICategory> DepthFirst(ICategory root);
public static IEnumerable<ICategory> BreadthFirst(ICategory root);
}Attributes / Surface Area
Namespace: PatternKit.Generators.Composite
Core
-
[CompositeComponent]on component contractstring? ComponentBaseName(default:<Name>ComponentBase)string? CompositeBaseName(default:<Name>CompositeBase)string ChildrenPropertyName(default:Children)CompositeChildrenStorage Storage(default:List)bool GenerateTraversalHelpers(default: false)
Optional:
[CompositeIgnore]for members that should not appear in base types.
Enums:
CompositeChildrenStorage:List,ImmutableArray(v2)
Semantics (must-have)
Leaf defaults
IsLeaf = trueChildren = empty- Add/Remove/Clear throw NotSupportedException
Composite defaults
IsLeaf = false- Maintains an internal child collection
Childrenreturns read-only view- Add/Remove/Clear are deterministic and validated
Validation rules
V1:
- Prevent null children.
- Optional
PreventCycles=trueis v2 unless cheap.
Traversal helpers
If enabled:
- DFS: pre-order
- BFS: FIFO
Diagnostics (must-have)
PKCMP001Type marked[CompositeComponent]must bepartial.PKCMP002Component type must be interface or abstract class.PKCMP003Name conflicts for generated base types.PKCMP004Contract contains unsupported members (events) for v1.
Generated Code Layout
ComponentName.Composite.g.csComponentName.Composite.Traversal.g.cs(optional)
Determinism:
- stable ordering by member name.
Testing Expectations
- Leaf base throws on Add/Remove/Clear.
- Composite base manages children correctly.
- Traversal ordering correct (if enabled).
- Diagnostics: invalid targets, naming conflicts.
Acceptance Criteria
- Generates component base + composite base for a contract.
- Leaf and composite semantics are deterministic and documented.
- Optional traversal helpers supported.
- Diagnostics and tests included.