ruby_tree_sitter 1.1.0-arm64-darwin-22

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +22 -0
  3. data/README.md +199 -0
  4. data/ext/tree_sitter/encoding.c +29 -0
  5. data/ext/tree_sitter/extconf.rb +149 -0
  6. data/ext/tree_sitter/input.c +127 -0
  7. data/ext/tree_sitter/input_edit.c +42 -0
  8. data/ext/tree_sitter/language.c +219 -0
  9. data/ext/tree_sitter/logger.c +228 -0
  10. data/ext/tree_sitter/macros.h +163 -0
  11. data/ext/tree_sitter/node.c +618 -0
  12. data/ext/tree_sitter/parser.c +398 -0
  13. data/ext/tree_sitter/point.c +26 -0
  14. data/ext/tree_sitter/quantifier.c +43 -0
  15. data/ext/tree_sitter/query.c +282 -0
  16. data/ext/tree_sitter/query_capture.c +28 -0
  17. data/ext/tree_sitter/query_cursor.c +215 -0
  18. data/ext/tree_sitter/query_error.c +41 -0
  19. data/ext/tree_sitter/query_match.c +44 -0
  20. data/ext/tree_sitter/query_predicate_step.c +83 -0
  21. data/ext/tree_sitter/range.c +35 -0
  22. data/ext/tree_sitter/repo.rb +121 -0
  23. data/ext/tree_sitter/symbol_type.c +46 -0
  24. data/ext/tree_sitter/tree.c +234 -0
  25. data/ext/tree_sitter/tree_cursor.c +269 -0
  26. data/ext/tree_sitter/tree_sitter.c +44 -0
  27. data/ext/tree_sitter/tree_sitter.h +107 -0
  28. data/lib/tree_sitter/node.rb +197 -0
  29. data/lib/tree_sitter/tree_sitter.bundle +0 -0
  30. data/lib/tree_sitter/version.rb +8 -0
  31. data/lib/tree_sitter.rb +14 -0
  32. data/lib/tree_stand/ast_modifier.rb +30 -0
  33. data/lib/tree_stand/breadth_first_visitor.rb +54 -0
  34. data/lib/tree_stand/config.rb +13 -0
  35. data/lib/tree_stand/node.rb +224 -0
  36. data/lib/tree_stand/parser.rb +67 -0
  37. data/lib/tree_stand/range.rb +55 -0
  38. data/lib/tree_stand/tree.rb +123 -0
  39. data/lib/tree_stand/utils/printer.rb +73 -0
  40. data/lib/tree_stand/version.rb +7 -0
  41. data/lib/tree_stand/visitor.rb +127 -0
  42. data/lib/tree_stand/visitors/tree_walker.rb +37 -0
  43. data/lib/tree_stand.rb +48 -0
  44. data/tree_sitter.gemspec +35 -0
  45. metadata +124 -0
@@ -0,0 +1,282 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQuery;
6
+
7
+ DATA_PTR_WRAP(Query, query);
8
+
9
+ /**
10
+ * Get the number of captures literals in the query.
11
+ *
12
+ * @return [Integer]
13
+ */
14
+ static VALUE query_capture_count(VALUE self) {
15
+ return UINT2NUM(ts_query_capture_count(SELF));
16
+ }
17
+
18
+ /**
19
+ * Get the name and length of one of the query's captures, or one of the
20
+ * query's string literals. Each capture and string is associated with a
21
+ * numeric id based on the order that it appeared in the query's source.
22
+ *
23
+ * @raise [IndexError] if out of range.
24
+ *
25
+ * @param index [Integer]
26
+ *
27
+ * @return [String]
28
+ */
29
+ static VALUE query_capture_name_for_id(VALUE self, VALUE index) {
30
+ const TSQuery *query = SELF;
31
+ uint32_t idx = NUM2UINT(index);
32
+ uint32_t range = ts_query_capture_count(query);
33
+
34
+ if (idx >= range) {
35
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", idx, range);
36
+ } else {
37
+ uint32_t length;
38
+ const char *name = ts_query_capture_name_for_id(query, idx, &length);
39
+ return safe_str2(name, length);
40
+ }
41
+ }
42
+
43
+ /**
44
+ * Get the quantifier of the query's captures. Each capture is associated
45
+ * with a numeric id based on the order that it appeared in the query's source.
46
+ *
47
+ * @raise [IndexError] if out of range.
48
+ *
49
+ * @param query_idx [Integer]
50
+ * @param capture_idx [Integer]
51
+ *
52
+ * @return [Integer]
53
+ */
54
+ static VALUE query_capture_quantifier_for_id(VALUE self, VALUE query_idx,
55
+ VALUE capture_idx) {
56
+ const TSQuery *query = SELF;
57
+ uint32_t pattern = NUM2UINT(query_idx);
58
+ uint32_t index = NUM2UINT(capture_idx);
59
+ uint32_t range = ts_query_capture_count(query);
60
+
61
+ if (index >= range) {
62
+ rb_raise(rb_eIndexError, "Capture ID %d out of range (len = %d)", index,
63
+ range);
64
+ } else {
65
+ return UINT2NUM(ts_query_capture_quantifier_for_id(query, pattern, index));
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Disable a certain capture within a query.
71
+ *
72
+ * This prevents the capture from being returned in matches, and also avoids
73
+ * any resource usage associated with recording the capture. Currently, there
74
+ * is no way to undo this.
75
+ *
76
+ * @param capture [String]
77
+ *
78
+ * @return [nil]
79
+ */
80
+ static VALUE query_disable_capture(VALUE self, VALUE capture) {
81
+ const char *cap = StringValuePtr(capture);
82
+ uint32_t length = (uint32_t)RSTRING_LEN(capture);
83
+ ts_query_disable_capture(SELF, cap, length);
84
+ return Qnil;
85
+ }
86
+
87
+ /**
88
+ * Disable a certain pattern within a query.
89
+ *
90
+ * This prevents the pattern from matching and removes most of the overhead
91
+ * associated with the pattern. Currently, there is no way to undo this.
92
+ *
93
+ * @raise [IndexError] if out of range.
94
+ *
95
+ * @param pattern [Integer]
96
+ *
97
+ * @return [nil]
98
+ */
99
+ static VALUE query_disable_pattern(VALUE self, VALUE pattern) {
100
+ TSQuery *query = SELF;
101
+ uint32_t index = NUM2UINT(pattern);
102
+ uint32_t range = ts_query_pattern_count(query);
103
+
104
+ if (index >= range) {
105
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
106
+ } else {
107
+ ts_query_disable_pattern(query, index);
108
+ return Qnil;
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Create a new query from a string containing one or more S-expression
114
+ * patterns. The query is associated with a particular language, and can
115
+ * only be run on syntax nodes parsed with that language.
116
+ *
117
+ * If all of the given patterns are valid, this returns a {Query}.
118
+ *
119
+ * @raise [RuntimeError]
120
+ *
121
+ * @param language [Language]
122
+ * @param source [String]
123
+ *
124
+ * @return [Query]
125
+ */
126
+ static VALUE query_initialize(VALUE self, VALUE language, VALUE source) {
127
+ // FIXME: should we raise an exception here?
128
+ TSLanguage *lang = value_to_language(language);
129
+ const char *src = StringValuePtr(source);
130
+ uint32_t len = (uint32_t)RSTRING_LEN(source);
131
+ uint32_t error_offset = 0;
132
+ TSQueryError error_type;
133
+
134
+ TSQuery *res = ts_query_new(lang, src, len, &error_offset, &error_type);
135
+
136
+ if (res == NULL || error_offset > 0) {
137
+ rb_raise(rb_eRuntimeError, "Could not create query: TSQueryError%s",
138
+ query_error_str(error_type));
139
+ } else {
140
+ SELF = res;
141
+ }
142
+
143
+ return self;
144
+ }
145
+
146
+ /**
147
+ * Get the number of patterns in the query.
148
+ *
149
+ * @return [Integer]
150
+ */
151
+ static VALUE query_pattern_count(VALUE self) {
152
+ return UINT2NUM(ts_query_pattern_count(SELF));
153
+ }
154
+
155
+ /**
156
+ * Check if a given pattern is guaranteed to match once a given step is reached.
157
+ * The step is specified by its byte offset in the query's source code.
158
+ *
159
+ * @param byte_offset [Integer]
160
+ *
161
+ * @return [Integer]
162
+ */
163
+ static VALUE query_pattern_guaranteed_at_step(VALUE self, VALUE byte_offset) {
164
+ return UINT2NUM(
165
+ ts_query_is_pattern_guaranteed_at_step(SELF, NUM2UINT(byte_offset)));
166
+ }
167
+
168
+ /**
169
+ * Get all of the predicates for the given pattern in the query.
170
+ *
171
+ * The predicates are represented as a single array of steps. There are three
172
+ * types of steps in this array, which correspond to the three legal values for
173
+ * the +type+ field:
174
+ * - {QueryPredicateStep::CAPTURE}: Steps with this type represent names
175
+ * of captures. Their +value_id+ can be used with the
176
+ * {Query#capture_name_for_id} function to obtain the name of the capture.
177
+ * - {QueryPredicateStep::STRING}: Steps with this type represent literal
178
+ * strings. Their +value_id+ can be used with the
179
+ * {Query#string_value_for_id} function to obtain their string value.
180
+ * - {QueryPredicateStep::DONE}: Steps with this type are *sentinels*
181
+ * that represent the end of an individual predicate. If a pattern has two
182
+ * predicates, then there will be two steps with this +type+ in the array.
183
+ *
184
+ * @param pattern_index [Integer]
185
+ *
186
+ * @return [Array<QueryPredicateStep>]
187
+ */
188
+ static VALUE query_predicates_for_pattern(VALUE self, VALUE pattern_index) {
189
+ const TSQuery *query = SELF;
190
+ uint32_t index = NUM2UINT(pattern_index);
191
+ uint32_t length;
192
+ const TSQueryPredicateStep *steps =
193
+ ts_query_predicates_for_pattern(query, index, &length);
194
+ VALUE res = rb_ary_new_capa(length);
195
+
196
+ for (uint32_t i = 0; i < length; i++) {
197
+ rb_ary_push(res, new_query_predicate_step(&steps[i]));
198
+ }
199
+
200
+ return res;
201
+ }
202
+
203
+ /**
204
+ * Get the byte offset where the given pattern starts in the query's source.
205
+ *
206
+ * This can be useful when combining queries by concatenating their source
207
+ * code strings.
208
+ *
209
+ * @raise [IndexError] if out of range.
210
+ *
211
+ * @param pattern_index [Integer]
212
+ *
213
+ * @return [Integer]
214
+ */
215
+ static VALUE query_start_byte_for_pattern(VALUE self, VALUE pattern_index) {
216
+ const TSQuery *query = SELF;
217
+ uint32_t index = NUM2UINT(pattern_index);
218
+ uint32_t range = ts_query_pattern_count(query);
219
+
220
+ if (index >= range) {
221
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
222
+ } else {
223
+ return UINT2NUM(ts_query_start_byte_for_pattern(SELF, index));
224
+ }
225
+ }
226
+
227
+ /**
228
+ * Get the number of string literals in the query.
229
+ *
230
+ * @return [Integer]
231
+ */
232
+ static VALUE query_string_count(VALUE self) {
233
+ return UINT2NUM(ts_query_string_count(SELF));
234
+ }
235
+
236
+ /**
237
+ * @raise [IndexError] if out of range.
238
+ *
239
+ * @param id [Integer]
240
+ *
241
+ * @return [String]
242
+ */
243
+ static VALUE query_string_value_for_id(VALUE self, VALUE id) {
244
+ const TSQuery *query = SELF;
245
+ uint32_t index = NUM2UINT(id);
246
+ uint32_t range = ts_query_string_count(query);
247
+
248
+ if (index >= range) {
249
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
250
+ } else {
251
+ uint32_t length;
252
+ const char *string = ts_query_string_value_for_id(query, index, &length);
253
+ return safe_str2(string, length);
254
+ }
255
+ }
256
+
257
+ // FIXME: missing:
258
+ // 1. ts_query_is_pattern_rooted
259
+ // 1. ts_query_is_pattern_non_local
260
+ void init_query(void) {
261
+ cQuery = rb_define_class_under(mTreeSitter, "Query", rb_cObject);
262
+
263
+ rb_define_alloc_func(cQuery, query_allocate);
264
+
265
+ /* Class methods */
266
+ rb_define_method(cQuery, "capture_count", query_capture_count, 0);
267
+ rb_define_method(cQuery, "capture_name_for_id", query_capture_name_for_id, 1);
268
+ rb_define_method(cQuery, "capture_quantifier_for_id",
269
+ query_capture_quantifier_for_id, 2);
270
+ rb_define_method(cQuery, "disable_capture", query_disable_capture, 1);
271
+ rb_define_method(cQuery, "disable_pattern", query_disable_pattern, 1);
272
+ rb_define_method(cQuery, "initialize", query_initialize, 2);
273
+ rb_define_method(cQuery, "pattern_count", query_pattern_count, 0);
274
+ rb_define_method(cQuery, "pattern_guaranteed_at_step?",
275
+ query_pattern_guaranteed_at_step, 1);
276
+ rb_define_method(cQuery, "predicates_for_pattern",
277
+ query_predicates_for_pattern, 1);
278
+ rb_define_method(cQuery, "start_byte_for_pattern",
279
+ query_start_byte_for_pattern, 1);
280
+ rb_define_method(cQuery, "string_count", query_string_count, 0);
281
+ rb_define_method(cQuery, "string_value_for_id", query_string_value_for_id, 1);
282
+ }
@@ -0,0 +1,28 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQueryCapture;
6
+
7
+ DATA_WRAP(QueryCapture, query_capture)
8
+ DATA_DEFINE_GETTER(query_capture, index, UINT2NUM)
9
+ DATA_DEFINE_GETTER(query_capture, node, new_node_by_val)
10
+
11
+ static VALUE query_capture_inspect(VALUE self) {
12
+ TSQueryCapture query_capture = SELF;
13
+ return rb_sprintf("{index=%d, node=%+" PRIsVALUE "}", query_capture.index,
14
+ new_node(&query_capture.node));
15
+ }
16
+
17
+ void init_query_capture(void) {
18
+ cQueryCapture =
19
+ rb_define_class_under(mTreeSitter, "QueryCapture", rb_cObject);
20
+
21
+ rb_define_alloc_func(cQueryCapture, query_capture_allocate);
22
+
23
+ /* Class methods */
24
+ DECLARE_GETTER(cQueryCapture, query_capture, index)
25
+ DECLARE_GETTER(cQueryCapture, query_capture, node)
26
+ rb_define_method(cQueryCapture, "inspect", query_capture_inspect, 0);
27
+ rb_define_method(cQueryCapture, "to_s", query_capture_inspect, 0);
28
+ }
@@ -0,0 +1,215 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQueryCursor;
6
+
7
+ DATA_TYPE(TSQueryCursor *, query_cursor)
8
+ DATA_FREE_PTR(query_cursor)
9
+ DATA_MEMSIZE(query_cursor)
10
+ DATA_DECLARE_DATA_TYPE(query_cursor)
11
+ static VALUE query_cursor_allocate(VALUE klass) {
12
+ query_cursor_t *query_cursor;
13
+ VALUE res = TypedData_Make_Struct(klass, query_cursor_t,
14
+ &query_cursor_data_type, query_cursor);
15
+ query_cursor->data = ts_query_cursor_new();
16
+ return res;
17
+ }
18
+ DATA_UNWRAP(query_cursor)
19
+ /**
20
+ * Create a new cursor for executing a given query.
21
+ *
22
+ * The cursor stores the state that is needed to iteratively search
23
+ * for matches. To use the query cursor, first call {QueryCursor#exec}
24
+ * to start running a given query on a given syntax node. Then, there are
25
+ * two options for consuming the results of the query:
26
+ * 1. Repeatedly call {QueryCursor#next_match} to iterate over all of the
27
+ * *matches* in the order that they were found. Each match contains the
28
+ * index of the pattern that matched, and an array of captures. Because
29
+ * multiple patterns can match the same set of nodes, one match may contain
30
+ * captures that appear *before* some of the captures from a previous match.
31
+ * 2. Repeatedly call {QueryCursor#next_capture} to iterate over all of the
32
+ * individual *captures* in the order that they appear. This is useful if
33
+ * don't care about which pattern matched, and just want a single ordered
34
+ * sequence of captures.
35
+ *
36
+ * If you don't care about consuming all of the results, you can stop calling
37
+ * {QueryCursor#next_match} or {QueryCursor#next_capture} at any point.
38
+ * You can then start executing another query on another node by calling
39
+ * {QueryCursor#exec} again.
40
+ */
41
+ DATA_PTR_NEW(cQueryCursor, TSQueryCursor, query_cursor)
42
+ DATA_FROM_VALUE(TSQueryCursor *, query_cursor)
43
+
44
+ /**
45
+ * Start running a given query on a given node.
46
+ *
47
+ * @param query [Query]
48
+ * @param node [Node]
49
+ *
50
+ * @return [QueryCursor]
51
+ */
52
+ static VALUE query_cursor_exec(VALUE self, VALUE query, VALUE node) {
53
+ VALUE res = query_cursor_allocate(cQueryCursor);
54
+ query_cursor_t *query_cursor = unwrap(res);
55
+ ts_query_cursor_exec(query_cursor->data, value_to_query(query),
56
+ value_to_node(node));
57
+ return res;
58
+ }
59
+
60
+ /**
61
+ * Manage the maximum number of in-progress matches allowed by this query
62
+ * cursor.
63
+ *
64
+ * Query cursors have an optional maximum capacity for storing lists of
65
+ * in-progress captures. If this capacity is exceeded, then the
66
+ * earliest-starting match will silently be dropped to make room for further
67
+ * matches. This maximum capacity is optional — by default, query cursors allow
68
+ * any number of pending matches, dynamically allocating new space for them as
69
+ * needed as the query is executed.
70
+ */
71
+ static VALUE query_cursor_did_exceed_match_limit(VALUE self) {
72
+ return ts_query_cursor_did_exceed_match_limit(SELF) ? Qtrue : Qfalse;
73
+ }
74
+
75
+ /**
76
+ * @param limit [Integer]
77
+ *
78
+ * @return [nil]
79
+ */
80
+ static VALUE query_cursor_set_match_limit(VALUE self, VALUE limit) {
81
+ ts_query_cursor_set_match_limit(SELF, NUM2UINT(limit));
82
+ return Qnil;
83
+ }
84
+
85
+ /**
86
+ * @return [Integer]
87
+ */
88
+ static VALUE query_cursor_get_match_limit(VALUE self) {
89
+ return UINT2NUM(ts_query_cursor_match_limit(SELF));
90
+ }
91
+
92
+ /**
93
+ * Set the maximum start depth for a query cursor.
94
+ *
95
+ * This prevents cursors from exploring children nodes at a certain depth.
96
+ * Note if a pattern includes many children, then they will still be checked.
97
+ *
98
+ * The zero max start depth value can be used as a special behavior and
99
+ * it helps to destructure a subtree by staying on a node and using captures
100
+ * for interested parts. Note that the zero max start depth only limit a search
101
+ * depth for a pattern's root node but other nodes that are parts of the pattern
102
+ * may be searched at any depth what defined by the pattern structure.
103
+ *
104
+ * @param max_start_depth [Integer|nil] set to nil to remove the maximum start
105
+ * depth.
106
+ *
107
+ * @return [nil]
108
+ */
109
+ static VALUE query_cursor_set_max_start_depth(VALUE self,
110
+ VALUE max_start_depth) {
111
+ uint32_t max = UINT32_MAX;
112
+ if (!NIL_P(max_start_depth)) {
113
+ max = NUM2UINT(max_start_depth);
114
+ }
115
+ ts_query_cursor_set_max_start_depth(SELF, max);
116
+ return Qnil;
117
+ }
118
+
119
+ // FIXME: maybe this is the limit of how "transparent" the bindings need to be.
120
+ // Pending benchmarks, this can be very inefficient because obviously
121
+ // ts_query_cursor_next_capture is intended to be used in a loop. Creating an
122
+ // array of two values and returning them, intuitively speaking, seem very
123
+ // inefficient.
124
+ // FIXME: maybe this needs to return an empty array to make for a nicer ruby
125
+ // API?
126
+ /**
127
+ * Advance to the next capture of the currently running query.
128
+ *
129
+ * @return [Array<Integer|Boolean>|nil] If there is a capture, return a tuple
130
+ * [Integer, Boolean], otherwise return +nil+.
131
+ */
132
+ static VALUE query_cursor_next_capture(VALUE self) {
133
+ TSQueryMatch match;
134
+ uint32_t index;
135
+ if (ts_query_cursor_next_capture(SELF, &match, &index)) {
136
+ VALUE res = rb_ary_new_capa(2);
137
+ rb_ary_push(res, UINT2NUM(index));
138
+ rb_ary_push(res, new_query_match(&match));
139
+ return res;
140
+ } else {
141
+ return Qnil;
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Advance to the next match of the currently running query.
147
+ *
148
+ * @return [Boolean] Whether there's a match.
149
+ */
150
+ static VALUE query_cursor_next_match(VALUE self) {
151
+ TSQueryMatch match;
152
+ if (ts_query_cursor_next_match(SELF, &match)) {
153
+ return new_query_match(&match);
154
+ } else {
155
+ return Qnil;
156
+ }
157
+ }
158
+
159
+ static VALUE query_cursor_remove_match(VALUE self, VALUE id) {
160
+ ts_query_cursor_remove_match(SELF, NUM2UINT(id));
161
+ return Qnil;
162
+ }
163
+
164
+ /**
165
+ * @param from [Integer]
166
+ * @param to [Integer]
167
+ *
168
+ * @return [nil]
169
+ */
170
+ static VALUE query_cursor_set_byte_range(VALUE self, VALUE from, VALUE to) {
171
+ ts_query_cursor_set_byte_range(SELF, NUM2UINT(from), NUM2UINT(to));
172
+ return Qnil;
173
+ }
174
+
175
+ /**
176
+ * @param from [Point]
177
+ * @param to [Point]
178
+ *
179
+ * @return [nil]
180
+ */
181
+ static VALUE query_cursor_set_point_range(VALUE self, VALUE from, VALUE to) {
182
+ ts_query_cursor_set_point_range(SELF, value_to_point(from),
183
+ value_to_point(to));
184
+ return Qnil;
185
+ }
186
+
187
+ void init_query_cursor(void) {
188
+ cQueryCursor = rb_define_class_under(mTreeSitter, "QueryCursor", rb_cObject);
189
+
190
+ rb_define_alloc_func(cQueryCursor, query_cursor_allocate);
191
+
192
+ /* Module methods */
193
+ rb_define_module_function(cQueryCursor, "exec", query_cursor_exec, 2);
194
+
195
+ /* Class methods */
196
+ // Accessors
197
+ DECLARE_ACCESSOR(cQueryCursor, query_cursor, match_limit)
198
+
199
+ // Other
200
+ rb_define_method(cQueryCursor, "exceed_match_limit?",
201
+ query_cursor_did_exceed_match_limit, 0);
202
+ rb_define_method(cQueryCursor, "match_limit", query_cursor_get_match_limit,
203
+ 0);
204
+ rb_define_method(cQueryCursor, "match_limit=", query_cursor_set_match_limit,
205
+ 1);
206
+ rb_define_method(cQueryCursor,
207
+ "max_start_depth=", query_cursor_set_max_start_depth, 1);
208
+ rb_define_method(cQueryCursor, "next_capture", query_cursor_next_capture, 0);
209
+ rb_define_method(cQueryCursor, "next_match", query_cursor_next_match, 0);
210
+ rb_define_method(cQueryCursor, "remove_match", query_cursor_remove_match, 1);
211
+ rb_define_method(cQueryCursor, "set_byte_range", query_cursor_set_byte_range,
212
+ 2);
213
+ rb_define_method(cQueryCursor, "set_point_range",
214
+ query_cursor_set_point_range, 2);
215
+ }
@@ -0,0 +1,41 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE mQueryError;
6
+
7
+ TSQueryError value_to_query_error(VALUE query_error) {
8
+ return NUM2UINT(query_error);
9
+ }
10
+
11
+ const char *query_error_str(TSQueryError error) {
12
+ switch (error) {
13
+ case TSQueryErrorNone:
14
+ return "None";
15
+ case TSQueryErrorSyntax:
16
+ return "Syntax";
17
+ case TSQueryErrorNodeType:
18
+ return "Node Type";
19
+ case TSQueryErrorField:
20
+ return "Field";
21
+ case TSQueryErrorCapture:
22
+ return "Capture";
23
+ case TSQueryErrorStructure:
24
+ return "Structure";
25
+ case TSQueryErrorLanguage:
26
+ return "Language";
27
+ default:
28
+ return "??";
29
+ }
30
+ }
31
+
32
+ void init_query_error(void) {
33
+ mQueryError = rb_define_module_under(mTreeSitter, "QueryError");
34
+ rb_define_const(mQueryError, "NONE", UINT2NUM(0));
35
+ rb_define_const(mQueryError, "Syntax", UINT2NUM(1));
36
+ rb_define_const(mQueryError, "NodeType", UINT2NUM(2));
37
+ rb_define_const(mQueryError, "Field", UINT2NUM(3));
38
+ rb_define_const(mQueryError, "Capture", UINT2NUM(4));
39
+ rb_define_const(mQueryError, "Structure", UINT2NUM(5));
40
+ rb_define_const(mQueryError, "Language", UINT2NUM(6));
41
+ }
@@ -0,0 +1,44 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQueryMatch;
6
+
7
+ DATA_WRAP(QueryMatch, query_match)
8
+ DATA_DEFINE_GETTER(query_match, id, UINT2NUM)
9
+ DATA_DEFINE_GETTER(query_match, pattern_index, INT2FIX)
10
+ DATA_DEFINE_GETTER(query_match, capture_count, INT2FIX)
11
+
12
+ static VALUE query_match_get_captures(VALUE self) {
13
+ query_match_t *query_match = unwrap(self);
14
+
15
+ uint16_t length = query_match->data.capture_count;
16
+ VALUE res = rb_ary_new_capa(length);
17
+ const TSQueryCapture *captures = query_match->data.captures;
18
+ for (int i = 0; i < length; i++) {
19
+ rb_ary_push(res, new_query_capture(&captures[i]));
20
+ }
21
+
22
+ return res;
23
+ }
24
+
25
+ static VALUE query_match_inspect(VALUE self) {
26
+ TSQueryMatch query_match = SELF;
27
+ return rb_sprintf("{id=%d, pattern_inex=%d, capture_count=%d}",
28
+ query_match.id, query_match.pattern_index,
29
+ query_match.capture_count);
30
+ }
31
+
32
+ void init_query_match(void) {
33
+ cQueryMatch = rb_define_class_under(mTreeSitter, "QueryMatch", rb_cObject);
34
+
35
+ rb_define_alloc_func(cQueryMatch, query_match_allocate);
36
+
37
+ /* Class methods */
38
+ DECLARE_GETTER(cQueryMatch, query_match, id)
39
+ DECLARE_GETTER(cQueryMatch, query_match, pattern_index)
40
+ DECLARE_GETTER(cQueryMatch, query_match, capture_count)
41
+ DECLARE_GETTER(cQueryMatch, query_match, captures)
42
+ rb_define_method(cQueryMatch, "inspect", query_match_inspect, 0);
43
+ rb_define_method(cQueryMatch, "to_s", query_match_inspect, 0);
44
+ }
@@ -0,0 +1,83 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQueryPredicateStep;
6
+
7
+ const char *done = "Done";
8
+ const char *capture = "capture";
9
+ const char *string = "String";
10
+
11
+ DATA_WRAP(QueryPredicateStep, query_predicate_step)
12
+
13
+ VALUE new_query_predicate_step_type(TSQueryPredicateStepType type) {
14
+ switch (type) {
15
+ case TSQueryPredicateStepTypeDone:
16
+ return ID2SYM(rb_intern(done));
17
+ case TSQueryPredicateStepTypeCapture:
18
+ return ID2SYM(rb_intern(capture));
19
+ case TSQueryPredicateStepTypeString:
20
+ return ID2SYM(rb_intern(string));
21
+ default:
22
+ return Qnil;
23
+ }
24
+ }
25
+
26
+ static const char *query_predicate_type_string(TSQueryPredicateStepType type) {
27
+ switch (type) {
28
+ case TSQueryPredicateStepTypeDone:
29
+ return done;
30
+ case TSQueryPredicateStepTypeCapture:
31
+ return capture;
32
+ case TSQueryPredicateStepTypeString:
33
+ return string;
34
+ default:
35
+ return "???";
36
+ }
37
+ }
38
+
39
+ TSQueryPredicateStepType value_to_query_predicate_step_type(VALUE step_type) {
40
+ VALUE type = SYM2ID(step_type);
41
+ VALUE c = rb_const_get_at(cQueryPredicateStep, rb_intern(capture));
42
+ VALUE s = rb_const_get_at(cQueryPredicateStep, rb_intern(string));
43
+
44
+ // NOTE: should we emit a warning instead of defaulting to done?
45
+ if (type == c) {
46
+ return TSQueryPredicateStepTypeCapture;
47
+ } else if (type == s) {
48
+ return TSQueryPredicateStepTypeString;
49
+ } else {
50
+ return TSQueryPredicateStepTypeDone;
51
+ }
52
+ }
53
+
54
+ static VALUE query_predicate_step_inspect(VALUE self) {
55
+ query_predicate_step_t *step = unwrap(self);
56
+ return rb_sprintf("{value_id=%i, type=%s}", step->data.value_id,
57
+ query_predicate_type_string(step->data.type));
58
+ }
59
+
60
+ DATA_DEFINE_ACCESSOR(query_predicate_step, type, new_query_predicate_step_type,
61
+ value_to_query_predicate_step_type)
62
+ DATA_DEFINE_ACCESSOR(query_predicate_step, value_id, UINT2NUM, NUM2UINT)
63
+
64
+ void init_query_predicate_step(void) {
65
+ cQueryPredicateStep =
66
+ rb_define_class_under(mTreeSitter, "QueryPredicateStep", rb_cObject);
67
+
68
+ rb_define_alloc_func(cQueryPredicateStep, query_predicate_step_allocate);
69
+
70
+ /* Constants */
71
+ rb_define_const(cQueryPredicateStep, "DONE", ID2SYM(rb_intern(done)));
72
+ rb_define_const(cQueryPredicateStep, "CAPTURE", ID2SYM(rb_intern(capture)));
73
+ rb_define_const(cQueryPredicateStep, "STRING", ID2SYM(rb_intern(string)));
74
+
75
+ /* Class methods */
76
+ DECLARE_ACCESSOR(cQueryPredicateStep, query_predicate_step, type)
77
+ DECLARE_ACCESSOR(cQueryPredicateStep, query_predicate_step, value_id)
78
+
79
+ rb_define_method(cQueryPredicateStep, "inspect", query_predicate_step_inspect,
80
+ 0);
81
+ rb_define_method(cQueryPredicateStep, "to_s", query_predicate_step_inspect,
82
+ 0);
83
+ }