@@ -90,6 +90,8 @@ def __init__(self, protocol: LanguageServerProtocol) -> None:
90
90
] = {}
91
91
92
92
self ._current_workspace_task : Optional [asyncio .Task [WorkspaceDiagnosticReport ]] = None
93
+ self .in_get_document_diagnostics = Event (True )
94
+ self .in_get_workspace_diagnostics = Event (True )
93
95
94
96
def extend_capabilities (self , capabilities : ServerCapabilities ) -> None :
95
97
if (
@@ -108,14 +110,26 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
108
110
async def collect (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
109
111
...
110
112
113
+ @async_tasking_event_iterator
114
+ async def collect_stage2 (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
115
+ ...
116
+
111
117
@async_tasking_event
112
- async def collect_workspace_documents (sender ) -> List [WorkspaceDocumentsResult ]: # NOSONAR
118
+ async def load_workspace_documents (sender ) -> List [WorkspaceDocumentsResult ]: # NOSONAR
113
119
...
114
120
115
121
@async_tasking_event
116
122
async def on_workspace_loaded (sender ) -> None : # NOSONAR
117
123
...
118
124
125
+ @async_tasking_event
126
+ async def on_workspace_diagnostics_ended (sender ) -> None : # NOSONAR
127
+ ...
128
+
129
+ @async_tasking_event
130
+ async def on_document_diagnostics_ended (sender ) -> None : # NOSONAR
131
+ ...
132
+
119
133
@async_event
120
134
async def on_get_analysis_progress_mode (sender , uri : Uri ) -> Optional [AnalysisProgressMode ]: # NOSONAR
121
135
...
@@ -125,17 +139,18 @@ async def on_get_diagnostics_mode(sender, uri: Uri) -> Optional[DiagnosticsMode]
125
139
...
126
140
127
141
async def ensure_workspace_loaded (self ) -> None :
128
- async with self ._workspace_load_lock :
129
- if not self ._workspace_loaded :
130
- if self .workspace_loaded_event .is_set ():
131
- return
132
-
133
- try :
134
- await self .collect_workspace_documents (self )
135
- finally :
136
- self ._workspace_loaded = True
137
- self .workspace_loaded_event .set ()
138
- await self .on_workspace_loaded (self )
142
+ if not self ._workspace_loaded :
143
+ async with self ._workspace_load_lock :
144
+ if not self ._workspace_loaded :
145
+ if self .workspace_loaded_event .is_set ():
146
+ return
147
+
148
+ try :
149
+ await self .load_workspace_documents (self )
150
+ finally :
151
+ self ._workspace_loaded = True
152
+ self .workspace_loaded_event .set ()
153
+ await self .on_workspace_loaded (self )
139
154
140
155
async def get_document_diagnostics (self , document : TextDocument ) -> RelatedFullDocumentDiagnosticReport :
141
156
return await document .get_cache (self .__get_document_diagnostics )
@@ -171,11 +186,13 @@ async def _text_document_diagnostic(
171
186
* args : Any ,
172
187
** kwargs : Any ,
173
188
) -> DocumentDiagnosticReport :
174
- self ._logger .info (lambda : f"textDocument/diagnostic for { text_document } " )
189
+ self ._logger .debug (lambda : f"textDocument/diagnostic for { text_document } " )
175
190
176
- await self .ensure_workspace_loaded ()
191
+ self .in_get_document_diagnostics . clear ()
177
192
178
193
try :
194
+ await self .ensure_workspace_loaded ()
195
+
179
196
document = await self .parent .documents .get (text_document .uri )
180
197
if document is None :
181
198
raise JsonRPCErrorException (ErrorCodes .INVALID_PARAMS , f"Document { text_document !r} not found" )
@@ -187,7 +204,7 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
187
204
return None
188
205
189
206
if document in self ._current_document_tasks and not self ._current_document_tasks [document ].done ():
190
- self ._logger .info (lambda : f"textDocument/diagnostic cancel old task { text_document } " )
207
+ self ._logger .debug (lambda : f"textDocument/diagnostic cancel old task { text_document } " )
191
208
self ._current_document_tasks [document ].cancel ()
192
209
193
210
task = create_sub_task (_get_diagnostics ())
@@ -199,7 +216,7 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
199
216
raise RuntimeError ("Unexpected result." )
200
217
201
218
except asyncio .CancelledError as e :
202
- self ._logger .info (lambda : f"textDocument/diagnostic canceled { text_document } " )
219
+ self ._logger .debug (lambda : f"textDocument/diagnostic canceled { text_document } " )
203
220
204
221
raise JsonRPCErrorException (
205
222
ErrorCodes .SERVER_CANCELLED , "Cancelled" , data = DiagnosticServerCancellationData (True )
@@ -213,7 +230,10 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
213
230
214
231
return result
215
232
finally :
216
- self ._logger .info (lambda : f"textDocument/diagnostic ready { text_document } " )
233
+ self .in_get_document_diagnostics .set ()
234
+ await self .on_document_diagnostics_ended (self )
235
+
236
+ self ._logger .debug (lambda : f"textDocument/diagnostic ready { text_document } " )
217
237
218
238
@rpc_method (name = "workspace/diagnostic" , param_type = WorkspaceDiagnosticParams )
219
239
@threaded ()
@@ -226,9 +246,7 @@ async def _workspace_diagnostic(
226
246
* args : Any ,
227
247
** kwargs : Any ,
228
248
) -> WorkspaceDiagnosticReport :
229
- self ._logger .critical ("workspace/diagnostic" )
230
-
231
- await self .ensure_workspace_loaded ()
249
+ self ._logger .debug ("workspace/diagnostic" )
232
250
233
251
async def _get_diagnostics () -> WorkspaceDiagnosticReport :
234
252
result : List [WorkspaceDocumentDiagnosticReport ] = []
@@ -303,22 +321,30 @@ async def _task(doc: TextDocument) -> None:
303
321
304
322
return WorkspaceDiagnosticReport (items = [])
305
323
306
- if self ._current_workspace_task is not None :
307
- self ._current_workspace_task .cancel ()
308
-
309
- task = create_sub_task (_get_diagnostics () if partial_result_token is None else _get_partial_diagnostics ())
310
- self ._current_workspace_task = task
324
+ await self .in_get_document_diagnostics .wait ()
325
+ self .in_get_workspace_diagnostics .clear ()
311
326
try :
312
- return await task
313
- except asyncio .CancelledError as e :
314
- self ._logger .critical ("workspace/diagnostic canceled" )
315
- raise JsonRPCErrorException (
316
- ErrorCodes .SERVER_CANCELLED , "Cancelled" , data = DiagnosticServerCancellationData (True )
317
- ) from e
327
+ await self .ensure_workspace_loaded ()
328
+
329
+ if self ._current_workspace_task is not None :
330
+ self ._current_workspace_task .cancel ()
331
+
332
+ task = create_sub_task (_get_diagnostics () if partial_result_token is None else _get_partial_diagnostics ())
333
+ self ._current_workspace_task = task
334
+ try :
335
+ return await task
336
+ except asyncio .CancelledError as e :
337
+ self ._logger .debug ("workspace/diagnostic canceled" )
338
+ raise JsonRPCErrorException (
339
+ ErrorCodes .SERVER_CANCELLED , "ServerCancelled" , data = DiagnosticServerCancellationData (True )
340
+ ) from e
341
+ finally :
342
+ if self ._current_workspace_task == task :
343
+ self ._current_workspace_task = None
344
+ self ._logger .debug ("workspace/diagnostic ready" )
318
345
finally :
319
- if self ._current_workspace_task == task :
320
- self ._current_workspace_task = None
321
- self ._logger .critical ("workspace/diagnostic ready" )
346
+ self .in_get_workspace_diagnostics .set ()
347
+ await self .on_workspace_diagnostics_ended (self )
322
348
323
349
def cancel_workspace_diagnostics (self ) -> None :
324
350
if self ._current_workspace_task is not None and not self ._current_workspace_task .done ():
0 commit comments