Skip to content

Commit 4b82587

Browse files
authored
Merge pull request swiftlang#174 from dabelknap/closures
Add closure captures, and allow for bodiless closures.
2 parents 3437e7a + 60c11a1 commit 4b82587

File tree

3 files changed

+88
-15
lines changed

3 files changed

+88
-15
lines changed

Sources/SwiftFormatPrettyPrint/PrettyPrint.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ public class PrettyPrinter {
465465
print("[SPACE Size: \(size) Length: \(length)]")
466466

467467
case .reset:
468+
printDebugIndent()
468469
print("[RESET]")
469470

470471
case .comment(let comment):

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -200,27 +200,29 @@ private final class TokenStreamCreator: SyntaxVisitor {
200200

201201
override func visit(_ node: FunctionCallArgumentSyntax) {
202202
after(node.colon, tokens: .break)
203-
204-
before(node.firstToken, tokens: .open)
205-
if let trailingComma = node.trailingComma {
206-
after(trailingComma, tokens: .close, .break)
207-
} else {
208-
after(node.lastToken, tokens: .close)
209-
}
210-
super.visit(node)
203+
before(node.firstToken, tokens: .open)
204+
if let trailingComma = node.trailingComma {
205+
after(trailingComma, tokens: .close, .break)
206+
} else {
207+
after(node.lastToken, tokens: .close)
208+
}
209+
super.visit(node)
211210
}
212211

213212
override func visit(_ node: ClosureExprSyntax) {
214213
before(node.firstToken, tokens: .reset)
215214
if let signature = node.signature {
216215
before(signature.firstToken, tokens: .break(offset: 2))
217-
before(node.statements.firstToken, tokens: .newline(offset: 2), .open(.consistent, 0))
216+
if node.statements.count > 0 {
217+
after(signature.inTok, tokens: .newline(offset: 2), .open(.consistent, 0))
218+
} else {
219+
after(signature.inTok, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
220+
}
218221
before(node.rightBrace, tokens: .break(offset: -2), .close)
219222
} else {
220-
before(node.statements.firstToken, tokens: .break(offset: 2), .open(.consistent, 0))
223+
after(node.leftBrace, tokens: .break(offset: 2), .open(.consistent, 0))
221224
before(node.rightBrace, tokens: .break(offset: -2), .close)
222225
}
223-
224226
super.visit(node)
225227
}
226228

@@ -230,19 +232,33 @@ private final class TokenStreamCreator: SyntaxVisitor {
230232
}
231233

232234
override func visit(_ node: ClosureSignatureSyntax) {
233-
before(node.firstToken, tokens: .open(.inconsistent, 2))
234-
after(node.input?.lastToken, tokens: .break)
235+
before(node.firstToken, tokens: .open(.inconsistent, 0))
236+
after(node.capture?.lastToken, tokens: .break)
237+
before(node.input?.firstToken, tokens: .open)
238+
after(node.input?.lastToken, tokens: .close, .break)
235239
after(node.output?.lastToken, tokens: .break)
236240
after(node.throwsTok, tokens: .break)
237241
after(node.lastToken, tokens: .close)
238242
super.visit(node)
239243
}
240244

241245
override func visit(_ node: ClosureCaptureSignatureSyntax) {
246+
after(node.leftSquare, tokens: .break(size: 0, offset: 2), .open(.consistent, 0))
247+
before(node.rightSquare, tokens: .break(size: 0, offset: -2), .close)
242248
super.visit(node)
243249
}
244250

245251
override func visit(_ node: ClosureCaptureItemSyntax) {
252+
before(node.firstToken, tokens: .open)
253+
after(node.specifier?.lastToken, tokens: .break)
254+
before(node.assignToken, tokens: .break)
255+
after(node.assignToken, tokens: .break)
256+
if let trailingComma = node.trailingComma {
257+
before(trailingComma, tokens: .close)
258+
after(trailingComma, tokens: .break)
259+
} else {
260+
after(node.lastToken, tokens: .close)
261+
}
246262
super.visit(node)
247263
}
248264

@@ -1398,7 +1414,7 @@ private final class TokenStreamCreator: SyntaxVisitor {
13981414
if index > 0 || isStartOfFile {
13991415
if token.withoutTrivia().text == "}" {
14001416
if let previousToken = token.previousToken,
1401-
previousToken.withoutTrivia().text == "{" {
1417+
(["{", "in"].contains { $0 == previousToken.withoutTrivia().text }) {
14021418
// do nothing
14031419
} else {
14041420
appendToken(.newline)

Tests/SwiftFormatPrettyPrintTests/FunctionCallTests.swift

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class FunctionCallTests: PrettyPrintTestCase {
7575
})
7676
funcCall(closure: {
7777
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10
78-
in
78+
in
7979
return s1
8080
})
8181
funcCall(
@@ -164,4 +164,60 @@ public class FunctionCallTests: PrettyPrintTestCase {
164164

165165
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
166166
}
167+
168+
public func testClosureCapture() {
169+
let input =
170+
"""
171+
let a = funcCall() { [weak self] (a: Int) in
172+
return a + 1
173+
}
174+
let a = funcCall() { [weak self, weak a = self.b] (a: Int) in
175+
return a + 1
176+
}
177+
let b = funcCall() { [unowned self, weak delegate = self.delegate!] (a: Int, b: String) -> String in
178+
return String(a) + b
179+
}
180+
"""
181+
182+
let expected =
183+
"""
184+
let a = funcCall() { [weak self] (a: Int) in
185+
return a + 1
186+
}
187+
let a = funcCall() {
188+
[weak self, weak a = self.b] (a: Int) in
189+
return a + 1
190+
}
191+
let b = funcCall() {
192+
[unowned self, weak delegate = self.delegate!]
193+
(a: Int, b: String) -> String in
194+
return String(a) + b
195+
}
196+
197+
"""
198+
199+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
200+
}
201+
202+
public func testBodilessClosure() {
203+
let input =
204+
"""
205+
let a = funcCall() { s1, s2 in
206+
// Move along, nothing here to see
207+
}
208+
let a = funcCall() { s1, s2 in }
209+
"""
210+
211+
212+
let expected =
213+
"""
214+
let a = funcCall() { s1, s2 in
215+
// Move along, nothing here to see
216+
}
217+
let a = funcCall() { s1, s2 in }
218+
219+
"""
220+
221+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
222+
}
167223
}

0 commit comments

Comments
 (0)