ruby_tree_sitter 0.20.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +152 -0
- data/ext/tree_sitter/encoding.c +29 -0
- data/ext/tree_sitter/extconf.rb +172 -0
- data/ext/tree_sitter/input.c +126 -0
- data/ext/tree_sitter/input_edit.c +42 -0
- data/ext/tree_sitter/language.c +134 -0
- data/ext/tree_sitter/logger.c +212 -0
- data/ext/tree_sitter/macros.h +163 -0
- data/ext/tree_sitter/node.c +310 -0
- data/ext/tree_sitter/parser.c +203 -0
- data/ext/tree_sitter/point.c +26 -0
- data/ext/tree_sitter/quantifier.c +43 -0
- data/ext/tree_sitter/query.c +157 -0
- data/ext/tree_sitter/query_capture.c +28 -0
- data/ext/tree_sitter/query_cursor.c +103 -0
- data/ext/tree_sitter/query_error.c +41 -0
- data/ext/tree_sitter/query_match.c +44 -0
- data/ext/tree_sitter/query_predicate_step.c +83 -0
- data/ext/tree_sitter/range.c +35 -0
- data/ext/tree_sitter/symbol_type.c +46 -0
- data/ext/tree_sitter/tree.c +145 -0
- data/ext/tree_sitter/tree_cursor.c +97 -0
- data/ext/tree_sitter/tree_sitter.c +32 -0
- data/ext/tree_sitter/tree_sitter.h +107 -0
- data/lib/tree_sitter/node.rb +164 -0
- data/lib/tree_sitter/version.rb +5 -0
- data/lib/tree_sitter.rb +13 -0
- data/test/README.md +15 -0
- data/test/test_helper.rb +9 -0
- data/test/tree_sitter/language_test.rb +68 -0
- data/test/tree_sitter/logger_test.rb +69 -0
- data/test/tree_sitter/node_test.rb +355 -0
- data/test/tree_sitter/parser_test.rb +140 -0
- data/test/tree_sitter/query_test.rb +153 -0
- data/test/tree_sitter/tree_cursor_test.rb +83 -0
- data/test/tree_sitter/tree_test.rb +51 -0
- data/tree_sitter.gemspec +32 -0
- metadata +189 -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
|
+
}
|