diff --git a/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs b/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs index 0471674501472..4376ad61d88f2 100644 --- a/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs +++ b/src/Compilers/CSharp/Portable/Syntax/SyntaxNormalizer.cs @@ -100,7 +100,7 @@ public override SyntaxToken VisitToken(SyntaxToken token) isTrailing: false, indentAfterLineBreak: NeedsIndentAfterLineBreak(token), mustHaveSeparator: false, - lineBreaksAfter: 0)); + lineBreaksAfter: lineBreaksAfterLeading(token))); var nextToken = this.GetNextRelevantToken(token); @@ -118,6 +118,22 @@ public override SyntaxToken VisitToken(SyntaxToken token) lineBreaksAfter: lineBreaksAfter)); return tk; + + static int lineBreaksAfterLeading(SyntaxToken syntaxToken) + { + if (syntaxToken.LeadingTrivia.Count < 2) + { + return 0; + } + + if (syntaxToken.LeadingTrivia[^2].IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia) && + syntaxToken.LeadingTrivia[^1].IsKind(SyntaxKind.EndOfLineTrivia)) + { + return 1; + } + + return 0; + } } finally { @@ -1247,7 +1263,7 @@ private static bool EndsInLineBreak(SyntaxTrivia trivia) } else { - return IsLineBreak(node.GetLastToken()); + return !node.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia) && IsLineBreak(node.GetLastToken()); } } diff --git a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs index bcb044788b178..4abda44062fae 100644 --- a/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs +++ b/src/Compilers/CSharp/Test/Syntax/Syntax/SyntaxNormalizerTests.cs @@ -3790,6 +3790,26 @@ void goo() "}"); } + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/76856")] + public void TestNormalizeDocumentationMultiLineCommentsWithTrailingNewline() + { + TestNormalizeStatement(""" + /** + * + * Escape XML special characters + */ + private String EscapeXML(String str) + { + """, """ + /// + /// + /// Escape XML special characters + ////// + private String EscapeXML(String str) + { + """); + } + [Fact] public void TestNormalizeEOL() {