Update trees' offsets when editing them
This commit is contained in:
parent
131bbee160
commit
591fcc980c
3 changed files with 39 additions and 31 deletions
|
|
@ -29,8 +29,8 @@ static void expect_a_consistent_tree(TSNode node, TSDocument *document) {
|
|||
AssertThat(start_char, !IsGreaterThan(end_char));
|
||||
AssertThat(start_point, !IsGreaterThan(end_point));
|
||||
|
||||
size_t last_child_end_char = 0;
|
||||
TSPoint last_child_end_point = {0, 0};
|
||||
size_t last_child_end_char = start_char;
|
||||
TSPoint last_child_end_point = start_point;
|
||||
|
||||
for (size_t i = 0; i < child_count; i++) {
|
||||
TSNode child = ts_node_child(node, i);
|
||||
|
|
@ -39,17 +39,10 @@ static void expect_a_consistent_tree(TSNode node, TSDocument *document) {
|
|||
TSPoint child_start_point = ts_node_start_point(child);
|
||||
TSPoint child_end_point = ts_node_end_point(child);
|
||||
|
||||
if (i > 0) {
|
||||
AssertThat(child_start_char, !IsLessThan(last_child_end_char));
|
||||
AssertThat(child_start_point, !IsLessThan(last_child_end_point));
|
||||
last_child_end_char = child_end_char;
|
||||
last_child_end_point = child_end_point;
|
||||
}
|
||||
|
||||
AssertThat(child_start_char, !IsLessThan(start_char));
|
||||
AssertThat(child_end_char, !IsGreaterThan(end_char));
|
||||
AssertThat(child_start_point, !IsLessThan(start_point));
|
||||
AssertThat(child_end_point, !IsGreaterThan(end_point));
|
||||
AssertThat(child_start_char, !IsLessThan(last_child_end_char));
|
||||
AssertThat(child_start_point, !IsLessThan(last_child_end_point));
|
||||
last_child_end_char = child_end_char;
|
||||
last_child_end_point = child_end_point;
|
||||
|
||||
expect_a_consistent_tree(child, document);
|
||||
|
||||
|
|
@ -57,8 +50,14 @@ static void expect_a_consistent_tree(TSNode node, TSDocument *document) {
|
|||
some_child_has_changes = true;
|
||||
}
|
||||
|
||||
if (child_count > 0)
|
||||
if (child_count > 0) {
|
||||
AssertThat(end_char, !IsLessThan(last_child_end_char));
|
||||
|
||||
if (!has_changes)
|
||||
AssertThat(end_point, !IsLessThan(last_child_end_point));
|
||||
|
||||
AssertThat(has_changes, Equals(some_child_has_changes));
|
||||
}
|
||||
}
|
||||
|
||||
START_TEST
|
||||
|
|
|
|||
|
|
@ -3,6 +3,22 @@
|
|||
#include "runtime/tree.h"
|
||||
#include "runtime/length.h"
|
||||
|
||||
void assert_consistent(const TSTree *tree) {
|
||||
if (tree->child_count == 0)
|
||||
return;
|
||||
AssertThat(tree->children[0]->padding, Equals<TSLength>(tree->padding));
|
||||
|
||||
TSLength total_children_size = ts_length_zero();
|
||||
for (size_t i = 0; i < tree->child_count; i++) {
|
||||
TSTree *child = tree->children[i];
|
||||
AssertThat(child->context.offset, Equals(total_children_size));
|
||||
assert_consistent(child);
|
||||
total_children_size = ts_length_add(total_children_size, ts_tree_total_size(child));
|
||||
}
|
||||
|
||||
AssertThat(total_children_size, Equals<TSLength>(ts_tree_total_size(tree)));
|
||||
};
|
||||
|
||||
START_TEST
|
||||
|
||||
enum {
|
||||
|
|
@ -163,14 +179,6 @@ describe("Tree", []() {
|
|||
ts_tree_release(tree);
|
||||
});
|
||||
|
||||
auto assert_consistent = [&](const TSTree *tree) {
|
||||
AssertThat(tree->children[0]->padding, Equals<TSLength>(tree->padding));
|
||||
|
||||
TSLength total_children_size = ts_length_zero();
|
||||
for (size_t i = 0; i < tree->child_count; i++)
|
||||
total_children_size = ts_length_add(total_children_size, ts_tree_total_size(tree->children[i]));
|
||||
AssertThat(total_children_size, Equals<TSLength>(ts_tree_total_size(tree)));
|
||||
};
|
||||
|
||||
describe("edits within a tree's padding", [&]() {
|
||||
it("resizes the padding of the tree and its leftmost descendants", [&]() {
|
||||
|
|
|
|||
|
|
@ -335,37 +335,38 @@ void ts_tree_edit(TSTree *self, TSInputEdit edit) {
|
|||
|
||||
bool found_first_child = false;
|
||||
long remainder_to_delete = edit.chars_removed - edit.chars_inserted;
|
||||
size_t child_left = 0, child_right = 0;
|
||||
TSLength child_left, child_right = ts_length_zero();
|
||||
for (size_t i = 0; i < self->child_count; i++) {
|
||||
TSTree *child = self->children[i];
|
||||
size_t child_size = ts_tree_total_chars(child);
|
||||
child_left = child_right;
|
||||
child_right += child_size;
|
||||
|
||||
if (!found_first_child) {
|
||||
if (child_right >= start) {
|
||||
child_right = ts_length_add(child_left, ts_tree_total_size(child));
|
||||
if (child_right.chars >= start) {
|
||||
found_first_child = true;
|
||||
size_t chars_removed = min(edit.chars_removed, child_right - start);
|
||||
size_t chars_removed = min(edit.chars_removed, child_right.chars - start);
|
||||
remainder_to_delete -= (chars_removed - edit.chars_inserted);
|
||||
ts_tree_edit(child, (TSInputEdit){
|
||||
.position = start - child_left,
|
||||
.position = start - child_left.chars,
|
||||
.chars_inserted = edit.chars_inserted,
|
||||
.chars_removed = chars_removed,
|
||||
});
|
||||
child_right = ts_length_add(child_left, ts_tree_total_size(child));
|
||||
}
|
||||
} else {
|
||||
if (remainder_to_delete > 0) {
|
||||
size_t chars_removed = min(remainder_to_delete, child_size);
|
||||
size_t chars_removed = min(remainder_to_delete, ts_tree_total_chars(child));
|
||||
remainder_to_delete -= chars_removed;
|
||||
ts_tree_edit(
|
||||
child,
|
||||
(TSInputEdit){
|
||||
.position = 0, .chars_inserted = 0, .chars_removed = chars_removed,
|
||||
});
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
child_right = ts_length_add(child_right, ts_tree_total_size(child));
|
||||
}
|
||||
|
||||
child->context.offset = child_left;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue