37
37
from ...common .text_document import TextDocument
38
38
from ..utils .ast import (
39
39
Token ,
40
- is_non_variable_token ,
40
+ is_not_variable_token ,
41
41
range_from_node ,
42
42
range_from_token ,
43
43
range_from_token_or_node ,
@@ -599,14 +599,14 @@ async def _analyse_run_keyword(
599
599
if keyword_doc is None or not keyword_doc .is_any_run_keyword ():
600
600
return argument_tokens
601
601
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 ]):
603
603
await self ._analyze_keyword_call (argument_tokens [0 ].value , node , argument_tokens [0 ], argument_tokens [1 :])
604
604
605
605
return argument_tokens [1 :]
606
606
elif (
607
607
keyword_doc .is_run_keyword_with_condition ()
608
608
and len (argument_tokens ) > 1
609
- and is_non_variable_token (argument_tokens [1 ])
609
+ and is_not_variable_token (argument_tokens [1 ])
610
610
):
611
611
await self ._analyze_keyword_call (argument_tokens [1 ].value , node , argument_tokens [1 ], argument_tokens [2 :])
612
612
return argument_tokens [2 :]
@@ -627,7 +627,7 @@ async def _analyse_run_keyword(
627
627
)
628
628
continue
629
629
630
- if not is_non_variable_token (t ):
630
+ if not is_not_variable_token (t ):
631
631
continue
632
632
633
633
and_token = next ((e for e in argument_tokens if e .value == "AND" ), None )
@@ -640,7 +640,7 @@ async def _analyse_run_keyword(
640
640
641
641
return []
642
642
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 ]):
644
644
645
645
def skip_args () -> None :
646
646
nonlocal argument_tokens
@@ -714,7 +714,7 @@ async def visit_Fixture(self, node: ast.AST) -> None: # noqa: N802
714
714
715
715
# TODO: calculate possible variables in NAME
716
716
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 ):
718
718
await self ._analyze_keyword_call (
719
719
value .name , value , keyword_token , [cast (Token , e ) for e in value .get_tokens (RobotToken .ARGUMENT )]
720
720
)
@@ -730,7 +730,7 @@ async def visit_TestTemplate(self, node: ast.AST) -> None: # noqa: N802
730
730
731
731
# TODO: calculate possible variables in NAME
732
732
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 ):
734
734
await self ._analyze_keyword_call (value .value , value , keyword_token , [])
735
735
736
736
await self .generic_visit (node )
@@ -744,7 +744,7 @@ async def visit_Template(self, node: ast.AST) -> None: # noqa: N802
744
744
745
745
# TODO: calculate possible variables in NAME
746
746
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 ):
748
748
await self ._analyze_keyword_call (value .value , value , keyword_token , [])
749
749
750
750
await self .generic_visit (node )
@@ -908,6 +908,7 @@ def __init__(
908
908
self ._analyzed = False
909
909
self ._analyze_lock = asyncio .Lock ()
910
910
self ._library_doc : Optional [LibraryDoc ] = None
911
+ self ._library_doc_lock = asyncio .Lock ()
911
912
self ._imports : Optional [List [Import ]] = None
912
913
self ._own_variables : Optional [List [VariableDefinition ]] = None
913
914
self ._diagnostics : List [Diagnostic ] = []
@@ -921,15 +922,14 @@ def __init__(
921
922
def document (self ) -> Optional [TextDocument ]:
922
923
return self ._document () if self ._document is not None else None
923
924
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 :
927
927
if any (e for e in self ._libraries .values () if e .library_doc == p ):
928
928
self .invalidated_callback (self )
929
929
break
930
930
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 :
933
933
if any (e for e in self ._resources .values () if e .library_doc .source == p .source ):
934
934
self .invalidated_callback (self )
935
935
break
@@ -972,34 +972,43 @@ async def get_library_doc(self) -> LibraryDoc:
972
972
from ..parts .documents_cache import DocumentType
973
973
974
974
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
+ )
991
992
992
993
return self ._library_doc
993
994
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
+
994
1001
@_logger .call
995
1002
async def ensure_initialized (self ) -> bool :
996
1003
if not self ._initialized :
997
1004
async with self ._initialize_lock :
998
1005
if not self ._initialized :
999
1006
imports = await self .get_imports ()
1000
1007
1008
+ data_entry : Optional [Namespace .DataEntry ] = None
1001
1009
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
1003
1012
old_imports : List [Import ] = self .document .get_data (Namespace )
1004
1013
if old_imports is None :
1005
1014
self .document .set_data (Namespace , imports )
@@ -1012,9 +1021,28 @@ async def ensure_initialized(self) -> bool:
1012
1021
if e not in new_imports :
1013
1022
new_imports .append (e )
1014
1023
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
+ )
1018
1046
1019
1047
self ._initialized = True
1020
1048
0 commit comments