Skip to content

Commit 7cc41e2

Browse files
authored
Merge pull request #3610 from sharwell/optimize-sa1141
Optimize SA1141
2 parents 7aaba60 + e66216d commit 7cc41e2

File tree

6 files changed

+114
-156
lines changed

6 files changed

+114
-156
lines changed

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/ReadabilityRules/SA1141CSharp7UnitTests.cs

Lines changed: 35 additions & 85 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.CSharp7.ReadabilityRules
75
{
86
using System.Threading;
@@ -33,28 +31,28 @@ public async Task ValidateMemberDeclarationsWithValueTuplesAsync()
3331
3432
public class TestClass
3533
{
36-
public ValueTuple<int, int> TestMethod(ValueTuple<double, double> value)
34+
public [|ValueTuple<int, int>|] TestMethod([|ValueTuple<double, double>|] value)
3735
{
3836
throw new NotImplementedException();
3937
}
4038
41-
public System.ValueTuple<(int, int), int> TestMethod2(int p1, ValueTuple<System.ValueTuple<long, long>, long> p2, (ValueTuple<string, string>, string) p3)
39+
public [|System.ValueTuple<(int, int), int>|] TestMethod2(int p1, [|ValueTuple<System.ValueTuple<long, long>, long>|] p2, ([|ValueTuple<string, string>|], string) p3)
4240
{
4341
throw new NotImplementedException();
4442
}
4543
46-
public System.ValueTuple<int, int> TestProperty1 { get; set; }
44+
public [|System.ValueTuple<int, int>|] TestProperty1 { get; set; }
4745
48-
public System.Collections.Generic.List<ValueTuple<int, int>> TestProperty2 { get; set; }
46+
public System.Collections.Generic.List<[|ValueTuple<int, int>|]> TestProperty2 { get; set; }
4947
50-
public System.ValueTuple<int, long> this[int i] { get { return (1, 1l); } set { } }
48+
public [|System.ValueTuple<int, long>|] this[int i] { get { return (1, 1l); } set { } }
5149
52-
public static explicit operator TestClass(System.ValueTuple<int, int> p1)
50+
public static explicit operator TestClass([|System.ValueTuple<int, int>|] p1)
5351
{
5452
throw new NotImplementedException();
5553
}
5654
57-
public static implicit operator System.ValueTuple<int, int>(TestClass p1)
55+
public static implicit operator [|System.ValueTuple<int, int>|](TestClass p1)
5856
{
5957
throw new NotImplementedException();
6058
}
@@ -93,21 +91,7 @@ public static implicit operator (int, int)(TestClass p1)
9391
}
9492
";
9593

96-
DiagnosticResult[] expectedDiagnostics =
97-
{
98-
Diagnostic().WithLocation(5, 12),
99-
Diagnostic().WithLocation(5, 44),
100-
Diagnostic().WithLocation(10, 12),
101-
Diagnostic().WithLocation(10, 67),
102-
Diagnostic().WithLocation(10, 120),
103-
Diagnostic().WithLocation(15, 12),
104-
Diagnostic().WithLocation(17, 44),
105-
Diagnostic().WithLocation(19, 12),
106-
Diagnostic().WithLocation(21, 47),
107-
Diagnostic().WithLocation(26, 37),
108-
};
109-
110-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
94+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
11195
}
11296

11397
/// <summary>
@@ -118,28 +102,32 @@ public static implicit operator (int, int)(TestClass p1)
118102
public async Task ValidateValueTupleObjectCreationAsync()
119103
{
120104
var testCode = @"using System;
105+
using VT = System.ValueTuple;
121106
122107
public class TestClass
123108
{
124109
public void TestMethod()
125110
{
126-
var test1 = new ValueTuple<int, int>(1, 2);
127-
var test2 = new System.ValueTuple<int, int>(1, 2);
128-
var test3 = new ValueTuple<ValueTuple<int, int>, int>(new ValueTuple<int, int>(3, 4), 2);
129-
var test4 = new System.ValueTuple<int, System.ValueTuple<int, int>>(1, new System.ValueTuple<int, int>(2, 3));
130-
var test5 = (new ValueTuple<int, int>(3, 4), 2);
131-
var test6 = new System.ValueTuple<int, System.ValueTuple<int, int>>(1, (2, 3));
132-
var test7 = ValueTuple.Create(1, 2);
133-
var test8 = ValueTuple.Create<int, double>(1, 2);
134-
var test9 = System.ValueTuple.Create(1, new ValueTuple<int, double>(2, 3));
135-
var test10 = ValueTuple.Create(ValueTuple.Create(1, 2, 3), 4);
136-
var test11 = new ValueTuple<int, ValueTuple<int, int>>(1, ValueTuple.Create(2, 3));
137-
var test12 = new System.ValueTuple<byte, int>(1, 2);
111+
var test1 = [|new ValueTuple<int, int>(1, 2)|];
112+
var test2 = [|new System.ValueTuple<int, int>(1, 2)|];
113+
var test3 = [|new ValueTuple<ValueTuple<int, int>, int>([|new ValueTuple<int, int>(3, 4)|], 2)|];
114+
var test4 = [|new System.ValueTuple<int, System.ValueTuple<int, int>>(1, [|new System.ValueTuple<int, int>(2, 3)|])|];
115+
var test5 = ([|new ValueTuple<int, int>(3, 4)|], 2);
116+
var test6 = [|new System.ValueTuple<int, System.ValueTuple<int, int>>(1, (2, 3))|];
117+
var test7 = [|ValueTuple.Create|](1, 2);
118+
var test7B = [|VT.Create|](1, 2);
119+
var test8 = [|ValueTuple.Create<int, double>|](1, 2);
120+
var test8B = [|VT.Create<int, double>|](1, 2);
121+
var test9 = [|System.ValueTuple.Create|](1, [|new ValueTuple<int, double>(2, 3)|]);
122+
var test10 = [|ValueTuple.Create|]([|ValueTuple.Create|](1, 2, 3), 4);
123+
var test11 = [|new ValueTuple<int, ValueTuple<int, int>>(1, [|ValueTuple.Create|](2, 3))|];
124+
var test12 = [|new System.ValueTuple<byte, int>(1, 2)|];
138125
}
139126
}
140127
";
141128

142129
var fixedCode = @"using System;
130+
using VT = System.ValueTuple;
143131
144132
public class TestClass
145133
{
@@ -152,7 +140,9 @@ public void TestMethod()
152140
var test5 = ((3, 4), 2);
153141
var test6 = (1, (2, 3));
154142
var test7 = (1, 2);
143+
var test7B = (1, 2);
155144
var test8 = (1, (double)2);
145+
var test8B = (1, (double)2);
156146
var test9 = (1, (2, (double)3));
157147
var test10 = ((1, 2, 3), 4);
158148
var test11 = (1, (2, 3));
@@ -161,28 +151,7 @@ public void TestMethod()
161151
}
162152
";
163153

164-
DiagnosticResult[] expectedDiagnostics =
165-
{
166-
Diagnostic().WithLocation(7, 21),
167-
Diagnostic().WithLocation(8, 21),
168-
Diagnostic().WithLocation(9, 21),
169-
Diagnostic().WithLocation(9, 63),
170-
Diagnostic().WithLocation(10, 21),
171-
Diagnostic().WithLocation(10, 80),
172-
Diagnostic().WithLocation(11, 22),
173-
Diagnostic().WithLocation(12, 21),
174-
Diagnostic().WithLocation(13, 21),
175-
Diagnostic().WithLocation(14, 21),
176-
Diagnostic().WithLocation(15, 21),
177-
Diagnostic().WithLocation(15, 49),
178-
Diagnostic().WithLocation(16, 22),
179-
Diagnostic().WithLocation(16, 40),
180-
Diagnostic().WithLocation(17, 22),
181-
Diagnostic().WithLocation(17, 67),
182-
Diagnostic().WithLocation(18, 22),
183-
};
184-
185-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
154+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
186155
}
187156

188157
/// <summary>
@@ -330,8 +299,8 @@ public class TestClass
330299
{
331300
public void TestMethod(object input)
332301
{
333-
var test1 = (ValueTuple<int, int>)input;
334-
var test2 = (System.ValueTuple<System.ValueTuple<int, long>, byte>)input;
302+
var test1 = ([|ValueTuple<int, int>|])input;
303+
var test2 = ([|System.ValueTuple<System.ValueTuple<int, long>, byte>|])input;
335304
}
336305
}
337306
";
@@ -348,13 +317,7 @@ public void TestMethod(object input)
348317
}
349318
";
350319

351-
DiagnosticResult[] expectedDiagnostics =
352-
{
353-
Diagnostic().WithLocation(7, 22),
354-
Diagnostic().WithLocation(8, 22),
355-
};
356-
357-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
320+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
358321
}
359322

360323
/// <summary>
@@ -370,8 +333,8 @@ public class TestClass
370333
{
371334
public void TestMethod()
372335
{
373-
var test1 = default(ValueTuple<int, int>);
374-
var test2 = default(System.ValueTuple<System.ValueTuple<int, long>, byte>);
336+
var test1 = default([|ValueTuple<int, int>|]);
337+
var test2 = default([|System.ValueTuple<System.ValueTuple<int, long>, byte>|]);
375338
}
376339
}
377340
";
@@ -388,13 +351,7 @@ public void TestMethod()
388351
}
389352
";
390353

391-
DiagnosticResult[] expectedDiagnostics =
392-
{
393-
Diagnostic().WithLocation(7, 29),
394-
Diagnostic().WithLocation(8, 29),
395-
};
396-
397-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
354+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
398355
}
399356

400357
/// <summary>
@@ -408,7 +365,7 @@ public async Task ValidateValueTupleUsageInDelegateAsync()
408365
409366
public class TestClass
410367
{
411-
public delegate System.ValueTuple<int, bool> TestDelegate(ValueTuple<int, ValueTuple<int, long>> arg1, (long, double) arg2, (long, System.ValueTuple<bool, bool>) arg3);
368+
public delegate [|System.ValueTuple<int, bool>|] TestDelegate([|ValueTuple<int, ValueTuple<int, long>>|] arg1, (long, double) arg2, (long, [|System.ValueTuple<bool, bool>|]) arg3);
412369
}
413370
";
414371

@@ -420,14 +377,7 @@ public class TestClass
420377
}
421378
";
422379

423-
DiagnosticResult[] expectedDiagnostics =
424-
{
425-
Diagnostic().WithLocation(5, 21),
426-
Diagnostic().WithLocation(5, 63),
427-
Diagnostic().WithLocation(5, 136),
428-
};
429-
430-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
380+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
431381
}
432382
}
433383
}

StyleCop.Analyzers/StyleCop.Analyzers.Test.CSharp7/ReadabilityRules/SA1142CSharp7UnitTests.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
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.CSharp7.ReadabilityRules
75
{
86
using System.Threading;
97
using System.Threading.Tasks;
108
using Microsoft.CodeAnalysis.Testing;
119
using StyleCop.Analyzers.ReadabilityRules;
10+
using StyleCop.Analyzers.Test.ReadabilityRules;
1211
using Xunit;
1312
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
1413
StyleCop.Analyzers.ReadabilityRules.SA1142ReferToTupleElementsByName,
@@ -19,7 +18,7 @@ namespace StyleCop.Analyzers.Test.CSharp7.ReadabilityRules
1918
/// </summary>
2019
/// <seealso cref="SA1142ReferToTupleElementsByName"/>
2120
/// <seealso cref="SA1142CodeFixProvider"/>
22-
public partial class SA1142CSharp7UnitTests
21+
public partial class SA1142CSharp7UnitTests : SA1142UnitTests
2322
{
2423
/// <summary>
2524
/// Validate that tuple fields that are referenced by their name will not produce any diagnostics.
@@ -78,12 +77,7 @@ public int TestMethod2((int nameA, (int subNameA, int subNameB) nameB) p1)
7877
}
7978
";
8079

81-
DiagnosticResult[] expectedDiagnostics =
82-
{
83-
// diagnostics are specified inline
84-
};
85-
86-
await VerifyCSharpFixAsync(testCode, expectedDiagnostics, fixedCode, CancellationToken.None).ConfigureAwait(false);
80+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, fixedCode, CancellationToken.None).ConfigureAwait(false);
8781
}
8882
}
8983
}

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1141UnitTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,5 @@ public ValueTuple<int, int> TestMethod(ValueTuple<double, double> value)
4444

4545
await VerifyCSharpDiagnosticAsync(LanguageVersion.CSharp6, testCode, DiagnosticResult.EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
4646
}
47-
48-
//// TODO: Make sure that all paths are covered!
4947
}
5048
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Tunnel Vision Laboratories, LLC. All Rights Reserved.
2+
// Licensed under the MIT License. See LICENSE in the project root for license information.
3+
4+
namespace StyleCop.Analyzers.Test.ReadabilityRules
5+
{
6+
using System.Threading;
7+
using System.Threading.Tasks;
8+
using Microsoft.CodeAnalysis.Testing;
9+
using StyleCop.Analyzers.ReadabilityRules;
10+
using Xunit;
11+
using static StyleCop.Analyzers.Test.Verifiers.StyleCopCodeFixVerifier<
12+
StyleCop.Analyzers.ReadabilityRules.SA1142ReferToTupleElementsByName,
13+
StyleCop.Analyzers.ReadabilityRules.SA1142CodeFixProvider>;
14+
15+
/// <summary>
16+
/// This class contains the unit tests for SA1142.
17+
/// </summary>
18+
/// <seealso cref="SA1142ReferToTupleElementsByName"/>
19+
/// <seealso cref="SA1142CodeFixProvider"/>
20+
public class SA1142UnitTests
21+
{
22+
/// <summary>
23+
/// Verify that ValueTuple names referenced by their metadata name will not produce diagnostics when no other
24+
/// name is available.
25+
/// </summary>
26+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
27+
[Fact]
28+
public async Task ValidateFieldNameReferencesWithoutReplacementAsync()
29+
{
30+
var testCode = @"using System;
31+
32+
public class TestClass
33+
{
34+
public int TestMethod1(ValueTuple<int, int> p1)
35+
{
36+
return p1.Item1 + p1.Item2 + p1.ToString().Length;
37+
}
38+
39+
public int TestMethod2(ValueTuple<int, ValueTuple<int, int>> p1)
40+
{
41+
return p1.Item1 + p1.Item2.Item1 + p1.Item2.Item2;
42+
}
43+
}
44+
";
45+
46+
await VerifyCSharpFixAsync(testCode, DiagnosticResult.EmptyDiagnosticResults, testCode, CancellationToken.None).ConfigureAwait(false);
47+
}
48+
}
49+
}

StyleCop.Analyzers/StyleCop.Analyzers/Helpers/LanguageFeatureHelpers.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
namespace StyleCop.Analyzers.Helpers
77
{
8+
using System.Diagnostics.CodeAnalysis;
89
using Microsoft.CodeAnalysis.CSharp;
910
using Microsoft.CodeAnalysis.Diagnostics;
1011
using StyleCop.Analyzers.Lightup;
@@ -14,6 +15,17 @@ namespace StyleCop.Analyzers.Helpers
1415
/// </summary>
1516
internal static class LanguageFeatureHelpers
1617
{
18+
/// <summary>
19+
/// Checks if the tuple language feature is supported.
20+
/// </summary>
21+
/// <param name="context">The analysis context that will be checked.</param>
22+
/// <returns>True if tuples are supported by the compiler.</returns>
23+
[SuppressMessage("MicrosoftCodeAnalysisPerformance", "RS1012:Start action has no registered actions", Justification = "This is not a start action method.")]
24+
internal static bool SupportsTuples(this CompilationStartAnalysisContext context)
25+
{
26+
return context.Compilation is CSharpCompilation { LanguageVersion: >= LanguageVersionEx.CSharp7 };
27+
}
28+
1729
/// <summary>
1830
/// Checks if the tuple language feature is supported.
1931
/// </summary>

0 commit comments

Comments
 (0)