Skip to content

Commit f7fa91b

Browse files
committed
SwiftFixIt: Require that locations are resolved in the right source file
1 parent 71134e0 commit f7fa91b

File tree

2 files changed

+41
-32
lines changed

2 files changed

+41
-32
lines changed

Sources/SwiftFixIt/SwiftFixit.swift

+13-8
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,12 @@ private struct SourceFile {
219219
)
220220
}
221221

222-
func position(of location: borrowing some AnySourceLocation) -> AbsolutePosition {
222+
func position(of location: borrowing some AnySourceLocation) throws -> AbsolutePosition {
223+
guard try AbsolutePath(validating: location.filename) == self.path else {
224+
// Wrong source file.
225+
throw Error.failedToResolveSourceLocation
226+
}
227+
223228
guard location.offset == 0 else {
224229
return AbsolutePosition(utf8Offset: Int(location.offset))
225230
}
@@ -231,7 +236,7 @@ private struct SourceFile {
231236
}
232237

233238
func node(at location: some AnySourceLocation) throws -> Syntax {
234-
let position = position(of: location)
239+
let position = try position(of: location)
235240

236241
if let token = syntax.token(at: position) {
237242
return SwiftSyntax.Syntax(token)
@@ -305,10 +310,10 @@ extension DiagnosticConverter {
305310
private static func fixIt(
306311
from diagnostic: borrowing some AnyDiagnostic,
307312
in sourceFile: borrowing SourceFile
308-
) -> SwiftDiagnostics.FixIt {
309-
let changes = diagnostic.fixIts.map { fixIt in
310-
let startPosition = sourceFile.position(of: fixIt.start)
311-
let endPosition = sourceFile.position(of: fixIt.end)
313+
) throws -> SwiftDiagnostics.FixIt {
314+
let changes = try diagnostic.fixIts.map { fixIt in
315+
let startPosition = try sourceFile.position(of: fixIt.start)
316+
let endPosition = try sourceFile.position(of: fixIt.end)
312317

313318
return SwiftDiagnostics.FixIt.Change.replaceText(
314319
range: startPosition ..< endPosition,
@@ -325,8 +330,8 @@ extension DiagnosticConverter {
325330
in sourceFile: borrowing SourceFile
326331
) throws -> [Syntax] {
327332
try diagnostic.ranges.map { startLocation, endLocation in
328-
let startPosition = sourceFile.position(of: startLocation)
329-
let endPosition = sourceFile.position(of: endLocation)
333+
let startPosition = try sourceFile.position(of: startLocation)
334+
let endPosition = try sourceFile.position(of: endLocation)
330335

331336
var highlightedNode = try sourceFile.node(at: startLocation)
332337

Tests/SwiftFixItTests/SwiftFixItTests.swift

+28-24
Original file line numberDiff line numberDiff line change
@@ -549,31 +549,35 @@ extension SwiftFixItTests {
549549
}
550550
}
551551

552-
func testFixItInDifferentFile() throws {
553-
XCTExpectFailure()
554-
555-
// Apply a fix-it in a different file.
556-
try self.testAPI { (filename1: String, filename2: String) in
557-
(
558-
sourceFileEdits: (
559-
.init(input: "var x = 1", result: "let x = 1"),
560-
.init(input: "", result: "")
561-
),
562-
diagnostics: [
563-
TestDiagnostic(
564-
text: "error",
565-
level: .error,
566-
location: .init(filename: filename2, line: 1, column: 1, offset: 0),
567-
fixIts: [
568-
.init(
569-
start: .init(filename: filename1, line: 1, column: 1, offset: 0),
570-
end: .init(filename: filename1, line: 1, column: 4, offset: 0),
571-
text: "let"
572-
),
573-
]
552+
func testFixItInDifferentFile() {
553+
do {
554+
try self.testAPI { (filename1: String, filename2: String) in
555+
(
556+
sourceFileEdits: (
557+
.init(input: "var x = 1", result: "let x = 1"),
558+
.init(input: "", result: "")
574559
),
575-
]
576-
)
560+
diagnostics: [
561+
TestDiagnostic(
562+
text: "error",
563+
level: .error,
564+
location: .init(filename: filename2, line: 1, column: 1, offset: 0),
565+
fixIts: [
566+
.init(
567+
start: .init(filename: filename1, line: 1, column: 1, offset: 0),
568+
end: .init(filename: filename1, line: 1, column: 4, offset: 0),
569+
text: "let"
570+
),
571+
]
572+
),
573+
]
574+
)
575+
}
576+
} catch {
577+
// Expected to throw an error.
578+
return
577579
}
580+
581+
XCTFail()
578582
}
579583
}

0 commit comments

Comments
 (0)