Skip to content

Commit a1fd498

Browse files
committed
Only disable wrapping in import decls when it is safe to do so.
The ImportDeclSyntax attributes might include IfConfigDecls, which absolutely require line breaks in certain positions. The disable breaking logic of ImportDecl was preventing these from being emitted.
1 parent d7976ce commit a1fd498

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift

+12-4
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
14581458

14591459
override func visit(_ node: IfConfigDeclSyntax) -> SyntaxVisitorContinueKind {
14601460
// there has to be a break after an #endif
1461-
after(node.poundEndif, tokens: .break(.same, size: 0))
1461+
after(node.poundEndif, tokens: .break(.same, size: 0, newlines: .soft))
14621462
return .visitChildren
14631463
}
14641464

@@ -1893,14 +1893,22 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
18931893
}
18941894

18951895
override func visit(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind {
1896-
// Import declarations should never be wrapped.
1897-
before(node.firstToken(viewMode: .sourceAccurate), tokens: .printerControl(kind: .disableBreaking(allowDiscretionary: false)))
1896+
// Import declarations ignore wrapping when it is safe to do so (no #if constructs)
1897+
let isSafeToIgnoreBreaking = !node.attributes.contains(where: { element in
1898+
return element.is(IfConfigDeclSyntax.self)
1899+
})
1900+
1901+
if isSafeToIgnoreBreaking {
1902+
before(node.firstToken(viewMode: .sourceAccurate), tokens: .printerControl(kind: .disableBreaking(allowDiscretionary: false)))
1903+
}
18981904

18991905
arrangeAttributeList(node.attributes)
19001906
after(node.importKeyword, tokens: .space)
19011907
after(node.importKindSpecifier, tokens: .space)
19021908

1903-
after(node.lastToken(viewMode: .sourceAccurate), tokens: .printerControl(kind: .enableBreaking))
1909+
if isSafeToIgnoreBreaking {
1910+
after(node.lastToken(viewMode: .sourceAccurate), tokens: .printerControl(kind: .enableBreaking))
1911+
}
19041912
return .visitChildren
19051913
}
19061914

Tests/SwiftFormatTests/PrettyPrint/IfConfigTests.swift

+11-6
Original file line numberDiff line numberDiff line change
@@ -383,10 +383,10 @@ final class IfConfigTests: PrettyPrintTestCase {
383383
.toggleStyle(
384384
SwitchToggleStyle(tint: Color.blue))
385385
#endif
386-
.accessibilityValue(
387-
binding.wrappedValue == true
388-
? "On" : "Off"
389-
)
386+
.accessibilityValue(
387+
binding.wrappedValue == true
388+
? "On" : "Off"
389+
)
390390
}
391391
392392
"""
@@ -482,7 +482,7 @@ final class IfConfigTests: PrettyPrintTestCase {
482482
#if os(iOS)
483483
.iOSSpecificModifier()
484484
#endif
485-
.commonModifier()
485+
.commonModifier()
486486
487487
"""
488488

@@ -510,7 +510,7 @@ final class IfConfigTests: PrettyPrintTestCase {
510510
#if os(iOS)
511511
.iOSSpecificModifier()
512512
#endif
513-
.commonModifier()
513+
.commonModifier()
514514
515515
"""
516516

@@ -563,11 +563,16 @@ final class IfConfigTests: PrettyPrintTestCase {
563563
"""
564564
#if os(Foo)
565565
@_spiOnly
566+
#elseif os(Bar)
567+
@_spiOnly
568+
#else
569+
@_spiOnly
566570
#endif
567571
@_spi(Foo) import Foundation
568572
569573
"""
570574
var configuration = Configuration.forTesting
575+
configuration.respectsExistingLineBreaks = false
571576
configuration.indentConditionalCompilationBlocks = false
572577
assertPrettyPrintEqual(input: input, expected: input, linelength: 80, configuration: configuration)
573578

0 commit comments

Comments
 (0)