Skip to content

Commit d9ec4ae

Browse files
Add successfully resolved external references to reference index (#582)
* Add successfully resolved external references to reference index rdar://108974747 * Undo accidental whitespace change Co-authored-by: Ethan Kusters <[email protected]>
1 parent dd9c44c commit d9ec4ae

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

Sources/SwiftDocC/Infrastructure/DocumentationContext.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2442,6 +2442,9 @@ public class DocumentationContext: DocumentationContextDataProviderDelegate {
24422442
for reference in knownIdentifiers {
24432443
referenceIndex[reference.absoluteString] = reference
24442444
}
2445+
for case .success(let reference) in externallyResolvedLinks.values {
2446+
referenceIndex[reference.absoluteString] = reference
2447+
}
24452448
for reference in nodeAnchorSections.keys {
24462449
referenceIndex[reference.absoluteString] = reference
24472450
}

Sources/SwiftDocC/Model/Rendering/RenderContentCompiler.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,16 @@ struct RenderContentCompiler: MarkupVisitor {
207207

208208
mutating func resolveTopicReference(_ destination: String) -> ResolvedTopicReference? {
209209
if let cached = context.referenceIndex[destination] {
210+
if let node = context.topicGraph.nodeWithReference(cached), !context.topicGraph.isLinkable(node.reference) {
211+
return nil
212+
}
210213
collectedTopicReferences.append(cached)
211214
return cached
212215
}
213216

217+
// FIXME: Links from this build already exist in the reference index and don't need to be resolved again.
218+
// https://github.com/apple/swift-docc/issues/581
219+
214220
guard let validatedURL = ValidatedURL(parsingAuthoredLink: destination) else {
215221
return nil
216222
}

Tests/SwiftDocCTests/Infrastructure/ExternalReferenceResolverTests.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import XCTest
1212
@testable import SwiftDocC
1313
import Markdown
1414
import SymbolKit
15+
import SwiftDocCTestUtilities
1516

1617
class ExternalReferenceResolverTests: XCTestCase {
1718
class TestExternalReferenceResolver: ExternalReferenceResolver, FallbackReferenceResolver {
@@ -399,6 +400,66 @@ Document @1:1-1:35
399400
])
400401
}
401402

403+
func testExternalReferenceWithDifferentResolvedPath() throws {
404+
let externalResolver = TestExternalReferenceResolver()
405+
externalResolver.bundleIdentifier = "com.test.external"
406+
// Return a different path for this resolved reference
407+
externalResolver.expectedReferencePath = "/path/to/externally-resolved-symbol"
408+
externalResolver.resolvedEntityTitle = "ClassName"
409+
externalResolver.resolvedEntityKind = .class
410+
411+
let tempFolder = try createTempFolder(content: [
412+
Folder(name: "SingleArticleWithExternalLink.docc", content: [
413+
TextFile(name: "article.md", utf8Content: """
414+
# Article with external link
415+
416+
@Metadata {
417+
@TechnologyRoot
418+
}
419+
420+
Link to an external page: <doc://com.test.external/path/to/external/symbol>
421+
""")
422+
])
423+
])
424+
425+
let workspace = DocumentationWorkspace()
426+
let context = try DocumentationContext(dataProvider: workspace)
427+
context.externalReferenceResolvers = [externalResolver.bundleIdentifier: externalResolver]
428+
let dataProvider = try LocalFileSystemDataProvider(rootURL: tempFolder)
429+
try workspace.registerProvider(dataProvider)
430+
let bundle = try XCTUnwrap(workspace.bundles.first?.value)
431+
432+
let converter = DocumentationNodeConverter(bundle: bundle, context: context)
433+
let node = try context.entity(with: ResolvedTopicReference(bundleIdentifier: bundle.identifier, path: "/documentation/article", sourceLanguage: .swift))
434+
435+
guard let fileURL = context.documentURL(for: node.reference) else {
436+
XCTFail("Unable to find the file for \(node.reference.path)")
437+
return
438+
}
439+
440+
let renderNode = try converter.convert(node, at: fileURL)
441+
442+
XCTAssertEqual(externalResolver.resolvedExternalPaths, ["/path/to/external/symbol"], "The authored link was resolved")
443+
444+
// Verify that the article contains the external reference
445+
guard let symbolRenderReference = renderNode.references["doc://com.test.external/path/to/externally-resolved-symbol"] as? TopicRenderReference else {
446+
XCTFail("The external reference should be resolved and included among the article's references.")
447+
return
448+
}
449+
450+
XCTAssertEqual(symbolRenderReference.identifier.identifier, "doc://com.test.external/path/to/externally-resolved-symbol")
451+
XCTAssertEqual(symbolRenderReference.title, "ClassName")
452+
XCTAssertEqual(symbolRenderReference.url, "/example/path/to/externally-resolved-symbol") // External references in topic groups use relative URLs
453+
XCTAssertEqual(symbolRenderReference.kind, .symbol)
454+
455+
// Verify that the rendered abstract contains the resolved link
456+
if case RenderInlineContent.reference(identifier: let identifier, isActive: true, overridingTitle: _, overridingTitleInlineContent: _)? = renderNode.abstract?.last {
457+
XCTAssertEqual(identifier.identifier, "doc://com.test.external/path/to/externally-resolved-symbol")
458+
} else {
459+
XCTFail("Unexpected abstract content: \(renderNode.abstract ?? [])")
460+
}
461+
}
462+
402463
func testSampleCodeReferenceHasSampleCodeRole() throws {
403464
let externalResolver = TestExternalReferenceResolver()
404465
externalResolver.bundleIdentifier = "com.test.external"

0 commit comments

Comments
 (0)