55using System . Reactive . Linq ;
66using System . Reactive . Subjects ;
77using System . Reactive . Threading . Tasks ;
8+ using System . Reflection ;
89using System . Threading ;
910using System . Threading . Tasks ;
1011using DryIoc ;
@@ -42,6 +43,7 @@ public class LanguageClient : JsonRpcServerBase, ILanguageClient
4243 private readonly IEnumerable < IOnLanguageClientInitialize > _initializeHandlers ;
4344 private readonly IEnumerable < OnLanguageClientInitializedDelegate > _initializedDelegates ;
4445 private readonly IEnumerable < IOnLanguageClientInitialized > _initializedHandlers ;
46+ private readonly ISerializer _serializer ;
4547 private readonly IResponseRouter _responseRouter ;
4648 private readonly ISubject < InitializeResult > _initializeComplete = new AsyncSubject < InitializeResult > ( ) ;
4749 private readonly CompositeDisposable _disposable = new CompositeDisposable ( ) ;
@@ -140,7 +142,8 @@ internal LanguageClient(
140142 IRegistrationManager registrationManager ,
141143 ILanguageClientWorkspaceFoldersManager languageClientWorkspaceFoldersManager , IEnumerable < OnLanguageClientInitializeDelegate > initializeDelegates ,
142144 IEnumerable < IOnLanguageClientInitialize > initializeHandlers , IEnumerable < OnLanguageClientInitializedDelegate > initializedDelegates ,
143- IEnumerable < IOnLanguageClientInitialized > initializedHandlers
145+ IEnumerable < IOnLanguageClientInitialized > initializedHandlers ,
146+ ISerializer serializer
144147 ) : base ( handlerCollection , responseRouter )
145148 {
146149 _connection = connection ;
@@ -167,6 +170,7 @@ IEnumerable<IOnLanguageClientInitialized> initializedHandlers
167170 _initializeHandlers = initializeHandlers ;
168171 _initializedDelegates = initializedDelegates ;
169172 _initializedHandlers = initializedHandlers ;
173+ _serializer = serializer ;
170174 _concurrency = options . Value . Concurrency ;
171175
172176 // We need to at least create Window here in case any handler does loggin in their constructor
@@ -205,15 +209,43 @@ public async Task Initialize(CancellationToken token)
205209 {
206210 var @params = new InitializeParams {
207211 Trace = _trace ,
208- Capabilities = _clientCapabilities ,
209212 ClientInfo = _clientInfo ,
213+ Capabilities = _clientCapabilities ,
210214 RootUri = _rootUri ,
211215 RootPath = _rootUri ? . GetFileSystemPath ( ) ,
212216 WorkspaceFolders = new Container < WorkspaceFolder > ( WorkspaceFoldersManager . CurrentWorkspaceFolders ) ,
213217 InitializationOptions = _initializationOptions
214218 } ;
215219
216- RegisterCapabilities ( @params . Capabilities ) ;
220+ var capabilitiesObject = new JObject ( ) ;
221+ foreach ( var capability in _capabilities )
222+ {
223+ var keys = capability . GetType ( ) . GetCustomAttribute < CapabilityKeyAttribute > ( ) ? . Keys . Select ( key => char . ToLower ( key [ 0 ] ) + key . Substring ( 1 ) ) . ToArray ( ) ;
224+ if ( keys != null )
225+ {
226+ var value = capabilitiesObject ;
227+ foreach ( var key in keys . Take ( keys . Length - 1 ) )
228+ {
229+ if ( value . TryGetValue ( key , out var t ) && t is JObject to )
230+ {
231+ value = to ;
232+ }
233+ else
234+ {
235+ value [ key ] = value = new JObject ( ) ;
236+ }
237+ }
238+ var lastKey = keys [ keys . Length - 1 ] ;
239+ value [ lastKey ] = JToken . FromObject ( capability , _serializer . JsonSerializer ) ;
240+ }
241+ }
242+
243+ using ( var reader = capabilitiesObject . CreateReader ( ) )
244+ {
245+ _serializer . JsonSerializer . Populate ( reader , _clientCapabilities ) ;
246+ }
247+
248+ RegisterCapabilities ( _clientCapabilities ) ;
217249
218250 WorkDoneManager . Initialize ( @params . Capabilities . Window ) ;
219251
@@ -229,7 +261,7 @@ await LanguageProtocolEventingHelper.Run(
229261 ) ;
230262
231263 _connection . Open ( ) ;
232- var serverParams = await this . RequestLanguageProtocolInitialize ( ClientSettings , token ) ;
264+ var serverParams = await SendRequest ( ClientSettings , token ) ;
233265 _receiver . Initialized ( ) ;
234266
235267 ServerSettings = serverParams ;
@@ -334,17 +366,17 @@ public async Task Shutdown()
334366 _connection . Dispose ( ) ;
335367 }
336368
337- private T UseOrTryAndFindCapability < T > ( Supports < T > supports )
369+ private Supports < T > UseOrTryAndFindCapability < T > ( Supports < T > supports ) where T : class
338370 {
339371 var value = supports . IsSupported
340372 ? supports . Value
341- : _capabilities . OfType < T > ( ) . FirstOrDefault ( ) ?? Activator . CreateInstance < T > ( ) ;
373+ : _capabilities . OfType < T > ( ) . FirstOrDefault ( ) ;
342374 if ( value is IDynamicCapability dynamicCapability )
343375 {
344376 dynamicCapability . DynamicRegistration = _collection . ContainsHandler ( typeof ( IRegisterCapabilityHandler ) ) ;
345377 }
346378
347- return value ;
379+ return Supports . OfValue ( value ) ;
348380 }
349381
350382 public IObservable < InitializeResult > Start => _initializeComplete . AsObservable ( ) ;
0 commit comments