Skip to main content

tree_sitter_groovy_sqry/
lib.rs

1//! Tree-sitter grammar for Groovy (vendored for sqry)
2//!
3//! This is a first-party binding maintained in the sqry repository.
4//!
5//! **Source Grammar**: <https://github.com/murtaza64/tree-sitter-groovy>
6//! **Commit**: 86911590a8e46d71301c66468e5620d9faa5b6af
7//! **Date**: 2025-01-22
8//! **License**: MIT
9
10use tree_sitter::Language;
11
12unsafe extern "C" {
13    fn tree_sitter_groovy() -> Language;
14}
15
16/// Returns the tree-sitter Language for Groovy
17///
18/// # Panics
19///
20/// Panics if the loaded grammar fails validation:
21/// - Null pointer returned from C library
22/// - ABI version mismatch (outside 9-14 range)
23/// - Incompatible version (below tree-sitter minimum)
24/// - Invalid grammar (zero node kinds)
25///
26/// These failures indicate a serious build or linking problem that cannot
27/// be recovered from at runtime.
28///
29/// # Safety
30///
31/// This function wraps an `unsafe` FFI call to `tree_sitter_groovy()`.
32/// The returned Language handle is validated before being exposed to prevent
33/// undefined behavior from invalid pointers or ABI mismatches.
34#[must_use = "Language handles must be registered with tree-sitter consumers"]
35pub fn language() -> Language {
36    // SAFETY: tree_sitter_groovy() is an extern C function from the linked
37    // tree-sitter-groovy library. We immediately validate the returned Language
38    // handle (including null-pointer check) before any dereference occurs.
39    // If validation fails, we panic (per infallible API contract).
40    // The C library is assumed to be correctly built and linked (cargo
41    // build-time invariant).
42    let lang = unsafe { tree_sitter_groovy() };
43    sqry_tree_sitter_support::validate_language_or_panic(lang, "Groovy")
44}
45
46/// Returns the tree-sitter Language for Groovy, with error handling
47///
48/// This is a fallible alternative to [`language()`] for use cases that need
49/// to handle grammar loading errors gracefully.
50///
51/// # Errors
52///
53/// Returns an error if the loaded grammar fails validation. See
54/// [`sqry_tree_sitter_support::TreeSitterError`] for possible error variants.
55pub fn try_language() -> Result<Language, sqry_tree_sitter_support::TreeSitterError> {
56    // SAFETY: Same as language(), but with Result instead of panic
57    let lang = unsafe { tree_sitter_groovy() };
58    sqry_tree_sitter_support::validate_language(lang)
59}
60
61/// The content of the [`node-types.json`][] file for this grammar.
62///
63/// [`node-types.json`]: https://tree-sitter.github.io/tree-sitter/using-parsers#static-node-types
64pub const NODE_TYPES: &str = include_str!("../grammar-src/node-types.json");
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_can_load_grammar() {
72        let lang = language();
73        assert!(
74            lang.abi_version() > 0,
75            "Language ABI version should be non-zero"
76        );
77    }
78
79    #[test]
80    fn test_try_language_succeeds() {
81        let result = try_language();
82        assert!(
83            result.is_ok(),
84            "try_language() should succeed for valid grammar"
85        );
86        let lang = result.unwrap();
87        assert!(lang.abi_version() > 0);
88    }
89
90    #[test]
91    #[allow(clippy::const_is_empty)]
92    fn test_node_types_not_empty() {
93        assert!(!NODE_TYPES.is_empty(), "Node types should not be empty");
94    }
95}