Skip to content

Enable nullable in every generated file's header [patch] - #57

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/55-nullable-enable-generated-header
Oct 30, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/55-nullable-enable-generated-header

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #55

What changed

Roslyn compiles any file that carries the // <auto-generated /> marker with the nullable context disabled, whatever <Nullable> the consuming project sets. WriteFileHeader wrote no #nullable directive, and WriteSourceFile writes the header and body in one call, so callers couldn't add one themselves. As a result:

  • every string? in the output raised CS8669, which is an error under TreatWarningsAsErrors
  • every unannotated reference member was null-oblivious to consumers

WriteFileHeader now writes #nullable enable straight after the marker, and WriteSourceFile inherits it. The remarks on WriteFileHeader and the README API table say why.

A generator that already writes its own #nullable enable after the header now emits the directive twice. That is legal C# and changes nothing.

Tests

  • TheHeaderEnablesNullableAfterTheGeneratedMarker: the header contains // <auto-generated />\n#nullable enable\n.
  • AnnotatedGeneratedMembersCompileWithoutCS8669: compiles WriteSourceFile output that holds a string? field next to a consumer under NullableContextOptions.Enable, and asserts there is no CS8669.
  • UnannotatedGeneratedMembersAreNotNullOblivious: assigning null to the generated string field raises CS8625.
  • AMultiLineCopyrightIsCommentedOnEveryLine now expects the directive in its exact-output check.

With the one-line fix reverted, 6 tests fail (the 3 new ones and the 3 DataRows of the exact-header test). With it applied, all 63 pass on net10.0.

Note

Open PR #56 (copyright splitting) also edits WriteFileHeader, so whichever lands second may need a small rebase.


Generated by Claude Code

Roslyn compiles a file carrying the <auto-generated /> marker with the
nullable context disabled, whatever the consuming project sets. Without a
directive, every string? in WriteSourceFile output raised CS8669 and every
unannotated member was null-oblivious to consumers. WriteFileHeader now
writes #nullable enable after the marker, so WriteSourceFile inherits it.

Fixes #55

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW3EdFmyBthXBAkdCiZ
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017vfJW3EdFmyBthXBAkdCiZ
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit e4f9c90 into main Oct 30, 2026
15 checks passed
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.

Code written by WriteSourceFile has nullable disabled: every string? it emits raises CS8669, and non-annotated members are null-oblivious to consumers

2 participants