Skip to content

Commit b055c81

Browse files
committed
Update SA1212 for readonly members
1 parent 38c9d10 commit b055c81

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/OrderingRules/SA1212CSharp8UnitTests.cs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,120 @@
33

44
namespace StyleCop.Analyzers.Test.CSharp8.OrderingRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp7.OrderingRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.OrderingRules.SA1212PropertyAccessorsMustFollowOrder,
13+
StyleCop.Analyzers.OrderingRules.SA1212SA1213CodeFixProvider>;
714

815
public partial class SA1212CSharp8UnitTests : SA1212CSharp7UnitTests
916
{
17+
[Fact]
18+
[WorkItem(3001, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3001")]
19+
public async Task TestPropertyWithReadonlyGetterAfterSetterAsync()
20+
{
21+
var testCode = @"
22+
public struct S
23+
{
24+
private int _value;
25+
26+
public int Value
27+
{
28+
[|set
29+
{
30+
_value = value;
31+
}|]
32+
readonly get
33+
{
34+
return _value;
35+
}
36+
}
37+
}";
38+
39+
var fixedCode = @"
40+
public struct S
41+
{
42+
private int _value;
43+
44+
public int Value
45+
{
46+
readonly get
47+
{
48+
return _value;
49+
}
50+
set
51+
{
52+
_value = value;
53+
}
54+
}
55+
}";
56+
57+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
58+
}
59+
60+
[Fact]
61+
[WorkItem(3001, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3001")]
62+
public async Task TestIndexerWithReadonlyGetterAfterSetterAsync()
63+
{
64+
var testCode = @"
65+
public struct S
66+
{
67+
private int[] _values;
68+
69+
public int this[int index]
70+
{
71+
[|set
72+
{
73+
_values[index] = value;
74+
}|]
75+
readonly get
76+
{
77+
return _values[index];
78+
}
79+
}
80+
}";
81+
82+
var fixedCode = @"
83+
public struct S
84+
{
85+
private int[] _values;
86+
87+
public int this[int index]
88+
{
89+
readonly get
90+
{
91+
return _values[index];
92+
}
93+
set
94+
{
95+
_values[index] = value;
96+
}
97+
}
98+
}";
99+
100+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
101+
}
102+
103+
[Fact]
104+
[WorkItem(3001, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3001")]
105+
public async Task TestReadonlyGetterBeforeSetterAsync()
106+
{
107+
var testCode = @"
108+
public struct S
109+
{
110+
private int _value;
111+
112+
public int Value
113+
{
114+
readonly get => _value;
115+
set => _value = value;
116+
}
117+
}";
118+
119+
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
120+
}
10121
}
11122
}

documentation/SA1212.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,23 @@ public string Name
4343
}
4444
```
4545

46+
### C# 8 readonly accessors
47+
48+
Readonly members in structs do not change the ordering requirement. A `readonly` getter still needs to appear before any `set` or `init` accessor to satisfy this rule.
49+
50+
```csharp
51+
public struct S
52+
{
53+
public int Value
54+
{
55+
set => this.value = value;
56+
readonly get => this.value;
57+
}
58+
}
59+
```
60+
61+
The preceding property violates SA1212 because the readonly getter comes after the setter. Move the readonly getter before the setter to resolve the warning.
62+
4663
## How to fix violations
4764

4865
To fix an instance of this violation, place the get accessor before the set accessor.

0 commit comments

Comments
 (0)