Skip to content

Commit 1d5aba8

Browse files
add a "references" relationship kind and referenceLocation mixin (#59)
rdar://108470705
1 parent 53e5cb9 commit 1d5aba8

File tree

4 files changed

+88
-0
lines changed

4 files changed

+88
-0
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import Foundation
12+
13+
extension SymbolGraph.Relationship {
14+
/// A mixin for `references` relationships that indicates the source location of the reference.
15+
public struct ReferenceLocation: Mixin, Codable, Equatable {
16+
public static var mixinKey = "referenceLocation"
17+
18+
/// The source locations where the reference occurs.
19+
public var range: SymbolGraph.LineList.SourceRange
20+
21+
/// The URI of the source file where the reference occurs.
22+
public var uri: String
23+
24+
/// The file URL of the source file where the reference occurs.
25+
@available(macOS 10.11, *)
26+
public var url: URL? {
27+
// The URI string provided in the symbol graph file may be an invalid URL (rdar://69242070)
28+
//
29+
// Using `URL.init(dataRepresentation:relativeTo:)` here handles URI strings with unescaped
30+
// characters without trying to escape or otherwise process the URI string in SymbolKit.
31+
return URL(dataRepresentation: Data(uri.utf8), relativeTo: nil)
32+
}
33+
34+
public init(range: SymbolGraph.LineList.SourceRange, uri: String) {
35+
self.range = range
36+
self.uri = uri
37+
}
38+
}
39+
}

Sources/SymbolKit/SymbolGraph/Relationship/Relationship.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,12 @@ extension SymbolGraph.Relationship {
116116
// Mixins
117117
static let swiftConstraints = Swift.GenericConstraints.relationshipCodingInfo
118118
static let sourceOrigin = SourceOrigin.relationshipCodingInfo
119+
static let referenceLocation = ReferenceLocation.relationshipCodingInfo
119120

120121
static let mixinKeys: [String: RelationshipMixinCodingInfo] = [
121122
CodingKeys.swiftConstraints.codingKey.stringValue: Self.swiftConstraints,
122123
CodingKeys.sourceOrigin.codingKey.stringValue: Self.sourceOrigin,
124+
CodingKeys.referenceLocation.codingKey.stringValue: Self.referenceLocation,
123125
]
124126

125127
static func == (lhs: SymbolGraph.Relationship.CodingKeys, rhs: SymbolGraph.Relationship.CodingKeys) -> Bool {

Sources/SymbolKit/SymbolGraph/Relationship/RelationshipKind.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,5 +107,16 @@ extension SymbolGraph.Relationship {
107107
by an extension block symbol `A`.
108108
*/
109109
public static let extensionTo = Kind(rawValue: "extensionTo")
110+
111+
/**
112+
A symbol `A` references a symbol `B` in its implementation.
113+
114+
This relationship can be used to describe implementation details of functions or
115+
properties, by noting which symbols are used in its implementation.
116+
117+
The implied inverse of this relationship is that the symbol `B` is referenced by the
118+
symbol `A`.
119+
*/
120+
public static let references = Kind(rawValue: "references")
110121
}
111122
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
This source file is part of the Swift.org open source project
3+
4+
Copyright (c) 2023 Apple Inc. and the Swift project authors
5+
Licensed under Apache License v2.0 with Runtime Library Exception
6+
7+
See https://swift.org/LICENSE.txt for license information
8+
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
9+
*/
10+
11+
import XCTest
12+
@testable import SymbolKit
13+
14+
class ReferenceLocationTests: XCTestCase {
15+
typealias ReferenceLocation = SymbolGraph.Relationship.ReferenceLocation
16+
17+
func testRoundTrip() throws {
18+
let referenceLocation = ReferenceLocation(
19+
range: .init(
20+
start: .init(line: 14, character: 0),
21+
end: .init(line: 14, character: 6)),
22+
uri: "file://file.swift"
23+
)
24+
var source = SymbolGraph.Relationship(source: "source", target: "target", kind: .references, targetFallback: nil)
25+
source[mixin: ReferenceLocation.self] = referenceLocation
26+
27+
let encoder = JSONEncoder()
28+
let decoder = JSONDecoder()
29+
30+
let encodedRelationship = try encoder.encode(source)
31+
let decoded = try decoder.decode(SymbolGraph.Relationship.self, from: encodedRelationship)
32+
33+
XCTAssertEqual(source, decoded)
34+
XCTAssertEqual(decoded[mixin: ReferenceLocation.self], referenceLocation)
35+
}
36+
}

0 commit comments

Comments
 (0)