1#[cfg(feature = "lang-cpp")]
11pub mod cpp;
12#[cfg(feature = "lang-csharp")]
13pub mod csharp;
14#[cfg(feature = "lang-fortran")]
15pub mod fortran;
16#[cfg(feature = "lang-go")]
17pub mod go;
18#[cfg(feature = "lang-java")]
19pub mod java;
20#[cfg(feature = "lang-javascript")]
21pub mod javascript;
22#[cfg(feature = "lang-kotlin")]
23pub mod kotlin;
24#[cfg(feature = "lang-python")]
25pub mod python;
26#[cfg(feature = "lang-rust")]
27pub mod rust;
28#[cfg(any(feature = "lang-typescript", feature = "lang-tsx"))]
29pub mod typescript;
30
31use tree_sitter::{Language, Node};
32
33#[must_use]
37pub fn get_node_text(node: &Node, source: &str) -> Option<String> {
38 let end = node.end_byte();
39 if end <= source.len() {
40 Some(source[node.start_byte()..end].to_string())
41 } else {
42 None
43 }
44}
45
46pub type ExtractFunctionNameHandler = fn(&Node, &str, &str) -> Option<String>;
48
49pub type FindMethodForReceiverHandler = fn(&Node, &str, Option<usize>) -> Option<String>;
51
52pub type FindReceiverTypeHandler = fn(&Node, &str) -> Option<String>;
54
55pub type ExtractInheritanceHandler = fn(&Node, &str) -> Vec<String>;
57
58pub struct LanguageInfo {
60 pub name: &'static str,
61 pub language: Language,
62 pub element_query: &'static str,
63 pub call_query: &'static str,
64 pub reference_query: Option<&'static str>,
65 pub import_query: Option<&'static str>,
66 pub impl_query: Option<&'static str>,
67 pub impl_trait_query: Option<&'static str>,
68 pub defuse_query: Option<&'static str>,
69 pub extract_function_name: Option<ExtractFunctionNameHandler>,
70 pub find_method_for_receiver: Option<FindMethodForReceiverHandler>,
71 pub find_receiver_type: Option<FindReceiverTypeHandler>,
72 pub extract_inheritance: Option<ExtractInheritanceHandler>,
73}
74
75#[allow(clippy::too_many_lines)] pub fn get_language_info(lang_name: &str) -> Option<LanguageInfo> {
78 match lang_name {
79 #[cfg(feature = "lang-rust")]
80 "rust" => Some(LanguageInfo {
81 name: "rust",
82 language: tree_sitter_rust::LANGUAGE.into(),
83 element_query: rust::ELEMENT_QUERY,
84 call_query: rust::CALL_QUERY,
85 reference_query: Some(rust::REFERENCE_QUERY),
86 import_query: Some(rust::IMPORT_QUERY),
87 impl_query: Some(rust::IMPL_QUERY),
88 impl_trait_query: Some(rust::IMPL_TRAIT_QUERY),
89 defuse_query: Some(rust::DEFUSE_QUERY),
90 extract_function_name: Some(rust::extract_function_name),
91 find_method_for_receiver: Some(rust::find_method_for_receiver),
92 find_receiver_type: Some(rust::find_receiver_type),
93 extract_inheritance: Some(rust::extract_inheritance),
94 }),
95 #[cfg(feature = "lang-python")]
96 "python" => Some(LanguageInfo {
97 name: "python",
98 language: tree_sitter_python::LANGUAGE.into(),
99 element_query: python::ELEMENT_QUERY,
100 call_query: python::CALL_QUERY,
101 reference_query: Some(python::REFERENCE_QUERY),
102 import_query: Some(python::IMPORT_QUERY),
103 impl_query: None,
104 impl_trait_query: None,
105 defuse_query: Some(python::DEFUSE_QUERY),
106 extract_function_name: None,
107 find_method_for_receiver: None,
108 find_receiver_type: None,
109 extract_inheritance: Some(python::extract_inheritance),
110 }),
111 #[cfg(feature = "lang-typescript")]
112 "typescript" => Some(LanguageInfo {
113 name: "typescript",
114 language: tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(),
115 element_query: typescript::ELEMENT_QUERY,
116 call_query: typescript::CALL_QUERY,
117 reference_query: Some(typescript::REFERENCE_QUERY),
118 import_query: Some(typescript::IMPORT_QUERY),
119 impl_query: None,
120 impl_trait_query: None,
121 defuse_query: Some(typescript::DEFUSE_QUERY),
122 extract_function_name: None,
123 find_method_for_receiver: None,
124 find_receiver_type: None,
125 extract_inheritance: Some(typescript::extract_inheritance),
126 }),
127 #[cfg(feature = "lang-tsx")]
128 "tsx" => Some(LanguageInfo {
129 name: "tsx",
130 language: tree_sitter_typescript::LANGUAGE_TSX.into(),
131 element_query: typescript::ELEMENT_QUERY,
132 call_query: typescript::CALL_QUERY,
133 reference_query: Some(typescript::REFERENCE_QUERY),
134 import_query: Some(typescript::IMPORT_QUERY),
135 impl_query: None,
136 impl_trait_query: None,
137 defuse_query: Some(typescript::DEFUSE_QUERY),
138 extract_function_name: None,
139 find_method_for_receiver: None,
140 find_receiver_type: None,
141 extract_inheritance: Some(typescript::extract_inheritance),
142 }),
143 #[cfg(feature = "lang-go")]
144 "go" => Some(LanguageInfo {
145 name: "go",
146 language: tree_sitter_go::LANGUAGE.into(),
147 element_query: go::ELEMENT_QUERY,
148 call_query: go::CALL_QUERY,
149 reference_query: Some(go::REFERENCE_QUERY),
150 import_query: Some(go::IMPORT_QUERY),
151 impl_query: None,
152 impl_trait_query: None,
153 defuse_query: Some(go::DEFUSE_QUERY),
154 extract_function_name: Some(go::extract_function_name),
155 find_method_for_receiver: Some(go::find_method_for_receiver),
156 find_receiver_type: Some(go::find_receiver_type),
157 extract_inheritance: Some(go::extract_inheritance),
158 }),
159 #[cfg(feature = "lang-cpp")]
160 "c" | "cpp" => Some(LanguageInfo {
161 name: if lang_name == "c" { "c" } else { "cpp" },
162 language: tree_sitter_cpp::LANGUAGE.into(),
163 element_query: cpp::ELEMENT_QUERY,
164 call_query: cpp::CALL_QUERY,
165 reference_query: Some(cpp::REFERENCE_QUERY),
166 import_query: Some(cpp::IMPORT_QUERY),
167 impl_query: None,
168 impl_trait_query: None,
169 defuse_query: Some(cpp::DEFUSE_QUERY),
170 extract_function_name: Some(cpp::extract_function_name),
171 find_method_for_receiver: Some(cpp::find_method_for_receiver),
172 find_receiver_type: None,
173 extract_inheritance: Some(cpp::extract_inheritance),
174 }),
175 #[cfg(feature = "lang-java")]
176 "java" => Some(LanguageInfo {
177 name: "java",
178 language: tree_sitter_java::LANGUAGE.into(),
179 element_query: java::ELEMENT_QUERY,
180 call_query: java::CALL_QUERY,
181 reference_query: Some(java::REFERENCE_QUERY),
182 import_query: Some(java::IMPORT_QUERY),
183 impl_query: None,
184 impl_trait_query: None,
185 defuse_query: Some(java::DEFUSE_QUERY),
186 extract_function_name: Some(java::extract_function_name),
187 find_method_for_receiver: Some(java::find_method_for_receiver),
188 find_receiver_type: Some(java::find_receiver_type),
189 extract_inheritance: Some(java::extract_inheritance),
190 }),
191 #[cfg(feature = "lang-kotlin")]
192 "kotlin" => Some(LanguageInfo {
193 name: "kotlin",
194 language: tree_sitter_kotlin_ng::LANGUAGE.into(),
195 element_query: kotlin::ELEMENT_QUERY,
196 call_query: kotlin::CALL_QUERY,
197 reference_query: Some(kotlin::REFERENCE_QUERY),
198 import_query: Some(kotlin::IMPORT_QUERY),
199 impl_query: None,
200 impl_trait_query: None,
201 defuse_query: Some(kotlin::DEFUSE_QUERY),
202 extract_function_name: Some(kotlin::extract_function_name),
203 find_method_for_receiver: Some(kotlin::find_method_for_receiver),
204 find_receiver_type: Some(kotlin::find_receiver_type),
205 extract_inheritance: Some(kotlin::extract_inheritance),
206 }),
207 #[cfg(feature = "lang-fortran")]
208 "fortran" => Some(LanguageInfo {
209 name: "fortran",
210 language: tree_sitter_fortran::LANGUAGE.into(),
211 element_query: fortran::ELEMENT_QUERY,
212 call_query: fortran::CALL_QUERY,
213 reference_query: Some(fortran::REFERENCE_QUERY),
214 import_query: Some(fortran::IMPORT_QUERY),
215 impl_query: None,
216 impl_trait_query: None,
217 defuse_query: None,
218 extract_function_name: Some(fortran::extract_function_name),
219 find_method_for_receiver: Some(fortran::find_method_for_receiver),
220 find_receiver_type: Some(fortran::find_receiver_type),
221 extract_inheritance: Some(fortran::extract_inheritance),
222 }),
223 #[cfg(feature = "lang-csharp")]
224 "csharp" => Some(LanguageInfo {
225 name: "csharp",
226 language: tree_sitter_c_sharp::LANGUAGE.into(),
227 element_query: csharp::ELEMENT_QUERY,
228 call_query: csharp::CALL_QUERY,
229 reference_query: Some(csharp::REFERENCE_QUERY),
230 import_query: Some(csharp::IMPORT_QUERY),
231 impl_query: None,
232 impl_trait_query: None,
233 defuse_query: Some(csharp::DEFUSE_QUERY),
234 extract_function_name: Some(csharp::extract_function_name),
235 find_method_for_receiver: Some(csharp::find_method_for_receiver),
236 find_receiver_type: Some(csharp::find_receiver_type),
237 extract_inheritance: Some(csharp::extract_inheritance),
238 }),
239 #[cfg(feature = "lang-javascript")]
240 "javascript" => Some(LanguageInfo {
241 name: "javascript",
242 language: tree_sitter_javascript::LANGUAGE.into(),
243 element_query: javascript::ELEMENT_QUERY,
244 call_query: javascript::CALL_QUERY,
245 reference_query: None,
246 import_query: Some(javascript::IMPORT_QUERY),
247 impl_query: None,
248 impl_trait_query: None,
249 defuse_query: Some(javascript::DEFUSE_QUERY),
250 extract_function_name: Some(javascript::extract_function_name),
251 find_method_for_receiver: Some(javascript::find_method_for_receiver),
252 find_receiver_type: Some(javascript::find_receiver_type),
253 extract_inheritance: Some(javascript::extract_inheritance),
254 }),
255 _ => None,
256 }
257}
258
259#[must_use]
263pub fn get_ts_language(lang_name: &str) -> Option<Language> {
264 match lang_name {
265 #[cfg(feature = "lang-rust")]
266 "rust" => Some(tree_sitter_rust::LANGUAGE.into()),
267 #[cfg(feature = "lang-python")]
268 "python" => Some(tree_sitter_python::LANGUAGE.into()),
269 #[cfg(feature = "lang-typescript")]
270 "typescript" => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
271 #[cfg(feature = "lang-tsx")]
272 "tsx" => Some(tree_sitter_typescript::LANGUAGE_TSX.into()),
273 #[cfg(feature = "lang-go")]
274 "go" => Some(tree_sitter_go::LANGUAGE.into()),
275 #[cfg(feature = "lang-cpp")]
276 "c" | "cpp" => Some(tree_sitter_cpp::LANGUAGE.into()),
277 #[cfg(feature = "lang-java")]
278 "java" => Some(tree_sitter_java::LANGUAGE.into()),
279 #[cfg(feature = "lang-kotlin")]
280 "kotlin" => Some(tree_sitter_kotlin_ng::LANGUAGE.into()),
281 #[cfg(feature = "lang-fortran")]
282 "fortran" => Some(tree_sitter_fortran::LANGUAGE.into()),
283 #[cfg(feature = "lang-csharp")]
284 "csharp" => Some(tree_sitter_c_sharp::LANGUAGE.into()),
285 #[cfg(feature = "lang-javascript")]
286 "javascript" => Some(tree_sitter_javascript::LANGUAGE.into()),
287 _ => None,
288 }
289}
290
291#[cfg(test)]
292mod tests {
293 use super::*;
294
295 #[test]
296 fn test_get_language_info_known() {
297 assert!(
299 get_language_info("rust").is_some(),
300 "expected Some for 'rust'"
301 );
302 assert!(get_language_info("go").is_some(), "expected Some for 'go'");
303 assert!(
304 get_language_info("python").is_some(),
305 "expected Some for 'python'"
306 );
307 }
308
309 #[test]
310 fn test_get_language_info_unknown() {
311 assert!(
313 get_language_info("cobol").is_none(),
314 "expected None for 'cobol'"
315 );
316 }
317
318 #[test]
319 fn test_get_ts_language_known() {
320 assert!(
322 get_ts_language("rust").is_some(),
323 "expected Some for 'rust'"
324 );
325 }
326
327 #[test]
328 fn test_get_ts_language_unknown() {
329 assert!(
331 get_ts_language("cobol").is_none(),
332 "expected None for 'cobol'"
333 );
334 }
335}