Skip to content

Commit ab9ad2f

Browse files
committed
Add open breaks around type annotations in optional condition exprs.
This matches the breaks and grouping used by pattern binding syntax nodes (i.e. let and var expressions) so that the formatting of a let in a guard/if stmt will have the same formatting as an identical let/var expression outside of a guard/if stmt. This fixes an issue where there was no space between the ":" and the type annotation when the let in an optional condition included a type annotation.
1 parent 0ed97ac commit ab9ad2f

File tree

5 files changed

+104
-0
lines changed

5 files changed

+104
-0
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1802,6 +1802,12 @@ private final class TokenStreamCreator: SyntaxVisitor {
18021802

18031803
func visit(_ node: OptionalBindingConditionSyntax) -> SyntaxVisitorContinueKind {
18041804
after(node.letOrVarKeyword, tokens: .break)
1805+
1806+
if let typeAnnotation = node.typeAnnotation {
1807+
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
1808+
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
1809+
}
1810+
18051811
return .visitChildren
18061812
}
18071813

Tests/SwiftFormatPrettyPrintTests/GuardStmtTests.swift

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,35 @@ public class GuardStmtTests: PrettyPrintTestCase {
163163

164164
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
165165
}
166+
167+
public func testOptionalBindingConditions() {
168+
let input =
169+
"""
170+
guard let someObject: Foo = object as? Int else {
171+
return nil
172+
}
173+
guard let someObject: (foo: Foo, bar: SomeVeryLongTypeNameThatBreaks, baz: Baz) = foo(a, b, c, d) else { return nil }
174+
"""
175+
176+
let expected =
177+
"""
178+
guard
179+
let someObject: Foo = object as? Int
180+
else {
181+
return nil
182+
}
183+
guard
184+
let someObject:
185+
(
186+
foo: Foo,
187+
bar:
188+
SomeVeryLongTypeNameThatBreaks,
189+
baz: Baz
190+
) = foo(a, b, c, d)
191+
else { return nil }
192+
193+
"""
194+
195+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
196+
}
166197
}

Tests/SwiftFormatPrettyPrintTests/IfStmtTests.swift

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,33 @@ public class IfStmtTests: PrettyPrintTestCase {
325325

326326
assertPrettyPrintEqual(input: input, expected: expected, linelength: 50)
327327
}
328+
329+
public func testOptionalBindingConditions() {
330+
let input =
331+
"""
332+
if let someObject: Foo = object as? Int {
333+
return nil
334+
}
335+
if let someObject: (foo: Foo, bar: SomeVeryLongTypeNameThatDefinitelyBreaks, baz: Baz) = foo(a, b, c, d) { return nil }
336+
"""
337+
338+
let expected =
339+
"""
340+
if let someObject: Foo = object as? Int
341+
{
342+
return nil
343+
}
344+
if let someObject:
345+
(
346+
foo: Foo,
347+
bar:
348+
SomeVeryLongTypeNameThatDefinitelyBreaks,
349+
baz: Baz
350+
) = foo(a, b, c, d)
351+
{ return nil }
352+
353+
"""
354+
355+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
356+
}
328357
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import SwiftFormatConfiguration
2+
3+
public class PatternBindingTests: PrettyPrintTestCase {
4+
public func testBindingIncludingTypeAnnotation() {
5+
let input =
6+
"""
7+
let someObject: Foo = object
8+
let someObject: (foo: Foo, bar: SomeVeryLongTypeNameThatDefinitelyBreaks, baz: Baz) = foo(a, b, c, d)
9+
"""
10+
11+
let expected =
12+
"""
13+
let someObject: Foo = object
14+
let someObject:
15+
(
16+
foo: Foo,
17+
bar:
18+
SomeVeryLongTypeNameThatDefinitelyBreaks,
19+
baz: Baz
20+
) = foo(a, b, c, d)
21+
22+
"""
23+
24+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
25+
}
26+
}

Tests/SwiftFormatPrettyPrintTests/XCTestManifests.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ extension GuardStmtTests {
302302
("testGuardStatement", testGuardStatement),
303303
("testGuardWithFuncCall", testGuardWithFuncCall),
304304
("testOpenBraceIsGluedToElseKeyword", testOpenBraceIsGluedToElseKeyword),
305+
("testOptionalBindingConditions", testOptionalBindingConditions),
305306
]
306307
}
307308

@@ -329,6 +330,7 @@ extension IfStmtTests {
329330
("testIfLetStatements", testIfLetStatements),
330331
("testIfStatement", testIfStatement),
331332
("testMatchingPatternConditions", testMatchingPatternConditions),
333+
("testOptionalBindingConditions", testOptionalBindingConditions),
332334
]
333335
}
334336

@@ -417,6 +419,15 @@ extension OperatorDeclTests {
417419
]
418420
}
419421

422+
extension PatternBindingTests {
423+
// DO NOT MODIFY: This is autogenerated, use:
424+
// `swift test --generate-linuxmain`
425+
// to regenerate.
426+
static let __allTests__PatternBindingTests = [
427+
("testBindingIncludingTypeAnnotation", testBindingIncludingTypeAnnotation),
428+
]
429+
}
430+
420431
extension ProtocolDeclTests {
421432
// DO NOT MODIFY: This is autogenerated, use:
422433
// `swift test --generate-linuxmain`
@@ -701,6 +712,7 @@ public func __allTests() -> [XCTestCaseEntry] {
701712
testCase(NewlineTests.__allTests__NewlineTests),
702713
testCase(ObjectLiteralExprTests.__allTests__ObjectLiteralExprTests),
703714
testCase(OperatorDeclTests.__allTests__OperatorDeclTests),
715+
testCase(PatternBindingTests.__allTests__PatternBindingTests),
704716
testCase(ProtocolDeclTests.__allTests__ProtocolDeclTests),
705717
testCase(RepeatStmtTests.__allTests__RepeatStmtTests),
706718
testCase(RespectsExistingLineBreaksTests.__allTests__RespectsExistingLineBreaksTests),

0 commit comments

Comments
 (0)