Skip to main content

cha_core/plugins/
comments.rs

1use crate::{AnalysisContext, Finding, Location, Plugin, Severity, SmellCategory};
2
3/// Detect functions where comment lines exceed a threshold ratio.
4pub struct CommentsAnalyzer {
5    pub max_comment_ratio: f64,
6    pub min_lines: usize,
7}
8
9impl Default for CommentsAnalyzer {
10    fn default() -> Self {
11        Self {
12            max_comment_ratio: 0.3,
13            min_lines: 10,
14        }
15    }
16}
17
18impl Plugin for CommentsAnalyzer {
19    fn name(&self) -> &str {
20        "comments"
21    }
22
23    fn description(&self) -> &str {
24        "Excessive comment-to-code ratio"
25    }
26
27    fn analyze(&self, ctx: &AnalysisContext) -> Vec<Finding> {
28        ctx.model
29            .functions
30            .iter()
31            .filter_map(|f| {
32                if f.line_count < self.min_lines || f.comment_lines == 0 {
33                    return None;
34                }
35                let ratio = f.comment_lines as f64 / f.line_count as f64;
36                if ratio <= self.max_comment_ratio {
37                    return None;
38                }
39                Some(Finding {
40                    smell_name: "excessive_comments".into(),
41                    category: SmellCategory::Dispensables,
42                    severity: Severity::Hint,
43                    location: Location {
44                        path: ctx.file.path.clone(),
45                        start_line: f.start_line,
46                        end_line: f.end_line,
47                        name: Some(f.name.clone()),
48                        ..Default::default()
49                    },
50                    message: format!(
51                        "Function `{}` has {:.0}% comment lines ({}/{}), consider Extract Method",
52                        f.name,
53                        ratio * 100.0,
54                        f.comment_lines,
55                        f.line_count
56                    ),
57                    suggested_refactorings: vec!["Extract Method".into(), "Rename Method".into()],
58                    actual_value: Some(ratio),
59                    threshold: Some(self.max_comment_ratio),
60                })
61            })
62            .collect()
63    }
64}