11import ast
2- import threading
32from concurrent .futures import CancelledError
43from typing import TYPE_CHECKING , Any , List , Optional
54
2423 GlobalVariableDefinition ,
2524 LibraryArgumentDefinition ,
2625)
26+ from robotcode .robot .diagnostics .library_doc import LibraryDoc
2727from robotcode .robot .diagnostics .namespace import Namespace
2828from robotcode .robot .utils .ast import (
2929 iter_nodes ,
3232)
3333from robotcode .robot .utils .stubs import HasError , HasErrors , HeaderAndBodyBlock
3434
35- from ...common .parts .diagnostics import DiagnosticsResult
35+ from ...common .parts .diagnostics import DiagnosticsCollectType , DiagnosticsResult
3636
3737if TYPE_CHECKING :
3838 from ..protocol import RobotLanguageServerProtocol
@@ -58,57 +58,81 @@ def __init__(self, parent: "RobotLanguageServerProtocol") -> None:
5858 self .parent .diagnostics .collect .add (self .collect_unused_keyword_references )
5959 self .parent .diagnostics .collect .add (self .collect_unused_variable_references )
6060
61- self ._collect_unused_references_event = threading .Event ()
62-
63- self .parent .diagnostics .on_workspace_diagnostics_analyze .add (self ._on_workspace_diagnostics_analyze )
64- self .parent .diagnostics .on_workspace_diagnostics_collect .add (self ._on_workspace_diagnostics_collect )
61+ self .parent .diagnostics .on_get_related_documents .add (self ._on_get_related_documents )
6562
6663 def _on_initialized (self , sender : Any ) -> None :
6764 self .parent .diagnostics .analyze .add (self .analyze )
68-
69- self .parent .documents_cache .namespace_invalidated .add (self .namespace_invalidated )
70-
71- def _on_workspace_diagnostics_analyze (self , sender : Any ) -> None :
72- self ._collect_unused_references_event .clear ()
73-
74- def _on_workspace_diagnostics_collect (self , sender : Any ) -> None :
75- self ._collect_unused_references_event .set ()
65+ self .parent .documents_cache .namespace_invalidated .add (self ._on_namespace_invalidated )
66+ self .parent .documents_cache .namespace_initialized (self ._on_namespace_initialized )
67+ self .parent .documents_cache .libraries_changed .add (self ._on_libraries_changed )
68+ self .parent .documents_cache .variables_changed .add (self ._on_variables_changed )
69+
70+ def _on_libraries_changed (self , sender : Any , libraries : List [LibraryDoc ]) -> None :
71+ for doc in self .parent .documents .documents :
72+ namespace = self .parent .documents_cache .get_only_initialized_namespace (doc )
73+ if namespace is not None :
74+ lib_docs = (e .library_doc for e in namespace .get_libraries ().values ())
75+ if any (lib_doc in lib_docs for lib_doc in libraries ):
76+ self .parent .diagnostics .force_refresh_document (doc )
77+
78+ def _on_variables_changed (self , sender : Any , variables : List [LibraryDoc ]) -> None :
79+ for doc in self .parent .documents .documents :
80+ namespace = self .parent .documents_cache .get_only_initialized_namespace (doc )
81+ if namespace is not None :
82+ lib_docs = (e .library_doc for e in namespace .get_imported_variables ().values ())
83+ if any (lib_doc in lib_docs for lib_doc in variables ):
84+ self .parent .diagnostics .force_refresh_document (doc )
7685
7786 @language_id ("robotframework" )
7887 def analyze (self , sender : Any , document : TextDocument ) -> None :
7988 self .parent .documents_cache .get_namespace (document ).analyze ()
8089
8190 @language_id ("robotframework" )
82- def namespace_invalidated (self , sender : Any , namespace : Namespace ) -> None :
83- self ._collect_unused_references_event .clear ()
91+ def _on_namespace_initialized (self , sender : Any , namespace : Namespace ) -> None :
92+ if namespace .document is not None :
93+ self .parent .diagnostics .force_refresh_document (namespace .document )
94+
95+ @language_id ("robotframework" )
96+ def _on_namespace_invalidated (self , sender : Any , namespace : Namespace ) -> None :
97+ if namespace .document is not None :
98+ namespace .document .remove_cache_entry (self ._collect_model_errors )
99+ namespace .document .remove_cache_entry (self ._collect_token_errors )
100+
101+ @language_id ("robotframework" )
102+ def _on_get_related_documents (self , sender : Any , document : TextDocument ) -> Optional [List [TextDocument ]]:
103+ namespace = self .parent .documents_cache .get_only_initialized_namespace (document )
104+ if namespace is None :
105+ return None
84106
85- self . _namespace_invalidated ( namespace )
107+ result = []
86108
87- self .parent .diagnostics .break_workspace_diagnostics_loop ()
109+ resources = namespace .get_resources ().values ()
110+ for r in resources :
111+ if r .library_doc .source :
112+ doc = self .parent .documents .get (Uri .from_path (r .library_doc .source ).normalized ())
113+ if doc is not None :
114+ result .append (doc )
88115
89- def _namespace_invalidated (self , namespace : Namespace ) -> None :
90- if namespace .document is not None :
91- refresh = namespace .document .opened_in_editor
116+ lib_doc = namespace .get_library_doc ()
117+ for doc in self .parent .documents .documents :
118+ if doc .language_id != "robotframework" :
119+ continue
92120
93- self .parent .diagnostics .force_refresh_document (namespace .document , False )
121+ doc_namespace = self .parent .documents_cache .get_only_initialized_namespace (doc )
122+ if doc_namespace is None :
123+ continue
94124
95- if namespace .is_initialized ():
96- resources = namespace .get_resources ().values ()
97- for r in resources :
98- if r .library_doc .source :
99- doc = self .parent .documents .get (Uri .from_path (r .library_doc .source ).normalized ())
100- if doc is not None :
101- refresh |= doc .opened_in_editor
102- self .parent .diagnostics .force_refresh_document (doc , False )
125+ if doc_namespace .is_analyzed ():
126+ for ref in doc_namespace .get_namespace_references ():
127+ if ref .library_doc == lib_doc :
128+ result .append (doc )
103129
104- if refresh :
105- self .parent .diagnostics .refresh ()
130+ return result
106131
107132 @language_id ("robotframework" )
108- def collect_namespace_diagnostics (self , sender : Any , document : TextDocument ) -> DiagnosticsResult :
109- return document .get_cache (self ._collect_namespace_diagnostics )
110-
111- def _collect_namespace_diagnostics (self , document : TextDocument ) -> DiagnosticsResult :
133+ def collect_namespace_diagnostics (
134+ self , sender : Any , document : TextDocument , diagnostics_type : DiagnosticsCollectType
135+ ) -> DiagnosticsResult :
112136 try :
113137 namespace = self .parent .documents_cache .get_namespace (document )
114138
@@ -172,7 +196,9 @@ def _create_error_from_token(self, token: Token, source: Optional[str] = None) -
172196
173197 @language_id ("robotframework" )
174198 @_logger .call
175- def collect_token_errors (self , sender : Any , document : TextDocument ) -> DiagnosticsResult :
199+ def collect_token_errors (
200+ self , sender : Any , document : TextDocument , diagnostics_type : DiagnosticsCollectType
201+ ) -> DiagnosticsResult :
176202 return document .get_cache (self ._collect_token_errors )
177203
178204 def _collect_token_errors (self , document : TextDocument ) -> DiagnosticsResult :
@@ -238,7 +264,9 @@ def _collect_token_errors(self, document: TextDocument) -> DiagnosticsResult:
238264
239265 @language_id ("robotframework" )
240266 @_logger .call
241- def collect_model_errors (self , sender : Any , document : TextDocument ) -> DiagnosticsResult :
267+ def collect_model_errors (
268+ self , sender : Any , document : TextDocument , diagnostics_type : DiagnosticsCollectType
269+ ) -> DiagnosticsResult :
242270 return document .get_cache (self ._collect_model_errors )
243271
244272 def _collect_model_errors (self , document : TextDocument ) -> DiagnosticsResult :
@@ -284,13 +312,15 @@ def _collect_model_errors(self, document: TextDocument) -> DiagnosticsResult:
284312
285313 @language_id ("robotframework" )
286314 @_logger .call
287- def collect_unused_keyword_references (self , sender : Any , document : TextDocument ) -> DiagnosticsResult :
315+ def collect_unused_keyword_references (
316+ self , sender : Any , document : TextDocument , diagnostics_type : DiagnosticsCollectType
317+ ) -> DiagnosticsResult :
288318 config = self .parent .workspace .get_configuration (AnalysisConfig , document .uri )
289319
290320 if not config .find_unused_references :
291321 return DiagnosticsResult (self .collect_unused_keyword_references , [])
292322
293- if not self . _collect_unused_references_event . is_set () :
323+ if diagnostics_type != DiagnosticsCollectType . SLOW :
294324 return DiagnosticsResult (self .collect_unused_keyword_references , None , True )
295325
296326 return self ._collect_unused_keyword_references (document )
@@ -341,13 +371,15 @@ def _collect_unused_keyword_references(self, document: TextDocument) -> Diagnost
341371
342372 @language_id ("robotframework" )
343373 @_logger .call
344- def collect_unused_variable_references (self , sender : Any , document : TextDocument ) -> DiagnosticsResult :
374+ def collect_unused_variable_references (
375+ self , sender : Any , document : TextDocument , diagnostics_type : DiagnosticsCollectType
376+ ) -> DiagnosticsResult :
345377 config = self .parent .workspace .get_configuration (AnalysisConfig , document .uri )
346378
347379 if not config .find_unused_references :
348380 return DiagnosticsResult (self .collect_unused_variable_references , [])
349381
350- if not self . _collect_unused_references_event . is_set () :
382+ if diagnostics_type != DiagnosticsCollectType . SLOW :
351383 return DiagnosticsResult (self .collect_unused_variable_references , None , True )
352384
353385 return self ._collect_unused_variable_references (document )
0 commit comments