Coverage for models.py: 100%

83 statements  

« prev     ^ index     » next       coverage.py v7.13.3, created at 2026-02-08 15:04 -0800

1"""Shared data models for Vibelexity complexity analysis.""" 

2 

3from __future__ import annotations 

4 

5from dataclasses import dataclass, field 

6 

7 

8@dataclass 

9class PatternViolation: 

10 type: str 

11 line: int 

12 description: str 

13 severity: str = "warning" 

14 

15 

16@dataclass 

17class HalsteadMetrics: 

18 n1: int = 0 # distinct operators 

19 n2: int = 0 # distinct operands 

20 N1: int = 0 # total operators 

21 N2: int = 0 # total operands 

22 vocabulary: int = 0 # n = n1 + n2 

23 length: int = 0 # N = N1 + N2 

24 volume: float = 0.0 # V = N * log2(n) 

25 difficulty: float = 0.0 # D = (n1/2) * (N2/n2) 

26 effort: float = 0.0 # E = D * V 

27 time: float = 0.0 # T = E / 18 (seconds) 

28 bugs: float = 0.0 # B = E^(2/3) / 3000 

29 

30 

31@dataclass 

32class FunctionComplexity: 

33 name: str 

34 line: int 

35 complexity: int 

36 halstead: HalsteadMetrics | None = None 

37 npath: int | None = None 

38 dtd: int | None = None 

39 mi: float | None = None 

40 ldi: float | None = None 

41 cyclomatic: int | None = None 

42 type1_hash: str | None = None 

43 type2_hash: str | None = None 

44 func_loc: int = 0 

45 stmt_count: int = 0 

46 

47 

48@dataclass 

49class DuplicateCluster: 

50 dup_type: int # 1 or 2 

51 hash_value: str 

52 members: list[tuple[str, FunctionComplexity]] 

53 

54 

55@dataclass 

56class FileComplexity: 

57 path: str 

58 functions: list[FunctionComplexity] = field(default_factory=list) 

59 loc: int = 0 

60 lloc: int = 0 

61 sloc: int = 0 

62 pattern_violations: list[PatternViolation] = field(default_factory=list) 

63 

64 @property 

65 def total(self) -> int: 

66 return sum(f.complexity for f in self.functions) 

67 

68 

69@dataclass 

70class DeadCodeViolation: 

71 type: str 

72 symbol: str | None 

73 location: str 

74 line: int 

75 confidence: str 

76 

77 

78@dataclass 

79class FunctionDefinition: 

80 name: str 

81 filepath: str 

82 line: int 

83 def_type: str 

84 class_name: str | None = None 

85 params: list[str] = field(default_factory=list) 

86 

87 

88@dataclass 

89class CallEdge: 

90 caller_file: str 

91 caller_function: str 

92 caller_line: int 

93 callee_file: str | None 

94 callee_function: str 

95 callee_line: int | None 

96 call_site_line: int 

97 call_type: str = "local" 

98 receiver_object: str | None = None 

99 

100 

101@dataclass 

102class CallGraph: 

103 functions: dict[tuple[str, str], FunctionDefinition] = field(default_factory=dict) 

104 calls: list[CallEdge] = field(default_factory=list) 

105 reverse_calls: dict[str, list[CallEdge]] = field(default_factory=dict)