Skip to content

Commit 0b976ba

Browse files
committed
Add tests for base type declarations and fix bugs
* Ignore leading attribute lists when analyzing other element kinds
1 parent b4610a1 commit 0b976ba

2 files changed

Lines changed: 104 additions & 3 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1137UnitTests.cs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,90 @@ namespace StyleCop.Analyzers.Test.ReadabilityRules
1717
/// </summary>
1818
public class SA1137UnitTests : CodeFixVerifier
1919
{
20+
[Theory]
21+
[InlineData("class")]
22+
[InlineData("struct")]
23+
[InlineData("interface")]
24+
[InlineData("enum")]
25+
public async Task TestBaseTypeDeclarationAsync(string baseTypeKind)
26+
{
27+
// Need to test attribute lists here
28+
string testCode = $@"
29+
using System;
30+
31+
namespace Namespace0
32+
{{
33+
[My] [My] {baseTypeKind} TypeName {{ }}
34+
}}
35+
36+
namespace Namespace1
37+
{{
38+
[My]
39+
[My] {baseTypeKind} TypeName {{ }}
40+
}}
41+
42+
namespace Namespace2
43+
{{
44+
[My]
45+
[My]
46+
{baseTypeKind} TypeName {{ }}
47+
}}
48+
49+
namespace Namespace3
50+
{{
51+
[My]
52+
[My]
53+
{baseTypeKind} TypeName {{ }}
54+
}}
55+
56+
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
57+
class MyAttribute : Attribute {{ }}
58+
";
59+
string fixedCode = $@"
60+
using System;
61+
62+
namespace Namespace0
63+
{{
64+
[My] [My] {baseTypeKind} TypeName {{ }}
65+
}}
66+
67+
namespace Namespace1
68+
{{
69+
[My]
70+
[My] {baseTypeKind} TypeName {{ }}
71+
}}
72+
73+
namespace Namespace2
74+
{{
75+
[My]
76+
[My]
77+
{baseTypeKind} TypeName {{ }}
78+
}}
79+
80+
namespace Namespace3
81+
{{
82+
[My]
83+
[My]
84+
{baseTypeKind} TypeName {{ }}
85+
}}
86+
87+
[AttributeUsage(AttributeTargets.All, AllowMultiple = true)]
88+
class MyAttribute : Attribute {{ }}
89+
";
90+
91+
DiagnosticResult[] expected =
92+
{
93+
this.CSharpDiagnostic().WithLocation(12, 1),
94+
this.CSharpDiagnostic().WithLocation(18, 1),
95+
this.CSharpDiagnostic().WithLocation(24, 1),
96+
this.CSharpDiagnostic().WithLocation(25, 1),
97+
};
98+
99+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
100+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
101+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
102+
}
103+
20104
[Fact]
21105
public async Task TestBlockAsync()
22106
{

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1137ElementsShouldHaveTheSameIndentation.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ private static void CheckElements<T>(SyntaxNodeAnalysisContext context, Immutabl
349349
elements = elements.RemoveAll(
350350
element =>
351351
{
352-
SyntaxToken firstToken = element.GetFirstToken();
352+
SyntaxToken firstToken = GetFirstTokenForAnalysis(element);
353353
return firstToken.IsMissingOrDefault() || !firstToken.IsFirstInLine();
354354
});
355355

@@ -362,7 +362,8 @@ private static void CheckElements<T>(SyntaxNodeAnalysisContext context, Immutabl
362362
string expectedIndentation = null;
363363
foreach (T element in elements)
364364
{
365-
SyntaxTrivia indentationTrivia = element.GetFirstToken().LeadingTrivia.LastOrDefault();
365+
SyntaxToken firstToken = GetFirstTokenForAnalysis(element);
366+
SyntaxTrivia indentationTrivia = firstToken.LeadingTrivia.LastOrDefault();
366367
string indentation = indentationTrivia.IsKind(SyntaxKind.WhitespaceTrivia) ? indentationTrivia.ToString() : string.Empty;
367368

368369
if (first)
@@ -381,7 +382,7 @@ private static void CheckElements<T>(SyntaxNodeAnalysisContext context, Immutabl
381382
Location location;
382383
if (indentation.Length == 0)
383384
{
384-
location = element.GetFirstToken().GetLocation();
385+
location = firstToken.GetLocation();
385386
}
386387
else
387388
{
@@ -392,5 +393,21 @@ private static void CheckElements<T>(SyntaxNodeAnalysisContext context, Immutabl
392393
context.ReportDiagnostic(Diagnostic.Create(Descriptor, location, properties));
393394
}
394395
}
396+
397+
private static SyntaxToken GetFirstTokenForAnalysis(SyntaxNode node)
398+
{
399+
SyntaxToken firstToken = node.GetFirstToken();
400+
if (!node.IsKind(SyntaxKind.AttributeList))
401+
{
402+
while (firstToken.IsKind(SyntaxKind.OpenBracketToken)
403+
&& firstToken.Parent.IsKind(SyntaxKind.AttributeList))
404+
{
405+
// Skip over the attribute list since it's not the focus of this check
406+
firstToken = firstToken.Parent.GetLastToken().GetNextToken();
407+
}
408+
}
409+
410+
return firstToken;
411+
}
395412
}
396413
}

0 commit comments

Comments
 (0)