1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#![cfg_attr(coverage_nightly, coverage(off))]
//! Concrete implementations of defect analyzers for various quality issues.
//!
//! This module provides specific analyzers that implement the `DefectAnalyzer`
//! trait to detect different types of code quality issues. Each analyzer focuses
//! on a specific category of defects and can be composed to provide comprehensive
//! code quality assessment.
//!
//! # Analyzer Types
//!
//! - **`ComplexityDefectAnalyzer`**: Detects overly complex code using TDG metrics
//! - **`DeadCodeDefectAnalyzer`**: Identifies unreachable and unused code
//! - **`DuplicateDefectAnalyzer`**: Finds duplicated code blocks and patterns
//! - **`PerformanceDefectAnalyzer`**: Detects performance anti-patterns
//! - **`SecurityDefectAnalyzer`**: Identifies potential security vulnerabilities
//! - **`TechnicalDebtAnalyzer`**: Tracks self-admitted technical debt (SATD)
use crate::models::defect_report::{Defect, DefectCategory, Severity};
use crate::models::tdg::{TDGScore, TDGSeverity};
use crate::services::{
big_o_analyzer::FunctionComplexity,
dead_code_analyzer::{DeadCodeItem, UnreachableBlock},
defect_analyzer::{AnalyzerConfig, DefectAnalyzer},
duplicate_detector::{CloneGroup, CloneType},
satd_detector::{DebtCategory, TechnicalDebt},
};
use anyhow::Result;
use async_trait::async_trait;
use std::collections::HashMap;
use std::path::{Path, PathBuf};
/// Helper function to discover source files
async fn discover_source_files(path: &Path) -> Result<Vec<PathBuf>> {
use walkdir::WalkDir;
let mut files = Vec::new();
let extensions = ["rs", "js", "ts", "py", "java", "cpp", "c", "go"];
for entry in WalkDir::new(path)
.follow_links(false)
.into_iter()
.filter_map(std::result::Result::ok)
.filter(|e| e.file_type().is_file())
{
let path = entry.path();
if let Some(ext) = path.extension().and_then(|e| e.to_str()) {
if extensions.contains(&ext) {
files.push(path.to_path_buf());
}
}
}
Ok(files)
}
// --- Struct and config definitions ---
/// Adapter for complexity analysis (TDG-based)
pub struct ComplexityDefectAnalyzer;
#[derive(Clone)]
/// Configuration for complexity.
pub struct ComplexityConfig {
pub max_tdg_score: f64,
pub high_threshold: f64,
}
impl Default for ComplexityConfig {
fn default() -> Self {
Self {
max_tdg_score: 2.0,
high_threshold: 1.5,
}
}
}
impl AnalyzerConfig for ComplexityConfig {}
#[derive(Clone, Default)]
/// Configuration for s a t d.
pub struct SATDConfig {
pub include_test_files: bool,
}
impl AnalyzerConfig for SATDConfig {}
/// Adapter for SATD (Self-Admitted Technical Debt) detection
pub struct SATDDefectAnalyzer {
detector: crate::services::satd_detector::SATDDetector,
}
/// Adapter for dead code detection
pub struct DeadCodeDefectAnalyzer;
#[derive(Clone)]
/// Configuration for dead code.
pub struct DeadCodeConfig {
pub min_confidence: f64,
}
impl Default for DeadCodeConfig {
fn default() -> Self {
Self {
min_confidence: 0.7,
}
}
}
impl AnalyzerConfig for DeadCodeConfig {}
/// Adapter for code duplication detection
pub struct DuplicationDefectAnalyzer {
detector: crate::services::duplicate_detector::DuplicateDetectionEngine,
}
#[derive(Clone)]
/// Configuration for duplication.
pub struct DuplicationConfig {
pub min_similarity: f64,
}
impl Default for DuplicationConfig {
fn default() -> Self {
Self {
min_similarity: 0.8,
}
}
}
impl AnalyzerConfig for DuplicationConfig {}
/// Adapter for performance analysis (Big-O)
pub struct PerformanceDefectAnalyzer {
analyzer: crate::services::big_o_analyzer::BigOAnalyzer,
}
#[derive(Clone, Default)]
/// Configuration for performance.
pub struct PerformanceConfig {
pub include_nlogn: bool,
}
impl AnalyzerConfig for PerformanceConfig {}
/// Adapter for architecture issues detection
pub struct ArchitectureDefectAnalyzer;
#[derive(Clone)]
/// Configuration for architecture.
pub struct ArchitectureConfig {
pub max_coupling: usize,
}
impl Default for ArchitectureConfig {
fn default() -> Self {
Self { max_coupling: 10 }
}
}
impl AnalyzerConfig for ArchitectureConfig {}
// --- Include files with trait impls and helper methods ---
// ComplexityDefectAnalyzer trait impl and TDG-based complexity detection helpers
include!("defect_analyzers_complexity.rs");
// SATDDefectAnalyzer constructors, trait impl, and technical debt detection helpers
include!("defect_analyzers_debt.rs");
// DeadCodeDefectAnalyzer constructors, trait impl, and dead/unreachable code detection helpers
include!("defect_analyzers_dead_code.rs");
// DuplicationDefectAnalyzer constructors, trait impl, and code clone detection helpers
include!("defect_analyzers_duplication.rs");
// PerformanceDefectAnalyzer and ArchitectureDefectAnalyzer constructors, trait impls, and helpers
include!("defect_analyzers_performance.rs");
// Fixed: TDGComponents dead_code field added to all initializers
#[cfg(test)]
#[path = "defect_analyzers_tests.rs"]
mod tests;