1pub mod cpp;
11pub mod csharp;
12pub mod css;
13pub mod fortran;
14pub mod go;
15pub mod html;
16pub mod java;
17pub mod javascript;
18pub mod kotlin;
19pub mod markdown;
20pub mod python;
21pub mod regex_fallback;
22pub mod rust;
23pub mod typescript;
24pub mod yaml;
25
26use tree_sitter::{Language, Node};
27
28#[must_use]
32pub fn get_node_text(node: &Node, source: &str) -> Option<String> {
33 let end = node.end_byte();
34 if end <= source.len() {
35 Some(source[node.start_byte()..end].to_string())
36 } else {
37 None
38 }
39}
40
41pub type ExtractFunctionNameHandler = fn(&Node, &str, &str) -> Option<String>;
43
44pub type FindMethodForReceiverHandler = fn(&Node, &str, Option<usize>) -> Option<String>;
46
47pub type FindReceiverTypeHandler = fn(&Node, &str) -> Option<String>;
49
50pub type ExtractInheritanceHandler = fn(&Node, &str) -> Vec<String>;
52
53pub struct LanguageInfo {
55 pub name: &'static str,
56 pub language: Language,
57 pub element_query: &'static str,
58 pub call_query: &'static str,
59 pub reference_query: Option<&'static str>,
60 pub import_query: Option<&'static str>,
61 pub impl_query: Option<&'static str>,
62 pub impl_trait_query: Option<&'static str>,
63 pub defuse_query: Option<&'static str>,
64 pub extract_function_name: Option<ExtractFunctionNameHandler>,
65 pub find_method_for_receiver: Option<FindMethodForReceiverHandler>,
66 pub find_receiver_type: Option<FindReceiverTypeHandler>,
67 pub extract_inheritance: Option<ExtractInheritanceHandler>,
68}
69
70#[allow(clippy::too_many_lines)] pub fn get_language_info(lang_name: &str) -> Option<LanguageInfo> {
73 match lang_name {
74 "rust" => Some(LanguageInfo {
75 name: "rust",
76 language: tree_sitter_rust::LANGUAGE.into(),
77 element_query: rust::ELEMENT_QUERY,
78 call_query: rust::CALL_QUERY,
79 reference_query: Some(rust::REFERENCE_QUERY),
80 import_query: Some(rust::IMPORT_QUERY),
81 impl_query: Some(rust::IMPL_QUERY),
82 impl_trait_query: Some(rust::IMPL_TRAIT_QUERY),
83 defuse_query: Some(rust::DEFUSE_QUERY),
84 extract_function_name: Some(rust::extract_function_name),
85 find_method_for_receiver: Some(rust::find_method_for_receiver),
86 find_receiver_type: Some(rust::find_receiver_type),
87 extract_inheritance: Some(rust::extract_inheritance),
88 }),
89 "python" => Some(LanguageInfo {
90 name: "python",
91 language: tree_sitter_python::LANGUAGE.into(),
92 element_query: python::ELEMENT_QUERY,
93 call_query: python::CALL_QUERY,
94 reference_query: Some(python::REFERENCE_QUERY),
95 import_query: Some(python::IMPORT_QUERY),
96 impl_query: None,
97 impl_trait_query: None,
98 defuse_query: Some(python::DEFUSE_QUERY),
99 extract_function_name: None,
100 find_method_for_receiver: None,
101 find_receiver_type: None,
102 extract_inheritance: Some(python::extract_inheritance),
103 }),
104 "typescript" => Some(LanguageInfo {
105 name: "typescript",
106 language: tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into(),
107 element_query: typescript::ELEMENT_QUERY,
108 call_query: typescript::CALL_QUERY,
109 reference_query: Some(typescript::REFERENCE_QUERY),
110 import_query: Some(typescript::IMPORT_QUERY),
111 impl_query: None,
112 impl_trait_query: None,
113 defuse_query: Some(typescript::DEFUSE_QUERY),
114 extract_function_name: None,
115 find_method_for_receiver: None,
116 find_receiver_type: None,
117 extract_inheritance: Some(typescript::extract_inheritance),
118 }),
119 "tsx" => Some(LanguageInfo {
120 name: "tsx",
121 language: tree_sitter_typescript::LANGUAGE_TSX.into(),
122 element_query: typescript::ELEMENT_QUERY,
123 call_query: typescript::CALL_QUERY,
124 reference_query: Some(typescript::REFERENCE_QUERY),
125 import_query: Some(typescript::IMPORT_QUERY),
126 impl_query: None,
127 impl_trait_query: None,
128 defuse_query: Some(typescript::DEFUSE_QUERY),
129 extract_function_name: None,
130 find_method_for_receiver: None,
131 find_receiver_type: None,
132 extract_inheritance: Some(typescript::extract_inheritance),
133 }),
134 "go" => Some(LanguageInfo {
135 name: "go",
136 language: tree_sitter_go::LANGUAGE.into(),
137 element_query: go::ELEMENT_QUERY,
138 call_query: go::CALL_QUERY,
139 reference_query: Some(go::REFERENCE_QUERY),
140 import_query: Some(go::IMPORT_QUERY),
141 impl_query: None,
142 impl_trait_query: None,
143 defuse_query: Some(go::DEFUSE_QUERY),
144 extract_function_name: Some(go::extract_function_name),
145 find_method_for_receiver: Some(go::find_method_for_receiver),
146 find_receiver_type: Some(go::find_receiver_type),
147 extract_inheritance: Some(go::extract_inheritance),
148 }),
149 "c" | "cpp" => Some(LanguageInfo {
150 name: if lang_name == "c" { "c" } else { "cpp" },
151 language: tree_sitter_cpp::LANGUAGE.into(),
152 element_query: cpp::ELEMENT_QUERY,
153 call_query: cpp::CALL_QUERY,
154 reference_query: Some(cpp::REFERENCE_QUERY),
155 import_query: Some(cpp::IMPORT_QUERY),
156 impl_query: None,
157 impl_trait_query: None,
158 defuse_query: Some(cpp::DEFUSE_QUERY),
159 extract_function_name: Some(cpp::extract_function_name),
160 find_method_for_receiver: Some(cpp::find_method_for_receiver),
161 find_receiver_type: None,
162 extract_inheritance: Some(cpp::extract_inheritance),
163 }),
164 "java" => Some(LanguageInfo {
165 name: "java",
166 language: tree_sitter_java::LANGUAGE.into(),
167 element_query: java::ELEMENT_QUERY,
168 call_query: java::CALL_QUERY,
169 reference_query: Some(java::REFERENCE_QUERY),
170 import_query: Some(java::IMPORT_QUERY),
171 impl_query: None,
172 impl_trait_query: None,
173 defuse_query: Some(java::DEFUSE_QUERY),
174 extract_function_name: Some(java::extract_function_name),
175 find_method_for_receiver: Some(java::find_method_for_receiver),
176 find_receiver_type: Some(java::find_receiver_type),
177 extract_inheritance: Some(java::extract_inheritance),
178 }),
179 "kotlin" => Some(LanguageInfo {
180 name: "kotlin",
181 language: tree_sitter_kotlin_ng::LANGUAGE.into(),
182 element_query: kotlin::ELEMENT_QUERY,
183 call_query: kotlin::CALL_QUERY,
184 reference_query: Some(kotlin::REFERENCE_QUERY),
185 import_query: Some(kotlin::IMPORT_QUERY),
186 impl_query: None,
187 impl_trait_query: None,
188 defuse_query: Some(kotlin::DEFUSE_QUERY),
189 extract_function_name: Some(kotlin::extract_function_name),
190 find_method_for_receiver: Some(kotlin::find_method_for_receiver),
191 find_receiver_type: Some(kotlin::find_receiver_type),
192 extract_inheritance: Some(kotlin::extract_inheritance),
193 }),
194 "fortran" => Some(LanguageInfo {
195 name: "fortran",
196 language: tree_sitter_fortran::LANGUAGE.into(),
197 element_query: fortran::ELEMENT_QUERY,
198 call_query: fortran::CALL_QUERY,
199 reference_query: Some(fortran::REFERENCE_QUERY),
200 import_query: Some(fortran::IMPORT_QUERY),
201 impl_query: None,
202 impl_trait_query: None,
203 defuse_query: None,
204 extract_function_name: Some(fortran::extract_function_name),
205 find_method_for_receiver: Some(fortran::find_method_for_receiver),
206 find_receiver_type: Some(fortran::find_receiver_type),
207 extract_inheritance: Some(fortran::extract_inheritance),
208 }),
209 "csharp" => Some(LanguageInfo {
210 name: "csharp",
211 language: tree_sitter_c_sharp::LANGUAGE.into(),
212 element_query: csharp::ELEMENT_QUERY,
213 call_query: csharp::CALL_QUERY,
214 reference_query: Some(csharp::REFERENCE_QUERY),
215 import_query: Some(csharp::IMPORT_QUERY),
216 impl_query: None,
217 impl_trait_query: None,
218 defuse_query: Some(csharp::DEFUSE_QUERY),
219 extract_function_name: Some(csharp::extract_function_name),
220 find_method_for_receiver: Some(csharp::find_method_for_receiver),
221 find_receiver_type: Some(csharp::find_receiver_type),
222 extract_inheritance: Some(csharp::extract_inheritance),
223 }),
224 "javascript" => Some(LanguageInfo {
225 name: "javascript",
226 language: tree_sitter_javascript::LANGUAGE.into(),
227 element_query: javascript::ELEMENT_QUERY,
228 call_query: javascript::CALL_QUERY,
229 reference_query: None,
230 import_query: Some(javascript::IMPORT_QUERY),
231 impl_query: None,
232 impl_trait_query: None,
233 defuse_query: Some(javascript::DEFUSE_QUERY),
234 extract_function_name: Some(javascript::extract_function_name),
235 find_method_for_receiver: Some(javascript::find_method_for_receiver),
236 find_receiver_type: Some(javascript::find_receiver_type),
237 extract_inheritance: Some(javascript::extract_inheritance),
238 }),
239 "html" => None,
249 "markdown" => Some(LanguageInfo {
250 name: "markdown",
251 language: tree_sitter_md::LANGUAGE.into(),
252 element_query: markdown::ELEMENT_QUERY,
253 call_query: markdown::CALL_QUERY,
254 reference_query: None,
255 import_query: None,
256 impl_query: None,
257 impl_trait_query: None,
258 defuse_query: None,
259 extract_function_name: None,
260 find_method_for_receiver: None,
261 find_receiver_type: None,
262 extract_inheritance: None,
263 }),
264 "css" => Some(LanguageInfo {
265 name: "css",
266 language: tree_sitter_css::LANGUAGE.into(),
267 element_query: css::ELEMENT_QUERY,
268 call_query: css::CALL_QUERY,
269 reference_query: None,
270 import_query: Some(css::IMPORT_QUERY),
271 impl_query: None,
272 impl_trait_query: None,
273 defuse_query: None,
274 extract_function_name: None,
275 find_method_for_receiver: None,
276 find_receiver_type: None,
277 extract_inheritance: None,
278 }),
279 "yaml" => Some(LanguageInfo {
280 name: "yaml",
281 language: tree_sitter_yaml::LANGUAGE.into(),
282 element_query: yaml::ELEMENT_QUERY,
283 call_query: yaml::CALL_QUERY,
284 reference_query: None,
285 import_query: None,
286 impl_query: None,
287 impl_trait_query: None,
288 defuse_query: None,
289 extract_function_name: None,
290 find_method_for_receiver: None,
291 find_receiver_type: None,
292 extract_inheritance: None,
293 }),
294 _ => None,
295 }
296}
297
298#[must_use]
302pub fn get_ts_language(lang_name: &str) -> Option<Language> {
303 match lang_name {
304 "rust" => Some(tree_sitter_rust::LANGUAGE.into()),
305 "python" => Some(tree_sitter_python::LANGUAGE.into()),
306 "typescript" => Some(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
307 "tsx" => Some(tree_sitter_typescript::LANGUAGE_TSX.into()),
308 "go" => Some(tree_sitter_go::LANGUAGE.into()),
309 "c" | "cpp" => Some(tree_sitter_cpp::LANGUAGE.into()),
310 "java" => Some(tree_sitter_java::LANGUAGE.into()),
311 "kotlin" => Some(tree_sitter_kotlin_ng::LANGUAGE.into()),
312 "fortran" => Some(tree_sitter_fortran::LANGUAGE.into()),
313 "csharp" => Some(tree_sitter_c_sharp::LANGUAGE.into()),
314 "javascript" => Some(tree_sitter_javascript::LANGUAGE.into()),
315 "css" => Some(tree_sitter_css::LANGUAGE.into()),
316 "yaml" => Some(tree_sitter_yaml::LANGUAGE.into()),
317 _ => None,
318 }
319}
320
321#[must_use]
326pub fn try_regex_fallback(source: &str, language: &str) -> Option<crate::types::SemanticAnalysis> {
327 match language {
328 "css" => Some(regex_fallback::extract_css(source)),
329 "yaml" => Some(regex_fallback::extract_yaml(source)),
330 "json" => Some(regex_fallback::extract_json(source)),
331 "toml" => Some(regex_fallback::extract_toml(source)),
332 "astro" => Some(regex_fallback::extract_astro(source)),
333 _ => None,
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340
341 #[test]
342 fn test_get_language_info_known() {
343 assert!(
345 get_language_info("rust").is_some(),
346 "expected Some for 'rust'"
347 );
348 assert!(get_language_info("go").is_some(), "expected Some for 'go'");
349 assert!(
350 get_language_info("python").is_some(),
351 "expected Some for 'python'"
352 );
353 }
354
355 #[test]
356 fn test_get_language_info_unknown() {
357 assert!(
359 get_language_info("cobol").is_none(),
360 "expected None for 'cobol'"
361 );
362 }
363
364 #[test]
365 fn test_get_ts_language_known() {
366 assert!(
368 get_ts_language("rust").is_some(),
369 "expected Some for 'rust'"
370 );
371 }
372
373 #[test]
374 fn test_get_ts_language_unknown() {
375 assert!(
377 get_ts_language("cobol").is_none(),
378 "expected None for 'cobol'"
379 );
380 }
381}