@@ -15,6 +15,7 @@ extension SymbolGraph.Symbol {
15
15
///
16
16
/// This mixin is created while a symbol graph is decoded, to hold ``DeclarationFragments-swift.struct``
17
17
/// 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. " )
18
19
public struct AlternateDeclarations : Mixin , Codable {
19
20
public static let mixinKey = " alternateDeclarations "
20
21
@@ -36,23 +37,121 @@ extension SymbolGraph.Symbol {
36
37
}
37
38
}
38
39
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
+
39
119
/// Convenience accessor to fetch alternate declarations for this symbol.
40
120
public var alternateDeclarations : [ DeclarationFragments ] ? {
41
- ( mixins [ AlternateDeclarations . mixinKey ] as? AlternateDeclarations ) ? . declarations
121
+ alternateSymbols ? . alternateSymbols . compactMap ( \ . declarationFragments )
42
122
}
43
123
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 } )
51
144
}
52
145
53
146
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] )
56
155
}
57
156
}
58
157
}
0 commit comments