feat: initial implementation of LayeredCraft.OptimizedEnums#1
Conversation
Introduces the full library: AOT-safe smart enum base classes, an incremental source generator (inheritance-based triggering, no attribute required), snapshot-tested generator suite, BenchmarkDotNet benchmarks, MkDocs documentation site, and GitHub Actions CI/CD workflows. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 461cf905c3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- EnumEmitter: use fully-qualified name (minus global::) as hint name to
prevent DuplicateHintNameException when two types share a class name
across different namespaces
- EnumSyntaxProvider: capture containing type chain via
GetContainingTypeDeclarations, stored as EquatableArray<string> on EnumInfo
- EnumEmitter: build preamble/suffix strings in C# instead of Scriban to
avoid whitespace control complexity; nested types now emit correct
partial class wrappers in the generated output
- Scriban template: replace namespace if-block with {{ preamble ~}} and
add {{ suffix }} for containing type closing braces
- Rename snapshots to reflect new namespace-qualified hint names
- Add NestedType and SameClassName_DifferentNamespaces snapshot tests
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ff6210893
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
… coverage - DiagnosticInfo.Equals/GetHashCode now include MessageArgs for correct incremental cache invalidation - Add OE9001 GeneratorInternalError descriptor; wrap template render+AddSource in try/catch - Replace C# 13 field keyword lazy prop with static readonly for thread safety in EnumEmitter - Use HashSet<string> in DetectDuplicateValues to avoid O(n) Contains on validMembers list - ReadOnlyCollection<T> via Array.AsReadOnly prevents cast-and-mutate of singleton collections - Dictionary initial capacity hints and public const Count (compile-time constant) in template - Add document Location exclusion comment in EnumInfo equality - Add OE0101 assert, OE0102 non-readonly field, and OE0005 duplicate value tests (12 total, all pass) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Initial implementation of LayeredCraft.OptimizedEnums: a runtime base type plus an incremental source generator that emits lookup tables/APIs for “smart-enum” style classes, along with tests, benchmarks, docs, and CI wiring.
Changes:
- Added runtime base classes (
OptimizedEnum<TEnum, TValue>+OptimizedEnum<TEnum>) targetingnetstandard2.0. - Added incremental source generator + Scriban template to emit cached collections and O(1) lookup APIs, with diagnostics.
- Added xUnit runtime tests, generator snapshot tests (Verify), BenchmarkDotNet benchmarks, and MkDocs-based documentation + GitHub Actions/Dependabot.
Reviewed changes
Copilot reviewed 68 out of 74 changed files in this pull request and generated 14 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/LayeredCraft.OptimizedEnums.Tests/xunit.runner.json | xUnit runner schema config for runtime tests |
| tests/LayeredCraft.OptimizedEnums.Tests/OrderStatusFixture.cs | Sample optimized-enum type used by runtime tests |
| tests/LayeredCraft.OptimizedEnums.Tests/OptimizedEnumTests.cs | Runtime tests validating generated APIs + base behavior |
| tests/LayeredCraft.OptimizedEnums.Tests/LayeredCraft.OptimizedEnums.Tests.csproj | Runtime test project wiring (mtp runner + generator as analyzer) |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/xunit.runner.json | xUnit runner schema config for generator tests |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/ModuleInitializer.cs | Verify.SourceGenerators initialization |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/LayeredCraft.OptimizedEnums.Generator.Tests.csproj | Generator test project wiring + reference assemblies |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/GeneratorVerifyTests.cs | Snapshot-style verification coverage for generator output/diagnostics |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/GeneratorTestHelpers.cs | Roslyn compilation/driver harness for generator tests |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.Warning_NonPrivateConstructor#MyApp.Domain.OrderStatus.g.verified.cs | Snapshot: generated output (warning scenario) |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.StringValueType#MyApp.Domain.Color.g.verified.cs | Snapshot: generated output for string value type |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.SimpleEnum_WithNamespace#MyApp.Domain.OrderStatus.g.verified.cs | Snapshot: generated output for namespaced enum |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.SimpleEnum_GlobalNamespace#Priority.g.verified.cs | Snapshot: generated output for global-namespace enum |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.SameClassName_DifferentNamespaces#MyApp.Domain2.Status.g.verified.cs | Snapshot: hint-name collision avoidance across namespaces |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.SameClassName_DifferentNamespaces#MyApp.Domain1.Status.g.verified.cs | Snapshot: hint-name collision avoidance across namespaces |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.NestedType#MyApp.Domain.Outer.Status.g.verified.cs | Snapshot: nested type generation behavior |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.MultipleMembers#MyApp.Domain.DayOfWeek.g.verified.cs | Snapshot: multiple member generation behavior |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.Error_NotPartial.verified.txt | Snapshot: OE0001 diagnostic output |
| tests/LayeredCraft.OptimizedEnums.Generator.Tests/Snapshots/GeneratorVerifyTests.Error_NoMembers.verified.txt | Snapshot: OE0004 diagnostic output |
| tests/LayeredCraft.OptimizedEnums.Benchmarks/Program.cs | BenchmarkDotNet entry point |
| tests/LayeredCraft.OptimizedEnums.Benchmarks/LayeredCraft.OptimizedEnums.Benchmarks.csproj | Benchmarks project wiring + generator as analyzer |
| tests/LayeredCraft.OptimizedEnums.Benchmarks/EnumLookupBenchmarks.cs | Benchmarks comparing generated lookups |
| tests/LayeredCraft.OptimizedEnums.Benchmarks/Directory.Build.props | Overrides test global-usings for benchmarks project |
| tests/Directory.Build.props | Global usings for test projects (Xunit, AwesomeAssertions) |
| src/LayeredCraft.OptimizedEnums/OptimizedEnum.cs | Runtime base classes + equality/compare/operators |
| src/LayeredCraft.OptimizedEnums/LayeredCraft.OptimizedEnums.csproj | Runtime project configuration (netstandard2.0) |
| src/LayeredCraft.OptimizedEnums.Generator/TrackingNames.cs | Tracking names for incremental pipeline |
| src/LayeredCraft.OptimizedEnums.Generator/Templates/OptimizedEnum.scriban | Scriban template for generated partial class |
| src/LayeredCraft.OptimizedEnums.Generator/Providers/EnumSyntaxProvider.cs | Discovery/validation of optimized-enum types + diagnostics |
| src/LayeredCraft.OptimizedEnums.Generator/OptimizedEnumGenerator.cs | Incremental generator setup + source output registration |
| src/LayeredCraft.OptimizedEnums.Generator/Models/LocationInfo.cs | Location model + helpers for diagnostic reporting |
| src/LayeredCraft.OptimizedEnums.Generator/Models/EquatableArray.cs | Structural-equality array wrapper for incremental caching |
| src/LayeredCraft.OptimizedEnums.Generator/Models/EnumInfo.cs | Immutable model driving emission (members/types/diagnostics) |
| src/LayeredCraft.OptimizedEnums.Generator/LayeredCraft.OptimizedEnums.Generator.csproj | Generator packaging + analyzer/runtime bundling |
| src/LayeredCraft.OptimizedEnums.Generator/Emitters/TemplateHelper.cs | Embedded template loading/caching + rendering |
| src/LayeredCraft.OptimizedEnums.Generator/Emitters/EnumEmitter.cs | Model creation + AddSource hint naming |
| src/LayeredCraft.OptimizedEnums.Generator/Diagnostics/DiagnosticInfo.cs | Diagnostic model + reporting helpers |
| src/LayeredCraft.OptimizedEnums.Generator/Diagnostics/DiagnosticDescriptors.cs | OE* diagnostic descriptor definitions |
| src/LayeredCraft.OptimizedEnums.Generator/AnalyzerReleases.Unshipped.md | Roslyn analyzer release tracking (unshipped rules) |
| src/LayeredCraft.OptimizedEnums.Generator/AnalyzerReleases.Shipped.md | Roslyn analyzer release tracking (shipped rules) |
| requirements.txt | Python deps for MkDocs site |
| mkdocs.yml | MkDocs Material site configuration |
| layeredcraft-optimized-enums-spec.md | Implementation/spec document for the project |
| global.json | SDK pinning + MTP runner config |
| docs/index.md | Docs homepage content |
| docs/getting-started/installation.md | Installation guide for consumers |
| docs/getting-started/quick-start.md | Quick start guide for consumers |
| docs/core-concepts/how-it-works.md | Explains generator approach + sample generated code |
| docs/core-concepts/source-generators.md | Explains incremental generator trigger/pipeline |
| docs/core-concepts/inheritance-model.md | Explains base types + inheritance triggering model |
| docs/usage/defining-enums.md | Usage guide for defining optimized enums |
| docs/usage/lookups.md | Usage guide for lookup/query APIs |
| docs/usage/string-values.md | Usage guide for non-int value types (e.g., string) |
| docs/api-reference/base-class.md | API reference for runtime base classes |
| docs/api-reference/generated-members.md | API reference for generator-emitted members |
| docs/advanced/performance.md | Benchmark results + perf explanation |
| docs/advanced/diagnostics.md | Diagnostic codes and troubleshooting info |
| docs/advanced/aot-trimming.md | AOT/trimming guidance |
| docs/contributing.md | Contributor documentation |
| docs/changelog.md | Changelog for the project |
| docs/assets/css/extra.css | MkDocs site custom styling |
| README.md | Repository/package overview and usage summary |
| LayeredCraft.OptimizedEnums.slnx | Solution structure including docs/tests projects |
| Directory.Packages.props | Central package version management |
| Directory.Build.props | Shared build/package metadata configuration |
| .idea/.idea.LayeredCraft.OptimizedEnums/.idea/encodings.xml | Rider IDE metadata (currently committed) |
| .idea/.idea.LayeredCraft.OptimizedEnums/.idea/.gitignore | Rider IDE metadata ignore list (currently committed) |
| .gitignore | Added ignores for IDE/config/script artifacts |
| .github/workflows/build.yaml | Build/package workflow |
| .github/workflows/pr-build.yaml | PR validation workflow |
| .github/workflows/docs.yml | MkDocs build + GitHub Pages deploy workflow |
| .github/dependabot.yml | Dependabot configuration |
Files not reviewed (2)
- .idea/.idea.LayeredCraft.OptimizedEnums/.idea/.gitignore: Language not supported
- .idea/.idea.LayeredCraft.OptimizedEnums/.idea/encodings.xml: Language not supported
Comments suppressed due to low confidence (1)
.idea/.idea.LayeredCraft.OptimizedEnums/.idea/.gitignore:16
- This repository is now set up to ignore
.idea/via the root.gitignore, so committing.ideametadata (like this file) will keep IDE-specific state in source control unnecessarily. Consider deleting the committed.ideadirectory contents and relying on the ignore rule instead.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…icate scan, use value equality for duplicate detection - GetContainingTypeDeclarations now includes type parameters (MinimallyQualifiedFormat) and static modifier so generated partial wrappers compile for generic/static outer types - DetectDuplicateValues now iterates all DeclaringSyntaxReferences instead of a single classDecl so members declared in other partial files are included in duplicate-value checks - Switch duplicate-value dictionary key from .ToString() to raw object so value-type equality (e.g. decimal 1.0m == 1.00m) is used rather than string representation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
Introduces the complete
LayeredCraft.OptimizedEnumslibrary — an AOT-safe, trim-friendly alternative to reflection-based smart enum patterns. The generator triggers on inheritance fromOptimizedEnum<TEnum, TValue>(or theint-defaultingOptimizedEnum<TEnum>convenience class) rather than requiring an attribute, eliminating boilerplate and false positives on unrelated classes.Changes
Runtime (
src/LayeredCraft.OptimizedEnums)OptimizedEnum<TEnum, TValue>— abstract base class withIEquatable<TEnum>,IComparable<TEnum>, value/name properties, operatorsOptimizedEnum<TEnum>— single-parameter convenience class that fixesTValue = intSource Generator (
src/LayeredCraft.OptimizedEnums.Generator)IIncrementalGeneratorusingCreateSyntaxProvider— inheritance-based triggering, no attribute neededTransformto avoid false diagnostics on unrelated typesAll,Names,Values,Count,FromName,TryFromName,FromValue,TryFromValue,ContainsName,ContainsValueMicrosoft.CSharp.dllbundled inanalyzers/dotnet/cs/viaGetDependencyTargetPathsMSBuild target so Scriban dynamic dispatch works in consuming packagesTests
Enum.Parse/Enum.TryParseDocs & CI
docs/,mkdocs.yml,requirements.txt)build.yaml(push/tag),pr-build.yaml(PR validation),docs.yml(GitHub Pages deploy)Validation
Microsoft.CSharp.dllbundling fix)Enumeration, domain events) confirmed resolvedRelease Notes
Initial pre-release of
LayeredCraft.OptimizedEnums. Inherit fromOptimizedEnum<TEnum>(int-valued) orOptimizedEnum<TEnum, TValue>(custom value type) and the source generator emits O(1) lookup tables, collection properties, and factory methods — all AOT- and trim-safe with no reflection at runtime.