Skip to content

Commit e56a218

Browse files
authored
Merge pull request swiftlang#199 from dabelknap/fix-closures
Fix an issue where closures unindent at the start of lines
2 parents da7b3a4 + a11f634 commit e56a218

File tree

3 files changed

+195
-174
lines changed

3 files changed

+195
-174
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -709,7 +709,7 @@ private final class TokenStreamCreator: SyntaxVisitor {
709709
after(node.leftParen, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
710710
before(node.rightParen, tokens: .break(size: 0, offset: -2), .close)
711711
}
712-
before(node.trailingClosure?.leftBrace, tokens: .space)
712+
before(node.trailingClosure?.leftBrace, tokens: .space, .reset)
713713
super.visit(node)
714714
}
715715

@@ -725,7 +725,6 @@ private final class TokenStreamCreator: SyntaxVisitor {
725725
}
726726

727727
override func visit(_ node: ClosureExprSyntax) {
728-
before(node.firstToken, tokens: .reset)
729728
if let signature = node.signature {
730729
before(signature.firstToken, tokens: .break(offset: 2))
731730
if node.statements.count > 0 {
@@ -734,7 +733,7 @@ private final class TokenStreamCreator: SyntaxVisitor {
734733
after(signature.inTok, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
735734
}
736735
before(node.rightBrace, tokens: .break(offset: -2), .close)
737-
} else {
736+
} else if node.statements.count > 0 {
738737
after(node.leftBrace, tokens: .break(offset: 2), .open(.consistent, 0))
739738
before(node.rightBrace, tokens: .break(offset: -2), .close)
740739
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
public class ClosureExprTests: PrettyPrintTestCase {
2+
public func testBasicFunctionClosures() {
3+
let input =
4+
"""
5+
funcCall(closure: <)
6+
funcCall(closure: { 4 })
7+
funcCall(closure: { $0 < $1 })
8+
funcCall(closure: { s1, s2 in s1 < s2 })
9+
funcCall(closure: { s1, s2 in return s1 < s2})
10+
funcCall(closure: { s1, s2, s3, s4, s5, s6 in return s1})
11+
funcCall(closure: { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 in return s1 })
12+
funcCall(param1: 123, closure: { s1, s2, s3 in return s1 })
13+
funcCall(closure: { (s1: String, s2: String) -> Bool in return s1 > s2 })
14+
"""
15+
16+
let expected =
17+
"""
18+
funcCall(closure: <)
19+
funcCall(closure: { 4 })
20+
funcCall(closure: { $0 < $1 })
21+
funcCall(closure: { s1, s2 in
22+
s1 < s2
23+
})
24+
funcCall(closure: { s1, s2 in
25+
return s1 < s2
26+
})
27+
funcCall(closure: {
28+
s1, s2, s3, s4, s5, s6 in
29+
return s1
30+
})
31+
funcCall(closure: {
32+
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10
33+
in
34+
return s1
35+
})
36+
funcCall(
37+
param1: 123,
38+
closure: { s1, s2, s3 in
39+
return s1
40+
}
41+
)
42+
funcCall(closure: {
43+
(s1: String, s2: String) -> Bool in
44+
return s1 > s2
45+
})
46+
47+
"""
48+
49+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 42)
50+
}
51+
52+
public func testTrailingClosure() {
53+
let input =
54+
"""
55+
funcCall() { $1 < $2 }
56+
funcCall(param1: 2) { $1 < $2 }
57+
funcCall(param1: 2) { s1, s2, s3 in return s1}
58+
funcCall(param1: 2) { s1, s2, s3, s4, s5 in return s1}
59+
"""
60+
61+
let expected =
62+
"""
63+
funcCall() { $1 < $2 }
64+
funcCall(param1: 2) { $1 < $2 }
65+
funcCall(param1: 2) { s1, s2, s3 in
66+
return s1
67+
}
68+
funcCall(param1: 2) {
69+
s1, s2, s3, s4, s5 in
70+
return s1
71+
}
72+
73+
"""
74+
75+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
76+
}
77+
78+
public func testClosuresWithIfs() {
79+
let input =
80+
"""
81+
let a = afunc() {
82+
if condition1 {
83+
return true
84+
}
85+
return false
86+
}
87+
88+
let a = afunc() {
89+
if condition1 {
90+
return true
91+
}
92+
if condition2 {
93+
return true
94+
}
95+
return false
96+
}
97+
"""
98+
99+
let expected =
100+
"""
101+
let a = afunc() {
102+
if condition1 { return true }
103+
return false
104+
}
105+
106+
let a = afunc() {
107+
if condition1 { return true }
108+
if condition2 { return true }
109+
return false
110+
}
111+
112+
"""
113+
114+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
115+
}
116+
117+
public func testClosureCapture() {
118+
let input =
119+
"""
120+
let a = funcCall() { [weak self] (a: Int) in
121+
return a + 1
122+
}
123+
let a = funcCall() { [weak self, weak a = self.b] (a: Int) in
124+
return a + 1
125+
}
126+
let b = funcCall() { [unowned self, weak delegate = self.delegate!] (a: Int, b: String) -> String in
127+
return String(a) + b
128+
}
129+
"""
130+
131+
let expected =
132+
"""
133+
let a = funcCall() { [weak self] (a: Int) in
134+
return a + 1
135+
}
136+
let a = funcCall() {
137+
[weak self, weak a = self.b] (a: Int) in
138+
return a + 1
139+
}
140+
let b = funcCall() {
141+
[unowned self, weak delegate = self.delegate!]
142+
(a: Int, b: String) -> String in
143+
return String(a) + b
144+
}
145+
146+
"""
147+
148+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
149+
}
150+
151+
public func testBodilessClosure() {
152+
let input =
153+
"""
154+
let a = funcCall() { s1, s2 in
155+
// Move along, nothing here to see
156+
}
157+
let a = funcCall() { s1, s2 in }
158+
let a = funcCall() {}
159+
"""
160+
161+
162+
let expected =
163+
"""
164+
let a = funcCall() { s1, s2 in
165+
// Move along, nothing here to see
166+
}
167+
let a = funcCall() { s1, s2 in }
168+
let a = funcCall() {}
169+
170+
"""
171+
172+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
173+
}
174+
175+
public func testArrayClosures() {
176+
let input =
177+
"""
178+
let a = [ { a, b in someFunc(a, b) } ]
179+
"""
180+
181+
let expected =
182+
"""
183+
let a = [
184+
{ a, b in
185+
someFunc(a, b)
186+
}
187+
]
188+
189+
"""
190+
191+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
192+
}
193+
}

Tests/SwiftFormatPrettyPrintTests/FunctionCallTests.swift

Lines changed: 0 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -43,175 +43,4 @@ public class FunctionCallTests: PrettyPrintTestCase {
4343

4444
assertPrettyPrintEqual(input: input, expected: expected, linelength: 45)
4545
}
46-
47-
public func testBasicFunctionClosures() {
48-
let input =
49-
"""
50-
funcCall(closure: <)
51-
funcCall(closure: { 4 })
52-
funcCall(closure: { $0 < $1 })
53-
funcCall(closure: { s1, s2 in s1 < s2 })
54-
funcCall(closure: { s1, s2 in return s1 < s2})
55-
funcCall(closure: { s1, s2, s3, s4, s5, s6 in return s1})
56-
funcCall(closure: { s1, s2, s3, s4, s5, s6, s7, s8, s9, s10 in return s1 })
57-
funcCall(param1: 123, closure: { s1, s2, s3 in return s1 })
58-
funcCall(closure: { (s1: String, s2: String) -> Bool in return s1 > s2 })
59-
"""
60-
61-
let expected =
62-
"""
63-
funcCall(closure: <)
64-
funcCall(closure: { 4 })
65-
funcCall(closure: { $0 < $1 })
66-
funcCall(closure: { s1, s2 in
67-
s1 < s2
68-
})
69-
funcCall(closure: { s1, s2 in
70-
return s1 < s2
71-
})
72-
funcCall(closure: {
73-
s1, s2, s3, s4, s5, s6 in
74-
return s1
75-
})
76-
funcCall(closure: {
77-
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10
78-
in
79-
return s1
80-
})
81-
funcCall(
82-
param1: 123,
83-
closure: { s1, s2, s3 in
84-
return s1
85-
}
86-
)
87-
funcCall(closure: {
88-
(s1: String, s2: String) -> Bool in
89-
return s1 > s2
90-
})
91-
92-
"""
93-
94-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 42)
95-
}
96-
97-
public func testTrailingClosure() {
98-
let input =
99-
"""
100-
funcCall() { $1 < $2 }
101-
funcCall(param1: 2) { $1 < $2 }
102-
funcCall(param1: 2) { s1, s2, s3 in return s1}
103-
funcCall(param1: 2) { s1, s2, s3, s4, s5 in return s1}
104-
"""
105-
106-
let expected =
107-
"""
108-
funcCall() { $1 < $2 }
109-
funcCall(param1: 2) { $1 < $2 }
110-
funcCall(param1: 2) { s1, s2, s3 in
111-
return s1
112-
}
113-
funcCall(param1: 2) {
114-
s1, s2, s3, s4, s5 in
115-
return s1
116-
}
117-
118-
"""
119-
120-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
121-
}
122-
123-
public func testClosuresWithIfs() {
124-
let input =
125-
"""
126-
let a = afunc() {
127-
if condition1 {
128-
return true
129-
}
130-
return false
131-
}
132-
133-
let a = afunc() {
134-
if condition1 {
135-
return true
136-
}
137-
if condition2 {
138-
return true
139-
}
140-
return false
141-
}
142-
"""
143-
144-
let expected =
145-
"""
146-
let a = afunc() {
147-
if condition1 { return true }
148-
return false
149-
}
150-
151-
let a = afunc() {
152-
if condition1 { return true }
153-
if condition2 { return true }
154-
return false
155-
}
156-
157-
"""
158-
159-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
160-
}
161-
162-
public func testClosureCapture() {
163-
let input =
164-
"""
165-
let a = funcCall() { [weak self] (a: Int) in
166-
return a + 1
167-
}
168-
let a = funcCall() { [weak self, weak a = self.b] (a: Int) in
169-
return a + 1
170-
}
171-
let b = funcCall() { [unowned self, weak delegate = self.delegate!] (a: Int, b: String) -> String in
172-
return String(a) + b
173-
}
174-
"""
175-
176-
let expected =
177-
"""
178-
let a = funcCall() { [weak self] (a: Int) in
179-
return a + 1
180-
}
181-
let a = funcCall() {
182-
[weak self, weak a = self.b] (a: Int) in
183-
return a + 1
184-
}
185-
let b = funcCall() {
186-
[unowned self, weak delegate = self.delegate!]
187-
(a: Int, b: String) -> String in
188-
return String(a) + b
189-
}
190-
191-
"""
192-
193-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
194-
}
195-
196-
public func testBodilessClosure() {
197-
let input =
198-
"""
199-
let a = funcCall() { s1, s2 in
200-
// Move along, nothing here to see
201-
}
202-
let a = funcCall() { s1, s2 in }
203-
"""
204-
205-
206-
let expected =
207-
"""
208-
let a = funcCall() { s1, s2 in
209-
// Move along, nothing here to see
210-
}
211-
let a = funcCall() { s1, s2 in }
212-
213-
"""
214-
215-
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
216-
}
21746
}

0 commit comments

Comments
 (0)