@@ -126,7 +126,8 @@ internal extension swiftscan_diagnostic_severity_t {
126126
127127 func preScanImports( workingDirectory: AbsolutePath ,
128128 moduleAliases: [ String : String ] ? ,
129- invocationCommand: [ String ] ) throws -> InterModuleDependencyImports {
129+ invocationCommand: [ String ] ,
130+ diagnostics: inout [ ScannerDiagnosticPayload ] ) throws -> InterModuleDependencyImports {
130131 // Create and configure the scanner invocation
131132 let invocation = api. swiftscan_scan_invocation_create ( )
132133 defer { api. swiftscan_scan_invocation_dispose ( invocation) }
@@ -144,6 +145,13 @@ internal extension swiftscan_diagnostic_severity_t {
144145 guard let importSetRef = importSetRefOrNull else {
145146 throw DependencyScanningError . dependencyScanFailed ( " Unable to produce import set " )
146147 }
148+ if canQueryPerScanDiagnostics {
149+ let diagnosticsSetRefOrNull = api. swiftscan_import_set_get_diagnostics ( importSetRef)
150+ guard let diagnosticsSetRef = diagnosticsSetRefOrNull else {
151+ throw DependencyScanningError . dependencyScanFailed ( " Unable to query dependency diagnostics " )
152+ }
153+ diagnostics = try mapToDriverDiagnosticPayload ( diagnosticsSetRef)
154+ }
147155
148156 let importSet = try constructImportSet ( from: importSetRef, with: moduleAliases)
149157 // Free the memory allocated for the in-memory representation of the import set
@@ -154,7 +162,8 @@ internal extension swiftscan_diagnostic_severity_t {
154162
155163 func scanDependencies( workingDirectory: AbsolutePath ,
156164 moduleAliases: [ String : String ] ? ,
157- invocationCommand: [ String ] ) throws -> InterModuleDependencyGraph {
165+ invocationCommand: [ String ] ,
166+ diagnostics: inout [ ScannerDiagnosticPayload ] ) throws -> InterModuleDependencyGraph {
158167 // Create and configure the scanner invocation
159168 let invocation = api. swiftscan_scan_invocation_create ( )
160169 defer { api. swiftscan_scan_invocation_dispose ( invocation) }
@@ -172,6 +181,13 @@ internal extension swiftscan_diagnostic_severity_t {
172181 guard let graphRef = graphRefOrNull else {
173182 throw DependencyScanningError . dependencyScanFailed ( " Unable to produce dependency graph " )
174183 }
184+ if canQueryPerScanDiagnostics {
185+ let diagnosticsSetRefOrNull = api. swiftscan_dependency_graph_get_diagnostics ( graphRef)
186+ guard let diagnosticsSetRef = diagnosticsSetRefOrNull else {
187+ throw DependencyScanningError . dependencyScanFailed ( " Unable to query dependency diagnostics " )
188+ }
189+ diagnostics = try mapToDriverDiagnosticPayload ( diagnosticsSetRef)
190+ }
175191
176192 let dependencyGraph = try constructGraph ( from: graphRef, moduleAliases: moduleAliases)
177193 // Free the memory allocated for the in-memory representation of the dependency
@@ -184,7 +200,8 @@ internal extension swiftscan_diagnostic_severity_t {
184200 func batchScanDependencies( workingDirectory: AbsolutePath ,
185201 moduleAliases: [ String : String ] ? ,
186202 invocationCommand: [ String ] ,
187- batchInfos: [ BatchScanModuleInfo ] )
203+ batchInfos: [ BatchScanModuleInfo ] ,
204+ diagnostics: inout [ ScannerDiagnosticPayload ] )
188205 throws -> [ ModuleDependencyId : [ InterModuleDependencyGraph ] ] {
189206 // Create and configure the scanner invocation
190207 let invocationRef = api. swiftscan_scan_invocation_create ( )
@@ -315,6 +332,12 @@ internal extension swiftscan_diagnostic_severity_t {
315332 return api. swiftscan_swift_textual_detail_get_bridging_pch_command_line != nil
316333 }
317334
335+
336+ @_spi ( Testing) public var canQueryPerScanDiagnostics : Bool {
337+ return api. swiftscan_dependency_graph_get_diagnostics != nil &&
338+ api. swiftscan_import_set_get_diagnostics != nil
339+ }
340+
318341 func serializeScannerCache( to path: AbsolutePath ) {
319342 api. swiftscan_scanner_cache_serialize ( scanner,
320343 path. description. cString ( using: String . Encoding. utf8) )
@@ -329,18 +352,10 @@ internal extension swiftscan_diagnostic_severity_t {
329352 api. swiftscan_scanner_cache_reset ( scanner)
330353 }
331354
332- @ _spi ( Testing ) public func queryScannerDiagnostics ( ) throws -> [ ScannerDiagnosticPayload ] {
355+ internal func mapToDriverDiagnosticPayload ( _ diagnosticSetRef : UnsafeMutablePointer < swiftscan_diagnostic_set_t > ) throws -> [ ScannerDiagnosticPayload ] {
333356 var result : [ ScannerDiagnosticPayload ] = [ ]
334- let diagnosticSetRefOrNull = api. swiftscan_scanner_diagnostics_query ( scanner)
335- guard let diagnosticSetRef = diagnosticSetRefOrNull else {
336- // Seems heavy-handed to fail here
337- // throw DependencyScanningError.dependencyScanFailed
338- return [ ]
339- }
340- defer { api. swiftscan_diagnostics_set_dispose ( diagnosticSetRef) }
341357 let diagnosticRefArray = Array ( UnsafeBufferPointer ( start: diagnosticSetRef. pointee. diagnostics,
342358 count: Int ( diagnosticSetRef. pointee. count) ) )
343-
344359 for diagnosticRefOrNull in diagnosticRefArray {
345360 guard let diagnosticRef = diagnosticRefOrNull else {
346361 throw DependencyScanningError . dependencyScanFailed ( " Unable to produce scanner diagnostics " )
@@ -352,6 +367,17 @@ internal extension swiftscan_diagnostic_severity_t {
352367 return result
353368 }
354369
370+ @_spi ( Testing) public func queryScannerDiagnostics( ) throws -> [ ScannerDiagnosticPayload ] {
371+ let diagnosticSetRefOrNull = api. swiftscan_scanner_diagnostics_query ( scanner)
372+ guard let diagnosticSetRef = diagnosticSetRefOrNull else {
373+ // Seems heavy-handed to fail here
374+ // throw DependencyScanningError.dependencyScanFailed
375+ return [ ]
376+ }
377+ defer { api. swiftscan_diagnostics_set_dispose ( diagnosticSetRef) }
378+ return try mapToDriverDiagnosticPayload ( diagnosticSetRef)
379+ }
380+
355381 @_spi ( Testing) public func resetScannerDiagnostics( ) throws {
356382 api. swiftscan_scanner_diagnostics_reset ( scanner)
357383 }
@@ -567,6 +593,12 @@ private extension swiftscan_functions_t {
567593 self . swiftscan_swift_binary_detail_get_header_dependencies =
568594 try loadOptional ( " swiftscan_swift_binary_detail_get_header_dependencies " )
569595
596+ // Per-scan-query diagnostic output
597+ self . swiftscan_dependency_graph_get_diagnostics =
598+ try loadOptional ( " swiftscan_dependency_graph_get_diagnostics " )
599+ self . swiftscan_import_set_get_diagnostics =
600+ try loadOptional ( " swiftscan_import_set_get_diagnostics " )
601+
570602 // MARK: Required Methods
571603 func loadRequired< T> ( _ symbol: String ) throws -> T {
572604 guard let sym: T = Loader . lookup ( symbol: symbol, in: swiftscan) else {
0 commit comments