@@ -484,9 +484,6 @@ extension DocumentationContentRenderer {
484484 /// Applies Swift symbol navigator titles rules to a title.
485485 /// Will strip the typeIdentifier's precise identifier.
486486 static func navigatorTitle( for tokens: [ DeclarationRenderSection . Token ] , symbolTitle: String ) -> [ DeclarationRenderSection . Token ] {
487- // Replace kind "typeIdentifier" with "identifier" if the title matches the pattern:
488- // [keyword=class,protocol,enum,typealias,etc.][ ]([typeIdentifier=ancestor(Self)][.])*[typeIdentifier=Self]
489-
490487 return tokens. mapNameFragmentsToIdentifierKind ( matching: symbolTitle)
491488 }
492489
@@ -498,8 +495,7 @@ extension DocumentationContentRenderer {
498495 static func subHeading( for tokens: [ DeclarationRenderSection . Token ] , symbolTitle: String , symbolKind: String ) -> [ DeclarationRenderSection . Token ] {
499496 var tokens = tokens
500497
501- // 1. Replace kind "typeIdentifier" with "identifier" if the title matches the pattern:
502- // [keyword=class,protocol,enum,typealias,etc.][ ]([typeIdentifier=ancestor(Self)][.])*[typeIdentifier=Self]
498+ // 1. Map typeIdenifier tokens to identifier tokens where applicable
503499 tokens = tokens. mapNameFragmentsToIdentifierKind ( matching: symbolTitle)
504500
505501
@@ -518,79 +514,46 @@ extension DocumentationContentRenderer {
518514
519515private extension Array where Element == DeclarationRenderSection . Token {
520516 // Replaces kind "typeIdentifier" with "identifier" if the fragments matches the pattern:
521- // [keyword=class,protocol,enum,typealias,etc.][ ]([ typeIdentifier=x_i)][.])* [typeIdentifier=x_i],
522- // where the x_i joined with separator "." equal the `symbolTitle`
517+ // [keyword=_] [text=" "] [( typeIdentifier|identifier)=Name_0] ( [text="."] [typeIdentifier=Name_i] )*
518+ // where the Name_i from typeIdentifier tokens joined with separator "." equal the `symbolTitle`
523519 func mapNameFragmentsToIdentifierKind( matching symbolTitle: String ) -> Self {
524- let ( includesTypeOrExtensionDeclaration, nameRange) = self . typeOrExtensionDeclaration ( )
525-
526- if includesTypeOrExtensionDeclaration
527- && self [ nameRange] . map ( \. text) . joined ( ) == symbolTitle {
528- return self . enumerated ( ) . map { ( index, token) -> DeclarationRenderSection . Token in
529-
530- if nameRange. contains ( index) && token. kind == . typeIdentifier {
531- return DeclarationRenderSection . Token (
532- text: token. text,
533- kind: . identifier,
534- preciseIdentifier: token. preciseIdentifier
535- )
536- }
537-
538- return token
539- }
520+ // Check that the first 3 tokens are: [keyword=_] [text=" "] [(typeIdentifier|identifier)=_]
521+ guard count >= 3 ,
522+ self [ 0 ] . kind == . keyword,
523+ self [ 1 ] . kind == . text, self [ 1 ] . text == " " ,
524+ self [ 2 ] . kind == . typeIdentifier || self [ 2 ] . kind == . identifier
525+ else { return self }
526+
527+ // If the first named token belongs to an identifier, this is a module prefix.
528+ // We store it for later comparison with the `combinedName`
529+ let modulePrefix = self [ 2 ] . kind == . identifier ? self [ 2 ] . text + " . " : " "
530+
531+ var combinedName = self [ 2 ] . text
532+
533+ var finalTypeIdentifierIndex = 2
534+ var remainder = self . dropFirst ( 3 )
535+ // Continue checking for pairs of "." text tokens and typeIdentifier tokens: ( [text="."] [typeIdentifier=Name_i] )*
536+ while remainder. count >= 2 {
537+ let separator = remainder. removeFirst ( )
538+ guard separator. kind == . text, separator. text == " . " else { break }
539+ let next = remainder. removeFirst ( )
540+ guard next. kind == . typeIdentifier else { break }
541+
542+ finalTypeIdentifierIndex += 2
543+ combinedName += " . " + next. text
540544 }
541545
542- return self
543- }
544- }
545-
546- private extension Collection where Element == DeclarationRenderSection . Token , Index == Int {
547- func typeOrExtensionDeclaration( ) -> ( includesTypeOrExtensionDeclaration: Bool , name: Range < Index > ) {
548- self . reduce ( into: TypeOrExtensionDeclarationNameExtractionSM ( ) , { sm, token in sm. consume ( token) } ) . result ( )
549- }
550- }
551-
552- private enum TypeOrExtensionDeclarationNameExtractionSM {
553- case initial
554- case illegal
555- case foundKeyword
556- case foundIdentifier( Int )
557- case expectIdentifier( Int )
558- case done( Range < Int > )
559-
560- init ( ) {
561- self = . initial
562- }
563-
564- static let expectedNameStartIndex = 2
565-
566- mutating func consume( _ token: DeclarationRenderSection . Token ) {
567- switch ( self , token. kind, token. text) {
568- case ( . initial, . keyword, _) :
569- self = . foundKeyword
570- case ( . foundKeyword, . text, " " ) :
571- self = . expectIdentifier( Self . expectedNameStartIndex)
572- case let ( . expectIdentifier( index) , . identifier, _) ,
573- let ( . expectIdentifier( index) , . typeIdentifier, _) :
574- self = . foundIdentifier( index+ 1 )
575- case let ( . foundIdentifier( index) , . text, " . " ) :
576- self = . expectIdentifier( index+ 1 )
577- case let ( . foundIdentifier( index) , . text, _) :
578- self = . done( . init( uncheckedBounds: ( Self . expectedNameStartIndex, index) ) )
579- case let ( . done( namerange) , _, _) :
580- self = . done( namerange)
581- default :
582- self = . illegal
583- }
584- }
585-
586- func result( ) -> ( includesTypeOrExtensionDeclaration: Bool , name: Range < Int > ) {
587- switch self {
588- case let . done( range) :
589- return ( true , range)
590- case let . foundIdentifier( index) :
591- return ( true , . init( uncheckedBounds: ( Self . expectedNameStartIndex, index) ) )
592- default :
593- return ( false , . init( uncheckedBounds: ( 0 , 0 ) ) )
546+ guard combinedName == modulePrefix + symbolTitle else { return self }
547+
548+ var mapped = self
549+ for index in stride ( from: 2 , to: finalTypeIdentifierIndex+ 1 , by: 2 ) {
550+ let token = self [ index]
551+ mapped [ index] = DeclarationRenderSection . Token (
552+ text: token. text,
553+ kind: . identifier,
554+ preciseIdentifier: token. preciseIdentifier
555+ )
594556 }
557+ return mapped
595558 }
596559}
0 commit comments