You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix crash caused by repeatedly cloning the same path hierarchy node (#1220)
* Don't repeatedly clone nodes that have already been cloned
rdar://150706871
* Fix unrelated code warning about unused local variable
* Fix unrelated list of symbols in other assertion message
* Avoid repetition in debug assertions
* Only create sparse nodes after processing all symbol graph files
* Try to find existing nodes before creating sparse nodes
rdar://148247074
* Remove trailing commas for compatibility before Swift 6.1
* Remove unintentional print statement
* Try to repair symbol graphs with deep hierarchies but no actual memberOf relationships
* Add additional test assertion about counterpart references
Copy file name to clipboardExpand all lines: Sources/SwiftDocC/Infrastructure/Link Resolution/PathHierarchy.swift
+94-41Lines changed: 94 additions & 41 deletions
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
/*
2
2
This source file is part of the Swift.org open source project
3
3
4
-
Copyright (c) 2022-2024 Apple Inc. and the Swift project authors
4
+
Copyright (c) 2022-2025 Apple Inc. and the Swift project authors
5
5
Licensed under Apache License v2.0 with Runtime Library Exception
6
6
7
7
See https://swift.org/LICENSE.txt for license information
@@ -74,7 +74,11 @@ struct PathHierarchy {
74
74
.sorted(by:{ lhs, rhs in
75
75
return !lhs.url.lastPathComponent.contains("@")
76
76
})
77
-
77
+
78
+
// To try to handle certain invalid symbol graph files gracefully, we track symbols that don't have a place in the hierarchy so that we can look for a place for those symbols.
79
+
// Because this is a last resort, we only want to do this processing after all the symbol graphs have already been processed.
// If the node we have for the child has an existing parent that doesn't
155
162
// match the parent from this symbol graph, we need to clone the child to
156
163
// ensure that the hierarchy remains consistent.
@@ -166,7 +173,7 @@ struct PathHierarchy {
166
173
sourceNode.languages.remove(language!)
167
174
168
175
// Make sure that the clone's children can all line up with symbols from this symbol graph.
169
-
for(childName,children)in sourceNode.children {
176
+
forchildrenin sourceNode.children.values{
170
177
forchildin children.storage {
171
178
guardlet childSymbol = child.node.symbol else{
172
179
// We shouldn't come across any non-symbol nodes here,
@@ -198,8 +205,13 @@ struct PathHierarchy {
198
205
// If the source was added in an extension symbol graph file, then its target won't be found in the same symbol graph file (in `nodes`).
199
206
200
207
// We may have encountered multiple language representations of the target symbol. Try to find the best matching representation of the target to add the source to.
201
-
// Remove any targets that don't match the source symbol's path components (see comment above for more details).
// This code path is both expected (when `knownDisambiguatedPathComponents` is non-nil) and unexpected (when the symbol graph is missing data or contains extra relationships).
301
+
// It would be good to restructure this code to better distinguish what's supported behavior and what's a best-effort attempt at gracefully handle invalid symbol graphs.
302
+
iflet existing = parent.children[component]{
303
+
// This code tries to repair incomplete symbol graph files by guessing that the symbol with the most overlapping languages is the intended container.
304
+
// Valid symbol graph files we should never end up here.
Every node's findable parent should exist in the lookup. \
436
-
This wasn't true for \(lookup.values.filter({ $0.parent?.identifier !=nil && lookup[$0.parent!.identifier]==nil}).map(\.symbol!.identifier.precise).sorted())
0 commit comments