diff --git a/Sources/SwiftFormat/PrettyPrint/PrettyPrint.swift b/Sources/SwiftFormat/PrettyPrint/PrettyPrint.swift index 5f4ff24c8..1201f84c2 100644 --- a/Sources/SwiftFormat/PrettyPrint/PrettyPrint.swift +++ b/Sources/SwiftFormat/PrettyPrint/PrettyPrint.swift @@ -515,7 +515,7 @@ public class PrettyPrinter { write(comment.print(indent: currentIndentation)) if wasEndOfLine { - if comment.length > spaceRemaining { + if comment.length > spaceRemaining && !isBreakingSuppressed { diagnose(.moveEndOfLineComment, category: .endOfLineComment) } } else { diff --git a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift index 048f0c866..fc10ebbf0 100644 --- a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift @@ -2742,9 +2742,10 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { /// will stay inside the group. /// /// * If the trailing comment is a line comment, we first append any enqueued after-tokens - /// that are *not* breaks or newlines, then we append the comment, and then the remaining - /// after-tokens. Due to visitation ordering, this ensures that a trailing line comment is - /// not incorrectly inserted into the token stream *after* a break or newline. + /// that are *not* related to breaks or newlines (e.g. includes print control tokens), then + /// we append the comment, and then the remaining after-tokens. Due to visitation ordering, + /// this ensures that a trailing line comment is not incorrectly inserted into the token stream + /// *after* a break or newline. private func appendAfterTokensAndTrailingComments(_ token: TokenSyntax) { let (wasLineComment, trailingCommentTokens) = afterTokensForTrailingComment(token) let afterGroups = afterMap.removeValue(forKey: token) ?? [] @@ -2759,7 +2760,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { var shouldExtractTrailingComment = false if wasLineComment && !hasAppendedTrailingComment { switch afterToken { - case .break: shouldExtractTrailingComment = true + case .break, .printerControl: shouldExtractTrailingComment = true default: break } } diff --git a/Tests/SwiftFormatTests/PrettyPrint/CommentTests.swift b/Tests/SwiftFormatTests/PrettyPrint/CommentTests.swift index c197c5d69..96aeb9908 100644 --- a/Tests/SwiftFormatTests/PrettyPrint/CommentTests.swift +++ b/Tests/SwiftFormatTests/PrettyPrint/CommentTests.swift @@ -1,3 +1,5 @@ +import _SwiftFormatTestSupport + final class CommentTests: PrettyPrintTestCase { func testDocumentationComments() { let input = @@ -408,7 +410,7 @@ final class CommentTests: PrettyPrintTestCase { case quux } """ - + let expected = """ struct Foo { @@ -424,7 +426,7 @@ final class CommentTests: PrettyPrintTestCase { } """ - + assertPrettyPrintEqual(input: input, expected: expected, linelength: 100) } @@ -594,25 +596,25 @@ final class CommentTests: PrettyPrintTestCase { func testCommentsInIfStatements() { let input = - """ - if foo.bar && false && // comment about foo.bar - baz && // comment about baz - // comment about next - next - && // other is important - // second line about other - other && - // comment about final on a new line - final - { - } - if foo.bar && foo.baz - && // comment about the next line - // another comment line - next.line - { - } - """ + """ + if foo.bar && false && // comment about foo.bar + baz && // comment about baz + // comment about next + next + && // other is important + // second line about other + other && + // comment about final on a new line + final + { + } + if foo.bar && foo.baz + && // comment about the next line + // another comment line + next.line + { + } + """ let expected = """ @@ -682,4 +684,32 @@ final class CommentTests: PrettyPrintTestCase { assertPrettyPrintEqual(input: input, expected: expected, linelength: 60) } + + func testDiagnoseMoveEndOfLineComment() { + assertPrettyPrintEqual( + input: """ + import veryveryverylongmodulenameherebecauseitistypical // special sentinel comment + + func fooBarBazRunningOutOfIdeas() { 1️⃣// comment that needs to move + if foo { // comment is fine + } + } + + """, + expected: """ + import veryveryverylongmodulenameherebecauseitistypical // special sentinel comment + + func fooBarBazRunningOutOfIdeas() { // comment that needs to move + if foo { // comment is fine + } + } + + """, + linelength: 45, + whitespaceOnly: true, + findings: [ + FindingSpec("1️⃣", message: "move end-of-line comment that exceeds the line length"), + ] + ) + } }