Skip to content

Commit fae34cb

Browse files
committed
Removing an empty statement will no longer leave trailing whitespace
1 parent 4e5fe43 commit fae34cb

2 files changed

Lines changed: 69 additions & 4 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.Test/ReadabilityRules/SA1106UnitTests.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,52 @@ public async Task TestMemberAsync(string declaration)
340340
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
341341
}
342342

343+
/// <summary>
344+
/// Verifies that the code fix will remove all unnecessary whitespace.
345+
/// This is a regression for #1556
346+
/// </summary>
347+
/// <returns>A <see cref="Task"/> representing the asynchronous unit test.</returns>
348+
[Fact]
349+
public async Task VerifyCodeFixWillRemoveUnnecessaryWhitespaceAsync()
350+
{
351+
var testCode = @"
352+
class TestClass
353+
{
354+
public void TestMethod1()
355+
{
356+
throw new System.NotImplementedException(); ;
357+
}
358+
359+
public void TestMethod2()
360+
{
361+
throw new System.NotImplementedException(); /* c1 */ ;
362+
}
363+
}";
364+
var fixedCode = @"
365+
class TestClass
366+
{
367+
public void TestMethod1()
368+
{
369+
throw new System.NotImplementedException();
370+
}
371+
372+
public void TestMethod2()
373+
{
374+
throw new System.NotImplementedException(); /* c1 */
375+
}
376+
}";
377+
378+
DiagnosticResult[] expected =
379+
{
380+
this.CSharpDiagnostic().WithLocation(6, 53),
381+
this.CSharpDiagnostic().WithLocation(11, 62)
382+
};
383+
384+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
385+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
386+
await this.VerifyCSharpFixAsync(testCode, fixedCode).ConfigureAwait(false);
387+
}
388+
343389
/// <inheritdoc/>
344390
protected override IEnumerable<DiagnosticAnalyzer> GetCSharpDiagnosticAnalyzers()
345391
{

StyleCop.Analyzers/StyleCop.Analyzers/ReadabilityRules/SA1106CodeFixProvider.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,39 @@ private static async Task<Document> RemoveEmptyStatementAsync(Document document,
106106

107107
private static async Task<Document> RemoveSemicolonTextAsync(Document document, SyntaxToken token, CancellationToken cancellationToken)
108108
{
109+
TextChange textChange;
110+
109111
SourceText sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);
110112
TextLine line = sourceText.Lines.GetLineFromPosition(token.SpanStart);
111113
if (sourceText.ToString(line.Span).Trim() == token.Text)
112114
{
113115
// remove the line containing the semicolon token
114-
TextChange textChange = new TextChange(line.SpanIncludingLineBreak, string.Empty);
116+
textChange = new TextChange(line.SpanIncludingLineBreak, string.Empty);
115117
return document.WithText(sourceText.WithChanges(textChange));
116118
}
119+
120+
TextSpan spanToRemove;
121+
var whitespaceIndex = TriviaHelper.IndexOfTrailingWhitespace(token.LeadingTrivia);
122+
if (whitespaceIndex >= 0)
123+
{
124+
spanToRemove = TextSpan.FromBounds(token.LeadingTrivia[whitespaceIndex].Span.Start, token.Span.End);
125+
}
117126
else
118127
{
119-
// remove just the semicolon
120-
TextChange textChange = new TextChange(token.Span, string.Empty);
121-
return document.WithText(sourceText.WithChanges(textChange));
128+
var previousToken = token.GetPreviousToken();
129+
whitespaceIndex = TriviaHelper.IndexOfTrailingWhitespace(previousToken.TrailingTrivia);
130+
if (whitespaceIndex >= 0)
131+
{
132+
spanToRemove = TextSpan.FromBounds(previousToken.TrailingTrivia[whitespaceIndex].Span.Start, token.Span.End);
133+
}
134+
else
135+
{
136+
spanToRemove = token.Span;
137+
}
122138
}
139+
140+
textChange = new TextChange(spanToRemove, string.Empty);
141+
return document.WithText(sourceText.WithChanges(textChange));
123142
}
124143
}
125144
}

0 commit comments

Comments
 (0)