@@ -15,6 +15,7 @@ extension SymbolGraph.Symbol {
1515 ///
1616 /// This mixin is created while a symbol graph is decoded, to hold ``DeclarationFragments-swift.struct``
1717 /// for symbols which share the same precise identifier.
18+ @available ( * , deprecated, message: " This type is now unused; alternate declaration information is stored in AlternateSymbols instead. " )
1819 public struct AlternateDeclarations : Mixin , Codable {
1920 public static let mixinKey = " alternateDeclarations "
2021
@@ -36,23 +37,121 @@ extension SymbolGraph.Symbol {
3637 }
3738 }
3839
40+ /// A mixin to hold alternate symbol information for a symbol.
41+ ///
42+ /// This mixin is created while a symbol graph is decoded,
43+ /// to hold distinct information for symbols with the same precise identifier.
44+ public struct AlternateSymbols : Mixin , Codable {
45+ public static let mixinKey = " alternateSymbols "
46+
47+ public struct AlternateSymbol : Codable {
48+ /// The doc comment for the alternate symbol.
49+ public let docComment : SymbolGraph . LineList ?
50+
51+ /// The mixins for the alternate symbol.
52+ public var mixins : [ String : Mixin ] = [ : ]
53+
54+ public init ( from decoder: any Decoder ) throws {
55+ let container = try decoder. container ( keyedBy: SymbolGraph . Symbol. CodingKeys. self)
56+ self . docComment = try container. decodeIfPresent ( SymbolGraph . LineList. self, forKey: . docComment)
57+
58+ for key in container. allKeys {
59+ guard let info = SymbolGraph . Symbol. CodingKeys. mixinCodingInfo [ key. stringValue] ?? decoder. registeredSymbolMixins ? [ key. stringValue] else {
60+ continue
61+ }
62+
63+ mixins [ key. stringValue] = try info. decode ( container)
64+ }
65+ }
66+
67+ public func encode( to encoder: Encoder ) throws {
68+ var container = encoder. container ( keyedBy: SymbolGraph . Symbol. CodingKeys. self)
69+
70+ try container. encodeIfPresent ( docComment, forKey: . docComment)
71+
72+ for (key, mixin) in mixins {
73+ guard let info = SymbolGraph . Symbol. CodingKeys. mixinCodingInfo [ key] ?? encoder. registeredSymbolMixins ? [ key] else {
74+ continue
75+ }
76+
77+ try info. encode ( mixin, & container)
78+ }
79+ }
80+
81+ public init ( symbol: SymbolGraph . Symbol ) {
82+ self . docComment = symbol. docComment
83+ self . mixins = symbol. mixins
84+ }
85+
86+ public init ( declarationFragments: DeclarationFragments ) {
87+ self . docComment = nil
88+ self . mixins = [ DeclarationFragments . mixinKey: declarationFragments]
89+ }
90+
91+ /// Whether this alternate has no information and should be discarded.
92+ public var isEmpty : Bool {
93+ docComment == nil && mixins. isEmpty
94+ }
95+
96+ /// Convenience accessor to fetch declaration fragments from the mixins dictionary.
97+ public var declarationFragments : DeclarationFragments ? {
98+ self . mixins [ DeclarationFragments . mixinKey] as? DeclarationFragments
99+ }
100+
101+ /// Convenience accessor to fetch function signature information from the mixins dictionary.
102+ public var functionSignature : FunctionSignature ? {
103+ self . mixins [ FunctionSignature . mixinKey] as? FunctionSignature
104+ }
105+ }
106+
107+ public init ( alternateSymbols: [ AlternateSymbol ] ) {
108+ self . alternateSymbols = alternateSymbols
109+ }
110+
111+ init ( alternateDeclarations: AlternateDeclarations ) {
112+ self . alternateSymbols = alternateDeclarations. declarations. map ( { . init( declarationFragments: $0) } )
113+ }
114+
115+ /// The list of alternate symbol information.
116+ public var alternateSymbols : [ AlternateSymbol ]
117+ }
118+
39119 /// Convenience accessor to fetch alternate declarations for this symbol.
40120 public var alternateDeclarations : [ DeclarationFragments ] ? {
41- ( mixins [ AlternateDeclarations . mixinKey ] as? AlternateDeclarations ) ? . declarations
121+ alternateSymbols ? . alternateSymbols . compactMap ( \ . declarationFragments )
42122 }
43123
44- internal mutating func addAlternateDeclaration( _ declaration: DeclarationFragments ) {
45- if var alternateDeclarations = mixins [ AlternateDeclarations . mixinKey] as? AlternateDeclarations {
46- alternateDeclarations. declarations. append ( declaration)
47- mixins [ AlternateDeclarations . mixinKey] = alternateDeclarations
48- } else {
49- mixins [ AlternateDeclarations . mixinKey] = AlternateDeclarations ( declarations: [ declaration] )
50- }
124+ /// Convenience accessor to fetch alternate symbol information.
125+ ///
126+ /// Returns `nil` if there were no alternate symbols found when decoding the symbol graph.
127+ public var alternateSymbols : AlternateSymbols ? {
128+ mixins [ AlternateSymbols . mixinKey] as? AlternateSymbols
129+ }
130+
131+ /// Convenience accessor to fetch a specific mixin from this symbol's alternate symbols.
132+ ///
133+ /// Because the mixin key is inferred from the type parameter,
134+ /// the easiest way to call this method is by assigning it to a variable with an appropriate type:
135+ ///
136+ /// ```swift
137+ /// let alternateFunctionSignatures: [SymbolGraph.Symbol.FunctionSignature]? = symbol.alternateSymbolMixins()
138+ /// ```
139+ ///
140+ /// If there are multiple alternate symbols and only some of them have the requested mixin,
141+ /// any missing data is removed from the resulting array via a `compactMap`.
142+ public func alternateSymbolMixins< M: Mixin > ( mixinKey: String = M . mixinKey) -> [ M ] ? {
143+ alternateSymbols? . alternateSymbols. compactMap ( { $0. mixins [ mixinKey] as? M } )
51144 }
52145
53146 internal mutating func addAlternateDeclaration( from symbol: SymbolGraph . Symbol ) {
54- if let declaration = symbol. mixins [ DeclarationFragments . mixinKey] as? DeclarationFragments {
55- addAlternateDeclaration ( declaration)
147+ let alternate = AlternateSymbols . AlternateSymbol ( symbol: symbol)
148+ guard !alternate. isEmpty else { return }
149+
150+ if var alternateSymbols = mixins [ AlternateSymbols . mixinKey] as? AlternateSymbols {
151+ alternateSymbols. alternateSymbols. append ( alternate)
152+ mixins [ AlternateSymbols . mixinKey] = alternateSymbols
153+ } else {
154+ mixins [ AlternateSymbols . mixinKey] = AlternateSymbols ( alternateSymbols: [ alternate] )
56155 }
57156 }
58157}
0 commit comments