#![cfg_attr(coverage_nightly, coverage(off))]
use super::service_base::{Service, ServiceMetrics, ValidationError};
use crate::services::dead_code_analyzer::DeadCodeAnalyzer;
use crate::services::satd_detector::SATDDetector;
use anyhow::Result;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use tokio::sync::RwLock;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisInput {
pub operation: AnalysisOperation,
pub path: PathBuf,
pub options: AnalysisOptions,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AnalysisOperation {
Complexity,
Satd,
DeadCode,
All,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisOptions {
pub max_complexity: Option<u32>,
pub include_tests: bool,
pub parallel: bool,
pub format: OutputFormat,
}
impl Default for AnalysisOptions {
fn default() -> Self {
Self {
max_complexity: Some(20),
include_tests: false,
parallel: true,
format: OutputFormat::Json,
}
}
}
pub use crate::contracts::OutputFormat;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisOutput {
pub operation: AnalysisOperation,
pub results: AnalysisResults,
pub summary: AnalysisSummary,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(untagged)]
pub enum AnalysisResults {
Complexity(ComplexityResults),
Satd(SatdResults),
DeadCode(DeadCodeResults),
Combined(CombinedResults),
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplexityResults {
pub total_files: usize,
pub average_complexity: f64,
pub max_complexity: u32,
pub violations: Vec<ComplexityViolation>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SatdResults {
pub total_files: usize,
pub total_satd: usize,
pub violations: Vec<SatdViolation>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeadCodeResults {
pub total_files: usize,
pub dead_code_count: usize,
pub dead_code_percentage: f64,
pub unused_items: Vec<UnusedItem>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CombinedResults {
pub complexity: ComplexityResults,
pub satd: SatdResults,
pub dead_code: DeadCodeResults,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AnalysisSummary {
pub files_analyzed: usize,
pub total_issues: usize,
pub critical_issues: usize,
pub duration_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ComplexityViolation {
pub file: String,
pub function: String,
pub complexity: u32,
pub line: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SatdViolation {
pub file: String,
pub line: usize,
pub comment: String,
pub category: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UnusedItem {
pub file: String,
pub item: String,
pub item_type: String,
pub line: usize,
}
pub struct AnalysisService {
metrics: Arc<RwLock<ServiceMetrics>>,
satd_detector: SATDDetector,
}
impl AnalysisService {
#[must_use]
pub fn new() -> Self {
Self {
metrics: Arc::new(RwLock::new(ServiceMetrics::default())),
satd_detector: SATDDetector::new(),
}
}
}
impl Default for AnalysisService {
fn default() -> Self {
Self::new()
}
}
include!("analysis_service_analyzers.rs");
include!("analysis_service_dispatch.rs");
include!("analysis_service_tests.rs");