@@ -194,7 +194,9 @@ extension ExtendedTypesFormatTransformation {
194
194
195
195
var ( extendedTypeSymbols,
196
196
extensionBlockToExtendedTypeMapping,
197
- extendedTypeToExtensionBlockMapping) = synthesizeExtendedTypeSymbols ( using: extensionBlockSymbols, extensionToRelationships)
197
+ extendedTypeToExtensionBlockMapping) = synthesizePrimaryExtendedTypeSymbols ( using: extensionBlockSymbols, extensionToRelationships)
198
+
199
+ let contextOfRelationships = synthesizeSecondaryExtendedTypeSymbols ( & extendedTypeSymbols)
198
200
199
201
redirect ( \. target, of: & memberOfRelationships, using: extensionBlockToExtendedTypeMapping)
200
202
@@ -217,12 +219,79 @@ extension ExtendedTypesFormatTransformation {
217
219
218
220
symbolGraph. relationships. append ( contentsOf: memberOfRelationships)
219
221
symbolGraph. relationships. append ( contentsOf: conformsToRelationships)
222
+ symbolGraph. relationships. append ( contentsOf: contextOfRelationships)
220
223
extendedTypeSymbols. values. forEach { symbol in symbolGraph. symbols [ symbol. identifier. precise] = symbol }
221
224
222
- try synthesizeExtendedModuleSymbolsAndDeclaredInRelationships ( on: & symbolGraph, using: extendedTypeSymbols. values. map ( \. identifier. precise) )
225
+ try synthesizeExtendedModuleSymbolsAndDeclaredInRelationships ( on: & symbolGraph, using: extendedTypeSymbols. values. filter { symbol in symbol . pathComponents . count == 2 } . map ( \. identifier. precise) )
223
226
224
227
return true
225
228
}
229
+
230
+ private static func synthesizeSecondaryExtendedTypeSymbols( _ extendedTypeSymbols: inout [ String : SymbolGraph . Symbol ] ) -> [ SymbolGraph . Relationship ] {
231
+ let sortedKeys : [ ( pathComponents: [ String ] , preciseId: String ) ] = extendedTypeSymbols. map { key, value in
232
+ ( value. pathComponents, key)
233
+ } . sorted ( by: { a, b in a. pathComponents. count <= b. pathComponents. count && a. preciseId < b. preciseId } )
234
+
235
+ var pathComponentsToSymbolIds : [ ArraySlice < String > : String ] = [ : ]
236
+ pathComponentsToSymbolIds. reserveCapacity ( extendedTypeSymbols. count)
237
+ for (key, symbol) in extendedTypeSymbols {
238
+ pathComponentsToSymbolIds [ symbol. pathComponents [ 1 ... ] ] = key
239
+ }
240
+
241
+ func lookupSymbol( _ pathComponents: ArraySlice < String > ) -> SymbolGraph . Symbol ? {
242
+ guard let id = pathComponentsToSymbolIds [ pathComponents] else {
243
+ return nil
244
+ }
245
+
246
+ return extendedTypeSymbols [ id]
247
+ }
248
+
249
+ var relationships = [ SymbolGraph . Relationship] ( )
250
+ var symbolIsConnectedToParent = [ String: Bool] ( )
251
+ symbolIsConnectedToParent. reserveCapacity ( extendedTypeSymbols. count)
252
+
253
+ for (pathComponents, preciseId) in sortedKeys {
254
+ guard var symbol = extendedTypeSymbols [ preciseId] else {
255
+ continue
256
+ }
257
+
258
+ let modulePrefix = pathComponents [ 0 ]
259
+ var pathComponents = pathComponents [ 1 ..< pathComponents. count- 1 ]
260
+
261
+ while !pathComponents. isEmpty {
262
+ let parent = lookupSymbol ( pathComponents) ? . replacing ( \. accessLevel) { oldSymbol in
263
+ max ( oldSymbol. accessLevel, symbol. accessLevel)
264
+ } ?? SymbolGraph . Symbol ( identifier: . init( precise: " s:e: " + symbol. identifier. precise,
265
+ interfaceLanguage: symbol. identifier. interfaceLanguage) ,
266
+ names: . init( title: pathComponents. joined ( separator: " . " ) ,
267
+ navigator: pathComponents. last? . asDeclarationFragment ( . identifier) ,
268
+ subHeading: nil ,
269
+ prose: nil ) ,
270
+ pathComponents: [ modulePrefix] + pathComponents,
271
+ docComment: nil ,
272
+ accessLevel: symbol. accessLevel,
273
+ kind: . unknownExtendedType,
274
+ mixins: symbol. mixins. keeping ( SymbolGraph . Symbol. Swift. Extension. mixinKey) )
275
+
276
+
277
+ pathComponentsToSymbolIds [ pathComponents] = parent. identifier. precise
278
+ extendedTypeSymbols [ parent. identifier. precise] = parent
279
+
280
+ if !symbolIsConnectedToParent[ symbol. identifier. precise, default: false ] {
281
+ relationships. append ( . init( source: symbol. identifier. precise,
282
+ target: parent. identifier. precise,
283
+ kind: . inContextOf,
284
+ targetFallback: parent. title) )
285
+ symbolIsConnectedToParent [ symbol. identifier. precise] = true
286
+ }
287
+
288
+ symbol = parent
289
+ pathComponents. removeLast ( )
290
+ }
291
+ }
292
+
293
+ return relationships
294
+ }
226
295
227
296
/// Tries to obtain `docComment`s for all `targets` and copies the documentaiton from sources to the target.
228
297
///
@@ -344,7 +413,7 @@ extension ExtendedTypesFormatTransformation {
344
413
///
345
414
/// - Returns: - the created extended type symbols keyed by their precise identifier, along with a bidirectional
346
415
/// mapping between the extended type symbols and the `.extension` symbols
347
- private static func synthesizeExtendedTypeSymbols < RS: Sequence > ( using extensionBlockSymbols: [ String : SymbolGraph . Symbol ] ,
416
+ private static func synthesizePrimaryExtendedTypeSymbols < RS: Sequence > ( using extensionBlockSymbols: [ String : SymbolGraph . Symbol ] ,
348
417
_ extensionToRelationships: RS )
349
418
-> ( extendedTypeSymbols: [ String : SymbolGraph . Symbol ] ,
350
419
extensionBlockToExtendedTypeMapping: [ String : String ] ,
@@ -354,10 +423,11 @@ extension ExtendedTypesFormatTransformation {
354
423
var extendedTypeSymbols : [ String : SymbolGraph . Symbol ] = [ : ]
355
424
var extensionBlockToExtendedTypeMapping : [ String : String ] = [ : ]
356
425
var extendedTypeToExtensionBlockMapping : [ String : [ String ] ] = [ : ]
426
+ var pathComponentToExtendedTypeMapping : [ ArraySlice < String > : String ] = [ : ]
357
427
358
428
extensionBlockToExtendedTypeMapping. reserveCapacity ( extensionBlockSymbols. count)
359
429
360
- let createExtendedTypeSymbol = { ( extensionBlockSymbol: SymbolGraph . Symbol , id: String ) -> SymbolGraph . Symbol in
430
+ let createExtendedTypeSymbolAndAnchestors = { ( extensionBlockSymbol: SymbolGraph . Symbol , id: String ) -> SymbolGraph . Symbol in
361
431
var newMixins = [ String: Mixin] ( )
362
432
363
433
if var swiftExtension = extensionBlockSymbol [ mixin: SymbolGraph . Symbol. Swift. Extension. self] {
@@ -408,13 +478,14 @@ extension ExtendedTypesFormatTransformation {
408
478
409
479
let symbol : SymbolGraph . Symbol = extendedTypeSymbols [ extendedSymbolId] ? . replacing ( \. accessLevel) { oldSymbol in
410
480
max ( oldSymbol. accessLevel, extensionBlockSymbol. accessLevel)
411
- } ?? createExtendedTypeSymbol ( extensionBlockSymbol, extendedSymbolId)
481
+ } ?? createExtendedTypeSymbolAndAnchestors ( extensionBlockSymbol, extendedSymbolId)
482
+
483
+ pathComponentToExtendedTypeMapping [ symbol. pathComponents [ ... ] ] = symbol. identifier. precise
412
484
413
485
extendedTypeSymbols [ symbol. identifier. precise] = symbol
414
486
415
487
extensionBlockToExtendedTypeMapping [ extensionTo. source] = symbol. identifier. precise
416
- extendedTypeToExtensionBlockMapping [ symbol. identifier. precise]
417
- = ( extendedTypeToExtensionBlockMapping [ symbol. identifier. precise] ?? [ ] ) + [ extensionBlockSymbol. identifier. precise]
488
+ extendedTypeToExtensionBlockMapping [ symbol. identifier. precise, default: [ ] ] += [ extensionBlockSymbol. identifier. precise]
418
489
}
419
490
420
491
return ( extendedTypeSymbols, extensionBlockToExtendedTypeMapping, extendedTypeToExtensionBlockMapping)
@@ -522,3 +593,21 @@ private extension SymbolGraph.Relationship {
522
593
return new
523
594
}
524
595
}
596
+
597
+ private extension String {
598
+ func asDeclarationFragment( _ kind: SymbolGraph . Symbol . DeclarationFragments . Fragment . Kind ) -> [ SymbolGraph . Symbol . DeclarationFragments . Fragment ] {
599
+ [ . init( kind: kind, spelling: self , preciseIdentifier: nil ) ]
600
+ }
601
+ }
602
+
603
+ private extension Dictionary {
604
+ func keeping( _ keys: Key ... ) -> Self {
605
+ var new = Self ( )
606
+
607
+ for key in keys {
608
+ new [ key] = self [ key]
609
+ }
610
+
611
+ return new
612
+ }
613
+ }
0 commit comments