Skip to content

Commit d06074d

Browse files
committed
Update SA1015 for nullable reference types
1 parent d99b446 commit d06074d

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/SpacingRules/SA1015CSharp8UnitTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,61 @@ public struct Foo<T>
3535

3636
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
3737
}
38+
39+
/// <summary>
40+
/// Verifies that nullable reference type annotations following closing generic brackets do not produce diagnostics.
41+
/// </summary>
42+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
43+
[Fact]
44+
[WorkItem(3006, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3006")]
45+
public async Task TestNullableReferenceTypeAnnotationsAsync()
46+
{
47+
const string testCode = @"#nullable enable
48+
using System.Collections.Generic;
49+
50+
public class TestClass
51+
{
52+
private List<string?>? names;
53+
private Dictionary<string, List<object?>?>? items;
54+
55+
public IReadOnlyList<List<string?>?>? Property { get; }
56+
57+
public void TestMethod()
58+
{
59+
List<(string? key, List<string?>? values)>? local = null;
60+
List<string?>?[]? jagged = null;
61+
}
62+
}
63+
";
64+
65+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
66+
}
67+
68+
/// <summary>
69+
/// Verifies that nullable reference type constraints involving generic types are handled without diagnostics.
70+
/// </summary>
71+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
72+
[Fact]
73+
[WorkItem(3006, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3006")]
74+
public async Task TestNullableReferenceTypeConstraintsAsync()
75+
{
76+
const string testCode = @"#nullable enable
77+
using System.Collections.Generic;
78+
79+
public class ConstraintClass<T> where T : class
80+
{
81+
public void TestMethod<TValue>(TValue? value)
82+
where TValue : class, IEnumerable<T?>?
83+
{
84+
if (value is List<T?> items)
85+
{
86+
_ = items;
87+
}
88+
}
89+
}
90+
";
91+
92+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
93+
}
3894
}
3995
}

documentation/SA1015.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ A closing generic bracket within a C# element is not spaced correctly.
2424
A violation of this rule occurs when the spacing around a closing generic bracket is not correct.
2525

2626
A closing generic bracket should never be preceded by whitespace, unless the bracket is the first character on the line.
27-
A closing generic bracket should be followed by an open parenthesis, a close
28-
parenthesis, a closing generic bracket, a nullable symbol, an end of
29-
line or a single whitespace (but not whitespace and an open parenthesis).
27+
A closing generic bracket should be followed by an open parenthesis, a close parenthesis, a closing generic bracket, a
28+
nullable symbol, an end of line or a single whitespace (but not whitespace and an open parenthesis). In nullable-aware
29+
contexts, nullable reference type annotations (for example `List<string?>?`) follow the same rules as nullable value
30+
types.
3031

3132
## How to fix violations
3233

33-
To fix a violation of this rule, ensure the whitespace around the closing generic bracket
34-
is correct.
34+
To fix a violation of this rule, ensure the whitespace around the closing generic bracket is correct.
3535

3636
## How to suppress violations
3737

0 commit comments

Comments
 (0)