scope_engine/language/
mod.rs1pub mod c;
2pub mod cpp;
3pub mod go;
4pub mod java;
5pub mod php;
6pub mod python;
7pub mod ruby;
8pub mod rust;
9pub mod typescript;
10
11use tree_sitter::{Language, Parser};
12
13pub struct LanguageQueries {
19 pub definitions: &'static str,
20 pub references: &'static str,
21}
22
23pub trait LanguageAdapter: Send + Sync {
24 fn language_name(&self) -> &'static str;
25 fn extensions(&self) -> &[&'static str];
26 fn language(&self) -> Language;
27 fn queries(&self) -> LanguageQueries;
28 fn parser(&self) -> Parser {
29 let mut p = Parser::new();
30 p.set_language(&self.language())
31 .expect("tree-sitter language init failed");
32 p
33 }
34}
35
36use std::collections::HashMap;
37
38pub struct LanguageRegistry {
39 adapters: Vec<Box<dyn LanguageAdapter>>,
40 by_ext: HashMap<String, usize>,
41}
42
43impl LanguageRegistry {
44 #[must_use]
45 pub fn new() -> Self {
46 let mut r = Self {
47 adapters: Vec::new(),
48 by_ext: HashMap::new(),
49 };
50 r.register(Box::new(rust::RustAdapter::new()));
51 r.register(Box::new(python::PythonAdapter::new()));
52 r.register(Box::new(go::GoAdapter::new()));
53 r.register(Box::new(typescript::TypeScriptAdapter::new()));
54 r.register(Box::new(typescript::TsxAdapter::new()));
55 r.register(Box::new(typescript::JavaScriptAdapter::new()));
56 r.register(Box::new(java::JavaAdapter::new()));
57 r.register(Box::new(c::CAdapter::new()));
58 r.register(Box::new(cpp::CppAdapter::new()));
59 r.register(Box::new(ruby::RubyAdapter::new()));
60 r.register(Box::new(php::PhpAdapter::new()));
61 r
62 }
63
64 pub fn register(&mut self, adapter: Box<dyn LanguageAdapter>) {
65 let idx = self.adapters.len();
66 for ext in adapter.extensions() {
67 self.by_ext.insert(ext.to_string(), idx);
68 }
69 self.adapters.push(adapter);
70 }
71
72 #[must_use]
73 pub fn get(&self, ext: &str) -> Option<&dyn LanguageAdapter> {
74 let idx = self.by_ext.get(ext)?;
75 Some(self.adapters[*idx].as_ref())
76 }
77
78 #[must_use]
80 pub fn list_languages(&self) -> Vec<(&str, &[&str])> {
81 self.adapters
82 .iter()
83 .map(|a| (a.language_name(), a.extensions()))
84 .collect()
85 }
86}
87
88impl Default for LanguageRegistry {
89 fn default() -> Self {
90 Self::new()
91 }
92}