slither.utils.code_complexity

 1# Function computing the code complexity
 2from typing import TYPE_CHECKING, List
 3
 4if TYPE_CHECKING:
 5    from slither.core.declarations import Function
 6    from slither.core.cfg.node import Node
 7
 8
 9def compute_number_edges(function: "Function") -> int:
10    """
11    Compute the number of edges of the CFG
12    Args:
13        function (core.declarations.function.Function)
14    Returns:
15        int
16    """
17    n = 0
18    for node in function.nodes:
19        n += len(node.sons)
20    return n
21
22
23def compute_strongly_connected_components(function: "Function") -> List[List["Node"]]:
24    """
25        Compute strongly connected components
26        Based on Kosaraju algo
27        Implem follows wikipedia algo: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm#The_algorithm
28    Args:
29        function (core.declarations.function.Function)
30    Returns:
31        list(list(nodes))
32    """
33    visited = {n: False for n in function.nodes}
34    assigned = {n: False for n in function.nodes}
35    components = []
36    l = []
37
38    def visit(node: "Node") -> None:
39        if not visited[node]:
40            visited[node] = True
41            for son in node.sons:
42                visit(son)
43            l.append(node)
44
45    for n in function.nodes:
46        visit(n)
47
48    def assign(node: "Node", root: List["Node"]) -> None:
49        if not assigned[node]:
50            assigned[node] = True
51            root.append(node)
52            for father in node.fathers:
53                assign(father, root)
54
55    for n in reversed(l):
56        component: List["Node"] = []
57        assign(n, component)
58        if component:
59            components.append(component)
60
61    return components
62
63
64def compute_cyclomatic_complexity(function: "Function") -> int:
65    """
66    Compute the cyclomatic complexity of a function
67    Args:
68        function (core.declarations.function.Function)
69    Returns:
70        int
71    """
72    # from https://en.wikipedia.org/wiki/Cyclomatic_complexity
73    # M = E - N + 2P
74    # where M is the complexity
75    # E number of edges
76    # N number of nodes
77    # P number of connected components (always 1 for a function)
78
79    E = compute_number_edges(function)
80    N = len(function.nodes)
81    P = 1
82    return E - N + 2 * P
def compute_number_edges(function: slither.core.declarations.function.Function) -> int:
10def compute_number_edges(function: "Function") -> int:
11    """
12    Compute the number of edges of the CFG
13    Args:
14        function (core.declarations.function.Function)
15    Returns:
16        int
17    """
18    n = 0
19    for node in function.nodes:
20        n += len(node.sons)
21    return n

Compute the number of edges of the CFG Args: function (core.declarations.function.Function) Returns: int

def compute_strongly_connected_components( function: slither.core.declarations.function.Function) -> list[list[slither.core.cfg.node.Node]]:
24def compute_strongly_connected_components(function: "Function") -> List[List["Node"]]:
25    """
26        Compute strongly connected components
27        Based on Kosaraju algo
28        Implem follows wikipedia algo: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm#The_algorithm
29    Args:
30        function (core.declarations.function.Function)
31    Returns:
32        list(list(nodes))
33    """
34    visited = {n: False for n in function.nodes}
35    assigned = {n: False for n in function.nodes}
36    components = []
37    l = []
38
39    def visit(node: "Node") -> None:
40        if not visited[node]:
41            visited[node] = True
42            for son in node.sons:
43                visit(son)
44            l.append(node)
45
46    for n in function.nodes:
47        visit(n)
48
49    def assign(node: "Node", root: List["Node"]) -> None:
50        if not assigned[node]:
51            assigned[node] = True
52            root.append(node)
53            for father in node.fathers:
54                assign(father, root)
55
56    for n in reversed(l):
57        component: List["Node"] = []
58        assign(n, component)
59        if component:
60            components.append(component)
61
62    return components

Compute strongly connected components Based on Kosaraju algo Implem follows wikipedia algo: https://en.wikipedia.org/wiki/Kosaraju%27s_algorithm#The_algorithm Args: function (core.declarations.function.Function) Returns: list(list(nodes))

def compute_cyclomatic_complexity(function: slither.core.declarations.function.Function) -> int:
65def compute_cyclomatic_complexity(function: "Function") -> int:
66    """
67    Compute the cyclomatic complexity of a function
68    Args:
69        function (core.declarations.function.Function)
70    Returns:
71        int
72    """
73    # from https://en.wikipedia.org/wiki/Cyclomatic_complexity
74    # M = E - N + 2P
75    # where M is the complexity
76    # E number of edges
77    # N number of nodes
78    # P number of connected components (always 1 for a function)
79
80    E = compute_number_edges(function)
81    N = len(function.nodes)
82    P = 1
83    return E - N + 2 * P

Compute the cyclomatic complexity of a function Args: function (core.declarations.function.Function) Returns: int