@@ -54,22 +54,20 @@ import SwiftOptions
54
54
self . creationPhase = phase
55
55
}
56
56
57
- private func addMapEntry( _ input: TypedVirtualPath , _ dependencySource: DependencySource ) {
58
- assert ( input. type == . swift && dependencySource. typedFile. type == . swiftDeps)
59
- inputDependencySourceMap [ input] = dependencySource
60
- }
61
-
62
- @_spi ( Testing) public func getSource( for input: TypedVirtualPath ,
63
- function: String = #function,
64
- file: String = #file,
65
- line: Int = #line) -> DependencySource {
66
- guard let source = inputDependencySourceMap [ input] else {
57
+ @_spi ( Testing) public func getRequiredSource( for input: TypedVirtualPath ,
58
+ function: String = #function,
59
+ file: String = #file,
60
+ line: Int = #line) -> DependencySource {
61
+ guard let source = inputDependencySourceMap. getSourceIfKnown ( for: input)
62
+ else {
67
63
fatalError ( " \( input. file. basename) not found in inputDependencySourceMap, \( file) : \( line) in \( function) " )
68
64
}
69
65
return source
70
66
}
71
- @_spi ( Testing) public func getInput( for source: DependencySource ) -> TypedVirtualPath ? {
72
- guard let input = inputDependencySourceMap [ source] else {
67
+
68
+ @_spi ( Testing) public func getNeededInput( for source: DependencySource ) -> TypedVirtualPath ? {
69
+ guard let input = inputDependencySourceMap. getInputIfKnown ( for: source)
70
+ else {
73
71
info. diagnosticEngine. emit ( warning: " Failed to find source file for ' \( source. file. basename) ', recovering with a full rebuild. Next build will be incremental. " )
74
72
return nil
75
73
}
@@ -143,7 +141,7 @@ extension ModuleDependencyGraph {
143
141
return TransitivelyInvalidatedInputSet ( )
144
142
}
145
143
return collectInputsRequiringCompilationAfterProcessing (
146
- dependencySource: getSource ( for: input) )
144
+ dependencySource: getRequiredSource ( for: input) )
147
145
}
148
146
}
149
147
@@ -163,7 +161,7 @@ extension ModuleDependencyGraph {
163
161
/// speculatively scheduled in the first wave.
164
162
func collectInputsInvalidatedBy( input: TypedVirtualPath
165
163
) -> TransitivelyInvalidatedInputArray {
166
- let changedSource = getSource ( for: input)
164
+ let changedSource = getRequiredSource ( for: input)
167
165
let allDependencySourcesToRecompile =
168
166
collectSwiftDepsUsing ( dependencySource: changedSource)
169
167
@@ -172,8 +170,8 @@ extension ModuleDependencyGraph {
172
170
guard dependencySource != changedSource else { return nil }
173
171
let dependentSource = inputDependencySourceMap [ dependencySource]
174
172
info. reporter? . report (
175
- " Found dependent of \( input. file. basename) : " , dependentSource )
176
- return dependentSource
173
+ " Found dependent of \( input. file. basename) : " , dependentInput )
174
+ return dependentInput
177
175
}
178
176
}
179
177
@@ -190,7 +188,7 @@ extension ModuleDependencyGraph {
190
188
/// Does the graph contain any dependency nodes for a given source-code file?
191
189
func containsNodes( forSourceFile file: TypedVirtualPath ) -> Bool {
192
190
precondition ( file. type == . swift)
193
- guard let source = inputDependencySourceMap [ file] else {
191
+ guard let source = inputDependencySourceMap. getSourceIfKnown ( for : file) else {
194
192
return false
195
193
}
196
194
return containsNodes ( forDependencySource: source)
@@ -200,17 +198,47 @@ extension ModuleDependencyGraph {
200
198
return nodeFinder. findNodes ( for: source) . map { !$0. isEmpty}
201
199
?? false
202
200
}
203
-
204
- /// Return true on success
205
- func populateInputDependencySourceMap( ) -> Bool {
201
+
202
+ /// Returns: false on error
203
+ func populateInputDependencySourceMap(
204
+ `for` purpose: InputDependencySourceMap . AdditionPurpose
205
+ ) -> Bool {
206
206
let ofm = info. outputFileMap
207
- let de = info. diagnosticEngine
208
- return info. inputFiles. reduce ( true ) { okSoFar, input in
209
- ofm. getDependencySource ( for: input, diagnosticEngine: de)
210
- . map { source in addMapEntry ( input, source) ; return okSoFar } ?? false
207
+ let diags = info. diagnosticEngine
208
+ var allFound = true
209
+ for input in info. inputFiles {
210
+ if let source = ofm. getDependencySource ( for: input, diagnosticEngine: diags) {
211
+ inputDependencySourceMap. addEntry ( input, source, for: purpose)
212
+ }
213
+ else {
214
+ // Don't break in order to report all failures.
215
+ allFound = false
216
+ }
217
+ }
218
+ return allFound
219
+ }
220
+ }
221
+ extension OutputFileMap {
222
+ fileprivate func getDependencySource(
223
+ for sourceFile: TypedVirtualPath ,
224
+ diagnosticEngine: DiagnosticsEngine
225
+ ) -> DependencySource ? {
226
+ assert ( sourceFile. type == FileType . swift)
227
+ guard let swiftDepsPath = existingOutput ( inputFile: sourceFile. fileHandle,
228
+ outputType: . swiftDeps)
229
+ else {
230
+ // The legacy driver fails silently here.
231
+ diagnosticEngine. emit (
232
+ . remarkDisabled( " \( sourceFile. file. basename) has no swiftDeps file " )
233
+ )
234
+ return nil
211
235
}
236
+ assert ( VirtualPath . lookup ( swiftDepsPath) . extension == FileType . swiftDeps. rawValue)
237
+ let typedSwiftDepsFile = TypedVirtualPath ( file: swiftDepsPath, type: . swiftDeps)
238
+ return DependencySource ( typedSwiftDepsFile)
212
239
}
213
240
}
241
+
214
242
// MARK: - Scheduling the 2nd wave
215
243
extension ModuleDependencyGraph {
216
244
/// After `source` has been compiled, figure out what other source files need compiling.
@@ -220,7 +248,7 @@ extension ModuleDependencyGraph {
220
248
func collectInputsRequiringCompilation( byCompiling input: TypedVirtualPath
221
249
) -> TransitivelyInvalidatedInputSet ? {
222
250
precondition ( input. type == . swift)
223
- let dependencySource = getSource ( for: input)
251
+ let dependencySource = getRequiredSource ( for: input)
224
252
return collectInputsRequiringCompilationAfterProcessing (
225
253
dependencySource: dependencySource)
226
254
}
@@ -315,7 +343,8 @@ extension ModuleDependencyGraph {
315
343
) -> TransitivelyInvalidatedInputSet ? {
316
344
var invalidatedInputs = TransitivelyInvalidatedInputSet ( )
317
345
for invalidatedSwiftDeps in collectSwiftDepsUsingInvalidated ( nodes: directlyInvalidatedNodes) {
318
- guard let invalidatedInput = getInput ( for: invalidatedSwiftDeps) else {
346
+ guard let invalidatedInput = getNeededInput ( for: invalidatedSwiftDeps)
347
+ else {
319
348
return nil
320
349
}
321
350
invalidatedInputs. insert ( invalidatedInput)
@@ -439,27 +468,6 @@ extension ModuleDependencyGraph {
439
468
}
440
469
}
441
470
442
- extension OutputFileMap {
443
- fileprivate func getDependencySource(
444
- for sourceFile: TypedVirtualPath ,
445
- diagnosticEngine: DiagnosticsEngine
446
- ) -> DependencySource ? {
447
- assert ( sourceFile. type == FileType . swift)
448
- guard let swiftDepsPath = existingOutput ( inputFile: sourceFile. fileHandle,
449
- outputType: . swiftDeps)
450
- else {
451
- // The legacy driver fails silently here.
452
- diagnosticEngine. emit (
453
- . remarkDisabled( " \( sourceFile. file. basename) has no swiftDeps file " )
454
- )
455
- return nil
456
- }
457
- assert ( VirtualPath . lookup ( swiftDepsPath) . extension == FileType . swiftDeps. rawValue)
458
- let typedSwiftDepsFile = TypedVirtualPath ( file: swiftDepsPath, type: . swiftDeps)
459
- return DependencySource ( typedSwiftDepsFile)
460
- }
461
- }
462
-
463
471
// MARK: - tracking traced nodes
464
472
extension ModuleDependencyGraph {
465
473
@@ -584,10 +592,11 @@ extension ModuleDependencyGraph {
584
592
. record ( def: dependencyKey, use: self . allNodes [ useID] )
585
593
assert ( isNewUse, " Duplicate use def-use arc in graph? " )
586
594
}
587
- for (input, source) in inputDependencySourceMap {
588
- graph. addMapEntry ( input, source)
595
+ for (input, dependencySource) in inputDependencySourceMap {
596
+ graph. inputDependencySourceMap. addEntry ( input,
597
+ dependencySource,
598
+ for: . readingPriors)
589
599
}
590
-
591
600
return self . graph
592
601
}
593
602
@@ -883,7 +892,7 @@ extension ModuleDependencyGraph {
883
892
}
884
893
}
885
894
886
- for ( input, dependencySource) in graph . inputDependencySourceMap {
895
+ graph . inputDependencySourceMap . enumerateToSerializePriors { input, dependencySource in
887
896
self . addIdentifier ( input. file. name)
888
897
self . addIdentifier ( dependencySource. file. name)
889
898
}
@@ -1028,7 +1037,8 @@ extension ModuleDependencyGraph {
1028
1037
}
1029
1038
}
1030
1039
}
1031
- for (input, dependencySource) in graph. inputDependencySourceMap {
1040
+ graph. inputDependencySourceMap. enumerateToSerializePriors {
1041
+ input, dependencySource in
1032
1042
serializer. stream. writeRecord ( serializer. abbreviations [ . mapNode] !) {
1033
1043
$0. append ( RecordID . mapNode)
1034
1044
$0. append ( serializer. lookupIdentifierCode ( for: input. file. name) )
@@ -1164,6 +1174,6 @@ extension ModuleDependencyGraph {
1164
1174
_ mockInput: TypedVirtualPath ,
1165
1175
_ mockDependencySource: DependencySource
1166
1176
) {
1167
- addMapEntry ( mockInput, mockDependencySource)
1177
+ inputDependencySourceMap . addEntry ( mockInput, mockDependencySource, for : . mocking )
1168
1178
}
1169
1179
}
0 commit comments