debtmap/analyzers/
traits.rs1use anyhow::Result;
4use std::path::Path;
5
6pub trait LanguageAnalyzer: Send + Sync {
8 fn analyze_file(&self, path: &Path, content: &str) -> Result<crate::core::FileMetrics>;
10
11 fn language(&self) -> crate::core::Language;
13
14 fn can_handle(&self, path: &Path) -> bool {
16 crate::core::Language::from_path(path) == self.language()
17 }
18}
19
20pub trait CallGraphAnalyzer: Send + Sync {
22 fn build_call_graph(&self, content: &str, path: &Path) -> Result<CallGraph>;
24
25 fn find_dependencies(&self, function: &str, graph: &CallGraph) -> Vec<String>;
27}
28
29#[derive(Debug, Clone)]
31pub struct CallGraph {
32 pub nodes: Vec<CallNode>,
33 pub edges: Vec<CallEdge>,
34}
35
36#[derive(Debug, Clone)]
37pub struct CallNode {
38 pub name: String,
39 pub file: std::path::PathBuf,
40 pub line: usize,
41}
42
43#[derive(Debug, Clone)]
44pub struct CallEdge {
45 pub from: String,
46 pub to: String,
47 pub call_type: CallType,
48}
49
50#[derive(Debug, Clone)]
51pub enum CallType {
52 Direct,
53 Trait,
54 Generic,
55 Closure,
56}
57
58pub trait TypeTracker: Send + Sync {
60 fn track_type(&mut self, symbol: &str, type_info: TypeInfo);
62
63 fn get_type(&self, symbol: &str) -> Option<&TypeInfo>;
65
66 fn clear(&mut self);
68}
69
70#[derive(Debug, Clone)]
71pub struct TypeInfo {
72 pub name: String,
73 pub kind: TypeKind,
74 pub generic_params: Vec<String>,
75}
76
77#[derive(Debug, Clone)]
78pub enum TypeKind {
79 Struct,
80 Enum,
81 Trait,
82 Function,
83 Primitive,
84 Generic,
85}
86
87pub trait TestDetector: Send + Sync {
89 fn is_test_function(&self, name: &str, attributes: &[String]) -> bool;
91
92 fn is_test_module(&self, path: &Path) -> bool;
94
95 fn extract_test_metadata(&self, content: &str) -> TestMetadata;
97}
98
99#[derive(Debug, Clone, Default)]
100pub struct TestMetadata {
101 pub test_count: usize,
102 pub assertion_count: usize,
103 pub has_setup: bool,
104 pub has_teardown: bool,
105 pub test_frameworks: Vec<String>,
106}
107
108pub trait PurityAnalyzer: Send + Sync {
110 fn is_pure(&self, function: &str, body: &str) -> (bool, f32);
112
113 fn find_side_effects(&self, body: &str) -> Vec<SideEffect>;
115}
116
117#[derive(Debug, Clone)]
118pub struct SideEffect {
119 pub kind: SideEffectKind,
120 pub location: usize,
121 pub description: String,
122}
123
124#[derive(Debug, Clone)]
125pub enum SideEffectKind {
126 IO,
127 Mutation,
128 GlobalState,
129 ExternalCall,
130 Unsafe,
131}