Skip to content

Commit 9ef9e05

Browse files
committed
Visit child nodes in NoParensAroundConditions rule.
Without visiting the child nodes, the rule wasn't applied to nested nodes meaning parens wouldn't be removed.
1 parent e2c5240 commit 9ef9e05

File tree

2 files changed

+135
-9
lines changed

2 files changed

+135
-9
lines changed

Sources/SwiftFormatRules/NoParensAroundConditions.swift

+21-9
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,36 @@ public final class NoParensAroundConditions: SyntaxFormatRule {
4040
$0.highlight(expr.sourceRange(converter: self.context.sourceLocationConverter))
4141
}
4242

43+
guard
44+
let visitedTuple = visit(tuple).as(TupleExprSyntax.self),
45+
let visitedExpr = visitedTuple.elementList.first?.expression
46+
else {
47+
return expr
48+
}
4349
return replaceTrivia(
44-
on: expr,
45-
token: expr.lastToken,
46-
leadingTrivia: tuple.leftParen.leadingTrivia,
47-
trailingTrivia: tuple.rightParen.trailingTrivia
50+
on: visitedExpr,
51+
token: visitedExpr.lastToken,
52+
leadingTrivia: visitedTuple.leftParen.leadingTrivia,
53+
trailingTrivia: visitedTuple.rightParen.trailingTrivia
4854
)
4955
}
5056

5157
public override func visit(_ node: IfStmtSyntax) -> StmtSyntax {
5258
let conditions = visit(node.conditions).as(ConditionElementListSyntax.self)!
53-
let result = node.withIfKeyword(node.ifKeyword.withOneTrailingSpace())
59+
var result = node.withIfKeyword(node.ifKeyword.withOneTrailingSpace())
5460
.withConditions(conditions)
61+
.withBody(CodeBlockSyntax(visit(node.body)))
62+
if let elseBody = node.elseBody {
63+
result = result.withElseBody(visit(elseBody))
64+
}
5565
return StmtSyntax(result)
5666
}
5767

5868
public override func visit(_ node: ConditionElementSyntax) -> Syntax {
5969
guard let tup = node.condition.as(TupleExprSyntax.self),
6070
tup.elementList.firstAndOnly != nil
6171
else {
62-
return Syntax(node)
72+
return super.visit(node)
6373
}
6474
return Syntax(node.withCondition(Syntax(extractExpr(tup))))
6575
}
@@ -69,19 +79,21 @@ public final class NoParensAroundConditions: SyntaxFormatRule {
6979
guard let tup = node.expression.as(TupleExprSyntax.self),
7080
tup.elementList.firstAndOnly != nil
7181
else {
72-
return StmtSyntax(node)
82+
return super.visit(node)
7383
}
74-
return StmtSyntax(node.withExpression(extractExpr(tup)))
84+
return StmtSyntax(
85+
node.withExpression(extractExpr(tup)).withCases(SwitchCaseListSyntax(visit(node.cases))))
7586
}
7687

7788
public override func visit(_ node: RepeatWhileStmtSyntax) -> StmtSyntax {
7889
guard let tup = node.condition.as(TupleExprSyntax.self),
7990
tup.elementList.firstAndOnly != nil
8091
else {
81-
return StmtSyntax(node)
92+
return super.visit(node)
8293
}
8394
let newNode = node.withCondition(extractExpr(tup))
8495
.withWhileKeyword(node.whileKeyword.withOneTrailingSpace())
96+
.withBody(CodeBlockSyntax(visit(node.body)))
8597
return StmtSyntax(newNode)
8698
}
8799
}

Tests/SwiftFormatRulesTests/NoParensAroundConditionsTests.swift

+114
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,118 @@ final class NoParensAroundConditionsTests: LintOrFormatRuleTestCase {
2121
switch 4 { default: break }
2222
""")
2323
}
24+
25+
func testParensAroundNestedParenthesizedStatements() {
26+
XCTAssertFormatting(
27+
NoParensAroundConditions.self,
28+
input: """
29+
switch (a) {
30+
case 1:
31+
switch (b) {
32+
default: break
33+
}
34+
}
35+
if (x) {
36+
if (y) {
37+
} else if (z) {
38+
} else {
39+
}
40+
} else if (w) {
41+
}
42+
while (x) {
43+
while (y) {}
44+
}
45+
guard (x), (y), (x == 3) else {
46+
guard (a), (b), (c == x) else {
47+
return
48+
}
49+
return
50+
}
51+
repeat {
52+
repeat {
53+
} while (y)
54+
} while(x)
55+
if (foo.someCall({ if (x) {} })) {}
56+
""",
57+
expected: """
58+
switch a {
59+
case 1:
60+
switch b {
61+
default: break
62+
}
63+
}
64+
if x {
65+
if y {
66+
} else if z {
67+
} else {
68+
}
69+
} else if w {
70+
}
71+
while x {
72+
while y {}
73+
}
74+
guard x, y, x == 3 else {
75+
guard a, b, c == x else {
76+
return
77+
}
78+
return
79+
}
80+
repeat {
81+
repeat {
82+
} while y
83+
} while x
84+
if foo.someCall({ if x {} }) {}
85+
""")
86+
}
87+
88+
func testParensAroundNestedUnparenthesizedStatements() {
89+
XCTAssertFormatting(
90+
NoParensAroundConditions.self,
91+
input: """
92+
switch b {
93+
case 2:
94+
switch (d) {
95+
default: break
96+
}
97+
}
98+
if x {
99+
if (y) {
100+
} else if (z) {
101+
} else {
102+
}
103+
} else if (w) {
104+
}
105+
while x {
106+
while (y) {}
107+
}
108+
repeat {
109+
repeat {
110+
} while (y)
111+
} while x
112+
if foo.someCall({ if (x) {} }) {}
113+
""",
114+
expected: """
115+
switch b {
116+
case 2:
117+
switch d {
118+
default: break
119+
}
120+
}
121+
if x {
122+
if y {
123+
} else if z {
124+
} else {
125+
}
126+
} else if w {
127+
}
128+
while x {
129+
while y {}
130+
}
131+
repeat {
132+
repeat {
133+
} while y
134+
} while x
135+
if foo.someCall({ if x {} }) {}
136+
""")
137+
}
24138
}

0 commit comments

Comments
 (0)