Skip to content

Commit f8627f7

Browse files
committed
Improve SA1642 code fix handling of empty lines
Fixes #2686
1 parent ed512f9 commit f8627f7

3 files changed

Lines changed: 88 additions & 6 deletions

File tree

StyleCop.Analyzers/StyleCop.Analyzers.CodeFixes/DocumentationRules/SA1642SA1643CodeFixProvider.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,11 @@ private static SyntaxList<XmlNodeSyntax> RemoveTrailingEmptyLines(SyntaxList<Xml
306306
{
307307
firstEmptyToken = j;
308308
}
309+
else if (textToken.IsXmlNewLine() && textToken.LeadingTrivia.Any(SyntaxKind.DocumentationCommentExteriorTrivia))
310+
{
311+
// Skip completely blank lines
312+
firstEmptyToken = j;
313+
}
309314
else if (textToken.IsKind(SyntaxKind.XmlTextLiteralToken) && !string.IsNullOrWhiteSpace(textToken.Text))
310315
{
311316
break;
@@ -314,8 +319,10 @@ private static SyntaxList<XmlNodeSyntax> RemoveTrailingEmptyLines(SyntaxList<Xml
314319

315320
if (firstEmptyToken > -1)
316321
{
317-
var newContent = SyntaxFactory.List(content.Take(firstEmptyToken));
318-
newContent.Add(newContent.Last());
322+
var newContent = content.RemoveAt(content.Count - 1);
323+
newContent = newContent
324+
.Add(XmlSyntaxFactory.Text(xmlText.TextTokens.Take(firstEmptyToken).ToArray()))
325+
.Add(XmlSyntaxFactory.Text(xmlText.TextTokens.Last()));
319326
return newContent;
320327
}
321328

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1642UnitTests.cs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ public TestClass() { }
918918

919919
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
920920
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
921-
await this.VerifyCSharpFixAsync(testCode, fixedCode, numberOfFixAllIterations: 2, cancellationToken: CancellationToken.None).ConfigureAwait(false);
921+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
922922
}
923923

924924
/// <summary>
@@ -954,7 +954,82 @@ public TestClass() { }
954954

955955
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
956956
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
957-
await this.VerifyCSharpFixAsync(testCode, fixedCode, numberOfFixAllIterations: 2, cancellationToken: CancellationToken.None).ConfigureAwait(false);
957+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
958+
}
959+
960+
[Theory]
961+
[WorkItem(2686, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2686")]
962+
[InlineData("")]
963+
[InlineData(" ")]
964+
public async Task TestConstructorEmptyDocumentationSingleLineAsync(string emptyContent)
965+
{
966+
var testCode = $@"namespace FooNamespace
967+
{{
968+
public class ClassName
969+
{{
970+
/// <summary>{emptyContent}</summary>
971+
public ClassName()
972+
{{
973+
}}
974+
}}
975+
}}";
976+
977+
var fixedCode = $@"namespace FooNamespace
978+
{{
979+
public class ClassName
980+
{{
981+
/// <summary>
982+
/// Initializes a new instance of the <see cref=""ClassName""/> class.{emptyContent}</summary>
983+
public ClassName()
984+
{{
985+
}}
986+
}}
987+
}}";
988+
989+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(5, 13);
990+
991+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
992+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
993+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
994+
}
995+
996+
[Theory]
997+
[WorkItem(2686, "https://github.com/DotNetAnalyzers/StyleCopAnalyzers/issues/2686")]
998+
[InlineData("")]
999+
[InlineData(" ")]
1000+
public async Task TestConstructorEmptyDocumentationAsync(string emptyContent)
1001+
{
1002+
var testCode = $@"namespace FooNamespace
1003+
{{
1004+
public class ClassName
1005+
{{
1006+
/// <summary>
1007+
///{emptyContent}
1008+
/// </summary>
1009+
public ClassName()
1010+
{{
1011+
}}
1012+
}}
1013+
}}";
1014+
1015+
var fixedCode = $@"namespace FooNamespace
1016+
{{
1017+
public class ClassName
1018+
{{
1019+
/// <summary>
1020+
/// Initializes a new instance of the <see cref=""ClassName""/> class.
1021+
/// </summary>
1022+
public ClassName()
1023+
{{
1024+
}}
1025+
}}
1026+
}}";
1027+
1028+
DiagnosticResult expected = this.CSharpDiagnostic().WithLocation(5, 13);
1029+
1030+
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
1031+
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
1032+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
9581033
}
9591034

9601035
protected override Project ApplyCompilationOptions(Project project)

StyleCop.Analyzers/StyleCop.Analyzers.Test/DocumentationRules/SA1643UnitTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public class TestClass
183183

184184
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
185185
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
186-
await this.VerifyCSharpFixAsync(testCode, fixedCode, numberOfFixAllIterations: 2, cancellationToken: CancellationToken.None).ConfigureAwait(false);
186+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
187187
}
188188

189189
/// <summary>
@@ -217,7 +217,7 @@ public class TestClass
217217

218218
await this.VerifyCSharpDiagnosticAsync(testCode, expected, CancellationToken.None).ConfigureAwait(false);
219219
await this.VerifyCSharpDiagnosticAsync(fixedCode, EmptyDiagnosticResults, CancellationToken.None).ConfigureAwait(false);
220-
await this.VerifyCSharpFixAsync(testCode, fixedCode, numberOfFixAllIterations: 2, cancellationToken: CancellationToken.None).ConfigureAwait(false);
220+
await this.VerifyCSharpFixAsync(testCode, fixedCode, cancellationToken: CancellationToken.None).ConfigureAwait(false);
221221
}
222222

223223
protected override Project ApplyCompilationOptions(Project project)

0 commit comments

Comments
 (0)