@@ -111,3 +111,109 @@ extension SourceFileDependencyGraph {
111
111
}
112
112
}
113
113
}
114
+
115
+ extension SourceFileDependencyGraph {
116
+ private static let recordBlockId = 8
117
+
118
+ private enum RecordKind : UInt64 {
119
+ case metadata = 1
120
+ case sourceFileDepGraphNode
121
+ case fingerprintNode
122
+ case dependsOnDefinitionNode
123
+ case identifierNode
124
+ }
125
+
126
+ private enum ReadError : Error {
127
+ case badMagic
128
+ case noRecordBlock
129
+ case malformedMetadataRecord
130
+ case unexpectedMetadataRecord
131
+ case malformedFingerprintRecord
132
+ case malformedDependsOnDefinitionRecord
133
+ case malformedIdentifierRecord
134
+ case malformedSourceFileDepGraphNodeRecord
135
+ case unknownRecord
136
+ case unexpectedSubblock
137
+ }
138
+
139
+ public init ( data: Data ) throws {
140
+ let bitcode = try Bitcode ( data: data)
141
+ guard bitcode. signature == 0x53_50_45_44 else { throw ReadError . badMagic } // DEPS
142
+
143
+ guard bitcode. elements. count == 1 ,
144
+ case . block( let recordBlock) = bitcode. elements. first,
145
+ recordBlock. id == Self . recordBlockId else { throw ReadError . noRecordBlock }
146
+
147
+ guard case . record( let metadataRecord) = recordBlock. elements. first,
148
+ RecordKind ( rawValue: metadataRecord. id) == . metadata,
149
+ metadataRecord. fields. count == 2 ,
150
+ case . blob( let compilerVersionBlob) = metadataRecord. payload,
151
+ let compilerVersionString = String ( data: compilerVersionBlob, encoding: . utf8)
152
+ else { throw ReadError . malformedMetadataRecord }
153
+
154
+ self . majorVersion = metadataRecord. fields [ 0 ]
155
+ self . minorVersion = metadataRecord. fields [ 1 ]
156
+ self . compilerVersionString = compilerVersionString
157
+
158
+ var nodes : [ Node ] = [ ]
159
+ var node : Node ? = nil
160
+ var identifiers : [ String ] = [ " " ] // The empty string is hardcoded as identifiers[0]
161
+ var sequenceNumber = 0
162
+ for element in recordBlock. elements. dropFirst ( ) {
163
+ guard case . record( let record) = element else { throw ReadError . unexpectedSubblock }
164
+ guard let kind = RecordKind ( rawValue: record. id) else { throw ReadError . unknownRecord }
165
+ switch kind {
166
+ case . metadata:
167
+ throw ReadError . unexpectedMetadataRecord
168
+ case . sourceFileDepGraphNode:
169
+ if let node = node {
170
+ nodes. append ( node)
171
+ }
172
+ guard record. fields. count == 5 ,
173
+ let nodeKind = DependencyKey . Kind ( rawValue: record. fields [ 0 ] ) ,
174
+ let declAspect = DeclAspect ( rawValue: record. fields [ 1 ] ) ,
175
+ record. fields [ 2 ] < identifiers. count,
176
+ record. fields [ 3 ] < identifiers. count else {
177
+ throw ReadError . malformedSourceFileDepGraphNodeRecord
178
+ }
179
+ let context = identifiers [ Int ( record. fields [ 2 ] ) ]
180
+ let identifier = identifiers [ Int ( record. fields [ 3 ] ) ]
181
+ let isProvides = record. fields [ 4 ] != 0
182
+ node = Node ( key: . init( kind: nodeKind,
183
+ aspect: declAspect,
184
+ context: context,
185
+ name: identifier) ,
186
+ fingerprint: nil ,
187
+ sequenceNumber: sequenceNumber,
188
+ defsIDependUpon: [ ] ,
189
+ isProvides: isProvides)
190
+ sequenceNumber += 1
191
+ case . fingerprintNode:
192
+ guard node != nil ,
193
+ record. fields. count == 0 ,
194
+ case . blob( let fingerprintBlob) = record. payload,
195
+ let fingerprint = String ( data: fingerprintBlob, encoding: . utf8) else {
196
+ throw ReadError . malformedFingerprintRecord
197
+ }
198
+ node? . fingerprint = fingerprint
199
+ case . dependsOnDefinitionNode:
200
+ guard node != nil ,
201
+ record. fields. count == 1 else { throw ReadError . malformedDependsOnDefinitionRecord }
202
+ node? . defsIDependUpon. append ( Int ( record. fields [ 0 ] ) )
203
+ case . identifierNode:
204
+ guard record. fields. count == 0 ,
205
+ case . blob( let identifierBlob) = record. payload,
206
+ let identifier = String ( data: identifierBlob, encoding: . utf8) else {
207
+ throw ReadError . malformedIdentifierRecord
208
+ }
209
+ identifiers. append ( identifier)
210
+ }
211
+ }
212
+
213
+ if let node = node {
214
+ nodes. append ( node)
215
+ }
216
+
217
+ self . allNodes = nodes
218
+ }
219
+ }
0 commit comments