Coverage for metrics / halstead / common.py: 100%
28 statements
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 15:04 -0800
« prev ^ index » next coverage.py v7.13.3, created at 2026-02-08 15:04 -0800
1"""Shared Halstead collection logic for all languages."""
3from __future__ import annotations
5from common import compute_halstead
6from functools import partial
7from models import HalsteadMetrics
10def _collect_halstead_generic(
11 node,
12 operators,
13 operands,
14 comment_types,
15 keyword_operators,
16 operand_types,
17 operator_tokens,
18) -> None:
19 """Recursively classify AST nodes as operators or operands.
21 Language-specific behavior is controlled entirely by the constant sets:
22 *comment_types*, *keyword_operators*, *operand_types*, *operator_tokens*.
23 """
24 if node.type in comment_types:
25 return
27 if node.type in keyword_operators:
28 operators.append(node.type)
29 for child in node.children:
30 _collect_halstead_generic(
31 child,
32 operators,
33 operands,
34 comment_types,
35 keyword_operators,
36 operand_types,
37 operator_tokens,
38 )
39 return
41 if node.child_count == 0:
42 text = node.text.decode()
43 if node.type in operand_types:
44 operands.append(text)
45 elif text in operator_tokens or node.type in operator_tokens:
46 operators.append(text)
47 return
49 for child in node.children:
50 _collect_halstead_generic(
51 child,
52 operators,
53 operands,
54 comment_types,
55 keyword_operators,
56 operand_types,
57 operator_tokens,
58 )
61def compute_halstead_generic(
62 root, comment_types, keyword_operators, operand_types, operator_tokens
63) -> HalsteadMetrics:
64 """Compute Halstead metrics for an AST using the given language token sets."""
65 operators: list[str] = []
66 operands: list[str] = []
67 _collect_halstead_generic(
68 root,
69 operators,
70 operands,
71 comment_types,
72 keyword_operators,
73 operand_types,
74 operator_tokens,
75 )
76 return compute_halstead(operators, operands)
79def make_compute_halstead(
80 comment_types, keyword_operators, operand_types, operator_tokens
81):
82 return partial(
83 compute_halstead_generic,
84 comment_types=comment_types,
85 keyword_operators=keyword_operators,
86 operand_types=operand_types,
87 operator_tokens=operator_tokens,
88 )