Skip to content

Commit

Permalink
Add fix and tests for postfix pound ifs (#383)
Browse files Browse the repository at this point in the history
Add fix and tests for postfix pound ifs

Co-authored-by: David Brunow <>
  • Loading branch information
DavidBrunow committed Aug 22, 2022
1 parent 0874463 commit 7216a18
Show file tree
Hide file tree
Showing 2 changed files with 188 additions and 2 deletions.
30 changes: 28 additions & 2 deletions Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift
Expand Up @@ -1307,7 +1307,15 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
before(tokenToOpenWith.nextToken, tokens: .break(breakKindClose, newlines: .soft), .close)
}

if let condition = node.condition {
if isNestedInPostfixIfConfig(node: Syntax(node)) {
before(
node.firstToken,
tokens: [
.printerControl(kind: .enableBreaking),
.break(.reset),
]
)
} else if let condition = node.condition {
before(condition.firstToken, tokens: .printerControl(kind: .disableBreaking))
after(
condition.lastToken,
Expand Down Expand Up @@ -3459,7 +3467,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {

if let calledMemberAccessExpr = calledExpression.as(MemberAccessExprSyntax.self) {
if calledMemberAccessExpr.base != nil {
before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)])
if isNestedInPostfixIfConfig(node: Syntax(calledMemberAccessExpr)) {
before(calledMemberAccessExpr.dot, tokens: [.break(.same, size: 0)])
} else {
before(calledMemberAccessExpr.dot, tokens: [.break(.contextual, size: 0)])
}
}
before(calledMemberAccessExpr.dot, tokens: beforeTokens)
after(expr.lastToken, tokens: afterTokens)
Expand All @@ -3484,6 +3496,20 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
}
}

private func isNestedInPostfixIfConfig(node: Syntax) -> Bool {
var this: Syntax? = node

while this?.parent != nil {
if this?.parent?.is(PostfixIfConfigExprSyntax.self) == true {
return true
}

this = this?.parent
}

return false
}

extension Syntax {
/// Creates a pretty-printable token stream for the provided Syntax node.
func makeTokenStream(configuration: Configuration, operatorContext: OperatorContext) -> [Token] {
Expand Down
160 changes: 160 additions & 0 deletions Tests/SwiftFormatPrettyPrintTests/IfConfigTests.swift
Expand Up @@ -230,4 +230,164 @@ final class IfConfigTests: PrettyPrintTestCase {

assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
}

func testPostfixPoundIfAfterParentheses() {
let input =
"""
VStack {
Text("something")
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
}
"""

let expected =
"""
VStack {
Text("something")
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
}
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
}

func testPostfixPoundIfAfterParenthesesMultipleMembers() {
let input =
"""
VStack {
Text("something")
#if os(iOS)
.iOSSpecificModifier()
.anotherModifier()
.anotherAnotherModifier()
#endif
.commonModifier()
.anotherCommonModifier()
}
"""

let expected =
"""
VStack {
Text("something")
#if os(iOS)
.iOSSpecificModifier()
.anotherModifier()
.anotherAnotherModifier()
#endif
.commonModifier()
.anotherCommonModifier()
}
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
}

func testPostfixPoundIfNested() {
let input =
"""
VStack {
Text("something")
#if os(iOS) || os(watchOS)
#if os(iOS)
.iOSModifier()
#else
.watchOSModifier()
#endif
.iOSAndWatchOSModifier()
#endif
}
"""

let expected =
"""
VStack {
Text("something")
#if os(iOS) || os(watchOS)
#if os(iOS)
.iOSModifier()
#else
.watchOSModifier()
#endif
.iOSAndWatchOSModifier()
#endif
}
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
}


func testPostfixPoundIfAfterVariables() {
let input =
"""
VStack {
textView
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
}
"""

let expected =
"""
VStack {
textView
#if os(iOS)
.iOSSpecificModifier()
#endif
.commonModifier()
}
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
}

func testPostfixPoundIfAfterClosingBrace() {
let input =
"""
HStack {
Toggle(isOn: binding) {
Text("Some text")
}
#if !os(tvOS)
.toggleStyle(SwitchToggleStyle(tint: Color.blue))
#endif
.accessibilityValue(
binding.wrappedValue == true ? "On" : "Off"
)
}
"""

let expected =
"""
HStack {
Toggle(isOn: binding) {
Text("Some text")
}
#if !os(tvOS)
.toggleStyle(
SwitchToggleStyle(tint: Color.blue))
#endif
.accessibilityValue(
binding.wrappedValue == true
? "On" : "Off"
)
}
"""

assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
}
}

0 comments on commit 7216a18

Please sign in to comment.