@@ -43,6 +43,10 @@ public class LanguageClient : JsonRpcServerBase, ILanguageClient
43
43
// private readonly IEnumerable<InitializedDelegate> _initializedDelegates;
44
44
private readonly IEnumerable < OnLanguageClientStartedDelegate > _startedDelegates ;
45
45
private readonly IEnumerable < IOnLanguageClientStarted > _startedHandlers ;
46
+ private readonly IEnumerable < OnLanguageClientInitializeDelegate > _initializeDelegates ;
47
+ private readonly IEnumerable < IOnLanguageClientInitialize > _initializeHandlers ;
48
+ private readonly IEnumerable < OnLanguageClientInitializedDelegate > _initializedDelegates ;
49
+ private readonly IEnumerable < IOnLanguageClientInitialized > _initializedHandlers ;
46
50
private readonly IResponseRouter _responseRouter ;
47
51
private readonly ISubject < InitializeResult > _initializeComplete = new AsyncSubject < InitializeResult > ( ) ;
48
52
private readonly CompositeDisposable _disposable = new CompositeDisposable ( ) ;
@@ -55,6 +59,7 @@ public class LanguageClient : JsonRpcServerBase, ILanguageClient
55
59
private readonly ClientCapabilities _clientCapabilities ;
56
60
private readonly LanguageProtocolSettingsBag _settingsBag ;
57
61
private bool _started ;
62
+ private readonly int ? _concurrency ;
58
63
59
64
internal static IContainer CreateContainer ( LanguageClientOptions options , IServiceProvider outerServiceProvider ) =>
60
65
JsonRpcServerContainer . Create ( outerServiceProvider )
@@ -70,7 +75,9 @@ public static LanguageClient Create(Action<LanguageClientOptions> optionsAction,
70
75
return Create ( options , outerServiceProvider ) ;
71
76
}
72
77
73
- public static LanguageClient Create ( LanguageClientOptions options , IServiceProvider outerServiceProvider ) => CreateContainer ( options , outerServiceProvider ) . Resolve < LanguageClient > ( ) ;
78
+ public static LanguageClient Create ( LanguageClientOptions options , IServiceProvider outerServiceProvider ) =>
79
+ CreateContainer ( options , outerServiceProvider ) . Resolve < LanguageClient > ( ) ;
80
+
74
81
public static Task < LanguageClient > From ( LanguageClientOptions options ) => From ( options , null , CancellationToken . None ) ;
75
82
public static Task < LanguageClient > From ( Action < LanguageClientOptions > optionsAction ) => From ( optionsAction , null , CancellationToken . None ) ;
76
83
public static Task < LanguageClient > From ( LanguageClientOptions options , CancellationToken cancellationToken ) => From ( options , null , cancellationToken ) ;
@@ -142,8 +149,9 @@ internal LanguageClient(
142
149
IProgressManager progressManager ,
143
150
IClientWorkDoneManager clientWorkDoneManager ,
144
151
IRegistrationManager registrationManager ,
145
- ILanguageClientWorkspaceFoldersManager languageClientWorkspaceFoldersManager
146
- ) : base ( handlerCollection , responseRouter )
152
+ ILanguageClientWorkspaceFoldersManager languageClientWorkspaceFoldersManager , IEnumerable < OnLanguageClientInitializeDelegate > initializeDelegates ,
153
+ IEnumerable < IOnLanguageClientInitialize > initializeHandlers , IEnumerable < OnLanguageClientInitializedDelegate > initializedDelegates ,
154
+ IEnumerable < IOnLanguageClientInitialized > initializedHandlers ) : base ( handlerCollection , responseRouter )
147
155
{
148
156
_connection = connection ;
149
157
_capabilities = capabilities ;
@@ -165,6 +173,11 @@ ILanguageClientWorkspaceFoldersManager languageClientWorkspaceFoldersManager
165
173
WorkDoneManager = clientWorkDoneManager ;
166
174
RegistrationManager = registrationManager ;
167
175
WorkspaceFoldersManager = languageClientWorkspaceFoldersManager ;
176
+ _initializeDelegates = initializeDelegates ;
177
+ _initializeHandlers = initializeHandlers ;
178
+ _initializedDelegates = initializedDelegates ;
179
+ _initializedHandlers = initializedHandlers ;
180
+ _concurrency = options . Value . Concurrency ;
168
181
169
182
// We need to at least create Window here in case any handler does loggin in their constructor
170
183
TextDocument = textDocumentLanguageClient ;
@@ -209,34 +222,55 @@ public async Task Initialize(CancellationToken token)
209
222
WorkspaceFolders = new Container < WorkspaceFolder > ( WorkspaceFoldersManager . CurrentWorkspaceFolders ) ,
210
223
InitializationOptions = _initializationOptions
211
224
} ;
225
+
212
226
RegisterCapabilities ( @params . Capabilities ) ;
227
+
213
228
WorkDoneManager . Initialize ( @params . Capabilities . Window ) ;
214
229
215
230
ClientSettings = @params ;
216
231
232
+ await LanguageProtocolEventingHelper . Run (
233
+ _initializeDelegates ,
234
+ ( handler , ct ) => handler ( this , @params , ct ) ,
235
+ _initializeHandlers . Union ( _collection . Select ( z => z . Handler ) . OfType < IOnLanguageClientInitialize > ( ) ) ,
236
+ ( handler , ct ) => handler . OnInitialize ( this , @params , ct ) ,
237
+ _concurrency ,
238
+ token
239
+ ) ;
240
+
217
241
_connection . Open ( ) ;
218
242
var serverParams = await this . RequestLanguageProtocolInitialize ( ClientSettings , token ) ;
219
243
_receiver . Initialized ( ) ;
220
244
221
- var tasks =
222
- _startedDelegates . Select ( handler => handler ( this , serverParams , token ) )
223
- . Concat ( _startedHandlers
224
- . Union ( _collection . Select ( z => z . Handler ) . OfType < IOnLanguageClientStarted > ( ) )
225
- . Select ( handler => handler . OnStarted ( this , serverParams , token ) )
226
- )
227
- . ToArray ( ) ;
228
- if ( tasks . Length > 0 )
229
- {
230
- await Task . WhenAll ( tasks ) ;
231
- }
232
-
233
245
ServerSettings = serverParams ;
246
+
247
+ await LanguageProtocolEventingHelper . Run (
248
+ _initializedDelegates ,
249
+ ( handler , ct ) => handler ( this , @params , serverParams , ct ) ,
250
+ _initializedHandlers . Union ( _collection . Select ( z => z . Handler ) . OfType < IOnLanguageClientInitialized > ( ) ) ,
251
+ ( handler , ct ) => handler . OnInitialized ( this , @params , serverParams , ct ) ,
252
+ _concurrency ,
253
+ token
254
+ ) ;
255
+
256
+ // post init
257
+
234
258
if ( _collection . ContainsHandler ( typeof ( IRegisterCapabilityHandler ) ) )
235
259
RegistrationManager . RegisterCapabilities ( serverParams . Capabilities ) ;
236
260
261
+ await LanguageProtocolEventingHelper . Run (
262
+ _startedDelegates ,
263
+ ( handler , ct ) => handler ( this , ct ) ,
264
+ _startedHandlers . Union ( _collection . Select ( z => z . Handler ) . OfType < IOnLanguageClientStarted > ( ) ) ,
265
+ ( handler , ct ) => handler . OnStarted ( this , ct ) ,
266
+ _concurrency ,
267
+ token
268
+ ) ;
269
+
270
+ _started = true ;
271
+
237
272
// TODO: pull supported fields and add any static registrations to the registration manager
238
273
this . SendLanguageProtocolInitialized ( new InitializedParams ( ) ) ;
239
- _started = true ;
240
274
}
241
275
242
276
private void RegisterCapabilities ( ClientCapabilities capabilities )
@@ -347,14 +381,34 @@ public IDisposable Register(Action<ILanguageClientRegistry> registryAction)
347
381
var result = manager . GetDisposable ( ) ;
348
382
if ( _started )
349
383
{
350
- foreach ( var item in result . OfType < LspHandlerDescriptorDisposable > ( ) )
351
- foreach ( var descriptor in item . Descriptors )
384
+ static IEnumerable < T > GetUniqueHandlers < T > ( CompositeDisposable disposable )
385
+ {
386
+ return disposable . OfType < ILspHandlerDescriptor > ( )
387
+ . Select ( z => z . Handler )
388
+ . OfType < T > ( )
389
+ . Concat ( disposable . OfType < CompositeDisposable > ( ) . SelectMany ( GetUniqueHandlers < T > ) )
390
+ . Concat ( disposable . OfType < LspHandlerDescriptorDisposable > ( ) . SelectMany ( GetLspHandlers < T > ) )
391
+ . Distinct ( ) ;
392
+ }
393
+ static IEnumerable < T > GetLspHandlers < T > ( LspHandlerDescriptorDisposable disposable )
352
394
{
353
- if ( descriptor . Handler is IOnLanguageClientStarted clientStarted )
354
- {
355
- Observable . FromAsync ( ( ct ) => clientStarted . OnStarted ( this , ServerSettings , ct ) ) . Subscribe ( ) ;
356
- }
395
+ return disposable . Descriptors
396
+ . Select ( z => z . Handler )
397
+ . OfType < T > ( )
398
+ . Distinct ( ) ;
357
399
}
400
+
401
+ Observable . Concat (
402
+ GetUniqueHandlers < IOnLanguageClientInitialize > ( result )
403
+ . Select ( handler => Observable . FromAsync ( ( ct ) => handler . OnInitialize ( this , ClientSettings , ct ) ) )
404
+ . Merge ( ) ,
405
+ GetUniqueHandlers < IOnLanguageClientInitialized > ( result )
406
+ . Select ( handler => Observable . FromAsync ( ( ct ) => handler . OnInitialized ( this , ClientSettings , ServerSettings , ct ) ) )
407
+ . Merge ( ) ,
408
+ GetUniqueHandlers < IOnLanguageClientStarted > ( result )
409
+ . Select ( handler => Observable . FromAsync ( ( ct ) => handler . OnStarted ( this , ct ) ) )
410
+ . Merge ( )
411
+ ) . Subscribe ( ) ;
358
412
}
359
413
360
414
return result ;
0 commit comments