Coverage for metrics/halstead/common.py: 100%

1"""Shared Halstead collection logic for all languages."""

2

3 from __future__ import annotations

4

5 from common import compute_halstead

6 from functools import partial

7 from models import HalsteadMetrics

8

9

10 def _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.

20

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

26

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

40

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

48

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 )

59

60

61 def 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)

77

78

79 def 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 )