@@ -141,18 +141,45 @@ func printJobInfo(_ job: Job, _ start: Bool, _ verbose: Bool) {
141141  } 
142142} 
143143
144+ class  JSONOutputDelegate :  Encodable  { 
145+   enum  SDKFailureKind :  String ,  Encodable  { 
146+     case  BrokenTextualInterface
147+   } 
148+   struct  SDKFailure :  Encodable  { 
149+     let  inputPath :  String 
150+     let  kind :  SDKFailureKind 
151+   } 
152+   var  allFailures =  [ SDKFailure] ( ) 
153+   func  jobFinished( _ job:  Job ,  _ result:  ProcessResult )  { 
154+     switch  result. exitStatus { 
155+     case  . terminated( code:  let  code) : 
156+       if  code ==  0  { 
157+         break 
158+       }  else  { 
159+         allFailures. append ( SDKFailure ( inputPath:  getLastInputPath ( job) . pathString, 
160+                                       kind:  . BrokenTextualInterface) ) 
161+       } 
162+     default : 
163+       break 
164+     } 
165+   } 
166+ } 
167+ 
144168fileprivate  class  ModuleCompileDelegate :  JobExecutionDelegate  { 
145169  var  failingModules =  Set < String > ( ) 
146170  var  commandMap :  [ Int :  String ]  =  [ : ] 
147171  let  diagnosticsEngine :  DiagnosticsEngine 
148172  let  verbose :  Bool 
149173  var  failingCriticalOutputs :  Set < VirtualPath > 
150174  let  logPath :  AbsolutePath ? 
151-   public  init ( _ jobs:  [ Job ] ,  _ diagnosticsEngine:  DiagnosticsEngine ,  _ verbose:  Bool ,  _ logPath:  AbsolutePath ? )  { 
175+   let  jsonDelegate :  JSONOutputDelegate 
176+   init ( _ jobs:  [ Job ] ,  _ diagnosticsEngine:  DiagnosticsEngine ,  _ verbose:  Bool , 
177+               _ logPath:  AbsolutePath ? ,  _ jsonDelegate:  JSONOutputDelegate )  { 
152178    self . diagnosticsEngine =  diagnosticsEngine
153179    self . verbose =  verbose
154180    self . failingCriticalOutputs =  Set < VirtualPath > ( jobs. compactMap ( ModuleCompileDelegate . getCriticalOutput) ) 
155181    self . logPath =  logPath
182+     self . jsonDelegate =  jsonDelegate
156183  } 
157184
158185  /// Dangling jobs are macabi-only modules. We should run those jobs if foundation
@@ -175,6 +202,7 @@ fileprivate class ModuleCompileDelegate: JobExecutionDelegate {
175202  } 
176203
177204  public  func  jobFinished( job:  Job ,  result:  ProcessResult ,  pid:  Int )  { 
205+     self . jsonDelegate. jobFinished ( job,  result) 
178206    switch  result. exitStatus { 
179207    case  . terminated( code:  let  code) : 
180208      if  code ==  0  { 
@@ -249,6 +277,7 @@ fileprivate class ABICheckingDelegate: JobExecutionDelegate {
249277
250278public  class  PrebuiltModuleGenerationDelegate :  JobExecutionDelegate  { 
251279
280+   fileprivate  let  jsonDelegate :  JSONOutputDelegate 
252281  fileprivate  let  compileDelegate :  ModuleCompileDelegate 
253282  fileprivate  let  abiCheckDelegate :  ABICheckingDelegate 
254283
@@ -264,7 +293,10 @@ public class PrebuiltModuleGenerationDelegate: JobExecutionDelegate {
264293
265294  public  init ( _ jobs:  [ Job ] ,  _ diagnosticsEngine:  DiagnosticsEngine , 
266295              _ verbose:  Bool ,  _ logPath:  AbsolutePath ? )  { 
267-     self . compileDelegate =  ModuleCompileDelegate ( jobs. filter ( ModuleCompileDelegate . canHandle) ,  diagnosticsEngine,  verbose,  logPath) 
296+     self . jsonDelegate =  JSONOutputDelegate ( ) 
297+     self . compileDelegate =  ModuleCompileDelegate ( jobs. filter ( ModuleCompileDelegate . canHandle) , 
298+                                                  diagnosticsEngine,  verbose,  logPath, 
299+                                                  self . jsonDelegate) 
268300    self . abiCheckDelegate =  ABICheckingDelegate ( verbose,  logPath) 
269301  } 
270302
@@ -285,6 +317,13 @@ public class PrebuiltModuleGenerationDelegate: JobExecutionDelegate {
285317  public  var  hasCriticalFailure :  Bool  { 
286318    return  compileDelegate. hasCriticalFailure
287319  } 
320+   public  func  emitJsonOutput( to path:  AbsolutePath )  throws  { 
321+     let  data  =  try JSONEncoder ( ) . encode ( self . jsonDelegate) 
322+     if  let  json =  try ? JSONSerialization . jsonObject ( with:  data,  options:  . mutableContainers) , 
323+        let  jsonData =  try ? JSONSerialization . data ( withJSONObject:  json,  options:  . prettyPrinted)  { 
324+       try . writeFileContents ( path,  bytes:  ByteString ( jsonData) ) 
325+     } 
326+   } 
288327} 
289328
290329public  struct  PrebuiltModuleInput  { 
0 commit comments