14
14
async_tasking_event ,
15
15
async_tasking_event_iterator ,
16
16
create_sub_task ,
17
- threaded ,
18
17
)
19
18
from ....utils .logging import LoggingDescriptor
20
19
from ....utils .uri import Uri
@@ -92,6 +91,7 @@ def __init__(self, protocol: LanguageServerProtocol) -> None:
92
91
self ._current_workspace_task : Optional [asyncio .Task [WorkspaceDiagnosticReport ]] = None
93
92
self .in_get_document_diagnostics = Event (True )
94
93
self .in_get_workspace_diagnostics = Event (True )
94
+ self ._collect_full_diagnostics = False
95
95
96
96
def extend_capabilities (self , capabilities : ServerCapabilities ) -> None :
97
97
if (
@@ -106,12 +106,17 @@ def extend_capabilities(self, capabilities: ServerCapabilities) -> None:
106
106
work_done_progress = True ,
107
107
)
108
108
109
- @async_tasking_event_iterator
110
- async def collect (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
111
- ...
109
+ @property
110
+ def collect_full_diagnostics (self ) -> bool :
111
+ return self ._collect_full_diagnostics
112
+
113
+ async def set_collect_full_diagnostics (self , value : bool ) -> None :
114
+ if self ._collect_full_diagnostics != value :
115
+ self ._collect_full_diagnostics = value
116
+ await self .refresh ()
112
117
113
118
@async_tasking_event_iterator
114
- async def collect_stage2 (sender , document : TextDocument ) -> DiagnosticsResult : # NOSONAR
119
+ async def collect (sender , document : TextDocument , full : bool ) -> DiagnosticsResult : # NOSONAR
115
120
...
116
121
117
122
@async_tasking_event
@@ -153,6 +158,8 @@ async def ensure_workspace_loaded(self) -> None:
153
158
await self .on_workspace_loaded (self )
154
159
155
160
async def get_document_diagnostics (self , document : TextDocument ) -> RelatedFullDocumentDiagnosticReport :
161
+ if self .collect_full_diagnostics :
162
+ return await document .get_cache (self .__get_full_document_diagnostics )
156
163
return await document .get_cache (self .__get_document_diagnostics )
157
164
158
165
async def __get_document_diagnostics (self , document : TextDocument ) -> RelatedFullDocumentDiagnosticReport :
@@ -163,6 +170,29 @@ async def __get_document_diagnostics(self, document: TextDocument) -> RelatedFul
163
170
async for result_any in self .collect (
164
171
self ,
165
172
document ,
173
+ full = False ,
174
+ callback_filter = language_id_filter (document ),
175
+ return_exceptions = True ,
176
+ ):
177
+ result = cast (DiagnosticsResult , result_any )
178
+
179
+ if isinstance (result , BaseException ):
180
+ if not isinstance (result , asyncio .CancelledError ):
181
+ self ._logger .exception (result , exc_info = result )
182
+ else :
183
+ diagnostics .extend (result .diagnostics or [])
184
+
185
+ return RelatedFullDocumentDiagnosticReport (items = diagnostics , result_id = str (uuid .uuid4 ()))
186
+
187
+ async def __get_full_document_diagnostics (self , document : TextDocument ) -> RelatedFullDocumentDiagnosticReport :
188
+ await self .ensure_workspace_loaded ()
189
+
190
+ diagnostics : List [Diagnostic ] = []
191
+
192
+ async for result_any in self .collect (
193
+ self ,
194
+ document ,
195
+ full = True ,
166
196
callback_filter = language_id_filter (document ),
167
197
return_exceptions = True ,
168
198
):
@@ -177,7 +207,6 @@ async def __get_document_diagnostics(self, document: TextDocument) -> RelatedFul
177
207
return RelatedFullDocumentDiagnosticReport (items = diagnostics , result_id = str (uuid .uuid4 ()))
178
208
179
209
@rpc_method (name = "textDocument/diagnostic" , param_type = DocumentDiagnosticParams )
180
- @threaded ()
181
210
async def _text_document_diagnostic (
182
211
self ,
183
212
text_document : TextDocumentIdentifier ,
@@ -236,7 +265,6 @@ async def _get_diagnostics() -> Optional[RelatedFullDocumentDiagnosticReport]:
236
265
self ._logger .debug (lambda : f"textDocument/diagnostic ready { text_document } " )
237
266
238
267
@rpc_method (name = "workspace/diagnostic" , param_type = WorkspaceDiagnosticParams )
239
- @threaded ()
240
268
async def _workspace_diagnostic (
241
269
self ,
242
270
identifier : Optional [str ],
@@ -272,7 +300,9 @@ async def _get_diagnostics() -> WorkspaceDiagnosticReport:
272
300
273
301
async def _get_partial_diagnostics () -> WorkspaceDiagnosticReport :
274
302
async with self .parent .window .progress (
275
- "Analyse Workspace" , progress_token = work_done_token , cancellable = False
303
+ f"Analyse { 'full ' if self .collect_full_diagnostics else '' } Workspace" ,
304
+ progress_token = work_done_token ,
305
+ cancellable = False ,
276
306
) as progress :
277
307
278
308
async def _task (doc : TextDocument ) -> None :
@@ -285,7 +315,7 @@ async def _task(doc: TextDocument) -> None:
285
315
else :
286
316
name = path .relative_to (folder .uri .to_path ())
287
317
288
- progress .report (f"Analyse { name } " )
318
+ progress .report (f"Analyse { 'full ' if self . collect_full_diagnostics else '' } { name } " )
289
319
290
320
doc_result = await self .get_document_diagnostics (doc )
291
321
@@ -332,7 +362,9 @@ async def _task(doc: TextDocument) -> None:
332
362
task = create_sub_task (_get_diagnostics () if partial_result_token is None else _get_partial_diagnostics ())
333
363
self ._current_workspace_task = task
334
364
try :
335
- return await task
365
+ result = await task
366
+ await self .set_collect_full_diagnostics (True )
367
+ return result
336
368
except asyncio .CancelledError as e :
337
369
self ._logger .debug ("workspace/diagnostic canceled" )
338
370
raise JsonRPCErrorException (
@@ -350,6 +382,12 @@ def cancel_workspace_diagnostics(self) -> None:
350
382
if self ._current_workspace_task is not None and not self ._current_workspace_task .done ():
351
383
self ._current_workspace_task .cancel ()
352
384
385
+ def cancel_document_diagnostics (self , document : TextDocument ) -> None :
386
+ task = self ._current_document_tasks .get (document , None )
387
+ if task is not None :
388
+ self ._logger .critical (lambda : f"textDocument/diagnostic canceled { document } " )
389
+ task .cancel ()
390
+
353
391
async def get_analysis_progress_mode (self , uri : Uri ) -> AnalysisProgressMode :
354
392
for e in await self .on_get_analysis_progress_mode (self , uri ):
355
393
if e is not None :
0 commit comments