@@ -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