@@ -90,6 +90,8 @@ def __init__(self, protocol: LanguageServerProtocol) -> None:
9090 ] = {}
9191
9292 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 )
9395
9496 def extend_capabilities (self , capabilities : ServerCapabilities ) -> None :
9597 if (
@@ -108,14 +110,26 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
108110 async def collect (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
109111 ...
110112
113+ @async_tasking_event_iterator
114+ async def collect_stage2 (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
115+ ...
116+
111117 @async_tasking_event
112- async def collect_workspace_documents (sender ) -> List [WorkspaceDocumentsResult ]: # NOSONAR
118+ async def load_workspace_documents (sender ) -> List [WorkspaceDocumentsResult ]: # NOSONAR
113119 ...
114120
115121 @async_tasking_event
116122 async def on_workspace_loaded (sender ) -> None : # NOSONAR
117123 ...
118124
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+
119133 @async_event
120134 async def on_get_analysis_progress_mode (sender , uri : Uri ) -> Optional [AnalysisProgressMode ]: # NOSONAR
121135 ...
@@ -125,17 +139,18 @@ async def on_get_diagnostics_mode(sender, uri: Uri) -> Optional[DiagnosticsMode]
125139 ...
126140
127141 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 )
139154
140155 async def get_document_diagnostics (self , document : TextDocument ) -> RelatedFullDocumentDiagnosticReport :
141156 return await document .get_cache (self .__get_document_diagnostics )
@@ -171,11 +186,13 @@ async def _text_document_diagnostic(
171186 * args : Any ,
172187 ** kwargs : Any ,
173188 ) -> DocumentDiagnosticReport :
174- self ._logger .info (lambda : f"textDocument/diagnostic for { text_document } " )
189+ self ._logger .debug (lambda : f"textDocument/diagnostic for { text_document } " )
175190
176- await self .ensure_workspace_loaded ()
191+ self .in_get_document_diagnostics . clear ()
177192
178193 try :
194+ await self .ensure_workspace_loaded ()
195+
179196 document = await self .parent .documents .get (text_document .uri )
180197 if document is None :
181198 raise JsonRPCErrorException (ErrorCodes .INVALID_PARAMS , f"Document { text_document !r} not found" )
@@ -187,7 +204,7 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
187204 return None
188205
189206 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 } " )
191208 self ._current_document_tasks [document ].cancel ()
192209
193210 task = create_sub_task (_get_diagnostics ())
@@ -199,7 +216,7 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
199216 raise RuntimeError ("Unexpected result." )
200217
201218 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 } " )
203220
204221 raise JsonRPCErrorException (
205222 ErrorCodes .SERVER_CANCELLED , "Cancelled" , data = DiagnosticServerCancellationData (True )
@@ -213,7 +230,10 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
213230
214231 return result
215232 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 } " )
217237
218238 @rpc_method (name = "workspace/diagnostic" , param_type = WorkspaceDiagnosticParams )
219239 @threaded ()
@@ -226,9 +246,7 @@ async def _workspace_diagnostic(
226246 * args : Any ,
227247 ** kwargs : Any ,
228248 ) -> WorkspaceDiagnosticReport :
229- self ._logger .critical ("workspace/diagnostic" )
230-
231- await self .ensure_workspace_loaded ()
249+ self ._logger .debug ("workspace/diagnostic" )
232250
233251 async def _get_diagnostics () -> WorkspaceDiagnosticReport :
234252 result : List [WorkspaceDocumentDiagnosticReport ] = []
@@ -303,22 +321,30 @@ async def _task(doc: TextDocument) -> None:
303321
304322 return WorkspaceDiagnosticReport (items = [])
305323
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 ()
311326 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" )
318345 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 )
322348
323349 def cancel_workspace_diagnostics (self ) -> None :
324350 if self ._current_workspace_task is not None and not self ._current_workspace_task .done ():
0 commit comments