Skip to content

Commit 2065608

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 fca02c2 commit 2065608

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

Sources/SwiftFormat/PrettyPrint/TokenStreamCreator.swift

+18-7
Original file line numberDiff line numberDiff line change
@@ -1492,7 +1492,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
14921492

14931493
override func visit(_ node: IfConfigDeclSyntax) -> SyntaxVisitorContinueKind {
14941494
// there has to be a break after an #endif
1495-
after(node.poundEndif, tokens: .break(.same, size: 0))
1495+
after(node.poundEndif, tokens: .break(.same, size: 0, newlines: .soft))
14961496
return .visitChildren
14971497
}
14981498

@@ -1951,17 +1951,28 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
19511951
}
19521952

19531953
override func visit(_ node: ImportDeclSyntax) -> SyntaxVisitorContinueKind {
1954-
// Import declarations should never be wrapped.
1955-
before(
1956-
node.firstToken(viewMode: .sourceAccurate),
1957-
tokens: .printerControl(kind: .disableBreaking(allowDiscretionary: false))
1958-
)
1954+
// Import declarations ignore wrapping when it is safe to do so (no #if constructs)
1955+
let isSafeToIgnoreBreaking = !node.attributes.contains(where: { element in
1956+
return element.is(IfConfigDeclSyntax.self)
1957+
})
1958+
1959+
if isSafeToIgnoreBreaking {
1960+
before(
1961+
node.firstToken(viewMode: .sourceAccurate),
1962+
tokens: .printerControl(kind: .disableBreaking(allowDiscretionary: false))
1963+
)
1964+
}
19591965

19601966
arrangeAttributeList(node.attributes)
19611967
after(node.importKeyword, tokens: .space)
19621968
after(node.importKindSpecifier, tokens: .space)
19631969

1964-
after(node.lastToken(viewMode: .sourceAccurate), tokens: .printerControl(kind: .enableBreaking))
1970+
if isSafeToIgnoreBreaking {
1971+
after(
1972+
node.lastToken(viewMode: .sourceAccurate),
1973+
tokens: .printerControl(kind: .enableBreaking)
1974+
)
1975+
}
19651976
return .visitChildren
19661977
}
19671978

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)