Skip to content

Commit dd6ec9e

Browse files
authored
Merge pull request #91 from allevato/operator-scrunching
Fix scrunching of range operators.
2 parents eb5fcfa + 9d8bfe4 commit dd6ec9e

File tree

3 files changed

+166
-6
lines changed

3 files changed

+166
-6
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2445,13 +2445,24 @@ private final class TokenStreamCreator: SyntaxVisitor {
24452445
// The token kind (spaced or unspaced operator) represents how the *user* wrote it, and we want
24462446
// to ignore that and apply our own rules.
24472447
if let binaryOperator = operatorExpr as? BinaryOperatorExprSyntax {
2448-
let operatorText = binaryOperator.operatorToken.text
2449-
if let precedence = operatorContext.infixOperator(named: operatorText)?.precedenceGroup,
2448+
let token = binaryOperator.operatorToken
2449+
if let precedence = operatorContext.infixOperator(named: token.text)?.precedenceGroup,
24502450
precedence === operatorContext.precedenceGroup(named: .rangeFormation)
24512451
{
2452+
// We want to omit whitespace around range formation operators if possible. We can't do this
2453+
// if the token is either preceded by a postfix operator or followed by a prefix operator---
2454+
// removing the spaces in those situations would cause the parser to greedily treat the
2455+
// combined sequence of operator characters as a single operator.
2456+
if case .postfixOperator? = token.previousToken?.tokenKind { return true }
2457+
if case .prefixOperator? = token.nextToken?.tokenKind { return true }
24522458
return false
24532459
}
24542460
}
2461+
2462+
// For all other operators, we want to require whitespace on each side. That's always safe, so
2463+
// we don't need to be concerned about neighboring operator tokens. For example, we don't need
2464+
// to be concerned about the user writing "4+-5" when they meant "4 + -5", because Swift would
2465+
// always parse the former as "4 +- 5".
24552466
return true
24562467
}
24572468
}
Lines changed: 148 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,161 @@
11
public class BinaryOperatorExprTests: PrettyPrintTestCase {
2-
public func testOperatorSpacing() {
2+
3+
public func testNonRangeFormationOperatorsAreSurroundedByBreaks() {
4+
let input =
5+
"""
6+
x=1+8-9 ^*^ 5*4/10
7+
"""
8+
9+
let expected80 =
10+
"""
11+
x = 1 + 8 - 9 ^*^ 5 * 4 / 10
12+
13+
"""
14+
15+
assertPrettyPrintEqual(input: input, expected: expected80, linelength: 80)
16+
17+
let expected10 =
18+
"""
19+
x = 1 + 8
20+
- 9
21+
^*^ 5
22+
* 4 / 10
23+
24+
"""
25+
26+
assertPrettyPrintEqual(input: input, expected: expected10, linelength: 10)
27+
}
28+
29+
public func testRangeFormationOperatorsAreCompactedWhenPossible() {
330
let input =
431
"""
5-
x=1+8-9 ..< 5*4/10
32+
x = 1...100
33+
x = 1..<100
34+
x = (1++)...(-100)
35+
x = 1 ... 100
36+
x = 1 ..< 100
37+
x = (1++) ... (-100)
638
"""
739

840
let expected =
941
"""
10-
x = 1 + 8 - 9..<5 * 4 / 10
42+
x = 1...100
43+
x = 1..<100
44+
x = (1++)...(-100)
45+
x = 1...100
46+
x = 1..<100
47+
x = (1++)...(-100)
1148
1249
"""
1350

1451
assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
1552
}
53+
54+
public func testRangeFormationOperatorsAreNotCompactedWhenFollowingAPostfixOperator() {
55+
let input =
56+
"""
57+
x = 1++ ... 100
58+
x = 1-- ..< 100
59+
x = 1++ ... 100
60+
x = 1-- ..< 100
61+
"""
62+
63+
let expected80 =
64+
"""
65+
x = 1++ ... 100
66+
x = 1-- ..< 100
67+
x = 1++ ... 100
68+
x = 1-- ..< 100
69+
70+
"""
71+
72+
assertPrettyPrintEqual(input: input, expected: expected80, linelength: 80)
73+
74+
let expected10 =
75+
"""
76+
x = 1++
77+
... 100
78+
x = 1--
79+
..< 100
80+
x = 1++
81+
... 100
82+
x = 1--
83+
..< 100
84+
85+
"""
86+
87+
assertPrettyPrintEqual(input: input, expected: expected10, linelength: 10)
88+
}
89+
90+
public func testRangeFormationOperatorsAreNotCompactedWhenPrecedingAPrefixOperator() {
91+
let input =
92+
"""
93+
x = 1 ... -100
94+
x = 1 ..< -100
95+
x = 1 ... √100
96+
x = 1 ..< √100
97+
"""
98+
99+
let expected80 =
100+
"""
101+
x = 1 ... -100
102+
x = 1 ..< -100
103+
x = 1 ... √100
104+
x = 1 ..< √100
105+
106+
"""
107+
108+
assertPrettyPrintEqual(input: input, expected: expected80, linelength: 80)
109+
110+
let expected10 =
111+
"""
112+
x = 1
113+
... -100
114+
x = 1
115+
..< -100
116+
x = 1
117+
... √100
118+
x = 1
119+
..< √100
120+
121+
"""
122+
123+
assertPrettyPrintEqual(input: input, expected: expected10, linelength: 10)
124+
}
125+
126+
public func testRangeFormationOperatorsAreNotCompactedWhenUnaryOperatorsAreOnEachSide() {
127+
let input =
128+
"""
129+
x = 1++ ... -100
130+
x = 1-- ..< -100
131+
x = 1++ ... √100
132+
x = 1-- ..< √100
133+
"""
134+
135+
let expected80 =
136+
"""
137+
x = 1++ ... -100
138+
x = 1-- ..< -100
139+
x = 1++ ... √100
140+
x = 1-- ..< √100
141+
142+
"""
143+
144+
assertPrettyPrintEqual(input: input, expected: expected80, linelength: 80)
145+
146+
let expected10 =
147+
"""
148+
x = 1++
149+
... -100
150+
x = 1--
151+
..< -100
152+
x = 1++
153+
... √100
154+
x = 1--
155+
..< √100
156+
157+
"""
158+
159+
assertPrettyPrintEqual(input: input, expected: expected10, linelength: 10)
160+
}
16161
}

Tests/SwiftFormatPrettyPrintTests/XCTestManifests.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,11 @@ extension BinaryOperatorExprTests {
8989
// `swift test --generate-linuxmain`
9090
// to regenerate.
9191
static let __allTests__BinaryOperatorExprTests = [
92-
("testOperatorSpacing", testOperatorSpacing),
92+
("testNonRangeFormationOperatorsAreSurroundedByBreaks", testNonRangeFormationOperatorsAreSurroundedByBreaks),
93+
("testRangeFormationOperatorsAreCompactedWhenPossible", testRangeFormationOperatorsAreCompactedWhenPossible),
94+
("testRangeFormationOperatorsAreNotCompactedWhenFollowingAPostfixOperator", testRangeFormationOperatorsAreNotCompactedWhenFollowingAPostfixOperator),
95+
("testRangeFormationOperatorsAreNotCompactedWhenPrecedingAPrefixOperator", testRangeFormationOperatorsAreNotCompactedWhenPrecedingAPrefixOperator),
96+
("testRangeFormationOperatorsAreNotCompactedWhenUnaryOperatorsAreOnEachSide", testRangeFormationOperatorsAreNotCompactedWhenUnaryOperatorsAreOnEachSide),
9397
]
9498
}
9599

0 commit comments

Comments
 (0)