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_exclude_if_kws(self, keyword):
     """Test that there is no use for an if keyword."""
     script = ("if ({0} OTHER)\n"
               "endif ()").format(keyword)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals(keyword))))
 def test_no_use_by_foreach_var(self):
     """Test that there is no use for a foreach var."""
     script = ("foreach (VAR ${LIST})\n"
               "endforeach ()")
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals("VAR"))))
 def test_exclude_foreach_kws(self, keyword):
     """Test that there is no use for a foreach keyword."""
     script = ("foreach (VAR {0} LIST)\n"
               "endforeach ()").format(keyword)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals(keyword))))
Example #5
0
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 variables_used_matching(abstract_syntax_tree, node_matcher, name_matcher):
    """Return a set of variable names used whose nodes satisfy matchers."""
    variables_used = {}

    global_scope = find_variables_in_scopes.used_in_tree(abstract_syntax_tree)

    def _visit_scope(scope):
        """Visit a scope."""
        for subscope in scope.scopes:
            _visit_scope(subscope)

        for word, _ in scope.used_vars:

            if not node_matcher(word):
                continue

            variable_uses = _RE_VARIABLE_USE.findall(word.contents)

            for match in variable_uses:
                if not name_matcher(match):
                    continue

                _append_to_set_variables(match, word, variables_used)

    _visit_scope(global_scope)

    return variables_used
 def test_used_in_macro(self, call):
     """Test that a variable is marked as used in a macro."""
     script = ("macro (name)\n"
               "    f ({0})\n"
               "endmacro ()\n").format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.scopes[0].used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.MacroVar)))
 def test_used_in_macro(self, call):
     """Test that a variable is marked as used in a macro."""
     script = ("macro (name)\n"
               "    f ({0})\n"
               "endmacro ()\n").format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.scopes[0].used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.MacroVar)))
 def test_used_in_func_foreach(self, call):
     """Test that a variable is marked as used in a function when nested."""
     script = ("function (name)\n"
               "    foreach (VAR {0})"
               "    endforeach ()"
               "endfunction ()\n").format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.scopes[0].used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.FunctionVar)))
 def test_used_in_func_foreach(self, call):
     """Test that a variable is marked as used in a function when nested."""
     script = ("function (name)\n"
               "    foreach (VAR {0})"
               "    endforeach ()"
               "endfunction ()\n").format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.scopes[0].used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.FunctionVar)))
def private_definitions_used(abstract_syntax_tree):
    """Check that all private definitions are used by this module."""
    calls, defs = find_all.private_calls_and_definitions(abstract_syntax_tree)

    errors = []

    # There's no scoping of functions defined within other functions, so
    # we search from the root of the tree.
    global_scope = find_variables_in_scopes.used_in_tree(abstract_syntax_tree)

    for definition, info in defs.items():
        not_in_function_calls = definition not in calls.keys()
        not_used_as_variable = not _variable_used_in_scope(
            definition, None, global_scope)
        if not_in_function_calls and not_used_as_variable:
            for line in info:
                msg = "Unused private definition {0}".format(definition)
                errors.append(LinterFailure(msg, line))

    return errors
 def test_use_at_toplevel(self, call):
     """Test that a variable is marked as used at the toplevel."""
     script = "f ({0})".format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.GlobalVar)))
 def test_not_used_in_function_hdr(self):
     """Test that there is no use in a function header."""
     script = ("function (name ARGUMENT)\n"
               "endfunction ()")
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertEqual(len(global_scope.scopes[0].used_vars), 0)
 def test_use_at_toplevel(self, call):
     """Test that a variable is marked as used at the toplevel."""
     script = "f ({0})".format(call)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0],
                     MatchesStructure(source=Equals(VarSrc.GlobalVar)))
 def test_exclude_if_kws(self, keyword):
     """Test that there is no use for an if keyword."""
     script = ("if ({0} OTHER)\n" "endif ()").format(keyword)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals(keyword))))
 def test_exclude_foreach_kws(self, keyword):
     """Test that there is no use for a foreach keyword."""
     script = ("foreach (VAR {0} LIST)\n" "endforeach ()").format(keyword)
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals(keyword))))
 def test_no_use_by_foreach_var(self):
     """Test that there is no use for a foreach var."""
     script = ("foreach (VAR ${LIST})\n" "endforeach ()")
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertThat(global_scope.used_vars[0].node,
                     MatchesStructure(contents=Not(Equals("VAR"))))
 def test_not_used_in_function_hdr(self):
     """Test that there is no use in a function header."""
     script = ("function (name ARGUMENT)\n" "endfunction ()")
     global_scope = find_variables_in_scopes.used_in_tree(ast.parse(script))
     self.assertEqual(len(global_scope.scopes[0].used_vars), 0)