pub mod c;
pub mod cpp;
pub mod go;
pub mod java;
pub mod php;
pub mod python;
pub mod ruby;
pub mod rust;
pub mod typescript;
use tree_sitter::{Language, Parser};
pub struct LanguageQueries {
pub definitions: &'static str,
pub references: &'static str,
}
pub trait LanguageAdapter: Send + Sync {
fn language_name(&self) -> &'static str;
fn extensions(&self) -> &[&'static str];
fn language(&self) -> Language;
fn queries(&self) -> LanguageQueries;
fn parser(&self) -> Parser {
let mut p = Parser::new();
p.set_language(&self.language())
.expect("tree-sitter language init failed");
p
}
}
use std::collections::HashMap;
pub struct LanguageRegistry {
adapters: Vec<Box<dyn LanguageAdapter>>,
by_ext: HashMap<String, usize>,
}
impl LanguageRegistry {
#[must_use]
pub fn new() -> Self {
let mut r = Self {
adapters: Vec::new(),
by_ext: HashMap::new(),
};
r.register(Box::new(rust::RustAdapter::new()));
r.register(Box::new(python::PythonAdapter::new()));
r.register(Box::new(go::GoAdapter::new()));
r.register(Box::new(typescript::TypeScriptAdapter::new()));
r.register(Box::new(typescript::TsxAdapter::new()));
r.register(Box::new(typescript::JavaScriptAdapter::new()));
r.register(Box::new(java::JavaAdapter::new()));
r.register(Box::new(c::CAdapter::new()));
r.register(Box::new(cpp::CppAdapter::new()));
r.register(Box::new(ruby::RubyAdapter::new()));
r.register(Box::new(php::PhpAdapter::new()));
r
}
pub fn register(&mut self, adapter: Box<dyn LanguageAdapter>) {
let idx = self.adapters.len();
for ext in adapter.extensions() {
self.by_ext.insert(ext.to_string(), idx);
}
self.adapters.push(adapter);
}
#[must_use]
pub fn get(&self, ext: &str) -> Option<&dyn LanguageAdapter> {
let idx = self.by_ext.get(ext)?;
Some(self.adapters[*idx].as_ref())
}
#[must_use]
pub fn list_languages(&self) -> Vec<(&str, &[&str])> {
self.adapters
.iter()
.map(|a| (a.language_name(), a.extensions()))
.collect()
}
}
impl Default for LanguageRegistry {
fn default() -> Self {
Self::new()
}
}