@@ -18,35 +18,43 @@ class CopilotLocalProcessServer {
1818 public convenience init (
1919 path: String ,
2020 arguments: [ String ] ,
21- environment: [ String : String ] ? = nil
21+ environment: [ String : String ] ? = nil ,
22+ serverNotificationHandler: ServerNotificationHandler
2223 ) {
2324 let params = Process . ExecutionParameters (
2425 path: path,
2526 arguments: arguments,
2627 environment: environment
2728 )
2829
29- self . init ( executionParameters: params)
30+ self . init ( executionParameters: params, serverNotificationHandler : serverNotificationHandler )
3031 }
3132
32- init ( executionParameters parameters: Process . ExecutionParameters ) {
33+ init (
34+ executionParameters parameters: Process . ExecutionParameters ,
35+ serverNotificationHandler: ServerNotificationHandler
36+ ) {
3337 transport = StdioDataTransport ( )
3438 let framing = SeperatedHTTPHeaderMessageFraming ( )
3539 let messageTransport = MessageTransport (
3640 dataTransport: transport,
3741 messageProtocol: framing
3842 )
3943 customTransport = CustomDataTransport ( nextTransport: messageTransport)
40- wrappedServer = CustomJSONRPCLanguageServer ( dataTransport: customTransport)
44+ wrappedServer = CustomJSONRPCLanguageServer (
45+ dataTransport: customTransport,
46+ serverNotificationHandler: serverNotificationHandler
47+ )
4148
4249 process = Process ( )
4350
4451 // Because the implementation of LanguageClient is so closed,
4552 // we need to get the request IDs from a custom transport before the data
4653 // is written to the language server.
4754 customTransport. onWriteRequest = { [ weak self] request in
48- if request. method == " getCompletionsCycling "
49- || request. method == " textDocument/inlineCompletion " {
55+ if request. method == " getCompletionsCycling "
56+ || request. method == " textDocument/inlineCompletion "
57+ {
5058 Task { @MainActor [ weak self] in
5159 self ? . ongoingCompletionRequestIDs. append ( request. id)
5260 }
@@ -85,7 +93,7 @@ class CopilotLocalProcessServer {
8593 get { return wrappedServer? . logMessages ?? false }
8694 set { wrappedServer? . logMessages = newValue }
8795 }
88-
96+
8997 func terminate( ) {
9098 process. terminate ( )
9199 }
@@ -155,36 +163,47 @@ final class CustomJSONRPCLanguageServer: Server {
155163
156164 private let protocolTransport : ProtocolTransport
157165
158- public var requestHandler : RequestHandler ?
159- public var notificationHandler : NotificationHandler ?
166+ var requestHandler : RequestHandler ?
167+ var serverNotificationHandler : ServerNotificationHandler
168+
169+ @available ( * , deprecated, message: " Use `serverNotificationHandler` instead. " )
170+ var notificationHandler : NotificationHandler ? {
171+ get { nil }
172+ set { }
173+ }
160174
161175 private var outOfBandError : Error ?
162176
163- init ( protocolTransport: ProtocolTransport ) {
177+ init (
178+ protocolTransport: ProtocolTransport ,
179+ serverNotificationHandler: ServerNotificationHandler
180+ ) {
181+ self . serverNotificationHandler = serverNotificationHandler
164182 self . protocolTransport = protocolTransport
165183 internalServer = JSONRPCLanguageServer ( protocolTransport: protocolTransport)
166184
167- let previouseRequestHandler = protocolTransport. requestHandler
168- let previouseNotificationHandler = protocolTransport. notificationHandler
185+ let previousRequestHandler = protocolTransport. requestHandler
169186
170- protocolTransport
171- . requestHandler = { [ weak self] in
172- guard let self else { return }
173- if !self . handleRequest ( $0, data: $1, callback: $2) {
174- previouseRequestHandler ? ( $0, $1, $2)
175- }
176- }
177- protocolTransport
178- . notificationHandler = { [ weak self] in
179- guard let self else { return }
180- if !self . handleNotification ( $0, data: $1, block: $2) {
181- previouseNotificationHandler ? ( $0, $1, $2)
182- }
187+ protocolTransport. requestHandler = { [ weak self] in
188+ guard let self else { return }
189+ if !self . handleRequest ( $0, data: $1, callback: $2) {
190+ previousRequestHandler ? ( $0, $1, $2)
183191 }
192+ }
193+ protocolTransport. notificationHandler = { [ weak self] in
194+ guard let self else { return }
195+ self . handleNotification ( $0, data: $1, block: $2)
196+ }
184197 }
185198
186- convenience init ( dataTransport: DataTransport ) {
187- self . init ( protocolTransport: ProtocolTransport ( dataTransport: dataTransport) )
199+ convenience init (
200+ dataTransport: DataTransport ,
201+ serverNotificationHandler: ServerNotificationHandler
202+ ) {
203+ self . init (
204+ protocolTransport: ProtocolTransport ( dataTransport: dataTransport) ,
205+ serverNotificationHandler: serverNotificationHandler
206+ )
188207 }
189208
190209 deinit {
@@ -203,7 +222,72 @@ extension CustomJSONRPCLanguageServer {
203222 _ anyNotification: AnyJSONRPCNotification ,
204223 data: Data ,
205224 block: @escaping ( Error ? ) -> Void
225+ ) {
226+ Task {
227+ do {
228+ try await serverNotificationHandler. handleNotification (
229+ anyNotification,
230+ data: data
231+ )
232+ block ( nil )
233+ } catch {
234+ block ( error)
235+ }
236+ }
237+ }
238+
239+ func sendNotification(
240+ _ notif: ClientNotification ,
241+ completionHandler: @escaping ( ServerError ? ) -> Void
242+ ) {
243+ internalServer. sendNotification ( notif, completionHandler: completionHandler)
244+ }
245+ }
246+
247+ extension CustomJSONRPCLanguageServer {
248+ private func handleRequest(
249+ _ request: AnyJSONRPCRequest ,
250+ data: Data ,
251+ callback: @escaping ( AnyJSONRPCResponse ) -> Void
206252 ) -> Bool {
253+ return false
254+ }
255+ }
256+
257+ extension CustomJSONRPCLanguageServer {
258+ public func sendRequest< Response: Codable > (
259+ _ request: ClientRequest ,
260+ completionHandler: @escaping ( ServerResult < Response > ) -> Void
261+ ) {
262+ internalServer. sendRequest ( request, completionHandler: completionHandler)
263+ }
264+ }
265+
266+ @GitHubCopilotSuggestionActor
267+ final class ServerNotificationHandler {
268+ typealias Handler = (
269+ _ anyNotification: AnyJSONRPCNotification ,
270+ _ data: Data
271+ ) async throws -> Bool
272+
273+ var handlers = [ AnyHashable: Handler] ( )
274+ nonisolated init ( ) { }
275+
276+ func handleNotification(
277+ _ anyNotification: AnyJSONRPCNotification ,
278+ data: Data
279+ ) async throws {
280+ for handler in handlers. values {
281+ do {
282+ let handled = try await handler ( anyNotification, data)
283+ if handled {
284+ return
285+ }
286+ } catch {
287+ throw ServerError . notificationDispatchFailed ( error)
288+ }
289+ }
290+
207291 let methodName = anyNotification. method
208292 let debugDescription = {
209293 if let params = anyNotification. params {
@@ -223,65 +307,29 @@ extension CustomJSONRPCLanguageServer {
223307 Logger . gitHubCopilot
224308 . info ( " \( anyNotification. method) : \( debugDescription) " )
225309 }
226- block ( nil )
227- return true
228310 case " LogMessage " :
229311 if UserDefaults . shared. value ( for: \. gitHubCopilotVerboseLog) {
230312 Logger . gitHubCopilot
231313 . info ( " \( anyNotification. method) : \( debugDescription) " )
232314 }
233- block ( nil ) //
234- return true
235315 case " statusNotification " :
236316 if UserDefaults . shared. value ( for: \. gitHubCopilotVerboseLog) {
237317 Logger . gitHubCopilot
238318 . info ( " \( anyNotification. method) : \( debugDescription) " )
239319 }
240- block ( nil )
241- return true
242320 case " featureFlagsNotification " :
243321 if UserDefaults . shared. value ( for: \. gitHubCopilotVerboseLog) {
244322 Logger . gitHubCopilot
245323 . info ( " \( anyNotification. method) : \( debugDescription) " )
246324 }
247- block ( nil )
248- return true
249325 case " conversation/preconditionsNotification " :
250326 if UserDefaults . shared. value ( for: \. gitHubCopilotVerboseLog) {
251327 Logger . gitHubCopilot
252328 . info ( " \( anyNotification. method) : \( debugDescription) " )
253329 }
254- block ( nil )
255- return true
256330 default :
257- return false
331+ throw ServerError . handlerUnavailable ( methodName )
258332 }
259333 }
260-
261- public func sendNotification(
262- _ notif: ClientNotification ,
263- completionHandler: @escaping ( ServerError ? ) -> Void
264- ) {
265- internalServer. sendNotification ( notif, completionHandler: completionHandler)
266- }
267- }
268-
269- extension CustomJSONRPCLanguageServer {
270- private func handleRequest(
271- _ request: AnyJSONRPCRequest ,
272- data: Data ,
273- callback: @escaping ( AnyJSONRPCResponse ) -> Void
274- ) -> Bool {
275- return false
276- }
277- }
278-
279- extension CustomJSONRPCLanguageServer {
280- public func sendRequest< Response: Codable > (
281- _ request: ClientRequest ,
282- completionHandler: @escaping ( ServerResult < Response > ) -> Void
283- ) {
284- internalServer. sendRequest ( request, completionHandler: completionHandler)
285- }
286334}
287335
0 commit comments