Skip to content

Commit 1f96ddf

Browse files
committed
Add newline fix-it after consecutive declarations
1 parent 4d5dafa commit 1f96ddf

File tree

4 files changed

+264
-28
lines changed

4 files changed

+264
-28
lines changed

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,8 +1047,16 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
10471047
position: position,
10481048
.consecutiveDeclarationsOnSameLine,
10491049
fixIts: [
1050-
FixIt(message: .insertSemicolon, changes: .makePresent(semicolon))
1051-
],
1050+
node.lastToken(viewMode: .sourceAccurate).map {
1051+
FixIt(
1052+
message: .insertNewline,
1053+
changes: [
1054+
.replaceTrailingTrivia(token: $0, newTrivia: $0.trailingTrivia + .newlines(1))
1055+
]
1056+
)
1057+
},
1058+
FixIt(message: .insertSemicolon, changes: .makePresent(semicolon)),
1059+
].compactMap { $0 },
10521060
handledNodes: [semicolon.id]
10531061
)
10541062
} else {

Tests/SwiftParserTest/translated/ConsecutiveStatementsTests.swift

Lines changed: 110 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,8 @@ final class ConsecutiveStatementsTests: XCTestCase {
102102
}
103103
""",
104104
diagnostics: [
105-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
106-
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
105+
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
106+
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
107107
DiagnosticSpec(locationMarker: "3️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
108108
DiagnosticSpec(locationMarker: "4️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
109109
DiagnosticSpec(locationMarker: "5️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
@@ -129,7 +129,7 @@ final class ConsecutiveStatementsTests: XCTestCase {
129129
)
130130
}
131131

132-
func testConsecutiveStatements4() {
132+
func testConsecutiveStatements4a() {
133133
assertParse(
134134
"""
135135
class C {
@@ -142,12 +142,14 @@ final class ConsecutiveStatementsTests: XCTestCase {
142142
}
143143
""",
144144
diagnostics: [
145-
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"])
145+
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"])
146146
],
147+
applyFixIts: ["insert newline"],
147148
fixedSource: """
148149
class C {
149150
// In a sequence of declarations.
150-
var a, b : Int; func d() -> Int {}
151+
var a, b : Int
152+
func d() -> Int {}
151153
init() {
152154
a = 0
153155
b = 0
@@ -157,25 +159,75 @@ final class ConsecutiveStatementsTests: XCTestCase {
157159
)
158160
}
159161

160-
func testConsecutiveStatements5() {
162+
func testConsecutiveStatements4b() {
163+
assertParse(
164+
"""
165+
class C {
166+
// In a sequence of declarations.
167+
var a, b : Int1️⃣ func d() -> Int {}
168+
init() {
169+
a = 0
170+
b = 0
171+
}
172+
}
173+
""",
174+
diagnostics: [
175+
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"])
176+
],
177+
applyFixIts: ["insert ';'"],
178+
fixedSource: """
179+
class C {
180+
// In a sequence of declarations.
181+
var a, b : Int; func d() -> Int {}
182+
init() {
183+
a = 0
184+
b = 0
185+
}
186+
}
187+
"""
188+
)
189+
}
190+
191+
func testConsecutiveStatements5a() {
161192
assertParse(
162193
"""
163194
protocol P {
164195
func a()1️⃣ func b()
165196
}
166197
""",
167198
diagnostics: [
168-
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"])
199+
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"])
169200
],
201+
applyFixIts: ["insert newline"],
170202
fixedSource: """
171203
protocol P {
172-
func a(); func b()
204+
func a()
205+
func b()
173206
}
174207
"""
175208
)
176209
}
177210

178-
func testConsecutiveStatements6() {
211+
func testConsecutiveStatements5b() {
212+
assertParse(
213+
"""
214+
protocol P {
215+
func a()1️⃣ func b()
216+
}
217+
""",
218+
diagnostics: [
219+
DiagnosticSpec(message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"])
220+
],
221+
applyFixIts: ["insert ';'"],
222+
fixedSource: """
223+
protocol P {
224+
func a(); func b()
225+
}
226+
"""
227+
)
228+
}
229+
230+
func testConsecutiveStatements6a() {
179231
assertParse(
180232
"""
181233
enum Color {
@@ -184,18 +236,43 @@ final class ConsecutiveStatementsTests: XCTestCase {
184236
}
185237
""",
186238
diagnostics: [
187-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
188-
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert ';'"]),
239+
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
240+
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
189241
],
242+
applyFixIts: ["insert newline"],
190243
fixedSource: """
191244
enum Color {
192-
case Red; case Blue
193-
func a() {}; func b() {}
245+
case Red
246+
case Blue
247+
func a() {}
248+
func b() {}
194249
}
195250
"""
196251
)
197252
}
198253

254+
func testConsecutiveStatements6b() {
255+
assertParse(
256+
"""
257+
enum Color {
258+
case Red1️⃣ case Blue
259+
func a() {}2️⃣ func b() {}
260+
}
261+
""",
262+
diagnostics: [
263+
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
264+
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
265+
],
266+
applyFixIts: ["insert ';'"],
267+
fixedSource: """
268+
enum Color {
269+
case Red; case Blue
270+
func a() {}; func b() {}
271+
}
272+
"""
273+
)
274+
}
275+
199276
func testConsecutiveStatements7() {
200277
assertParse(
201278
"""
@@ -212,4 +289,24 @@ final class ConsecutiveStatementsTests: XCTestCase {
212289
"""
213290
)
214291
}
292+
293+
func testConsecutiveStatements8() {
294+
assertParse(
295+
"""
296+
class Foo {
297+
func a() {}1️⃣/* some comment */ func b() {}
298+
}
299+
""",
300+
diagnostics: [
301+
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive declarations on a line must be separated by ';'", fixIts: ["insert newline", "insert ';'"]),
302+
],
303+
applyFixIts: ["insert newline"],
304+
fixedSource: """
305+
class Foo {
306+
func a() {}/* some comment */
307+
func b() {}
308+
}
309+
"""
310+
)
311+
}
215312
}

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ final class RecoveryTests: XCTestCase {
918918
)
919919
}
920920

921-
func testRecovery62() {
921+
func testRecovery62a() {
922922
assertParse(
923923
"""
924924
enum EE 1️⃣EE<T> where T : Multi {
@@ -935,19 +935,52 @@ final class RecoveryTests: XCTestCase {
935935
DiagnosticSpec(
936936
locationMarker: "2️⃣",
937937
message: "consecutive declarations on a line must be separated by ';'",
938-
fixIts: ["insert ';'"]
938+
fixIts: ["insert newline", "insert ';'"]
939939
),
940940
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code 'a' before enum case"),
941941
],
942+
applyFixIts: ["join the identifiers together", "insert newline"],
942943
fixedSource: """
943944
enum EEEE<T> where T : Multi {
944-
case a;a
945+
case a
946+
a
945947
case b
946948
}
947949
"""
948950
)
949951
}
950952

953+
func testRecovery62b() {
954+
assertParse(
955+
"""
956+
enum EE 1️⃣EE<T> where T : Multi {
957+
case a2️⃣ 3️⃣a
958+
case b
959+
}
960+
""",
961+
diagnostics: [
962+
DiagnosticSpec(
963+
locationMarker: "1️⃣",
964+
message: "found an unexpected second identifier in enum; is there an accidental break?",
965+
fixIts: ["join the identifiers together"]
966+
),
967+
DiagnosticSpec(
968+
locationMarker: "2️⃣",
969+
message: "consecutive declarations on a line must be separated by ';'",
970+
fixIts: ["insert newline", "insert ';'"]
971+
),
972+
DiagnosticSpec(locationMarker: "3️⃣", message: "unexpected code 'a' before enum case"),
973+
],
974+
applyFixIts: ["join the identifiers together", "insert ';'"],
975+
fixedSource: """
976+
enum EEEE<T> where T : Multi {
977+
case a;a
978+
case b
979+
}
980+
"""
981+
)
982+
}
983+
951984
func testRecovery63() {
952985
assertParse(
953986
#"""
@@ -1546,7 +1579,7 @@ final class RecoveryTests: XCTestCase {
15461579
DiagnosticSpec(
15471580
locationMarker: "1️⃣",
15481581
message: "consecutive declarations on a line must be separated by ';'",
1549-
fixIts: ["insert ';'"]
1582+
fixIts: ["insert newline", "insert ';'"]
15501583
),
15511584
DiagnosticSpec(
15521585
locationMarker: "1️⃣",
@@ -1585,7 +1618,8 @@ final class RecoveryTests: XCTestCase {
15851618
],
15861619
fixedSource: """
15871620
struct ErrorTypeInVarDeclDictionaryType {
1588-
let a1: String;:
1621+
let a1: String
1622+
:
15891623
let a2: [String: Int]
15901624
let a3: [String: [Int]]
15911625
let a4: [String: Int]

0 commit comments

Comments
 (0)