@@ -106,10 +106,10 @@ extension ModuleDependencyGraph {
106106
107107// MARK: - Getting a graph read from priors ready to use
108108extension ModuleDependencyGraph {
109- func collectNodesInvalidatedByChangedOrAddedExternals ( ) -> Set < Node > {
109+ func collectNodesDirectlyInvalidatedByChangedOrAddedExternals ( ) -> Set < Node > {
110110 fingerprintedExternalDependencies. reduce ( into: Set ( ) ) { invalidatedNodes, fed in
111111 invalidatedNodes. formUnion (
112- self . collectNodesInvalidatedByProcessing ( fingerprintedExternalDependency: fed) )
112+ self . collectNodesDirectlyInvalidatedByProcessing ( fingerprintedExternalDependency: fed) )
113113 }
114114 }
115115}
@@ -252,18 +252,18 @@ extension ModuleDependencyGraph {
252252 /// If reading for the first time, the driver is compiling all outdated source files anyway, so only
253253 /// nodes invalidated by external dependencies matter.
254254 /// But when updating, all invalidations matter.
255- let invalidatedNodes = phase. isUpdating
256- ? results. allInvalidatedNodes
257- : results. nodesInvalidatedByUsingSomeExternal
255+ let directlyInvalidatedNodes = phase. isUpdating
256+ ? results. allDirectlyInvalidatedNodes
257+ : results. nodesDirectlyInvalidatedByUsingSomeExternal
258258
259- return collectInputsUsingTransitivelyInvalidated ( nodes: invalidatedNodes )
259+ return collectInputsUsingTransitivelyInvalidated ( nodes: directlyInvalidatedNodes )
260260 }
261261
262262 /// Given nodes that are invalidated, find all the affected inputs that must be recompiled.
263263 func collectInputsUsingTransitivelyInvalidated(
264- nodes invalidatedNodes : Set < Node >
264+ nodes directlyInvalidatedNodes : Set < Node >
265265 ) -> Set < TypedVirtualPath > {
266- collectSwiftDepsUsingTransitivelyInvalidated ( nodes: invalidatedNodes )
266+ collectSwiftDepsUsingTransitivelyInvalidated ( nodes: directlyInvalidatedNodes )
267267 . reduce ( into: Set ( ) ) { invalidatedInputs, invalidatedSwiftDeps in
268268 invalidatedInputs. insert ( getInput ( for: invalidatedSwiftDeps) )
269269 }
@@ -276,7 +276,8 @@ extension ModuleDependencyGraph {
276276 /// Process a possibly-fingerprinted external dependency by reading and integrating, if applicable.
277277 /// Return the nodes thus invalidated.
278278 /// But always integrate, in order to detect future changes.
279- func collectNodesInvalidatedByProcessing(
279+ /// This function does not to the transitive closure; that is left to the callers
280+ func collectNodesDirectlyInvalidatedByProcessing(
280281 fingerprintedExternalDependency fed: FingerprintedExternalDependency )
281282 -> Set < Node > {
282283
@@ -291,16 +292,28 @@ extension ModuleDependencyGraph {
291292 let shouldTryToProcess = info. isCrossModuleIncrementalBuildEnabled &&
292293 ( isNewToTheGraph || lazyModTimer. hasExternalFileChanged)
293294
294- let invalidatedNodesFromIncrementalExternal = shouldTryToProcess
295- ? collectNodesInvalidatedByAttemptingToProcess ( fed, info)
295+ // Do this no matter what in order to integrate any incremental external dependencies.
296+ let directlyInvalidatedNodesFromIncrementalExternal = shouldTryToProcess
297+ ? collectNodesDirectlyInvalidatedByAttemptingToProcess ( fed, info)
296298 : nil
297299
298- let callerWantsTheseChanges = ( phase. isUpdating && isNewToTheGraph) ||
300+ if phase == . buildingAfterEachCompilation {
301+ // going to compile every input anyway, less work for callers
302+ return Set ( )
303+ }
304+
305+ /// When building a graph from scratch, an unchanged but new-to-the-graph external dependendcy should be ignored.
306+ /// Otherwise, it represents an added Import
307+ let callerWantsTheseChanges = ( phase != . buildingWithoutAPrior && isNewToTheGraph) ||
299308 lazyModTimer. hasExternalFileChanged
300309
301- return !callerWantsTheseChanges
302- ? Set < Node > ( )
303- : invalidatedNodesFromIncrementalExternal ?? collectUntracedNodesDirectlyUsing ( fed)
310+ guard callerWantsTheseChanges else {
311+ return Set ( )
312+ }
313+
314+ // If there was an error integrating the external dependency, or if it was not an incremental one,
315+ // return anything that uses that dependency.
316+ return directlyInvalidatedNodesFromIncrementalExternal ?? collectUntracedNodesDirectlyUsing ( fed)
304317 }
305318
306319 private struct LazyModTimer {
@@ -311,15 +324,17 @@ extension ModuleDependencyGraph {
311324 >= info. buildTime
312325 }
313326
314- private func collectNodesInvalidatedByAttemptingToProcess(
327+ /// Try to read and integrate an external dependency.
328+ /// Return nil if it's not incremental, or if an error occurs.
329+ private func collectNodesDirectlyInvalidatedByAttemptingToProcess(
315330 _ fed: FingerprintedExternalDependency ,
316331 _ info: IncrementalCompilationState . InitialStateComputer ) -> Set < Node > ? {
317332 fed. incrementalDependencySource?
318333 . read ( in: info. fileSystem, reporter: info. reporter)
319334 . map { unserializedDepGraph in
320335 info. reporter? . report ( " Integrating changes from: \( fed. externalDependency) " )
321336 return Integrator . integrate ( from: unserializedDepGraph, into: self )
322- . allInvalidatedNodes
337+ . allDirectlyInvalidatedNodes
323338 }
324339 }
325340
0 commit comments