#![cfg_attr(coverage_nightly, coverage(off))]
#![allow(clippy::module_name_repetitions)]
use crate::services::ast::AstStrategy;
use crate::services::context::FileContext;
use crate::services::file_classifier::FileClassifier;
use crate::services::languages::java::JavaAstVisitor;
use async_trait::async_trait;
use std::path::Path;
use tokio::fs;
use anyhow::Result;
pub struct JavaStrategy;
impl JavaStrategy {
#[must_use]
pub fn new() -> Self {
Self
}
}
#[async_trait]
impl AstStrategy for JavaStrategy {
async fn analyze(&self, file_path: &Path, _classifier: &FileClassifier) -> Result<FileContext> {
let content = fs::read_to_string(file_path).await?;
let visitor = JavaAstVisitor::new(file_path);
match visitor.analyze_java_source(&content) {
Ok(items) => {
Ok(FileContext {
path: file_path.to_string_lossy().to_string(),
language: "java".to_string(),
items,
complexity_metrics: None,
})
},
Err(e) => {
tracing::warn!("Failed to parse Java file {}: {}", file_path.display(), e);
Ok(FileContext {
path: file_path.to_string_lossy().to_string(),
language: "java".to_string(),
items: vec![],
complexity_metrics: None,
})
}
}
}
fn primary_extension(&self) -> &'static str {
"java"
}
fn supported_extensions(&self) -> Vec<&'static str> {
vec!["java"]
}
fn language_name(&self) -> &'static str {
"Java"
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use crate::services::context::AstItem;
use std::path::PathBuf;
use std::fs::File;
use std::io::Write;
use tempfile::TempDir;
fn create_temp_java_file(content: &str) -> (PathBuf, TempDir) {
let temp_dir = TempDir::new().expect("Failed to create temp directory");
let file_path = temp_dir.path().join("Test.java");
let mut file = File::create(&file_path).expect("Failed to create temp file");
file.write_all(content.as_bytes()).expect("Failed to write to temp file");
(file_path, temp_dir)
}
#[tokio::test]
async fn test_java_strategy_analyze() {
let java_content = r#"
package com.example;
public class Test {
public void exampleMethod() {
System.out.println("Hello, Java!");
}
}
"#;
let (file_path, _temp_dir) = create_temp_java_file(java_content);
let strategy = JavaStrategy::new();
let classifier = FileClassifier::new();
let context = strategy.analyze(&file_path, &classifier).await.unwrap();
assert_eq!(context.language, "java");
assert!(!context.items.is_empty());
let class_items: Vec<_> = context.items.iter()
.filter(|item| matches!(item, AstItem::Struct { .. }))
.collect();
assert!(!class_items.is_empty());
let method_items: Vec<_> = context.items.iter()
.filter(|item| matches!(item, AstItem::Function { .. }))
.collect();
assert!(!method_items.is_empty());
}
#[test]
fn test_java_strategy_extensions() {
let strategy = JavaStrategy::new();
assert_eq!(strategy.primary_extension(), "java");
assert!(strategy.supported_extensions().contains(&"java"));
assert_eq!(strategy.language_name(), "Java");
}
}