-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
enhancementNew feature or requestNew feature or request
Description
Generator: Create Bridge Pattern
Summary
Add a source generator that produces boilerplate-free, GoF-consistent Bridge pattern scaffolding, separating an abstraction from its implementation with explicit contracts and generated forwarding.
The generator lives in PatternKit.Generators and emits self-contained C# with no runtime PatternKit dependency.
Primary goals:
- Generate the “abstraction” and “implementor” wiring consistently.
- Avoid hand-written forwarding drift.
- Support interface- or abstract-class based implementors.
- Support sync + async members (preserve signatures).
Motivation / Problem
Bridge implementations often repeat:
- Abstraction storing implementor reference
- Forwarding members
- Optional refined abstractions
- Naming collisions and inconsistent wiring
Generator can emit the canonical scaffolding once, consistently.
Supported Targets (must-have)
Bridge generation must support:
- implementor contract:
interfaceorabstract class - abstraction host:
partial class/partial record class(struct support optional; v1 can support struct if desired)
V1 scope can focus on:
- generating an abstraction base type that forwards to implementor
- optional generation of a default abstraction implementation
Proposed User Experience
A) Annotate implementor contract, generate abstraction base
[BridgeImplementor]
public partial interface IRenderer
{
void DrawLine(int x1, int y1, int x2, int y2);
ValueTask FlushAsync(CancellationToken ct = default);
}
[BridgeAbstraction(typeof(IRenderer))]
public partial class Shape
{
// user adds domain methods and calls into generated forwarding
}Generated (representative shape):
public abstract partial class Shape
{
protected Shape(IRenderer implementor);
protected IRenderer Implementor { get; }
protected void DrawLine(int x1, int y1, int x2, int y2)
=> Implementor.DrawLine(x1, y1, x2, y2);
protected ValueTask FlushAsync(CancellationToken ct = default)
=> Implementor.FlushAsync(ct);
}B) Generate a default refined abstraction (optional)
[BridgeAbstraction(typeof(IRenderer), GenerateDefault = true, DefaultTypeName = "DefaultShape")]
public partial class Shape { }Generated:
DefaultShape : Shapewith minimal constructor.
Attributes / Surface Area
Namespace: PatternKit.Generators.Bridge
Core
-
[BridgeImplementor]on implementor contractstring? ImplementorTypeName(optional; mostly marker)
-
[BridgeAbstraction(Type implementorType)]on abstraction hoststring ImplementorPropertyName = "Implementor"bool GenerateDefault(default: false)string? DefaultTypeName(default:<AbstractionName>Default)
Optional:
[BridgeIgnore]for implementor members to exclude from generated forwarding.
Semantics (must-have)
Forwarding
- Generated protected forwarding methods for each implementor member.
- Preserve signatures (no rewriting).
- For interface implementors, forward all members.
- For abstract class implementors, forward only virtual/abstract members (v1).
Construction
- Abstraction must store implementor reference.
- Generated constructor should be
protected. - Null checking: throw
ArgumentNullException.
Async
- Preserve implementor async signatures.
- Do not rewrite Task/ValueTask; just forward.
Diagnostics (must-have)
PKBRG001Type marked[BridgeAbstraction]must bepartial.PKBRG002Implementor type must be interface or abstract class.PKBRG003Implementor member unsupported for forwarding (events v1).PKBRG004Name conflicts for generated default type.PKBRG005Inaccessible implementor members for forwarding.
Generated Code Layout
AbstractionName.Bridge.g.csAbstractionName.Bridge.Default.g.cs(optional)
Determinism:
- stable ordering by member name.
Testing Expectations
- Implementor calls are forwarded correctly.
- Null implementor throws.
- Diagnostics: invalid implementor type, name conflicts.
- Async forwarding works.
Acceptance Criteria
- Generates abstraction wiring and forwarding for implementor contract.
- Works with interface and abstract class implementors.
- Preserves signatures (sync and async).
- Optional default refined abstraction generation.
- Diagnostics and tests included.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request