1
- from __future__ import annotations
2
-
3
- import asyncio
4
1
import threading
5
2
import uuid
6
3
import weakref
7
4
from concurrent .futures import Future
8
- from dataclasses import dataclass
9
5
from typing import (
10
6
TYPE_CHECKING ,
11
7
Any ,
12
8
Callable ,
9
+ ClassVar ,
13
10
Coroutine ,
14
11
Dict ,
15
12
Final ,
16
13
List ,
17
14
Mapping ,
18
15
NamedTuple ,
19
16
Optional ,
20
- Protocol ,
21
17
Tuple ,
22
18
Type ,
23
19
TypeVar ,
24
20
Union ,
25
21
cast ,
26
- runtime_checkable ,
27
22
)
28
23
29
24
from robotcode .core .concurrent import threaded
@@ -125,6 +120,9 @@ def __init__(self, name: str, uri: Uri, document_uri: DocumentUri) -> None:
125
120
self .document_uri = document_uri
126
121
127
122
123
+ _F = TypeVar ("_F" , bound = Callable [..., Any ])
124
+
125
+
128
126
def config_section (name : str ) -> Callable [[_F ], _F ]:
129
127
def decorator (func : _F ) -> _F :
130
128
setattr (func , "__config_section__" , name )
@@ -133,26 +131,20 @@ def decorator(func: _F) -> _F:
133
131
return decorator
134
132
135
133
136
- @runtime_checkable
137
- class HasConfigSection (Protocol ):
138
- __config_section__ : str
139
-
140
-
141
- @dataclass
134
+ # @dataclass
142
135
class ConfigBase (CamelSnakeMixin ):
143
- pass
136
+ __config_section__ : ClassVar [ str ]
144
137
145
138
146
139
_TConfig = TypeVar ("_TConfig" , bound = ConfigBase )
147
- _F = TypeVar ("_F" , bound = Callable [..., Any ])
148
140
149
141
150
142
class Workspace (LanguageServerProtocolPart ):
151
143
_logger : Final = LoggingDescriptor ()
152
144
153
145
def __init__ (
154
146
self ,
155
- parent : LanguageServerProtocol ,
147
+ parent : " LanguageServerProtocol" ,
156
148
root_uri : Optional [str ],
157
149
root_path : Optional [str ],
158
150
workspace_folders : Optional [List [TypesWorkspaceFolder ]] = None ,
@@ -174,6 +166,7 @@ def __init__(
174
166
175
167
self .parent .on_shutdown .add (self .server_shutdown )
176
168
self .parent .on_initialize .add (self .server_initialize )
169
+ self ._settings_cache : Dict [Tuple [Optional [WorkspaceFolder ], str ], ConfigBase ] = {}
177
170
178
171
def server_initialize (self , sender : Any , initialization_options : Optional [Any ] = None ) -> None :
179
172
if (
@@ -260,6 +253,7 @@ def did_change_configuration(sender, settings: Dict[str, Any]) -> None: # NOSON
260
253
@threaded
261
254
def _workspace_did_change_configuration (self , settings : Dict [str , Any ], * args : Any , ** kwargs : Any ) -> None :
262
255
self .settings = settings
256
+ self ._settings_cache .clear ()
263
257
self .did_change_configuration (self , settings )
264
258
265
259
@event
@@ -333,14 +327,6 @@ def _workspace_will_delete_files(self, files: List[FileDelete], *args: Any, **kw
333
327
def _workspace_did_delete_files (self , files : List [FileDelete ], * args : Any , ** kwargs : Any ) -> None :
334
328
self .did_delete_files (self , [f .uri for f in files ])
335
329
336
- def get_configuration_async (
337
- self ,
338
- section : Type [_TConfig ],
339
- scope_uri : Union [str , Uri , None ] = None ,
340
- request : bool = True ,
341
- ) -> asyncio .Future [_TConfig ]:
342
- return asyncio .wrap_future (self .get_configuration_future (section , scope_uri , request ))
343
-
344
330
def get_configuration (
345
331
self ,
346
332
section : Type [_TConfig ],
@@ -357,6 +343,12 @@ def get_configuration_future(
357
343
) -> Future [_TConfig ]:
358
344
result_future : Future [_TConfig ] = Future ()
359
345
346
+ scope = self .get_workspace_folder (scope_uri ) if scope_uri is not None else None
347
+
348
+ if (scope , section .__config_section__ ) in self ._settings_cache :
349
+ result_future .set_result (cast (_TConfig , self ._settings_cache [(scope , section .__config_section__ )]))
350
+ return result_future
351
+
360
352
def _get_configuration_done (f : Future [Optional [Any ]]) -> None :
361
353
try :
362
354
if result_future .cancelled ():
@@ -371,12 +363,14 @@ def _get_configuration_done(f: Future[Optional[Any]]) -> None:
371
363
return
372
364
373
365
result = f .result ()
374
- result_future .set_result (from_dict (result [0 ] if result else {}, section ))
366
+ r = from_dict (result [0 ] if result else {}, section )
367
+ self ._settings_cache [(scope , section .__config_section__ )] = r
368
+ result_future .set_result (r )
375
369
except Exception as e :
376
370
result_future .set_exception (e )
377
371
378
372
self .get_configuration_raw (
379
- section = cast ( HasConfigSection , section ) .__config_section__ ,
373
+ section = section .__config_section__ ,
380
374
scope_uri = scope_uri ,
381
375
request = request ,
382
376
).add_done_callback (_get_configuration_done )
@@ -453,6 +447,10 @@ def _workspace_did_change_workspace_folders(
453
447
for r in to_remove :
454
448
self ._workspace_folders .remove (r )
455
449
450
+ settings_to_remove = [k for k in self ._settings_cache .keys () if k [0 ] == r ]
451
+ for k in settings_to_remove :
452
+ self ._settings_cache .pop (k , None )
453
+
456
454
for a in event .added :
457
455
self ._workspace_folders .append (WorkspaceFolder (a .name , Uri (a .uri ), a .uri ))
458
456
0 commit comments