Extract 'internal' versions of tree cursor movement fns that allow visiting hidden nodes
This commit is contained in:
parent
189cf6d59d
commit
29c9073177
2 changed files with 72 additions and 69 deletions
|
|
@ -98,34 +98,43 @@ void ts_tree_cursor_delete(TSTreeCursor *_self) {
|
|||
|
||||
// TSTreeCursor - walking the tree
|
||||
|
||||
bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self) {
|
||||
TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *_self) {
|
||||
TreeCursor *self = (TreeCursor *)_self;
|
||||
|
||||
bool did_descend;
|
||||
do {
|
||||
did_descend = false;
|
||||
|
||||
bool visible;
|
||||
TreeCursorEntry entry;
|
||||
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
||||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
if (visible) {
|
||||
array_push(&self->stack, entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
|
||||
array_push(&self->stack, entry);
|
||||
did_descend = true;
|
||||
break;
|
||||
}
|
||||
bool visible;
|
||||
TreeCursorEntry entry;
|
||||
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
||||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
if (visible) {
|
||||
array_push(&self->stack, entry);
|
||||
return TreeCursorStepVisible;
|
||||
}
|
||||
} while (did_descend);
|
||||
if (ts_subtree_visible_child_count(*entry.subtree) > 0) {
|
||||
array_push(&self->stack, entry);
|
||||
return TreeCursorStepHidden;
|
||||
}
|
||||
}
|
||||
return TreeCursorStepNone;
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_first_child(TSTreeCursor *self) {
|
||||
for (;;) {
|
||||
switch (ts_tree_cursor_goto_first_child_internal(self)) {
|
||||
case TreeCursorStepHidden:
|
||||
continue;
|
||||
case TreeCursorStepVisible:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t goal_byte) {
|
||||
static inline int64_t ts_tree_cursor_goto_first_child_for_byte_and_point(
|
||||
TSTreeCursor *_self,
|
||||
uint32_t goal_byte,
|
||||
TSPoint goal_point
|
||||
) {
|
||||
TreeCursor *self = (TreeCursor *)_self;
|
||||
uint32_t initial_size = self->stack.size;
|
||||
uint32_t visible_child_index = 0;
|
||||
|
|
@ -138,48 +147,8 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
|
|||
TreeCursorEntry entry;
|
||||
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
||||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
uint32_t end_byte = entry.position.bytes + ts_subtree_size(*entry.subtree).bytes;
|
||||
bool at_goal = end_byte >= goal_byte;
|
||||
uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
|
||||
|
||||
if (at_goal) {
|
||||
if (visible) {
|
||||
array_push(&self->stack, entry);
|
||||
return visible_child_index;
|
||||
}
|
||||
|
||||
if (visible_child_count > 0) {
|
||||
array_push(&self->stack, entry);
|
||||
did_descend = true;
|
||||
break;
|
||||
}
|
||||
} else if (visible) {
|
||||
visible_child_index++;
|
||||
} else {
|
||||
visible_child_index += visible_child_count;
|
||||
}
|
||||
}
|
||||
} while (did_descend);
|
||||
|
||||
self->stack.size = initial_size;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *_self, TSPoint goal_point) {
|
||||
TreeCursor *self = (TreeCursor *)_self;
|
||||
uint32_t initial_size = self->stack.size;
|
||||
uint32_t visible_child_index = 0;
|
||||
|
||||
bool did_descend;
|
||||
do {
|
||||
did_descend = false;
|
||||
|
||||
bool visible;
|
||||
TreeCursorEntry entry;
|
||||
CursorChildIterator iterator = ts_tree_cursor_iterate_children(self);
|
||||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
TSPoint end_point = point_add(entry.position.extent, ts_subtree_size(*entry.subtree).extent);
|
||||
bool at_goal = point_gte(end_point, goal_point);
|
||||
Length entry_end = length_add(entry.position, ts_subtree_size(*entry.subtree));
|
||||
bool at_goal = entry_end.bytes >= goal_byte && point_gte(entry_end.extent, goal_point);
|
||||
uint32_t visible_child_count = ts_subtree_visible_child_count(*entry.subtree);
|
||||
if (at_goal) {
|
||||
if (visible) {
|
||||
|
|
@ -203,7 +172,15 @@ int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *_self, TSPoint g
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) {
|
||||
int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *self, uint32_t goal_byte) {
|
||||
return ts_tree_cursor_goto_first_child_for_byte_and_point(self, goal_byte, POINT_ZERO);
|
||||
}
|
||||
|
||||
int64_t ts_tree_cursor_goto_first_child_for_point(TSTreeCursor *self, TSPoint goal_point) {
|
||||
return ts_tree_cursor_goto_first_child_for_byte_and_point(self, 0, goal_point);
|
||||
}
|
||||
|
||||
TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *_self) {
|
||||
TreeCursor *self = (TreeCursor *)_self;
|
||||
uint32_t initial_size = self->stack.size;
|
||||
|
||||
|
|
@ -221,19 +198,30 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) {
|
|||
while (ts_tree_cursor_child_iterator_next(&iterator, &entry, &visible)) {
|
||||
if (visible) {
|
||||
array_push(&self->stack, entry);
|
||||
return true;
|
||||
return TreeCursorStepVisible;
|
||||
}
|
||||
|
||||
if (ts_subtree_visible_child_count(*entry.subtree)) {
|
||||
array_push(&self->stack, entry);
|
||||
ts_tree_cursor_goto_first_child(_self);
|
||||
return true;
|
||||
return TreeCursorStepHidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self->stack.size = initial_size;
|
||||
return false;
|
||||
return TreeCursorStepNone;
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *self) {
|
||||
switch (ts_tree_cursor_goto_next_sibling_internal(self)) {
|
||||
case TreeCursorStepHidden:
|
||||
ts_tree_cursor_goto_first_child(self);
|
||||
return true;
|
||||
case TreeCursorStepVisible:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ts_tree_cursor_goto_parent(TSTreeCursor *_self) {
|
||||
|
|
|
|||
|
|
@ -15,6 +15,12 @@ typedef struct {
|
|||
Array(TreeCursorEntry) stack;
|
||||
} TreeCursor;
|
||||
|
||||
typedef enum {
|
||||
TreeCursorStepNone,
|
||||
TreeCursorStepHidden,
|
||||
TreeCursorStepVisible,
|
||||
} TreeCursorStep;
|
||||
|
||||
void ts_tree_cursor_init(TreeCursor *, TSNode);
|
||||
void ts_tree_cursor_current_status(
|
||||
const TSTreeCursor *,
|
||||
|
|
@ -26,6 +32,15 @@ void ts_tree_cursor_current_status(
|
|||
unsigned *
|
||||
);
|
||||
|
||||
TreeCursorStep ts_tree_cursor_goto_first_child_internal(TSTreeCursor *);
|
||||
TreeCursorStep ts_tree_cursor_goto_next_sibling_internal(TSTreeCursor *);
|
||||
|
||||
static inline Subtree ts_tree_cursor_current_subtree(const TSTreeCursor *_self) {
|
||||
const TreeCursor *self = (const TreeCursor *)_self;
|
||||
TreeCursorEntry *last_entry = array_back(&self->stack);
|
||||
return *last_entry->subtree;
|
||||
}
|
||||
|
||||
TSNode ts_tree_cursor_parent_node(const TSTreeCursor *);
|
||||
|
||||
#endif // TREE_SITTER_TREE_CURSOR_H_
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue