Skip to content

Commit a768642

Browse files
committed
[Dependency Scanning] Upon scan failure, ensure scanner diagnostics are emitted
1 parent 54ec38b commit a768642

File tree

3 files changed

+50
-38
lines changed

3 files changed

+50
-38
lines changed

Sources/SwiftDriver/ExplicitModuleBuilds/ModuleDependencyScanning.swift

+38-26
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extension Diagnostic.Message {
2727
.warning("Fallback to `swift-frontend` dependency scanner invocation")
2828
}
2929
static func scanner_diagnostic_error(_ message: String) -> Diagnostic.Message {
30-
.error("Dependency scanning failure: \(message)")
30+
.error(message)
3131
}
3232
static func scanner_diagnostic_warn(_ message: String) -> Diagnostic.Message {
3333
.warning(message)
@@ -205,11 +205,15 @@ public extension Driver {
205205
useResponseFiles: .disabled,
206206
using: executor.resolver)
207207
Self.sanitizeCommandForLibScanInvocation(&command)
208-
imports =
209-
try interModuleDependencyOracle.getImports(workingDirectory: cwd,
210-
moduleAliases: moduleOutputInfo.aliases,
211-
commandLine: command)
212-
208+
do {
209+
imports = try interModuleDependencyOracle.getImports(workingDirectory: cwd,
210+
moduleAliases: moduleOutputInfo.aliases,
211+
commandLine: command)
212+
} catch let DependencyScanningError.dependencyScanFailed(reason) {
213+
try emitScannerDiagnostics()
214+
throw DependencyScanningError.dependencyScanFailed(reason)
215+
}
216+
try emitScannerDiagnostics()
213217
} else {
214218
// Fallback to legacy invocation of the dependency scanner with
215219
// `swift-frontend -scan-dependencies -import-prescan`
@@ -222,6 +226,26 @@ public extension Driver {
222226
return imports
223227
}
224228

229+
mutating internal func emitScannerDiagnostics() throws {
230+
let possibleDiags = try interModuleDependencyOracle.getScannerDiagnostics()
231+
if let diags = possibleDiags {
232+
for diagnostic in diags {
233+
switch diagnostic.severity {
234+
case .error:
235+
diagnosticEngine.emit(.scanner_diagnostic_error(diagnostic.message))
236+
case .warning:
237+
diagnosticEngine.emit(.scanner_diagnostic_warn(diagnostic.message))
238+
case .note:
239+
diagnosticEngine.emit(.scanner_diagnostic_note(diagnostic.message))
240+
case .remark:
241+
diagnosticEngine.emit(.scanner_diagnostic_remark(diagnostic.message))
242+
case .ignored:
243+
diagnosticEngine.emit(.scanner_diagnostic_error(diagnostic.message))
244+
}
245+
}
246+
}
247+
}
248+
225249
mutating internal func performDependencyScan() throws -> InterModuleDependencyGraph {
226250
let scannerJob = try dependencyScanningJob()
227251
let forceResponseFiles = parsedOptions.hasArgument(.driverForceResponseFiles)
@@ -241,27 +265,15 @@ public extension Driver {
241265
useResponseFiles: .disabled,
242266
using: executor.resolver)
243267
Self.sanitizeCommandForLibScanInvocation(&command)
244-
dependencyGraph =
245-
try interModuleDependencyOracle.getDependencies(workingDirectory: cwd,
246-
moduleAliases: moduleOutputInfo.aliases,
247-
commandLine: command)
248-
let possibleDiags = try interModuleDependencyOracle.getScannerDiagnostics()
249-
if let diags = possibleDiags {
250-
for diagnostic in diags {
251-
switch diagnostic.severity {
252-
case .error:
253-
diagnosticEngine.emit(.scanner_diagnostic_error(diagnostic.message))
254-
case .warning:
255-
diagnosticEngine.emit(.scanner_diagnostic_warn(diagnostic.message))
256-
case .note:
257-
diagnosticEngine.emit(.scanner_diagnostic_note(diagnostic.message))
258-
case .remark:
259-
diagnosticEngine.emit(.scanner_diagnostic_remark(diagnostic.message))
260-
case .ignored:
261-
diagnosticEngine.emit(.scanner_diagnostic_error(diagnostic.message))
262-
}
263-
}
268+
do {
269+
dependencyGraph = try interModuleDependencyOracle.getDependencies(workingDirectory: cwd,
270+
moduleAliases: moduleOutputInfo.aliases,
271+
commandLine: command)
272+
} catch let DependencyScanningError.dependencyScanFailed(reason) {
273+
try emitScannerDiagnostics()
274+
throw DependencyScanningError.dependencyScanFailed(reason)
264275
}
276+
try emitScannerDiagnostics()
265277
} else {
266278
// Fallback to legacy invocation of the dependency scanner with
267279
// `swift-frontend -scan-dependencies`

Sources/SwiftDriver/SwiftScan/DependencyGraphBuilder.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ internal extension SwiftScan {
6767
// Note, respective indices of the batch scan input and the returned result must be aligned.
6868
for (index, resultGraphRefOrNull) in resultGraphRefArray.enumerated() {
6969
guard let resultGraphRef = resultGraphRefOrNull else {
70-
throw DependencyScanningError.dependencyScanFailed
70+
throw DependencyScanningError.dependencyScanFailed("Unable to produce dependency graph from batch scan result")
7171
}
7272
let decodedGraph = try constructGraph(from: resultGraphRef, moduleAliases: moduleAliases)
7373

Sources/SwiftDriver/SwiftScan/SwiftScan.swift

+11-11
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import struct TSCBasic.Diagnostic
2323

2424
public enum DependencyScanningError: Error, DiagnosticData {
2525
case missingRequiredSymbol(String)
26-
case dependencyScanFailed
26+
case dependencyScanFailed(String)
2727
case failedToInstantiateScanner
2828
case casError(String)
2929
case missingField(String)
@@ -38,14 +38,14 @@ public enum DependencyScanningError: Error, DiagnosticData {
3838
switch self {
3939
case .missingRequiredSymbol(let symbolName):
4040
return "libSwiftScan missing required symbol: '\(symbolName)'"
41-
case .dependencyScanFailed:
42-
return "libSwiftScan dependency scan query failed"
41+
case .dependencyScanFailed(let reason):
42+
return "Dependency scan query failed: `\(reason)`"
4343
case .failedToInstantiateScanner:
44-
return "libSwiftScan failed to create scanner instance"
44+
return "Failed to create scanner instance"
4545
case .casError(let reason):
46-
return "libSwiftScan CAS error: \(reason)"
46+
return "CAS error: \(reason)"
4747
case .missingField(let fieldName):
48-
return "libSwiftScan scan result missing required field: `\(fieldName)`"
48+
return "Scan result missing required field: `\(fieldName)`"
4949
case .moduleNameDecodeFailure(let encodedName):
5050
return "Failed to decode dependency module name: `\(encodedName)`"
5151
case .unsupportedDependencyDetailsKind(let kindRawValue):
@@ -57,7 +57,7 @@ public enum DependencyScanningError: Error, DiagnosticData {
5757
case .scanningLibraryNotFound(let path):
5858
return "Dependency Scanning library not found at path: \(path)"
5959
case .argumentQueryFailed:
60-
return "libSwiftScan supported compiler argument query failed"
60+
return "Supported compiler argument query failed"
6161
}
6262
}
6363
}
@@ -137,7 +137,7 @@ internal extension swiftscan_diagnostic_severity_t {
137137

138138
let importSetRefOrNull = api.swiftscan_import_set_create(scanner, invocation)
139139
guard let importSetRef = importSetRefOrNull else {
140-
throw DependencyScanningError.dependencyScanFailed
140+
throw DependencyScanningError.dependencyScanFailed("Unable to produce import set")
141141
}
142142

143143
let importSet = try constructImportSet(from: importSetRef, with: moduleAliases)
@@ -165,7 +165,7 @@ internal extension swiftscan_diagnostic_severity_t {
165165

166166
let graphRefOrNull = api.swiftscan_dependency_graph_create(scanner, invocation)
167167
guard let graphRef = graphRefOrNull else {
168-
throw DependencyScanningError.dependencyScanFailed
168+
throw DependencyScanningError.dependencyScanFailed("Unable to produce dependency graph")
169169
}
170170

171171
let dependencyGraph = try constructGraph(from: graphRef, moduleAliases: moduleAliases)
@@ -226,7 +226,7 @@ internal extension swiftscan_diagnostic_severity_t {
226226
inputRef,
227227
invocationRef)
228228
guard let batchResultRef = batchResultRefOrNull else {
229-
throw DependencyScanningError.dependencyScanFailed
229+
throw DependencyScanningError.dependencyScanFailed("Unable to produce batch scan results")
230230
}
231231
// Translate `swiftscan_batch_scan_result_t`
232232
// into `[ModuleDependencyId: [InterModuleDependencyGraph]]`
@@ -326,7 +326,7 @@ internal extension swiftscan_diagnostic_severity_t {
326326

327327
for diagnosticRefOrNull in diagnosticRefArray {
328328
guard let diagnosticRef = diagnosticRefOrNull else {
329-
throw DependencyScanningError.dependencyScanFailed
329+
throw DependencyScanningError.dependencyScanFailed("Unable to produce scanner diagnostics")
330330
}
331331
let message = try toSwiftString(api.swiftscan_diagnostic_get_message(diagnosticRef))
332332
let severity = api.swiftscan_diagnostic_get_severity(diagnosticRef)

0 commit comments

Comments
 (0)