5656 strip_variable_token ,
5757 tokenize_variables ,
5858)
59+ from ..utils .match import normalize
5960from ..utils .stubs import Languages
6061from ..utils .variables import (
6162 BUILTIN_VARIABLES ,
7475 GlobalVariableDefinition ,
7576 LibraryEntry ,
7677 LocalVariableDefinition ,
77- TagDefinition ,
7878 TestCaseDefinition ,
7979 TestVariableDefinition ,
8080 VariableDefinition ,
@@ -106,11 +106,11 @@ class AnalyzerResult:
106106 local_variable_assignments : Dict [VariableDefinition , Set [Range ]]
107107 namespace_references : Dict [LibraryEntry , Set [Location ]]
108108 test_case_definitions : List [TestCaseDefinition ]
109- tag_definitions : List [TagDefinition ]
109+ keyword_tag_references : Dict [str , Set [Location ]]
110+ testcase_tag_references : Dict [str , Set [Location ]]
111+ metadata_references : Dict [str , Set [Location ]]
110112 scope_tree : ScopeTree = None # type: ignore[assignment] # set by run()
111113
112- # TODO Tag references
113-
114114
115115_builtin_variables : Optional [List [VariableDefinition ]] = None
116116
@@ -150,7 +150,9 @@ def __init__(
150150 self ._local_variable_assignments : Dict [VariableDefinition , Set [Range ]] = defaultdict (set )
151151 self ._namespace_references : Dict [LibraryEntry , Set [Location ]] = defaultdict (set )
152152 self ._test_case_definitions : List [TestCaseDefinition ] = []
153- self ._tag_definitions : List [TagDefinition ] = []
153+ self ._keyword_tag_references : Dict [str , Set [Location ]] = defaultdict (set )
154+ self ._testcase_tag_references : Dict [str , Set [Location ]] = defaultdict (set )
155+ self ._metadata_references : Dict [str , Set [Location ]] = defaultdict (set )
154156
155157 # Phase 1+2 results (set by resolve())
156158 self ._library_doc : ResourceDoc = None # type: ignore[assignment] # set by resolve()
@@ -246,7 +248,9 @@ def run(self, finder: KeywordFinder) -> AnalyzerResult:
246248 self ._local_variable_assignments ,
247249 self ._namespace_references ,
248250 self ._test_case_definitions ,
249- self ._tag_definitions ,
251+ self ._keyword_tag_references ,
252+ self ._testcase_tag_references ,
253+ self ._metadata_references ,
250254 self ._scope_builder .build (self ._variable_scope ),
251255 )
252256
@@ -1595,11 +1599,18 @@ def visit_TemplateArguments(self, node: TemplateArguments) -> None: # noqa: N80
15951599
15961600 self .generic_visit (node )
15971601
1602+ def _collect_tag_references (self , node : Statement , refs : Dict [str , Set [Location ]]) -> None :
1603+ for token in node .get_tokens (Token .ARGUMENT ):
1604+ if token .value :
1605+ refs [normalize (token .value )].add (Location (self ._document_uri , range_from_token (token )))
1606+
15981607 def visit_DefaultTags (self , node : Statement ) -> None : # noqa: N802
15991608 self ._analyze_statement_variables (node , DiagnosticSeverity .HINT )
1609+ self ._collect_tag_references (node , self ._testcase_tag_references )
16001610
16011611 def visit_ForceTags (self , node : Statement ) -> None : # noqa: N802
16021612 self ._analyze_statement_variables (node , DiagnosticSeverity .HINT )
1613+ self ._collect_tag_references (node , self ._testcase_tag_references )
16031614
16041615 if get_robot_version () >= (6 , 0 ):
16051616 tag = node .get_token (Token .FORCE_TAGS )
@@ -1614,6 +1625,7 @@ def visit_ForceTags(self, node: Statement) -> None: # noqa: N802
16141625
16151626 def visit_TestTags (self , node : Statement ) -> None : # noqa: N802
16161627 self ._analyze_statement_variables (node , DiagnosticSeverity .HINT )
1628+ self ._collect_tag_references (node , self ._testcase_tag_references )
16171629
16181630 if get_robot_version () >= (6 , 0 ):
16191631 tag = node .get_token (Token .FORCE_TAGS )
@@ -1629,9 +1641,18 @@ def visit_TestTags(self, node: Statement) -> None: # noqa: N802
16291641 def visit_Arguments (self , node : Statement ) -> None : # noqa: N802
16301642 pass
16311643
1644+ def visit_KeywordTags (self , node : Statement ) -> None : # noqa: N802
1645+ self ._visit_settings_statement (node , DiagnosticSeverity .HINT )
1646+ self ._collect_tag_references (node , self ._keyword_tag_references )
1647+
16321648 def visit_DocumentationOrMetadata (self , node : Statement ) -> None : # noqa: N802
16331649 self ._visit_settings_statement (node , DiagnosticSeverity .HINT )
16341650
1651+ if hasattr (node , "name" ) and node .name :
1652+ name_token = node .get_token (Token .NAME )
1653+ if name_token is not None :
1654+ self ._metadata_references [node .name ].add (Location (self ._document_uri , range_from_token (name_token )))
1655+
16351656 def visit_Timeout (self , node : Statement ) -> None : # noqa: N802
16361657 self ._visit_block_settings_statement (node )
16371658
@@ -1643,6 +1664,10 @@ def visit_MultiValue(self, node: Statement) -> None: # noqa: N802
16431664
16441665 def visit_Tags (self , node : Statement ) -> None : # noqa: N802
16451666 self ._visit_settings_statement (node , DiagnosticSeverity .HINT )
1667+ if any (isinstance (n , Keyword ) for n in self ._node_stack ):
1668+ self ._collect_tag_references (node , self ._keyword_tag_references )
1669+ else :
1670+ self ._collect_tag_references (node , self ._testcase_tag_references )
16461671
16471672 if (6 , 0 ) < get_robot_version () < (7 , 0 ):
16481673 for tag in node .get_tokens (Token .ARGUMENT ):
0 commit comments