tree_stump 0.1.0 → 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.
- checksums.yaml +4 -4
- data/Cargo.lock +154 -109
- data/LICENSE +21 -0
- data/README.md +41 -4
- data/ext/tree_stump/Cargo.toml +5 -2
- data/ext/tree_stump/src/language.rs +5 -1
- data/ext/tree_stump/src/lib.rs +42 -18
- data/ext/tree_stump/src/parser.rs +32 -17
- data/ext/tree_stump/src/query.rs +17 -7
- data/ext/tree_stump/src/tree.rs +14 -8
- data/ext/tree_stump/src/util.rs +15 -4
- data/lib/tree_stump/version.rb +1 -1
- data/lib/tree_stump.rb +2 -6
- metadata +22 -10
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fbb9e50517f16c70868597bb9e48e4e28f01d5450bfdf45eea3e5753beafbf3a
|
|
4
|
+
data.tar.gz: eb8259cdb0612654c6574ae4fad7cef477850116d2f0c14f977dc2901ac8de33
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b464a93c384ef2a1ec0d3186110210253e6fb4899cae8beb98cf6e33e32cef79e08ddf38e35ff51532d1dbe2f95f8912c443590c3fc85ae6374519d4ce1c622f
|
|
7
|
+
data.tar.gz: 2a282c202023dbaab64d84642fb2d95dd741572a6e6c70848a3269fe9063aa8962bf393d0b4294eafd0222475f57c6cecd80f7ec344c01a45b917afaae8229e6
|
data/Cargo.lock
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# This file is automatically @generated by Cargo.
|
|
2
2
|
# It is not intended for manual editing.
|
|
3
|
-
version =
|
|
3
|
+
version = 4
|
|
4
4
|
|
|
5
5
|
[[package]]
|
|
6
6
|
name = "aho-corasick"
|
|
7
|
-
version = "1.1.
|
|
7
|
+
version = "1.1.4"
|
|
8
8
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9
|
-
checksum = "
|
|
9
|
+
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
|
|
10
10
|
dependencies = [
|
|
11
11
|
"memchr",
|
|
12
12
|
]
|
|
13
13
|
|
|
14
14
|
[[package]]
|
|
15
15
|
name = "bindgen"
|
|
16
|
-
version = "0.69.
|
|
16
|
+
version = "0.69.5"
|
|
17
17
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
18
|
-
checksum = "
|
|
18
|
+
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
|
19
19
|
dependencies = [
|
|
20
20
|
"bitflags",
|
|
21
21
|
"cexpr",
|
|
@@ -33,16 +33,17 @@ dependencies = [
|
|
|
33
33
|
|
|
34
34
|
[[package]]
|
|
35
35
|
name = "bitflags"
|
|
36
|
-
version = "2.
|
|
36
|
+
version = "2.10.0"
|
|
37
37
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
38
|
-
checksum = "
|
|
38
|
+
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
|
39
39
|
|
|
40
40
|
[[package]]
|
|
41
41
|
name = "cc"
|
|
42
|
-
version = "1.
|
|
42
|
+
version = "1.2.51"
|
|
43
43
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
44
|
-
checksum = "
|
|
44
|
+
checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203"
|
|
45
45
|
dependencies = [
|
|
46
|
+
"find-msvc-tools",
|
|
46
47
|
"shlex",
|
|
47
48
|
]
|
|
48
49
|
|
|
@@ -57,9 +58,9 @@ dependencies = [
|
|
|
57
58
|
|
|
58
59
|
[[package]]
|
|
59
60
|
name = "cfg-if"
|
|
60
|
-
version = "1.0.
|
|
61
|
+
version = "1.0.4"
|
|
61
62
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
62
|
-
checksum = "
|
|
63
|
+
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
63
64
|
|
|
64
65
|
[[package]]
|
|
65
66
|
name = "clang-sys"
|
|
@@ -74,15 +75,43 @@ dependencies = [
|
|
|
74
75
|
|
|
75
76
|
[[package]]
|
|
76
77
|
name = "either"
|
|
77
|
-
version = "1.
|
|
78
|
+
version = "1.15.0"
|
|
78
79
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
79
|
-
checksum = "
|
|
80
|
+
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
|
81
|
+
|
|
82
|
+
[[package]]
|
|
83
|
+
name = "equivalent"
|
|
84
|
+
version = "1.0.2"
|
|
85
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
86
|
+
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
87
|
+
|
|
88
|
+
[[package]]
|
|
89
|
+
name = "find-msvc-tools"
|
|
90
|
+
version = "0.1.6"
|
|
91
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
92
|
+
checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff"
|
|
80
93
|
|
|
81
94
|
[[package]]
|
|
82
95
|
name = "glob"
|
|
83
|
-
version = "0.3.
|
|
96
|
+
version = "0.3.3"
|
|
84
97
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
85
|
-
checksum = "
|
|
98
|
+
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
|
99
|
+
|
|
100
|
+
[[package]]
|
|
101
|
+
name = "hashbrown"
|
|
102
|
+
version = "0.16.1"
|
|
103
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
104
|
+
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
|
105
|
+
|
|
106
|
+
[[package]]
|
|
107
|
+
name = "indexmap"
|
|
108
|
+
version = "2.12.1"
|
|
109
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
110
|
+
checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
|
|
111
|
+
dependencies = [
|
|
112
|
+
"equivalent",
|
|
113
|
+
"hashbrown",
|
|
114
|
+
]
|
|
86
115
|
|
|
87
116
|
[[package]]
|
|
88
117
|
name = "itertools"
|
|
@@ -93,6 +122,12 @@ dependencies = [
|
|
|
93
122
|
"either",
|
|
94
123
|
]
|
|
95
124
|
|
|
125
|
+
[[package]]
|
|
126
|
+
name = "itoa"
|
|
127
|
+
version = "1.0.17"
|
|
128
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
129
|
+
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
|
130
|
+
|
|
96
131
|
[[package]]
|
|
97
132
|
name = "lazy_static"
|
|
98
133
|
version = "1.5.0"
|
|
@@ -107,25 +142,25 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
|
|
107
142
|
|
|
108
143
|
[[package]]
|
|
109
144
|
name = "libc"
|
|
110
|
-
version = "0.2.
|
|
145
|
+
version = "0.2.178"
|
|
111
146
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
112
|
-
checksum = "
|
|
147
|
+
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
|
113
148
|
|
|
114
149
|
[[package]]
|
|
115
150
|
name = "libloading"
|
|
116
|
-
version = "0.8.
|
|
151
|
+
version = "0.8.9"
|
|
117
152
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
118
|
-
checksum = "
|
|
153
|
+
checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55"
|
|
119
154
|
dependencies = [
|
|
120
155
|
"cfg-if",
|
|
121
|
-
"windows-
|
|
156
|
+
"windows-link",
|
|
122
157
|
]
|
|
123
158
|
|
|
124
159
|
[[package]]
|
|
125
160
|
name = "magnus"
|
|
126
|
-
version = "0.
|
|
161
|
+
version = "0.8.2"
|
|
127
162
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
128
|
-
checksum = "
|
|
163
|
+
checksum = "3b36a5b126bbe97eb0d02d07acfeb327036c6319fd816139a49824a83b7f9012"
|
|
129
164
|
dependencies = [
|
|
130
165
|
"magnus-macros",
|
|
131
166
|
"rb-sys",
|
|
@@ -135,9 +170,9 @@ dependencies = [
|
|
|
135
170
|
|
|
136
171
|
[[package]]
|
|
137
172
|
name = "magnus-macros"
|
|
138
|
-
version = "0.
|
|
173
|
+
version = "0.8.0"
|
|
139
174
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
140
|
-
checksum = "
|
|
175
|
+
checksum = "47607461fd8e1513cb4f2076c197d8092d921a1ea75bd08af97398f593751892"
|
|
141
176
|
dependencies = [
|
|
142
177
|
"proc-macro2",
|
|
143
178
|
"quote",
|
|
@@ -146,9 +181,9 @@ dependencies = [
|
|
|
146
181
|
|
|
147
182
|
[[package]]
|
|
148
183
|
name = "memchr"
|
|
149
|
-
version = "2.7.
|
|
184
|
+
version = "2.7.6"
|
|
150
185
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
151
|
-
checksum = "
|
|
186
|
+
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
|
152
187
|
|
|
153
188
|
[[package]]
|
|
154
189
|
name = "minimal-lexical"
|
|
@@ -168,36 +203,36 @@ dependencies = [
|
|
|
168
203
|
|
|
169
204
|
[[package]]
|
|
170
205
|
name = "proc-macro2"
|
|
171
|
-
version = "1.0.
|
|
206
|
+
version = "1.0.104"
|
|
172
207
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
173
|
-
checksum = "
|
|
208
|
+
checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0"
|
|
174
209
|
dependencies = [
|
|
175
210
|
"unicode-ident",
|
|
176
211
|
]
|
|
177
212
|
|
|
178
213
|
[[package]]
|
|
179
214
|
name = "quote"
|
|
180
|
-
version = "1.0.
|
|
215
|
+
version = "1.0.42"
|
|
181
216
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
182
|
-
checksum = "
|
|
217
|
+
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
|
183
218
|
dependencies = [
|
|
184
219
|
"proc-macro2",
|
|
185
220
|
]
|
|
186
221
|
|
|
187
222
|
[[package]]
|
|
188
223
|
name = "rb-sys"
|
|
189
|
-
version = "0.9.
|
|
224
|
+
version = "0.9.123"
|
|
190
225
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
191
|
-
checksum = "
|
|
226
|
+
checksum = "45fb1a185af97ee456f1c9e56dbe6e2e662bec4fdeaf83c4c28e0e6adfb18816"
|
|
192
227
|
dependencies = [
|
|
193
228
|
"rb-sys-build",
|
|
194
229
|
]
|
|
195
230
|
|
|
196
231
|
[[package]]
|
|
197
232
|
name = "rb-sys-build"
|
|
198
|
-
version = "0.9.
|
|
233
|
+
version = "0.9.123"
|
|
199
234
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
200
|
-
checksum = "
|
|
235
|
+
checksum = "a58ebd02d7a6033e6a5f6f8d150c1e9f16506039092b84a73e6bedce6d3adf41"
|
|
201
236
|
dependencies = [
|
|
202
237
|
"bindgen",
|
|
203
238
|
"lazy_static",
|
|
@@ -210,15 +245,15 @@ dependencies = [
|
|
|
210
245
|
|
|
211
246
|
[[package]]
|
|
212
247
|
name = "rb-sys-env"
|
|
213
|
-
version = "0.
|
|
248
|
+
version = "0.2.2"
|
|
214
249
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
215
|
-
checksum = "
|
|
250
|
+
checksum = "08f8d2924cf136a1315e2b4c7460a39f62ef11ee5d522df9b2750fab55b868b6"
|
|
216
251
|
|
|
217
252
|
[[package]]
|
|
218
253
|
name = "regex"
|
|
219
|
-
version = "1.
|
|
254
|
+
version = "1.12.2"
|
|
220
255
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
221
|
-
checksum = "
|
|
256
|
+
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
|
|
222
257
|
dependencies = [
|
|
223
258
|
"aho-corasick",
|
|
224
259
|
"memchr",
|
|
@@ -228,9 +263,9 @@ dependencies = [
|
|
|
228
263
|
|
|
229
264
|
[[package]]
|
|
230
265
|
name = "regex-automata"
|
|
231
|
-
version = "0.4.
|
|
266
|
+
version = "0.4.13"
|
|
232
267
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
233
|
-
checksum = "
|
|
268
|
+
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
|
|
234
269
|
dependencies = [
|
|
235
270
|
"aho-corasick",
|
|
236
271
|
"memchr",
|
|
@@ -239,9 +274,9 @@ dependencies = [
|
|
|
239
274
|
|
|
240
275
|
[[package]]
|
|
241
276
|
name = "regex-syntax"
|
|
242
|
-
version = "0.8.
|
|
277
|
+
version = "0.8.8"
|
|
243
278
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
244
|
-
checksum = "
|
|
279
|
+
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
|
|
245
280
|
|
|
246
281
|
[[package]]
|
|
247
282
|
name = "rustc-hash"
|
|
@@ -251,118 +286,128 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
|
|
251
286
|
|
|
252
287
|
[[package]]
|
|
253
288
|
name = "seq-macro"
|
|
254
|
-
version = "0.3.
|
|
289
|
+
version = "0.3.6"
|
|
255
290
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
256
|
-
checksum = "
|
|
291
|
+
checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
|
257
292
|
|
|
258
293
|
[[package]]
|
|
259
|
-
name = "
|
|
260
|
-
version = "1.
|
|
294
|
+
name = "serde"
|
|
295
|
+
version = "1.0.228"
|
|
261
296
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
262
|
-
checksum = "
|
|
297
|
+
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
298
|
+
dependencies = [
|
|
299
|
+
"serde_core",
|
|
300
|
+
]
|
|
263
301
|
|
|
264
302
|
[[package]]
|
|
265
|
-
name = "
|
|
266
|
-
version = "1.
|
|
303
|
+
name = "serde_core"
|
|
304
|
+
version = "1.0.228"
|
|
267
305
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
268
|
-
checksum = "
|
|
306
|
+
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
307
|
+
dependencies = [
|
|
308
|
+
"serde_derive",
|
|
309
|
+
]
|
|
269
310
|
|
|
270
311
|
[[package]]
|
|
271
|
-
name = "
|
|
272
|
-
version = "
|
|
312
|
+
name = "serde_derive"
|
|
313
|
+
version = "1.0.228"
|
|
273
314
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
274
|
-
checksum = "
|
|
315
|
+
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
275
316
|
dependencies = [
|
|
276
317
|
"proc-macro2",
|
|
277
318
|
"quote",
|
|
278
|
-
"
|
|
319
|
+
"syn",
|
|
279
320
|
]
|
|
280
321
|
|
|
281
322
|
[[package]]
|
|
282
|
-
name = "
|
|
283
|
-
version = "0.
|
|
323
|
+
name = "serde_json"
|
|
324
|
+
version = "1.0.148"
|
|
284
325
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
285
|
-
checksum = "
|
|
326
|
+
checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da"
|
|
286
327
|
dependencies = [
|
|
287
|
-
"
|
|
288
|
-
"
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
version = "0.1.0"
|
|
294
|
-
dependencies = [
|
|
295
|
-
"libloading",
|
|
296
|
-
"magnus",
|
|
297
|
-
"tree-sitter",
|
|
328
|
+
"indexmap",
|
|
329
|
+
"itoa",
|
|
330
|
+
"memchr",
|
|
331
|
+
"serde",
|
|
332
|
+
"serde_core",
|
|
333
|
+
"zmij",
|
|
298
334
|
]
|
|
299
335
|
|
|
300
336
|
[[package]]
|
|
301
|
-
name = "
|
|
302
|
-
version = "1.
|
|
337
|
+
name = "shell-words"
|
|
338
|
+
version = "1.1.1"
|
|
303
339
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
304
|
-
checksum = "
|
|
340
|
+
checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77"
|
|
305
341
|
|
|
306
342
|
[[package]]
|
|
307
|
-
name = "
|
|
308
|
-
version = "
|
|
343
|
+
name = "shlex"
|
|
344
|
+
version = "1.3.0"
|
|
309
345
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
310
|
-
checksum = "
|
|
311
|
-
dependencies = [
|
|
312
|
-
"windows_aarch64_gnullvm",
|
|
313
|
-
"windows_aarch64_msvc",
|
|
314
|
-
"windows_i686_gnu",
|
|
315
|
-
"windows_i686_gnullvm",
|
|
316
|
-
"windows_i686_msvc",
|
|
317
|
-
"windows_x86_64_gnu",
|
|
318
|
-
"windows_x86_64_gnullvm",
|
|
319
|
-
"windows_x86_64_msvc",
|
|
320
|
-
]
|
|
346
|
+
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
|
321
347
|
|
|
322
348
|
[[package]]
|
|
323
|
-
name = "
|
|
324
|
-
version = "0.
|
|
349
|
+
name = "streaming-iterator"
|
|
350
|
+
version = "0.1.9"
|
|
325
351
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
326
|
-
checksum = "
|
|
352
|
+
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
|
|
327
353
|
|
|
328
354
|
[[package]]
|
|
329
|
-
name = "
|
|
330
|
-
version = "0.
|
|
355
|
+
name = "syn"
|
|
356
|
+
version = "2.0.112"
|
|
331
357
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
332
|
-
checksum = "
|
|
358
|
+
checksum = "21f182278bf2d2bcb3c88b1b08a37df029d71ce3d3ae26168e3c653b213b99d4"
|
|
359
|
+
dependencies = [
|
|
360
|
+
"proc-macro2",
|
|
361
|
+
"quote",
|
|
362
|
+
"unicode-ident",
|
|
363
|
+
]
|
|
333
364
|
|
|
334
365
|
[[package]]
|
|
335
|
-
name = "
|
|
336
|
-
version = "0.
|
|
366
|
+
name = "tree-sitter"
|
|
367
|
+
version = "0.26.3"
|
|
337
368
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
338
|
-
checksum = "
|
|
369
|
+
checksum = "974d205cc395652cfa8b37daa053fe56eebd429acf8dc055503fee648dae981e"
|
|
370
|
+
dependencies = [
|
|
371
|
+
"cc",
|
|
372
|
+
"regex",
|
|
373
|
+
"regex-syntax",
|
|
374
|
+
"serde_json",
|
|
375
|
+
"streaming-iterator",
|
|
376
|
+
"tree-sitter-language",
|
|
377
|
+
]
|
|
339
378
|
|
|
340
379
|
[[package]]
|
|
341
|
-
name = "
|
|
342
|
-
version = "0.
|
|
380
|
+
name = "tree-sitter-language"
|
|
381
|
+
version = "0.1.6"
|
|
343
382
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
344
|
-
checksum = "
|
|
383
|
+
checksum = "4ae62f7eae5eb549c71b76658648b72cc6111f2d87d24a1e31fa907f4943e3ce"
|
|
345
384
|
|
|
346
385
|
[[package]]
|
|
347
|
-
name = "
|
|
348
|
-
version = "0.
|
|
349
|
-
|
|
350
|
-
|
|
386
|
+
name = "tree_stump"
|
|
387
|
+
version = "0.1.0"
|
|
388
|
+
dependencies = [
|
|
389
|
+
"libloading",
|
|
390
|
+
"magnus",
|
|
391
|
+
"rb-sys",
|
|
392
|
+
"streaming-iterator",
|
|
393
|
+
"tree-sitter",
|
|
394
|
+
"tree-sitter-language",
|
|
395
|
+
]
|
|
351
396
|
|
|
352
397
|
[[package]]
|
|
353
|
-
name = "
|
|
354
|
-
version = "0.
|
|
398
|
+
name = "unicode-ident"
|
|
399
|
+
version = "1.0.22"
|
|
355
400
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
356
|
-
checksum = "
|
|
401
|
+
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
|
357
402
|
|
|
358
403
|
[[package]]
|
|
359
|
-
name = "
|
|
360
|
-
version = "0.
|
|
404
|
+
name = "windows-link"
|
|
405
|
+
version = "0.2.1"
|
|
361
406
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
362
|
-
checksum = "
|
|
407
|
+
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
|
363
408
|
|
|
364
409
|
[[package]]
|
|
365
|
-
name = "
|
|
366
|
-
version = "0.
|
|
410
|
+
name = "zmij"
|
|
411
|
+
version = "1.0.8"
|
|
367
412
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
368
|
-
checksum = "
|
|
413
|
+
checksum = "317f17ff091ac4515f17cc7a190d2769a8c9a96d227de5d64b500b01cda8f2cd"
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Tomohiro Hashidate (joker1007)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# TreeStump
|
|
2
|
+
|
|
2
3
|
[](https://github.com/joker1007/tree_stump/actions/workflows/rspec.yml)
|
|
3
4
|
|
|
4
|
-
[tree-sitter](https://github.com/tree-sitter/tree-sitter) binding for Ruby written by Rust.
|
|
5
|
+
[tree-sitter](https://github.com/tree-sitter/tree-sitter) binding for MRI Ruby written by Rust.
|
|
5
6
|
|
|
6
7
|
## Installation
|
|
7
8
|
|
|
@@ -13,6 +14,40 @@ If bundler is not being used to manage dependencies, install the gem by executin
|
|
|
13
14
|
|
|
14
15
|
$ gem install tree_stump
|
|
15
16
|
|
|
17
|
+
## Platform Compatibility
|
|
18
|
+
|
|
19
|
+
tree_stump is a Rust native extension using [magnus](https://github.com/matsadler/magnus) and [rb-sys](https://github.com/oxidize-rb/rb-sys) for Ruby bindings.
|
|
20
|
+
|
|
21
|
+
| Platform | Supported | Notes |
|
|
22
|
+
|----------|-----------|-------|
|
|
23
|
+
| **MRI Ruby** | ✅ Yes | Full support (3.1+) |
|
|
24
|
+
| **JRuby** | ❌ No | JRuby runs on the JVM and cannot load native `.so` extensions |
|
|
25
|
+
| **TruffleRuby** | ❌ No | magnus/rb-sys are incompatible with TruffleRuby's C API emulation |
|
|
26
|
+
|
|
27
|
+
<details>
|
|
28
|
+
<summary>Why JRuby doesn't work</summary>
|
|
29
|
+
|
|
30
|
+
JRuby runs on the Java Virtual Machine and cannot load native C/Rust extensions (`.so` files). The `rb-sys` build system fails during `extconf.rb` because JRuby doesn't provide the platform detection APIs that native extensions require.
|
|
31
|
+
|
|
32
|
+
**Alternative for JRuby**: Use [java-tree-sitter](https://github.com/tree-sitter/java-tree-sitter) / [jtreesitter](https://central.sonatype.com/artifact/io.github.tree-sitter/jtreesitter) directly, or use [TreeHaver](https://github.com/kettle-rb/tree_haver)'s Java backend which wraps it.
|
|
33
|
+
|
|
34
|
+
</details>
|
|
35
|
+
|
|
36
|
+
<details>
|
|
37
|
+
<summary>Why TruffleRuby doesn't work</summary>
|
|
38
|
+
|
|
39
|
+
TruffleRuby implements Ruby on GraalVM, not as a C program. While it has a C API emulation layer (via Sulong/LLVM), this layer doesn't expose all of MRI's internal structures that `magnus` requires:
|
|
40
|
+
|
|
41
|
+
- Missing C API functions: `rb_bug`, `rb_warning`, `rb_gc_writebarrier`, `rb_data_define`, etc.
|
|
42
|
+
- Missing struct fields: `RBasic.flags`, `RBasic.klass`
|
|
43
|
+
- Missing constants: `ruby_rvalue_flags`, `RUBY_ENC_CODERANGE_MASK`
|
|
44
|
+
|
|
45
|
+
These are MRI implementation details that TruffleRuby doesn't need (and can't easily provide) because its objects are implemented completely differently.
|
|
46
|
+
|
|
47
|
+
**Alternative for TruffleRuby**: Use [TreeHaver](https://github.com/kettle-rb/tree_haver) with non-tree-sitter backends (prism, psych, citrus) for parsing needs.
|
|
48
|
+
|
|
49
|
+
</details>
|
|
50
|
+
|
|
16
51
|
## Usage
|
|
17
52
|
|
|
18
53
|
```ruby
|
|
@@ -49,12 +84,14 @@ puts tree.root_node.to_sexp
|
|
|
49
84
|
### Requirements
|
|
50
85
|
|
|
51
86
|
- Rust Toolchain
|
|
87
|
+
- MRI Ruby (not JRuby or TruffleRuby)
|
|
52
88
|
- tree-sitter-ruby
|
|
53
89
|
|
|
54
90
|
1. Download source of tree-sitter-ruby from [GitHub Repository](https://github.com/tree-sitter/tree-sitter-ruby).
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
91
|
+
2. Extract tree-sitter-ruby source
|
|
92
|
+
3. mv tree-sitter-ruby-v{version_num} to tree_stump/tree-sitter-ruby
|
|
93
|
+
4. Execute `make` in tree-sitter-ruby directory
|
|
94
|
+
5. Execute `bundle exec rake compile`
|
|
58
95
|
|
|
59
96
|
## Contributing
|
|
60
97
|
|
data/ext/tree_stump/Cargo.toml
CHANGED
|
@@ -9,6 +9,9 @@ publish = false
|
|
|
9
9
|
crate-type = ["cdylib"]
|
|
10
10
|
|
|
11
11
|
[dependencies]
|
|
12
|
-
magnus = { version = "0.
|
|
13
|
-
|
|
12
|
+
magnus = { version = "0.8.2" }
|
|
13
|
+
rb-sys = { version = "0.9.119", features = ["stable-api-compiled-fallback"] }
|
|
14
|
+
tree-sitter = "0.26"
|
|
15
|
+
tree-sitter-language = "0.1"
|
|
14
16
|
libloading = "~0.8.4"
|
|
17
|
+
streaming-iterator = "0.1"
|
|
@@ -8,7 +8,11 @@ unsafe impl Send for LanguageRef<'_> {}
|
|
|
8
8
|
|
|
9
9
|
impl<'a> LanguageRef<'a> {
|
|
10
10
|
pub fn version(&self) -> usize {
|
|
11
|
-
self.raw_language_ref.
|
|
11
|
+
self.raw_language_ref.abi_version()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub fn abi_version(&self) -> usize {
|
|
15
|
+
self.raw_language_ref.abi_version()
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
pub fn node_kind_count(&self) -> usize {
|
data/ext/tree_stump/src/lib.rs
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
use magnus::{function, method, prelude::*, typed_data, value::Lazy, Error, RClass, Ruby};
|
|
2
2
|
|
|
3
3
|
use libloading::Library;
|
|
4
|
-
use tree_sitter::ffi::TSLanguage;
|
|
5
4
|
|
|
6
5
|
use std::collections::HashMap;
|
|
7
6
|
use std::sync::Mutex;
|
|
@@ -18,15 +17,16 @@ use crate::language::{LanguageRef, LookaheadIterator};
|
|
|
18
17
|
use crate::parser::Parser;
|
|
19
18
|
use crate::query::{Query, QueryCursor, QueryMatch};
|
|
20
19
|
use crate::tree::{Node, Tree, TreeCursor};
|
|
20
|
+
use crate::util::build_error;
|
|
21
21
|
|
|
22
22
|
pub static LANG_LIBRARIES: OnceLock<Mutex<HashMap<String, Library>>> = OnceLock::new();
|
|
23
23
|
pub static LANG_LANGUAGES: OnceLock<Mutex<HashMap<String, tree_sitter::Language>>> =
|
|
24
24
|
OnceLock::new();
|
|
25
25
|
|
|
26
26
|
pub static QUERY_CAPTURE_CLASS: Lazy<RClass> =
|
|
27
|
-
Lazy::new(|ruby| ruby.define_struct(None, ("node", "index")).
|
|
27
|
+
Lazy::new(|ruby| ruby.define_struct(None, ("node", "index")).expect("Failed to define QueryCapture struct"));
|
|
28
28
|
|
|
29
|
-
fn register_lang(lang: String, path: String) -> () {
|
|
29
|
+
fn register_lang(lang: String, path: String) -> Result<(), Error> {
|
|
30
30
|
let func_name = String::from("tree_sitter_") + ⟨
|
|
31
31
|
let language;
|
|
32
32
|
|
|
@@ -34,26 +34,42 @@ fn register_lang(lang: String, path: String) -> () {
|
|
|
34
34
|
let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
|
|
35
35
|
|
|
36
36
|
unsafe {
|
|
37
|
-
let mut libraries = libraries.lock().
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
let mut libraries = libraries.lock().map_err(|e| {
|
|
38
|
+
build_error(format!("Failed to acquire library lock: {}", e))
|
|
39
|
+
})?;
|
|
40
|
+
let lib = match libraries.entry(lang.clone()) {
|
|
41
|
+
std::collections::hash_map::Entry::Occupied(e) => e.into_mut(),
|
|
42
|
+
std::collections::hash_map::Entry::Vacant(e) => {
|
|
43
|
+
let loaded = Library::new(&path).map_err(|err| {
|
|
44
|
+
build_error(format!("Failed to load library '{}': {}", path, err))
|
|
45
|
+
})?;
|
|
46
|
+
e.insert(loaded)
|
|
47
|
+
}
|
|
48
|
+
};
|
|
42
49
|
|
|
43
|
-
|
|
44
|
-
|
|
50
|
+
// In tree-sitter 0.26+, we use tree_sitter_language::LanguageFn
|
|
51
|
+
let func: libloading::Symbol<tree_sitter_language::LanguageFn> =
|
|
52
|
+
lib.get(func_name.as_bytes()).map_err(|err| {
|
|
53
|
+
build_error(format!("Failed to find symbol '{}': {}", func_name, err))
|
|
54
|
+
})?;
|
|
45
55
|
|
|
46
|
-
language = tree_sitter::Language::
|
|
56
|
+
language = tree_sitter::Language::from(*func);
|
|
47
57
|
|
|
48
|
-
let mut languages = languages.lock().
|
|
58
|
+
let mut languages = languages.lock().map_err(|e| {
|
|
59
|
+
build_error(format!("Failed to acquire language lock: {}", e))
|
|
60
|
+
})?;
|
|
49
61
|
languages.insert(lang.to_string(), language);
|
|
50
62
|
};
|
|
63
|
+
|
|
64
|
+
Ok(())
|
|
51
65
|
}
|
|
52
66
|
|
|
53
|
-
fn available_langs() -> Vec<String> {
|
|
67
|
+
fn available_langs() -> Result<Vec<String>, Error> {
|
|
54
68
|
let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
|
|
55
|
-
let languages = languages.lock().
|
|
56
|
-
|
|
69
|
+
let languages = languages.lock().map_err(|e| {
|
|
70
|
+
build_error(format!("Failed to acquire language lock: {}", e))
|
|
71
|
+
})?;
|
|
72
|
+
Ok(languages.keys().cloned().collect())
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
#[magnus::init]
|
|
@@ -67,8 +83,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
67
83
|
parser_class.define_method("set_language", method!(Parser::set_language, 1))?;
|
|
68
84
|
parser_class.define_method("parse", method!(Parser::parse, 1))?;
|
|
69
85
|
parser_class.define_method("reset", method!(Parser::reset, 0))?;
|
|
70
|
-
|
|
71
|
-
parser_class.define_method("set_timeout_micros", method!(Parser::set_timeout_micros, 1))?;
|
|
86
|
+
// NOTE: timeout_micros was removed in tree-sitter 0.26
|
|
72
87
|
parser_class.define_method("build_query", method!(Parser::build_query, 1))?;
|
|
73
88
|
|
|
74
89
|
let tree_class = namespace.define_class("Tree", ruby.class_object())?;
|
|
@@ -107,15 +122,19 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
107
122
|
node_class.define_method("eql?", method!(<Node as typed_data::IsEql>::is_eql, 1))?;
|
|
108
123
|
node_class.define_method("id", method!(Node::id, 0))?;
|
|
109
124
|
node_class.define_method("kind", method!(Node::kind, 0))?;
|
|
125
|
+
node_class.define_method("type", method!(Node::kind, 0))?; // Alias for compatibility
|
|
110
126
|
node_class.define_method("kind_id", method!(Node::kind_id, 0))?;
|
|
111
127
|
node_class.define_method("grammar_id", method!(Node::grammar_id, 0))?;
|
|
112
128
|
node_class.define_method("grammar_name", method!(Node::grammar_name, 0))?;
|
|
113
129
|
node_class.define_method("language", method!(Node::language, 0))?;
|
|
114
130
|
node_class.define_method("is_named?", method!(Node::is_named, 0))?;
|
|
131
|
+
node_class.define_method("named?", method!(Node::is_named, 0))?; // Alias for compatibility
|
|
115
132
|
node_class.define_method("is_extra?", method!(Node::is_extra, 0))?;
|
|
116
133
|
node_class.define_method("has_changes?", method!(Node::has_changes, 0))?;
|
|
117
134
|
node_class.define_method("has_error?", method!(Node::has_error, 0))?;
|
|
118
135
|
node_class.define_method("is_error?", method!(Node::is_error, 0))?;
|
|
136
|
+
node_class.define_method("is_missing?", method!(Node::is_missing, 0))?;
|
|
137
|
+
node_class.define_method("missing?", method!(Node::is_missing, 0))?; // Alias for compatibility
|
|
119
138
|
node_class.define_method("parse_state", method!(Node::parse_state, 0))?;
|
|
120
139
|
node_class.define_method("next_parse_state", method!(Node::next_parse_state, 0))?;
|
|
121
140
|
node_class.define_method("start_byte", method!(Node::start_byte, 0))?;
|
|
@@ -123,7 +142,9 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
123
142
|
node_class.define_method("byte_range", method!(Node::byte_range, 0))?;
|
|
124
143
|
node_class.define_method("range", method!(Node::range, 0))?;
|
|
125
144
|
node_class.define_method("start_position", method!(Node::start_position, 0))?;
|
|
145
|
+
node_class.define_method("start_point", method!(Node::start_position, 0))?; // Alias for compatibility
|
|
126
146
|
node_class.define_method("end_position", method!(Node::end_position, 0))?;
|
|
147
|
+
node_class.define_method("end_point", method!(Node::end_position, 0))?; // Alias for compatibility
|
|
127
148
|
node_class.define_method("child", method!(Node::child, 1))?;
|
|
128
149
|
node_class.define_method("child_count", method!(Node::child_count, 0))?;
|
|
129
150
|
node_class.define_method("named_child", method!(Node::named_child, 1))?;
|
|
@@ -180,6 +201,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
180
201
|
|
|
181
202
|
node_class.define_method("to_sexp", method!(Node::to_sexp, 0))?;
|
|
182
203
|
node_class.define_method("utf8_text", method!(Node::utf8_text, 1))?;
|
|
204
|
+
node_class.define_method("text", method!(Node::utf8_text, 1))?; // Alias for compatibility
|
|
183
205
|
node_class.define_method("walk", method!(Node::walk, 0))?;
|
|
184
206
|
|
|
185
207
|
node_class.define_method("inspect", method!(Node::inspect, 0))?;
|
|
@@ -215,6 +237,7 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
215
237
|
|
|
216
238
|
let language_class = namespace.define_class("LanguageRef", ruby.class_object())?;
|
|
217
239
|
language_class.define_method("version", method!(LanguageRef::version, 0))?;
|
|
240
|
+
language_class.define_method("abi_version", method!(LanguageRef::abi_version, 0))?;
|
|
218
241
|
language_class.define_method("node_kind_count", method!(LanguageRef::node_kind_count, 0))?;
|
|
219
242
|
language_class.define_method(
|
|
220
243
|
"parse_state_count",
|
|
@@ -282,7 +305,8 @@ fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
|
282
305
|
)?;
|
|
283
306
|
|
|
284
307
|
Lazy::force(&QUERY_CAPTURE_CLASS, ruby);
|
|
285
|
-
let struct_class = Lazy::try_get_inner(&QUERY_CAPTURE_CLASS)
|
|
308
|
+
let struct_class = Lazy::try_get_inner(&QUERY_CAPTURE_CLASS)
|
|
309
|
+
.ok_or_else(|| build_error("Failed to get QueryCapture struct class"))?;
|
|
286
310
|
namespace.const_set("QueryCapture", struct_class)?;
|
|
287
311
|
|
|
288
312
|
let query_match_class = namespace.define_class("QueryMatch", ruby.class_object())?;
|
|
@@ -10,23 +10,36 @@ use std::sync::{Arc, Mutex};
|
|
|
10
10
|
#[magnus::wrap(class = "TreeStump::Parser")]
|
|
11
11
|
pub struct Parser {
|
|
12
12
|
raw_parser: RefCell<tree_sitter::Parser>,
|
|
13
|
+
/// The name of the currently set language, used to look up from the global map
|
|
14
|
+
language_name: RefCell<Option<String>>,
|
|
13
15
|
}
|
|
14
16
|
|
|
15
17
|
impl Parser {
|
|
16
18
|
pub fn new() -> Self {
|
|
17
19
|
Self {
|
|
18
20
|
raw_parser: RefCell::new(tree_sitter::Parser::new()),
|
|
21
|
+
language_name: RefCell::new(None),
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
pub fn set_language(&self, lang: String) -> Result<bool, magnus::Error> {
|
|
23
26
|
let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
|
|
24
|
-
let languages = languages.lock().
|
|
27
|
+
let languages = languages.lock().map_err(|e| {
|
|
28
|
+
build_error(format!("Failed to acquire language lock: {}", e))
|
|
29
|
+
})?;
|
|
25
30
|
let language = languages.get(&lang);
|
|
26
31
|
match language {
|
|
27
32
|
Some(language) => {
|
|
33
|
+
// tree-sitter 0.26+ set_language takes impl Into<LanguageRef<'_>>
|
|
28
34
|
let result = self.raw_parser.borrow_mut().set_language(language);
|
|
29
|
-
result.map_or_else(
|
|
35
|
+
result.map_or_else(
|
|
36
|
+
|e| Err(build_error(e.to_string())),
|
|
37
|
+
|_| {
|
|
38
|
+
// Store the language name for later lookup
|
|
39
|
+
*self.language_name.borrow_mut() = Some(lang);
|
|
40
|
+
Ok(true)
|
|
41
|
+
},
|
|
42
|
+
)
|
|
30
43
|
}
|
|
31
44
|
None => Err(build_error(format!("Language {} is not registered", lang))),
|
|
32
45
|
}
|
|
@@ -45,23 +58,25 @@ impl Parser {
|
|
|
45
58
|
self.raw_parser.borrow_mut().reset();
|
|
46
59
|
}
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
61
|
+
// NOTE: timeout_micros and set_timeout_micros were removed in tree-sitter 0.26
|
|
62
|
+
// The timeout functionality is no longer available in the C/Rust API
|
|
51
63
|
|
|
52
|
-
pub fn
|
|
53
|
-
self.
|
|
54
|
-
|
|
64
|
+
pub fn build_query(&self, source: String) -> Result<Query, magnus::Error> {
|
|
65
|
+
let lang_name = self.language_name.borrow();
|
|
66
|
+
let lang_name = lang_name.as_ref().ok_or_else(|| {
|
|
67
|
+
build_error("No language set on parser")
|
|
68
|
+
})?;
|
|
55
69
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
let languages = LANG_LANGUAGES.get_or_init(|| Mutex::new(HashMap::new()));
|
|
71
|
+
let languages = languages.lock().map_err(|e| {
|
|
72
|
+
build_error(format!("Failed to acquire language lock: {}", e))
|
|
73
|
+
})?;
|
|
59
74
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
75
|
+
let language = languages.get(lang_name).ok_or_else(|| {
|
|
76
|
+
build_error(format!("Language {} is no longer registered", lang_name))
|
|
77
|
+
})?;
|
|
78
|
+
|
|
79
|
+
// Clone the language to pass to Query::new
|
|
80
|
+
Query::new(language, source)
|
|
66
81
|
}
|
|
67
82
|
}
|
data/ext/tree_stump/src/query.rs
CHANGED
|
@@ -7,6 +7,7 @@ use magnus::{
|
|
|
7
7
|
value::{InnerRef, Opaque, ReprValue},
|
|
8
8
|
Class, Error, IntoValue, RArray, RStruct, RTypedData, Ruby, Value,
|
|
9
9
|
};
|
|
10
|
+
use streaming_iterator::StreamingIterator;
|
|
10
11
|
|
|
11
12
|
use crate::{data::Point, tree::Node, util::build_error, QUERY_CAPTURE_CLASS};
|
|
12
13
|
|
|
@@ -45,12 +46,14 @@ impl Query {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
pub fn capture_quantifiers(&self, index: usize) -> Result<RArray, Error> {
|
|
49
|
+
let ruby = Ruby::get().map_err(|_| {
|
|
50
|
+
build_error("Ruby is not initialized")
|
|
51
|
+
})?;
|
|
48
52
|
let raw_query = self.raw_query.borrow();
|
|
49
53
|
let quantifiers = raw_query
|
|
50
54
|
.capture_quantifiers(index)
|
|
51
55
|
.iter()
|
|
52
|
-
.map(|q| format!("{:?}", q).
|
|
53
|
-
let ruby = Ruby::get().expect("Ruby is not initialized");
|
|
56
|
+
.map(|q| format!("{:?}", q).into_symbol_with(&ruby));
|
|
54
57
|
let array = ruby.ary_from_iter(quantifiers);
|
|
55
58
|
Ok(array)
|
|
56
59
|
}
|
|
@@ -128,11 +131,12 @@ impl QueryCursor {
|
|
|
128
131
|
let mut cursor = rb_self.raw_cursor.borrow_mut();
|
|
129
132
|
let raw_query = query.raw_query.borrow();
|
|
130
133
|
|
|
131
|
-
let matches = cursor.matches(&raw_query, node.get_raw_node(), source.as_bytes());
|
|
134
|
+
let mut matches = cursor.matches(&raw_query, node.get_raw_node(), source.as_bytes());
|
|
132
135
|
let struct_class = QUERY_CAPTURE_CLASS.get_inner_ref_with(ruby);
|
|
133
136
|
let array = ruby.ary_new();
|
|
134
137
|
|
|
135
|
-
|
|
138
|
+
// tree-sitter 0.24+ uses StreamingIterator instead of Iterator
|
|
139
|
+
while let Some(m) = matches.next() {
|
|
136
140
|
let captures = ruby.ary_new();
|
|
137
141
|
for c in m.captures {
|
|
138
142
|
let r_struct = RStruct::from_value(
|
|
@@ -153,7 +157,7 @@ impl QueryCursor {
|
|
|
153
157
|
} else {
|
|
154
158
|
Ok(Yield::Enumerator(rb_self.enumeratorize(
|
|
155
159
|
"matches",
|
|
156
|
-
(query, node, source.
|
|
160
|
+
(query, node, source.into_value_with(ruby)),
|
|
157
161
|
)))
|
|
158
162
|
}
|
|
159
163
|
}
|
|
@@ -184,10 +188,16 @@ impl QueryCursor {
|
|
|
184
188
|
let start: Value = range.beg()?;
|
|
185
189
|
let end: Value = range.end()?;
|
|
186
190
|
|
|
187
|
-
let
|
|
191
|
+
let ruby = Ruby::get().map_err(|_| build_error("Ruby is not initialized"))?;
|
|
192
|
+
|
|
193
|
+
let start_typed_data = RTypedData::from_value(start).ok_or_else(|| {
|
|
194
|
+
Error::new(ruby.exception_type_error(), "Expected typed data for start point")
|
|
195
|
+
})?;
|
|
188
196
|
let start = start_typed_data.get::<Point>()?;
|
|
189
197
|
|
|
190
|
-
let end_typed_data = RTypedData::from_value(end).
|
|
198
|
+
let end_typed_data = RTypedData::from_value(end).ok_or_else(|| {
|
|
199
|
+
Error::new(ruby.exception_type_error(), "Expected typed data for end point")
|
|
200
|
+
})?;
|
|
191
201
|
let end = end_typed_data.get::<Point>()?;
|
|
192
202
|
|
|
193
203
|
let point_range = start.into_raw()..end.into_raw();
|
data/ext/tree_stump/src/tree.rs
CHANGED
|
@@ -60,7 +60,7 @@ pub struct TreeCursor<'cursor> {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
impl<'cursor> TreeCursor<'cursor> {
|
|
63
|
-
pub fn node(&self) -> Node {
|
|
63
|
+
pub fn node(&self) -> Node<'_> {
|
|
64
64
|
Node {
|
|
65
65
|
raw_tree: Arc::clone(&self.raw_tree),
|
|
66
66
|
raw_node: self.raw_cursor.borrow().node(),
|
|
@@ -192,6 +192,10 @@ impl<'tree> Node<'tree> {
|
|
|
192
192
|
self.raw_node.is_error()
|
|
193
193
|
}
|
|
194
194
|
|
|
195
|
+
pub fn is_missing(&self) -> bool {
|
|
196
|
+
self.raw_node.is_missing()
|
|
197
|
+
}
|
|
198
|
+
|
|
195
199
|
pub fn parse_state(&self) -> u16 {
|
|
196
200
|
self.raw_node.parse_state()
|
|
197
201
|
}
|
|
@@ -225,7 +229,8 @@ impl<'tree> Node<'tree> {
|
|
|
225
229
|
}
|
|
226
230
|
|
|
227
231
|
pub fn child(&self, index: usize) -> Option<Self> {
|
|
228
|
-
|
|
232
|
+
let index_u32: u32 = index.try_into().ok()?;
|
|
233
|
+
self.raw_node.child(index_u32).map(|node| Self {
|
|
229
234
|
raw_tree: Arc::clone(&self.raw_tree),
|
|
230
235
|
raw_node: node,
|
|
231
236
|
})
|
|
@@ -236,7 +241,8 @@ impl<'tree> Node<'tree> {
|
|
|
236
241
|
}
|
|
237
242
|
|
|
238
243
|
pub fn named_child(&self, index: usize) -> Option<Self> {
|
|
239
|
-
|
|
244
|
+
let index_u32: u32 = index.try_into().ok()?;
|
|
245
|
+
self.raw_node.named_child(index_u32).map(|node| Self {
|
|
240
246
|
raw_tree: Arc::clone(&self.raw_tree),
|
|
241
247
|
raw_node: node,
|
|
242
248
|
})
|
|
@@ -416,7 +422,7 @@ impl<'tree> Node<'tree> {
|
|
|
416
422
|
) -> Result<Option<Self>, Error> {
|
|
417
423
|
Ok(self
|
|
418
424
|
.raw_node
|
|
419
|
-
.
|
|
425
|
+
.child_with_descendant(descendant.raw_node)
|
|
420
426
|
.map(|node| Self {
|
|
421
427
|
raw_tree: Arc::clone(&self.raw_tree),
|
|
422
428
|
raw_node: node,
|
|
@@ -507,14 +513,14 @@ impl<'tree> Node<'tree> {
|
|
|
507
513
|
self.raw_node.to_sexp()
|
|
508
514
|
}
|
|
509
515
|
|
|
510
|
-
pub fn utf8_text(&self, source: String) -> String {
|
|
516
|
+
pub fn utf8_text(&self, source: String) -> Result<String, magnus::Error> {
|
|
511
517
|
self.raw_node
|
|
512
518
|
.utf8_text(source.as_bytes())
|
|
513
|
-
.
|
|
514
|
-
.
|
|
519
|
+
.map(|s| s.to_string())
|
|
520
|
+
.map_err(|e| build_error(format!("Failed to get utf8 text: {}", e)))
|
|
515
521
|
}
|
|
516
522
|
|
|
517
|
-
pub fn walk(&self) -> TreeCursor {
|
|
523
|
+
pub fn walk(&self) -> TreeCursor<'_> {
|
|
518
524
|
TreeCursor {
|
|
519
525
|
raw_tree: Arc::clone(&self.raw_tree),
|
|
520
526
|
raw_cursor: RefCell::new(self.raw_node.walk()),
|
data/ext/tree_stump/src/util.rs
CHANGED
|
@@ -7,13 +7,24 @@ use magnus::{
|
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
static ERROR_CLASS: Lazy<ExceptionClass> = Lazy::new(|ruby| {
|
|
10
|
-
let ex = ExceptionClass::from_value(
|
|
10
|
+
let ex = ExceptionClass::from_value(
|
|
11
|
+
ruby.eval("TreeStump::Error").expect("TreeStump::Error class not defined")
|
|
12
|
+
).expect("Failed to convert to ExceptionClass");
|
|
11
13
|
register_mark_object(ex);
|
|
12
14
|
ex
|
|
13
15
|
});
|
|
14
16
|
|
|
15
17
|
pub fn build_error(message: impl Into<Cow<'static, str>>) -> magnus::Error {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
18
|
+
match Ruby::get() {
|
|
19
|
+
Ok(ruby) => {
|
|
20
|
+
let error_class = ERROR_CLASS.get_inner_with(&ruby);
|
|
21
|
+
magnus::Error::new(error_class, message)
|
|
22
|
+
}
|
|
23
|
+
Err(_) => {
|
|
24
|
+
// Fallback when Ruby isn't initialized - use deprecated function
|
|
25
|
+
// This case should rarely happen in practice
|
|
26
|
+
#[allow(deprecated)]
|
|
27
|
+
magnus::Error::new(magnus::exception::runtime_error(), message)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
19
30
|
}
|
data/lib/tree_stump/version.rb
CHANGED
data/lib/tree_stump.rb
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative "tree_stump/version"
|
|
4
|
+
require_relative "tree_stump/tree_stump"
|
|
4
5
|
|
|
5
6
|
module TreeStump
|
|
6
|
-
class Error < StandardError;
|
|
7
|
-
def initialize(msg)
|
|
8
|
-
super(msg)
|
|
9
|
-
end
|
|
10
|
-
end
|
|
7
|
+
class Error < StandardError; end
|
|
11
8
|
|
|
12
9
|
class QueryError < Error; end
|
|
13
10
|
end
|
|
14
11
|
|
|
15
|
-
require_relative "tree_stump/tree_stump"
|
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tree_stump
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- joker1007
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rb_sys
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 0.9.119
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 0.9.119
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: rspec
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -24,17 +37,18 @@ dependencies:
|
|
|
24
37
|
- - ">="
|
|
25
38
|
- !ruby/object:Gem::Version
|
|
26
39
|
version: '0'
|
|
27
|
-
description: Ruby bindings for Tree-sitter written in Rust
|
|
40
|
+
description: Ruby bindings for Tree-sitter written in Rust using rb_sys and magnus.
|
|
28
41
|
email:
|
|
29
42
|
- kakyoin.hierophant@gmail.com
|
|
30
43
|
executables: []
|
|
31
44
|
extensions:
|
|
32
|
-
- ext/tree_stump/
|
|
45
|
+
- ext/tree_stump/extconf.rb
|
|
33
46
|
extra_rdoc_files: []
|
|
34
47
|
files:
|
|
35
48
|
- ".rspec"
|
|
36
49
|
- Cargo.lock
|
|
37
50
|
- Cargo.toml
|
|
51
|
+
- LICENSE
|
|
38
52
|
- README.md
|
|
39
53
|
- Rakefile
|
|
40
54
|
- ext/tree_stump/Cargo.toml
|
|
@@ -50,11 +64,10 @@ files:
|
|
|
50
64
|
- lib/tree_stump/version.rb
|
|
51
65
|
- sig/tree_house.rbs
|
|
52
66
|
homepage: https://github.com/joker1007/tree_stump
|
|
53
|
-
licenses:
|
|
67
|
+
licenses:
|
|
68
|
+
- MIT
|
|
54
69
|
metadata:
|
|
55
70
|
homepage_uri: https://github.com/joker1007/tree_stump
|
|
56
|
-
source_code_uri: https://github.com/joker1007/tree_stump
|
|
57
|
-
post_install_message:
|
|
58
71
|
rdoc_options: []
|
|
59
72
|
require_paths:
|
|
60
73
|
- lib
|
|
@@ -69,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
69
82
|
- !ruby/object:Gem::Version
|
|
70
83
|
version: 3.3.11
|
|
71
84
|
requirements: []
|
|
72
|
-
rubygems_version:
|
|
73
|
-
signing_key:
|
|
85
|
+
rubygems_version: 4.0.0.dev
|
|
74
86
|
specification_version: 4
|
|
75
87
|
summary: Ruby bindings for Tree-sitter written in Rust
|
|
76
88
|
test_files: []
|