ruby_tree_sitter 0.20.6.4-x86_64-darwin-20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +152 -0
  4. data/ext/tree_sitter/encoding.c +29 -0
  5. data/ext/tree_sitter/extconf.rb +172 -0
  6. data/ext/tree_sitter/input.c +126 -0
  7. data/ext/tree_sitter/input_edit.c +42 -0
  8. data/ext/tree_sitter/language.c +134 -0
  9. data/ext/tree_sitter/logger.c +212 -0
  10. data/ext/tree_sitter/macros.h +163 -0
  11. data/ext/tree_sitter/node.c +310 -0
  12. data/ext/tree_sitter/parser.c +203 -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 +157 -0
  16. data/ext/tree_sitter/query_capture.c +28 -0
  17. data/ext/tree_sitter/query_cursor.c +103 -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/symbol_type.c +46 -0
  23. data/ext/tree_sitter/tree.c +144 -0
  24. data/ext/tree_sitter/tree_cursor.c +97 -0
  25. data/ext/tree_sitter/tree_sitter.c +32 -0
  26. data/ext/tree_sitter/tree_sitter.h +107 -0
  27. data/lib/tree_sitter/node.rb +164 -0
  28. data/lib/tree_sitter/tree_sitter.bundle +0 -0
  29. data/lib/tree_sitter/version.rb +5 -0
  30. data/lib/tree_sitter.rb +13 -0
  31. data/test/README.md +15 -0
  32. data/test/test_helper.rb +9 -0
  33. data/test/tree_sitter/language_test.rb +68 -0
  34. data/test/tree_sitter/logger_test.rb +69 -0
  35. data/test/tree_sitter/node_test.rb +355 -0
  36. data/test/tree_sitter/parser_test.rb +140 -0
  37. data/test/tree_sitter/query_test.rb +153 -0
  38. data/test/tree_sitter/tree_cursor_test.rb +83 -0
  39. data/test/tree_sitter/tree_test.rb +51 -0
  40. data/tree_sitter.gemspec +32 -0
  41. metadata +192 -0
@@ -0,0 +1,203 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cParser;
6
+
7
+ typedef struct {
8
+ TSParser *data;
9
+ size_t cancellation_flag;
10
+ } parser_t;
11
+
12
+ static void parser_free(void *ptr) {
13
+ ts_parser_delete(((parser_t *)ptr)->data);
14
+ xfree(ptr);
15
+ }
16
+
17
+ static size_t parser_memsize(const void *ptr) {
18
+ parser_t *type = (parser_t *)ptr;
19
+ return sizeof(type);
20
+ }
21
+
22
+ const rb_data_type_t parser_data_type = {
23
+ .wrap_struct_name = "parser",
24
+ .function =
25
+ {
26
+ .dmark = NULL,
27
+ .dfree = parser_free,
28
+ .dsize = parser_memsize,
29
+ .dcompact = NULL,
30
+ },
31
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY,
32
+ };
33
+
34
+ DATA_UNWRAP(parser)
35
+
36
+ static VALUE parser_allocate(VALUE klass) {
37
+ parser_t *parser;
38
+ VALUE res = TypedData_Make_Struct(klass, parser_t, &parser_data_type, parser);
39
+ parser->data = ts_parser_new();
40
+ return res;
41
+ }
42
+
43
+ static VALUE parser_get_language(VALUE self) {
44
+ return new_language(ts_parser_language(SELF));
45
+ }
46
+
47
+ static VALUE parser_get_included_ranges(VALUE self) {
48
+ uint32_t length;
49
+ const TSRange *ranges = ts_parser_included_ranges(SELF, &length);
50
+ VALUE res = rb_ary_new_capa(length);
51
+ for (uint32_t i = 0; i < length; i++) {
52
+ rb_ary_push(res, new_range(&ranges[i]));
53
+ }
54
+ return res;
55
+ }
56
+
57
+ static VALUE parser_get_timeout_micros(VALUE self) {
58
+ return ULL2NUM(ts_parser_timeout_micros(SELF));
59
+ }
60
+
61
+ static VALUE parser_get_logger(VALUE self) {
62
+ return new_logger_by_val(ts_parser_logger(SELF));
63
+ }
64
+
65
+ static VALUE parser_get_cancellation_flag(VALUE self) {
66
+ return SIZET2NUM(*ts_parser_cancellation_flag(SELF));
67
+ }
68
+
69
+ static VALUE parser_set_language(VALUE self, VALUE language) {
70
+ return ts_parser_set_language(SELF, value_to_language(language)) ? Qtrue
71
+ : Qfalse;
72
+ }
73
+
74
+ static VALUE parser_set_included_ranges(VALUE self, VALUE array) {
75
+ Check_Type(array, T_ARRAY);
76
+
77
+ long length = rb_array_len(array);
78
+ TSRange *ranges = (TSRange *)malloc(length * sizeof(TSRange));
79
+ for (long i = 0; i < length; i++) {
80
+ ranges[i] = value_to_range(rb_ary_entry(array, i));
81
+ }
82
+ bool res = ts_parser_set_included_ranges(SELF, ranges, (uint32_t)length);
83
+ if (ranges) {
84
+ free(ranges);
85
+ }
86
+ return res ? Qtrue : Qfalse;
87
+ }
88
+
89
+ static VALUE parser_set_timeout_micros(VALUE self, VALUE timeout) {
90
+ ts_parser_set_timeout_micros(SELF, NUM2ULL(timeout));
91
+ return Qnil;
92
+ }
93
+
94
+ static VALUE parser_set_cancellation_flag(VALUE self, VALUE flag) {
95
+ unwrap(self)->cancellation_flag = NUM2SIZET(flag);
96
+ ts_parser_set_cancellation_flag(SELF, &unwrap(self)->cancellation_flag);
97
+ return Qnil;
98
+ }
99
+
100
+ static VALUE parser_set_logger(VALUE self, VALUE logger) {
101
+ ts_parser_set_logger(SELF, value_to_logger(logger));
102
+ return Qnil;
103
+ }
104
+
105
+ static VALUE parser_parse(VALUE self, VALUE old_tree, VALUE input) {
106
+ if (NIL_P(input)) {
107
+ return Qnil;
108
+ }
109
+
110
+ TSTree *tree = NULL;
111
+ if (!NIL_P(old_tree)) {
112
+ tree = value_to_tree(old_tree);
113
+ }
114
+
115
+ TSTree *ret = ts_parser_parse(SELF, tree, value_to_input(input));
116
+ if (ret == NULL) {
117
+ return Qnil;
118
+ } else {
119
+ return new_tree(ret);
120
+ }
121
+ }
122
+
123
+ static VALUE parser_parse_string(VALUE self, VALUE old_tree, VALUE string) {
124
+ if (NIL_P(string)) {
125
+ return Qnil;
126
+ }
127
+
128
+ const char *str = StringValuePtr(string);
129
+ uint32_t len = (uint32_t)RSTRING_LEN(string);
130
+ TSTree *tree = NULL;
131
+ if (!NIL_P(old_tree)) {
132
+ tree = value_to_tree(old_tree);
133
+ }
134
+
135
+ TSTree *ret = ts_parser_parse_string(SELF, tree, str, len);
136
+ if (ret == NULL) {
137
+ return Qnil;
138
+ } else {
139
+ return new_tree(ret);
140
+ }
141
+ }
142
+
143
+ static VALUE parser_parse_string_encoding(VALUE self, VALUE old_tree,
144
+ VALUE string, VALUE encoding) {
145
+ if (NIL_P(string)) {
146
+ return Qnil;
147
+ }
148
+
149
+ const char *str = StringValuePtr(string);
150
+ uint32_t len = (uint32_t)RSTRING_LEN(string);
151
+ TSTree *tree = NULL;
152
+ if (!NIL_P(old_tree)) {
153
+ tree = value_to_tree(old_tree);
154
+ }
155
+
156
+ TSTree *ret = ts_parser_parse_string_encoding(SELF, tree, str, len,
157
+ value_to_encoding(encoding));
158
+
159
+ if (ret == NULL) {
160
+ return Qnil;
161
+ } else {
162
+ return new_tree(ret);
163
+ }
164
+ }
165
+
166
+ static VALUE parser_reset(VALUE self) {
167
+ ts_parser_reset(SELF);
168
+ return Qnil;
169
+ }
170
+
171
+ static VALUE parser_print_dot_graphs(VALUE self, VALUE file) {
172
+ if (NIL_P(file)) {
173
+ ts_parser_print_dot_graphs(SELF, -1);
174
+ } else if (rb_integer_type_p(file) && NUM2INT(file) < 0) {
175
+ ts_parser_print_dot_graphs(SELF, NUM2INT(file));
176
+ } else {
177
+ Check_Type(file, T_STRING);
178
+ char *path = StringValueCStr(file);
179
+ int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
180
+ 0644); // 0644 = all read + user write
181
+ ts_parser_print_dot_graphs(SELF, fd);
182
+ }
183
+ return Qnil;
184
+ }
185
+
186
+ void init_parser(void) {
187
+ cParser = rb_define_class_under(mTreeSitter, "Parser", rb_cObject);
188
+
189
+ rb_define_alloc_func(cParser, parser_allocate);
190
+
191
+ /* Class methods */
192
+ DECLARE_ACCESSOR(cParser, parser, language)
193
+ DECLARE_ACCESSOR(cParser, parser, included_ranges)
194
+ DECLARE_ACCESSOR(cParser, parser, timeout_micros)
195
+ DECLARE_ACCESSOR(cParser, parser, logger)
196
+ DECLARE_ACCESSOR(cParser, parser, cancellation_flag)
197
+ rb_define_method(cParser, "parse", parser_parse, 2);
198
+ rb_define_method(cParser, "parse_string", parser_parse_string, 2);
199
+ rb_define_method(cParser, "parse_string_encoding",
200
+ parser_parse_string_encoding, 3);
201
+ rb_define_method(cParser, "reset", parser_reset, 0);
202
+ rb_define_method(cParser, "print_dot_graphs", parser_print_dot_graphs, 1);
203
+ }
@@ -0,0 +1,26 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cPoint;
6
+
7
+ DATA_WRAP(Point, point)
8
+ DATA_DEFINE_ACCESSOR(point, row, UINT2NUM, NUM2UINT)
9
+ DATA_DEFINE_ACCESSOR(point, column, UINT2NUM, NUM2UINT)
10
+
11
+ static VALUE point_inspect(VALUE self) {
12
+ point_t *point = unwrap(self);
13
+ return rb_sprintf("{row=%i, column=%i}", point->data.row, point->data.column);
14
+ }
15
+
16
+ void init_point(void) {
17
+ cPoint = rb_define_class_under(mTreeSitter, "Point", rb_cObject);
18
+
19
+ rb_define_alloc_func(cPoint, point_allocate);
20
+
21
+ /* Class methods */
22
+ DECLARE_ACCESSOR(cPoint, point, row)
23
+ DECLARE_ACCESSOR(cPoint, point, column)
24
+ rb_define_method(cPoint, "inspect", point_inspect, 0);
25
+ rb_define_method(cPoint, "to_s", point_inspect, 0);
26
+ }
@@ -0,0 +1,43 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE mQuantifier;
6
+
7
+ TSQuantifier value_to_quantifier(VALUE quantifier) {
8
+ return NUM2UINT(quantifier);
9
+ }
10
+
11
+ const char *quantifier_str(TSQuantifier error) {
12
+ switch (error) {
13
+ case TSQuantifierZero:
14
+ return "Zero";
15
+ case TSQuantifierZeroOrOne:
16
+ return "ZeroOrOne";
17
+ case TSQuantifierZeroOrMore:
18
+ return "ZeroOrMore";
19
+ case TSQuantifierOne:
20
+ return "One";
21
+ case TSQuantifierOneOrMore:
22
+ return "OneOrMore";
23
+ default:
24
+ return "??";
25
+ }
26
+ }
27
+
28
+ static VALUE quantifier_name(VALUE self, VALUE quant) {
29
+ int q = NUM2UINT(quant);
30
+ return safe_str(quantifier_str(q));
31
+ }
32
+
33
+ void init_quantifier(void) {
34
+ mQuantifier = rb_define_module_under(mTreeSitter, "Quantifier");
35
+
36
+ rb_define_module_function(mTreeSitter, "quantifier_name", quantifier_name, 1);
37
+
38
+ rb_define_const(mQuantifier, "ZERO", UINT2NUM(0));
39
+ rb_define_const(mQuantifier, "ZERO_OR_ONE", UINT2NUM(1));
40
+ rb_define_const(mQuantifier, "ZERO_OR_MORE", UINT2NUM(2));
41
+ rb_define_const(mQuantifier, "ONE", UINT2NUM(3));
42
+ rb_define_const(mQuantifier, "ONE_OR_MORE", UINT2NUM(4));
43
+ }
@@ -0,0 +1,157 @@
1
+ #include "tree_sitter.h"
2
+
3
+ extern VALUE mTreeSitter;
4
+
5
+ VALUE cQuery;
6
+
7
+ DATA_PTR_WRAP(Query, query);
8
+
9
+ static VALUE query_initialize(VALUE self, VALUE language, VALUE source) {
10
+ TSLanguage *lang = value_to_language(language);
11
+ const char *src = StringValuePtr(source);
12
+ uint32_t len = (uint32_t)RSTRING_LEN(source);
13
+ uint32_t error_offset = 0;
14
+ TSQueryError error_type;
15
+
16
+ TSQuery *res = ts_query_new(lang, src, len, &error_offset, &error_type);
17
+
18
+ if (res == NULL || error_offset > 0) {
19
+ rb_raise(rb_eRuntimeError, "Could not create query: TSQueryError%s",
20
+ query_error_str(error_type));
21
+ } else {
22
+ SELF = res;
23
+ }
24
+
25
+ return self;
26
+ }
27
+
28
+ static VALUE query_pattern_count(VALUE self) {
29
+ return UINT2NUM(ts_query_pattern_count(SELF));
30
+ }
31
+
32
+ static VALUE query_capture_count(VALUE self) {
33
+ return UINT2NUM(ts_query_capture_count(SELF));
34
+ }
35
+
36
+ static VALUE query_string_count(VALUE self) {
37
+ return UINT2NUM(ts_query_string_count(SELF));
38
+ }
39
+
40
+ static VALUE query_start_byte_for_pattern(VALUE self, VALUE pattern_index) {
41
+ const TSQuery *query = SELF;
42
+ uint32_t index = NUM2UINT(pattern_index);
43
+ uint32_t range = ts_query_pattern_count(query);
44
+
45
+ if (index >= range) {
46
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
47
+ } else {
48
+ return UINT2NUM(ts_query_start_byte_for_pattern(SELF, index));
49
+ }
50
+ }
51
+
52
+ static VALUE query_predicates_for_pattern(VALUE self, VALUE pattern_index) {
53
+ const TSQuery *query = SELF;
54
+ uint32_t index = NUM2UINT(pattern_index);
55
+ uint32_t length;
56
+ const TSQueryPredicateStep *steps =
57
+ ts_query_predicates_for_pattern(query, index, &length);
58
+ VALUE res = rb_ary_new_capa(length);
59
+
60
+ for (uint32_t i = 0; i < length; i++) {
61
+ rb_ary_push(res, new_query_predicate_step(&steps[i]));
62
+ }
63
+
64
+ return res;
65
+ }
66
+
67
+ static VALUE query_pattern_guaranteed_at_step(VALUE self, VALUE byte_offset) {
68
+ return UINT2NUM(
69
+ ts_query_is_pattern_guaranteed_at_step(SELF, NUM2UINT(byte_offset)));
70
+ }
71
+
72
+ static VALUE query_capture_name_for_id(VALUE self, VALUE id) {
73
+ const TSQuery *query = SELF;
74
+ uint32_t index = NUM2UINT(id);
75
+ uint32_t range = ts_query_capture_count(query);
76
+
77
+ if (index >= range) {
78
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
79
+ } else {
80
+ uint32_t length;
81
+ const char *name = ts_query_capture_name_for_id(query, index, &length);
82
+ return safe_str2(name, length);
83
+ }
84
+ }
85
+
86
+ static VALUE query_capture_quantifier_for_id(VALUE self, VALUE id,
87
+ VALUE capture_id) {
88
+ const TSQuery *query = SELF;
89
+ uint32_t pattern = NUM2UINT(id);
90
+ uint32_t index = NUM2UINT(capture_id);
91
+ uint32_t range = ts_query_capture_count(query);
92
+
93
+ if (index >= range) {
94
+ rb_raise(rb_eIndexError, "Capture ID %d out of range (len = %d)", index,
95
+ range);
96
+ } else {
97
+ return UINT2NUM(ts_query_capture_quantifier_for_id(query, pattern, index));
98
+ }
99
+ }
100
+
101
+ static VALUE query_string_value_for_id(VALUE self, VALUE id) {
102
+ const TSQuery *query = SELF;
103
+ uint32_t index = NUM2UINT(id);
104
+ uint32_t range = ts_query_string_count(query);
105
+
106
+ if (index >= range) {
107
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
108
+ } else {
109
+ uint32_t length;
110
+ const char *string = ts_query_string_value_for_id(query, index, &length);
111
+ return safe_str2(string, length);
112
+ }
113
+ }
114
+
115
+ static VALUE query_disable_capture(VALUE self, VALUE capture) {
116
+ const char *cap = StringValuePtr(capture);
117
+ uint32_t length = (uint32_t)RSTRING_LEN(capture);
118
+ ts_query_disable_capture(SELF, cap, length);
119
+ return Qnil;
120
+ }
121
+
122
+ static VALUE query_disable_pattern(VALUE self, VALUE pattern) {
123
+ TSQuery *query = SELF;
124
+ uint32_t index = NUM2UINT(pattern);
125
+ uint32_t range = ts_query_pattern_count(query);
126
+
127
+ if (index >= range) {
128
+ rb_raise(rb_eIndexError, "Index %d out of range (len = %d)", index, range);
129
+ } else {
130
+ ts_query_disable_pattern(query, index);
131
+ return Qnil;
132
+ }
133
+ }
134
+
135
+ void init_query(void) {
136
+ cQuery = rb_define_class_under(mTreeSitter, "Query", rb_cObject);
137
+
138
+ rb_define_alloc_func(cQuery, query_allocate);
139
+
140
+ /* Class methods */
141
+ rb_define_method(cQuery, "initialize", query_initialize, 2);
142
+ rb_define_method(cQuery, "pattern_count", query_pattern_count, 0);
143
+ rb_define_method(cQuery, "capture_count", query_capture_count, 0);
144
+ rb_define_method(cQuery, "string_count", query_string_count, 0);
145
+ rb_define_method(cQuery, "start_byte_for_pattern",
146
+ query_start_byte_for_pattern, 1);
147
+ rb_define_method(cQuery, "predicates_for_pattern",
148
+ query_predicates_for_pattern, 1);
149
+ rb_define_method(cQuery, "pattern_guaranteed_at_step?",
150
+ query_pattern_guaranteed_at_step, 1);
151
+ rb_define_method(cQuery, "capture_name_for_id", query_capture_name_for_id, 1);
152
+ rb_define_method(cQuery, "capture_quantifier_for_id",
153
+ query_capture_quantifier_for_id, 2);
154
+ rb_define_method(cQuery, "string_value_for_id", query_string_value_for_id, 1);
155
+ rb_define_method(cQuery, "disable_capture", query_disable_capture, 1);
156
+ rb_define_method(cQuery, "disable_pattern", query_disable_pattern, 1);
157
+ }
@@ -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,103 @@
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
+ DATA_PTR_NEW(cQueryCursor, TSQueryCursor, query_cursor)
20
+ DATA_FROM_VALUE(TSQueryCursor *, query_cursor)
21
+
22
+ static VALUE query_cursor_exec(VALUE self, VALUE query, VALUE node) {
23
+ VALUE res = query_cursor_allocate(cQueryCursor);
24
+ query_cursor_t *query_cursor = unwrap(res);
25
+ ts_query_cursor_exec(query_cursor->data, value_to_query(query),
26
+ value_to_node(node));
27
+ return res;
28
+ }
29
+
30
+ static VALUE query_cursor_did_exceed_match_limit(VALUE self) {
31
+ return ts_query_cursor_did_exceed_match_limit(SELF) ? Qtrue : Qfalse;
32
+ }
33
+
34
+ static VALUE query_cursor_get_match_limit(VALUE self) {
35
+ return UINT2NUM(ts_query_cursor_match_limit(SELF));
36
+ }
37
+
38
+ static VALUE query_cursor_set_match_limit(VALUE self, VALUE limit) {
39
+ ts_query_cursor_set_match_limit(SELF, NUM2UINT(limit));
40
+ return Qnil;
41
+ }
42
+
43
+ static VALUE query_cursor_set_byte_range(VALUE self, VALUE from, VALUE to) {
44
+ ts_query_cursor_set_byte_range(SELF, NUM2UINT(from), NUM2UINT(to));
45
+ return Qnil;
46
+ }
47
+
48
+ static VALUE query_cursor_set_point_range(VALUE self, VALUE from, VALUE to) {
49
+ ts_query_cursor_set_point_range(SELF, value_to_point(from),
50
+ value_to_point(to));
51
+ return Qnil;
52
+ }
53
+
54
+ static VALUE query_cursor_next_match(VALUE self) {
55
+ TSQueryMatch match;
56
+ if (ts_query_cursor_next_match(SELF, &match)) {
57
+ return new_query_match(&match);
58
+ } else {
59
+ return Qnil;
60
+ }
61
+ }
62
+
63
+ static VALUE query_cursor_remove_match(VALUE self, VALUE id) {
64
+ ts_query_cursor_remove_match(SELF, NUM2UINT(id));
65
+ return Qnil;
66
+ }
67
+
68
+ // NOTE: maybe this is the limit of how "transparent" the bindings need to be.
69
+ // Pending benchmarks, this can be very inefficient because obviously
70
+ // ts_query_cursor_next_capture is intended to be used in a loop. Creating an
71
+ // array of two values and returning them, intuitively speaking, seem very
72
+ // inefficient.
73
+ static VALUE query_cursor_next_capture(VALUE self) {
74
+ TSQueryMatch match;
75
+ uint32_t index;
76
+ if (ts_query_cursor_next_capture(SELF, &match, &index)) {
77
+ VALUE res = rb_ary_new_capa(2);
78
+ rb_ary_push(res, UINT2NUM(index));
79
+ rb_ary_push(res, new_query_match(&match));
80
+ return res;
81
+ } else {
82
+ return Qnil;
83
+ }
84
+ }
85
+
86
+ void init_query_cursor(void) {
87
+ cQueryCursor = rb_define_class_under(mTreeSitter, "QueryCursor", rb_cObject);
88
+
89
+ rb_define_alloc_func(cQueryCursor, query_cursor_allocate);
90
+
91
+ /* Class methods */
92
+ DECLARE_ACCESSOR(cQueryCursor, query_cursor, match_limit)
93
+ rb_define_module_function(cQueryCursor, "exec", query_cursor_exec, 2);
94
+ rb_define_method(cQueryCursor, "exceed_match_limit?",
95
+ query_cursor_did_exceed_match_limit, 0);
96
+ rb_define_method(cQueryCursor, "set_byte_range", query_cursor_set_byte_range,
97
+ 2);
98
+ rb_define_method(cQueryCursor, "set_point_range",
99
+ query_cursor_set_point_range, 2);
100
+ rb_define_method(cQueryCursor, "next_match", query_cursor_next_match, 0);
101
+ rb_define_method(cQueryCursor, "remove_match", query_cursor_remove_match, 1);
102
+ rb_define_method(cQueryCursor, "next_capture", query_cursor_next_capture, 0);
103
+ }
@@ -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
+ }