Skip to content

Commit 7216a18

Browse files
authored
Add fix and tests for postfix pound ifs (swiftlang#383)
Add fix and tests for postfix pound ifs Co-authored-by: David Brunow <>
1 parent 0874463 commit 7216a18

File tree

2 files changed

+188
-2
lines changed

2 files changed

+188
-2
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,7 +1307,15 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
13071307
before(tokenToOpenWith.nextToken, tokens: .break(breakKindClose, newlines: .soft), .close)
13081308
}
13091309

1310-
if let condition = node.condition {
1310+
if isNestedInPostfixIfConfig(node: Syntax(node)) {
1311+
before(
1312+
node.firstToken,
1313+
tokens: [
1314+
.printerControl(kind: .enableBreaking),
1315+
.break(.reset),
1316+
]
1317+
)
1318+
} else if let condition = node.condition {
13111319
before(condition.firstToken, tokens: .printerControl(kind: .disableBreaking))
13121320
after(
13131321
condition.lastToken,
@@ -3459,7 +3467,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
34593467

34603468
if let calledMemberAccessExpr = calledExpression.as(MemberAccessExprSyntax.self) {
34613469
if calledMemberAccessExpr.base != nil {
3462-
before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)])
3470+
if isNestedInPostfixIfConfig(node: Syntax(calledMemberAccessExpr)) {
3471+
before(calledMemberAccessExpr.dot, tokens: [.break(.same, size: 0)])
3472+
} else {
3473+
before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)])
3474+
}
34633475
}
34643476
before(calledMemberAccessExpr.dot, tokens: beforeTokens)
34653477
after(expr.lastToken, tokens: afterTokens)
@@ -3484,6 +3496,20 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
34843496
}
34853497
}
34863498

3499+
private func isNestedInPostfixIfConfig(node: Syntax) -> Bool {
3500+
var this: Syntax? = node
3501+
3502+
while this?.parent != nil {
3503+
if this?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
3504+
return true
3505+
}
3506+
3507+
this = this?.parent
3508+
}
3509+
3510+
return false
3511+
}
3512+
34873513
extension Syntax {
34883514
/// Creates a pretty-printable token stream for the provided Syntax node.
34893515
func makeTokenStream(configuration: Configuration, operatorContext: OperatorContext) -> [Token] {

Tests/SwiftFormatPrettyPrintTests/IfConfigTests.swift

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,164 @@ final class IfConfigTests: PrettyPrintTestCase {
230230

231231
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
232232
}
233+
234+
func testPostfixPoundIfAfterParentheses() {
235+
let input =
236+
"""
237+
VStack {
238+
Text("something")
239+
#if os(iOS)
240+
.iOSSpecificModifier()
241+
#endif
242+
.commonModifier()
243+
}
244+
"""
245+
246+
let expected =
247+
"""
248+
VStack {
249+
Text("something")
250+
#if os(iOS)
251+
.iOSSpecificModifier()
252+
#endif
253+
.commonModifier()
254+
}
255+
256+
"""
257+
258+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
259+
}
260+
261+
func testPostfixPoundIfAfterParenthesesMultipleMembers() {
262+
let input =
263+
"""
264+
VStack {
265+
Text("something")
266+
#if os(iOS)
267+
.iOSSpecificModifier()
268+
.anotherModifier()
269+
.anotherAnotherModifier()
270+
#endif
271+
.commonModifier()
272+
.anotherCommonModifier()
273+
}
274+
"""
275+
276+
let expected =
277+
"""
278+
VStack {
279+
Text("something")
280+
#if os(iOS)
281+
.iOSSpecificModifier()
282+
.anotherModifier()
283+
.anotherAnotherModifier()
284+
#endif
285+
.commonModifier()
286+
.anotherCommonModifier()
287+
}
288+
289+
"""
290+
291+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
292+
}
293+
294+
func testPostfixPoundIfNested() {
295+
let input =
296+
"""
297+
VStack {
298+
Text("something")
299+
#if os(iOS) || os(watchOS)
300+
#if os(iOS)
301+
.iOSModifier()
302+
#else
303+
.watchOSModifier()
304+
#endif
305+
.iOSAndWatchOSModifier()
306+
#endif
307+
}
308+
"""
309+
310+
let expected =
311+
"""
312+
VStack {
313+
Text("something")
314+
#if os(iOS) || os(watchOS)
315+
#if os(iOS)
316+
.iOSModifier()
317+
#else
318+
.watchOSModifier()
319+
#endif
320+
.iOSAndWatchOSModifier()
321+
#endif
322+
}
323+
324+
"""
325+
326+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
327+
}
328+
329+
330+
func testPostfixPoundIfAfterVariables() {
331+
let input =
332+
"""
333+
VStack {
334+
textView
335+
#if os(iOS)
336+
.iOSSpecificModifier()
337+
#endif
338+
.commonModifier()
339+
}
340+
"""
341+
342+
let expected =
343+
"""
344+
VStack {
345+
textView
346+
#if os(iOS)
347+
.iOSSpecificModifier()
348+
#endif
349+
.commonModifier()
350+
}
351+
352+
"""
353+
354+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
355+
}
356+
357+
func testPostfixPoundIfAfterClosingBrace() {
358+
let input =
359+
"""
360+
HStack {
361+
Toggle(isOn: binding) {
362+
Text("Some text")
363+
}
364+
#if !os(tvOS)
365+
.toggleStyle(SwitchToggleStyle(tint: Color.blue))
366+
#endif
367+
.accessibilityValue(
368+
binding.wrappedValue == true ? "On" : "Off"
369+
)
370+
}
371+
"""
372+
373+
let expected =
374+
"""
375+
HStack {
376+
Toggle(isOn: binding) {
377+
Text("Some text")
378+
}
379+
#if !os(tvOS)
380+
.toggleStyle(
381+
SwitchToggleStyle(tint: Color.blue))
382+
#endif
383+
.accessibilityValue(
384+
binding.wrappedValue == true
385+
? "On" : "Off"
386+
)
387+
}
388+
389+
"""
390+
391+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
392+
}
233393
}

0 commit comments

Comments
 (0)