@@ -12,56 +12,107 @@ extension ABI {
1212 /// A type implementing the JSON encoding of ``SourceLocation`` for the ABI
1313 /// entry point and event stream output.
1414 ///
15- /// This type is not part of the public interface of the testing library. It
16- /// assists in converting values to JSON; clients that consume this JSON are
17- /// expected to write their own decoders.
18- struct EncodedSourceLocation < V> : Sendable where V: ABI . Version {
19- /// See ``SourceLocation`` for a discussion of these properties.
20- var fileID : String ?
21- var filePath : String ?
22- var _filePath : String ?
23- var line : Int
24- var column : Int
15+ /// You can use this type and its conformance to [`Codable`](https://developer.apple.com/documentation/swift/codable),
16+ /// when integrating the testing library with development tools. It is not
17+ /// part of the testing library's public interface.
18+ public struct EncodedSourceLocation < V> : Sendable where V: ABI . Version {
19+ /// The file ID of the source file.
20+ public var fileID : String ?
2521
26- init ( encoding sourceLocation: borrowing SourceLocation ) {
27- fileID = sourceLocation. fileID
28-
29- // When using the 6.3 schema, don't encode synthesized file IDs.
30- if V . versionNumber >= ABI . v6_3. versionNumber,
31- sourceLocation. moduleName == SourceLocation . synthesizedModuleName {
32- fileID = nil
33- }
34-
35- // When using the 6.3 schema, we encode both "filePath" and "_filePath" to
36- // ease migration for existing tools.
37- if V . versionNumber >= ABI . v6_3. versionNumber {
38- filePath = sourceLocation. filePath
22+ /// The file path of the source file.
23+ public var filePath : String ? {
24+ get {
25+ _filePath_v6_3 ?? _filePath_v0
3926 }
40- if V . versionNumber <= ABI . v6_3. versionNumber {
41- _filePath = sourceLocation. filePath
27+ set {
28+ // When using the 6.3 schema, we encode both "filePath" and "_filePath"
29+ // to ease migration for existing tools.
30+ if V . versionNumber >= ABI . v6_3. versionNumber {
31+ _filePath_v6_3 = newValue
32+ }
33+ if V . versionNumber <= ABI . v6_3. versionNumber {
34+ _filePath_v0 = newValue
35+ }
4236 }
43-
44- line = sourceLocation. line
45- column = sourceLocation. column
4637 }
38+
39+ /// The line in the source file.
40+ public var line : Int = 1
41+
42+ /// The column in the source file.
43+ public var column : Int = 1
44+
45+ /// Storage for ``filePath`` under the `"_filePath"` JSON key, as used prior
46+ /// to Swift 6.3.
47+ private var _filePath_v0 : String ?
48+
49+ /// Storage for ``filePath`` under the `"filePath"` JSON key, as used in
50+ /// Swift 6.3 and newer.
51+ private var _filePath_v6_3 : String ?
4752 }
4853}
4954
5055// MARK: - Codable
5156
52- extension ABI . EncodedSourceLocation : Codable { }
57+ extension ABI . EncodedSourceLocation : Codable {
58+ private enum CodingKeys : String , CodingKey {
59+ case fileID
60+ case _filePath_v0 = " _filePath "
61+ case _filePath_v6_3 = " filePath "
62+ case line
63+ case column
64+ }
65+ }
66+
67+ // MARK: - Conversion to/from library types
68+
69+ @_spi ( ForToolsIntegrationOnly)
70+ extension ABI . EncodedSourceLocation {
71+ /// Initialize an instance of this type from the given value.
72+ ///
73+ /// - Parameters:
74+ /// - sourceLocation: The source location to initialize this instance from.
75+ public init ( encoding sourceLocation: borrowing SourceLocation ) {
76+ fileID = sourceLocation. fileID
77+ filePath = sourceLocation. filePath
78+ line = sourceLocation. line
79+ column = sourceLocation. column
5380
54- // MARK: -
81+ // When using the 6.3 schema, don't encode synthesized file IDs.
82+ if V . versionNumber >= ABI . v6_3. versionNumber,
83+ sourceLocation. moduleName == SourceLocation . synthesizedModuleName {
84+ fileID = nil
85+ }
86+ }
87+ }
5588
89+ @_spi ( ForToolsIntegrationOnly)
5690extension SourceLocation {
57- init ? < V> ( _ sourceLocation: ABI . EncodedSourceLocation < V > ) {
91+ /// Initialize an instance of this type from the given value.
92+ ///
93+ /// - Parameters:
94+ /// - sourceLocation: The encoded source location to initialize this
95+ /// instance from.
96+ ///
97+ /// If `sourceLocation` does not specify a value for its `fileID` field, the
98+ /// testing library synthesizes a value from its `filePath` property and
99+ /// hard-codes a module name of `"__C"`.
100+ ///
101+ /// If `sourceLocation` does not specify a value for its `filePath` field,
102+ /// this initializer returns `nil`.
103+ public init ? < V> ( decoding sourceLocation: ABI . EncodedSourceLocation < V > ) {
58104 let fileID = sourceLocation. fileID
59- guard let filePath = sourceLocation. filePath ?? sourceLocation. _filePath else {
60- return nil
61- }
105+ let filePath = sourceLocation. filePath
62106 let line = max ( 1 , sourceLocation. line)
63107 let column = max ( 1 , sourceLocation. column)
64108
109+ if let fileID, !fileID. utf8. contains ( UInt8 ( ascii: " / " ) ) {
110+ return nil
111+ }
112+ guard let filePath else {
113+ return nil
114+ }
115+
65116 self . init ( fileIDSynthesizingIfNeeded: fileID, filePath: filePath, line: line, column: column)
66117 }
67118}
0 commit comments