41
41
LibraryEntry ,
42
42
ResourceEntry ,
43
43
VariableDefinition ,
44
+ VariableDefinitionType ,
44
45
VariableNotFoundDefinition ,
45
46
)
46
47
from .library_doc import KeywordDoc , KeywordMatcher , is_embedded_keyword
@@ -245,16 +246,36 @@ async def visit(self, node: ast.AST) -> None:
245
246
var_range = range_from_token (var_token )
246
247
else :
247
248
var_range = range_from_token (var_token )
249
+
250
+ suite_var = None
251
+ if isinstance (var , CommandLineVariableDefinition ):
252
+ suite_var = await self .namespace .find_variable (
253
+ var .name ,
254
+ skip_commandline_variables = True ,
255
+ ignore_error = True ,
256
+ )
257
+ if suite_var is not None and suite_var .type not in [
258
+ VariableDefinitionType .VARIABLE
259
+ ]:
260
+ suite_var = None
261
+
248
262
if var .name_range != var_range :
249
263
self ._variable_references [var ].add (
250
264
Location (self .namespace .document .document_uri , var_range )
251
265
)
266
+ if suite_var is not None :
267
+ self ._variable_references [suite_var ].add (
268
+ Location (self .namespace .document .document_uri , var_range )
269
+ )
270
+
252
271
elif var not in self ._variable_references and token1 .type in [
253
272
RobotToken .ASSIGN ,
254
273
RobotToken .ARGUMENT ,
255
274
RobotToken .VARIABLE ,
256
275
]:
257
276
self ._variable_references [var ] = set ()
277
+ if suite_var is not None :
278
+ self ._variable_references [suite_var ] = set ()
258
279
259
280
if (
260
281
isinstance (node , Statement )
@@ -280,11 +301,23 @@ async def visit(self, node: ast.AST) -> None:
280
301
else :
281
302
if self .namespace .document is not None :
282
303
var_range = range_from_token (var_token )
304
+
283
305
if var .name_range != var_range :
284
306
self ._variable_references [var ].add (
285
307
Location (self .namespace .document .document_uri , range_from_token (var_token ))
286
308
)
287
309
310
+ if isinstance (var , CommandLineVariableDefinition ):
311
+ suite_var = await self .namespace .find_variable (
312
+ var .name ,
313
+ skip_commandline_variables = True ,
314
+ ignore_error = True ,
315
+ )
316
+ if suite_var is not None and suite_var .type in [VariableDefinitionType .VARIABLE ]:
317
+ self ._variable_references [suite_var ].add (
318
+ Location (self .namespace .document .document_uri , range_from_token (var_token ))
319
+ )
320
+
288
321
await super ().visit (node )
289
322
finally :
290
323
self .node_stack = self .node_stack [:- 1 ]
@@ -377,6 +410,37 @@ async def _analyze_keyword_call(
377
410
378
411
result = self .finder .find_keyword (keyword )
379
412
413
+ if (
414
+ result is not None
415
+ and lib_entry is not None
416
+ and kw_namespace
417
+ and result .parent is not None
418
+ and result .parent != lib_entry .library_doc .digest
419
+ ):
420
+ entry = next (
421
+ (
422
+ v
423
+ for v in (await self .namespace .get_libraries ()).values ()
424
+ if v .library_doc .digest == result .parent
425
+ ),
426
+ None ,
427
+ )
428
+ if entry is None :
429
+ entry = next (
430
+ (
431
+ v
432
+ for v in (await self .namespace .get_resources ()).values ()
433
+ if v .library_doc .digest == result .parent
434
+ ),
435
+ None ,
436
+ )
437
+ if entry is not None :
438
+ lib_entry = entry
439
+
440
+ if kw_namespace and lib_entry is not None and lib_range is not None :
441
+ if self .namespace .document is not None :
442
+ self ._namespace_references [lib_entry ].add (Location (self .namespace .document .document_uri , lib_range ))
443
+
380
444
if not ignore_errors_if_contains_variables or is_not_variable_token (keyword_token ):
381
445
for e in self .finder .diagnostics :
382
446
self .append_diagnostics (
@@ -386,11 +450,11 @@ async def _analyze_keyword_call(
386
450
code = e .code ,
387
451
)
388
452
389
- if kw_namespace and lib_entry is not None and lib_range is not None :
390
- if self .namespace .document is not None :
391
- self . _namespace_references [ lib_entry ]. add ( Location ( self .namespace . document . document_uri , lib_range ))
392
-
393
- if result is not None :
453
+ if result is None :
454
+ if self .namespace .document is not None and self . finder . multiple_keywords_result is not None :
455
+ for lib_entry , kw_doc in self .finder . multiple_keywords_result :
456
+ self . _keyword_references [ kw_doc ]. add ( Location ( self . namespace . document . document_uri , kw_range ))
457
+ else :
394
458
if self .namespace .document is not None :
395
459
self ._keyword_references [result ].add (Location (self .namespace .document .document_uri , kw_range ))
396
460
@@ -538,6 +602,17 @@ async def _analyze_keyword_call(
538
602
self ._variable_references [var ].add (
539
603
Location (self .namespace .document .document_uri , range_from_token (var_token ))
540
604
)
605
+
606
+ if isinstance (var , CommandLineVariableDefinition ):
607
+ suite_var = await self .namespace .find_variable (
608
+ var .name ,
609
+ skip_commandline_variables = True ,
610
+ ignore_error = True ,
611
+ )
612
+ if suite_var is not None and suite_var .type in [VariableDefinitionType .VARIABLE ]:
613
+ self ._variable_references [suite_var ].add (
614
+ Location (self .namespace .document .document_uri , range_from_token (var_token ))
615
+ )
541
616
if result .argument_definitions :
542
617
for arg in argument_tokens :
543
618
name , value = split_from_equals (arg .value )
@@ -964,22 +1039,61 @@ def _check_import_name(self, value: Optional[str], node: ast.AST, type: str) ->
964
1039
)
965
1040
966
1041
async def visit_VariablesImport (self , node : ast .AST ) -> None : # noqa: N802
967
- if get_robot_version () >= ( 6 , 1 ):
968
- from robot .parsing .model .statements import VariablesImport
1042
+ from robot . parsing . lexer . tokens import Token as RobotToken
1043
+ from robot .parsing .model .statements import VariablesImport
969
1044
1045
+ if get_robot_version () >= (6 , 1 ):
970
1046
import_node = cast (VariablesImport , node )
971
1047
self ._check_import_name (import_node .name , node , "Variables" )
972
1048
1049
+ n = cast (VariablesImport , node )
1050
+ name_token = cast (RobotToken , n .get_token (RobotToken .NAME ))
1051
+ if name_token is None :
1052
+ return
1053
+
1054
+ entries = await self .namespace .get_imported_variables ()
1055
+ if entries and self .namespace .document :
1056
+ for v in entries .values ():
1057
+ if v .import_source == self .namespace .source and v .import_range == range_from_token (name_token ):
1058
+ if v not in self ._namespace_references :
1059
+ self ._namespace_references [v ] = set ()
1060
+
973
1061
async def visit_ResourceImport (self , node : ast .AST ) -> None : # noqa: N802
974
- if get_robot_version () >= ( 6 , 1 ):
975
- from robot .parsing .model .statements import ResourceImport
1062
+ from robot . parsing . lexer . tokens import Token as RobotToken
1063
+ from robot .parsing .model .statements import ResourceImport
976
1064
1065
+ if get_robot_version () >= (6 , 1 ):
977
1066
import_node = cast (ResourceImport , node )
978
1067
self ._check_import_name (import_node .name , node , "Resource" )
979
1068
1069
+ n = cast (ResourceImport , node )
1070
+ name_token = cast (RobotToken , n .get_token (RobotToken .NAME ))
1071
+ if name_token is None :
1072
+ return
1073
+
1074
+ entries = await self .namespace .get_resources ()
1075
+ if entries and self .namespace .document :
1076
+ for v in entries .values ():
1077
+ if v .import_source == self .namespace .source and v .import_range == range_from_token (name_token ):
1078
+ if v not in self ._namespace_references :
1079
+ self ._namespace_references [v ] = set ()
1080
+
980
1081
async def visit_LibraryImport (self , node : ast .AST ) -> None : # noqa: N802
981
- if get_robot_version () >= ( 6 , 1 ):
982
- from robot .parsing .model .statements import LibraryImport
1082
+ from robot . parsing . lexer . tokens import Token as RobotToken
1083
+ from robot .parsing .model .statements import LibraryImport
983
1084
1085
+ if get_robot_version () >= (6 , 1 ):
984
1086
import_node = cast (LibraryImport , node )
985
1087
self ._check_import_name (import_node .name , node , "Library" )
1088
+
1089
+ n = cast (LibraryImport , node )
1090
+ name_token = cast (RobotToken , n .get_token (RobotToken .NAME ))
1091
+ if name_token is None :
1092
+ return
1093
+
1094
+ entries = await self .namespace .get_libraries ()
1095
+ if entries and self .namespace .document :
1096
+ for v in entries .values ():
1097
+ if v .import_source == self .namespace .source and v .import_range == range_from_token (name_token ):
1098
+ if v not in self ._namespace_references :
1099
+ self ._namespace_references [v ] = set ()
0 commit comments