Fix bug where ts_stack_pop results were backwards for some stack configurations

This commit is contained in:
Max Brunsfeld 2015-10-28 12:10:45 -07:00
parent 36eae5d5e9
commit f5d861a019
3 changed files with 24 additions and 5 deletions

View file

@ -344,17 +344,30 @@ describe("Stack", [&]() {
describe("when there is one path that leads to two different heads", [&]() {
it("returns two entries with the same array of trees", [&]() {
/*
* A0__B1__C2__D3__G6__H7.
* \__E4__F5__/
*/
ts_stack_push(stack, 0, stateH, trees[7]);
/*
* A0__B1__C2__D3.
* \__E4__F5.
*/
StackPopResultList pop = ts_stack_pop(stack, 0, 1, false);
StackPopResultList pop = ts_stack_pop(stack, 0, 2, false);
AssertThat(ts_stack_head_count(stack), Equals(2));
AssertThat(pop.size, Equals(2));
AssertThat(pop.contents[0].index, Equals(0));
AssertThat(pop.contents[0].tree_count, Equals(2));
AssertThat(pop.contents[0].trees[0], Equals(trees[6]));
AssertThat(pop.contents[0].trees[1], Equals(trees[7]));
AssertThat(pop.contents[1].index, Equals(1));
AssertThat(pop.contents[0].trees, Equals(pop.contents[1].trees));
AssertThat(pop.contents[1].tree_count, Equals(2));
AssertThat(pop.contents[1].trees[0], Equals(trees[6]));
AssertThat(pop.contents[1].trees[1], Equals(trees[7]));
});
});

View file

@ -22,7 +22,8 @@ static const char *empty_chunk = "";
static void ts_lexer__get_chunk(TSLexer *self) {
TSInput input = self->input;
if (!self->chunk || self->current_position.bytes != self->chunk_start + self->chunk_size)
if (!self->chunk ||
self->current_position.bytes != self->chunk_start + self->chunk_size)
input.seek_fn(input.payload, self->current_position);
self->chunk_start = self->current_position.bytes;

View file

@ -105,6 +105,7 @@ static bool stack_node_release(StackNode *self) {
static StackNode *stack_node_new(StackNode *next, TSStateId state, TSTree *tree) {
StackNode *self = malloc(sizeof(StackNode));
assert(tree->ref_count > 0);
ts_tree_retain(tree);
stack_node_retain(next);
*self = (StackNode){
@ -126,10 +127,12 @@ static void ts_stack__add_node_successor(Stack *self, StackNode *node,
if (successor == new_successor)
return;
if (successor->entry.state == new_successor->entry.state) {
if (successor->entry.tree != new_successor->entry.tree)
if (successor->entry.tree != new_successor->entry.tree) {
successor->entry.tree = self->tree_selection_callback.callback(
self->tree_selection_callback.data, successor->entry.tree,
new_successor->entry.tree);
ts_tree_retain(successor->entry.tree);
}
for (int j = 0; j < new_successor->successor_count; j++)
ts_stack__add_node_successor(self, successor,
new_successor->successors[j]);
@ -181,6 +184,7 @@ static bool ts_stack__merge_head(Stack *self, int head_index, TSStateId state,
if (head->entry.tree != tree) {
head->entry.tree = self->tree_selection_callback.callback(
self->tree_selection_callback.data, head->entry.tree, tree);
ts_tree_retain(head->entry.tree);
}
ts_stack__add_node_successor(self, head, self->heads[head_index]);
ts_stack_remove_head(self, head_index);
@ -275,7 +279,8 @@ StackPopResultList ts_stack_pop(Stack *self, int head_index, int child_count,
}
for (int path = 0; path < path_count; path++) {
tree_vector_reverse(&trees_by_path[path]);
if (!is_shared_by_path[path])
tree_vector_reverse(&trees_by_path[path]);
int index = -1;
if (path == 0) {
stack_node_retain(nodes_by_path[path]);