Skip to content

Commit baf0c2b

Browse files
committed
complete assign keywords and correct goto for variables
1 parent 9cb951a commit baf0c2b

File tree

3 files changed

+71
-28
lines changed

3 files changed

+71
-28
lines changed

robotcode/language_server/robotframework/diagnostics/namespace.py

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ def __hash__(self) -> int:
149149
def range(self) -> Range:
150150
return Range(
151151
start=Position(
152-
line=self.name_token.lineno - 1 if self.name_token is not None else self.line_no - 1,
153-
character=self.name_token.col_offset if self.name_token is not None else self.col_offset,
152+
line=self.line_no - 1,
153+
character=self.col_offset,
154154
),
155155
end=Position(
156-
line=self.name_token.lineno - 1 if self.name_token is not None else self.end_line_no - 1,
157-
character=self.name_token.end_col_offset if self.name_token is not None else self.end_col_offset,
156+
line=self.end_line_no - 1,
157+
character=self.end_col_offset,
158158
),
159159
)
160160

@@ -212,39 +212,77 @@ async def visit_Variable(self, node: ast.AST) -> None: # noqa: N802
212212
)
213213

214214

215-
class ArgumentsVisitor(AsyncVisitor):
215+
class BlockVariableVisitor(AsyncVisitor):
216216
async def get(self, source: str, model: ast.AST) -> List[VariableDefinition]:
217217
self._results: List[VariableDefinition] = []
218218
self.source = source
219219
await self.visit(model)
220220
return self._results
221221

222-
async def visit_Section(self, node: ast.AST) -> None: # noqa: N802
223-
from robot.parsing.model.blocks import VariableSection
224-
225-
if isinstance(node, VariableSection):
226-
await self.generic_visit(node)
227-
228222
async def visit_Arguments(self, node: ast.AST) -> None: # noqa: N802
223+
from robot.errors import VariableError
229224
from robot.parsing.lexer.tokens import Token as RobotToken
230225
from robot.parsing.model.statements import Arguments
231226
from robot.variables.search import is_variable
232227

233228
n = cast(Arguments, node)
234229
arguments = n.get_tokens(RobotToken.ARGUMENT)
235230
for argument in (cast(RobotToken, e) for e in arguments):
236-
if is_variable(argument.value):
231+
try:
232+
if is_variable(argument.value):
233+
self._results.append(
234+
ArgumentDefinition(
235+
name=argument.value,
236+
name_token=argument,
237+
line_no=node.lineno,
238+
col_offset=node.col_offset,
239+
end_line_no=node.end_lineno
240+
if node.end_lineno is not None
241+
else argument.lineno
242+
if argument.lineno is not None
243+
else -1,
244+
end_col_offset=node.end_col_offset
245+
if node.end_col_offset is not None
246+
else argument.end_col_offset
247+
if argument.end_col_offset is not None
248+
else -1,
249+
source=self.source,
250+
)
251+
)
252+
except VariableError:
253+
pass
254+
255+
async def visit_KeywordCall(self, node: ast.AST) -> None: # noqa: N802
256+
from robot.errors import VariableError
257+
from robot.parsing.lexer.tokens import Token as RobotToken
258+
from robot.parsing.model.statements import KeywordCall
259+
from robot.variables.search import contains_variable
260+
261+
try:
262+
n = cast(KeywordCall, node)
263+
assign_token = n.get_token(RobotToken.ASSIGN)
264+
if assign_token is not None and assign_token.value and contains_variable(assign_token.value):
237265
self._results.append(
238-
ArgumentDefinition(
239-
name=argument.value,
240-
name_token=argument,
241-
line_no=argument.lineno,
242-
col_offset=argument.col_offset,
243-
end_line_no=argument.lineno if argument.lineno is not None else -1,
244-
end_col_offset=argument.end_col_offset if argument.end_col_offset is not None else -1,
266+
VariableDefinition(
267+
name=assign_token.value,
268+
name_token=assign_token,
269+
line_no=node.lineno,
270+
col_offset=node.col_offset,
271+
end_line_no=node.end_lineno
272+
if node.end_lineno is not None
273+
else assign_token.lineno
274+
if assign_token.lineno is not None
275+
else -1,
276+
end_col_offset=node.end_col_offset
277+
if node.end_col_offset is not None
278+
else assign_token.end_col_offset
279+
if assign_token.end_col_offset is not None
280+
else -1,
245281
source=self.source,
246282
)
247283
)
284+
except VariableError:
285+
pass
248286

249287

250288
class ImportVisitor(AsyncVisitor):
@@ -851,14 +889,18 @@ def get_builtin_variables(cls) -> List[BuiltInVariableDefinition]:
851889
return cls._builtin_variables
852890

853891
async def get_variables(self, nodes: Optional[List[ast.AST]] = None) -> Dict[VariableMatcher, VariableDefinition]:
854-
from robot.parsing.model.blocks import Keyword
892+
from robot.parsing.model.blocks import Keyword, TestCase
855893

856894
await self._ensure_initialized()
857895

858896
result: Dict[VariableMatcher, VariableDefinition] = {}
859897

860898
async for var in async_chain(
861-
*[await ArgumentsVisitor().get(self.source, n) for n in nodes or [] if isinstance(n, Keyword)],
899+
*[
900+
await BlockVariableVisitor().get(self.source, n)
901+
for n in nodes or []
902+
if isinstance(n, (Keyword, TestCase))
903+
],
862904
(e for e in await self.get_own_variables()),
863905
*(e.variables for e in self._resources.values()),
864906
(e for e in self.get_builtin_variables()),

robotcode/language_server/robotframework/parts/completion.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ async def create_environment_variables_completion_items(self, range: Optional[Ra
308308
}
309309

310310
async def create_variables_completion_items(
311-
self, range: Optional[Range], nodes: Optional[List[ast.AST]] = None
311+
self, range: Range, nodes: List[ast.AST], position: Position
312312
) -> List[CompletionItem]:
313313
if self.document is None:
314314
return []
@@ -327,12 +327,11 @@ async def create_variables_completion_items(
327327
text_edit=TextEdit(
328328
range=range,
329329
new_text=s.name[2:-1],
330-
)
331-
if range is not None
332-
else None,
330+
),
331+
filter_text=s.name[2:-1] if range is not None else None,
333332
)
334333
for s in (await namespace.get_variables(nodes)).values()
335-
if s.name is not None
334+
if s.name is not None and (s.name_token is None or not position.is_in_range(range_from_token(s.name_token)))
336335
]
337336

338337
async def create_settings_completion_items(self, range: Optional[Range]) -> List[CompletionItem]:
@@ -624,7 +623,7 @@ async def complete_default(
624623
)
625624
if token_at_position.value[open_brace_index - 1] == "%":
626625
return await self.create_environment_variables_completion_items(range)
627-
return await self.create_variables_completion_items(range, nodes_at_position)
626+
return await self.create_variables_completion_items(range, nodes_at_position, position)
628627

629628
return None
630629

robotcode/language_server/robotframework/parts/goto.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ async def _definition_default(
114114
origin_selection_range=range_from_token_or_node(node, sub_token),
115115
target_uri=str(Uri.from_path(variable.source)),
116116
target_range=variable.range(),
117-
target_selection_range=variable.range(),
117+
target_selection_range=range_from_token(variable.name_token)
118+
if variable.name_token
119+
else variable.range(),
118120
)
119121
]
120122
except BaseException:

0 commit comments

Comments
 (0)