diff --git a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift index 1b7eb32a0..a6d50aec6 100644 --- a/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift @@ -640,6 +640,17 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { before(node.leftBrace, tokens: .break(.reset)) after(node.leftBrace, tokens: .close) + // An if-configuration clause around a switch-case encloses the case's node, so an + // if-configuration clause requires a break here in order to be allowed on a new line. + for ifConfigDecl in node.cases.filter({ $0.is(IfConfigDeclSyntax.self) }) { + if config.indentSwitchCaseLabels { + before(ifConfigDecl.firstToken, tokens: .break(.open)) + after(ifConfigDecl.lastToken, tokens: .break(.close, size: 0)) + } else { + before(ifConfigDecl.firstToken, tokens: .break(.same)) + } + } + let newlines: NewlineBehavior = areBracesCompletelyEmpty(node, contentsKeyPath: \.cases) ? .elective : .soft before(node.rightBrace, tokens: .break(.same, size: 0, newlines: newlines)) diff --git a/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift b/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift index 44f51097c..365e8ce36 100644 --- a/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift +++ b/Tests/SwiftFormatPrettyPrintTests/SwitchStmtTests.swift @@ -1,3 +1,5 @@ +import SwiftFormatConfiguration + final class SwitchStmtTests: PrettyPrintTestCase { func testBasicSwitch() { let input = @@ -332,4 +334,97 @@ final class SwitchStmtTests: PrettyPrintTestCase { assertPrettyPrintEqual(input: input, expected: expected, linelength: 20) } + + func testConditionalCases() { + let input = + """ + switch foo { + #if CONDITION_A + case bar: + callForBar() + #endif + case baz: + callForBaz() + } + switch foo2 { + case bar2: + callForBar() + #if CONDITION_B + case baz2: + callForBaz() + #endif + } + """ + + let expected = + """ + switch foo { + #if CONDITION_A + case bar: + callForBar() + #endif + case baz: + callForBaz() + } + switch foo2 { + case bar2: + callForBar() + #if CONDITION_B + case baz2: + callForBaz() + #endif + } + + """ + + assertPrettyPrintEqual(input: input, expected: expected, linelength: 40) + } + + func testConditionalCasesIndenting() { + let input = + """ + switch foo { + #if CONDITION_A + case bar: + callForBar() + #endif + case baz: + callForBaz() + } + switch foo2 { + case bar2: + callForBar() + #if CONDITION_B + case baz2: + callForBaz() + #endif + } + """ + + let expected = + """ + switch foo { + #if CONDITION_A + case bar: + callForBar() + #endif + case baz: + callForBaz() + } + switch foo2 { + case bar2: + callForBar() + #if CONDITION_B + case baz2: + callForBaz() + #endif + } + + """ + + var configuration = Configuration() + configuration.indentSwitchCaseLabels = true + assertPrettyPrintEqual( + input: input, expected: expected, linelength: 40, configuration: configuration) + } }