Skip to content

Commit 666df9c

Browse files
committed
namespace object now filters keywords correctly
1 parent 088d265 commit 666df9c

File tree

2 files changed

+54
-15
lines changed

2 files changed

+54
-15
lines changed

robotcode/language_server/robotframework/diagnostics/library_doc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ def __init__(self, name: str) -> None:
109109
def __eq__(self, o: object) -> bool:
110110
from robot.utils.normalizing import normalize
111111

112+
if isinstance(o, KeywordMatcher):
113+
o = o.name
114+
112115
if not isinstance(o, str):
113116
return False
114117

robotcode/language_server/robotframework/diagnostics/namespace.py

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
Any,
1111
AsyncIterator,
1212
Callable,
13+
Dict,
1314
Iterable,
1415
List,
1516
NamedTuple,
@@ -40,6 +41,7 @@
4041
BUILTIN_LIBRARY_NAME,
4142
DEFAULT_LIBRARIES,
4243
KeywordDoc,
44+
KeywordMatcher,
4345
LibraryDoc,
4446
is_embedded_keyword,
4547
)
@@ -125,6 +127,27 @@ class NameSpaceError(Exception):
125127
pass
126128

127129

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+
128151
class ImportVisitor(AsyncVisitor):
129152
async def get(self, source: str, model: ast.AST) -> List[Import]:
130153
self._results: List[Import] = []
@@ -578,6 +601,11 @@ class ResourceEntry(LibraryEntry):
578601
variables: List[str] = field(default_factory=lambda: [])
579602

580603

604+
@dataclass
605+
class VariablesEntry(LibraryEntry):
606+
pass
607+
608+
581609
IMPORTS_KEY = object()
582610
REFERENCED_DOCUMENTS_KEY = object()
583611

@@ -605,12 +633,14 @@ def __init__(
605633
self._document = weakref.ref(document) if document is not None else None
606634
self._libraries: OrderedDict[str, LibraryEntry] = OrderedDict()
607635
self._resources: OrderedDict[str, ResourceEntry] = OrderedDict()
636+
self._variables: OrderedDict[str, VariablesEntry] = OrderedDict()
608637
self._initialzed = False
609638
self._initialize_lock = asyncio.Lock()
610639
self._analyzed = False
611640
self._analyze_lock = asyncio.Lock()
612641
self._library_doc: Optional[LibraryDoc] = None
613642
self._imports: Optional[List[Import]] = None
643+
self._own_variables: Optional[List[str]] = None
614644
self._diagnostics: List[Diagnostic] = []
615645

616646
self._keywords: Optional[List[KeywordDoc]] = None
@@ -711,6 +741,12 @@ async def get_imports(self) -> List[Import]:
711741

712742
return self._imports
713743

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+
714750
async def _import_imports(self, imports: Iterable[Import], base_dir: str, *, top_level: bool = False) -> None:
715751
async def _import(value: Import) -> Optional[LibraryEntry]:
716752
result: Optional[LibraryEntry] = None
@@ -1014,31 +1050,31 @@ async def _get_resource_entry(self, name: str, base_dir: str, sentinel: Any = No
10141050
library_doc = await self.imports_manager.get_libdoc_for_resource_import(name, base_dir, sentinel=sentinel)
10151051

10161052
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(),
10181058
)
10191059

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
10241060
# TODO get_variables
10251061

10261062
@_logger.call
10271063
async def get_keywords(self) -> List[KeywordDoc]:
10281064
await self._ensure_initialized()
10291065

10301066
if self._keywords is None:
1067+
result: Dict[KeywordMatcher, KeywordDoc] = {}
10311068

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())
10421078

10431079
return self._keywords
10441080

0 commit comments

Comments
 (0)