Repository navigation
Support C# 15 unions in the remaining type declaration rules - #4193
Merged
Merged
Conversation
AArnott
force-pushed
the
csharp15-union-remaining
branch
from
October 9, 2026 13:56
1de14de to
ee5c0af
Compare
A union declaration is a struct type, but SA1642 expected union constructors to be documented as "Initializes a new instance of the <see cref="T"/> class", and the code fix inserted the class text. The code fix also had no case for unions in GetTypeParameterList: in Debug builds it failed an assertion, and in Release builds the cref for a generic union dropped its type parameters. SA1642 now expects the struct text for union constructors, and the code fix inserts it with the union's type parameters.
A union declaration is a TypeDeclarationSyntax, so it now appears in SyntaxKinds.BaseTypeDeclaration and SyntaxKinds.TypeDeclaration, the same way records do. Every rule that registers for those lists now also analyzes unions: - Layout: SA1500, SA1502, SA1505, SA1508, SA1516 - Readability (the union's case type list): SA1106, SA1110, SA1111, SA1112, SA1113, SA1114, SA1115, SA1116, SA1117, SA1137 - Ordering: SA1205 - Documentation: SA1604, SA1605, SA1606, SA1607, SA1608, SA1611, SA1612, SA1613, SA1614, SA1616, SA1618, SA1619, SA1620, SA1621, SA1622, SA1625, SA1629 The separate union registrations that #4191 added to SA1201, SA1202, SA1203, SA1400, SA1600 and SA1601 are removed, because the shared lists now cover them (keeping them would run those rules twice per union). Rules with their own lists of type declaration kinds now include unions too: SA1207, SA1214, SA1506, SA1514 and SA1648, plus the type kind checks in SA1137 (attribute lists of nested types) and SA1200 (a union in the global namespace suppresses the rule, like other types). SA1611 skips unions: the parameter list of a union declares its case types, which have no names to document. The SA1205 and SA1502 code fixes handle unions. All of these are syntax kind registrations, so code without unions does no extra work. The new C# 15 tests expect exactly one diagnostic per violation, with code fix tests where the rule has a fix. Closes #4182
AArnott
force-pushed
the
csharp15-union-remaining
branch
from
October 9, 2026 13:59
ee5c0af to
6f5c835
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4193 +/- ##
==========================================
+ Coverage 97.53% 97.54% +0.01%
==========================================
Files 1250 1277 +27
Lines 133401 134157 +756
Branches 4290 4291 +1
==========================================
+ Hits 130109 130863 +754
- Misses 2150 2152 +2
Partials 1142 1142 🚀 New features to boost your workflow:
|
AArnott
marked this pull request as ready for review
October 9, 2026 14:10
AArnott
marked this pull request as draft
October 9, 2026 14:26
Union constructors now expect and the code fix now inserts "Initializes a new instance of the <see cref="T"/> union." (and "Initializes static members of the ... union.") instead of the struct wording. Adds a TypeTextUnion resource to every DocumentationResources culture and documents the union form in SA1642.md.
AArnott
marked this pull request as ready for review
October 9, 2026 14:36
This was referenced Oct 9, 2026
This was referenced Nov 11, 2026
Bump StyleCop.Analyzers from 1.2.0-beta.556 to 1.3.180
microsoftgraph/aspnetcore-webhooks-sample#436
Open
This was referenced Nov 13, 2026
Open
Open
Merged
Open
Bump StyleCop.Analyzers from 1.2.0-beta.556 to 1.3.180
microsoftgraph/msgraph-sample-aspnet-core#256
Open
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #4192 (merged), which makes the C# 15 test project default to preview. This PR finishes union (
SyntaxKindEx.UnionDeclaration) support in the rules that still skipped unions.Closes #4182. Once this merges, every sub-issue of #4180 is closed, so #4180 can be closed too.
Approach
UnionDeclarationSyntaxis aTypeDeclarationSyntax, so I addedSyntaxKindEx.UnionDeclarationto the sharedSyntaxKinds.BaseTypeDeclarationandSyntaxKinds.TypeDeclarationlists, the same way records were added. Each of these is still a syntax-kind registration, so code without unions does no extra work.This differs from #4191, which added a separate union registration to each rule. With the shared lists, those per-rule lines in SA1201, SA1202, SA1203, SA1400, SA1600 and SA1601 would run each rule twice per union, so I removed them. Their existing union tests still pass, each with exactly one diagnostic. If you'd rather keep per-rule registrations, I can switch to that. It would mean about 25 extra registration lines.
Rules that now analyze unions
ElementDocumentationBase/ summary base classesRequested rules not in the table: SA1201–SA1204, SA1206, SA1300, SA1400, SA1402, SA1600, SA1601 and SA1649 were already done in #4188/#4191/#4096.
Adjustments
union Pet(Cat, Dog)), which have no names to document. Without this, the shared list would have reported each case type with an empty name.TestUnionCaseTypesAsynccovers it.UnionDeclarationSyntaxWrapper) and SA1502 (expands a single-line union body).SA1642 union constructors (5032740, 4ca6e40)
SA1642 and its code fix treated union constructors as class constructors. So on
master:Initializes a new instance of the <see cref="Pet"/> class.on union constructors.SA1642SA1643CodeFixProvider.GetTypeParameterListhad no union case. In Debug builds it hitDebug.Assert("Unhandled type UnionDeclaration"). In Release builds the cref for a generic union lost its type parameters (Resultinstead ofResult{T}).5032740 fixes the type parameter list. 4ca6e40 adds union wording, following the existing class/struct resources: a new
TypeTextUnionstring in everyDocumentationResourcesculture. Union constructors now expect, and the code fix inserts:Initializes a new instance of the <see cref="Result{T}"/> union.Initializes static members of the <see cref="Pet"/> union.The struct wording on a union constructor is now reported.
documentation/SA1642.mdhas a union example. SA1643 (destructors) has no type-kind text, and unions can't have destructors, so it needed no change.The translations are best effort: de "Union", fr/es/nl/en-GB "union", pt-BR "união", cs "sjednocení", pl "unii", ru "объединения". The French template is
de la {0}, so it produces "de la union" rather than "de l'union"; the Spanish template gives "de la union". Fixing the article would mean changing the shared template, which I left alone.Tests
There are new C# 15 tests for SA1106, SA1110, SA1111, SA1113–SA1117, SA1137 (2), SA1200, SA1205, SA1207, SA1214, SA1500, SA1502, SA1505, SA1506, SA1508, SA1514, SA1516, SA1604, SA1606, SA1611, SA1618, SA1620, SA1642 (5) and SA1648.
LanguageVersion.Preview.Local run (C# 15, net6.0, Linux): 9,593 tests. The only new failures are the 5 new code-fix tests that show the known Linux CRLF difference; Windows CI is authoritative for those.