Skip to content

Commit 1d9f2b9

Browse files
committed
SwiftFixIt: Always rely on the UTF-8 offset of an input source location
As it turns out, contrary to an old comment in the diagnostic deserializer, the Swift compiler *does* serialize the offset of a source location, so stop assuming that it may have been left blank. This slightly simplifies the diagnostic conversion logic and also enables us to stop hashing the line and column in the diagnostic filter.
1 parent f625710 commit 1d9f2b9

File tree

5 files changed

+294
-304
lines changed

5 files changed

+294
-304
lines changed

Sources/SwiftFixIt/SwiftFixIt.swift

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private enum Error: Swift.Error {
4343
}
4444

4545
// FIXME: An abstraction for tests to work around missing memberwise initializers in `TSCUtility.SerializedDiagnostics`.
46-
protocol AnySourceLocation: Hashable {
46+
protocol AnySourceLocation {
4747
var filename: String { get }
4848
var line: UInt64 { get }
4949
var column: UInt64 { get }
@@ -76,11 +76,11 @@ protocol AnyDiagnostic {
7676

7777
extension AnyDiagnostic {
7878
var isPrimary: Bool {
79-
self.level != .note
79+
!self.isNote
8080
}
8181

8282
var isNote: Bool {
83-
!self.isPrimary
83+
self.level == .note
8484
}
8585

8686
var isIgnored: Bool {
@@ -97,13 +97,7 @@ extension AnyDiagnostic {
9797
}
9898

9999
extension SerializedDiagnostics.Diagnostic: AnyDiagnostic {}
100-
extension SerializedDiagnostics.SourceLocation: AnySourceLocation, @retroactive Hashable {
101-
public func hash(into hasher: inout Hasher) {
102-
hasher.combine(self.filename)
103-
hasher.combine(self.line)
104-
hasher.combine(self.column)
105-
}
106-
}
100+
extension SerializedDiagnostics.SourceLocation: AnySourceLocation {}
107101

108102
extension SerializedDiagnostics.FixIt: AnyFixIt {}
109103

@@ -112,16 +106,18 @@ private struct PrimaryDiagnosticFilter<Diagnostic: AnyDiagnostic>: ~Copyable {
112106
/// A hashable type storing the minimum data necessary to uniquely identify
113107
/// a diagnostic for our purposes.
114108
private struct DiagnosticID: Hashable {
115-
private let location: Diagnostic.SourceLocation
116109
private let message: String
110+
private let filename: String
111+
private let utf8Offset: UInt64
117112
private let level: SerializedDiagnostics.Diagnostic.Level
118113

119114
init(diagnostic: Diagnostic) {
120115
self.level = diagnostic.level
121116
self.message = diagnostic.text
122117
// Force the location. We should be filtering out diagnostics
123118
// without a location.
124-
self.location = diagnostic.location!
119+
self.filename = diagnostic.location!.filename
120+
self.utf8Offset = diagnostic.location!.offset
125121
}
126122
}
127123

@@ -379,17 +375,10 @@ private struct SourceFile {
379375
throw Error.failedToResolveSourceLocation
380376
}
381377

382-
guard location.offset == 0 else {
383-
return AbsolutePosition(utf8Offset: Int(location.offset))
384-
}
385-
386-
return self.sourceLocationConverter.position(
387-
ofLine: Int(location.line),
388-
column: Int(location.column)
389-
)
378+
return AbsolutePosition(utf8Offset: Int(location.offset))
390379
}
391380

392-
func node(at location: some AnySourceLocation) throws -> Syntax {
381+
func node(at location: borrowing some AnySourceLocation) throws -> Syntax {
393382
let position = try position(of: location)
394383

395384
if let token = syntax.token(at: position) {

0 commit comments

Comments
 (0)