@@ -589,8 +589,9 @@ def __init__(
589589 self ._keyword_references : Dict [KeywordDoc , Set [Location ]] = {}
590590 self ._variable_references : Dict [VariableDefinition , Set [Location ]] = {}
591591
592+ self ._imported_keywords : Optional [List [KeywordDoc ]] = None
593+ self ._imported_keywords_lock = Lock ()
592594 self ._keywords : Optional [List [KeywordDoc ]] = None
593-
594595 self ._keywords_lock = Lock ()
595596
596597 # TODO: how to get the search order from model
@@ -673,6 +674,7 @@ async def _invalidate(self) -> None:
673674 self ._imports = None
674675 self ._import_entries = OrderedDict ()
675676 self ._own_variables = None
677+ self ._imported_keywords = None
676678 self ._keywords = None
677679 self ._library_doc = None
678680 self ._analyzed = False
@@ -766,6 +768,7 @@ class DataEntry(NamedTuple):
766768 variables : OrderedDict [str , VariablesEntry ] = OrderedDict ()
767769 diagnostics : List [Diagnostic ] = []
768770 import_entries : OrderedDict [Import , LibraryEntry ] = OrderedDict ()
771+ imported_keywords : Optional [List [KeywordDoc ]] = None
769772
770773 @_logger .call (condition = lambda self : not self ._initialized )
771774 async def ensure_initialized (self ) -> bool :
@@ -812,8 +815,10 @@ async def ensure_initialized(self) -> bool:
812815 self ._variables = data_entry .variables .copy ()
813816 self ._diagnostics = data_entry .diagnostics .copy ()
814817 self ._import_entries = data_entry .import_entries .copy ()
818+ self ._imported_keywords = (
819+ data_entry .imported_keywords .copy () if data_entry .imported_keywords else None
820+ )
815821 else :
816-
817822 variables = await self .get_resolvable_variables ()
818823
819824 await self ._import_default_libraries (variables )
@@ -830,6 +835,7 @@ async def ensure_initialized(self) -> bool:
830835 self ._variables .copy (),
831836 self ._diagnostics .copy (),
832837 self ._import_entries .copy (),
838+ self ._imported_keywords .copy () if self ._imported_keywords else None ,
833839 ),
834840 )
835841
@@ -1475,16 +1481,27 @@ async def get_imported_variables_libdoc(self, name: str, args: Tuple[str, ...] =
14751481 None ,
14761482 )
14771483
1484+ async def get_imported_keywords (self ) -> List [KeywordDoc ]:
1485+ async with self ._imported_keywords_lock :
1486+ if self ._imported_keywords is None :
1487+ self ._imported_keywords = list (
1488+ itertools .chain (
1489+ * (e .library_doc .keywords for e in self ._libraries .values ()),
1490+ * (e .library_doc .keywords for e in self ._resources .values ()),
1491+ )
1492+ )
1493+
1494+ return self ._imported_keywords
1495+
14781496 @_logger .call
14791497 async def iter_all_keywords (self ) -> AsyncGenerator [KeywordDoc , None ]:
14801498 import itertools
14811499
14821500 libdoc = await self .get_library_doc ()
14831501
14841502 for doc in itertools .chain (
1485- * (e .library_doc .keywords .values () for e in self ._libraries .values ()),
1486- * (e .library_doc .keywords .values () for e in self ._resources .values ()),
1487- libdoc .keywords .values () if libdoc is not None else [],
1503+ await self .get_imported_keywords (),
1504+ libdoc .keywords if libdoc is not None else [],
14881505 ):
14891506 yield doc
14901507
@@ -1504,10 +1521,13 @@ async def get_keywords(self) -> List[KeywordDoc]:
15041521
15051522 async for doc in self .iter_all_keywords ():
15061523 i += 1
1507- result [KeywordMatcher ( doc .name ) ] = doc
1524+ result [doc .matcher ] = doc
15081525
15091526 self ._keywords = list (result .values ())
1510- finally :
1527+ except BaseException :
1528+ self ._logger .debug ("Canceled collecting keywords " )
1529+ raise
1530+ else :
15111531 self ._logger .debug (
15121532 lambda : f"end collecting { len (self ._keywords ) if self ._keywords else 0 } "
15131533 f" keywords in { time .monotonic ()- current_time } s analyze { i } keywords"
0 commit comments