@dekobon/tree-sitter-groovy 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,88 @@
1
+ {
2
+ "name": "@dekobon/tree-sitter-groovy",
3
+ "version": "0.2.0",
4
+ "description": "Apache Groovy grammar for tree-sitter (dekobon fork)",
5
+ "main": "bindings/node",
6
+ "types": "bindings/node",
7
+ "keywords": [
8
+ "tree-sitter",
9
+ "parser",
10
+ "lexer",
11
+ "groovy",
12
+ "jenkins",
13
+ "gradle",
14
+ "spock",
15
+ "incremental",
16
+ "parsing"
17
+ ],
18
+ "files": [
19
+ "LICENSE-APACHE",
20
+ "LICENSE-MIT",
21
+ "grammar.js",
22
+ "binding.gyp",
23
+ "prebuilds/**",
24
+ "bindings/node/*",
25
+ "queries/*",
26
+ "src/**",
27
+ "tree-sitter.json",
28
+ "*.wasm"
29
+ ],
30
+ "homepage": "https://github.com/dekobon/tree-sitter-groovy",
31
+ "bugs": {
32
+ "url": "https://github.com/dekobon/tree-sitter-groovy/issues"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/dekobon/tree-sitter-groovy.git"
37
+ },
38
+ "scripts": {
39
+ "install": "node-gyp-build",
40
+ "prestart": "tree-sitter build --wasm",
41
+ "start": "tree-sitter playground",
42
+ "test": "node --test bindings/node/*_test.js",
43
+ "lint": "eslint .",
44
+ "prebuildify": "prebuildify --napi --strip"
45
+ },
46
+ "author": {
47
+ "email": "elijah@zupancic.name",
48
+ "name": "Elijah Zupancic"
49
+ },
50
+ "license": "Apache-2.0 OR MIT",
51
+ "publishConfig": {
52
+ "access": "public"
53
+ },
54
+ "engines": {
55
+ "node": ">=20"
56
+ },
57
+ "dependencies": {
58
+ "node-addon-api": "^8.7.0",
59
+ "node-gyp-build": "^4.8.4"
60
+ },
61
+ "peerDependencies": {
62
+ "tree-sitter": "^0.25.0"
63
+ },
64
+ "peerDependenciesMeta": {
65
+ "tree-sitter": {
66
+ "optional": true
67
+ }
68
+ },
69
+ "devDependencies": {
70
+ "eslint": "^9.39.4",
71
+ "eslint-config-treesitter": "^1.0.2",
72
+ "prebuildify": "^6.0.1",
73
+ "tree-sitter-cli": "^0.25.10"
74
+ },
75
+ "tree-sitter": [
76
+ {
77
+ "scope": "source.groovy",
78
+ "injection-regex": "^groovy$",
79
+ "file-types": [
80
+ "groovy",
81
+ "gradle",
82
+ "gvy",
83
+ "gy",
84
+ "jenkinsfile"
85
+ ]
86
+ }
87
+ ]
88
+ }
@@ -0,0 +1,18 @@
1
+ ; Fold regions for Groovy. nvim-treesitter / Neovim folding ranges
2
+ ; are taken from any node captured as @fold; the node's start and
3
+ ; end positions become the fold's bounds.
4
+ ;
5
+ ; See SPECIFICATION.md §9 — folds cover class / method / closure /
6
+ ; control-flow bodies plus large literal collections.
7
+
8
+ (class_body) @fold
9
+ (enum_body) @fold
10
+ (switch_block) @fold
11
+ (block) @fold
12
+ (closure) @fold
13
+ (list_literal) @fold
14
+ (map_literal) @fold
15
+ (argument_list) @fold
16
+
17
+ (groovydoc_comment) @fold
18
+ (block_comment) @fold
@@ -0,0 +1,235 @@
1
+ ; tree-sitter-groovy highlight queries.
2
+ ;
3
+ ; Capture names follow nvim-treesitter conventions:
4
+ ; https://neovim.io/doc/user/treesitter.html#treesitter-highlight-groups
5
+ ;
6
+ ; Precedence rule: tree-sitter highlight queries are last-match-wins
7
+ ; per node. Layers below are ordered from broadest to most specific:
8
+ ; 1. comments / number / string / boolean / null
9
+ ; 2. anonymous-token operators (also captures . , ?., etc.)
10
+ ; 3. generic identifier → @variable (the catch-all)
11
+ ; 4. keywords (@keyword, @keyword.control, @keyword.operator)
12
+ ; 5. field / property captures off the dot family
13
+ ; 6. declared names (class / method / record / formal parameter)
14
+ ; 7. call-site captures (@function.call) — must come AFTER property
15
+ ; so a method-named field beats the property capture
16
+ ; 8. type uses (@type on type_identifier) — must come AFTER
17
+ ; @variable so aliased identifier-as-type wins
18
+ ; 9. annotation usage (the @attribute capture)
19
+
20
+ ; -- Layer 1: comments and literals --------------------------------
21
+
22
+ (line_comment) @comment
23
+ (block_comment) @comment
24
+ (groovydoc_comment) @comment.documentation
25
+
26
+ (number_literal) @number
27
+ (string_literal) @string
28
+ (string_fragment) @string
29
+ (boolean_literal) @boolean
30
+ (null_literal) @constant.builtin
31
+
32
+ ; GString interpolation — `${expr}` and `$identifier` (per §5.7).
33
+ (gstring_brace_interpolation
34
+ "${" @punctuation.special
35
+ "}" @punctuation.special)
36
+ (gstring_dollar_interpolation
37
+ value: (identifier) @variable)
38
+
39
+ ; -- Layer 2: operators (anonymous tokens) -------------------------
40
+
41
+ [
42
+ "+"
43
+ "-"
44
+ "*"
45
+ "/"
46
+ "%"
47
+ "!"
48
+ "~"
49
+ "<<"
50
+ ">>"
51
+ ">>>"
52
+ "<"
53
+ "<="
54
+ ">"
55
+ ">="
56
+ "=="
57
+ "!="
58
+ "&"
59
+ "^"
60
+ "|"
61
+ "&&"
62
+ "||"
63
+ ".."
64
+ "..<"
65
+ "<.."
66
+ "<..<"
67
+ "==="
68
+ "!=="
69
+ "<=>"
70
+ "=~"
71
+ "==~"
72
+ "?:"
73
+ "?"
74
+ "==>"
75
+ "="
76
+ "+="
77
+ "-="
78
+ "*="
79
+ "/="
80
+ "%="
81
+ "**="
82
+ "<<="
83
+ ">>="
84
+ ">>>="
85
+ "&="
86
+ "^="
87
+ "|="
88
+ "?="
89
+ "**"
90
+ "++"
91
+ "--"
92
+ "."
93
+ "?."
94
+ "??."
95
+ "*."
96
+ ".&"
97
+ ".@"
98
+ "::"
99
+ "*:"
100
+ ] @operator
101
+
102
+ ; -- Layer 3: generic identifier fallback --------------------------
103
+
104
+ (identifier) @variable
105
+
106
+ ; -- Layer 4: keywords ---------------------------------------------
107
+
108
+ [
109
+ "new"
110
+ "as"
111
+ "in"
112
+ "instanceof"
113
+ ] @keyword.operator
114
+
115
+ ; `!in` and `!instanceof` are composite tokens (literal + trailing
116
+ ; whitespace) per SPECIFICATION.md §3.2.2 lexer rule, so they
117
+ ; cannot be referenced as direct anonymous tokens in a `[ … ]`
118
+ ; group. Capture them through the operator field instead.
119
+ (membership_expression operator: _ @keyword.operator)
120
+ (instanceof_expression operator: _ @keyword.operator)
121
+
122
+ [
123
+ "if"
124
+ "else"
125
+ "while"
126
+ "do"
127
+ "for"
128
+ "return"
129
+ "break"
130
+ "continue"
131
+ "throw"
132
+ "throws"
133
+ "assert"
134
+ "try"
135
+ "catch"
136
+ "finally"
137
+ "switch"
138
+ "case"
139
+ "default"
140
+ "yield"
141
+ ] @keyword.control
142
+
143
+ [
144
+ "class"
145
+ "trait"
146
+ "interface"
147
+ "enum"
148
+ "record"
149
+ "def"
150
+ "var"
151
+ "package"
152
+ "import"
153
+ "pipeline"
154
+ "sealed"
155
+ "non-sealed"
156
+ "permits"
157
+ "extends"
158
+ "implements"
159
+ ] @keyword
160
+
161
+ [
162
+ "public"
163
+ "private"
164
+ "protected"
165
+ "static"
166
+ "final"
167
+ "abstract"
168
+ "synchronized"
169
+ "native"
170
+ "transient"
171
+ "volatile"
172
+ "strictfp"
173
+ ] @keyword.modifier
174
+
175
+ (shebang) @keyword.directive
176
+
177
+ ; -- Layer 5: dot-family property captures -------------------------
178
+
179
+ (field_access field: [(identifier) (quoted_identifier)] @property)
180
+ (safe_navigation_expression property: [(identifier) (quoted_identifier)] @property)
181
+ (safe_chain_dot_expression property: [(identifier) (quoted_identifier)] @property)
182
+ (spread_dot_expression property: [(identifier) (quoted_identifier)] @property)
183
+ (direct_field_access_expression field: [(identifier) (quoted_identifier)] @property)
184
+ (method_pointer_expression method: [(identifier) (quoted_identifier)] @function)
185
+ ; `Foo::new` — the `new` literal is captured as @keyword.operator at
186
+ ; layer 4 instead of @function here.
187
+ (method_reference_expression name: (identifier) @function)
188
+
189
+ ; -- Layer 6: declared names ---------------------------------------
190
+
191
+ (class_declaration name: (identifier) @type.definition)
192
+ (trait_declaration name: (identifier) @type.definition)
193
+ (interface_declaration name: (identifier) @type.definition)
194
+ (enum_declaration name: (identifier) @type.definition)
195
+ (record_declaration name: (identifier) @type.definition)
196
+ (annotation_type_declaration name: (identifier) @type.definition)
197
+ (enum_constant name: (identifier) @constant)
198
+ (method_declaration name: [(identifier) (quoted_identifier)] @function)
199
+ (constructor_declaration name: (identifier) @constructor)
200
+ (formal_parameter name: (identifier) @variable.parameter)
201
+ (closure_parameter name: (identifier) @variable.parameter)
202
+ (record_component name: (identifier) @variable.parameter)
203
+ (variable_declarator name: (identifier) @variable)
204
+ (field_declaration (variable_declarator name: (identifier) @property))
205
+
206
+ ; Labels (declaration + use sites)
207
+ (labeled_statement label: (identifier) @label)
208
+ (break_statement label: (identifier) @label)
209
+ (continue_statement label: (identifier) @label)
210
+
211
+ ; -- Layer 7: call sites (after layer 5 so method-named fields win) -
212
+
213
+ (method_invocation
214
+ function: (identifier) @function.call)
215
+
216
+ (method_invocation
217
+ function: (field_access
218
+ field: (identifier) @function.call))
219
+
220
+ (command_chain
221
+ receiver: (identifier) @function.call)
222
+
223
+ ; -- Layer 8: types (after @variable so aliased identifier wins) ---
224
+
225
+ (type_identifier) @type
226
+
227
+ ; Java/Groovy primitive types and `void` highlight as builtin.
228
+ ((type_identifier) @type.builtin
229
+ (#match? @type.builtin "^(boolean|byte|char|double|float|int|long|short|void)$"))
230
+
231
+ ; -- Layer 9: annotation usage -------------------------------------
232
+
233
+ (annotation
234
+ "@" @attribute
235
+ name: (qualified_name) @attribute)
@@ -0,0 +1,35 @@
1
+ ; Indent rules for Groovy.
2
+ ;
3
+ ; nvim-treesitter conventions:
4
+ ; @indent.begin — node whose contents are indented one level
5
+ ; @indent.end — node that closes an indent block
6
+ ; @indent.dedent — node that dedents by one level
7
+ ; @indent.branch — node that aligns with its enclosing block
8
+ ;
9
+ ; See SPECIFICATION.md §9.
10
+
11
+ [
12
+ (class_body)
13
+ (enum_body)
14
+ (switch_block)
15
+ (block)
16
+ (closure)
17
+ (list_literal)
18
+ (map_literal)
19
+ (argument_list)
20
+ (formal_parameters)
21
+ (record_components)
22
+ ] @indent.begin
23
+
24
+ [
25
+ "}"
26
+ "]"
27
+ ")"
28
+ ] @indent.end
29
+
30
+ ; Branch labels — case / default lines align with the switch_block.
31
+ [
32
+ (switch_case)
33
+ (switch_arrow_case)
34
+ (switch_default)
35
+ ] @indent.branch
@@ -0,0 +1,38 @@
1
+ ; Language injections per SPECIFICATION.md §9.2.
2
+ ;
3
+ ; Doc comments inject as a documentation language. Slashy and
4
+ ; dollar-slashy string literals inject as `regex` so editors
5
+ ; highlight the pattern body. Named-call DSL strings
6
+ ; (`sql.execute """..."""`, `xmlSlurper.parseText """..."""`)
7
+ ; inject the embedded language when the receiver name matches.
8
+
9
+ ((groovydoc_comment) @injection.content
10
+ (#set! injection.language "javadoc"))
11
+
12
+ ; Slashy regex `/.../` — the leading `/` is what distinguishes it
13
+ ; from the plain-string flavours at the query layer (single-,
14
+ ; triple-single-, double-, triple-double-quoted strings all
15
+ ; share the `string_literal` node kind).
16
+ ((string_literal) @injection.content
17
+ (#match? @injection.content "^/[^/]")
18
+ (#set! injection.language "regex"))
19
+
20
+ ; Dollar-slashy regex `$/.../$`.
21
+ ((string_literal) @injection.content
22
+ (#match? @injection.content "^\\$/")
23
+ (#set! injection.language "regex"))
24
+
25
+ ; `sql.execute """SELECT ..."""` and similar SQL DSL idioms.
26
+ ; Matches a method invocation whose receiver chain ends in `sql`
27
+ ; or `Sql` and whose first argument is a triple-double-quoted
28
+ ; string. The injection content is the body's literal-fragment
29
+ ; range, so `${param}` interpolations stay tree-sitter-parsable
30
+ ; rather than being swallowed by the SQL highlighter.
31
+ ((method_invocation
32
+ function: (field_access
33
+ object: (identifier) @_recv
34
+ field: (identifier))
35
+ arguments: (argument_list
36
+ (string_literal (string_fragment) @injection.content)))
37
+ (#match? @_recv "^[Ss]ql$")
38
+ (#set! injection.language "sql"))
@@ -0,0 +1,32 @@
1
+ ; Local-scope captures per SPECIFICATION.md §9.3.
2
+ ;
3
+ ; nvim-treesitter / Neovim local-scope query language:
4
+ ; @local.scope — node introduces a fresh scope
5
+ ; @local.definition — captures a binding (formal, declarator, …)
6
+ ; @local.reference — captures a use site of an identifier
7
+
8
+ ; Scopes — anywhere a new symbol table is opened.
9
+ [
10
+ (class_body)
11
+ (block)
12
+ (closure)
13
+ (method_declaration)
14
+ (constructor_declaration)
15
+ (static_initializer)
16
+ (for_statement)
17
+ (for_in_statement)
18
+ (catch_clause)
19
+ ] @local.scope
20
+
21
+ ; Definitions — bound names introduced inside their enclosing scope.
22
+ (formal_parameter name: (identifier) @local.definition.parameter)
23
+ (closure_parameter name: (identifier) @local.definition.parameter)
24
+ (variable_declarator name: (identifier) @local.definition.var)
25
+ (field_declaration
26
+ (variable_declarator name: (identifier) @local.definition.field))
27
+ (for_in_statement variable: (identifier) @local.definition.var)
28
+ (catch_formal_parameter name: (identifier) @local.definition.var)
29
+ (record_component name: (identifier) @local.definition.parameter)
30
+
31
+ ; References — bare identifiers used as values.
32
+ (identifier) @local.reference
@@ -0,0 +1,67 @@
1
+ ; Tag captures per SPECIFICATION.md §2.1.
2
+ ;
3
+ ; Tag-query convention (matches tree-sitter-tags / nvim-treesitter):
4
+ ; @definition.<kind> — declaration site of a top-level symbol
5
+ ; @reference.<kind> — call / instantiation reference
6
+ ; @name — the identifier inside the tag, used to
7
+ ; resolve the symbol name when emitting tags
8
+ ;
9
+ ; Captures are kept conservative: only declarations whose name is a
10
+ ; bare `identifier` are tagged. Quoted-identifier method names
11
+ ; (`def "abstract"() { … }`) are skipped — `ctags` consumers expect
12
+ ; plain symbol names.
13
+
14
+ ; --- Definitions ----------------------------------------------------
15
+
16
+ (class_declaration
17
+ name: (identifier) @name) @definition.class
18
+
19
+ (interface_declaration
20
+ name: (identifier) @name) @definition.interface
21
+
22
+ (trait_declaration
23
+ name: (identifier) @name) @definition.trait
24
+
25
+ (annotation_type_declaration
26
+ name: (identifier) @name) @definition.interface
27
+
28
+ (enum_declaration
29
+ name: (identifier) @name) @definition.enum
30
+
31
+ (record_declaration
32
+ name: (identifier) @name) @definition.class
33
+
34
+ (method_declaration
35
+ name: (identifier) @name) @definition.method
36
+
37
+ (constructor_declaration
38
+ name: (identifier) @name) @definition.constructor
39
+
40
+ (field_declaration
41
+ (variable_declarator
42
+ name: (identifier) @name)) @definition.field
43
+
44
+ (enum_constant
45
+ name: (identifier) @name) @definition.constant
46
+
47
+ ; --- References -----------------------------------------------------
48
+
49
+ (method_invocation
50
+ function: (identifier) @name) @reference.call
51
+
52
+ (method_invocation
53
+ function: (field_access
54
+ field: (identifier) @name)) @reference.call
55
+
56
+ (object_creation_expression
57
+ type: (type_identifier) @name) @reference.class
58
+
59
+ (object_creation_expression
60
+ type: (generic_type
61
+ base: (type_identifier) @name)) @reference.class
62
+
63
+ (superclass (type_identifier) @name) @reference.class
64
+
65
+ (super_interfaces (type_identifier) @name) @reference.implementation
66
+
67
+ (extends_interfaces (type_identifier) @name) @reference.implementation