Skip to content

Fix source generator evolver and hint-name failures#359

Merged
jeremydmiller merged 2 commits into
JasperFx:mainfrom
erdtsieck:feature/4542-required-members-source-generator
May 23, 2026
Merged

Fix source generator evolver and hint-name failures#359
jeremydmiller merged 2 commits into
JasperFx:mainfrom
erdtsieck:feature/4542-required-members-source-generator

Conversation

@erdtsieck
Copy link
Copy Markdown
Contributor

@erdtsieck erdtsieck commented May 22, 2026

What changed

  • Treat a generated partial projection as covering its aggregate type so the snapshot-registration pipeline does not emit a second standalone evolver for the same aggregate.
  • Reuse the aggregate constructor helper for generated Evolve/EvolveAsync fallback paths.
  • Avoid emitting required-member object initializers for aggregate types without a public parameterless constructor.
  • Normalize aggregate types discovered from snapshot/ref-aggregate call sites so nullable reference annotations do not leak into generated evolvers.
  • Sanitize source-generator hint names before calling AddSource() so Roslyn-invalid characters such as ? cannot crash generation.
  • Add regression tests for required-member primary-constructor aggregates with conventional projection Create/Apply methods and nullable [ReadAggregate] aggregate parameters discovered via IRefersToAggregate attributes.

Why

Two source-generator paths could break Marten 9 upgrade scenarios:

  • A partial projection could generate the correct dispatcher while a later source-generator pipeline also emitted a fallback evolver for the same aggregate. That fallback did not know about the projection Create method and could generate construction code that fails for aggregates using required members and primary constructors.
  • Aggregate types discovered from nullable parameters such as [ReadAggregate] EigenPrestatie? prestatie could feed ? into generated hint names, causing Roslyn to reject AddSource() and abort the whole generator pass.

Addresses JasperFx/marten#4542 and JasperFx/marten#4543.

Validation

  • dotnet test .\src\JasperFx.Events.SourceGenerator.Tests\JasperFx.Events.SourceGenerator.Tests.csproj --no-restore

@erdtsieck erdtsieck marked this pull request as ready for review May 22, 2026 06:27
@erdtsieck erdtsieck changed the title Fix duplicate source generator evolvers for partial projections Fix source generator evolver and hint-name failures May 22, 2026
@erdtsieck erdtsieck marked this pull request as draft May 22, 2026 06:48
@erdtsieck erdtsieck marked this pull request as ready for review May 22, 2026 14:01
@jeremydmiller
Copy link
Copy Markdown
Member

Verified this locally and it's the complete fix for marten#4542 (+ marten#4543). 👍

Two small things I'd double-check before merge (both look fine on read):

  1. MarkSeen only suppresses the standalone evolver when Mode == PartialProjection && Methods.Count > 0 — so a Snapshot<T> with no covering partial projection still gets its evolver. ✅
  2. The default! guard now keys off TypeKind.Struct || InstanceConstructors.Any(public parameterless).

Happy to push my 3 construction-focused tests onto this branch if you'd like the extra coverage.

@jeremydmiller jeremydmiller merged commit 170a77c into JasperFx:main May 23, 2026
1 check passed
jeremydmiller added a commit that referenced this pull request May 23, 2026
Ships the source-generator required-member/duplicate-evolver/hint-name fixes
(#359, marten#4542 + marten#4543) and the new store-agnostic dead-letter count
read on IEventDatabase (#363, #356).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants