Skip to content

Commit 605c78d

Browse files
authored
Merge pull request #4038 from sharwell/indices-and-ranges
Support indices and ranges from C# 8
2 parents 04e9a1a + 16ff759 commit 605c78d

File tree

7 files changed

+435
-17
lines changed

7 files changed

+435
-17
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp8/MaintainabilityRules/SA1119CSharp8UnitTests.cs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,5 +328,82 @@ public void TestMethod()
328328

329329
await test.RunAsync(CancellationToken.None).ConfigureAwait(false);
330330
}
331+
332+
[Fact]
333+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
334+
public async Task TestParenthesizedRangeExpressionsAreAcceptedAsync()
335+
{
336+
const string testCode = @"using System;
337+
338+
public class TestClass
339+
{
340+
public Range TestMethod(int length)
341+
{
342+
Range local = {|#0:{|#1:(|}1..^3{|#2:)|}|};
343+
return {|#3:{|#4:(|}1..^length{|#5:)|}|};
344+
}
345+
}
346+
";
347+
const string fixedCode = @"using System;
348+
349+
public class TestClass
350+
{
351+
public Range TestMethod(int length)
352+
{
353+
Range local = 1..^3;
354+
return 1..^length;
355+
}
356+
}
357+
";
358+
359+
DiagnosticResult[] expected =
360+
{
361+
Diagnostic(DiagnosticId).WithLocation(0),
362+
Diagnostic(ParenthesesDiagnosticId).WithLocation(1),
363+
Diagnostic(ParenthesesDiagnosticId).WithLocation(2),
364+
Diagnostic(DiagnosticId).WithLocation(3),
365+
Diagnostic(ParenthesesDiagnosticId).WithLocation(4),
366+
Diagnostic(ParenthesesDiagnosticId).WithLocation(5),
367+
};
368+
369+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
370+
}
371+
372+
[Fact]
373+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
374+
public async Task TestParenthesizedIndexExpressionsAreAcceptedAsync()
375+
{
376+
const string testCode = @"using System;
377+
378+
public class TestClass
379+
{
380+
public int TestMethod(int length)
381+
{
382+
Index index = {|#0:{|#1:(|}^5{|#2:)|}|};
383+
return (^2).GetOffset(length);
384+
}
385+
}
386+
";
387+
const string fixedCode = @"using System;
388+
389+
public class TestClass
390+
{
391+
public int TestMethod(int length)
392+
{
393+
Index index = ^5;
394+
return (^2).GetOffset(length);
395+
}
396+
}
397+
";
398+
399+
DiagnosticResult[] expected =
400+
{
401+
Diagnostic(DiagnosticId).WithLocation(0),
402+
Diagnostic(ParenthesesDiagnosticId).WithLocation(1),
403+
Diagnostic(ParenthesesDiagnosticId).WithLocation(2),
404+
};
405+
406+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
407+
}
331408
}
332409
}

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

Lines changed: 95 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
22
// Licensed under the MIT License. See LICENSE in the project root for license information.
33

4-
#nullable disable
5-
64
namespace StyleCop.Analyzers.Test.CSharp8.SpacingRules
75
{
86
using System.Threading;
@@ -38,12 +36,11 @@ public class TestClass
3836
{
3937
public void TestMethod()
4038
{
41-
var test1 = .. {|#0:(|}int)1;
39+
var test1 = {|#0:..|} {|#1:(|}int)1;
4240
}
4341
}
4442
}
4543
";
46-
4744
var fixedCode = @"
4845
namespace TestNamespace
4946
{
@@ -62,7 +59,11 @@ public void TestMethod()
6259
{
6360
ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31,
6461
TestCode = testCode,
65-
ExpectedDiagnostics = { Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(0).WithArguments("(int)") },
62+
ExpectedDiagnostics =
63+
{
64+
Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(0).WithArguments(".."),
65+
Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(1).WithArguments("(int)"),
66+
},
6667
FixedCode = fixedCode,
6768
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
6869
}
@@ -142,5 +143,94 @@ public string TestMethod(string? x)
142143
};
143144
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
144145
}
146+
147+
[Fact]
148+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
149+
public async Task TestIndexAndRangeExpressionsAsync()
150+
{
151+
var testCode = @"
152+
namespace TestNamespace
153+
{
154+
using System;
155+
156+
public class TestClass
157+
{
158+
public void TestMethod(int[] values)
159+
{
160+
var last = values[^1];
161+
var slice = values[2..^5];
162+
var slice2 = values[..];
163+
Index start = ^5;
164+
Range middle = 1..4;
165+
}
166+
}
167+
}
168+
";
169+
170+
await new CSharpTest()
171+
{
172+
ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp31,
173+
TestCode = testCode,
174+
}.RunAsync(CancellationToken.None).ConfigureAwait(false);
175+
}
176+
177+
[Fact]
178+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
179+
public async Task TestIndexAndRangeExpressionsSpacingViolationsAsync()
180+
{
181+
var testCode = @"
182+
namespace TestNamespace
183+
{
184+
using System;
185+
186+
public class TestClass
187+
{
188+
public void TestMethod(int[] values)
189+
{
190+
var last = values[ {|#0:^|}1];
191+
var compactSlice = values[1 {|#1:..|} ^2];
192+
var prefixRangeSpaceAfter = values[{|#2:..|} ^2];
193+
var suffixRangeSpaceBefore = values[1 {|#3:..|}];
194+
Range missingLeadingSpace = 1 {|#4:..|} 4;
195+
var missingTrailingSpace = 1{|#5:..|} ^2;
196+
}
197+
}
198+
}
199+
";
200+
201+
var fixedCode = @"
202+
namespace TestNamespace
203+
{
204+
using System;
205+
206+
public class TestClass
207+
{
208+
public void TestMethod(int[] values)
209+
{
210+
var last = values[^1];
211+
var compactSlice = values[1..^2];
212+
var prefixRangeSpaceAfter = values[..^2];
213+
var suffixRangeSpaceBefore = values[1..];
214+
Range missingLeadingSpace = 1..4;
215+
var missingTrailingSpace = 1..^2;
216+
}
217+
}
218+
}
219+
";
220+
221+
var expected = new[]
222+
{
223+
Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(0).WithArguments("^"),
224+
Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(1).WithArguments(".."),
225+
Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(1).WithArguments(".."),
226+
Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(2).WithArguments(".."),
227+
Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(3).WithArguments(".."),
228+
Diagnostic(DescriptorNotPrecededByWhitespace).WithLocation(4).WithArguments(".."),
229+
Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(4).WithArguments(".."),
230+
Diagnostic(DescriptorNotFollowedByWhitespace).WithLocation(5).WithArguments(".."),
231+
};
232+
233+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
234+
}
145235
}
146236
}

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

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

44
namespace StyleCop.Analyzers.Test.CSharp8.SpacingRules
55
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
69
using StyleCop.Analyzers.Test.CSharp7.SpacingRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.SpacingRules.SA1010OpeningSquareBracketsMustBeSpacedCorrectly;
12+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
13+
StyleCop.Analyzers.SpacingRules.SA1010OpeningSquareBracketsMustBeSpacedCorrectly,
14+
StyleCop.Analyzers.SpacingRules.TokenSpacingCodeFixProvider>;
715

816
public partial class SA1010CSharp8UnitTests : SA1010CSharp7UnitTests
917
{
18+
[Fact]
19+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
20+
public async Task TestIndexAndRangeOpenBracketSpacingAsync()
21+
{
22+
var testCode = @"
23+
namespace TestNamespace
24+
{
25+
using System;
26+
27+
public class TestClass
28+
{
29+
public void TestMethod(int[] values)
30+
{
31+
_ = values {|#0:[|}^1];
32+
_ = values{|#1:[|} ^1];
33+
_ = values {|#2:[|} ^1];
34+
_ = values {|#3:[|}1..^2];
35+
_ = values{|#4:[|} 1..^2];
36+
_ = values[..];
37+
_ = values{|#5:[|} ..];
38+
}
39+
}
40+
}
41+
";
42+
var fixedCode = @"
43+
namespace TestNamespace
44+
{
45+
using System;
46+
47+
public class TestClass
48+
{
49+
public void TestMethod(int[] values)
50+
{
51+
_ = values[^1];
52+
_ = values[^1];
53+
_ = values[^1];
54+
_ = values[1..^2];
55+
_ = values[1..^2];
56+
_ = values[..];
57+
_ = values[..];
58+
}
59+
}
60+
}
61+
";
62+
63+
DiagnosticResult[] expected =
64+
{
65+
Diagnostic(DescriptorNotPreceded).WithLocation(0),
66+
Diagnostic(DescriptorNotFollowed).WithLocation(1),
67+
Diagnostic(DescriptorNotPreceded).WithLocation(2),
68+
Diagnostic(DescriptorNotFollowed).WithLocation(2),
69+
Diagnostic(DescriptorNotPreceded).WithLocation(3),
70+
Diagnostic(DescriptorNotFollowed).WithLocation(4),
71+
Diagnostic(DescriptorNotFollowed).WithLocation(5),
72+
};
73+
74+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
75+
}
1076
}
1177
}

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

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace StyleCop.Analyzers.Test.CSharp8.SpacingRules
77
using System.Threading.Tasks;
88
using Microsoft.CodeAnalysis.Testing;
99
using StyleCop.Analyzers.Test.CSharp7.SpacingRules;
10+
using StyleCop.Analyzers.Test.Helpers;
1011
using Xunit;
1112
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
1213
StyleCop.Analyzers.SpacingRules.SA1011ClosingSquareBracketsMustBeSpacedCorrectly,
@@ -183,5 +184,57 @@ public void TestMethod(int[] arg)
183184

184185
await VerifyCSharpDiagnosticAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
185186
}
187+
188+
[Fact]
189+
[WorkItem(3008, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/3008")]
190+
public async Task TestIndexAndRangeClosingBracketSpacingAsync()
191+
{
192+
var testCode = @"
193+
namespace TestNamespace
194+
{
195+
using System;
196+
197+
public class TestClass
198+
{
199+
public void TestMethod(int[] values)
200+
{
201+
_ = values[^1 {|#0:]|};
202+
_ = values[1..^2 {|#1:]|};
203+
_ = values[.. {|#2:]|};
204+
_ = values[^1{|#3:]|}^1;
205+
_ = values[^1] ^1;
206+
}
207+
}
208+
}
209+
";
210+
var fixedCode = @"
211+
namespace TestNamespace
212+
{
213+
using System;
214+
215+
public class TestClass
216+
{
217+
public void TestMethod(int[] values)
218+
{
219+
_ = values[^1];
220+
_ = values[1..^2];
221+
_ = values[..];
222+
_ = values[^1] ^1;
223+
_ = values[^1] ^1;
224+
}
225+
}
226+
}
227+
";
228+
229+
DiagnosticResult[] expected =
230+
{
231+
Diagnostic().WithArguments(" not", "preceded").WithLocation(0),
232+
Diagnostic().WithArguments(" not", "preceded").WithLocation(1),
233+
Diagnostic().WithArguments(" not", "preceded").WithLocation(2),
234+
Diagnostic().WithArguments(string.Empty, "followed").WithLocation(3),
235+
};
236+
237+
await VerifyCSharpFixAsync(testCode, expected, fixedCode, CancellationToken.None).ConfigureAwait(false);
238+
}
186239
}
187240
}

0 commit comments

Comments
 (0)