Skip to content

Commit 8fbc3f1

Browse files
dylansturgallevato
authored andcommitted
Add breaks around conditions of while-stmt.
This aligns the behavior of while-stmt and if-stmt conditions. The while-stmt conditions didn't have open-breaks, which meant there was no additional indentation nor would continuation breaks be able to stack. This can result in exceeding the max line length if a while-stmt has a label and first condition, up to its first break, that exceeds the remaining line length.
1 parent 0da09d0 commit 8fbc3f1

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

+13
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,19 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
526526
after(node.labelColon, tokens: .space)
527527
after(node.whileKeyword, tokens: .space)
528528

529+
// Add break groups, using open continuation breaks, around any conditions after the first so
530+
// that continuations inside of the conditions can stack in addition to continuations between
531+
// the conditions. There are no breaks around the first condition because there was historically
532+
// not break after the while token and adding such a break would cause excessive changes to
533+
// previously formatted code.
534+
// This has the side effect that the label + `while` + tokens up to the first break in the first
535+
// condition could be longer than the column limit since there are no breaks between the label
536+
// or while token.
537+
for condition in node.conditions.dropFirst() {
538+
before(condition.firstToken, tokens: .break(.open(kind: .continuation), size: 0))
539+
after(condition.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
540+
}
541+
529542
arrangeBracesAndContents(of: node.body, contentsKeyPath: \.statements)
530543

531544
return .visitChildren

Tests/SwiftFormatPrettyPrintTests/WhileStmtTests.swift

+54
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ final class WhileStmtTests: PrettyPrintTestCase {
6363
let a = 123
6464
var b = "abc"
6565
}
66+
myLabel: while myVeryLongFirstCondition && condition2 || condition3
67+
{
68+
let a = 123
69+
var b = "abc"
70+
}
6671
"""
6772

6873
let expected =
@@ -83,6 +88,55 @@ final class WhileStmtTests: PrettyPrintTestCase {
8388
let a = 123
8489
var b = "abc"
8590
}
91+
myLabel: while myVeryLongFirstCondition
92+
&& condition2 || condition3
93+
{
94+
let a = 123
95+
var b = "abc"
96+
}
97+
98+
"""
99+
100+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 29)
101+
}
102+
103+
func testWhileLoopMultipleConditionElements() {
104+
let input =
105+
"""
106+
while x >= 0 && y >= 0 && x < foo && y < bar, let object = foo.value(at: y), let otherObject = foo.value(at: x), isEqual(a, b) {
107+
foo()
108+
}
109+
while x >= 0 && y >= 0
110+
&& x < foo && y < bar,
111+
let object =
112+
foo.value(at: y),
113+
let otherObject = foo.value(at: x), isEqual(a, b) {
114+
foo()
115+
}
116+
"""
117+
118+
let expected =
119+
"""
120+
while x >= 0 && y >= 0
121+
&& x < foo && y < bar,
122+
let object = foo.value(
123+
at: y),
124+
let otherObject =
125+
foo.value(at: x),
126+
isEqual(a, b)
127+
{
128+
foo()
129+
}
130+
while x >= 0 && y >= 0
131+
&& x < foo && y < bar,
132+
let object =
133+
foo.value(at: y),
134+
let otherObject =
135+
foo.value(at: x),
136+
isEqual(a, b)
137+
{
138+
foo()
139+
}
86140
87141
"""
88142

Tests/SwiftFormatPrettyPrintTests/XCTestManifests.swift

+2
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,7 @@ extension NewlineTests {
493493
static let __allTests__NewlineTests = [
494494
("testLeadingNewlines", testLeadingNewlines),
495495
("testLeadingNewlinesWithComments", testLeadingNewlinesWithComments),
496+
("testNewlinesBetweenMembers", testNewlinesBetweenMembers),
496497
("testTrailingNewlines", testTrailingNewlines),
497498
("testTrailingNewlinesWithComments", testTrailingNewlinesWithComments),
498499
]
@@ -802,6 +803,7 @@ extension WhileStmtTests {
802803
static let __allTests__WhileStmtTests = [
803804
("testBasicWhileLoops", testBasicWhileLoops),
804805
("testLabeledWhileLoops", testLabeledWhileLoops),
806+
("testWhileLoopMultipleConditionElements", testWhileLoopMultipleConditionElements),
805807
]
806808
}
807809

0 commit comments

Comments
 (0)