/ src / languages / java.rs
java.rs
  1  use crate::languages::LanguageSupport;
  2  use std::sync::OnceLock;
  3  use tracing::error;
  4  use tree_sitter::{Language, Query};
  5  
  6  pub struct Java;
  7  
  8  static REFERENCE_QUERY: OnceLock<Query> = OnceLock::new();
  9  static BINDING_QUERY: OnceLock<Query> = OnceLock::new();
 10  static IMPORT_QUERY: OnceLock<Query> = OnceLock::new();
 11  static COMPLETION_QUERY: OnceLock<Query> = OnceLock::new();
 12  static REASSIGNMENT_QUERY: OnceLock<Query> = OnceLock::new();
 13  static IDENTIFIER_QUERY: OnceLock<Query> = OnceLock::new();
 14  static EXPORT_QUERY: OnceLock<Query> = OnceLock::new();
 15  static ASSIGNMENT_QUERY: OnceLock<Query> = OnceLock::new();
 16  static DESTRUCTURE_QUERY: OnceLock<Query> = OnceLock::new();
 17  static SCOPE_QUERY: OnceLock<Query> = OnceLock::new();
 18  
 19  fn compile_query(grammar: &Language, source: &str, query_name: &str) -> Query {
 20      match Query::new(grammar, source) {
 21          Ok(query) => query,
 22          Err(e) => {
 23              error!(
 24                  language = "java",
 25                  query = query_name,
 26                  error = %e,
 27                  "Failed to compile query, failing fast"
 28              );
 29              panic!("Failed to compile query '{}': {}", query_name, e)
 30          }
 31      }
 32  }
 33  
 34  impl LanguageSupport for Java {
 35      fn id(&self) -> &'static str {
 36          "java"
 37      }
 38  
 39      fn extensions(&self) -> &'static [&'static str] {
 40          &["java"]
 41      }
 42  
 43      fn language_ids(&self) -> &'static [&'static str] {
 44          &["java"]
 45      }
 46  
 47      fn grammar(&self) -> Language {
 48          tree_sitter_java::LANGUAGE.into()
 49      }
 50  
 51      fn reference_query(&self) -> &Query {
 52          REFERENCE_QUERY.get_or_init(|| {
 53              compile_query(
 54                  &self.grammar(),
 55                  include_str!("../../queries/java/references.scm"),
 56                  "references",
 57              )
 58          })
 59      }
 60  
 61      fn binding_query(&self) -> Option<&Query> {
 62          Some(BINDING_QUERY.get_or_init(|| {
 63              compile_query(
 64                  &self.grammar(),
 65                  include_str!("../../queries/java/bindings.scm"),
 66                  "bindings",
 67              )
 68          }))
 69      }
 70  
 71      fn import_query(&self) -> Option<&Query> {
 72          Some(IMPORT_QUERY.get_or_init(|| {
 73              compile_query(
 74                  &self.grammar(),
 75                  include_str!("../../queries/java/imports.scm"),
 76                  "imports",
 77              )
 78          }))
 79      }
 80  
 81      fn completion_query(&self) -> Option<&Query> {
 82          Some(COMPLETION_QUERY.get_or_init(|| {
 83              compile_query(
 84                  &self.grammar(),
 85                  include_str!("../../queries/java/completion.scm"),
 86                  "completion",
 87              )
 88          }))
 89      }
 90  
 91      fn reassignment_query(&self) -> Option<&Query> {
 92          Some(REASSIGNMENT_QUERY.get_or_init(|| {
 93              compile_query(
 94                  &self.grammar(),
 95                  include_str!("../../queries/java/reassignments.scm"),
 96                  "reassignments",
 97              )
 98          }))
 99      }
100  
101      fn identifier_query(&self) -> Option<&Query> {
102          Some(IDENTIFIER_QUERY.get_or_init(|| {
103              compile_query(
104                  &self.grammar(),
105                  include_str!("../../queries/java/identifiers.scm"),
106                  "identifiers",
107              )
108          }))
109      }
110  
111      fn export_query(&self) -> Option<&Query> {
112          Some(EXPORT_QUERY.get_or_init(|| {
113              compile_query(
114                  &self.grammar(),
115                  include_str!("../../queries/java/exports.scm"),
116                  "exports",
117              )
118          }))
119      }
120  
121      fn assignment_query(&self) -> Option<&Query> {
122          Some(ASSIGNMENT_QUERY.get_or_init(|| {
123              compile_query(
124                  &self.grammar(),
125                  include_str!("../../queries/java/assignments.scm"),
126                  "assignments",
127              )
128          }))
129      }
130  
131      fn destructure_query(&self) -> Option<&Query> {
132          Some(DESTRUCTURE_QUERY.get_or_init(|| {
133              compile_query(
134                  &self.grammar(),
135                  include_str!("../../queries/java/destructures.scm"),
136                  "destructures",
137              )
138          }))
139      }
140  
141      fn scope_query(&self) -> Option<&Query> {
142          Some(SCOPE_QUERY.get_or_init(|| {
143              compile_query(
144                  &self.grammar(),
145                  include_str!("../../queries/java/scopes.scm"),
146                  "scopes",
147              )
148          }))
149      }
150  
151      fn completion_trigger_characters(&self) -> &'static [&'static str] {
152          &["(\"", "('"]
153      }
154  
155      fn is_standard_env_object(&self, name: &str) -> bool {
156          name == "System"
157      }
158  
159      fn comment_node_kinds(&self) -> &'static [&'static str] {
160          &["line_comment", "block_comment"]
161      }
162  
163      fn is_scope_node(&self, node: tree_sitter::Node) -> bool {
164          matches!(
165              node.kind(),
166              "method_declaration"
167                  | "constructor_declaration"
168                  | "block"
169                  | "for_statement"
170                  | "enhanced_for_statement"
171                  | "if_statement"
172                  | "while_statement"
173                  | "do_statement"
174                  | "switch_expression"
175                  | "try_statement"
176                  | "catch_clause"
177                  | "class_declaration"
178                  | "interface_declaration"
179                  | "lambda_expression"
180          )
181      }
182  }
183  
184  #[cfg(test)]
185  mod tests {
186      use super::*;
187  
188      fn get_java() -> Java {
189          Java
190      }
191  
192      #[test]
193      fn test_id() {
194          assert_eq!(get_java().id(), "java");
195      }
196  
197      #[test]
198      fn test_extensions() {
199          let exts = get_java().extensions();
200          assert!(exts.contains(&"java"));
201      }
202  
203      #[test]
204      fn test_language_ids() {
205          let ids = get_java().language_ids();
206          assert!(ids.contains(&"java"));
207      }
208  
209      #[test]
210      fn test_grammar_compiles() {
211          let java = get_java();
212          let _grammar = java.grammar();
213      }
214  
215      #[test]
216      fn test_reference_query_compiles() {
217          let java = get_java();
218          let _query = java.reference_query();
219      }
220  
221      #[test]
222      fn test_binding_query_compiles() {
223          let java = get_java();
224          assert!(java.binding_query().is_some());
225      }
226  
227      #[test]
228      fn test_import_query_compiles() {
229          let java = get_java();
230          assert!(java.import_query().is_some());
231      }
232  
233      #[test]
234      fn test_completion_query_compiles() {
235          let java = get_java();
236          assert!(java.completion_query().is_some());
237      }
238  
239      #[test]
240      fn test_reassignment_query_compiles() {
241          let java = get_java();
242          assert!(java.reassignment_query().is_some());
243      }
244  
245      #[test]
246      fn test_identifier_query_compiles() {
247          let java = get_java();
248          assert!(java.identifier_query().is_some());
249      }
250  
251      #[test]
252      fn test_export_query_compiles() {
253          let java = get_java();
254          assert!(java.export_query().is_some());
255      }
256  
257      #[test]
258      fn test_assignment_query_compiles() {
259          let java = get_java();
260          assert!(java.assignment_query().is_some());
261      }
262  
263      #[test]
264      fn test_scope_query_compiles() {
265          let java = get_java();
266          assert!(java.scope_query().is_some());
267      }
268  
269      #[test]
270      fn test_destructure_query_compiles() {
271          let java = get_java();
272          assert!(java.destructure_query().is_some());
273      }
274  }