From 1a5a2cebb48d01bf09b138dae676b0fa280fd187 Mon Sep 17 00:00:00 2001 From: Bartlomiej Hirsz Date: Tue, 30 Jul 2024 11:42:51 +0200 Subject: [PATCH] Fix not used variables not detected in IF --- docs/releasenotes/unreleased/fixes.2.rst | 11 +++++++++ robocop/checkers/misc.py | 18 +++++++++++++- .../expected_output_after_var.txt | 15 +++++++----- .../expected_output_pre_var.txt | 11 +++++---- .../rules/misc/unused_variable/test.robot | 24 +++++++++++++++++++ 5 files changed, 68 insertions(+), 11 deletions(-) create mode 100644 docs/releasenotes/unreleased/fixes.2.rst diff --git a/docs/releasenotes/unreleased/fixes.2.rst b/docs/releasenotes/unreleased/fixes.2.rst new file mode 100644 index 00000000..7f3fb679 --- /dev/null +++ b/docs/releasenotes/unreleased/fixes.2.rst @@ -0,0 +1,11 @@ +unused-variable not detected within IF block (#1093) +---------------------------------------------------- + +If the variable was defined in the IF block, I0920 ``unused-variable`` was not reported even if variable was not used +anywhere:: + + *** Test Cases *** + Useless variable definition + IF True + ${not_used} Keyword Call + END diff --git a/robocop/checkers/misc.py b/robocop/checkers/misc.py index cdf58d60..f8964691 100644 --- a/robocop/checkers/misc.py +++ b/robocop/checkers/misc.py @@ -1343,12 +1343,28 @@ def visit_If(self, node): # noqa self.variables.append({}) for item in node.body: self.visit(item) - self.variables.pop() + self.add_variables_from_if_to_scope() if node.orelse: self.visit(node.orelse) for token in node.header.get_tokens(Token.ASSIGN): self.handle_assign_variable(token) + def add_variables_from_if_to_scope(self): + """ + Add all variables in given IF branch to common scope. If variable is used already in the branch, if it will + also be mark as used. + """ + variables = self.variables.pop() + if not self.variables: + self.variables.append(variables) + return + for var_name, cached_var in variables.items(): + if var_name in self.variables[-1]: + if cached_var.is_used: + self.variables[-1][var_name].is_used = True + else: + self.variables[-1][var_name] = cached_var + def visit_LibraryImport(self, node): # noqa for token in node.get_tokens(Token.NAME, Token.ARGUMENT): self.find_not_nested_variable(token.value, is_var=False) diff --git a/tests/atest/rules/misc/unused_variable/expected_output_after_var.txt b/tests/atest/rules/misc/unused_variable/expected_output_after_var.txt index 9c360f39..2cb6adf4 100644 --- a/tests/atest/rules/misc/unused_variable/expected_output_after_var.txt +++ b/tests/atest/rules/misc/unused_variable/expected_output_after_var.txt @@ -2,10 +2,13 @@ test.robot:15:5:15:11 [I] 0920 Variable '${var}' is assigned but not used test.robot:19:15:19:22 [I] 0920 Variable '${var2}' is assigned but not used test.robot:23:5:23:11 [I] 0920 Variable '${var}' is assigned but not used test.robot:31:5:31:14 [I] 0920 Variable '${assign}' is assigned but not used -test.robot:42:12:42:18 [I] 0920 Variable '${var}' is assigned but not used -test.robot:68:12:68:23 [I] 0920 Variable '${category}' is assigned but not used -test.robot:116:5:116:11 [I] 0920 Variable '${var}' is assigned but not used -test.robot:119:5:119:14 [I] 0920 Variable '${assign}' is assigned but not used -test.robot:122:12:122:23 [I] 0920 Variable '${not_used}' is assigned but not used -test.robot:130:12:130:23 [I] 0920 Variable '${variable}' is assigned but not used +test.robot:39:9:39:20 [I] 0920 Variable '${not_used}' is assigned but not used +test.robot:44:9:44:32 [I] 0920 Variable '${not_used_from_branch}' is assigned but not used +test.robot:52:13:52:30 [I] 0920 Variable '${nested_define3}' is assigned but not used +test.robot:66:12:66:18 [I] 0920 Variable '${var}' is assigned but not used +test.robot:92:12:92:23 [I] 0920 Variable '${category}' is assigned but not used +test.robot:140:5:140:11 [I] 0920 Variable '${var}' is assigned but not used +test.robot:143:5:143:14 [I] 0920 Variable '${assign}' is assigned but not used +test.robot:146:12:146:23 [I] 0920 Variable '${not_used}' is assigned but not used +test.robot:154:12:154:23 [I] 0920 Variable '${variable}' is assigned but not used unused_section_vars.robot:21:1:21:19 [I] 0920 Variable '${GLOBAL_NOT_USED}' is assigned but not used \ No newline at end of file diff --git a/tests/atest/rules/misc/unused_variable/expected_output_pre_var.txt b/tests/atest/rules/misc/unused_variable/expected_output_pre_var.txt index 9a08f157..55c64bb3 100644 --- a/tests/atest/rules/misc/unused_variable/expected_output_pre_var.txt +++ b/tests/atest/rules/misc/unused_variable/expected_output_pre_var.txt @@ -2,8 +2,11 @@ test.robot:15:5:15:11 [I] 0920 Variable '${var}' is assigned but not used test.robot:19:15:19:22 [I] 0920 Variable '${var2}' is assigned but not used test.robot:23:5:23:11 [I] 0920 Variable '${var}' is assigned but not used test.robot:31:5:31:14 [I] 0920 Variable '${assign}' is assigned but not used -test.robot:42:12:42:18 [I] 0920 Variable '${var}' is assigned but not used -test.robot:68:12:68:23 [I] 0920 Variable '${category}' is assigned but not used -test.robot:116:5:116:11 [I] 0920 Variable '${var}' is assigned but not used -test.robot:119:5:119:14 [I] 0920 Variable '${assign}' is assigned but not used +test.robot:39:9:39:20 [I] 0920 Variable '${not_used}' is assigned but not used +test.robot:44:9:44:32 [I] 0920 Variable '${not_used_from_branch}' is assigned but not used +test.robot:52:13:52:30 [I] 0920 Variable '${nested_define3}' is assigned but not used +test.robot:66:12:66:18 [I] 0920 Variable '${var}' is assigned but not used +test.robot:92:12:92:23 [I] 0920 Variable '${category}' is assigned but not used +test.robot:140:5:140:11 [I] 0920 Variable '${var}' is assigned but not used +test.robot:143:5:143:14 [I] 0920 Variable '${assign}' is assigned but not used unused_section_vars.robot:21:1:21:19 [I] 0920 Variable '${GLOBAL_NOT_USED}' is assigned but not used \ No newline at end of file diff --git a/tests/atest/rules/misc/unused_variable/test.robot b/tests/atest/rules/misc/unused_variable/test.robot index cb1b1165..1078d64f 100644 --- a/tests/atest/rules/misc/unused_variable/test.robot +++ b/tests/atest/rules/misc/unused_variable/test.robot @@ -34,6 +34,30 @@ Used In IF IF $var Keyword String with ${var2} END + ${used_in_if} Keyword + IF True + ${not_used} Keyword + # TODO even if branch used it, it should be mark as unused. Could be achieved by making + # add_variables_from_if_to_scope temporarily saving popped variables + ${used_in_branch} Keyword + ELSE IF False + ${not_used_from_branch} Keyword ${used_in_branch} + ELSE + Keyword ${used_in_if} + END + IF nested + IF nested-loop + ${nested_define} Keyword + ${nested_define2} Keyword + ${nested_define3} Keyword + ELSE + ${nested_define} Keyword + ${nested_define2} Keyword + ${nested_define3} Keyword + END + Keyword ${nested_define} + END + Keyword ${nested_define2} Not Used From FOR FOR ${var} IN 1 2 3