Skip to content

Commit a8e68f7

Browse files
committed
Add newline fix-it after consecutive statements
1 parent 1731e82 commit a8e68f7

14 files changed

+1259
-91
lines changed

Sources/SwiftParserDiagnostics/ParseDiagnosticsGenerator.swift

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -727,13 +727,28 @@ public class ParseDiagnosticsGenerator: SyntaxAnyVisitor {
727727
// Only diagnose the missing semicolon if the item doesn't contain any errors.
728728
// If the item contains errors, the root cause is most likely something different and not the missing semicolon.
729729
let position = semicolon.previousToken(viewMode: .sourceAccurate)?.endPositionBeforeTrailingTrivia
730+
var fixIts: [FixIt] = [
731+
FixIt(message: .insertSemicolon, changes: .makePresent(semicolon))
732+
]
733+
if let firstToken = node.firstToken(viewMode: .sourceAccurate),
734+
let lastToken = node.lastToken(viewMode: .sourceAccurate)
735+
{
736+
fixIts.insert(
737+
FixIt(
738+
message: .insertNewline,
739+
changes: [
740+
.replaceTrailingTrivia(token: lastToken, newTrivia: lastToken.trailingTrivia + .newlines(1) + firstToken.indentationOfLine)
741+
]
742+
),
743+
at: 0
744+
)
745+
}
746+
730747
addDiagnostic(
731748
semicolon,
732749
position: position,
733750
.consecutiveStatementsOnSameLine,
734-
fixIts: [
735-
FixIt(message: .insertSemicolon, changes: .makePresent(semicolon))
736-
],
751+
fixIts: fixIts,
737752
handledNodes: [semicolon.id]
738753
)
739754
} else {

Sources/SwiftParserDiagnostics/ParserDiagnosticMessages.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ extension DiagnosticMessage where Self == StaticParserError {
109109
.init("consecutive declarations on a line must be separated by newline or ';'")
110110
}
111111
public static var consecutiveStatementsOnSameLine: Self {
112-
.init("consecutive statements on a line must be separated by ';'")
112+
.init("consecutive statements on a line must be separated by newline or ';'")
113113
}
114114
public static var cStyleForLoop: Self {
115115
.init("C-style for statement has been removed in Swift 3")

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 128 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,54 @@ final class DeclarationTests: XCTestCase {
329329
internal(set) var defaultProp = 0
330330
""",
331331
diagnostics: [
332-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
333-
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
332+
DiagnosticSpec(
333+
locationMarker: "1️⃣",
334+
message: "consecutive statements on a line must be separated by newline or ';'",
335+
fixIts: ["insert newline", "insert ';'"]
336+
),
337+
DiagnosticSpec(
338+
locationMarker: "2️⃣",
339+
message: "consecutive statements on a line must be separated by newline or ';'",
340+
fixIts: ["insert newline", "insert ';'"]
341+
),
342+
],
343+
applyFixIts: ["insert newline"],
344+
fixedSource: """
345+
open
346+
open(set)
347+
var openProp = 0
348+
public public(set) var publicProp = 0
349+
package package(set) var packageProp = 0
350+
internal internal(set) var internalProp = 0
351+
fileprivate fileprivate(set) var fileprivateProp = 0
352+
private private(set) var privateProp = 0
353+
internal(set) var defaultProp = 0
354+
"""
355+
)
356+
357+
assertParse(
358+
"""
359+
open1️⃣ open(set)2️⃣ var openProp = 0
360+
public public(set) var publicProp = 0
361+
package package(set) var packageProp = 0
362+
internal internal(set) var internalProp = 0
363+
fileprivate fileprivate(set) var fileprivateProp = 0
364+
private private(set) var privateProp = 0
365+
internal(set) var defaultProp = 0
366+
""",
367+
diagnostics: [
368+
DiagnosticSpec(
369+
locationMarker: "1️⃣",
370+
message: "consecutive statements on a line must be separated by newline or ';'",
371+
fixIts: ["insert newline", "insert ';'"]
372+
),
373+
DiagnosticSpec(
374+
locationMarker: "2️⃣",
375+
message: "consecutive statements on a line must be separated by newline or ';'",
376+
fixIts: ["insert newline", "insert ';'"]
377+
),
334378
],
379+
applyFixIts: ["insert ';'"],
335380
fixedSource: """
336381
open; open(set); var openProp = 0
337382
public public(set) var publicProp = 0
@@ -1025,18 +1070,74 @@ final class DeclarationTests: XCTestCase {
10251070
)
10261071
}
10271072

1028-
func testTextRecovery() {
1073+
func testTextRecovery1() {
1074+
assertParse(
1075+
"""
1076+
Lorem1️⃣ ipsum2️⃣ dolor3️⃣ sit4️⃣ amet5️⃣, consectetur adipiscing elit
1077+
""",
1078+
diagnostics: [
1079+
DiagnosticSpec(
1080+
locationMarker: "1️⃣",
1081+
message: "consecutive statements on a line must be separated by newline or ';'",
1082+
fixIts: ["insert newline", "insert ';'"]
1083+
),
1084+
DiagnosticSpec(
1085+
locationMarker: "2️⃣",
1086+
message: "consecutive statements on a line must be separated by newline or ';'",
1087+
fixIts: ["insert newline", "insert ';'"]
1088+
),
1089+
DiagnosticSpec(
1090+
locationMarker: "3️⃣",
1091+
message: "consecutive statements on a line must be separated by newline or ';'",
1092+
fixIts: ["insert newline", "insert ';'"]
1093+
),
1094+
DiagnosticSpec(
1095+
locationMarker: "4️⃣",
1096+
message: "consecutive statements on a line must be separated by newline or ';'",
1097+
fixIts: ["insert newline", "insert ';'"]
1098+
),
1099+
DiagnosticSpec(locationMarker: "5️⃣", message: "extraneous code ', consectetur adipiscing elit' at top level"),
1100+
],
1101+
applyFixIts: ["insert newline"],
1102+
fixedSource: """
1103+
Lorem
1104+
ipsum
1105+
dolor
1106+
sit
1107+
amet, consectetur adipiscing elit
1108+
"""
1109+
)
1110+
}
1111+
1112+
func testTextRecovery2() {
10291113
assertParse(
10301114
"""
10311115
Lorem1️⃣ ipsum2️⃣ dolor3️⃣ sit4️⃣ amet5️⃣, consectetur adipiscing elit
10321116
""",
10331117
diagnostics: [
1034-
DiagnosticSpec(locationMarker: "1️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
1035-
DiagnosticSpec(locationMarker: "2️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
1036-
DiagnosticSpec(locationMarker: "3️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
1037-
DiagnosticSpec(locationMarker: "4️⃣", message: "consecutive statements on a line must be separated by ';'", fixIts: ["insert ';'"]),
1118+
DiagnosticSpec(
1119+
locationMarker: "1️⃣",
1120+
message: "consecutive statements on a line must be separated by newline or ';'",
1121+
fixIts: ["insert newline", "insert ';'"]
1122+
),
1123+
DiagnosticSpec(
1124+
locationMarker: "2️⃣",
1125+
message: "consecutive statements on a line must be separated by newline or ';'",
1126+
fixIts: ["insert newline", "insert ';'"]
1127+
),
1128+
DiagnosticSpec(
1129+
locationMarker: "3️⃣",
1130+
message: "consecutive statements on a line must be separated by newline or ';'",
1131+
fixIts: ["insert newline", "insert ';'"]
1132+
),
1133+
DiagnosticSpec(
1134+
locationMarker: "4️⃣",
1135+
message: "consecutive statements on a line must be separated by newline or ';'",
1136+
fixIts: ["insert newline", "insert ';'"]
1137+
),
10381138
DiagnosticSpec(locationMarker: "5️⃣", message: "extraneous code ', consectetur adipiscing elit' at top level"),
10391139
],
1140+
applyFixIts: ["insert ';'"],
10401141
fixedSource: """
10411142
Lorem; ipsum; dolor; sit; amet, consectetur adipiscing elit
10421143
"""
@@ -2409,4 +2510,24 @@ final class DeclarationTests: XCTestCase {
24092510
fixedSource: "protocol X<<#identifier#>> {}"
24102511
)
24112512
}
2513+
2514+
func testCorrectIndentationWithNewline() {
2515+
assertParse(
2516+
"""
2517+
func
2518+
test() {}1️⃣ var other: Int
2519+
""",
2520+
diagnostics: [
2521+
DiagnosticSpec(
2522+
message: "consecutive statements on a line must be separated by newline or ';'",
2523+
fixIts: ["insert newline", "insert ';'"]
2524+
)
2525+
],
2526+
fixedSource: """
2527+
func
2528+
test() {}
2529+
var other: Int
2530+
"""
2531+
)
2532+
}
24122533
}

0 commit comments

Comments
 (0)