Skip to content

Commit 7b5f149

Browse files
authored
Use both URS and name to add symbols to the right language representation of their container symbol (#765)
rdar://119300362
1 parent 2cc8b69 commit 7b5f149

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,18 @@ struct PathHierarchy {
122122

123123
var topLevelCandidates = nodes
124124
for relationship in graph.relationships where relationship.kind.formsHierarchy {
125-
guard let sourceNode = nodes[relationship.source] else {
125+
guard let sourceNode = nodes[relationship.source], let expectedContainerName = sourceNode.symbol?.pathComponents.dropLast().last else {
126126
continue
127127
}
128-
if let targetNode = nodes[relationship.target] {
128+
// The relationship only specify the target symbol's USR but if the target symbol has different representations in different source languages the relationship
129+
// alone doesn't specify which language representation the source symbol belongs to. We could check the source and target symbol's interface language but that
130+
// would require that we redundantly create multiple nodes for the same symbol in many common cases and then merge them. To avoid doing that, we instead check
131+
// the source symbol's path components to find the correct target symbol by matching its name.
132+
if let targetNode = nodes[relationship.target], targetNode.name == expectedContainerName {
129133
targetNode.add(symbolChild: sourceNode)
130134
topLevelCandidates.removeValue(forKey: relationship.source)
131135
} else if let targetNodes = allNodes[relationship.target] {
132-
for targetNode in targetNodes {
136+
for targetNode in targetNodes where targetNode.name == expectedContainerName {
133137
targetNode.add(symbolChild: sourceNode)
134138
}
135139
topLevelCandidates.removeValue(forKey: relationship.source)

Tests/SwiftDocCTests/Infrastructure/PathHierarchyTests.swift

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1575,7 +1575,7 @@ class PathHierarchyTests: XCTestCase {
15751575
XCTAssertEqual(paths["X.Y2.Z.W"], "/Module/X/Y2/Z/W")
15761576
}
15771577

1578-
func testMixedLanguageSymbolWithItsExtendingModule() throws {
1578+
func testMixedLanguageSymbolAndItsExtendingModule() throws {
15791579
let containerID = "some-container-symbol-id"
15801580
let memberID = "some-member-symbol-id"
15811581

@@ -1618,6 +1618,49 @@ class PathHierarchyTests: XCTestCase {
16181618
XCTAssertEqual(paths[memberID], "/ModuleName/ContainerName/MemberName")
16191619
}
16201620

1621+
func testMixedLanguageSymbolAndItsExtendingModuleWithDifferentContainerNames() throws {
1622+
let containerID = "some-container-symbol-id"
1623+
let memberID = "some-member-symbol-id"
1624+
1625+
let exampleDocumentation = Folder(name: "unit-test.docc", content: [
1626+
Folder(name: "clang", content: [
1627+
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
1628+
moduleName: "ModuleName",
1629+
symbols: [
1630+
(containerID, .objectiveC, ["ObjectiveCContainerName"])
1631+
]
1632+
)),
1633+
]),
1634+
1635+
Folder(name: "swift", content: [
1636+
JSONFile(name: "ModuleName.symbols.json", content: makeSymbolGraph(
1637+
moduleName: "ModuleName",
1638+
symbols: [
1639+
(containerID, .swift, ["SwiftContainerName"])
1640+
]
1641+
)),
1642+
1643+
JSONFile(name: "[email protected]", content: makeSymbolGraph(
1644+
moduleName: "ExtendingModule",
1645+
symbols: [
1646+
(memberID, .swift, ["SwiftContainerName", "MemberName"])
1647+
],
1648+
relationships: [
1649+
.init(source: memberID, target: containerID, kind: .memberOf, targetFallback: nil)
1650+
]
1651+
)),
1652+
])
1653+
])
1654+
1655+
let tempURL = try createTempFolder(content: [exampleDocumentation])
1656+
let (_, _, context) = try loadBundle(from: tempURL)
1657+
let tree = try XCTUnwrap(context.linkResolver.localResolver?.pathHierarchy)
1658+
1659+
let paths = tree.caseInsensitiveDisambiguatedPaths()
1660+
XCTAssertEqual(paths[containerID], "/ModuleName/SwiftContainerName")
1661+
XCTAssertEqual(paths[memberID], "/ModuleName/SwiftContainerName/MemberName")
1662+
}
1663+
16211664
func testOptionalMemberUnderCorrectContainer() throws {
16221665
let containerID = "some-container-symbol-id"
16231666
let otherID = "some-other-symbol-id"

0 commit comments

Comments
 (0)