|
10 | 10 | Any,
|
11 | 11 | AsyncIterator,
|
12 | 12 | Callable,
|
| 13 | + Dict, |
13 | 14 | Iterable,
|
14 | 15 | List,
|
15 | 16 | NamedTuple,
|
|
40 | 41 | BUILTIN_LIBRARY_NAME,
|
41 | 42 | DEFAULT_LIBRARIES,
|
42 | 43 | KeywordDoc,
|
| 44 | + KeywordMatcher, |
43 | 45 | LibraryDoc,
|
44 | 46 | is_embedded_keyword,
|
45 | 47 | )
|
@@ -125,6 +127,27 @@ class NameSpaceError(Exception):
|
125 | 127 | pass
|
126 | 128 |
|
127 | 129 |
|
| 130 | +class VariablesVisitor(AsyncVisitor): |
| 131 | + async def get(self, source: str, model: ast.AST) -> List[str]: |
| 132 | + self._results: List[str] = [] |
| 133 | + self.source = source |
| 134 | + await self.visit(model) |
| 135 | + return self._results |
| 136 | + |
| 137 | + async def visit_Section(self, node: ast.AST) -> None: # noqa: N802 |
| 138 | + from robot.parsing.model.blocks import VariableSection |
| 139 | + |
| 140 | + if isinstance(node, VariableSection): |
| 141 | + await self.generic_visit(node) |
| 142 | + |
| 143 | + async def visit_Variable(self, node: ast.AST) -> None: # noqa: N802 |
| 144 | + from robot.parsing.model.statements import Variable |
| 145 | + |
| 146 | + n = cast(Variable, node) |
| 147 | + if n.name: |
| 148 | + self._results.append(n.name) |
| 149 | + |
| 150 | + |
128 | 151 | class ImportVisitor(AsyncVisitor):
|
129 | 152 | async def get(self, source: str, model: ast.AST) -> List[Import]:
|
130 | 153 | self._results: List[Import] = []
|
@@ -578,6 +601,11 @@ class ResourceEntry(LibraryEntry):
|
578 | 601 | variables: List[str] = field(default_factory=lambda: [])
|
579 | 602 |
|
580 | 603 |
|
| 604 | +@dataclass |
| 605 | +class VariablesEntry(LibraryEntry): |
| 606 | + pass |
| 607 | + |
| 608 | + |
581 | 609 | IMPORTS_KEY = object()
|
582 | 610 | REFERENCED_DOCUMENTS_KEY = object()
|
583 | 611 |
|
@@ -605,12 +633,14 @@ def __init__(
|
605 | 633 | self._document = weakref.ref(document) if document is not None else None
|
606 | 634 | self._libraries: OrderedDict[str, LibraryEntry] = OrderedDict()
|
607 | 635 | self._resources: OrderedDict[str, ResourceEntry] = OrderedDict()
|
| 636 | + self._variables: OrderedDict[str, VariablesEntry] = OrderedDict() |
608 | 637 | self._initialzed = False
|
609 | 638 | self._initialize_lock = asyncio.Lock()
|
610 | 639 | self._analyzed = False
|
611 | 640 | self._analyze_lock = asyncio.Lock()
|
612 | 641 | self._library_doc: Optional[LibraryDoc] = None
|
613 | 642 | self._imports: Optional[List[Import]] = None
|
| 643 | + self._own_variables: Optional[List[str]] = None |
614 | 644 | self._diagnostics: List[Diagnostic] = []
|
615 | 645 |
|
616 | 646 | self._keywords: Optional[List[KeywordDoc]] = None
|
@@ -711,6 +741,12 @@ async def get_imports(self) -> List[Import]:
|
711 | 741 |
|
712 | 742 | return self._imports
|
713 | 743 |
|
| 744 | + async def get_own_variables(self) -> List[str]: |
| 745 | + if self._own_variables is None: |
| 746 | + self._own_variables = await VariablesVisitor().get(self.source, self.model) |
| 747 | + |
| 748 | + return self._own_variables |
| 749 | + |
714 | 750 | async def _import_imports(self, imports: Iterable[Import], base_dir: str, *, top_level: bool = False) -> None:
|
715 | 751 | async def _import(value: Import) -> Optional[LibraryEntry]:
|
716 | 752 | result: Optional[LibraryEntry] = None
|
@@ -1014,31 +1050,31 @@ async def _get_resource_entry(self, name: str, base_dir: str, sentinel: Any = No
|
1014 | 1050 | library_doc = await self.imports_manager.get_libdoc_for_resource_import(name, base_dir, sentinel=sentinel)
|
1015 | 1051 |
|
1016 | 1052 | return ResourceEntry(
|
1017 |
| - name=library_doc.name, import_name=name, library_doc=library_doc, imports=await namespace.get_imports() |
| 1053 | + name=library_doc.name, |
| 1054 | + import_name=name, |
| 1055 | + library_doc=library_doc, |
| 1056 | + imports=await namespace.get_imports(), |
| 1057 | + variables=await namespace.get_own_variables(), |
1018 | 1058 | )
|
1019 | 1059 |
|
1020 |
| - async def _get_variables_entry(self, name: str, args: Tuple[Any, ...], base_dir: str) -> LibraryEntry: |
1021 |
| - raise NotImplementedError("_import_variables") |
1022 |
| - |
1023 |
| - # TODO get_own_keywords |
1024 | 1060 | # TODO get_variables
|
1025 | 1061 |
|
1026 | 1062 | @_logger.call
|
1027 | 1063 | async def get_keywords(self) -> List[KeywordDoc]:
|
1028 | 1064 | await self._ensure_initialized()
|
1029 | 1065 |
|
1030 | 1066 | if self._keywords is None:
|
| 1067 | + result: Dict[KeywordMatcher, KeywordDoc] = {} |
1031 | 1068 |
|
1032 |
| - self._keywords = [ |
1033 |
| - e |
1034 |
| - async for e in async_chain( |
1035 |
| - *(e.library_doc.keywords.values() for e in self._libraries.values()), |
1036 |
| - *(e.library_doc.keywords.values() for e in self._resources.values()), |
1037 |
| - (await self.get_library_doc()).keywords.values() |
1038 |
| - if (await self.get_library_doc()) is not None |
1039 |
| - else [], |
1040 |
| - ) |
1041 |
| - ] |
| 1069 | + async for name, doc in async_chain( |
| 1070 | + (await self.get_library_doc()).keywords.items() if (await self.get_library_doc()) is not None else [], |
| 1071 | + *(e.library_doc.keywords.items() for e in self._resources.values()), |
| 1072 | + *(e.library_doc.keywords.items() for e in self._libraries.values()), |
| 1073 | + ): |
| 1074 | + if KeywordMatcher(name) not in result.keys(): |
| 1075 | + result[KeywordMatcher(name)] = doc |
| 1076 | + |
| 1077 | + self._keywords = list(result.values()) |
1042 | 1078 |
|
1043 | 1079 | return self._keywords
|
1044 | 1080 |
|
|
0 commit comments