diff --git a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift index dd3dd1929..e6eb43042 100644 --- a/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift +++ b/Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift @@ -2957,19 +2957,24 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor { if let attributes = attributes { let behavior: NewlineBehavior = separateByLineBreaks ? .hard : .elective before(attributes.firstToken(viewMode: .sourceAccurate), tokens: .open) - for element in attributes.dropLast() { - if let ifConfig = element.as(IfConfigDeclSyntax.self) { + if attributes.dropLast().isEmpty, + let ifConfig = attributes.first?.as(IfConfigDeclSyntax.self) { + for clause in ifConfig.clauses { + if let nestedAttributes = AttributeListSyntax(clause.elements) { + arrangeAttributeList(nestedAttributes, suppressFinalBreak: true, separateByLineBreaks: separateByLineBreaks) + } + } + } else { + for element in attributes.dropLast() { + if let ifConfig = element.as(IfConfigDeclSyntax.self) { for clause in ifConfig.clauses { - if let nestedAttributes = AttributeListSyntax(clause.elements) { - arrangeAttributeList( - nestedAttributes, - suppressFinalBreak: true, - separateByLineBreaks: separateByLineBreaks - ) - } + if let nestedAttributes = AttributeListSyntax(clause.elements) { + arrangeAttributeList(nestedAttributes, suppressFinalBreak: true, separateByLineBreaks: separateByLineBreaks) + } } - } else { + } else { after(element.lastToken(viewMode: .sourceAccurate), tokens: .break(.same, newlines: behavior)) + } } } var afterAttributeTokens = [Token.close] diff --git a/Tests/SwiftFormatTests/PrettyPrint/AttributeTests.swift b/Tests/SwiftFormatTests/PrettyPrint/AttributeTests.swift index c16950390..668df4de2 100644 --- a/Tests/SwiftFormatTests/PrettyPrint/AttributeTests.swift +++ b/Tests/SwiftFormatTests/PrettyPrint/AttributeTests.swift @@ -576,4 +576,27 @@ final class AttributeTests: PrettyPrintTestCase { configuration.lineBreakBetweenDeclarationAttributes = true assertPrettyPrintEqual(input: input, expected: expected, linelength: 80, configuration: configuration) } + + func testAttributesStartWithPoundIf() { + let input = + """ + #if os(macOS) + @available(macOS, unavailable) + @_spi(Foo) + #endif + public let myVar = "Test" + + """ + let expected = + """ + #if os(macOS) + @available(macOS, unavailable) + @_spi(Foo) + #endif + public let myVar = "Test" + + """ + + assertPrettyPrintEqual(input: input, expected: expected, linelength: 45) + } }