@@ -165,7 +165,33 @@ public protocol DiagnosticCollector {
165165
166166 /// Submits a diagnostic to the collector.
167167 /// - Parameter diagnostic: The diagnostic to submit.
168- func emit( _ diagnostic: Diagnostic )
168+ /// - Throws: An error if the implementing type determines that one should be thrown.
169+ func emit( _ diagnostic: Diagnostic ) throws
170+ }
171+
172+ /// A type that conforms to the `DiagnosticCollector` protocol.
173+ ///
174+ /// It receives diagnostics and forwards them to an upstream `DiagnosticCollector`.
175+ ///
176+ /// If a diagnostic with a severity of `.error` is emitted, this collector will throw the diagnostic as an error.
177+ public struct ErrorThrowingDiagnosticCollector : DiagnosticCollector {
178+ let upstream : any DiagnosticCollector
179+
180+ /// Initializes a new `ErrorThrowingDiagnosticCollector` with an upstream `DiagnosticCollector`.
181+ ///
182+ /// The upstream collector is where this collector will forward all received diagnostics.
183+ ///
184+ /// - Parameter upstream: The `DiagnosticCollector` to which this collector will forward diagnostics.
185+ public init ( upstream: any DiagnosticCollector ) { self . upstream = upstream }
186+
187+ /// Emits a diagnostic to the collector.
188+ ///
189+ /// - Parameter diagnostic: The diagnostic to be submitted.
190+ /// - Throws: The diagnostic itself if its severity is `.error`.
191+ public func emit( _ diagnostic: Diagnostic ) throws {
192+ try upstream. emit ( diagnostic)
193+ if diagnostic. severity == . error { throw diagnostic }
194+ }
169195}
170196
171197extension DiagnosticCollector {
@@ -180,8 +206,9 @@ extension DiagnosticCollector {
180206 /// feature was detected.
181207 /// - context: A set of key-value pairs that help the user understand
182208 /// where the warning occurred.
183- func emitUnsupported( _ feature: String , foundIn: String , context: [ String : String ] = [ : ] ) {
184- emit ( Diagnostic . unsupported ( feature, foundIn: foundIn, context: context) )
209+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
210+ func emitUnsupported( _ feature: String , foundIn: String , context: [ String : String ] = [ : ] ) throws {
211+ try emit ( Diagnostic . unsupported ( feature, foundIn: foundIn, context: context) )
185212 }
186213
187214 /// Emits a diagnostic for an unsupported schema found in the specified
@@ -193,9 +220,10 @@ extension DiagnosticCollector {
193220 /// schema was detected.
194221 /// - context: A set of key-value pairs that help the user understand
195222 /// where the warning occurred.
196- func emitUnsupportedSchema( reason: String , schema: JSONSchema , foundIn: String , context: [ String : String ] = [ : ] ) {
197- emit ( Diagnostic . unsupportedSchema ( reason: reason, schema: schema, foundIn: foundIn, context: context) )
198- }
223+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
224+ func emitUnsupportedSchema( reason: String , schema: JSONSchema , foundIn: String , context: [ String : String ] = [ : ] )
225+ throws
226+ { try emit ( Diagnostic . unsupportedSchema ( reason: reason, schema: schema, foundIn: foundIn, context: context) ) }
199227
200228 /// Emits a diagnostic for an unsupported feature found in the specified
201229 /// type name.
@@ -206,8 +234,9 @@ extension DiagnosticCollector {
206234 /// - foundIn: The type name related to where the issue was detected.
207235 /// - context: A set of key-value pairs that help the user understand
208236 /// where the warning occurred.
209- func emitUnsupported( _ feature: String , foundIn: TypeName , context: [ String : String ] = [ : ] ) {
210- emit ( Diagnostic . unsupported ( feature, foundIn: foundIn. description, context: context) )
237+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
238+ func emitUnsupported( _ feature: String , foundIn: TypeName , context: [ String : String ] = [ : ] ) throws {
239+ try emit ( Diagnostic . unsupported ( feature, foundIn: foundIn. description, context: context) )
211240 }
212241
213242 /// Emits a diagnostic for an unsupported feature found in the specified
@@ -222,9 +251,12 @@ extension DiagnosticCollector {
222251 /// feature was detected.
223252 /// - context: A set of key-value pairs that help the user understand
224253 /// where the warning occurred.
225- func emitUnsupportedIfNotNil( _ test: Any ? , _ feature: String , foundIn: String , context: [ String : String ] = [ : ] ) {
254+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
255+ func emitUnsupportedIfNotNil( _ test: Any ? , _ feature: String , foundIn: String , context: [ String : String ] = [ : ] )
256+ throws
257+ {
226258 if test == nil { return }
227- emitUnsupported ( feature, foundIn: foundIn, context: context)
259+ try emitUnsupported ( feature, foundIn: foundIn, context: context)
228260 }
229261
230262 /// Emits a diagnostic for an unsupported feature found in the specified
@@ -239,14 +271,15 @@ extension DiagnosticCollector {
239271 /// feature was detected.
240272 /// - context: A set of key-value pairs that help the user understand
241273 /// where the warning occurred.
274+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
242275 func emitUnsupportedIfNotEmpty< C: Collection > (
243276 _ test: C ? ,
244277 _ feature: String ,
245278 foundIn: String ,
246279 context: [ String : String ] = [ : ]
247- ) {
280+ ) throws {
248281 guard let test = test, !test. isEmpty else { return }
249- emitUnsupported ( feature, foundIn: foundIn, context: context)
282+ try emitUnsupported ( feature, foundIn: foundIn, context: context)
250283 }
251284
252285 /// Emits a diagnostic for an unsupported feature found in the specified
@@ -261,9 +294,11 @@ extension DiagnosticCollector {
261294 /// feature was detected.
262295 /// - context: A set of key-value pairs that help the user understand
263296 /// where the warning occurred.
264- func emitUnsupportedIfTrue( _ test: Bool , _ feature: String , foundIn: String , context: [ String : String ] = [ : ] ) {
297+ /// - Throws: This method will throw the diagnostic if the severity of the diagnostic is `.error`.
298+ func emitUnsupportedIfTrue( _ test: Bool , _ feature: String , foundIn: String , context: [ String : String ] = [ : ] ) throws
299+ {
265300 if !test { return }
266- emitUnsupported ( feature, foundIn: foundIn, context: context)
301+ try emitUnsupported ( feature, foundIn: foundIn, context: context)
267302 }
268303}
269304
0 commit comments