Coverage for models.py: 100%
83 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 data models for Vibelexity complexity analysis."""
3from __future__ import annotations
5from dataclasses import dataclass, field
8@dataclass
9class PatternViolation:
10 type: str
11 line: int
12 description: str
13 severity: str = "warning"
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
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
48@dataclass
49class DuplicateCluster:
50 dup_type: int # 1 or 2
51 hash_value: str
52 members: list[tuple[str, FunctionComplexity]]
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)
64 @property
65 def total(self) -> int:
66 return sum(f.complexity for f in self.functions)
69@dataclass
70class DeadCodeViolation:
71 type: str
72 symbol: str | None
73 location: str
74 line: int
75 confidence: str
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)
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
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)