use crate::analyzers::rust::metadata::{classify_function_role, extract_function_metadata};
use crate::analyzers::rust::metrics::{create_analysis_result, perform_enhanced_analysis};
use crate::analyzers::rust::patterns::{
analyze_functional_composition, build_language_specific, detect_mapping_pattern,
detect_parallel_patterns, detect_pattern_signals,
};
use crate::analyzers::rust::types::{
ComplexityMetricsData, FunctionAnalysisData, FunctionContext, FunctionMetadata,
};
use crate::analyzers::rust_complexity_calculation;
use crate::complexity::threshold_manager::ComplexityThresholds;
use crate::core::FunctionMetrics;
use crate::debt::error_swallowing::detect_error_swallowing_in_function;
#[allow(clippy::too_many_arguments)]
pub fn create_function_analysis_data(
name: &str,
item_fn: &syn::ItemFn,
_line: usize,
_is_trait_method: bool,
context: FunctionContext,
file_ast: Option<&syn::File>,
source_content: &str,
enhanced_thresholds: &ComplexityThresholds,
enable_functional_analysis: bool,
enable_rust_patterns: bool,
) -> FunctionAnalysisData {
let metadata = extract_function_metadata(name, item_fn);
let complexity_metrics = calculate_complexity_metrics(&item_fn.block, item_fn, file_ast);
let enhanced_analysis = perform_enhanced_analysis(&item_fn.block);
let role = classify_function_role(name, metadata.is_test);
let metrics = build_function_metrics(
&context,
metadata.clone(),
complexity_metrics,
&item_fn.block,
item_fn,
file_ast,
source_content,
enable_functional_analysis,
enable_rust_patterns,
);
let analysis_result = create_analysis_result(
name.to_string(),
&metrics,
role,
enhanced_analysis,
enhanced_thresholds,
);
FunctionAnalysisData {
metrics,
enhanced_analysis: analysis_result,
}
}
pub fn calculate_complexity_metrics(
block: &syn::Block,
item_fn: &syn::ItemFn,
file_ast: Option<&syn::File>,
) -> ComplexityMetricsData {
ComplexityMetricsData {
cyclomatic: rust_complexity_calculation::calculate_cyclomatic_with_visitor(
block, item_fn, file_ast,
),
cognitive: rust_complexity_calculation::calculate_cognitive_with_visitor(
block, item_fn, file_ast,
),
}
}
#[allow(clippy::too_many_arguments)]
pub fn build_function_metrics(
context: &FunctionContext,
metadata: FunctionMetadata,
complexity: ComplexityMetricsData,
block: &syn::Block,
item_fn: &syn::ItemFn,
file_ast: Option<&syn::File>,
source_content: &str,
enable_functional_analysis: bool,
enable_rust_patterns: bool,
) -> FunctionMetrics {
let (mapping_result, mapping_adjusted) =
detect_mapping_pattern(block, complexity.cyclomatic, complexity.cognitive);
let (detected_patterns, adjusted_complexity) = detect_parallel_patterns(
file_ast,
source_content,
complexity.cyclomatic,
mapping_adjusted,
);
let composition_metrics = analyze_functional_composition(enable_functional_analysis, item_fn);
let signals = detect_pattern_signals(block, &context.name);
let language_specific =
build_language_specific(context, item_fn, &signals, enable_rust_patterns);
let (error_count, error_patterns) = detect_error_swallowing_in_function(block);
FunctionMetrics {
name: context.name.clone(),
file: context.file.clone(),
line: context.line,
cyclomatic: complexity.cyclomatic,
cognitive: complexity.cognitive,
nesting: rust_complexity_calculation::calculate_nesting(block),
length: rust_complexity_calculation::count_function_lines(item_fn),
is_test: metadata.is_test,
visibility: metadata.visibility,
is_trait_method: context.is_trait_method,
in_test_module: context.in_test_module,
entropy_score: metadata.entropy_score,
is_pure: metadata.purity_info.0,
purity_confidence: metadata.purity_info.1,
purity_reason: None,
call_dependencies: None,
detected_patterns: if detected_patterns.is_empty() {
None
} else {
Some(detected_patterns)
},
upstream_callers: None,
downstream_callees: None,
mapping_pattern_result: if mapping_result.is_pure_mapping {
Some(mapping_result)
} else {
None
},
adjusted_complexity,
composition_metrics,
language_specific,
purity_level: metadata.purity_info.2,
error_swallowing_count: if error_count > 0 {
Some(error_count)
} else {
None
},
error_swallowing_patterns: if error_patterns.is_empty() {
None
} else {
Some(error_patterns)
},
entropy_analysis: None,
}
}