Skip to content

Commit ceb8574

Browse files
committed
In nodesDescription only merge tokens if they occur consecutively in the source code
This was motiviated by the following discussion, where the issue becomes more apparent: #1643 (comment).
1 parent 967e487 commit ceb8574

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

Sources/SwiftParserDiagnostics/MissingNodesError.swift

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ fileprivate enum NodesDescriptionPart {
6767
}
6868

6969
static func descriptionParts(for nodes: some Sequence<Syntax>) -> [NodesDescriptionPart] {
70+
// For each token that we modified (e.g. made it present), map to the original token in `nodes`
71+
var originalTokens: [TokenSyntax: TokenSyntax] = [:]
72+
73+
// Accumulates the result
7074
var parts: [NodesDescriptionPart] = []
75+
7176
for missingNode in nodes {
7277
if let token = missingNode.as(TokenSyntax.self) {
7378
let newPart: NodesDescriptionPart
@@ -77,10 +82,12 @@ fileprivate enum NodesDescriptionPart {
7782
let (rawKind, text) = token.tokenKind.decomposeToRaw()
7883
if let text = text, !text.isEmpty {
7984
let presentToken = token.with(\.presence, .present)
85+
originalTokens[presentToken] = token
8086
newPart = .tokensWithDefaultText([presentToken])
8187
} else if let defaultText = rawKind.defaultText {
8288
let newKind = TokenKind.fromRaw(kind: rawKind, text: String(syntaxText: defaultText))
8389
let presentToken = token.with(\.tokenKind, newKind).with(\.presence, .present)
90+
originalTokens[presentToken] = token
8491
newPart = .tokensWithDefaultText([presentToken])
8592
} else {
8693
newPart = .tokenWithoutDefaultText(token)
@@ -89,7 +96,15 @@ fileprivate enum NodesDescriptionPart {
8996

9097
switch (parts.last, newPart) {
9198
case (.tokensWithDefaultText(let previousTokens), .tokensWithDefaultText(let newTokens)):
92-
parts[parts.count - 1] = .tokensWithDefaultText(previousTokens + newTokens)
99+
// Merge `tokensWithDefaultText` if they occur consecutively in the tree
100+
if let lastPrevious = previousTokens.last,
101+
let firstNew = newTokens.first,
102+
originalTokens[lastPrevious, default: lastPrevious].nextToken(viewMode: .all) == originalTokens[firstNew, default: firstNew]
103+
{
104+
parts[parts.count - 1] = .tokensWithDefaultText(previousTokens + newTokens)
105+
} else {
106+
parts.append(newPart)
107+
}
93108
default:
94109
parts.append(newPart)
95110
}

Tests/SwiftParserTest/DeclarationTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ final class DeclarationTests: XCTestCase {
426426
diagnostics: [
427427
DiagnosticSpec(
428428
message: "expected 'set' in modifier",
429-
fixIts: ["remove 'get, , didSet'"]
429+
fixIts: ["remove 'get,' and ', didSet'"]
430430
)
431431
],
432432
fixedSource: """

Tests/SwiftParserTest/translated/RecoveryTests.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,7 @@ final class RecoveryTests: XCTestCase {
20172017
diagnostics: [
20182018
DiagnosticSpec(
20192019
message: "expected ':' to begin inheritance clause",
2020-
fixIts: ["replace '()' with ':'"]
2020+
fixIts: ["replace '(' and ')' with ':'"]
20212021
)
20222022
],
20232023
fixedSource: """
@@ -2034,7 +2034,7 @@ final class RecoveryTests: XCTestCase {
20342034
diagnostics: [
20352035
DiagnosticSpec(
20362036
message: "expected ':' to begin inheritance clause",
2037-
fixIts: ["replace '()' with ':'"]
2037+
fixIts: ["replace '(' and ')' with ':'"]
20382038
)
20392039
],
20402040
fixedSource: """
@@ -2051,7 +2051,7 @@ final class RecoveryTests: XCTestCase {
20512051
diagnostics: [
20522052
DiagnosticSpec(
20532053
message: "expected ':' to begin inheritance clause",
2054-
fixIts: ["replace '()' with ':'"]
2054+
fixIts: ["replace '(' and ')' with ':'"]
20552055
)
20562056
],
20572057
fixedSource: """
@@ -2068,7 +2068,7 @@ final class RecoveryTests: XCTestCase {
20682068
diagnostics: [
20692069
DiagnosticSpec(
20702070
message: "expected ':' to begin inheritance clause",
2071-
fixIts: ["replace '()' with ':'"]
2071+
fixIts: ["replace '(' and ')' with ':'"]
20722072
)
20732073
],
20742074
fixedSource: """
@@ -2085,7 +2085,7 @@ final class RecoveryTests: XCTestCase {
20852085
diagnostics: [
20862086
DiagnosticSpec(
20872087
message: "expected ':' to begin inheritance clause",
2088-
fixIts: ["replace '()' with ':'"]
2088+
fixIts: ["replace '(' and ')' with ':'"]
20892089
)
20902090
],
20912091
fixedSource: """

0 commit comments

Comments
 (0)