예제 #1
0
    def test_reference_reachability_with_referenced_all_params(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_PARAMS)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'a:': False,
            'l:': False,
            'a:0': False,
            'a:000': False,

            'a:param': False,

            'a:param1': False,
            'a:param2': False,

            'a:param_var': False,

            'a:param_with_range': False,
            'a:firstline': False,
            'a:lastline': False,
        }

        self.assertVariablesUndeclared(expected_variables_unused,
                                       scope_plugin,
                                       ast)
예제 #2
0
    def test_reference_reachability_with_referenced_all(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'g:explicit_global_var': False,
            'b:buffer_local_var': False,
            'w:window_local_var': False,
            't:tab_local_var': False,
            's:script_local_var': False,
            'implicit_global_var': False,
            'g:implicit_global_var': False,
            '$ENV_VAR': False,
            '@"': False,
            '&opt_var': False,
            'v:count': False,
            'count': False,
            'g:': False,
            'b:': False,
            'w:': False,
            't:': False,
            'v:': False,
            'v:key': False,
            'v:val': False,
            'filter': False,
            'g:dict': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin, ast)
예제 #3
0
    def test_reference_reachability_with_referenced_all(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'g:explicit_global_var': False,
            'b:buffer_local_var': False,
            'w:window_local_var': False,
            't:tab_local_var': False,
            's:script_local_var': False,
            'implicit_global_var': False,
            'g:implicit_global_var': False,
            '$ENV_VAR': False,
            '@"': False,
            '&opt_var': False,
            'v:count': False,
            'count': False,
            'g:': False,
            'b:': False,
            'w:': False,
            't:': False,
            'v:': False,
            'v:key': False,
            'v:val': False,
            'filter': False,
            'g:dict': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin,
                                       ast)
예제 #4
0
    def assertProcessing(self, file_path, expected_scope_tree):
        parser = Parser()
        ast = parser.parse_file(file_path)

        plugin = ScopePlugin()
        plugin.process(ast)

        self.assertScopeTree(ast['vint_scope_tree'], expected_scope_tree)
예제 #5
0
    def assertProcessing(self, file_path, expected_scope_tree):
        parser = Parser()
        ast = parser.parse_file(file_path)

        plugin = ScopePlugin()
        plugin.process(ast)

        self.assertScopeTree(ast['vint_scope_tree'], expected_scope_tree)
예제 #6
0
    def test_reference_reachability_with_unreferenced_var(self):
        ast = self.create_ast(Fixtures.UNREFERENCED_VAR)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            's:implicit_global_var': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin, ast)
예제 #7
0
    def test_reference_reachability_with_unanalyzable(self):
        ast = self.create_ast(Fixtures.UNANALYZABLE)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'list_slice': True,
            'dict': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin, ast)
예제 #8
0
    def test_reference_reachability_with_unreferenced_var(self):
        ast = self.create_ast(Fixtures.UNREFERENCED_VAR)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            's:implicit_global_var': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin,
                                       ast)
예제 #9
0
    def test_reference_reachability_with_referenced_all_funcs_in_func(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_FUNC_IN_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'g:ExplicitGlobalFunc': False,
            'ImplicitGlobalFunc': False,
            's:ExplicitScriptLocalFunc': False,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin, ast)
예제 #10
0
    def test_reference_reachability_with_unanalyzable(self):
        ast = self.create_ast(Fixtures.UNANALYZABLE)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'list_slice': True,
            'dict': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin,
                                       ast)
예제 #11
0
    def test_declarative_identifiers_referenced_with_referenced_all_func(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'g:ExplicitGlobalFunc': False,
            's:ScriptLocalFunc': False,
            'ImplicitGlobalFunc': False,
        }

        self.assertVariablesUnused(expected_variables_unused, scope_plugin,
                                   ast)
예제 #12
0
    def test_declarative_identifiers_referenced_with_referenced_all_func(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'g:ExplicitGlobalFunc': False,
            's:ScriptLocalFunc': False,
            'ImplicitGlobalFunc': False,
        }

        self.assertVariablesUnused(expected_variables_unused,
                                   scope_plugin,
                                   ast)
예제 #13
0
    def test_reference_reachability_with_referenced_all_funcs_in_func(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_FUNC_IN_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'g:ExplicitGlobalFunc': False,
            'ImplicitGlobalFunc': False,
            's:ExplicitScriptLocalFunc': False,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin,
                                       ast)
예제 #14
0
    def test_declarative_identifiers_referenced_with_unreferenced_func_in_func(
            self):
        ast = self.create_ast(Fixtures.UNREFERENCED_FUNC_IN_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'FuncContext': True,
            'g:ExplicitGlobalFunc': True,
            'ImplicitGlobalFunc': True,
            's:ExplicitScriptLocalFunc': True,
        }

        self.assertVariablesUnused(expected_variables_unused, scope_plugin,
                                   ast)
    def _is_declared_identifier(self, node):
        identifier_name = node['value']

        # Ignore definition identifiers.
        # See ScopePlugin documents to understand what is definition identifier.
        is_definition_identifier = node[ScopePlugin.DEFINITION_IDENTIFIER_FLAG_KEY]
        if is_definition_identifier:
            return True

        # No prefix identifier is already declared if the identifier is built-in.
        is_builtin_identifier = node[ScopePlugin.BUILTIN_IDENTIFIER_FLAG_KEY]
        if is_builtin_identifier:
            return True

        # Ignore special identifiers such as '...' and 'a:000'
        if self._is_ignored_identifier(identifier_name):
            return True

        scope = node[ScopePlugin.SCOPE_KEY]
        declaration_scope = ScopePlugin.detect_scope(identifier_name, scope)

        traceability_map = ProhibitUsingUndeclaredVariable.identifier_tracability_map
        is_traceable_identifier = traceability_map[declaration_scope]
        if not is_traceable_identifier:
            # Optimistic decision. Expect the identifier is declared by other
            # file.
            return True

        while scope is not None:
            if identifier_name in scope['variables']:
                return True

            scope = scope['parent_scope']

        return False
예제 #16
0
    def test_declarative_identifiers_referenced_with_unreferenced_func_in_func(self):
        ast = self.create_ast(Fixtures.UNREFERENCED_FUNC_IN_FUNC)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'FuncContext': True,
            'g:ExplicitGlobalFunc': True,
            'ImplicitGlobalFunc': True,
            's:ExplicitScriptLocalFunc': True,
        }

        self.assertVariablesUnused(expected_variables_unused,
                                   scope_plugin,
                                   ast)
예제 #17
0
    def test_reference_reachability_with_unreferenced_params(self):
        ast = self.create_ast(Fixtures.UNREFERENCED_PARAMS)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'param': True,
            'a:1': True,
            'a:firstline': True,
            'a:lastline': True,
            'a:18': True,
            'a:19': True,
            'a:20': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin, ast)
예제 #18
0
    def test_process_with_builtin(self):
        parser = Parser()
        ast = parser.parse_file(Fixtures['BUILTIN'])

        plugin = ScopePlugin()
        plugin.process(ast)

        expected_builtin_flags = {
            'abs': True,
            'sin': True,
            'strlen': True,
            'g:MyFunction': False,
        }

        # Keep identifier name that traverser visited
        identifiers_checking_map = {
            'abs': False,
            'sin': False,
            'strlen': False,
            'g:MyFunction': False,
        }

        def test_identifier(node):
            if NodeType(node['type']) is not NodeType.IDENTIFIER:
                return

            identifier = node

            # We focus to non-definition identifier
            if identifier[ScopePlugin.DEFINITION_IDENTIFIER_FLAG_KEY]:
                return

            identifier_name = identifier['value']
            identifiers_checking_map[identifier_name] = True

            is_builtin_identifier = identifier[
                ScopePlugin.BUILTIN_IDENTIFIER_FLAG_KEY]
            expected_builtin_flag = expected_builtin_flags[identifier_name]

            self.assertEqual(is_builtin_identifier, expected_builtin_flag)

        traverse(ast, on_enter=test_identifier)
        self.assertTrue(all(identifiers_checking_map.values()))
예제 #19
0
    def test_process_with_builtin(self):
        parser = Parser()
        ast = parser.parse_file(Fixtures['BUILTIN'])

        plugin = ScopePlugin()
        plugin.process(ast)

        expected_builtin_flags = {
            'abs': True,
            'sin': True,
            'strlen': True,
            'g:MyFunction': False,
        }

        # Keep identifier name that traverser visited
        identifiers_checking_map = {
            'abs': False,
            'sin': False,
            'strlen': False,
            'g:MyFunction': False,
        }

        def test_identifier(node):
            if NodeType(node['type']) is not NodeType.IDENTIFIER:
                return

            identifier = node

            # We focus to non-definition identifier
            if identifier[ScopePlugin.DEFINITION_IDENTIFIER_FLAG_KEY]:
                return

            identifier_name = identifier['value']
            identifiers_checking_map[identifier_name] = True

            is_builtin_identifier = identifier[ScopePlugin.BUILTIN_IDENTIFIER_FLAG_KEY]
            expected_builtin_flag = expected_builtin_flags[identifier_name]

            self.assertEqual(is_builtin_identifier, expected_builtin_flag)

        traverse(ast, on_enter=test_identifier)
        self.assertTrue(all(identifiers_checking_map.values()))
예제 #20
0
    def test_reference_reachability_with_unreferenced_params(self):
        ast = self.create_ast(Fixtures.UNREFERENCED_PARAMS)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_undeclared = {
            'param': True,
            'a:1': True,
            'a:firstline': True,
            'a:lastline': True,

            'a:18': True,
            'a:19': True,
            'a:20': True,
        }

        self.assertVariablesUndeclared(expected_variables_undeclared,
                                       scope_plugin,
                                       ast)
예제 #21
0
    def test_declarative_identifiers_referenced_with_referenced_all(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'g:explicit_global_var': False,
            'b:buffer_local_var': False,
            'w:window_local_var': False,
            't:tab_local_var': False,
            's:script_local_var': False,
            'implicit_global_var': False,
            '$ENV_VAR': False,
            '@"': False,
            '&opt_var': False,
            'v:count': False,
        }

        self.assertVariablesUnused(expected_variables_unused, scope_plugin,
                                   ast)
예제 #22
0
    def __init__(self, policy_set, config_dict_global):
        self._plugins = {
            'scope': ScopePlugin(),
        }
        self._policy_set = policy_set

        self._config_comment_source = ConfigCommentSource()
        self._config = self._decorate_config(config_dict_global,
                                             self._config_comment_source)

        self._parser = self.build_parser()

        self._listeners_map = {}
예제 #23
0
    def test_declarative_identifiers_referenced_with_referenced_all(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'g:explicit_global_var': False,
            'b:buffer_local_var': False,
            'w:window_local_var': False,
            't:tab_local_var': False,
            's:script_local_var': False,
            'implicit_global_var': False,
            '$ENV_VAR': False,
            '@"': False,
            '&opt_var': False,
            'v:count': False,
        }

        self.assertVariablesUnused(expected_variables_unused,
                                   scope_plugin,
                                   ast)
예제 #24
0
    def test_reference_reachability_with_referenced_all_params(self):
        ast = self.create_ast(Fixtures.REFERENCED_ALL_PARAMS)

        scope_plugin = ScopePlugin()
        scope_plugin.process(ast)

        expected_variables_unused = {
            'a:': False,
            'l:': False,
            'a:0': False,
            'a:000': False,
            'a:param': False,
            'a:param1': False,
            'a:param2': False,
            'a:param_var': False,
            'a:param_with_range': False,
            'a:firstline': False,
            'a:lastline': False,
        }

        self.assertVariablesUndeclared(expected_variables_unused, scope_plugin,
                                       ast)
예제 #25
0
    def _is_declared_identifier(self, node):
        identifier_name = node['value']

        # Ignore definition identifiers.
        # See ScopePlugin documents to understand what is definition identifier.
        is_definition_identifier = node[
            ScopePlugin.DEFINITION_IDENTIFIER_FLAG_KEY]
        if is_definition_identifier:
            return True

        # No prefix identifier is already declared if the identifier is built-in.
        is_builtin_identifier = node[ScopePlugin.BUILTIN_IDENTIFIER_FLAG_KEY]
        if is_builtin_identifier:
            return True

        # Ignore special identifiers such as '...' and 'a:000'
        if self._is_ignored_identifier(identifier_name):
            return True

        scope = node[ScopePlugin.SCOPE_KEY]
        declaration_scope = ScopePlugin.detect_scope(identifier_name, scope)

        traceability_map = ProhibitUsingUndeclaredVariable.identifier_tracability_map
        is_traceable_identifier = traceability_map[declaration_scope]
        if not is_traceable_identifier:
            # Optimistic decision. Expect the identifier is declared by other
            # file.
            return True

        while scope is not None:
            if identifier_name in scope['variables']:
                return True

            scope = scope['parent_scope']

        return False
예제 #26
0
def prettify_node_type(node):
    node['type'] = NodeType(node['type'])


if __name__ == '__main__':
    arg_parser = ArgumentParser(prog='show_ast', description='Show AST')
    arg_parser.add_argument('--enable-neovim',
                            action='store_true',
                            help='Enable Neovim syntax')
    arg_parser.add_argument('files', nargs='*', help='File to parse')
    namespace = vars(arg_parser.parse_args(sys.argv[1:]))

    filepaths = map(Path, namespace['files'])
    enable_neovim = namespace['enable_neovim']

    scope_plugin = ScopePlugin()
    parser = Parser(plugins={'scope': scope_plugin},
                    enable_neovim=enable_neovim)

    for filepath in filepaths:
        ast = parser.parse_file(filepath)
        traverse(ast, on_enter=prettify_node_type)

        print("////////// AST //////////\n")
        pprint(ast)
        print("\n\n")

        print("////////// SCOPE TREE //////////\n")
        pprint(scope_plugin._ref_tester._scope_tree)