Skip to content

Commit 8401492

Browse files
committed
Populate declaration fragments in navigator metadata for external links
Now that the declaration fragments will be the abbreviated declaration fragments from `LinkDestinationSummary`, we can propagate those to the navigator metadata for them to be used to inform the title of the navigator item [1]. Fixes rdar://156488052. [1]: https://github.com/swiftlang/swift-docc/blob/65aaf926ec079ddbd40f29540d4180a70af99e5e/Sources/SwiftDocC/Indexing/Navigator/RenderNode%2BNavigatorIndex.swift#L140
1 parent 5a3e31d commit 8401492

File tree

2 files changed

+24
-15
lines changed

2 files changed

+24
-15
lines changed

Sources/SwiftDocC/Infrastructure/Link Resolution/LinkResolver+NavigatorIndex.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ struct NavigatorExternalRenderNode: NavigatorIndexableRenderNodeRepresentation {
117117
externalID: renderNode.externalIdentifier.identifier,
118118
role: renderNode.role,
119119
symbolKind: renderNode.symbolKind?.identifier,
120-
images: renderNode.images
120+
images: renderNode.images,
121+
fragments: renderNode.fragmentsVariants.value(for: traits)
121122
)
122123
}
123124
}
@@ -130,19 +131,16 @@ struct ExternalRenderNodeMetadataRepresentation: NavigatorIndexableRenderMetadat
130131
var role: String?
131132
var symbolKind: String?
132133
var images: [TopicImage]
134+
var fragments: [DeclarationRenderSection.Token]?
133135

134136
// Values that we have insufficient information to derive.
135137
// These are needed to conform to the navigator indexable metadata protocol.
136138
//
137-
// The fragments that we get as part of the external link are the full declaration fragments.
138-
// These are too verbose for the navigator, so instead of using them, we rely on the title, navigator title and symbol kind instead.
139-
//
140139
// The role heading is used to identify Property Lists.
141140
// The value being missing is used for computing the final navigator title.
142141
//
143142
// The platforms are used for generating the availability index,
144143
// but doesn't affect how the node is rendered in the sidebar.
145-
var fragments: [DeclarationRenderSection.Token]? = nil
146144
var roleHeading: String? = nil
147145
var platforms: [AvailabilityRenderItem]? = nil
148-
}
146+
}

Tests/SwiftDocCTests/Indexing/ExternalRenderNodeTests.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import XCTest
1313
@_spi(ExternalLinks) @testable import SwiftDocC
1414

1515
class ExternalRenderNodeTests: XCTestCase {
16-
func generateExternalResover() -> TestMultiResultExternalReferenceResolver {
16+
func generateExternalResolver() -> TestMultiResultExternalReferenceResolver {
1717
let externalResolver = TestMultiResultExternalReferenceResolver()
1818
externalResolver.bundleID = "com.test.external"
1919
externalResolver.entitiesToReturn["/path/to/external/swiftArticle"] = .success(
@@ -37,23 +37,32 @@ class ExternalRenderNodeTests: XCTestCase {
3737
referencePath: "/path/to/external/swiftSymbol",
3838
title: "SwiftSymbol",
3939
kind: .class,
40-
language: .swift
40+
language: .swift,
41+
declarationFragments: .init(declarationFragments: [
42+
.init(kind: .keyword, spelling: "class", preciseIdentifier: nil),
43+
.init(kind: .text, spelling: " ", preciseIdentifier: nil),
44+
.init(kind: .identifier, spelling: "SwiftSymbol", preciseIdentifier: nil)
45+
])
4146
)
4247
)
4348
externalResolver.entitiesToReturn["/path/to/external/objCSymbol"] = .success(
4449
.init(
4550
referencePath: "/path/to/external/objCSymbol",
4651
title: "ObjCSymbol",
4752
kind: .function,
48-
language: .objectiveC
53+
language: .objectiveC,
54+
declarationFragments: .init(declarationFragments: [
55+
.init(kind: .text, spelling: "- ", preciseIdentifier: nil),
56+
.init(kind: .identifier, spelling: "ObjCSymbol", preciseIdentifier: nil),
57+
])
4958
)
5059
)
5160
return externalResolver
5261
}
5362

5463
func testExternalRenderNode() throws {
5564

56-
let externalResolver = generateExternalResover()
65+
let externalResolver = generateExternalResolver()
5766
let (_, bundle, context) = try testBundleAndContext(
5867
copying: "MixedLanguageFramework",
5968
externalResolvers: [externalResolver.bundleID: externalResolver]
@@ -146,16 +155,18 @@ class ExternalRenderNodeTests: XCTestCase {
146155
)
147156
XCTAssertEqual(swiftNavigatorExternalRenderNode.metadata.title, swiftTitle)
148157
XCTAssertEqual(swiftNavigatorExternalRenderNode.metadata.navigatorTitle, navigatorTitle)
158+
XCTAssertEqual(swiftNavigatorExternalRenderNode.metadata.fragments, fragments)
149159

150160
let objcNavigatorExternalRenderNode = try XCTUnwrap(
151161
NavigatorExternalRenderNode(renderNode: externalRenderNode, trait: .interfaceLanguage("objc"))
152162
)
153163
XCTAssertEqual(objcNavigatorExternalRenderNode.metadata.title, occTitle)
154164
XCTAssertEqual(objcNavigatorExternalRenderNode.metadata.navigatorTitle, occNavigatorTitle)
165+
XCTAssertEqual(objcNavigatorExternalRenderNode.metadata.fragments, occFragments)
155166
}
156167

157168
func testNavigatorWithExternalNodes() throws {
158-
let externalResolver = generateExternalResover()
169+
let externalResolver = generateExternalResolver()
159170
let (_, bundle, context) = try testBundleAndContext(
160171
copying: "MixedLanguageFramework",
161172
externalResolvers: [externalResolver.bundleID: externalResolver]
@@ -204,14 +215,14 @@ class ExternalRenderNodeTests: XCTestCase {
204215
let occExternalNodes = renderIndex.interfaceLanguages["occ"]?.first { $0.path == "/documentation/mixedlanguageframework" }?.children?.filter { $0.path?.contains("/path/to/external") ?? false } ?? []
205216
XCTAssertEqual(swiftExternalNodes.count, 2)
206217
XCTAssertEqual(occExternalNodes.count, 2)
207-
XCTAssertEqual(swiftExternalNodes.map(\.title), ["SwiftArticle", "SwiftSymbol"])
208-
XCTAssertEqual(occExternalNodes.map(\.title), ["ObjCArticle", "ObjCSymbol"])
218+
XCTAssertEqual(swiftExternalNodes.map(\.title), ["SwiftArticle", "class SwiftSymbol"])
219+
XCTAssertEqual(occExternalNodes.map(\.title), ["ObjCArticle", "- ObjCSymbol"])
209220
XCTAssert(swiftExternalNodes.allSatisfy(\.isExternal))
210221
XCTAssert(occExternalNodes.allSatisfy(\.isExternal))
211222
}
212223

213224
func testNavigatorWithExternalNodesOnlyAddsCuratedNodesToNavigator() throws {
214-
let externalResolver = generateExternalResover()
225+
let externalResolver = generateExternalResolver()
215226

216227
let (_, bundle, context) = try testBundleAndContext(
217228
copying: "MixedLanguageFramework",
@@ -265,7 +276,7 @@ class ExternalRenderNodeTests: XCTestCase {
265276
XCTAssertEqual(swiftExternalNodes.count, 1)
266277
XCTAssertEqual(occExternalNodes.count, 1)
267278
XCTAssertEqual(swiftExternalNodes.map(\.title), ["SwiftArticle"])
268-
XCTAssertEqual(occExternalNodes.map(\.title), ["ObjCSymbol"])
279+
XCTAssertEqual(occExternalNodes.map(\.title), ["- ObjCSymbol"])
269280
XCTAssert(swiftExternalNodes.allSatisfy(\.isExternal))
270281
XCTAssert(occExternalNodes.allSatisfy(\.isExternal))
271282
}

0 commit comments

Comments
 (0)