@@ -37,6 +37,9 @@ import SwiftOptions
37
37
38
38
@_spi ( Testing) public var phase : Phase
39
39
40
+ /// Minimize the number of file system modification-time queries.
41
+ private var externalDependencyModTimeCache = [ ExternalDependency: Bool] ( )
42
+
40
43
public init ( _ info: IncrementalCompilationState . InitialStateComputer ,
41
44
_ phase: Phase
42
45
) {
@@ -287,14 +290,10 @@ extension ModuleDependencyGraph {
287
290
288
291
let isNewToTheGraph = fingerprintedExternalDependencies. insert ( fed) . inserted
289
292
290
- var lazyModTimer = LazyModTimer (
291
- externalDependency: fed. externalDependency,
292
- info: info)
293
-
294
293
// If the graph already includes prior externals, then any new externals are changes
295
294
// Short-circuit conjunction may avoid the modTime query
296
295
let shouldTryToProcess = info. isCrossModuleIncrementalBuildEnabled &&
297
- ( isNewToTheGraph || lazyModTimer . hasExternalFileChanged )
296
+ ( isNewToTheGraph || hasFileChanged ( of : fed . externalDependency ) )
298
297
299
298
// Do this no matter what in order to integrate any incremental external dependencies.
300
299
let invalidatedNodesFromIncrementalExternal = shouldTryToProcess
@@ -309,7 +308,7 @@ extension ModuleDependencyGraph {
309
308
/// When building a graph from scratch, an unchanged but new-to-the-graph external dependendcy should be ignored.
310
309
/// Otherwise, it represents an added Import
311
310
let callerWantsTheseChanges = ( phase. isUpdating && isNewToTheGraph) ||
312
- lazyModTimer . hasExternalFileChanged
311
+ hasFileChanged ( of : fed . externalDependency )
313
312
314
313
guard callerWantsTheseChanges else {
315
314
return DirectlyInvalidatedNodeSet ( )
@@ -319,7 +318,18 @@ extension ModuleDependencyGraph {
319
318
// return anything that uses that dependency.
320
319
return invalidatedNodesFromIncrementalExternal ?? collectUntracedNodesUsing ( fed)
321
320
}
322
-
321
+
322
+ private func hasFileChanged( of externalDependency: ExternalDependency
323
+ ) -> Bool {
324
+ if let hasChanged = externalDependencyModTimeCache [ externalDependency] {
325
+ return hasChanged
326
+ }
327
+ let hasChanged = ( externalDependency. modTime ( info. fileSystem) ?? . distantFuture)
328
+ >= info. buildTime
329
+ externalDependencyModTimeCache [ externalDependency] = hasChanged
330
+ return hasChanged
331
+ }
332
+
323
333
private struct LazyModTimer {
324
334
let externalDependency : ExternalDependency
325
335
let info : IncrementalCompilationState . InitialStateComputer
0 commit comments