def test_macro_var_scope(self): """Test macro variable scope.""" script = ("macro (foo VAR)\n" "endmacro ()") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VAR")))
def test_global_scope(self, matcher): """Test setting and finding vars with {} at global scope.""" script = "{0}".format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_global_scope(self, matcher): """Test setting and finding vars with {} at global scope.""" script = "{0}".format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def only_use_own_priv_vars(ast): """Check that all private variables used are defined here.""" used_privs = [] global_set_vars = find_variables_in_scopes.set_in_tree(ast) global_used_vars = find_variables_in_scopes.used_in_tree(ast) _, global_definitions = find_all.private_calls_and_definitions(ast) # The big assumption here is that the "scopes" structure in both # trees are the same def _scope_visitor(set_vars_scope, used_vars_scope): """Visit scope's set vars and used vars. If a var was private and used, but not set in this scope or any parents, then report an error """ assert len(set_vars_scope.scopes) == len(used_vars_scope.scopes) for index in range(0, len(set_vars_scope.scopes)): _scope_visitor(set_vars_scope.scopes[index], used_vars_scope.scopes[index]) for variable in used_vars_scope.used_vars: used_privs.extend(list(_find_violating_priv_uses(variable, set_vars_scope))) _scope_visitor(global_set_vars, global_used_vars) # Filter out definitions of private functions of the same name # as functions can be used as variables. used_privs = [up for up in used_privs if up[0] not in global_definitions] err_msg = "Referenced external private variable {0}" return [LinterFailure(err_msg.format(u[0]), u[1]) for u in used_privs]
def vars_in_func_used(abstract_syntax_tree): """Check that variables defined in a function are used later.""" errors = [] set_scopes = find_variables_in_scopes.set_in_tree(abstract_syntax_tree) used_scopes = find_variables_in_scopes.used_in_tree(abstract_syntax_tree) # Iterate through the set and used variables - making sure that any set # variables are used somewhere down the scope chain def _scope_visitor(set_scope, used_scope): """Visit both scopes at the same level.""" assert len(set_scope.scopes) == len(used_scope.scopes) # Ignore the global scope if id(set_scopes) != id(set_scope): for var in set_scope.set_vars: if var.node.type != WordType.Variable: return if not _variable_used_in_scope(var.node.contents, var.node, used_scope): msg = "Unused local variable {0}".format(var.node.contents) errors.append(LinterFailure(msg, var.node.line)) for index in range(0, len(set_scope.scopes)): _scope_visitor(set_scope.scopes[index], used_scope.scopes[index]) _scope_visitor(set_scopes, used_scopes) return errors
def test_in_func_scope(self, matcher): """Test setting and finding vars with {} in function scope.""" script = ("function (foo)\n" " {0}\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_in_func_scope(self, matcher): """Test setting and finding vars with {} in function scope.""" script = ("function (foo)\n" " {0}\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_parent_scope(self): """Test that setting a variable in the parent scope propagates.""" script = ("function (foo)\n" " function (other)\n" " set (VARIABLE OTHER PARENT_SCOPE)\n" " endfunction ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VARIABLE")))
def test_foreach_in_func(self, matcher): """Test that using {} in an foreach statements propagates variable.""" script = ("function (foo)\n" " foreach (VAR LISTVAR)\n" " {0}\n" " endforeach ()\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_while_in_func(self, matcher): """Test that using {} in a while block propagates variable to func.""" script = ("function (foo)\n" " while (CONDITION)\n" " {0}\n" " endwhile (CONDITION)\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_global_setprop_scope(self): """Test that setting a variable in the set_property scope is global.""" script = ("function (foo)\n" " function (other)\n" " set_property (GLOBAL PROPERTY VARIABLE OTHER)\n" " endfunction ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.set_vars[0].node, MatchesStructure(contents=Equals("VARIABLE")))
def test_parent_scope(self): """Test that setting a variable in the parent scope propagates.""" script = ("function (foo)\n" " function (other)\n" " set (VARIABLE OTHER PARENT_SCOPE)\n" " endfunction ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VARIABLE")))
def test_global_setprop_scope(self): """Test that setting a variable in the set_property scope is global.""" script = ("function (foo)\n" " function (other)\n" " set_property (GLOBAL PROPERTY VARIABLE OTHER)\n" " endfunction ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.set_vars[0].node, MatchesStructure(contents=Equals("VARIABLE")))
def test_while_in_func(self, matcher): """Test that using {} in a while block propagates variable to func.""" script = ("function (foo)\n" " while (CONDITION)\n" " {0}\n" " endwhile (CONDITION)\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_foreach_in_func(self, matcher): """Test that using {} in an foreach statements propagates variable.""" script = ("function (foo)\n" " foreach (VAR LISTVAR)\n" " {0}\n" " endforeach ()\n" "endfunction ()\n").format(gen_source_line(matcher)) global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VALUE")))
def test_foreach_scope(self): """Test that setting a variable in an foreach statements propagates.""" script = ("function (foo)\n" " foreach (VAR LISTVAR)\n" " endforeach ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VAR"))) foreach_type = find_variables_in_scopes.ScopeType.Foreach self.assertThat(global_scope.scopes[0].scopes[0].info, MatchesStructure(type=Equals(foreach_type)))
def test_foreach_scope(self): """Test that setting a variable in an foreach statements propagates.""" script = ("function (foo)\n" " foreach (VAR LISTVAR)\n" " endforeach ()\n" "endfunction ()\n") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VAR"))) foreach_type = find_variables_in_scopes.ScopeType.Foreach self.assertThat(global_scope.scopes[0].scopes[0].info, MatchesStructure(type=Equals(foreach_type)))
def test_macro_var_scope(self): """Test macro variable scope.""" script = ("macro (foo VAR)\n" "endmacro ()") global_scope = find_variables_in_scopes.set_in_tree(ast.parse(script)) self.assertThat(global_scope.scopes[0].set_vars[0].node, MatchesStructure(contents=Equals("VAR")))