#![cfg_attr(coverage_nightly, coverage(off))]
use super::types::{CacheStats, CachedSyntax};
use super::visitor::ComplexityVisitor;
use crate::unified_quality::metrics::Metrics;
use anyhow::{anyhow, Result};
use std::path::PathBuf;
use std::sync::Arc;
use std::time::SystemTime;
use syn::{visit::Visit, File};
pub struct EnhancedParser {
cache: Arc<dashmap::DashMap<PathBuf, CachedSyntax>>,
}
impl Default for EnhancedParser {
fn default() -> Self {
Self::new()
}
}
impl EnhancedParser {
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new() -> Self {
Self {
cache: Arc::new(dashmap::DashMap::new()),
}
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn parse_incremental(&mut self, path: &PathBuf, content: &str) -> Result<Metrics> {
let content_hash = self.calculate_hash(content);
if let Some(cached) = self.cache.get(path) {
if cached.content_hash == content_hash {
if let Some(ref metrics) = cached.metrics {
return Ok(metrics.clone());
}
}
}
self.parse_and_analyze(path, content)
}
fn parse_and_analyze(&mut self, path: &PathBuf, content: &str) -> Result<Metrics> {
let syntax: File =
syn::parse_str(content).map_err(|e| anyhow!("Failed to parse Rust code: {e}"))?;
let mut visitor = ComplexityVisitor::new(content.to_string());
visitor.visit_file(&syntax);
let metrics = Metrics {
complexity: visitor.complexity,
cognitive: visitor.cognitive,
satd_count: visitor.satd_count,
coverage: 0.8, lines: content.lines().count() as u32,
functions: visitor.function_count,
timestamp: SystemTime::now(),
};
self.cache.insert(
path.clone(),
CachedSyntax {
syntax_str: format!("{syntax:#?}"), content: content.to_string(),
last_modified: SystemTime::now(),
content_hash: self.calculate_hash(content),
metrics: Some(metrics.clone()),
},
);
Ok(metrics)
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "score_range")]
pub(crate) fn calculate_hash(&self, content: &str) -> u64 {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
let mut hasher = DefaultHasher::new();
content.hash(&mut hasher);
hasher.finish()
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn get_cached_metrics(&self, path: &PathBuf) -> Option<Metrics> {
self.cache.get(path)?.metrics.clone()
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "path_exists")]
pub fn clear_cache(&self, path: &PathBuf) {
self.cache.remove(path);
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn clear_all_cache(&self) {
self.cache.clear();
}
#[must_use]
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn cache_stats(&self) -> CacheStats {
CacheStats {
total_entries: self.cache.len(),
memory_usage_estimate: self.cache.len() * 2048, }
}
}