Skip to content

AOT/trim compatibility: source-generated trigger registry, sample publishing, multi-machine tests, and compatibility docs#28

Merged
leeoades merged 6 commits intomainfrom
copilot/make-libraries-aot-and-trimmed
Feb 23, 2026
Merged

AOT/trim compatibility: source-generated trigger registry, sample publishing, multi-machine tests, and compatibility docs#28
leeoades merged 6 commits intomainfrom
copilot/make-libraries-aot-and-trimmed

Conversation

Copy link
Contributor

Copilot AI commented Feb 22, 2026

  • Add FunctionalStateMachine.Core.Generator as analyzer reference to StockPurchaserSampleApp.csproj, VendingMachineSampleApp.csproj, and FunctionalStateMachine.Samples.csproj
  • Fix PublishTrimmed=true propagation to netstandard2.0 builds
  • Add <PublishTrimmed>true</PublishTrimmed> to both executable sample csproj files
  • Tests for multiple machines sharing same trigger (registry once, both fire, independent, subset triggers)
  • Tests for hierarchical state machines with trigger registry
  • Create docs/Target-Framework-Compatibility.md
  • Create docs/AOT-and-Trim-Compatibility.md — updated to remove project-reference-specific sections (confusing to NuGet consumers); simplified "Enabling publishing" section to just say the generator is bundled in the NuGet package automatically
  • Update docs/index.md and README.md with links to new pages
  • All 180 tests pass, 0 warnings

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Make libraries AOT and trimmed for better consumption feat: AOT and trim compatibility for Core and CommandRunner libraries Feb 22, 2026
Copilot AI requested a review from leeoades February 22, 2026 09:56
Copilot AI changed the title feat: AOT and trim compatibility for Core and CommandRunner libraries feat: replace reflection-based trigger discovery with source-generated registry Feb 22, 2026
Copilot AI changed the title feat: replace reflection-based trigger discovery with source-generated registry AOT/trim compatibility: source-generated trigger registry, sample publishing, and multi-machine tests Feb 23, 2026
@leeoades
Copy link
Owner

@copilot - is there a test for where the same trigger is used on 2 different statemachines and one or both of them aren't using all of the triggers? Remind me why we were reflecting over all triggers in the first place?
Have you updated the docs? Please add a new page talking about compatibility with .netstandard2.0 and .net8. Also add a different page explaining about AoT and trimming compatibility / readiness.
Add a brief mention in the main README that links off to the more detailed pages. These are advanced features so we shouldn't over complicate the main README.

Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot - is there a test for where the same trigger is used on 2 different statemachines and one or both of them aren't using all of the triggers? Remind me why we were reflecting over all triggers ...

Added in commit 0515181.

Test for two machines sharing a trigger, each using only a subset:
MultipleMachines_SameTrigger_EachUsesSubsetOfTriggers_BothBuildSuccessfullymachineAlpha only wires up TriggerA (TriggerB unused), machineBeta only wires up TriggerB (TriggerA unused). Both build successfully — the unused-trigger analysis is per-machine and emits warnings (not errors), so an unused trigger in one machine never blocks the other.

Why were we reflecting?
The unused-trigger analysis needed to know all concrete trigger subtypes defined in the assembly, so it could compare that set against the triggers actually registered in transitions. The original approach used Assembly.GetTypes() (to enumerate all assembly types) and Type.GetProperty("EqualityContract", NonPublic) (to detect C# record types). These are the two reflection APIs that break under trimming and NativeAOT. The source generator replaces both: at compile time, Roslyn already knows the full type graph, so we can emit a [ModuleInitializer] that populates the registry before any user code runs — zero runtime reflection.

Docs added:

  • docs/Target-Framework-Compatibility.md — netstandard2.0 vs net8.0, feature comparison, generator behaviour per TFM
  • docs/AOT-and-Trim-Compatibility.md — NativeAOT/trim status, how the source generator eliminates reflection, enabling trimmed publishing
  • Both pages linked from docs/index.md (new "Advanced" section) and from a new "Advanced Topics" section in the README

Copilot AI changed the title AOT/trim compatibility: source-generated trigger registry, sample publishing, and multi-machine tests AOT/trim compatibility: source-generated trigger registry, sample publishing, multi-machine tests, and compatibility docs Feb 23, 2026
@leeoades
Copy link
Owner

@copilot - please rebase on main and resolve conflicts

Copy link
Contributor Author

Copilot AI commented Feb 23, 2026

@copilot - please rebase on main and resolve conflicts

I'm not able to perform a rebase — my environment doesn't allow force-push, which a rebase would require. You'll need to do one of the following from your local machine:

git fetch origin
git checkout copilot/make-libraries-aot-and-trimmed
git rebase origin/main
# resolve any conflicts, then:
git push --force-with-lease origin copilot/make-libraries-aot-and-trimmed

Or alternatively, merge main into the branch:

git fetch origin
git checkout copilot/make-libraries-aot-and-trimmed
git merge origin/main
git push origin copilot/make-libraries-aot-and-trimmed

Once the branch is up to date I can continue working on it.

Copilot AI and others added 5 commits February 23, 2026 09:39
Co-authored-by: leeoades <2321091+leeoades@users.noreply.github.com>
…d trigger type registry

Co-authored-by: leeoades <2321091+leeoades@users.noreply.github.com>
…ore.Generator added to samples

Co-authored-by: leeoades <2321091+leeoades@users.noreply.github.com>
Co-authored-by: leeoades <2321091+leeoades@users.noreply.github.com>
@leeoades leeoades force-pushed the copilot/make-libraries-aot-and-trimmed branch from 0515181 to 5fc2462 Compare February 23, 2026 09:39

<ItemGroup>
<ProjectReference Include="..\..\..\src\FunctionalStateMachine.Core\FunctionalStateMachine.Core.csproj" />
<ProjectReference Include="..\..\..\src\FunctionalStateMachine.Core.Generator\FunctionalStateMachine.Core.Generator.csproj"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot - how does someone consuming the package from Nuget do this? Does the consumer need to reference the core package and add the generator package as a reference or can we make referencing the main package sufficient?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referencing FunctionalStateMachine.Core from NuGet is sufficient — no separate generator package needed. The generator DLL is bundled inside the Core NuGet package at analyzers/dotnet/cs, which NuGet automatically applies as an analyzer.

The explicit Core.Generator project reference in the sample apps is only necessary because they use project references (not NuGet packages). That's the exact equivalent of what NuGet does automatically for package consumers.

</Project>
```

Reference the source generator so the trigger registry is populated at startup:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot - I don't think we need to mention this in the docs. It's confusing. Everyone will be consuming the nuget package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in commit 43ffdf0 — the project-reference snippet and "Trim propagation to analyzer projects" section are both gone. The "Enabling publishing" section now simply states the generator is bundled in the NuGet package and applied automatically.

…rence-specific sections

Co-authored-by: leeoades <2321091+leeoades@users.noreply.github.com>
Copilot AI requested a review from leeoades February 23, 2026 09:44
@leeoades leeoades marked this pull request as ready for review February 23, 2026 09:48
@leeoades leeoades merged commit cebe914 into main Feb 23, 2026
3 checks passed
@leeoades leeoades deleted the copilot/make-libraries-aot-and-trimmed branch February 23, 2026 09:48
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