1 #include <emscripten.h>
2 #include <tree_sitter/api.h>
3 #include <stdio.h>
4 #include "array.h"
5 #include "point.h"
6
7 /*****************************/
8 /* Section - Data marshaling */
9 /*****************************/
10
11 static const uint32_t INPUT_BUFFER_SIZE = 10 * 1024;
12
13 const void *TRANSFER_BUFFER[12] = {
14 NULL, NULL, NULL, NULL,
15 NULL, NULL, NULL, NULL,
16 NULL, NULL, NULL, NULL,
17 };
18
ts_init()19 void *ts_init() {
20 TRANSFER_BUFFER[0] = (const void *)TREE_SITTER_LANGUAGE_VERSION;
21 TRANSFER_BUFFER[1] = (const void *)TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION;
22 return TRANSFER_BUFFER;
23 }
24
code_unit_to_byte(uint32_t unit)25 static uint32_t code_unit_to_byte(uint32_t unit) {
26 return unit << 1;
27 }
28
byte_to_code_unit(uint32_t byte)29 static uint32_t byte_to_code_unit(uint32_t byte) {
30 return byte >> 1;
31 }
32
marshal_node(const void ** buffer,TSNode node)33 static inline void marshal_node(const void **buffer, TSNode node) {
34 buffer[0] = (const void *)node.id;
35 buffer[1] = (const void *)byte_to_code_unit(node.context[0]);
36 buffer[2] = (const void *)node.context[1];
37 buffer[3] = (const void *)byte_to_code_unit(node.context[2]);
38 buffer[4] = (const void *)node.context[3];
39 }
40
unmarshal_node(const TSTree * tree)41 static inline TSNode unmarshal_node(const TSTree *tree) {
42 TSNode node;
43 node.id = TRANSFER_BUFFER[0];
44 node.context[0] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[1]);
45 node.context[1] = (uint32_t)TRANSFER_BUFFER[2];
46 node.context[2] = code_unit_to_byte((uint32_t)TRANSFER_BUFFER[3]);
47 node.context[3] = (uint32_t)TRANSFER_BUFFER[4];
48 node.tree = tree;
49 return node;
50 }
51
marshal_cursor(const TSTreeCursor * cursor)52 static inline void marshal_cursor(const TSTreeCursor *cursor) {
53 TRANSFER_BUFFER[0] = (const void *)cursor->id;
54 TRANSFER_BUFFER[1] = (const void *)cursor->context[0];
55 TRANSFER_BUFFER[2] = (const void *)cursor->context[1];
56 }
57
unmarshal_cursor(const void ** buffer,const TSTree * tree)58 static inline TSTreeCursor unmarshal_cursor(const void **buffer, const TSTree *tree) {
59 TSTreeCursor cursor;
60 cursor.id = buffer[0];
61 cursor.context[0] = (uint32_t)buffer[1];
62 cursor.context[1] = (uint32_t)buffer[2];
63 cursor.tree = tree;
64 return cursor;
65 }
66
marshal_point(TSPoint point)67 static void marshal_point(TSPoint point) {
68 TRANSFER_BUFFER[0] = (const void *)point.row;
69 TRANSFER_BUFFER[1] = (const void *)byte_to_code_unit(point.column);
70 }
71
unmarshal_point(const void ** address)72 static TSPoint unmarshal_point(const void **address) {
73 TSPoint point;
74 point.row = (uint32_t)address[0];
75 point.column = code_unit_to_byte((uint32_t)address[1]);
76 return point;
77 }
78
marshal_range(TSRange * range)79 static void marshal_range(TSRange *range) {
80 range->start_byte = byte_to_code_unit(range->start_byte);
81 range->end_byte = byte_to_code_unit(range->end_byte);
82 range->start_point.column = byte_to_code_unit(range->start_point.column);
83 range->end_point.column = byte_to_code_unit(range->end_point.column);
84 }
85
unmarshal_range(TSRange * range)86 static void unmarshal_range(TSRange *range) {
87 range->start_byte = code_unit_to_byte(range->start_byte);
88 range->end_byte = code_unit_to_byte(range->end_byte);
89 range->start_point.column = code_unit_to_byte(range->start_point.column);
90 range->end_point.column = code_unit_to_byte(range->end_point.column);
91 }
92
unmarshal_edit()93 static TSInputEdit unmarshal_edit() {
94 TSInputEdit edit;
95 const void **address = TRANSFER_BUFFER;
96 edit.start_point = unmarshal_point(address); address += 2;
97 edit.old_end_point = unmarshal_point(address); address += 2;
98 edit.new_end_point = unmarshal_point(address); address += 2;
99 edit.start_byte = code_unit_to_byte((uint32_t)*address); address += 1;
100 edit.old_end_byte = code_unit_to_byte((uint32_t)*address); address += 1;
101 edit.new_end_byte = code_unit_to_byte((uint32_t)*address); address += 1;
102 return edit;
103 }
104
105 /********************/
106 /* Section - Parser */
107 /********************/
108
109 extern void tree_sitter_parse_callback(
110 char *input_buffer,
111 uint32_t index,
112 uint32_t row,
113 uint32_t column,
114 uint32_t *length_read
115 );
116
117 extern void tree_sitter_log_callback(
118 bool is_lex_message,
119 const char *message
120 );
121
call_parse_callback(void * payload,uint32_t byte,TSPoint position,uint32_t * bytes_read)122 static const char *call_parse_callback(
123 void *payload,
124 uint32_t byte,
125 TSPoint position,
126 uint32_t *bytes_read
127 ) {
128 char *buffer = (char *)payload;
129 tree_sitter_parse_callback(
130 buffer,
131 byte_to_code_unit(byte),
132 position.row,
133 byte_to_code_unit(position.column),
134 bytes_read
135 );
136 *bytes_read = code_unit_to_byte(*bytes_read);
137 if (*bytes_read >= INPUT_BUFFER_SIZE) {
138 *bytes_read = INPUT_BUFFER_SIZE - 2;
139 }
140 return buffer;
141 }
142
call_log_callback(void * payload,TSLogType log_type,const char * message)143 static void call_log_callback(
144 void *payload,
145 TSLogType log_type,
146 const char *message
147 ) {
148 tree_sitter_log_callback(log_type == TSLogTypeLex, message);
149 }
150
ts_parser_new_wasm()151 void ts_parser_new_wasm() {
152 TSParser *parser = ts_parser_new();
153 char *input_buffer = calloc(INPUT_BUFFER_SIZE, sizeof(char));
154 TRANSFER_BUFFER[0] = parser;
155 TRANSFER_BUFFER[1] = input_buffer;
156 }
157
ts_parser_enable_logger_wasm(TSParser * self,bool should_log)158 void ts_parser_enable_logger_wasm(TSParser *self, bool should_log) {
159 TSLogger logger = {self, should_log ? call_log_callback : NULL};
160 ts_parser_set_logger(self, logger);
161 }
162
ts_parser_parse_wasm(TSParser * self,char * input_buffer,const TSTree * old_tree,TSRange * ranges,uint32_t range_count)163 TSTree *ts_parser_parse_wasm(
164 TSParser *self,
165 char *input_buffer,
166 const TSTree *old_tree,
167 TSRange *ranges,
168 uint32_t range_count
169 ) {
170 TSInput input = {
171 input_buffer,
172 call_parse_callback,
173 TSInputEncodingUTF16
174 };
175 if (range_count) {
176 for (unsigned i = 0; i < range_count; i++) {
177 unmarshal_range(&ranges[i]);
178 }
179 ts_parser_set_included_ranges(self, ranges, range_count);
180 free(ranges);
181 } else {
182 ts_parser_set_included_ranges(self, NULL, 0);
183 }
184 return ts_parser_parse(self, old_tree, input);
185 }
186
187 /**********************/
188 /* Section - Language */
189 /**********************/
190
ts_language_type_is_named_wasm(const TSLanguage * self,TSSymbol typeId)191 int ts_language_type_is_named_wasm(const TSLanguage *self, TSSymbol typeId) {
192 const TSSymbolType symbolType = ts_language_symbol_type(self, typeId);
193 return symbolType == TSSymbolTypeRegular;
194 }
195
ts_language_type_is_visible_wasm(const TSLanguage * self,TSSymbol typeId)196 int ts_language_type_is_visible_wasm(const TSLanguage *self, TSSymbol typeId) {
197 const TSSymbolType symbolType = ts_language_symbol_type(self, typeId);
198 return symbolType <= TSSymbolTypeAnonymous;
199 }
200
201 /******************/
202 /* Section - Tree */
203 /******************/
204
ts_tree_root_node_wasm(const TSTree * tree)205 void ts_tree_root_node_wasm(const TSTree *tree) {
206 marshal_node(TRANSFER_BUFFER, ts_tree_root_node(tree));
207 }
208
ts_tree_edit_wasm(TSTree * tree)209 void ts_tree_edit_wasm(TSTree *tree) {
210 TSInputEdit edit = unmarshal_edit();
211 ts_tree_edit(tree, &edit);
212 }
213
ts_tree_get_changed_ranges_wasm(TSTree * tree,TSTree * other)214 void ts_tree_get_changed_ranges_wasm(TSTree *tree, TSTree *other) {
215 unsigned range_count;
216 TSRange *ranges = ts_tree_get_changed_ranges(tree, other, &range_count);
217 for (unsigned i = 0; i < range_count; i++) {
218 marshal_range(&ranges[i]);
219 }
220 TRANSFER_BUFFER[0] = (const void *)range_count;
221 TRANSFER_BUFFER[1] = (const void *)ranges;
222 }
223
224 /************************/
225 /* Section - TreeCursor */
226 /************************/
227
ts_tree_cursor_new_wasm(const TSTree * tree)228 void ts_tree_cursor_new_wasm(const TSTree *tree) {
229 TSNode node = unmarshal_node(tree);
230 TSTreeCursor cursor = ts_tree_cursor_new(node);
231 marshal_cursor(&cursor);
232 }
233
ts_tree_cursor_delete_wasm(const TSTree * tree)234 void ts_tree_cursor_delete_wasm(const TSTree *tree) {
235 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
236 ts_tree_cursor_delete(&cursor);
237 }
238
ts_tree_cursor_reset_wasm(const TSTree * tree)239 void ts_tree_cursor_reset_wasm(const TSTree *tree) {
240 TSNode node = unmarshal_node(tree);
241 TSTreeCursor cursor = unmarshal_cursor(&TRANSFER_BUFFER[5], tree);
242 ts_tree_cursor_reset(&cursor, node);
243 marshal_cursor(&cursor);
244 }
245
ts_tree_cursor_goto_first_child_wasm(const TSTree * tree)246 bool ts_tree_cursor_goto_first_child_wasm(const TSTree *tree) {
247 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
248 bool result = ts_tree_cursor_goto_first_child(&cursor);
249 marshal_cursor(&cursor);
250 return result;
251 }
252
ts_tree_cursor_goto_next_sibling_wasm(const TSTree * tree)253 bool ts_tree_cursor_goto_next_sibling_wasm(const TSTree *tree) {
254 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
255 bool result = ts_tree_cursor_goto_next_sibling(&cursor);
256 marshal_cursor(&cursor);
257 return result;
258 }
259
ts_tree_cursor_goto_parent_wasm(const TSTree * tree)260 bool ts_tree_cursor_goto_parent_wasm(const TSTree *tree) {
261 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
262 bool result = ts_tree_cursor_goto_parent(&cursor);
263 marshal_cursor(&cursor);
264 return result;
265 }
266
ts_tree_cursor_current_node_type_id_wasm(const TSTree * tree)267 uint16_t ts_tree_cursor_current_node_type_id_wasm(const TSTree *tree) {
268 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
269 TSNode node = ts_tree_cursor_current_node(&cursor);
270 return ts_node_symbol(node);
271 }
272
ts_tree_cursor_current_node_is_named_wasm(const TSTree * tree)273 bool ts_tree_cursor_current_node_is_named_wasm(const TSTree *tree) {
274 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
275 TSNode node = ts_tree_cursor_current_node(&cursor);
276 return ts_node_is_named(node);
277 }
278
ts_tree_cursor_current_node_is_missing_wasm(const TSTree * tree)279 bool ts_tree_cursor_current_node_is_missing_wasm(const TSTree *tree) {
280 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
281 TSNode node = ts_tree_cursor_current_node(&cursor);
282 return ts_node_is_missing(node);
283 }
284
ts_tree_cursor_current_node_id_wasm(const TSTree * tree)285 const uint32_t ts_tree_cursor_current_node_id_wasm(const TSTree *tree) {
286 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
287 TSNode node = ts_tree_cursor_current_node(&cursor);
288 return (uint32_t)node.id;
289 }
290
ts_tree_cursor_start_position_wasm(const TSTree * tree)291 void ts_tree_cursor_start_position_wasm(const TSTree *tree) {
292 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
293 TSNode node = ts_tree_cursor_current_node(&cursor);
294 marshal_point(ts_node_start_point(node));
295 }
296
ts_tree_cursor_end_position_wasm(const TSTree * tree)297 void ts_tree_cursor_end_position_wasm(const TSTree *tree) {
298 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
299 TSNode node = ts_tree_cursor_current_node(&cursor);
300 marshal_point(ts_node_end_point(node));
301 }
302
ts_tree_cursor_start_index_wasm(const TSTree * tree)303 uint32_t ts_tree_cursor_start_index_wasm(const TSTree *tree) {
304 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
305 TSNode node = ts_tree_cursor_current_node(&cursor);
306 return byte_to_code_unit(ts_node_start_byte(node));
307 }
308
ts_tree_cursor_end_index_wasm(const TSTree * tree)309 uint32_t ts_tree_cursor_end_index_wasm(const TSTree *tree) {
310 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
311 TSNode node = ts_tree_cursor_current_node(&cursor);
312 return byte_to_code_unit(ts_node_end_byte(node));
313 }
314
ts_tree_cursor_current_field_id_wasm(const TSTree * tree)315 uint32_t ts_tree_cursor_current_field_id_wasm(const TSTree *tree) {
316 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
317 return ts_tree_cursor_current_field_id(&cursor);
318 }
319
ts_tree_cursor_current_node_wasm(const TSTree * tree)320 void ts_tree_cursor_current_node_wasm(const TSTree *tree) {
321 TSTreeCursor cursor = unmarshal_cursor(TRANSFER_BUFFER, tree);
322 marshal_node(TRANSFER_BUFFER, ts_tree_cursor_current_node(&cursor));
323 }
324
325 /******************/
326 /* Section - Node */
327 /******************/
328
329 static TSTreeCursor scratch_cursor = {0};
330 static TSQueryCursor *scratch_query_cursor = NULL;
331
ts_node_symbol_wasm(const TSTree * tree)332 uint16_t ts_node_symbol_wasm(const TSTree *tree) {
333 TSNode node = unmarshal_node(tree);
334 return ts_node_symbol(node);
335 }
336
ts_node_child_count_wasm(const TSTree * tree)337 uint32_t ts_node_child_count_wasm(const TSTree *tree) {
338 TSNode node = unmarshal_node(tree);
339 return ts_node_child_count(node);
340 }
341
ts_node_named_child_count_wasm(const TSTree * tree)342 uint32_t ts_node_named_child_count_wasm(const TSTree *tree) {
343 TSNode node = unmarshal_node(tree);
344 return ts_node_named_child_count(node);
345 }
346
ts_node_child_wasm(const TSTree * tree,uint32_t index)347 void ts_node_child_wasm(const TSTree *tree, uint32_t index) {
348 TSNode node = unmarshal_node(tree);
349 marshal_node(TRANSFER_BUFFER, ts_node_child(node, index));
350 }
351
ts_node_named_child_wasm(const TSTree * tree,uint32_t index)352 void ts_node_named_child_wasm(const TSTree *tree, uint32_t index) {
353 TSNode node = unmarshal_node(tree);
354 marshal_node(TRANSFER_BUFFER, ts_node_named_child(node, index));
355 }
356
ts_node_child_by_field_id_wasm(const TSTree * tree,uint32_t field_id)357 void ts_node_child_by_field_id_wasm(const TSTree *tree, uint32_t field_id) {
358 TSNode node = unmarshal_node(tree);
359 marshal_node(TRANSFER_BUFFER, ts_node_child_by_field_id(node, field_id));
360 }
361
ts_node_next_sibling_wasm(const TSTree * tree)362 void ts_node_next_sibling_wasm(const TSTree *tree) {
363 TSNode node = unmarshal_node(tree);
364 marshal_node(TRANSFER_BUFFER, ts_node_next_sibling(node));
365 }
366
ts_node_prev_sibling_wasm(const TSTree * tree)367 void ts_node_prev_sibling_wasm(const TSTree *tree) {
368 TSNode node = unmarshal_node(tree);
369 marshal_node(TRANSFER_BUFFER, ts_node_prev_sibling(node));
370 }
371
ts_node_next_named_sibling_wasm(const TSTree * tree)372 void ts_node_next_named_sibling_wasm(const TSTree *tree) {
373 TSNode node = unmarshal_node(tree);
374 marshal_node(TRANSFER_BUFFER, ts_node_next_named_sibling(node));
375 }
376
ts_node_prev_named_sibling_wasm(const TSTree * tree)377 void ts_node_prev_named_sibling_wasm(const TSTree *tree) {
378 TSNode node = unmarshal_node(tree);
379 marshal_node(TRANSFER_BUFFER, ts_node_prev_named_sibling(node));
380 }
381
ts_node_parent_wasm(const TSTree * tree)382 void ts_node_parent_wasm(const TSTree *tree) {
383 TSNode node = unmarshal_node(tree);
384 marshal_node(TRANSFER_BUFFER, ts_node_parent(node));
385 }
386
ts_node_descendant_for_index_wasm(const TSTree * tree)387 void ts_node_descendant_for_index_wasm(const TSTree *tree) {
388 TSNode node = unmarshal_node(tree);
389 const void **address = TRANSFER_BUFFER + 5;
390 uint32_t start = code_unit_to_byte((uint32_t)address[0]);
391 uint32_t end = code_unit_to_byte((uint32_t)address[1]);
392 marshal_node(TRANSFER_BUFFER, ts_node_descendant_for_byte_range(node, start, end));
393 }
394
ts_node_named_descendant_for_index_wasm(const TSTree * tree)395 void ts_node_named_descendant_for_index_wasm(const TSTree *tree) {
396 TSNode node = unmarshal_node(tree);
397 const void **address = TRANSFER_BUFFER + 5;
398 uint32_t start = code_unit_to_byte((uint32_t)address[0]);
399 uint32_t end = code_unit_to_byte((uint32_t)address[1]);
400 marshal_node(TRANSFER_BUFFER, ts_node_named_descendant_for_byte_range(node, start, end));
401 }
402
ts_node_descendant_for_position_wasm(const TSTree * tree)403 void ts_node_descendant_for_position_wasm(const TSTree *tree) {
404 TSNode node = unmarshal_node(tree);
405 const void **address = TRANSFER_BUFFER + 5;
406 TSPoint start = unmarshal_point(address); address += 2;
407 TSPoint end = unmarshal_point(address);
408 marshal_node(TRANSFER_BUFFER, ts_node_descendant_for_point_range(node, start, end));
409 }
410
ts_node_named_descendant_for_position_wasm(const TSTree * tree)411 void ts_node_named_descendant_for_position_wasm(const TSTree *tree) {
412 TSNode node = unmarshal_node(tree);
413 const void **address = TRANSFER_BUFFER + 5;
414 TSPoint start = unmarshal_point(address); address += 2;
415 TSPoint end = unmarshal_point(address);
416 marshal_node(TRANSFER_BUFFER, ts_node_named_descendant_for_point_range(node, start, end));
417 }
418
ts_node_start_point_wasm(const TSTree * tree)419 void ts_node_start_point_wasm(const TSTree *tree) {
420 TSNode node = unmarshal_node(tree);
421 marshal_point(ts_node_start_point(node));
422 }
423
ts_node_end_point_wasm(const TSTree * tree)424 void ts_node_end_point_wasm(const TSTree *tree) {
425 TSNode node = unmarshal_node(tree);
426 marshal_point(ts_node_end_point(node));
427 }
428
ts_node_start_index_wasm(const TSTree * tree)429 uint32_t ts_node_start_index_wasm(const TSTree *tree) {
430 TSNode node = unmarshal_node(tree);
431 return byte_to_code_unit(ts_node_start_byte(node));
432 }
433
ts_node_end_index_wasm(const TSTree * tree)434 uint32_t ts_node_end_index_wasm(const TSTree *tree) {
435 TSNode node = unmarshal_node(tree);
436 return byte_to_code_unit(ts_node_end_byte(node));
437 }
438
ts_node_to_string_wasm(const TSTree * tree)439 char *ts_node_to_string_wasm(const TSTree *tree) {
440 TSNode node = unmarshal_node(tree);
441 return ts_node_string(node);
442 }
443
ts_node_children_wasm(const TSTree * tree)444 void ts_node_children_wasm(const TSTree *tree) {
445 TSNode node = unmarshal_node(tree);
446 uint32_t count = ts_node_child_count(node);
447 const void **result = NULL;
448 if (count > 0) {
449 result = calloc(sizeof(void *), 5 * count);
450 const void **address = result;
451 ts_tree_cursor_reset(&scratch_cursor, node);
452 ts_tree_cursor_goto_first_child(&scratch_cursor);
453 marshal_node(address, ts_tree_cursor_current_node(&scratch_cursor));
454 for (uint32_t i = 1; i < count; i++) {
455 address += 5;
456 ts_tree_cursor_goto_next_sibling(&scratch_cursor);
457 TSNode child = ts_tree_cursor_current_node(&scratch_cursor);
458 marshal_node(address, child);
459 }
460 }
461 TRANSFER_BUFFER[0] = (const void *)count;
462 TRANSFER_BUFFER[1] = result;
463 }
464
ts_node_named_children_wasm(const TSTree * tree)465 void ts_node_named_children_wasm(const TSTree *tree) {
466 TSNode node = unmarshal_node(tree);
467 uint32_t count = ts_node_named_child_count(node);
468 const void **result = NULL;
469 if (count > 0) {
470 result = calloc(sizeof(void *), 5 * count);
471 const void **address = result;
472 ts_tree_cursor_reset(&scratch_cursor, node);
473 ts_tree_cursor_goto_first_child(&scratch_cursor);
474 uint32_t i = 0;
475 for (;;) {
476 TSNode child = ts_tree_cursor_current_node(&scratch_cursor);
477 if (ts_node_is_named(child)) {
478 marshal_node(address, child);
479 address += 5;
480 i++;
481 if (i == count) break;
482 }
483 if (!ts_tree_cursor_goto_next_sibling(&scratch_cursor)) break;
484 }
485 }
486 TRANSFER_BUFFER[0] = (const void *)count;
487 TRANSFER_BUFFER[1] = result;
488 }
489
symbols_contain(const uint32_t * set,uint32_t length,uint32_t value)490 bool symbols_contain(const uint32_t *set, uint32_t length, uint32_t value) {
491 for (unsigned i = 0; i < length; i++) {
492 if (set[i] == value) return true;
493 if (set[i] > value) break;
494 }
495 return false;
496 }
497
ts_node_descendants_of_type_wasm(const TSTree * tree,const uint32_t * symbols,uint32_t symbol_count,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column)498 void ts_node_descendants_of_type_wasm(
499 const TSTree *tree,
500 const uint32_t *symbols,
501 uint32_t symbol_count,
502 uint32_t start_row,
503 uint32_t start_column,
504 uint32_t end_row,
505 uint32_t end_column
506 ) {
507 TSNode node = unmarshal_node(tree);
508 TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
509 TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
510 if (end_point.row == 0 && end_point.column == 0) {
511 end_point = (TSPoint) {UINT32_MAX, UINT32_MAX};
512 }
513
514 Array(const void *) result = array_new();
515
516 // Walk the tree depth first looking for matching nodes.
517 ts_tree_cursor_reset(&scratch_cursor, node);
518 bool already_visited_children = false;
519 while (true) {
520 TSNode descendant = ts_tree_cursor_current_node(&scratch_cursor);
521
522 if (!already_visited_children) {
523 // If this node is before the selected range, then avoid
524 // descending into it.
525 if (point_lte(ts_node_end_point(descendant), start_point)) {
526 if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
527 already_visited_children = false;
528 } else {
529 if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
530 already_visited_children = true;
531 }
532 continue;
533 }
534
535 // If this node is after the selected range, then stop walking.
536 if (point_lte(end_point, ts_node_start_point(descendant))) break;
537
538 // Add the node to the result if its type matches one of the given
539 // node types.
540 if (symbols_contain(symbols, symbol_count, ts_node_symbol(descendant))) {
541 array_grow_by(&result, 5);
542 marshal_node(result.contents + result.size - 5, descendant);
543 }
544
545 // Continue walking.
546 if (ts_tree_cursor_goto_first_child(&scratch_cursor)) {
547 already_visited_children = false;
548 } else if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
549 already_visited_children = false;
550 } else {
551 if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
552 already_visited_children = true;
553 }
554 } else {
555 if (ts_tree_cursor_goto_next_sibling(&scratch_cursor)) {
556 already_visited_children = false;
557 } else {
558 if (!ts_tree_cursor_goto_parent(&scratch_cursor)) break;
559 }
560 }
561 }
562
563 TRANSFER_BUFFER[0] = (const void *)(result.size / 5);
564 TRANSFER_BUFFER[1] = result.contents;
565 }
566
ts_node_is_named_wasm(const TSTree * tree)567 int ts_node_is_named_wasm(const TSTree *tree) {
568 TSNode node = unmarshal_node(tree);
569 return ts_node_is_named(node);
570 }
571
ts_node_has_changes_wasm(const TSTree * tree)572 int ts_node_has_changes_wasm(const TSTree *tree) {
573 TSNode node = unmarshal_node(tree);
574 return ts_node_has_changes(node);
575 }
576
ts_node_has_error_wasm(const TSTree * tree)577 int ts_node_has_error_wasm(const TSTree *tree) {
578 TSNode node = unmarshal_node(tree);
579 return ts_node_has_error(node);
580 }
581
ts_node_is_missing_wasm(const TSTree * tree)582 int ts_node_is_missing_wasm(const TSTree *tree) {
583 TSNode node = unmarshal_node(tree);
584 return ts_node_is_missing(node);
585 }
586
587 /******************/
588 /* Section - Query */
589 /******************/
590
ts_query_matches_wasm(const TSQuery * self,const TSTree * tree,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column,uint32_t match_limit)591 void ts_query_matches_wasm(
592 const TSQuery *self,
593 const TSTree *tree,
594 uint32_t start_row,
595 uint32_t start_column,
596 uint32_t end_row,
597 uint32_t end_column,
598 uint32_t match_limit
599 ) {
600 if (!scratch_query_cursor) scratch_query_cursor = ts_query_cursor_new();
601 if (match_limit == 0) {
602 ts_query_cursor_set_match_limit(scratch_query_cursor, UINT32_MAX);
603 } else {
604 ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit);
605 }
606
607 TSNode node = unmarshal_node(tree);
608 TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
609 TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
610 ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point);
611 ts_query_cursor_exec(scratch_query_cursor, self, node);
612
613 uint32_t index = 0;
614 uint32_t match_count = 0;
615 Array(const void *) result = array_new();
616
617 TSQueryMatch match;
618 while (ts_query_cursor_next_match(scratch_query_cursor, &match)) {
619 match_count++;
620 array_grow_by(&result, 2 + 6 * match.capture_count);
621 result.contents[index++] = (const void *)(uint32_t)match.pattern_index;
622 result.contents[index++] = (const void *)(uint32_t)match.capture_count;
623 for (unsigned i = 0; i < match.capture_count; i++) {
624 const TSQueryCapture *capture = &match.captures[i];
625 result.contents[index++] = (const void *)capture->index;
626 marshal_node(result.contents + index, capture->node);
627 index += 5;
628 }
629 }
630
631 bool did_exceed_match_limit =
632 ts_query_cursor_did_exceed_match_limit(scratch_query_cursor);
633 TRANSFER_BUFFER[0] = (const void *)(match_count);
634 TRANSFER_BUFFER[1] = result.contents;
635 TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit);
636 }
637
ts_query_captures_wasm(const TSQuery * self,const TSTree * tree,uint32_t start_row,uint32_t start_column,uint32_t end_row,uint32_t end_column,uint32_t match_limit)638 void ts_query_captures_wasm(
639 const TSQuery *self,
640 const TSTree *tree,
641 uint32_t start_row,
642 uint32_t start_column,
643 uint32_t end_row,
644 uint32_t end_column,
645 uint32_t match_limit
646 ) {
647 if (!scratch_query_cursor) scratch_query_cursor = ts_query_cursor_new();
648 if (match_limit == 0) {
649 ts_query_cursor_set_match_limit(scratch_query_cursor, UINT32_MAX);
650 } else {
651 ts_query_cursor_set_match_limit(scratch_query_cursor, match_limit);
652 }
653
654 TSNode node = unmarshal_node(tree);
655 TSPoint start_point = {start_row, code_unit_to_byte(start_column)};
656 TSPoint end_point = {end_row, code_unit_to_byte(end_column)};
657 ts_query_cursor_set_point_range(scratch_query_cursor, start_point, end_point);
658 ts_query_cursor_exec(scratch_query_cursor, self, node);
659
660 unsigned index = 0;
661 unsigned capture_count = 0;
662 Array(const void *) result = array_new();
663
664 TSQueryMatch match;
665 uint32_t capture_index;
666 while (ts_query_cursor_next_capture(
667 scratch_query_cursor,
668 &match,
669 &capture_index
670 )) {
671 capture_count++;
672
673 array_grow_by(&result, 3 + 6 * match.capture_count);
674 result.contents[index++] = (const void *)(uint32_t)match.pattern_index;
675 result.contents[index++] = (const void *)(uint32_t)match.capture_count;
676 result.contents[index++] = (const void *)(uint32_t)capture_index;
677 for (unsigned i = 0; i < match.capture_count; i++) {
678 const TSQueryCapture *capture = &match.captures[i];
679 result.contents[index++] = (const void *)capture->index;
680 marshal_node(result.contents + index, capture->node);
681 index += 5;
682 }
683 }
684
685 bool did_exceed_match_limit =
686 ts_query_cursor_did_exceed_match_limit(scratch_query_cursor);
687 TRANSFER_BUFFER[0] = (const void *)(capture_count);
688 TRANSFER_BUFFER[1] = result.contents;
689 TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit);
690 }
691