Skip to content

Emit attributes into the consuming compilation - #8

Merged
NoahStolk merged 1 commit into
mainfrom
fix/analyzer-only-package
Aug 8, 2026
Merged

Emit attributes into the consuming compilation#8
NoahStolk merged 1 commit into
mainfrom
fix/analyzer-only-package

Conversation

@NoahStolk

Copy link
Copy Markdown
Owner

Fixes #1.

The problem

EnumGenerator.Package set DevelopmentDependency=true while also shipping EnumGenerator.Attributes.dll in lib/netstandard2.0. NuGet writes this on install for a development dependency:

<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

Note the absent compile. The attributes assembly was therefore invisible to consumers, who had to hand-add compile after every install. The package was claiming "nothing to reference" while shipping something to reference.

The fix

Rather than push consumers toward including the compile asset (which is what the issue title suggests), this removes the need for it entirely — the package becomes a genuine development dependency.

AttributeSourceUtils now holds the attribute source, which EnumIncrementalGenerator emits via RegisterPostInitializationOutput. Post-initialization is mandatory here: both providers resolve [GenerateEnumUtilities] through the semantic model, and only post-initialization sources are visible to it during the generator run. Moving this to RegisterSourceOutput would silently break all detection.

The EnumGenerator.Attributes project is deleted. The package now contains nothing but the generator:

analyzers/dotnet/cs/EnumGenerator.dll
README.md

No lib/ folder, no assembly to reference, no runtime dependency, and the default PackageReference needs no editing.

Two packaging bugs found while verifying are fixed alongside:

  • lib/netstandard2.0/EnumGenerator.Package.dll — the packaging project's own empty assembly was leaking into the package (IncludeBuildOutput=false).
  • The empty netstandard2.0 dependency group tripped NU5128 once lib/ was gone (SuppressDependenciesWhenPacking=true).

Verification

EnumGenerator.Tests.NuGetIntegration now declares the exact metadata dotnet add package writes, instead of the hand-patched version with compile bolted on. It is the regression test for this issue — if it stops compiling, the package layout is wrong, not the test.

  • Snapshot tests: 28/28. The 27 pre-existing snapshots are unchanged, confirming generated output is unaffected; the new one covers the emitted attributes.
  • In-solution integration tests: 13/13.
  • NuGet integration tests (packed nuget, default IncludeAssets): 13/13.
  • EnumGenerator.Sample runs correctly.

Breaking change

The attributes go from public in a referenced assembly to internal in each compilation. This only matters for code that reflects over GenerateEnumUtilitiesAttribute at runtime or re-exposes it across assembly boundaries — unlikely, since the attribute only drives generation. Version bumped to 0.6.0 accordingly.

No new constraint on consumers: the generic GenerateEnumUtilitiesAttribute<T> needs C# 11, which the README already requires for UTF-8 literals and Enum.GetValues<T>().

🤖 Generated with Claude Code

The package set DevelopmentDependency=true while also shipping
EnumGenerator.Attributes.dll in lib/netstandard2.0. NuGet writes
"runtime; build; native; contentfiles; analyzers; buildtransitive" for a
development dependency -- note the absent "compile" -- so the attributes
assembly was invisible to consumers, who had to hand-edit IncludeAssets
after every install.

Resolve the contradiction in favour of the package genuinely being a
development dependency: AttributeSourceUtils now holds the attribute
source, which EnumIncrementalGenerator emits via
RegisterPostInitializationOutput. Post-initialization is mandatory here,
since both providers resolve [GenerateEnumUtilities] through the semantic
model, which only sees post-initialization sources during the run.

The EnumGenerator.Attributes project is gone, and the package now
contains nothing but the generator in analyzers/dotnet/cs. Consumers get
no lib/ folder, no assembly to reference, and no runtime dependency.

Also fixes two packaging bugs found along the way: the packaging
project's own empty assembly was leaking into lib/ (IncludeBuildOutput),
and the empty dependency group tripped NU5128 once lib/ was removed
(SuppressDependenciesWhenPacking).

EnumGenerator.Tests.NuGetIntegration now declares the exact metadata
`dotnet add package` writes rather than the hand-patched version, so it
regression-tests a default install.

The attributes change from public in a referenced assembly to internal in
each compilation, hence the minor version bump to 0.6.0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@NoahStolk
NoahStolk merged commit ee88bbd into main Aug 8, 2026
1 check passed
@NoahStolk
NoahStolk deleted the fix/analyzer-only-package branch August 8, 2026 10:01
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.

Make sure "compile" assets are included by default on install

1 participant