Skip to content

Commit 0266e97

Browse files
authored
Merge pull request swiftlang#143 from allevato/no-discretionary-colons
Ignore discretionary newlines in a number of new locations.
2 parents d212a6f + e8f37a5 commit 0266e97

File tree

9 files changed

+247
-15
lines changed

9 files changed

+247
-15
lines changed

Sources/SwiftFormatPrettyPrint/TokenStreamCreator.swift

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
510510
after(node.inKeyword, tokens: .space)
511511

512512
if let typeAnnotation = node.typeAnnotation {
513-
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
513+
after(
514+
typeAnnotation.colon,
515+
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
514516
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
515517
}
516518

@@ -695,7 +697,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
695697
/// - Parameter node: The tuple expression element to be arranged.
696698
private func arrangeAsTupleExprElement(_ node: TupleExprElementSyntax) {
697699
before(node.firstToken, tokens: .open)
698-
after(node.colon, tokens: .break)
700+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
699701
after(node.lastToken, tokens: .close)
700702
}
701703

@@ -756,13 +758,13 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
756758
}
757759

758760
override func visit(_ node: DictionaryTypeSyntax) -> SyntaxVisitorContinueKind {
759-
after(node.colon, tokens: .break)
761+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
760762
return .visitChildren
761763
}
762764

763765
override func visit(_ node: DictionaryElementSyntax) -> SyntaxVisitorContinueKind {
764766
before(node.firstToken, tokens: .open)
765-
after(node.colon, tokens: .break)
767+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
766768
after(node.lastToken, tokens: .close)
767769
return .visitChildren
768770
}
@@ -855,7 +857,11 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
855857
// If we have an open delimiter following the colon, use a space instead of a continuation
856858
// break so that we don't awkwardly shift the delimiter down and indent it further if it
857859
// wraps.
858-
let tokenAfterColon: Token = startsWithOpenDelimiter(Syntax(node.expression)) ? .space : .break
860+
let tokenAfterColon: Token =
861+
startsWithOpenDelimiter(Syntax(node.expression))
862+
? .space
863+
: .break(.continue, newlines: .elective(ignoresDiscretionary: true))
864+
859865
after(node.colon, tokens: tokenAfterColon)
860866

861867
if let trailingComma = node.trailingComma {
@@ -1028,8 +1034,10 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
10281034
override func visit(_ node: FunctionParameterSyntax) -> SyntaxVisitorContinueKind {
10291035
before(node.firstToken, tokens: .open)
10301036
arrangeAttributeList(node.attributes)
1031-
after(node.colon, tokens: .break)
1032-
before(node.secondName, tokens: .break)
1037+
before(
1038+
node.secondName,
1039+
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
1040+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
10331041

10341042
if let trailingComma = node.trailingComma {
10351043
after(trailingComma, tokens: .close, .break(.same))
@@ -1240,9 +1248,10 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
12401248

12411249
override func visit(_ node: TupleTypeElementSyntax) -> SyntaxVisitorContinueKind {
12421250
before(node.firstToken, tokens: .open)
1243-
after(node.colon, tokens: .break)
1244-
after(node.inOut, tokens: .break)
1245-
before(node.secondName, tokens: .break)
1251+
before(
1252+
node.secondName,
1253+
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
1254+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
12461255

12471256
if let trailingComma = node.trailingComma {
12481257
after(trailingComma, tokens: .close, .break(.same))
@@ -1303,7 +1312,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
13031312

13041313
override func visit(_ node: AvailabilityLabeledArgumentSyntax) -> SyntaxVisitorContinueKind {
13051314
before(node.label, tokens: .open)
1306-
after(node.colon, tokens: .break(.continue, size: 1))
1315+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
13071316
after(node.value.lastToken, tokens: .close)
13081317
return .visitChildren
13091318
}
@@ -1578,7 +1587,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
15781587
var closeAfterToken: TokenSyntax? = nil
15791588

15801589
if let typeAnnotation = node.typeAnnotation {
1581-
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
1590+
after(
1591+
typeAnnotation.colon,
1592+
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
15821593
closesNeeded += 1
15831594
closeAfterToken = typeAnnotation.lastToken
15841595
}
@@ -1664,7 +1675,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
16641675

16651676
override func visit(_ node: AttributedTypeSyntax) -> SyntaxVisitorContinueKind {
16661677
arrangeAttributeList(node.attributes)
1667-
after(node.specifier, tokens: .break)
1678+
after(
1679+
node.specifier,
1680+
tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
16681681
return .visitChildren
16691682
}
16701683

@@ -1751,7 +1764,7 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
17511764

17521765
override func visit(_ node: GenericParameterSyntax) -> SyntaxVisitorContinueKind {
17531766
before(node.firstToken, tokens: .open)
1754-
after(node.colon, tokens: .break)
1767+
after(node.colon, tokens: .break(.continue, newlines: .elective(ignoresDiscretionary: true)))
17551768
if let trailingComma = node.trailingComma {
17561769
after(trailingComma, tokens: .close, .break(.same))
17571770
} else {
@@ -1958,7 +1971,9 @@ fileprivate final class TokenStreamCreator: SyntaxVisitor {
19581971
after(node.letOrVarKeyword, tokens: .break)
19591972

19601973
if let typeAnnotation = node.typeAnnotation {
1961-
after(typeAnnotation.colon, tokens: .break(.open(kind: .continuation)))
1974+
after(
1975+
typeAnnotation.colon,
1976+
tokens: .break(.open(kind: .continuation), newlines: .elective(ignoresDiscretionary: true)))
19621977
after(typeAnnotation.lastToken, tokens: .break(.close(mustBreak: false), size: 0))
19631978
}
19641979

Tests/SwiftFormatPrettyPrintTests/AttributeTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,28 @@ final class AttributeTests: PrettyPrintTestCase {
290290

291291
assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
292292
}
293+
294+
func testIgnoresDiscretionaryLineBreakAfterColon() {
295+
let input =
296+
"""
297+
@available(
298+
*, unavailable,
299+
renamed:
300+
"MyRenamedFunction"
301+
)
302+
func f() {}
303+
"""
304+
305+
let expected =
306+
"""
307+
@available(
308+
*, unavailable,
309+
renamed: "MyRenamedFunction"
310+
)
311+
func f() {}
312+
313+
"""
314+
315+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 30)
316+
}
293317
}

Tests/SwiftFormatPrettyPrintTests/DictionaryDeclTests.swift

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,43 @@ final class DictionaryDeclTests: PrettyPrintTestCase {
9494
XCTAssertDiagnosed(.removeTrailingComma, line: 1, column: 32)
9595
XCTAssertDiagnosed(.addTrailingComma, line: 4, column: 17)
9696
}
97+
98+
func testIgnoresDiscretionaryNewlineAfterColon() {
99+
let input =
100+
"""
101+
let a = [
102+
"reallyLongKeySoTheValueWillWrap":
103+
value
104+
]
105+
let a = [
106+
"shortKey":
107+
value
108+
]
109+
let a:
110+
[ReallyLongKeySoTheValueWillWrap:
111+
Value]
112+
let a:
113+
[ShortKey:
114+
Value]
115+
"""
116+
117+
let expected =
118+
"""
119+
let a = [
120+
"reallyLongKeySoTheValueWillWrap":
121+
value
122+
]
123+
let a = [
124+
"shortKey": value
125+
]
126+
let a:
127+
[ReallyLongKeySoTheValueWillWrap:
128+
Value]
129+
let a:
130+
[ShortKey: Value]
131+
132+
"""
133+
134+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 20)
135+
}
97136
}

Tests/SwiftFormatPrettyPrintTests/ForInStmtTests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,4 +306,27 @@ final class ForInStmtTests: PrettyPrintTestCase {
306306

307307
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
308308
}
309+
310+
func testTypeAnnotationIgnoresDiscretionaryNewlineAfterColon() {
311+
let input =
312+
"""
313+
for i:
314+
ExplicitType in mycontainer
315+
{
316+
let a = 123
317+
let b = i
318+
}
319+
"""
320+
321+
let expected =
322+
"""
323+
for i: ExplicitType in mycontainer {
324+
let a = 123
325+
let b = i
326+
}
327+
328+
"""
329+
330+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 80)
331+
}
309332
}

Tests/SwiftFormatPrettyPrintTests/FunctionCallTests.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,28 @@ final class FunctionCallTests: PrettyPrintTestCase {
225225

226226
assertPrettyPrintEqual(input: input, expected: expected, linelength: 60)
227227
}
228+
229+
func testIgnoresDiscretionaryLineBreakAfterColon() {
230+
let input =
231+
"""
232+
myFunc(
233+
a:
234+
foo,
235+
b:
236+
bar + baz + quux
237+
)
238+
"""
239+
240+
let expected =
241+
"""
242+
myFunc(
243+
a: foo,
244+
b: bar + baz
245+
+ quux
246+
)
247+
248+
"""
249+
250+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 20)
251+
}
228252
}

Tests/SwiftFormatPrettyPrintTests/FunctionDeclTests.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,4 +1038,51 @@ final class FunctionDeclTests: PrettyPrintTestCase {
10381038

10391039
assertPrettyPrintEqual(input: input, expected: expected, linelength: 14)
10401040
}
1041+
1042+
func testIgnoresDiscretionaryLineBreakAfterColonAndInout() {
1043+
let input =
1044+
"""
1045+
func foo(
1046+
a:
1047+
ReallyLongTypeName,
1048+
b:
1049+
ShortType,
1050+
c:
1051+
inout
1052+
C,
1053+
labeled
1054+
d:
1055+
D,
1056+
reallyLongLabel
1057+
reallyLongArg: E
1058+
) {}
1059+
func foo<
1060+
A:
1061+
ReallyLongType,
1062+
B:
1063+
ShortType
1064+
>(a: A, b: B) {}
1065+
1066+
"""
1067+
1068+
let expected =
1069+
"""
1070+
func foo(
1071+
a:
1072+
ReallyLongTypeName,
1073+
b: ShortType,
1074+
c: inout C,
1075+
labeled d: D,
1076+
reallyLongLabel
1077+
reallyLongArg: E
1078+
) {}
1079+
func foo<
1080+
A: ReallyLongType,
1081+
B: ShortType
1082+
>(a: A, b: B) {}
1083+
1084+
"""
1085+
1086+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 23)
1087+
}
10411088
}

Tests/SwiftFormatPrettyPrintTests/PatternBindingTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,24 @@ final class PatternBindingTests: PrettyPrintTestCase {
2323

2424
assertPrettyPrintEqual(input: input, expected: expected, linelength: 40)
2525
}
26+
27+
func testIgnoresDiscretionaryNewlineAfterColon() {
28+
let input =
29+
"""
30+
let someObject:
31+
Foo = object
32+
let someObject:
33+
Foo = longerObjectName
34+
"""
35+
36+
let expected =
37+
"""
38+
let someObject: Foo = object
39+
let someObject: Foo =
40+
longerObjectName
41+
42+
"""
43+
44+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 28)
45+
}
2646
}

Tests/SwiftFormatPrettyPrintTests/TupleDeclTests.swift

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,37 @@ final class TupleDeclTests: PrettyPrintTestCase {
4545

4646
assertPrettyPrintEqual(input: input, expected: expected, linelength: 30)
4747
}
48+
49+
func testIgnoresDiscretionaryNewlineAfterColon() {
50+
let input =
51+
"""
52+
let a = (
53+
reallyLongKeySoTheValueWillWrap:
54+
value,
55+
b: c
56+
)
57+
let a = (
58+
shortKey:
59+
value,
60+
b:
61+
c
62+
)
63+
"""
64+
65+
let expected =
66+
"""
67+
let a = (
68+
reallyLongKeySoTheValueWillWrap:
69+
value,
70+
b: c
71+
)
72+
let a = (
73+
shortKey: value,
74+
b: c
75+
)
76+
77+
"""
78+
79+
assertPrettyPrintEqual(input: input, expected: expected, linelength: 25)
80+
}
4881
}

0 commit comments

Comments
 (0)