@@ -108,6 +108,9 @@ package actor DynamicallyLoadedSourceKitD: SourceKitD {
108108 /// List of notification handlers that will be called for each notification.
109109 private var notificationHandlers : [ WeakSKDNotificationHandler ] = [ ]
110110
111+ /// List of hooks that should be executed for every request sent to sourcekitd.
112+ private var requestHandlingHooks : [ UUID : ( SKDRequestDictionary ) -> Void ] = [ : ]
113+
111114 package static func getOrCreate(
112115 dylibPath: URL ,
113116 pluginPaths: PluginPaths ?
@@ -204,6 +207,29 @@ package actor DynamicallyLoadedSourceKitD: SourceKitD {
204207 notificationHandlers. removeAll ( where: { $0. value == nil || $0. value === handler } )
205208 }
206209
210+ /// Execute `body` and invoke `hook` for every sourcekitd request that is sent during the execution time of `body`.
211+ ///
212+ /// Note that `hook` will not only be executed for requests sent *by* body but this may also include sourcekitd
213+ /// requests that were sent by other clients of the same `DynamicallyLoadedSourceKitD` instance that just happen to
214+ /// send a request during that time.
215+ ///
216+ /// This is intended for testing only.
217+ package func withRequestHandlingHook(
218+ body: ( ) async throws -> Void ,
219+ hook: @escaping ( SKDRequestDictionary ) -> Void
220+ ) async rethrows {
221+ let id = UUID ( )
222+ requestHandlingHooks [ id] = hook
223+ defer { requestHandlingHooks [ id] = nil }
224+ try await body ( )
225+ }
226+
227+ package func didSend( request: SKDRequestDictionary ) {
228+ for hook in requestHandlingHooks. values {
229+ hook ( request)
230+ }
231+ }
232+
207233 package nonisolated func log( request: SKDRequestDictionary ) {
208234 logger. info (
209235 """
0 commit comments