3737from ...common .text_document import TextDocument
3838from ..utils .ast import (
3939 Token ,
40- is_non_variable_token ,
40+ is_not_variable_token ,
4141 range_from_node ,
4242 range_from_token ,
4343 range_from_token_or_node ,
@@ -599,14 +599,14 @@ async def _analyse_run_keyword(
599599 if keyword_doc is None or not keyword_doc .is_any_run_keyword ():
600600 return argument_tokens
601601
602- if keyword_doc .is_run_keyword () and len (argument_tokens ) > 0 and is_non_variable_token (argument_tokens [0 ]):
602+ if keyword_doc .is_run_keyword () and len (argument_tokens ) > 0 and is_not_variable_token (argument_tokens [0 ]):
603603 await self ._analyze_keyword_call (argument_tokens [0 ].value , node , argument_tokens [0 ], argument_tokens [1 :])
604604
605605 return argument_tokens [1 :]
606606 elif (
607607 keyword_doc .is_run_keyword_with_condition ()
608608 and len (argument_tokens ) > 1
609- and is_non_variable_token (argument_tokens [1 ])
609+ and is_not_variable_token (argument_tokens [1 ])
610610 ):
611611 await self ._analyze_keyword_call (argument_tokens [1 ].value , node , argument_tokens [1 ], argument_tokens [2 :])
612612 return argument_tokens [2 :]
@@ -627,7 +627,7 @@ async def _analyse_run_keyword(
627627 )
628628 continue
629629
630- if not is_non_variable_token (t ):
630+ if not is_not_variable_token (t ):
631631 continue
632632
633633 and_token = next ((e for e in argument_tokens if e .value == "AND" ), None )
@@ -640,7 +640,7 @@ async def _analyse_run_keyword(
640640
641641 return []
642642
643- elif keyword_doc .is_run_keyword_if () and len (argument_tokens ) > 1 and is_non_variable_token (argument_tokens [1 ]):
643+ elif keyword_doc .is_run_keyword_if () and len (argument_tokens ) > 1 and is_not_variable_token (argument_tokens [1 ]):
644644
645645 def skip_args () -> None :
646646 nonlocal argument_tokens
@@ -714,7 +714,7 @@ async def visit_Fixture(self, node: ast.AST) -> None: # noqa: N802
714714
715715 # TODO: calculate possible variables in NAME
716716
717- if keyword_token is not None and is_non_variable_token (keyword_token ):
717+ if keyword_token is not None and is_not_variable_token (keyword_token ):
718718 await self ._analyze_keyword_call (
719719 value .name , value , keyword_token , [cast (Token , e ) for e in value .get_tokens (RobotToken .ARGUMENT )]
720720 )
@@ -730,7 +730,7 @@ async def visit_TestTemplate(self, node: ast.AST) -> None: # noqa: N802
730730
731731 # TODO: calculate possible variables in NAME
732732
733- if keyword_token is not None and is_non_variable_token (keyword_token ):
733+ if keyword_token is not None and is_not_variable_token (keyword_token ):
734734 await self ._analyze_keyword_call (value .value , value , keyword_token , [])
735735
736736 await self .generic_visit (node )
@@ -744,7 +744,7 @@ async def visit_Template(self, node: ast.AST) -> None: # noqa: N802
744744
745745 # TODO: calculate possible variables in NAME
746746
747- if keyword_token is not None and is_non_variable_token (keyword_token ):
747+ if keyword_token is not None and is_not_variable_token (keyword_token ):
748748 await self ._analyze_keyword_call (value .value , value , keyword_token , [])
749749
750750 await self .generic_visit (node )
@@ -908,6 +908,7 @@ def __init__(
908908 self ._analyzed = False
909909 self ._analyze_lock = asyncio .Lock ()
910910 self ._library_doc : Optional [LibraryDoc ] = None
911+ self ._library_doc_lock = asyncio .Lock ()
911912 self ._imports : Optional [List [Import ]] = None
912913 self ._own_variables : Optional [List [VariableDefinition ]] = None
913914 self ._diagnostics : List [Diagnostic ] = []
@@ -921,15 +922,14 @@ def __init__(
921922 def document (self ) -> Optional [TextDocument ]:
922923 return self ._document () if self ._document is not None else None
923924
924- async def libraries_changed (self , sender : Any , params : List [LibraryDoc ]) -> None :
925-
926- for p in params :
925+ async def libraries_changed (self , sender : Any , libraries : List [LibraryDoc ]) -> None :
926+ for p in libraries :
927927 if any (e for e in self ._libraries .values () if e .library_doc == p ):
928928 self .invalidated_callback (self )
929929 break
930930
931- async def resources_changed (self , sender : Any , params : List [LibraryDoc ]) -> None :
932- for p in params :
931+ async def resources_changed (self , sender : Any , resources : List [LibraryDoc ]) -> None :
932+ for p in resources :
933933 if any (e for e in self ._resources .values () if e .library_doc .source == p .source ):
934934 self .invalidated_callback (self )
935935 break
@@ -972,34 +972,43 @@ async def get_library_doc(self) -> LibraryDoc:
972972 from ..parts .documents_cache import DocumentType
973973
974974 if self ._library_doc is None :
975-
976- model_type = ""
977-
978- if hasattr (self .model , "model_type" ):
979- t = getattr (self .model , "model_type" )
980-
981- if t == DocumentType .RESOURCE :
982- model_type = "RESOURCE"
983- elif t == DocumentType .GENERAL :
984- model_type = "TESTCASE"
985- elif t == DocumentType .INIT :
986- model_type = "INIT"
987-
988- self ._library_doc = await self .imports_manager .get_libdoc_from_model (
989- self .model , self .source , model_type = model_type
990- )
975+ async with self ._library_doc_lock :
976+ if self ._library_doc is None :
977+ model_type = ""
978+
979+ if hasattr (self .model , "model_type" ):
980+ t = getattr (self .model , "model_type" )
981+
982+ if t == DocumentType .RESOURCE :
983+ model_type = "RESOURCE"
984+ elif t == DocumentType .GENERAL :
985+ model_type = "TESTCASE"
986+ elif t == DocumentType .INIT :
987+ model_type = "INIT"
988+
989+ self ._library_doc = await self .imports_manager .get_libdoc_from_model (
990+ self .model , self .source , model_type = model_type
991+ )
991992
992993 return self ._library_doc
993994
995+ class DataEntry (NamedTuple ):
996+ libraries : OrderedDict [str , LibraryEntry ] = OrderedDict ()
997+ resources : OrderedDict [str , ResourceEntry ] = OrderedDict ()
998+ variables : OrderedDict [str , VariablesEntry ] = OrderedDict ()
999+ diagnostics : List [Diagnostic ] = []
1000+
9941001 @_logger .call
9951002 async def ensure_initialized (self ) -> bool :
9961003 if not self ._initialized :
9971004 async with self ._initialize_lock :
9981005 if not self ._initialized :
9991006 imports = await self .get_imports ()
10001007
1008+ data_entry : Optional [Namespace .DataEntry ] = None
10011009 if self .document is not None :
1002-
1010+ # check or save several data in documents data cache,
1011+ # if imports are different, then the data is invalid
10031012 old_imports : List [Import ] = self .document .get_data (Namespace )
10041013 if old_imports is None :
10051014 self .document .set_data (Namespace , imports )
@@ -1012,9 +1021,28 @@ async def ensure_initialized(self) -> bool:
10121021 if e not in new_imports :
10131022 new_imports .append (e )
10141023 self .document .set_data (Namespace , new_imports )
1015-
1016- await self ._import_default_libraries ()
1017- await self ._import_imports (imports , str (Path (self .source ).parent ), top_level = True )
1024+ else :
1025+ data_entry = self .document .get_data (Namespace .DataEntry )
1026+
1027+ if data_entry is not None :
1028+ self ._libraries = data_entry .libraries .copy ()
1029+ self ._resources = data_entry .resources .copy ()
1030+ self ._variables = data_entry .variables .copy ()
1031+ self ._diagnostics = data_entry .diagnostics .copy ()
1032+ else :
1033+ await self ._import_default_libraries ()
1034+ await self ._import_imports (imports , str (Path (self .source ).parent ), top_level = True )
1035+
1036+ if self .document is not None :
1037+ self .document .set_data (
1038+ Namespace .DataEntry ,
1039+ Namespace .DataEntry (
1040+ self ._libraries .copy (),
1041+ self ._resources .copy (),
1042+ self ._variables .copy (),
1043+ self ._diagnostics .copy (),
1044+ ),
1045+ )
10181046
10191047 self ._initialized = True
10201048
0 commit comments