use crate::error::ArboristError;
use crate::types::Language;
#[cfg(feature = "c")]
pub mod c;
#[cfg(feature = "cpp")]
pub mod cpp;
#[cfg(feature = "csharp")]
pub mod csharp;
#[cfg(feature = "go")]
pub mod go;
#[cfg(feature = "java")]
pub mod java;
#[cfg(feature = "javascript")]
pub mod javascript;
#[cfg(feature = "kotlin")]
pub mod kotlin;
#[cfg(feature = "php")]
pub mod php;
#[cfg(feature = "python")]
pub mod python;
#[cfg(feature = "rust")]
pub mod rust;
#[cfg(feature = "swift")]
pub mod swift;
#[cfg(feature = "typescript")]
pub mod typescript;
pub trait LanguageProfile {
fn function_nodes(&self) -> &[&str];
fn control_flow_nodes(&self) -> &[&str];
fn nesting_nodes(&self) -> &[&str];
fn boolean_operators(&self) -> &[&str];
fn else_if_nodes(&self) -> &[&str];
fn lambda_nodes(&self) -> &[&str];
fn comment_nodes(&self) -> &[&str];
fn extract_function_name(&self, node: &tree_sitter::Node, source: &[u8]) -> Option<String>;
fn parser_language(&self) -> tree_sitter::Language;
fn extensions(&self) -> &[&str];
fn is_method(&self, node: &tree_sitter::Node) -> bool;
fn boolean_expression_nodes(&self) -> &[&str] {
&["binary_expression"]
}
fn call_nodes(&self) -> &[&str] {
&["call_expression"]
}
fn call_function_field(&self) -> &str {
"function"
}
fn match_construct_nodes(&self) -> &[&str] {
&[]
}
fn match_arm_nodes(&self) -> &[&str] {
&[]
}
}
pub fn profile_for_extension(
ext: &str,
) -> Result<(Language, Box<dyn LanguageProfile>), ArboristError> {
let ext_lower = ext.to_lowercase();
let ext_ref = ext_lower.as_str();
let language = match ext_ref {
"rs" => Some(Language::Rust),
"py" | "pyi" => Some(Language::Python),
"js" | "jsx" | "mjs" | "cjs" => Some(Language::JavaScript),
"ts" | "tsx" | "mts" | "cts" => Some(Language::TypeScript),
"java" => Some(Language::Java),
"cs" => Some(Language::CSharp),
"cpp" | "cc" | "cxx" | "hpp" | "hxx" | "hh" => Some(Language::Cpp),
"c" | "h" => Some(Language::C),
"go" => Some(Language::Go),
"php" => Some(Language::Php),
"kt" | "kts" => Some(Language::Kotlin),
"swift" => Some(Language::Swift),
_ => None,
};
let language = language.ok_or_else(|| ArboristError::UnrecognizedExtension {
extension: ext.to_string(),
})?;
profile_for_language(language)
}
pub fn profile_for_language(
language: Language,
) -> Result<(Language, Box<dyn LanguageProfile>), ArboristError> {
let profile: Box<dyn LanguageProfile> = match language {
#[cfg(feature = "rust")]
Language::Rust => Box::new(rust::RustProfile),
#[cfg(feature = "python")]
Language::Python => Box::new(python::PythonProfile),
#[cfg(feature = "javascript")]
Language::JavaScript => Box::new(javascript::JavaScriptProfile),
#[cfg(feature = "typescript")]
Language::TypeScript => Box::new(typescript::TypeScriptProfile),
#[cfg(feature = "java")]
Language::Java => Box::new(java::JavaProfile),
#[cfg(feature = "csharp")]
Language::CSharp => Box::new(csharp::CSharpProfile),
#[cfg(feature = "cpp")]
Language::Cpp => Box::new(cpp::CppProfile),
#[cfg(feature = "c")]
Language::C => Box::new(c::CProfile),
#[cfg(feature = "go")]
Language::Go => Box::new(go::GoProfile),
#[cfg(feature = "php")]
Language::Php => Box::new(php::PhpProfile),
#[cfg(feature = "kotlin")]
Language::Kotlin => Box::new(kotlin::KotlinProfile),
#[cfg(feature = "swift")]
Language::Swift => Box::new(swift::SwiftProfile),
#[allow(unreachable_patterns)]
_ => {
return Err(ArboristError::LanguageNotEnabled {
language: language.to_string(),
});
}
};
Ok((language, profile))
}