Skip to content

Commit 5a4b97f

Browse files
author
David Ungar
authored
Merge pull request #395 from davidungar/missing-unreadable-swiftdeps
[Incremental] Handle missing or unreadable swiftdeps like the legacy driver.
2 parents a59ed35 + 5648e66 commit 5a4b97f

File tree

3 files changed

+65
-25
lines changed

3 files changed

+65
-25
lines changed

Sources/SwiftDriver/Incremental Compilation/IncrementalCompilationState.swift

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public class IncrementalCompilationState {
9191
? { Self.reportIncrementalDecisionFn($0, $1, outputFileMap, diagnosticEngine) }
9292
: nil
9393

94-
guard let moduleDependencyGraph =
94+
guard let (moduleDependencyGraph, inputsWithUnreadableSwiftDeps) =
9595
ModuleDependencyGraph.buildInitialGraph(
9696
diagnosticEngine: diagnosticEngine,
9797
inputs: buildRecordInfo.compilationInputModificationDates.keys,
@@ -102,13 +102,23 @@ public class IncrementalCompilationState {
102102
else {
103103
return nil
104104
}
105+
// preserve legacy behavior
106+
if let badSwiftDeps = inputsWithUnreadableSwiftDeps.first?.1 {
107+
diagnosticEngine.emit(
108+
.remark_incremental_compilation_disabled(
109+
because: "malformed swift dependencies file '\(badSwiftDeps)'")
110+
)
111+
return nil
112+
}
105113

114+
// But someday, just ensure inputsWithUnreadableSwiftDeps are compiled
106115
self.skippedCompilationInputs = Self.computeSkippedCompilationInputs(
107-
inputFiles: inputFiles,
108-
buildRecordInfo: buildRecordInfo,
109-
moduleDependencyGraph: moduleDependencyGraph,
110-
outOfDateBuildRecord: outOfDateBuildRecord,
111-
reportIncrementalDecision: reportIncrementalDecision)
116+
inputFiles: inputFiles,
117+
inputsWithUnreadableSwiftDeps: inputsWithUnreadableSwiftDeps.map {$0.0},
118+
buildRecordInfo: buildRecordInfo,
119+
moduleDependencyGraph: moduleDependencyGraph,
120+
outOfDateBuildRecord: outOfDateBuildRecord,
121+
reportIncrementalDecision: reportIncrementalDecision)
112122

113123
self.moduleDependencyGraph = moduleDependencyGraph
114124
self.reportIncrementalDecision = reportIncrementalDecision
@@ -194,6 +204,7 @@ extension IncrementalCompilationState {
194204
/// Figure out which compilation inputs are *not* mandatory
195205
private static func computeSkippedCompilationInputs(
196206
inputFiles: [TypedVirtualPath],
207+
inputsWithUnreadableSwiftDeps: [TypedVirtualPath],
197208
buildRecordInfo: BuildRecordInfo,
198209
moduleDependencyGraph: ModuleDependencyGraph,
199210
outOfDateBuildRecord: BuildRecord,
@@ -213,7 +224,7 @@ extension IncrementalCompilationState {
213224
reportIncrementalDecision: reportIncrementalDecision)
214225

215226
// Combine to obtain the inputs that definitely must be recompiled.
216-
let definitelyRequiredInputs = Set(changedInputs.map {$0.0} + externalDependents)
227+
let definitelyRequiredInputs = Set(changedInputs.map {$0.0} + externalDependents + inputsWithUnreadableSwiftDeps)
217228
if let report = reportIncrementalDecision {
218229
for scheduledInput in definitelyRequiredInputs.sorted(by: {$0.file.name < $1.file.name}) {
219230
report("Queuing (initial):", scheduledInput)
@@ -471,8 +482,12 @@ extension IncrementalCompilationState {
471482
Array(
472483
Set(
473484
job.primaryInputs.flatMap {
474-
moduleDependencyGraph.findSourcesToCompileAfterCompiling($0)
475-
?? Array(skippedCompilationInputs)
485+
input -> [TypedVirtualPath] in
486+
if let found = moduleDependencyGraph.findSourcesToCompileAfterCompiling(input) {
487+
return found
488+
}
489+
reportIncrementalDecision?("Failed to read some swiftdeps; compiling everything", input)
490+
return Array(skippedCompilationInputs)
476491
}
477492
)
478493
)

Sources/SwiftDriver/Incremental Compilation/ModuleDependencyGraph Parts/Integrator.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ extension ModuleDependencyGraph.Integrator {
5858
static func integrate(
5959
swiftDeps: Graph.SwiftDeps,
6060
into destination: Graph,
61+
input: TypedVirtualPath,
62+
reportIncrementalDecision: ((String, TypedVirtualPath) -> Void)?,
6163
diagnosticEngine: DiagnosticsEngine
6264
) -> Changes? {
6365
guard let sfdg = try? SourceFileDependencyGraph.read(
6466
from: swiftDeps)
6567
else {
68+
reportIncrementalDecision?("Could not read \(swiftDeps)", input)
6669
return nil
6770
}
6871
return integrate(from: sfdg,

Sources/SwiftDriver/Incremental Compilation/ModuleDependencyGraph.swift

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,40 +49,54 @@ final class ModuleDependencyGraph {
4949
}
5050
// MARK: - initial build only
5151
extension ModuleDependencyGraph {
52+
/// Builds a graph
53+
/// Returns nil if some input has no place to put a swiftdeps file
54+
/// Returns a list of inputs whose swiftdeps files could not be read
5255
static func buildInitialGraph<Inputs: Sequence>(
5356
diagnosticEngine: DiagnosticsEngine,
5457
inputs: Inputs,
5558
outputFileMap: OutputFileMap?,
5659
parsedOptions: inout ParsedOptions,
5760
remarkDisabled: (String) -> Diagnostic.Message,
5861
reportIncrementalDecision: ((String, TypedVirtualPath?) -> Void)?
59-
) -> Self?
62+
) -> (ModuleDependencyGraph, [(TypedVirtualPath, VirtualPath)])?
6063
where Inputs.Element == TypedVirtualPath
6164
{
6265
let emitOpt = Option.driverEmitFineGrainedDependencyDotFileAfterEveryImport
6366
let veriOpt = Option.driverVerifyFineGrainedDependencyGraphAfterEveryImport
64-
let r = Self (
67+
let graph = Self (
6568
diagnosticEngine: diagnosticEngine,
6669
reportIncrementalDecision: reportIncrementalDecision,
6770
emitDependencyDotFileAfterEveryImport: parsedOptions.contains(emitOpt),
6871
verifyDependencyGraphAfterEveryImport: parsedOptions.contains(veriOpt))
69-
for input in inputs {
70-
guard let swiftDepsFile = outputFileMap?.existingOutput(
71-
inputFile: input.file,
72-
outputType: .swiftDeps)
72+
73+
let inputsAndSwiftdeps = inputs.map {input in
74+
(input, outputFileMap?.existingOutput( inputFile: input.file,
75+
outputType: .swiftDeps)
76+
)
77+
}
78+
for isd in inputsAndSwiftdeps where isd.1 == nil {
79+
diagnosticEngine.emit(
80+
remarkDisabled("\(isd.0.file.basename) has no swiftDeps file")
81+
)
82+
return nil
83+
}
84+
let inputsWithUnreadableSwiftDeps = inputsAndSwiftdeps.compactMap {
85+
input, swiftDepsFile -> (TypedVirtualPath, VirtualPath)? in
86+
guard let swiftDepsFile = swiftDepsFile
7387
else {
74-
diagnosticEngine.emit(
75-
remarkDisabled("\(input.file.basename) has no swiftDeps file")
76-
)
7788
return nil
7889
}
7990
let swiftDeps = SwiftDeps(swiftDepsFile)
80-
r.sourceSwiftDepsMap[input] = swiftDeps
81-
_ = Integrator.integrate(swiftDeps: swiftDeps,
82-
into: r,
83-
diagnosticEngine: diagnosticEngine)
91+
graph.sourceSwiftDepsMap[input] = swiftDeps
92+
let changes = Integrator.integrate(swiftDeps: swiftDeps,
93+
into: graph,
94+
input: input,
95+
reportIncrementalDecision: reportIncrementalDecision,
96+
diagnosticEngine: diagnosticEngine)
97+
return changes == nil ? (input, swiftDepsFile) : nil
8498
}
85-
return r
99+
return (graph, inputsWithUnreadableSwiftDeps)
86100
}
87101
}
88102
// MARK: - Scheduling the first wave
@@ -129,17 +143,25 @@ extension ModuleDependencyGraph {
129143
func findSourcesToCompileAfterCompiling(
130144
_ source: TypedVirtualPath
131145
) -> [TypedVirtualPath]? {
132-
findSourcesToCompileAfterIntegrating( sourceSwiftDepsMap[source] )
146+
findSourcesToCompileAfterIntegrating(
147+
input: source,
148+
swiftDeps: sourceSwiftDepsMap[source],
149+
reportIncrementalDecision: reportIncrementalDecision
150+
)
133151
}
134152

135153
/// After a compile job has finished, read its swiftDeps file and return the source files needing
136154
/// recompilation.
137155
/// Return nil in case of an error.
138156
private func findSourcesToCompileAfterIntegrating(
139-
_ swiftDeps: SwiftDeps
157+
input: TypedVirtualPath,
158+
swiftDeps: SwiftDeps,
159+
reportIncrementalDecision: ((String, TypedVirtualPath) -> Void)?
140160
) -> [TypedVirtualPath]? {
141161
Integrator.integrate(swiftDeps: swiftDeps,
142162
into: self,
163+
input: input,
164+
reportIncrementalDecision: reportIncrementalDecision,
143165
diagnosticEngine: diagnosticEngine)
144166
.map {
145167
findSwiftDepsToRecompileWhenNodesChange($0)

0 commit comments

Comments
 (0)