Completed
Pull Request — master (#1)
by Valentin
02:24
created

get_id()   A

Complexity

Conditions 4

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
cc 4
dl 0
loc 5
rs 9.2
1
import sys
2
import ast
3
4
5
def add_imports(node):
6
    """Provide context of imports Module"""
7
    return ImportTransformer().visit(node)
8
9
10
def is_void_function(fun):
11
    finder = ReturnFinder()
12
    finder.visit(fun)
13
    return not finder.returns
14
15
if sys.version_info[0] >= 3:
16
    def get_id(var):
17
        if isinstance(var, ast.alias):
18
            return var.name
19
        elif isinstance(var, ast.Name):
20
            return var.id
21
        elif isinstance(var, ast.arg):
22
            return var.arg
23
else:
24
    def get_id(var):
25
        if isinstance(var, ast.alias):
26
            return var.name
27
        elif isinstance(var, ast.Name):
28
            return var.id
29
30
31
class ReturnFinder(ast.NodeVisitor):
32
    returns = False
33
34
    def visit_Return(self, node):
35
        self.returns = True
36
37
38
class FunctionTransformer(ast.NodeTransformer):
39
    """Tracks defined functions in scope"""
40
    def visit_Module(self, node):
41
        node.defined_functions = []
42
        self.generic_visit(node)
43
        return node
44
45
    def visit_FunctionDef(self, node):
46
        node.defined_functions = []
47
        node.scopes[-2].defined_functions.append(node)
48
        self.generic_visit(node)
49
        return node
50
51
    def visit_ImportFrom(self, node):
52
        for name in node.names:
53
            node.scopes[-1].defined_functions.append(name)
54
        return node
55
56
57
class CalledWithTransformer(ast.NodeTransformer):
58
    """
59
    Tracks whether variables or functions get
60
    used as arguments of other functions
61
    """
62
    def visit_Assign(self, node):
63
        for target in node.targets:
64
            target.called_with = []
65
        return node
66
67
    def visit_FunctionDef(self, node):
68
        node.called_with = []
69
        self.generic_visit(node)
70
        return node
71
72
    def visit_Call(self, node):
73
        for arg in node.args:
74
            if isinstance(arg, ast.Name):
75
                var = node.scopes.find(arg.id)
76
                var.called_with.append(node)
77
        self.generic_visit(node)
78
        return node
79
80
81
class AttributeCallTransformer(ast.NodeTransformer):
82
    """Tracks attribute function calls on variables"""
83
    def visit_Assign(self, node):
84
        for target in node.targets:
85
            target.calls = []
86
        return node
87
88
    def visit_Call(self, node):
89
        if isinstance(node.func, ast.Attribute):
90
            var = node.scopes.find(node.func.value.id)
91
            var.calls.append(node)
92
        return node
93
94
95
class ImportTransformer(ast.NodeTransformer):
96
    """Adds imports to scope block"""
97
    def visit_ImportFrom(self, node):
98
        for name in node.names:
99
            name.imported_from = node
100
            name.scopes[-1].imports.append(name)
101
        return node
102
103
    def visit_Module(self, node):
104
        node.imports = []
105
        self.generic_visit(node)
106
        return node
107