Fix handling of aliases in TreeCursor

This commit is contained in:
Max Brunsfeld 2018-05-22 13:30:10 -07:00
parent 5cb4b953e5
commit c0763c69c4
2 changed files with 101 additions and 25 deletions

View file

@ -29,17 +29,27 @@ void ts_tree_cursor_delete(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;
const Subtree *subtree = last_entry->subtree;
if (subtree->children.size == 0 || subtree->visible_child_count == 0) return false;
Length position = last_entry->position;
bool did_descend;
do {
did_descend = false;
const TSSymbol *alias_sequence = ts_language_alias_sequence(
self->tree->language,
subtree->alias_sequence_id
);
uint32_t structural_child_index = 0;
for (uint32_t i = 0; i < tree->children.size; i++) {
const Subtree *child = tree->children.contents[i];
if (child->visible || child->visible_child_count > 0) {
for (uint32_t i = 0; i < subtree->children.size; i++) {
const Subtree *child = subtree->children.contents[i];
bool visible = child->visible;
if (!child->extra) {
visible |= alias_sequence && alias_sequence[structural_child_index];
}
if (visible || (child->children.size > 0 && child->visible_child_count > 0)) {
array_push(&self->stack, ((TreeCursorEntry) {
.subtree = child,
.child_index = i,
@ -47,10 +57,10 @@ bool ts_tree_cursor_goto_first_child(TSTreeCursor *_self) {
.position = position,
}));
if (child->visible) {
if (visible) {
return true;
} else {
tree = child;
subtree = child;
did_descend = true;
break;
}
@ -67,7 +77,7 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
TreeCursor *self = (TreeCursor *)_self;
uint32_t initial_size = self->stack.size;
TreeCursorEntry *last_entry = array_back(&self->stack);
const Subtree *tree = last_entry->subtree;
const Subtree *subtree = last_entry->subtree;
Length position = last_entry->position;
uint32_t visible_child_index = 0;
@ -75,14 +85,25 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
do {
did_descend = false;
const TSSymbol *alias_sequence = ts_language_alias_sequence(
self->tree->language,
subtree->alias_sequence_id
);
uint32_t structural_child_index = 0;
for (uint32_t i = 0; i < tree->children.size; i++) {
const Subtree *child = tree->children.contents[i];
for (uint32_t i = 0; i < subtree->children.size; i++) {
const Subtree *child = subtree->children.contents[i];
Length next_position = length_add(position, ts_subtree_total_size(child));
bool at_goal = next_position.bytes > goal_byte;
bool visible = child->visible;
if (!child->extra) {
visible |= alias_sequence && alias_sequence[structural_child_index];
}
uint32_t visible_child_count = child->children.size > 0 ? child->visible_child_count : 0;
if (at_goal) {
if (child->visible || child->visible_child_count > 0) {
if (visible || visible_child_count > 0) {
array_push(&self->stack, ((TreeCursorEntry) {
.subtree = child,
.child_index = i,
@ -90,19 +111,19 @@ int64_t ts_tree_cursor_goto_first_child_for_byte(TSTreeCursor *_self, uint32_t g
.position = position,
}));
if (child->visible) {
if (visible) {
return visible_child_index;
} else {
tree = child;
subtree = child;
did_descend = true;
break;
}
}
} else {
if (child->visible) {
if (visible) {
visible_child_index++;
} else {
visible_child_index += child->visible_child_count;
visible_child_index += visible_child_count;
}
}
@ -127,13 +148,22 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) {
uint32_t structural_child_index = child_entry->structural_child_index;
Length position = child_entry->position;
const Subtree *child = parent->children.contents[child_index];
const TSSymbol *alias_sequence = ts_language_alias_sequence(
self->tree->language,
parent->alias_sequence_id
);
while (++child_index < parent->children.size) {
if (!child->extra) structural_child_index++;
position = length_add(position, ts_subtree_total_size(child));
child = parent->children.contents[child_index];
if (child->visible || child->visible_child_count > 0) {
bool visible = child->visible;
if (!child->extra) {
visible |= alias_sequence && alias_sequence[structural_child_index];
}
if (visible || (child->children.size > 0 && child->visible_child_count > 0)) {
self->stack.contents[i + 1] = (TreeCursorEntry) {
.subtree = child,
.child_index = child_index,
@ -142,7 +172,7 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *_self) {
};
self->stack.size = i + 2;
if (child->visible) {
if (visible) {
return true;
} else {
ts_tree_cursor_goto_first_child(_self);
@ -180,7 +210,7 @@ TSNode ts_tree_cursor_current_node(const TSTreeCursor *_self) {
self->tree->language,
parent_entry->subtree->alias_sequence_id
);
if (alias_sequence) {
if (alias_sequence && !last_entry->subtree->extra) {
alias_symbol = alias_sequence[last_entry->structural_child_index];
}
}