diff --git a/include/tree_sitter/runtime.h b/include/tree_sitter/runtime.h index 42fc7ea4..71c8b5b3 100644 --- a/include/tree_sitter/runtime.h +++ b/include/tree_sitter/runtime.h @@ -16,7 +16,6 @@ typedef unsigned short TSSymbol; typedef struct TSLanguage TSLanguage; typedef struct TSParser TSParser; typedef struct TSTree TSTree; -typedef struct TSTreeCursor TSTreeCursor; typedef enum { TSInputEncodingUTF8, @@ -66,10 +65,15 @@ typedef struct { } TSInputEdit; typedef struct { - const void *ref[2]; uint32_t context[4]; + const void *ref[2]; } TSNode; +typedef struct { + uint32_t context[2]; + void *ref[2]; +} TSTreeCursor; + TSParser *ts_parser_new(); void ts_parser_delete(TSParser *); const TSLanguage *ts_parser_language(const TSParser *); @@ -117,7 +121,7 @@ TSNode ts_node_named_descendant_for_byte_range(TSNode, uint32_t, uint32_t); TSNode ts_node_descendant_for_point_range(TSNode, TSPoint, TSPoint); TSNode ts_node_named_descendant_for_point_range(TSNode, TSPoint, TSPoint); -TSTreeCursor *ts_tree_cursor_new(const TSTree *); +TSTreeCursor ts_tree_cursor_new(const TSTree *); void ts_tree_cursor_delete(TSTreeCursor *); bool ts_tree_cursor_goto_first_child(TSTreeCursor *); int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *, uint32_t); diff --git a/src/runtime/get_changed_ranges.c b/src/runtime/get_changed_ranges.c index 2b015d27..d46bf704 100644 --- a/src/runtime/get_changed_ranges.c +++ b/src/runtime/get_changed_ranges.c @@ -25,13 +25,13 @@ static void range_array_add(RangeArray *results, TSPoint start, TSPoint end) { } typedef struct { - TSTreeCursor cursor; + TreeCursor cursor; const TSLanguage *language; unsigned visible_depth; bool in_padding; } Iterator; -static Iterator iterator_new(TSTreeCursor *cursor, const Subtree *tree, const TSLanguage *language) { +static Iterator iterator_new(TreeCursor *cursor, const Subtree *tree, const TSLanguage *language) { array_clear(&cursor->stack); array_push(&cursor->stack, ((TreeCursorEntry){ .subtree = tree, @@ -262,7 +262,7 @@ static inline void iterator_print_state(Iterator *self) { #endif unsigned ts_subtree_get_changed_ranges(const Subtree *old_tree, const Subtree *new_tree, - TSTreeCursor *cursor1, TSTreeCursor *cursor2, + TreeCursor *cursor1, TreeCursor *cursor2, const TSLanguage *language, TSRange **ranges) { RangeArray results = array_new(); diff --git a/src/runtime/get_changed_ranges.h b/src/runtime/get_changed_ranges.h index fbe9cc23..9daeb919 100644 --- a/src/runtime/get_changed_ranges.h +++ b/src/runtime/get_changed_ranges.h @@ -1,11 +1,12 @@ #ifndef RUNTIME_GET_CHANGED_RANGES_H_ #define RUNTIME_GET_CHANGED_RANGES_H_ +#include "runtime/tree_cursor.h" #include "runtime/subtree.h" unsigned ts_subtree_get_changed_ranges( const Subtree *old_tree, const Subtree *new_tree, - TSTreeCursor *cursor1, TSTreeCursor *cursor2, + TreeCursor *cursor1, TreeCursor *cursor2, const TSLanguage *language, TSRange **ranges ); diff --git a/src/runtime/node.c b/src/runtime/node.c index 24ce7b13..8eaaf220 100644 --- a/src/runtime/node.c +++ b/src/runtime/node.c @@ -16,13 +16,13 @@ typedef struct { TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, Length position, TSSymbol alias) { return (TSNode) { + {position.bytes, position.extent.row, position.extent.column, alias}, {tree, subtree}, - {position.bytes, position.extent.row, position.extent.column, alias} }; } static inline TSNode ts_node__null() { - return (TSNode) {{NULL, NULL}, {0, 0, 0, 0}}; + return ts_node_new(NULL, NULL, length_zero(), 0); } // TSNode - accessors diff --git a/src/runtime/tree.c b/src/runtime/tree.c index 4a64483b..5e82df89 100644 --- a/src/runtime/tree.c +++ b/src/runtime/tree.c @@ -36,7 +36,7 @@ void ts_tree_edit(TSTree *self, const TSInputEdit *edit) { TSRange *ts_tree_get_changed_ranges(const TSTree *self, const TSTree *other, uint32_t *count) { TSRange *result; - TSTreeCursor cursor1, cursor2; + TreeCursor cursor1, cursor2; ts_tree_cursor_init(&cursor1, self); ts_tree_cursor_init(&cursor2, self); *count = ts_subtree_get_changed_ranges( diff --git a/src/runtime/tree_cursor.c b/src/runtime/tree_cursor.c index 5300f3d3..d7695634 100644 --- a/src/runtime/tree_cursor.c +++ b/src/runtime/tree_cursor.c @@ -4,13 +4,13 @@ #include "runtime/language.h" #include "runtime/tree.h" -TSTreeCursor *ts_tree_cursor_new(const TSTree *tree) { - TSTreeCursor *self = ts_malloc(sizeof(TSTreeCursor)); - ts_tree_cursor_init(self, tree); +TSTreeCursor ts_tree_cursor_new(const TSTree *tree) { + TSTreeCursor self; + ts_tree_cursor_init((TreeCursor *)&self, tree); return self; } -void ts_tree_cursor_init(TSTreeCursor *self, const TSTree *tree) { +void ts_tree_cursor_init(TreeCursor *self, const TSTree *tree) { self->tree = tree; array_init(&self->stack); array_push(&self->stack, ((TreeCursorEntry) { @@ -21,12 +21,13 @@ void ts_tree_cursor_init(TSTreeCursor *self, const TSTree *tree) { })); } -void ts_tree_cursor_delete(TSTreeCursor *self) { +void ts_tree_cursor_delete(TSTreeCursor *_self) { + TreeCursor *self = (TreeCursor *)_self; array_delete(&self->stack); - ts_free(self); } -bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) { +bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self) { + TreeCursor *self = (TreeCursor *)_self; TreeCursorEntry *last_entry = array_back(&self->stack); const Subtree *tree = last_entry->subtree; Length position = last_entry->position; @@ -62,7 +63,8 @@ bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) { return false; } -int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) { +int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t goal_byte) { + TreeCursor *self = (TreeCursor *)_self; uint32_t initial_size = self->stack.size; TreeCursorEntry *last_entry = array_back(&self->stack); const Subtree *tree = last_entry->subtree; @@ -113,7 +115,8 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t go return -1; } -bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) { +bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) { + TreeCursor *self = (TreeCursor *)_self; TreeCursorEntry *child_entry = array_back(&self->stack); for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) { @@ -142,7 +145,7 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) { if (child->visible) { return true; } else { - ts_tree_cursor_goto_first_child(self); + ts_tree_cursor_goto_first_child(_self); return true; } } @@ -155,7 +158,8 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) { return false; } -bool ts_tree_cursor_goto_parent(TSTreeCursor *self) { +bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) { + TreeCursor *self = (TreeCursor *)_self; for (unsigned i = self->stack.size - 2; i + 1 > 0; i--) { TreeCursorEntry *entry = &self->stack.contents[i]; if (entry->subtree->visible) { @@ -166,7 +170,8 @@ bool ts_tree_cursor_goto_parent(TSTreeCursor *self) { return false; } -TSNode ts_tree_cursor_current_node(TSTreeCursor *self) { +TSNode ts_tree_cursor_current_node(TSTreeCursor *_self) { + TreeCursor *self = (TreeCursor *)_self; TreeCursorEntry *last_entry = array_back(&self->stack); TSSymbol alias_symbol = 0; if (self->stack.size > 1) { diff --git a/src/runtime/tree_cursor.h b/src/runtime/tree_cursor.h index 615e7e06..0fa1b167 100644 --- a/src/runtime/tree_cursor.h +++ b/src/runtime/tree_cursor.h @@ -10,11 +10,11 @@ typedef struct { uint32_t structural_child_index; } TreeCursorEntry; -struct TSTreeCursor { - const TSTree *tree; +typedef struct { Array(TreeCursorEntry) stack; -}; + const TSTree *tree; +} TreeCursor; -void ts_tree_cursor_init(TSTreeCursor *, const TSTree *); +void ts_tree_cursor_init(TreeCursor *, const TSTree *); #endif // RUNTIME_TREE_CURSOR_H_ diff --git a/test/runtime/node_test.cc b/test/runtime/node_test.cc index 68e79467..3cbd48c8 100644 --- a/test/runtime/node_test.cc +++ b/test/runtime/node_test.cc @@ -527,7 +527,7 @@ describe("Node", [&]() { describe("TreeCursor", [&]() { TSParser *parser; TSTree *tree; - TSTreeCursor *cursor; + TSTreeCursor cursor; before_each([&]() { record_alloc::start(); @@ -540,7 +540,7 @@ describe("TreeCursor", [&]() { after_each([&]() { ts_tree_delete(tree); - ts_tree_cursor_delete(cursor); + ts_tree_cursor_delete(&cursor); ts_parser_delete(parser); record_alloc::stop(); @@ -548,154 +548,154 @@ describe("TreeCursor", [&]() { }); it("can walk the tree", [&]() { - TSNode node = ts_tree_cursor_current_node(cursor); + TSNode node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("value")); AssertThat(ts_node_start_byte(node), Equals(array_index)); - AssertThat(ts_tree_cursor_goto_first_child(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_first_child(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("array")); AssertThat(ts_node_start_byte(node), Equals(array_index)); - AssertThat(ts_tree_cursor_goto_first_child(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_first_child(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("[")); AssertThat(ts_node_start_byte(node), Equals(array_index)); // Cannot descend into a node with no children - AssertThat(ts_tree_cursor_goto_first_child(cursor), IsFalse()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_first_child(&cursor), IsFalse()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("[")); AssertThat(ts_node_start_byte(node), Equals(array_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("number")); AssertThat(ts_node_start_byte(node), Equals(number_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals(",")); AssertThat(ts_node_start_byte(node), Equals(number_end_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("false")); AssertThat(ts_node_start_byte(node), Equals(false_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals(",")); AssertThat(ts_node_start_byte(node), Equals(false_end_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("object")); AssertThat(ts_node_start_byte(node), Equals(object_index)); - AssertThat(ts_tree_cursor_goto_first_child(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_first_child(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("{")); AssertThat(ts_node_start_byte(node), Equals(object_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("pair")); AssertThat(ts_node_start_byte(node), Equals(string_index)); - AssertThat(ts_tree_cursor_goto_first_child(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_first_child(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("string")); AssertThat(ts_node_start_byte(node), Equals(string_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals(":")); AssertThat(ts_node_start_byte(node), Equals(string_end_index)); - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("null")); AssertThat(ts_node_start_byte(node), Equals(null_index)); // Cannot move beyond a node with no next sibling - AssertThat(ts_tree_cursor_goto_next_sibling(cursor), IsFalse()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_next_sibling(&cursor), IsFalse()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("null")); AssertThat(ts_node_start_byte(node), Equals(null_index)); - AssertThat(ts_tree_cursor_goto_parent(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_parent(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("pair")); AssertThat(ts_node_start_byte(node), Equals(string_index)); - AssertThat(ts_tree_cursor_goto_parent(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_parent(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("object")); AssertThat(ts_node_start_byte(node), Equals(object_index)); - AssertThat(ts_tree_cursor_goto_parent(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_parent(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("array")); AssertThat(ts_node_start_byte(node), Equals(array_index)); - AssertThat(ts_tree_cursor_goto_parent(cursor), IsTrue()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_parent(&cursor), IsTrue()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("value")); AssertThat(ts_node_start_byte(node), Equals(array_index)); // The root node doesn't have a parent. - AssertThat(ts_tree_cursor_goto_parent(cursor), IsFalse()); - node = ts_tree_cursor_current_node(cursor); + AssertThat(ts_tree_cursor_goto_parent(&cursor), IsFalse()); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("value")); AssertThat(ts_node_start_byte(node), Equals(array_index)); }); it("can find the first child of a given node which spans the given byte offset", [&]() { - int64_t child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, 1); - TSNode node = ts_tree_cursor_current_node(cursor); + int64_t child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, 1); + TSNode node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("array")); AssertThat(ts_node_start_byte(node), Equals(array_index)); AssertThat(child_index, Equals(0)); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, array_index); - node = ts_tree_cursor_current_node(cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, array_index); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("[")); AssertThat(ts_node_start_byte(node), Equals(array_index)); AssertThat(child_index, Equals(0)); - ts_tree_cursor_goto_parent(cursor); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, array_index + 1); - node = ts_tree_cursor_current_node(cursor); + ts_tree_cursor_goto_parent(&cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, array_index + 1); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("number")); AssertThat(ts_node_start_byte(node), Equals(number_index)); AssertThat(child_index, Equals(1)); - ts_tree_cursor_goto_parent(cursor); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, number_index + 1); - node = ts_tree_cursor_current_node(cursor); + ts_tree_cursor_goto_parent(&cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, number_index + 1); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("number")); AssertThat(ts_node_start_byte(node), Equals(number_index)); AssertThat(child_index, Equals(1)); - ts_tree_cursor_goto_parent(cursor); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, false_index - 1); - node = ts_tree_cursor_current_node(cursor); + ts_tree_cursor_goto_parent(&cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, false_index - 1); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("false")); AssertThat(ts_node_start_byte(node), Equals(false_index)); AssertThat(child_index, Equals(3)); - ts_tree_cursor_goto_parent(cursor); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, object_end_index - 1); - node = ts_tree_cursor_current_node(cursor); + ts_tree_cursor_goto_parent(&cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, object_end_index - 1); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("object")); AssertThat(ts_node_start_byte(node), Equals(object_index)); AssertThat(child_index, Equals(5)); // There is no child past the end of the array - ts_tree_cursor_goto_parent(cursor); - child_index = ts_tree_cursor_goto_first_child_for_byte(cursor, array_end_index); - node = ts_tree_cursor_current_node(cursor); + ts_tree_cursor_goto_parent(&cursor); + child_index = ts_tree_cursor_goto_first_child_for_byte(&cursor, array_end_index); + node = ts_tree_cursor_current_node(&cursor); AssertThat(ts_node_type(node), Equals("array")); AssertThat(ts_node_start_byte(node), Equals(array_index)); AssertThat(child_index, Equals(-1));