Skip to content

Commit 2fde6d7

Browse files
authored
Merge pull request #402 from DavidBrunow/fixMorePostfixPoundIfs
Fix more postfix pound if scenarios
2 parents c05d1b8 + 79b9d3a commit 2fde6d7

File tree

2 files changed

+129
-30
lines changed

2 files changed

+129
-30
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,11 +1396,24 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
13961396
}
13971397

13981398
if isNestedInPostfixIfConfig(node: Syntax(node)) {
1399+
let breakToken: Token
1400+
let currentIfConfigDecl = node.parent?.parent?.as(IfConfigDeclSyntax.self)
1401+
1402+
if let currentIfConfigDecl = currentIfConfigDecl,
1403+
let tokenBeforeCurrentIfConfigDecl = currentIfConfigDecl.previousToken,
1404+
isNestedInIfConfig(node: Syntax(tokenBeforeCurrentIfConfigDecl)) ||
1405+
tokenBeforeCurrentIfConfigDecl.text == "}" {
1406+
breakToken = .break(.reset)
1407+
} else {
1408+
breakToken = .break
1409+
before(currentIfConfigDecl?.poundEndif, tokens: [.break])
1410+
}
1411+
13991412
before(
14001413
node.firstToken,
14011414
tokens: [
14021415
.printerControl(kind: .enableBreaking),
1403-
.break(.reset),
1416+
breakToken,
14041417
]
14051418
)
14061419
} else if let condition = node.condition {
@@ -3567,17 +3580,39 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
35673580
}
35683581

35693582
private func isNestedInPostfixIfConfig(node: Syntax) -> Bool {
3570-
var this: Syntax? = node
3583+
var this: Syntax? = node
35713584

3572-
while this?.parent != nil {
3573-
if this?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
3574-
return true
3575-
}
3585+
while this?.parent != nil {
3586+
// This guard handles the situation where a type with its own modifiers
3587+
// is nested inside of an if config. That type should not count as being
3588+
// in a postfix if config because its entire body is inside the if config.
3589+
if this?.is(TupleExprElementSyntax.self) == true {
3590+
return false
3591+
}
35763592

3577-
this = this?.parent
3593+
if this?.is(IfConfigDeclSyntax.self) == true &&
3594+
this?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
3595+
return true
35783596
}
35793597

3580-
return false
3598+
this = this?.parent
3599+
}
3600+
3601+
return false
3602+
}
3603+
3604+
private func isNestedInIfConfig(node: Syntax) -> Bool {
3605+
var this: Syntax? = node
3606+
3607+
while this?.parent != nil {
3608+
if this?.is(IfConfigClauseSyntax.self) == true {
3609+
return true
3610+
}
3611+
3612+
this = this?.parent
3613+
}
3614+
3615+
return false
35813616
}
35823617

35833618
extension Syntax {

Tests/SwiftFormatPrettyPrintTests/IfConfigTests.swift

Lines changed: 86 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,10 @@ final class IfConfigTests: PrettyPrintTestCase {
247247
"""
248248
VStack {
249249
Text("something")
250-
#if os(iOS)
251-
.iOSSpecificModifier()
252-
#endif
253-
.commonModifier()
250+
#if os(iOS)
251+
.iOSSpecificModifier()
252+
#endif
253+
.commonModifier()
254254
}
255255
256256
"""
@@ -277,13 +277,13 @@ final class IfConfigTests: PrettyPrintTestCase {
277277
"""
278278
VStack {
279279
Text("something")
280-
#if os(iOS)
281-
.iOSSpecificModifier()
282-
.anotherModifier()
283-
.anotherAnotherModifier()
284-
#endif
285-
.commonModifier()
286-
.anotherCommonModifier()
280+
#if os(iOS)
281+
.iOSSpecificModifier()
282+
.anotherModifier()
283+
.anotherAnotherModifier()
284+
#endif
285+
.commonModifier()
286+
.anotherCommonModifier()
287287
}
288288
289289
"""
@@ -311,14 +311,14 @@ final class IfConfigTests: PrettyPrintTestCase {
311311
"""
312312
VStack {
313313
Text("something")
314-
#if os(iOS) || os(watchOS)
315-
#if os(iOS)
316-
.iOSModifier()
317-
#else
318-
.watchOSModifier()
314+
#if os(iOS) || os(watchOS)
315+
#if os(iOS)
316+
.iOSModifier()
317+
#else
318+
.watchOSModifier()
319+
#endif
320+
.iOSAndWatchOSModifier()
319321
#endif
320-
.iOSAndWatchOSModifier()
321-
#endif
322322
}
323323
324324
"""
@@ -343,10 +343,10 @@ final class IfConfigTests: PrettyPrintTestCase {
343343
"""
344344
VStack {
345345
textView
346-
#if os(iOS)
347-
.iOSSpecificModifier()
348-
#endif
349-
.commonModifier()
346+
#if os(iOS)
347+
.iOSSpecificModifier()
348+
#endif
349+
.commonModifier()
350350
}
351351
352352
"""
@@ -390,4 +390,68 @@ final class IfConfigTests: PrettyPrintTestCase {
390390

391391
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
392392
}
393+
394+
func testPostfixPoundIfBetweenOtherModifiers() {
395+
let input =
396+
"""
397+
EmptyView()
398+
.padding([.vertical])
399+
#if os(iOS)
400+
.iOSSpecificModifier()
401+
#endif
402+
.commonModifier()
403+
"""
404+
405+
let expected =
406+
"""
407+
EmptyView()
408+
.padding([.vertical])
409+
#if os(iOS)
410+
.iOSSpecificModifier()
411+
#endif
412+
.commonModifier()
413+
414+
"""
415+
416+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
417+
}
418+
419+
func testPostfixPoundIfWithTypeInModifier() {
420+
let input =
421+
"""
422+
EmptyView()
423+
.padding([.vertical])
424+
#if os(iOS)
425+
.iOSSpecificModifier(
426+
SpecificType()
427+
.onChanged { _ in
428+
// do things
429+
}
430+
.onEnded { _ in
431+
// do things
432+
}
433+
)
434+
#endif
435+
"""
436+
437+
let expected =
438+
"""
439+
EmptyView()
440+
.padding([.vertical])
441+
#if os(iOS)
442+
.iOSSpecificModifier(
443+
SpecificType()
444+
.onChanged { _ in
445+
// do things
446+
}
447+
.onEnded { _ in
448+
// do things
449+
}
450+
)
451+
#endif
452+
453+
"""
454+
455+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
456+
}
393457
}

0 commit comments

Comments
 (0)