Skip to content

Commit d5c4d5a

Browse files
committed
Promote SourceLocation._filePath to proper, non-underscored SPI.
This PR introduces an `@_spi var filePath` property on `SourceLocation` with the intent of replacing the existing underscored/unsupported `_filePath` property. Because Xcode 16 through 26 directly encodes and decodes instances of `SourceLocation`, we can't just stop encoding/decoding the `_filePath` key and need to keep it there for at least a Swift release or two, until Apple's fork of Swift Testing has been updated to include the new encoding key. At that point we can remove the old one.
1 parent 894fc62 commit d5c4d5a

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

Sources/Testing/SourceAttribution/SourceLocation.swift

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,8 @@ public struct SourceLocation: Sendable {
7171
}
7272

7373
/// The path to the source file.
74-
///
75-
/// - Warning: This property is provided temporarily to aid in integrating the
76-
/// testing library with existing tools such as Swift Package Manager. It
77-
/// will be removed in a future release.
78-
public var _filePath: String
74+
@_spi(Experimental)
75+
public var filePath: String
7976

8077
/// The line in the source file.
8178
///
@@ -118,7 +115,7 @@ public struct SourceLocation: Sendable {
118115
precondition(column > 0, "SourceLocation.column must be greater than 0 (was \(column))")
119116

120117
self.fileID = fileID
121-
self._filePath = filePath
118+
self.filePath = filePath
122119
self.line = line
123120
self.column = column
124121
}
@@ -167,4 +164,54 @@ extension SourceLocation: CustomStringConvertible, CustomDebugStringConvertible
167164

168165
// MARK: - Codable
169166

170-
extension SourceLocation: Codable {}
167+
extension SourceLocation: Codable {
168+
private enum CodingKeys: String, CodingKey {
169+
case fileID
170+
case filePath
171+
case _filePath
172+
case line
173+
case column
174+
}
175+
176+
func encode(to encoder: any Encoder) throws {
177+
var container = encoder.container(keyedBy: CodingKeys.self)
178+
try container.encode(fileID, forKey: .fileID)
179+
try container.encode(line, forKey: .line)
180+
try container.encode(column, forKey: .column)
181+
182+
// For backwards-compatibility, we must always encode "_filePath".
183+
try container.encode(filePath, forKey: ._filePath)
184+
try container.encode(filePath, forKey: .filePath)
185+
}
186+
187+
init(from decoder: any Decoder) throws {
188+
let container = try decoder.container(keyedBy: CodingKeys.self)
189+
fileID = try container.decode(String.self, forKey: .fileID)
190+
line = try container.decode(Int.self, forKey: .line)
191+
column = try container.decode(Int.self, forKey: .column)
192+
193+
// For simplicity's sake, we won't be picky about which key contains the
194+
// file path.
195+
filePath = try container.decodeIfPresent(String.self, forKey: ._filePath)
196+
?? try container.decode(String.self, forKey: .filePath)
197+
}
198+
}
199+
200+
// MARK: - Deprecated
201+
202+
extension SourceLocation {
203+
/// The path to the source file.
204+
///
205+
/// - Warning: This property is provided temporarily to aid in integrating the
206+
/// testing library with existing tools such as Swift Package Manager. It
207+
/// will be removed in a future release.
208+
@available(swift, deprecated: 100000.0, renamed: "filePath")
209+
public var _filePath: String {
210+
get {
211+
filePath
212+
}
213+
set {
214+
filePath = newValue
215+
}
216+
}
217+
}

Tests/TestingTests/SourceLocationTests.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@ struct SourceLocationTests {
121121
}
122122
#endif
123123

124+
@Test("SourceLocation.filePath property")
125+
func sourceLocationFilePath() {
126+
var sourceLocation = #_sourceLocation
127+
#expect(sourceLocation.filePath == #filePath)
128+
129+
sourceLocation.filePath = "A"
130+
#expect(sourceLocation.filePath == "A")
131+
}
132+
133+
@available(swift, deprecated: 100000.0)
124134
@Test("SourceLocation._filePath property")
125135
func sourceLocationFilePath() {
126136
var sourceLocation = #_sourceLocation

0 commit comments

Comments
 (0)