Skip to content

Commit a3240ee

Browse files
committed
Fix SA1127 code fix indenting when additional preceding trivia is present (#1652)
1 parent e60c596 commit a3240ee

2 files changed

Lines changed: 66 additions & 11 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/ReadabilityRules/SA1127CodeFixProvider.cs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace StyleCop.Analyzers.ReadabilityRules
66
using System.Collections.Generic;
77
using System.Collections.Immutable;
88
using System.Composition;
9+
using System.Linq;
910
using System.Threading;
1011
using System.Threading.Tasks;
1112
using Helpers;
@@ -88,18 +89,12 @@ private static async Task<Document> GetTransformedDocumentAsync(Document documen
8889

8990
private static string GetParentIndentation(SyntaxToken token)
9091
{
91-
var parentLine = token.Parent.Parent;
92-
var parentIndentation = string.Empty;
93-
var parentTrivia = parentLine.GetLeadingTrivia();
94-
foreach (var trivia in parentTrivia)
95-
{
96-
if (trivia.IsKind(SyntaxKind.WhitespaceTrivia))
97-
{
98-
parentIndentation += trivia.ToString();
99-
}
100-
}
92+
var parentTrivia = token.Parent.Parent.GetLeadingTrivia();
10193

102-
return parentIndentation;
94+
return parentTrivia
95+
.Where(t => t.IsKind(SyntaxKind.WhitespaceTrivia))
96+
.LastOrDefault()
97+
.ToString();
10398
}
10499

105100
// This function will remove any unnecessary whitespace or end-of-line trivia from a token.

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1127UnitTests.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,66 @@ private void Method<T>(
128128
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
129129
}
130130

131+
/// <summary>
132+
/// This is a regression test for DotNetAnalyzers/StyleCopAnalyzers#1652:
133+
/// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1652
134+
/// </summary>
135+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
136+
[Fact]
137+
public async Task TestViolationWithMethodDeclarationAndXmlCommentsAsync()
138+
{
139+
var testCode = $@"
140+
class Foo
141+
{{
142+
/// <summary>Foo</summary>
143+
/// <typeparam name=""T"">The type.</typeparam>
144+
private void Method<T>() where T : class {{ }}
145+
}}";
146+
var fixedCode = $@"
147+
class Foo
148+
{{
149+
/// <summary>Foo</summary>
150+
/// <typeparam name=""T"">The type.</typeparam>
151+
private void Method<T>()
152+
where T : class
153+
{{ }}
154+
}}";
155+
var expected = this.CSharpDiagnostic().WithLocation(6, 30);
156+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
157+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
158+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
159+
}
160+
161+
/// <summary>
162+
/// This is a regression test for DotNetAnalyzers/StyleCopAnalyzers#1652:
163+
/// https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/1652
164+
/// </summary>
165+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
166+
[Fact]
167+
public async Task TestViolationWithMethodDeclarationRegionDirectiveAsync()
168+
{
169+
var testCode = $@"
170+
class Foo
171+
{{
172+
#region Test
173+
private void Method<T>() where T : class {{ }}
174+
#endregion
175+
}}";
176+
var fixedCode = $@"
177+
class Foo
178+
{{
179+
#region Test
180+
private void Method<T>()
181+
where T : class
182+
{{ }}
183+
#endregion
184+
}}";
185+
var expected = this.CSharpDiagnostic().WithLocation(5, 30);
186+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
187+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
188+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
189+
}
190+
131191
[Fact]
132192
public async Task TestViolationWithExpressionBodiedMethodDeclarationAsync()
133193
{

0 commit comments

Comments
 (0)