Skip to content

feat(analyzers): add union rule family E128219-E128221 - #158

Merged
e128 merged 1 commit into
mainfrom
feature/union-rule
Nov 12, 2026
Merged

e128 merged 1 commit into
mainfrom
feature/union-rule

Conversation

@e128

@e128 e128 commented Nov 12, 2026

Copy link
Copy Markdown
Owner

Executive Summary

Adds three union-aware design rules to the E128.Analyzers package, written against the typed UnionDeclarationSyntax. The typed node sits behind RSEXPERIMENTAL006 at the pinned Roslyn 5.9.0 band; the maintainer approved that suppression, which both component csproj files now carry.

  • E128219 Memberless internal abstract base whose derivation stays in one assembly: the shape a closed hierarchy replaces. Code fix replaces the abstract modifier with the closed keyword and keeps trivia. Skips a base that already carries closed (closed alone implies abstract, per CS0144 probe).
  • E128220 Union switch ending in a discard or var arm instead of a null arm. Code fix replaces a discard pattern with a null constant pattern; a var arm binds a value, so the fixer skips it. Probe finding: case _ on a union governing type parses _ as a case-type identifier (CS0103), so a statement catch-all is case var _:.
  • E128221 Union Value read or cast outside a pattern match. No code fix, because the conversion changes control flow.

Shared helper UnionTypes.IsUnion accepts a source union through UnionDeclarationSyntax or a binary/hand-written union through the compiler-synthesized IUnion interface, matched by name and namespace chain because no metadata lookup resolves it.

Code Changes

  • src/E128.Analyzers/Design/: three new analyzers plus UnionTypes.cs
  • src/E128.Analyzers.CodeFixers/Design/: two new code fix providers
  • Release files: rows promoted to AnalyzerReleases.Shipped.md under 2.10.0, PublicAPI.Unshipped.txt entries, README rule rows and sections
  • csproj: RSEXPERIMENTAL006 NoWarn additions, version 2.9.8 to 2.10.0, README install snippet updated

Tests and Tooling

  • 24 new tests across five files, plus UnionTestRuntime, a source stub for UnionAttribute, IsClosedTypeAttribute, and IUnion, because the net10.0 reference assemblies predate the union runtime. Fixture settings: LanguageVersion.Preview and an RSEXPERIMENTAL006 suppression.
  • Full gate (scripts/check.sh) green: format, build, and the full suite, 2928 passed with 2 pre-existing skips. Test gate ran on the union sources before the commit; the docs-only and release-file follow-up edits did not rerun the suite.
  • analyzer-release-check, readme-table-diff --analyzer, and readme-audit all clean after promotion.

Review Guide

Start with UnionTypes.cs for the detection contract, then each analyzer. The two-pass compilation-end shape of E128219 mirrors SealedByDefaultAnalyzer (E128005). Code fix tests for the compilation-end rule set SkipLocalDiagnosticCheck and NumberOfFixAllIterations = 1, the shape lode/dotnet/analyzers/testing.md records.

Rollback

Revert this single commit; the change set is self-contained to the analyzer package, its tests, and the release/README files.

🤖 Generated with Claude Code

@e128
e128 merged commit 17dddfd into main Nov 12, 2026
2 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.

1 participant