-
Notifications
You must be signed in to change notification settings - Fork 0
Add Memento pattern source generator for classes, structs, and records #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Created MementoAttribute with configuration options - Implemented MementoGenerator for class/struct/record class/record struct - Generated immutable memento structs with Capture and RestoreNew methods - Generated optional caretaker classes for undo/redo history - Added diagnostic support (PKMEM001-PKMEM006) - All 13 generator tests passing Co-authored-by: JerrettDavis <2610199+JerrettDavis@users.noreply.github.com>
- Created EditorStateDemo showing text editor with undo/redo - Created GameStateDemo showing game state save/load - Added comprehensive README with usage examples - Moved MementoAttribute to Abstractions project for accessibility - Fixed generator to skip computed/read-only properties - All 13 generator tests passing Co-authored-by: JerrettDavis <2610199+JerrettDavis@users.noreply.github.com>
- Added null checks for FirstOrDefault in test assertions - Fixed potential NullReferenceException in generated source access - All 13 Memento tests passing Co-authored-by: JerrettDavis <2610199+JerrettDavis@users.noreply.github.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
Test Results0 tests 0 ✅ 0s ⏱️ Results for commit bb0a281. |
🔍 PR Validation ResultsVersion: `` ✅ Validation Steps
📊 ArtifactsDry-run artifacts have been uploaded and will be available for 7 days. This comment was automatically generated by the PR validation workflow. |
Code Coverage |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #88 +/- ##
==========================================
+ Coverage 86.81% 89.73% +2.91%
==========================================
Files 139 143 +4
Lines 11295 11867 +572
Branches 1548 1610 +62
==========================================
+ Hits 9806 10649 +843
- Misses 1101 1218 +117
+ Partials 388 0 -388
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Implements a compile-time source generator that produces complete Memento pattern implementations for classes, structs, record classes, and record structs with optional undo/redo caretaker.
Generated Components
Capture(in TOriginator)andRestoreNew()methodsConfiguration
Type Support
RestoreNew()returning new instancesRestore(originator)(in-place) andRestoreNew()Member Selection
Usage Example
Implementation Details
Demos
EditorStateDemo: Text editor with undo/redo using record classGameStateDemo: Game state save/load with mutable class and in-place restoreOriginal prompt
This section details on the original issue you should resolve
<issue_title>Generator: Create Memento Pattern (supports class/struct/record + optional undo/redo caretaker)</issue_title>
<issue_description>## Summary
Add a source generator that produces a complete implementation of the Memento pattern for consumer types — including classes, structs, record classes, and record structs — focused on:
Motivation / Problem
Memento implementations are repetitive and correctness-sensitive:
This is ideal for source generation: emit correct, optimized code once, consistently.
Supported Originator Kinds (must-have)
The generator must support:
classstructrecord classrecord structEach kind has different restore semantics:
Mutable originators (class/struct with settable members)
Immutable originators (records with
initor positional parameters)restore should support returning a new instance:
RestoreNew(...)orApply(...)optionally support
with-expression restore when feasible:with { ... }for the included membersWe should not force mutation on records that are designed to be immutable.
Proposed User Experience
Minimal: snapshot only
Generated (shape):
Snapshot + caretaker (undo/redo)
Generated:
Notes
Member Selection
Support both modes:
Include-all (default, configurable)
Include-explicit
[MementoInclude]Attributes:
[Memento][MementoIgnore][MementoInclude]Capture Strategies for Mutable References (footgun prevention)
Default strategy should be explicit and safe:
stringtreated as safe immutableByReferencewith a warning unless configured otherwisePer-member strategy attribute:
Strategies:
ByReferenceClone(requires a known mechanism)DeepCopy(only when generator can safely emit it)Serialize(opt-in, future)Custom(partial hook)Restore Semantics (by originator type)
For class / struct (mutable)
Generate both:
void Restore(TOriginator originator)(in-place)TOriginator RestoreNew()(convenience)For record class / record struct
Generate:
TOriginator RestoreNew()(always)Apply(TOriginator originator)only if the record has writable members (rare / discouraged)Additionally:
if feasible, prefer
with-expression:originator with { Prop = value, ... }otherwise, use the best available constructor/positional parameters:
The generator must emit diagnostics if it cannot safely construct a new record instance.
Caretaker Generation (Undo/Redo)
Caretaker should be optional and support dete...
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.