Skip to content

Commit 0a38abb

Browse files
authored
Promote SourceLocation._filePath to proper, non-underscored SPI. (#1334)
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. (We'll need to introduce an `EncodedSourceLocation` structure at that point and keep including the underscored key for the v0 JSON stream, but that's not a "today" problem.) ### Checklist: - [x] Code and documentation should follow the style of the [Style Guide](https://github.com/apple/swift-testing/blob/main/Documentation/StyleGuide.md). - [x] If public symbols are renamed or modified, DocC references should be updated.
1 parent 894fc62 commit 0a38abb

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

Sources/Testing/SourceAttribution/SourceLocation.swift

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

Tests/TestingTests/SourceLocationTests.swift

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,18 @@ struct SourceLocationTests {
121121
}
122122
#endif
123123

124-
@Test("SourceLocation._filePath property")
124+
@Test("SourceLocation.filePath property")
125125
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)
134+
@Test("SourceLocation._filePath property")
135+
func sourceLocation_FilePath() {
126136
var sourceLocation = #_sourceLocation
127137
#expect(sourceLocation._filePath == #filePath)
128138

0 commit comments

Comments
 (0)