@@ -69,7 +69,11 @@ public final class TestSourceKitLSPClient: MessageHandler {
69
69
///
70
70
/// Conceptually, this is an array of `RequestHandler<any RequestType>` but
71
71
/// since we can't express this in the Swift type system, we use `[Any]`.
72
- private nonisolated ( unsafe) var requestHandlers = ThreadSafeBox < [ Any ] > ( initialValue: [ ] )
72
+ ///
73
+ /// `isOneShort` if the request handler should only serve a single request and should be removed from
74
+ /// `requestHandlers` after it has been called.
75
+ private nonisolated ( unsafe) var requestHandlers: ThreadSafeBox < [ ( requestHandler: Any , isOneShot: Bool ) ] > =
76
+ ThreadSafeBox ( initialValue: [ ] )
73
77
74
78
/// A closure that is called when the `TestSourceKitLSPClient` is destructed.
75
79
///
@@ -263,7 +267,12 @@ public final class TestSourceKitLSPClient: MessageHandler {
263
267
/// The request handler will only handle a single request. If the request is called again, the request handler won't
264
268
/// call again
265
269
public func handleSingleRequest< R: RequestType > ( _ requestHandler: @escaping RequestHandler < R > ) {
266
- requestHandlers. value. append ( requestHandler)
270
+ requestHandlers. value. append ( ( requestHandler: requestHandler, isOneShot: true ) )
271
+ }
272
+
273
+ /// Handle all requests of the given type that are sent to the client.
274
+ public func handleMultipleRequests< R: RequestType > ( _ requestHandler: @escaping RequestHandler < R > ) {
275
+ requestHandlers. value. append ( ( requestHandler: requestHandler, isOneShot: false ) )
267
276
}
268
277
269
278
// MARK: - Conformance to MessageHandler
@@ -280,19 +289,21 @@ public final class TestSourceKitLSPClient: MessageHandler {
280
289
reply: @escaping ( LSPResult < Request . Response > ) -> Void
281
290
) {
282
291
requestHandlers. withLock { requestHandlers in
283
- let requestHandlerAndIndex = requestHandlers. enumerated ( ) . compactMap {
284
- ( index, handler ) -> ( RequestHandler < Request > , Int ) ? in
285
- guard let handler = handler as? RequestHandler < Request > else {
292
+ let requestHandlerIndexAndIsOneShot = requestHandlers. enumerated ( ) . compactMap {
293
+ ( index, handlerAndIsOneShot ) -> ( RequestHandler < Request > , Int , Bool ) ? in
294
+ guard let handler = handlerAndIsOneShot . requestHandler as? RequestHandler < Request > else {
286
295
return nil
287
296
}
288
- return ( handler, index)
297
+ return ( handler, index, handlerAndIsOneShot . isOneShot )
289
298
} . first
290
- guard let ( requestHandler, index) = requestHandlerAndIndex else {
299
+ guard let ( requestHandler, index, isOneShot ) = requestHandlerIndexAndIsOneShot else {
291
300
reply ( . failure( . methodNotFound( Request . method) ) )
292
301
return
293
302
}
294
303
reply ( . success( requestHandler ( params) ) )
295
- requestHandlers. remove ( at: index)
304
+ if isOneShot {
305
+ requestHandlers. remove ( at: index)
306
+ }
296
307
}
297
308
}
298
309
0 commit comments