diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 5fc50c76f..a48db5759 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -718,13 +718,23 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { after(node.unknownAttr?.lastToken, tokens: .space) after(node.label.lastToken, tokens: .break(.reset, size: 0), .break(.open), .open) - // If switch/case labels were configured to be indented, insert an extra `close` break after the - // case body to match the `open` break above + // If switch/case labels were configured to be indented, insert an extra `close` break after + // the case body to match the `open` break above var afterLastTokenTokens: [Token] = [.break(.close, size: 0), .close] if config.indentSwitchCaseLabels { afterLastTokenTokens.append(.break(.close, size: 0)) } - after(node.lastToken, tokens: afterLastTokenTokens) + + // If the case contains statements, add the closing tokens after the last token of the case. + // Otherwise, add the closing tokens before the next case (or the end of the switch) to have the + // same effect. If instead the opening and closing tokens were omitted completely in the absence + // of statements, comments within the empty case would be incorrectly indented to the same level + // as the case label. + if node.label.lastToken != node.lastToken { + after(node.lastToken, tokens: afterLastTokenTokens) + } else { + before(node.nextToken, tokens: afterLastTokenTokens) + } return .visitChildren } diff --git a/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift b/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift index 35726d224..08e07d94e 100644 --- a/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift +++ b/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift @@ -78,6 +78,43 @@ final class SwitchStmtTests: PrettyPrintTestCase { assertPrettyPrintEqual(input: input, expected: expected, linelength: 35) } + func testSwitchEmptyCases() { + let input = + """ + switch a { + case b: + default: + print("Not b") + } + + switch a { + case b: + // Comment but no statements + default: + print("Not b") + } + """ + + let expected = + """ + switch a { + case b: + default: + print("Not b") + } + + switch a { + case b: + // Comment but no statements + default: + print("Not b") + } + + """ + + assertPrettyPrintEqual(input: input, expected: expected, linelength: 35) + } + func testSwitchCompoundCases() { let input = """