tree-sitter-groovy
An incremental tree-sitter grammar for parsing Groovy source, Gradle scripts, and Jenkinsfiles.
Repository Health
Technical Analysis
tree-sitter-groovy is an incremental parsing grammar for the Groovy language, built for the tree-sitter parsing framework. It extends tree-sitter-java’s grammar with Groovy-specific syntax — closures, ranges, and parenthesis-less method calls — and ships as a compiled parser with native bindings for Node.js, Python, Rust, Go, Swift, and C.
The grammar registers .groovy, .gradle, and Jenkinsfile as recognized file types, making it useful for editor syntax highlighting, Gradle build-script tooling, and Jenkins pipeline analysis. The author describes it as a work in progress, and it currently ships without default highlight/injection query files, so downstream consumers need to supply their own queries for syntax highlighting.
What You Get
- A precompiled Groovy grammar (
src/parser.c) generated fromgrammar.js, ready to parse Groovy source without writing a parser yourself. - Ready-to-use bindings for Node.js, Python, Rust, Go, Swift, and C so the same grammar can be embedded in tooling written in any of those languages.
- A
tree-sitter.jsonmanifest declaring file-type associations (.groovy,.gradle,Jenkinsfile) and an injection regex for embedding Groovy inside other language grammars. - A 25-file declarative test corpus exercising classes, closures, loops, maps, and string literals as a reference for the grammar’s coverage.
Common Use Cases
- Powering Groovy and Gradle syntax highlighting in tree-sitter-based editors such as Neovim, Zed, and Helix.
- Parsing
build.gradleandJenkinsfilescripts for linters, formatters, or refactoring tools. - Adding Groovy as a supported language in multi-language code-search or static-analysis platforms.
- Prototyping language tooling that needs a concrete syntax tree for Groovy without hand-writing a grammar.
Under The Hood
Architecture
The grammar is defined in grammar.js by requiring tree-sitter-java/grammar.js and passing it as the base to grammar(Java, {...}), so Groovy’s rules are expressed as overrides and additions — new conflict entries, closures, ranges, and juxtaposition function calls — layered on top of Java’s declaration and expression grammar rather than written from scratch. The tree-sitter CLI compiles this definition into a generated src/parser.c, and each language binding (bindings/{node,python,rust,go,swift,c}) is a thin wrapper exposing a single language() accessor around the compiled TSLanguage. Because the grammar directly extends Java’s rule set, an upstream change to tree-sitter-java’s grammar could silently break Groovy’s overridden rules and conflict list.
Tech Stack
The grammar itself is authored in JavaScript against the tree-sitter CLI DSL and depends on tree-sitter-java 0.23.4 as its extension base. Native bindings pull in node-addon-api/node-gyp-build for Node, tree-sitter-language for Rust, github.com/tree-sitter/go-tree-sitter for Go, and a setuptools extension (binding.c + parser.c) with a custom bdist_wheel tag override targeting abi3 for Python. Build tooling spans binding.gyp, CMakeLists.txt, a Makefile, and Package.swift for the respective platforms.
Code Quality
Testing follows tree-sitter’s declarative corpus format: 25 .test files under test/corpus/ cover classes, closures, loops, maps, strings, and more, run via the shared tree-sitter/parser-test-action across Node, Python, Rust, Go, and Swift bindings in CI, plus a lightweight per-binding smoke test asserting the grammar loads. A separate CI job lints grammar.js with ESLint’s tree-sitter config. There is no application error handling to assess since this is a grammar rather than runtime logic, and the repository’s own README describes the project as a work in progress “cobbled together in an hour,” so coverage of edge cases beyond the corpus tests is unverified.
API Design
The public surface is a single language() function per binding, matching the convention every other tree-sitter-* package uses, so developers already familiar with one tree-sitter grammar can pick this one up with zero new concepts. Getting started is a one-line install plus a one-line call (e.g. tree_sitter.Language(tree_sitter_groovy.language()) in Python). The main developer-experience gap is that the package ships no highlight/injection/locals query files yet, so integrators building syntax highlighting must write their own .scm queries from scratch.