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_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"))))
Example #3
0
 def test_parse_arg_for_col(self, col, statement):
     """Parse for column number of argument."""
     function_call_len = len("function_call (")
     script = " " * (col - 1) + statement
     parse_result = ast.parse(script)
     self.assertEqual(parse_result.statements[0].arguments[0].col,
                      col + function_call_len)
    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_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_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))))
Example #7
0
 def test_function_call_args(self, contents):
     """Parse for FunctionCall args."""
     body = ast.parse(contents)
     self.assertTrue(isinstance(body.statements[0].arguments[0],
                                ast.Word))
     self.assertTrue(isinstance(body.statements[0].arguments[1],
                                ast.Word))
Example #8
0
 def test_elseif_statement_has_body(self):
     """First element of ElseIfStatement body should be FunctionCall."""
     body = ast.parse(self.if_else_if_block)
     elseif_statement = body.statements[0].elseif_statements[0]
     self.assertTrue(isinstance(elseif_statement.body[0], ast.FunctionCall))
     self.assertEqual(elseif_statement.body[0].arguments[0].contents,
                      "ELSEIF")
def lint(contents, whitelist=None, blacklist=None, **kwargs):
    r"""Actually lints some file contents.

    Contents should be a raw string with \n. whitelist is a list of checks
    to only perform, blacklist is list of checks to never perform.
    """
    abstract_syntax_tree = ast.parse(contents)
    contents_lines = contents.splitlines(True)
    linter_functions = LINTER_FUNCTIONS

    def _keyvalue_pair_if(dictionary, condition):
        """Return a key-value pair in dictionary if condition matched."""
        return {k: v for (k, v) in dictionary.items() if condition(k)}

    def _check_list(check_list, cond):
        """Return filter function for cond."""
        def _check_against_list(key):
            """Return true if list exists and condition passes."""
            return cond(check_list, key) if check_list is not None else True

        return _check_against_list

    linter_functions = _keyvalue_pair_if(
        linter_functions, _check_list(whitelist, lambda l, k: k in l))
    linter_functions = _keyvalue_pair_if(
        linter_functions, _check_list(blacklist, lambda l, k: k not in l))

    linter_errors = []
    for (code, function) in linter_functions.items():
        errors = function(contents_lines, abstract_syntax_tree, **kwargs)
        for error in errors:
            linter_errors.append((code, error))

    return linter_errors
    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_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)))
Example #12
0
 def test_arguments_depth(self):
     """Test arguments to a function call have depth."""
     tree = ast.parse("function_call (ARGUMENT)")
     listener = MagicMock()
     wrapper = _ast_args_to_kwargs_wrapper(listener)
     ast_visitor.recurse(tree, word=wrapper)
     self.assertThat(listener.call_args_list[-1][1].items(),
                     Contains(("depth", 2)))
Example #13
0
 def test_body_depth(self):
     """Test node body has depth."""
     tree = ast.parse("function_call (ARGUMENT)")
     listener = MagicMock()
     wrapper = _ast_args_to_kwargs_wrapper(listener)
     ast_visitor.recurse(tree, function_call=wrapper)
     self.assertThat(listener.call_args_list[-1][1].items(),
                     Contains(("depth", 1)))
Example #14
0
    def test_suppress_extraneous_parens(self):
        """Convert unquoted parens in function arguments to CompoundLiteral."""
        parse_result = ast.parse("f ( ( ABC ) )")
        arguments = parse_result.statements[0].arguments

        self.assertEqual(arguments[0].type, WordType.CompoundLiteral)
        self.assertEqual(arguments[1].type, WordType.Variable)
        self.assertEqual(arguments[2].type, WordType.CompoundLiteral)
 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)))
Example #17
0
 def test_visit(self, node_type, keyword, script):
     """Visit a node."""
     tree = ast.parse(script)
     listener = MagicMock()
     wrapper = _ast_args_to_kwargs_wrapper(listener)
     keywords = {keyword: wrapper}
     ast_visitor.recurse(tree, **keywords)
     self.assertThat(listener.call_args_list[-1][1].items(),
                     Contains(("name", node_type)))
    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_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_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_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_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_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_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_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_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)))
Example #31
0
    def test_parse_multi_multilines(self):
        """Parse a multiple multiline strings from arguments..

        There should only be two arguments to the passed function and their
        type should be string
        """
        multiline_string = "\"MULTI\nLINE\nSTRING\""
        script_contents = "f ({0} {1})".format(multiline_string,
                                               multiline_string)
        parse_result = ast.parse(script_contents)
        arguments = parse_result.statements[0].arguments
        self.assertEqual(len(arguments), 2)
        self.assertEqual(arguments[0].type, WordType.String)
        self.assertEqual(arguments[0].contents, multiline_string)
        self.assertEqual(arguments[1].type, WordType.String)
        self.assertEqual(arguments[1].contents, multiline_string)
Example #32
0
 def test_if_block_in_function(self):
     """Check if block detected inside of function call."""
     script = """
     function (my_function FOO)\n
     \n
         if (FOO)\n
     \n
             message (BAR)\n
     \n
         endif (FOO)\n
     \n
         message (FOO)\n
     endfunction ()\n
     """
     body = ast.parse(script)
     function_definition = body.statements[0]
     self.assertTrue(isinstance(function_definition.body[0], ast.IfBlock))
Example #33
0
def do_print(filename):
    """Print the AST of filename."""
    with open(filename) as cmake_file:
        body = ast.parse(cmake_file.read())

        word_print = _print_details(
            lambda n: "{0} {1}".format(n.type, n.contents))
        ast_visitor.recurse(body,
                            while_stmnt=_print_details(),
                            foreach=_print_details(),
                            function_def=_print_details(),
                            macro_def=_print_details(),
                            if_block=_print_details(),
                            if_stmnt=_print_details(),
                            elseif_stmnt=_print_details(),
                            else_stmnt=_print_details(),
                            function_call=_print_details(lambda n: n.name),
                            word=word_print)
Example #34
0
def do_print(filename):
    """Print the AST of filename."""
    with open(filename) as cmake_file:
        body = ast.parse(cmake_file.read())

        word_print = _print_details(lambda n: "{0} {1}".format(n.type,
                                                               n.contents))
        ast_visitor.recurse(body,
                            while_stmnt=_print_details(),
                            foreach=_print_details(),
                            function_def=_print_details(),
                            macro_def=_print_details(),
                            if_block=_print_details(),
                            if_stmnt=_print_details(),
                            elseif_stmnt=_print_details(),
                            else_stmnt=_print_details(),
                            function_call=_print_details(lambda n: n.name),
                            word=word_print)
def lint(contents,
         whitelist=None,
         blacklist=None,
         **kwargs):
    r"""Actually lints some file contents.

    Contents should be a raw string with \n. whitelist is a list of checks
    to only perform, blacklist is list of checks to never perform.
    """
    abstract_syntax_tree = ast.parse(contents)
    contents_lines = contents.splitlines(True)
    linter_functions = LINTER_FUNCTIONS

    def _keyvalue_pair_if(dictionary, condition):
        """Return a key-value pair in dictionary if condition matched."""
        return {
            k: v for (k, v) in dictionary.items() if condition(k)
        }

    def _check_list(check_list, cond):
        """Return filter function for cond."""
        def _check_against_list(key):
            """Return true if list exists and condition passes."""
            return cond(check_list, key) if check_list is not None else True

        return _check_against_list

    linter_functions = _keyvalue_pair_if(linter_functions,
                                         _check_list(whitelist,
                                                     lambda l, k: k in l))
    linter_functions = _keyvalue_pair_if(linter_functions,
                                         _check_list(blacklist,
                                                     lambda l, k: k not in l))

    linter_errors = []
    for (code, function) in linter_functions.items():
        errors = function(contents_lines,
                          abstract_syntax_tree,
                          **kwargs)
        for error in errors:
            linter_errors.append((code, error))

    return linter_errors
Example #36
0
 def test_parse_for_col(self, col, statement):
     """Parse for column number."""
     script = " " * (col - 1) + statement
     parse_result = ast.parse(script)
     self.assertEqual(parse_result.statements[0].col, col)
Example #37
0
 def test_macro_footer_name(self):
     """Parse for macro footer, check if has name endmacro."""
     body = ast.parse(self.macro_definition)
     self.assertEqual(body.statements[0].footer.name, "endmacro")
Example #38
0
 def test_macro_body(self):
     """Check that the macro body is a FunctionCall with name message."""
     body = ast.parse(self.macro_definition)
     self.assertEqual(body.statements[0].body[0].name, "message")
Example #39
0
import os
import os.path
import sys
import subprocess
from glob import glob
from cmakeast import ast as cmakeast

os.chdir(os.path.dirname(sys.argv[0]))
os.chdir('..')

ctests = []
test_decs = ['add_unittest', 'add_fulltest']

with open('test/unit/CMakeLists.txt', 'r') as f:
	ast = cmakeast.parse(f.read())

for s in ast.statements:
	if isinstance(s, cmakeast.FunctionCall):
		if s.name in test_decs:
			args = list(map(lambda x: x.contents, s.arguments))
			suit = args[0]
			tests = args[1:]
			for t in tests:
				ctests.append(suit + '_' + t)

os.chdir('build')

uttests = []
for suit in glob('test/unit/ut-*'):
	suitname = suit.split('/ut-')[1]
Example #40
0
 def test_parse_for_if_statement(self):
     """Parse for IfStatement."""
     body = ast.parse(self.if_else_if_block)
     self.assertTrue(isinstance(body.statements[0].if_statement,
                                ast.IfStatement))
Example #41
0
 def test_else_statement_has_body(self):
     """Parse for ElseStatement, first element should be FunctionCall."""
     body = ast.parse(self.if_else_if_block)
     else_statement = body.statements[0].else_statement
     self.assertTrue(isinstance(else_statement.body[0], ast.FunctionCall))
     self.assertEqual(else_statement.body[0].arguments[0].contents, "ELSE")
Example #42
0
 def test_if_statement_has_body(self):
     """Parse for IfStatement body first element should be FunctionCall."""
     body = ast.parse(self.if_else_if_block)
     if_statement = body.statements[0].if_statement
     self.assertTrue(isinstance(if_statement.body[0], ast.FunctionCall))
     self.assertEqual(if_statement.body[0].arguments[0].contents, "IF")
Example #43
0
 def test_elseif_has_header(self):
     """Parse for ElseIfStatement header - should be a FunctionCall."""
     body = ast.parse(self.if_else_if_block)
     elseif_statement = body.statements[0].elseif_statements[0]
     self.assertTrue(isinstance(elseif_statement.header, ast.FunctionCall))
Example #44
0
 def test_parse_for_endif_footer(self):
     """Parse for footer (endif)."""
     body = ast.parse(self.if_else_if_block)
     self.assertTrue(isinstance(body.statements[0].footer,
                                ast.FunctionCall))
     self.assertEqual(body.statements[0].footer.name, "endif")
Example #45
0
 def test_parse_for_line(self, line, statement):
     """Parse for line numbers."""
     script = "\n" * (line - 1) + statement
     parse_result = ast.parse(script)
     self.assertEqual(parse_result.statements[0].line, line)
 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)