dry4rust/analyzer.rs
1// Copyright (c) 2026 Matjaz Domen Pecan
2// Copyright 2026 Umberto Gotti <umberto.gotti@umbertogotti.dev>
3// Licensed under the MIT License
4// SPDX-License-Identifier: MIT
5
6use std::path::Path;
7
8use crate::analysis_config::AnalysisConfig;
9use crate::code_unit::CodeUnit;
10use std::error::Error;
11
12/// Trait for language-specific code analysis.
13///
14/// Implementors provide file-extension detection and parsing logic,
15/// allowing `dry4rust` to work with any language.
16///
17/// **Test code handling:** Analyzers should set [`CodeUnit::is_test`] to `true`
18/// for test functions, test modules, etc. The [`crate::analysis::analyze`] function will
19/// filter them out when `Config::exclude_tests` is enabled, using [`LanguageAnalyzer::is_test_code`].
20pub trait LanguageAnalyzer: Send + Sync {
21 /// File extensions this analyzer handles (without the leading dot).
22 fn file_extensions(&self) -> &[&str];
23
24 /// Parse a single source file into code units.
25 ///
26 /// `path` is the file's location (for diagnostics), `source` is the file content,
27 /// and `config` carries min-node / min-line thresholds.
28 ///
29 /// Analyzers should tag test code via [`CodeUnit::is_test`] rather than
30 /// filtering it out; the caller handles exclusion.
31 fn parse_file(
32 &self,
33 path: &Path,
34 source: &str,
35 config: &AnalysisConfig,
36 ) -> Result<Vec<CodeUnit>, Box<dyn Error + Send + Sync>>;
37
38 /// Check whether a code unit represents test code.
39 ///
40 /// Required rather than defaulted: an analyser that cannot tell test code
41 /// from production code should have to say so, not inherit an answer.
42 fn is_test_code(&self, unit: &CodeUnit) -> bool;
43}