1use anyhow::Result;
4use rma_common::{Language, RmaError};
5use tree_sitter::Language as TsLanguage;
6
7pub fn get_language(lang: Language) -> Result<TsLanguage> {
9 match lang {
10 Language::Rust => Ok(tree_sitter_rust::LANGUAGE.into()),
11 Language::JavaScript => Ok(tree_sitter_javascript::LANGUAGE.into()),
12 Language::TypeScript => Ok(tree_sitter_typescript::LANGUAGE_TYPESCRIPT.into()),
13 Language::Python => Ok(tree_sitter_python::LANGUAGE.into()),
14 Language::Go => Ok(tree_sitter_go::LANGUAGE.into()),
15 Language::Java => Ok(tree_sitter_java::LANGUAGE.into()),
16 Language::Unknown => Err(RmaError::UnsupportedLanguage("unknown".into()).into()),
17 }
18}
19
20pub mod queries {
22 use rma_common::Language;
23
24 pub fn function_query(lang: Language) -> Option<&'static str> {
26 match lang {
27 Language::Rust => Some(
28 r#"
29 (function_item name: (identifier) @name) @function
30 (impl_item (function_item name: (identifier) @name)) @method
31 "#,
32 ),
33 Language::JavaScript | Language::TypeScript => Some(
34 r#"
35 (function_declaration name: (identifier) @name) @function
36 (method_definition name: (property_identifier) @name) @method
37 (arrow_function) @arrow
38 "#,
39 ),
40 Language::Python => Some(
41 r#"
42 (function_definition name: (identifier) @name) @function
43 (class_definition body: (block (function_definition name: (identifier) @name))) @method
44 "#,
45 ),
46 Language::Go => Some(
47 r#"
48 (function_declaration name: (identifier) @name) @function
49 (method_declaration name: (field_identifier) @name) @method
50 "#,
51 ),
52 Language::Java => Some(
53 r#"
54 (method_declaration name: (identifier) @name) @method
55 (constructor_declaration name: (identifier) @name) @constructor
56 "#,
57 ),
58 Language::Unknown => None,
59 }
60 }
61
62 pub fn class_query(lang: Language) -> Option<&'static str> {
64 match lang {
65 Language::Rust => Some(
66 r#"
67 (struct_item name: (type_identifier) @name) @struct
68 (enum_item name: (type_identifier) @name) @enum
69 (impl_item type: (type_identifier) @name) @impl
70 "#,
71 ),
72 Language::JavaScript | Language::TypeScript => Some(
73 r#"
74 (class_declaration name: (identifier) @name) @class
75 "#,
76 ),
77 Language::Python => Some(
78 r#"
79 (class_definition name: (identifier) @name) @class
80 "#,
81 ),
82 Language::Go => Some(
83 r#"
84 (type_declaration (type_spec name: (type_identifier) @name)) @type
85 "#,
86 ),
87 Language::Java => Some(
88 r#"
89 (class_declaration name: (identifier) @name) @class
90 (interface_declaration name: (identifier) @name) @interface
91 "#,
92 ),
93 Language::Unknown => None,
94 }
95 }
96
97 pub fn import_query(lang: Language) -> Option<&'static str> {
99 match lang {
100 Language::Rust => Some(
101 r#"
102 (use_declaration) @import
103 (extern_crate_declaration) @import
104 "#,
105 ),
106 Language::JavaScript | Language::TypeScript => Some(
107 r#"
108 (import_statement) @import
109 (import_clause) @import
110 "#,
111 ),
112 Language::Python => Some(
113 r#"
114 (import_statement) @import
115 (import_from_statement) @import
116 "#,
117 ),
118 Language::Go => Some(
119 r#"
120 (import_declaration) @import
121 "#,
122 ),
123 Language::Java => Some(
124 r#"
125 (import_declaration) @import
126 "#,
127 ),
128 Language::Unknown => None,
129 }
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_get_language() {
139 assert!(get_language(Language::Rust).is_ok());
140 assert!(get_language(Language::JavaScript).is_ok());
141 assert!(get_language(Language::Python).is_ok());
142 assert!(get_language(Language::Go).is_ok());
143 assert!(get_language(Language::Java).is_ok());
144 assert!(get_language(Language::Unknown).is_err());
145 }
146
147 #[test]
148 fn test_function_queries_exist() {
149 assert!(queries::function_query(Language::Rust).is_some());
150 assert!(queries::function_query(Language::JavaScript).is_some());
151 assert!(queries::function_query(Language::Python).is_some());
152 assert!(queries::function_query(Language::Unknown).is_none());
153 }
154}