cha_core/plugins/
lazy_class.rs1use crate::{AnalysisContext, Finding, Location, Plugin, Severity, SmellCategory};
2
3pub struct LazyClassAnalyzer {
5 pub max_methods: usize,
6 pub max_lines: usize,
7}
8
9impl Default for LazyClassAnalyzer {
10 fn default() -> Self {
11 Self {
12 max_methods: 1,
13 max_lines: 10,
14 }
15 }
16}
17
18impl Plugin for LazyClassAnalyzer {
19 fn name(&self) -> &str {
20 "lazy_class"
21 }
22
23 fn smells(&self) -> Vec<String> {
24 vec!["lazy_class".into()]
25 }
26
27 fn description(&self) -> &str {
28 "Class too small to justify its existence"
29 }
30
31 fn analyze(&self, ctx: &AnalysisContext) -> Vec<Finding> {
32 ctx.model
33 .classes
34 .iter()
35 .filter_map(|c| {
36 if c.is_interface
37 || c.method_count > self.max_methods
38 || c.line_count > self.max_lines
39 {
40 return None;
41 }
42 Some(Finding {
43 smell_name: "lazy_class".into(),
44 category: SmellCategory::Dispensables,
45 severity: Severity::Hint,
46 location: Location {
47 path: ctx.file.path.clone(),
48 start_line: c.start_line,
49 start_col: c.name_col,
50 end_line: c.start_line,
51 end_col: c.name_end_col,
52 name: Some(c.name.clone()),
53 },
54 message: format!(
55 "Class `{}` has only {} method(s) and {} lines, consider Inline Class",
56 c.name, c.method_count, c.line_count
57 ),
58 suggested_refactorings: vec!["Inline Class".into()],
59 actual_value: Some(c.method_count as f64),
60 threshold: Some(self.max_methods as f64),
61 risk_score: None,
62 })
63 })
64 .collect()
65 }
66}