Sat, 23 Feb 2019 10:08:14 +0100
Upgraded the embedded Radon library to version 3.0.1.
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
1 | '''This module contains the ComplexityVisitor class which is where all the |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
2 | analysis concerning Cyclomatic Complexity is done. There is also the class |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
3 | HalsteadVisitor, that counts Halstead metrics.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
4 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
5 | import ast |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
6 | import operator |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
7 | import collections |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
8 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
9 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
10 | # Helper functions to use in combination with map() |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
11 | GET_COMPLEXITY = operator.attrgetter('complexity') |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
12 | GET_REAL_COMPLEXITY = operator.attrgetter('real_complexity') |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
13 | NAMES_GETTER = operator.attrgetter('name', 'asname') |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
14 | GET_ENDLINE = operator.attrgetter('endline') |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
15 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
16 | BaseFunc = collections.namedtuple('Function', ['name', 'lineno', 'col_offset', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
17 | 'endline', 'is_method', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
18 | 'classname', 'closures', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
19 | 'complexity']) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
20 | BaseClass = collections.namedtuple('Class', ['name', 'lineno', 'col_offset', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
21 | 'endline', 'methods', |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
22 | 'inner_classes', |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
23 | 'real_complexity']) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
24 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
25 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
26 | def code2ast(source): |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
27 | '''Convert a string object into an AST object. |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
28 | |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
29 | This function is retained for backwards compatibility, but it no longer |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
30 | attemps any conversions. It's equivalent to a call to ``ast.parse``. |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
31 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
32 | return ast.parse(source) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
33 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
34 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
35 | class Function(BaseFunc): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
36 | '''Object represeting a function block.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
37 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
38 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
39 | def letter(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
40 | '''The letter representing the function. It is `M` if the function is |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
41 | actually a method, `F` otherwise. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
42 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
43 | return 'M' if self.is_method else 'F' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
44 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
45 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
46 | def fullname(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
47 | '''The full name of the function. If it is a method, then the full name |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
48 | is: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
49 | {class name}.{method name} |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
50 | Otherwise it is just the function name. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
51 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
52 | if self.classname is None: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
53 | return self.name |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
54 | return '{0}.{1}'.format(self.classname, self.name) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
55 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
56 | def __str__(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
57 | '''String representation of a function block.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
58 | return '{0} {1}:{2}->{3} {4} - {5}'.format(self.letter, self.lineno, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
59 | self.col_offset, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
60 | self.endline, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
61 | self.fullname, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
62 | self.complexity) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
63 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
64 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
65 | class Class(BaseClass): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
66 | '''Object representing a class block.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
67 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
68 | letter = 'C' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
69 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
70 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
71 | def fullname(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
72 | '''The full name of the class. It is just its name. This attribute |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
73 | exists for consistency (see :data:`Function.fullname`). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
74 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
75 | return self.name |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
76 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
77 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
78 | def complexity(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
79 | '''The average complexity of the class. It corresponds to the average |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
80 | complexity of its methods plus one. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
81 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
82 | if not self.methods: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
83 | return self.real_complexity |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
84 | methods = len(self.methods) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
85 | return int(self.real_complexity / float(methods)) + (methods > 1) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
86 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
87 | def __str__(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
88 | '''String representation of a class block.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
89 | return '{0} {1}:{2}->{3} {4} - {5}'.format(self.letter, self.lineno, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
90 | self.col_offset, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
91 | self.endline, self.name, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
92 | self.complexity) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
93 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
94 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
95 | class CodeVisitor(ast.NodeVisitor): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
96 | '''Base class for every NodeVisitors in `radon.visitors`. It implements a |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
97 | couple utility class methods and a static method. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
98 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
99 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
100 | @staticmethod |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
101 | def get_name(obj): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
102 | '''Shorthand for ``obj.__class__.__name__``.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
103 | return obj.__class__.__name__ |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
104 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
105 | @classmethod |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
106 | def from_code(cls, code, **kwargs): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
107 | '''Instanciate the class from source code (string object). The |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
108 | `**kwargs` are directly passed to the `ast.NodeVisitor` constructor. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
109 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
110 | return cls.from_ast(code2ast(code), **kwargs) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
111 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
112 | @classmethod |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
113 | def from_ast(cls, ast_node, **kwargs): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
114 | '''Instantiate the class from an AST node. The `**kwargs` are |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
115 | directly passed to the `ast.NodeVisitor` constructor. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
116 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
117 | visitor = cls(**kwargs) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
118 | visitor.visit(ast_node) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
119 | return visitor |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
120 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
121 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
122 | class ComplexityVisitor(CodeVisitor): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
123 | '''A visitor that keeps track of the cyclomatic complexity of |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
124 | the elements. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
125 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
126 | :param to_method: If True, every function is treated as a method. In this |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
127 | case the *classname* parameter is used as class name. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
128 | :param classname: Name of parent class. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
129 | :param off: If True, the starting value for the complexity is set to 1, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
130 | otherwise to 0. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
131 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
132 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
133 | def __init__(self, to_method=False, classname=None, off=True, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
134 | no_assert=False): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
135 | self.off = off |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
136 | self.complexity = 1 if off else 0 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
137 | self.functions = [] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
138 | self.classes = [] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
139 | self.to_method = to_method |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
140 | self.classname = classname |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
141 | self.no_assert = no_assert |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
142 | self._max_line = float('-inf') |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
143 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
144 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
145 | def functions_complexity(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
146 | '''The total complexity from all functions (i.e. the total number of |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
147 | decision points + 1). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
148 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
149 | This is *not* the sum of all the complexity from the functions. Rather, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
150 | it's the complexity of the code *inside* all the functions. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
151 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
152 | return sum(map(GET_COMPLEXITY, self.functions)) - len(self.functions) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
153 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
154 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
155 | def classes_complexity(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
156 | '''The total complexity from all classes (i.e. the total number of |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
157 | decision points + 1). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
158 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
159 | return sum(map(GET_REAL_COMPLEXITY, self.classes)) - len(self.classes) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
160 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
161 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
162 | def total_complexity(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
163 | '''The total complexity. Computed adding up the visitor complexity, the |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
164 | functions complexity, and the classes complexity. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
165 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
166 | return (self.complexity + self.functions_complexity + |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
167 | self.classes_complexity + (not self.off)) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
168 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
169 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
170 | def blocks(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
171 | '''All the blocks visited. These include: all the functions, the |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
172 | classes and their methods. The returned list is not sorted. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
173 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
174 | blocks = [] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
175 | blocks.extend(self.functions) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
176 | for cls in self.classes: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
177 | blocks.append(cls) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
178 | blocks.extend(cls.methods) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
179 | return blocks |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
180 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
181 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
182 | def max_line(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
183 | '''The maximum line number among the analyzed lines.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
184 | return self._max_line |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
185 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
186 | @max_line.setter |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
187 | def max_line(self, value): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
188 | '''The maximum line number among the analyzed lines.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
189 | if value > self._max_line: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
190 | self._max_line = value |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
191 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
192 | def generic_visit(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
193 | '''Main entry point for the visitor.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
194 | # Get the name of the class |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
195 | name = self.get_name(node) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
196 | # Check for a lineno attribute |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
197 | if hasattr(node, 'lineno'): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
198 | self.max_line = node.lineno |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
199 | # The Try/Except block is counted as the number of handlers |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
200 | # plus the `else` block. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
201 | # In Python 3.3 the TryExcept and TryFinally nodes have been merged |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
202 | # into a single node: Try |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
203 | if name in ('Try', 'TryExcept'): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
204 | self.complexity += len(node.handlers) + len(node.orelse) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
205 | elif name == 'BoolOp': |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
206 | self.complexity += len(node.values) - 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
207 | # Ifs, with and assert statements count all as 1. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
208 | # Note: Lambda functions are not counted anymore, see #68 |
61
f7c284ce1e18
Upgraded the embedded Radon library to version 3.0.1.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
55
diff
changeset
|
209 | elif name in ('If', 'IfExp'): |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
210 | self.complexity += 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
211 | # The For and While blocks count as 1 plus the `else` block. |
20
2677fbceea32
Patched the radon files to support Python 3.5 'async def'.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
1
diff
changeset
|
212 | elif name in ('For', 'While', 'AsyncFor'): |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
213 | self.complexity += bool(node.orelse) + 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
214 | # List, set, dict comprehensions and generator exps count as 1 plus |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
215 | # the `if` statement. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
216 | elif name == 'comprehension': |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
217 | self.complexity += len(node.ifs) + 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
218 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
219 | super(ComplexityVisitor, self).generic_visit(node) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
220 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
221 | def visit_Assert(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
222 | '''When visiting `assert` statements, the complexity is increased only |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
223 | if the `no_assert` attribute is `False`. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
224 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
225 | self.complexity += not self.no_assert |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
226 | |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
227 | def visit_AsyncFunctionDef(self, node): |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
228 | '''Async function definition is the same thing as the synchronous |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
229 | one. |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
230 | ''' |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
231 | self.visit_FunctionDef(node) |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
232 | |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
233 | def visit_FunctionDef(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
234 | '''When visiting functions a new visitor is created to recursively |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
235 | analyze the function's body. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
236 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
237 | # The complexity of a function is computed taking into account |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
238 | # the following factors: number of decorators, the complexity |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
239 | # the function's body and the number of closures (which count |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
240 | # double). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
241 | closures = [] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
242 | body_complexity = 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
243 | for child in node.body: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
244 | visitor = ComplexityVisitor(off=False, no_assert=self.no_assert) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
245 | visitor.visit(child) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
246 | closures.extend(visitor.functions) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
247 | # Add general complexity but not closures' complexity, see #68 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
248 | body_complexity += visitor.complexity |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
249 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
250 | func = Function(node.name, node.lineno, node.col_offset, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
251 | max(node.lineno, visitor.max_line), self.to_method, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
252 | self.classname, closures, body_complexity) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
253 | self.functions.append(func) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
254 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
255 | def visit_ClassDef(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
256 | '''When visiting classes a new visitor is created to recursively |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
257 | analyze the class' body and methods. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
258 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
259 | # The complexity of a class is computed taking into account |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
260 | # the following factors: number of decorators and the complexity |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
261 | # of the class' body (which is the sum of all the complexities). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
262 | methods = [] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
263 | # According to Cyclomatic Complexity definition it has to start off |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
264 | # from 1. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
265 | body_complexity = 1 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
266 | classname = node.name |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
267 | visitors_max_lines = [node.lineno] |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
268 | inner_classes = [] |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
269 | for child in node.body: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
270 | visitor = ComplexityVisitor(True, classname, off=False, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
271 | no_assert=self.no_assert) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
272 | visitor.visit(child) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
273 | methods.extend(visitor.functions) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
274 | body_complexity += (visitor.complexity + |
61
f7c284ce1e18
Upgraded the embedded Radon library to version 3.0.1.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
55
diff
changeset
|
275 | visitor.functions_complexity + |
f7c284ce1e18
Upgraded the embedded Radon library to version 3.0.1.
T.Rzepka <Tobias.Rzepka@gmail.com>
parents:
55
diff
changeset
|
276 | len(visitor.functions)) |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
277 | visitors_max_lines.append(visitor.max_line) |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
278 | inner_classes.extend(visitor.classes) |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
279 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
280 | cls = Class(classname, node.lineno, node.col_offset, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
281 | max(visitors_max_lines + list(map(GET_ENDLINE, methods))), |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
282 | methods, inner_classes, body_complexity) |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
283 | self.classes.append(cls) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
284 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
285 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
286 | class HalsteadVisitor(CodeVisitor): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
287 | '''Visitor that keeps track of operators and operands, in order to compute |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
288 | Halstead metrics (see :func:`radon.metrics.h_visit`). |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
289 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
290 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
291 | types = {ast.Num: 'n', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
292 | ast.Name: 'id', |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
293 | ast.Attribute: 'attr'} |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
294 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
295 | def __init__(self, context=None): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
296 | '''*context* is a string used to keep track the analysis' context.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
297 | self.operators_seen = set() |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
298 | self.operands_seen = set() |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
299 | self.operators = 0 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
300 | self.operands = 0 |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
301 | self.context = context |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
302 | |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
303 | # A new visitor is spawned for every scanned function. |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
304 | self.function_visitors = [] |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
305 | |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
306 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
307 | def distinct_operators(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
308 | '''The number of distinct operators.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
309 | return len(self.operators_seen) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
310 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
311 | @property |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
312 | def distinct_operands(self): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
313 | '''The number of distinct operands.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
314 | return len(self.operands_seen) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
315 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
316 | def dispatch(meth): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
317 | '''This decorator does all the hard work needed for every node. |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
318 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
319 | The decorated method must return a tuple of 4 elements: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
320 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
321 | * the number of operators |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
322 | * the number of operands |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
323 | * the operators seen (a sequence) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
324 | * the operands seen (a sequence) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
325 | ''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
326 | def aux(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
327 | '''Actual function that updates the stats.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
328 | results = meth(self, node) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
329 | self.operators += results[0] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
330 | self.operands += results[1] |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
331 | self.operators_seen.update(results[2]) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
332 | for operand in results[3]: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
333 | new_operand = getattr(operand, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
334 | self.types.get(type(operand), ''), |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
335 | operand) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
336 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
337 | self.operands_seen.add((self.context, new_operand)) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
338 | # Now dispatch to children |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
339 | super(HalsteadVisitor, self).generic_visit(node) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
340 | return aux |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
341 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
342 | @dispatch |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
343 | def visit_BinOp(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
344 | '''A binary operator.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
345 | return (1, 2, (self.get_name(node.op),), (node.left, node.right)) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
346 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
347 | @dispatch |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
348 | def visit_UnaryOp(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
349 | '''A unary operator.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
350 | return (1, 1, (self.get_name(node.op),), (node.operand,)) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
351 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
352 | @dispatch |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
353 | def visit_BoolOp(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
354 | '''A boolean operator.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
355 | return (1, len(node.values), (self.get_name(node.op),), node.values) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
356 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
357 | @dispatch |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
358 | def visit_AugAssign(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
359 | '''An augmented assign (contains an operator).''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
360 | return (1, 2, (self.get_name(node.op),), (node.target, node.value)) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
361 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
362 | @dispatch |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
363 | def visit_Compare(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
364 | '''A comparison.''' |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
365 | return (len(node.ops), len(node.comparators) + 1, |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
366 | map(self.get_name, node.ops), node.comparators + [node.left]) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
367 | |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
368 | def visit_FunctionDef(self, node): |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
369 | '''When visiting functions, another visitor is created to recursively |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
370 | analyze the function's body. We also track information on the function |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
371 | itself. |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
372 | ''' |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
373 | func_visitor = HalsteadVisitor(context=node.name) |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
374 | |
1
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
375 | for child in node.body: |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
376 | visitor = HalsteadVisitor.from_ast(child, context=node.name) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
377 | self.operators += visitor.operators |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
378 | self.operands += visitor.operands |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
379 | self.operators_seen.update(visitor.operators_seen) |
b6cced815847
Added the radon files.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
diff
changeset
|
380 | self.operands_seen.update(visitor.operands_seen) |
20
2677fbceea32
Patched the radon files to support Python 3.5 'async def'.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
1
diff
changeset
|
381 | |
55
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
382 | func_visitor.operators += visitor.operators |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
383 | func_visitor.operands += visitor.operands |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
384 | func_visitor.operators_seen.update(visitor.operators_seen) |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
385 | func_visitor.operands_seen.update(visitor.operands_seen) |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
386 | |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
387 | # Save the visited function visitor for later reference. |
755bc8e1485a
Upgraded the embedded Radon library to version 2.4.0.
Detlev Offenbach <detlev@die-offenbachs.de>
parents:
20
diff
changeset
|
388 | self.function_visitors.append(func_visitor) |