Change the TSInputEdit struct to work with old/new start and end positions
This commit is contained in:
parent
95be6e3bee
commit
074c051094
4 changed files with 81 additions and 69 deletions
|
|
@ -57,11 +57,11 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint32_t start_byte;
|
||||
uint32_t bytes_removed;
|
||||
uint32_t bytes_added;
|
||||
uint32_t old_end_byte;
|
||||
uint32_t new_end_byte;
|
||||
TSPoint start_point;
|
||||
TSPoint extent_removed;
|
||||
TSPoint extent_added;
|
||||
TSPoint old_end_point;
|
||||
TSPoint new_end_point;
|
||||
} TSInputEdit;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
typedef struct {
|
||||
Length start;
|
||||
Length added;
|
||||
Length removed;
|
||||
Length old_end;
|
||||
Length new_end;
|
||||
} Edit;
|
||||
|
||||
TSStateId TS_TREE_STATE_NONE = USHRT_MAX;
|
||||
|
|
@ -490,22 +490,23 @@ const Subtree *ts_subtree_invalidate_lookahead(const Subtree *self, uint32_t edi
|
|||
}
|
||||
|
||||
const Subtree *ts_subtree__edit(const Subtree *self, Edit edit, SubtreePool *pool) {
|
||||
Length new_end = length_add(edit.start, edit.added);
|
||||
Length old_end = length_add(edit.start, edit.removed);
|
||||
|
||||
Subtree *result = ts_subtree_make_mut(pool, self);
|
||||
result->has_changes = true;
|
||||
|
||||
if (old_end.bytes <= result->padding.bytes) {
|
||||
result->padding = length_add(new_end, length_sub(result->padding, old_end));
|
||||
bool pure_insertion = edit.old_end.bytes == edit.start.bytes;
|
||||
|
||||
if (edit.old_end.bytes <= result->padding.bytes) {
|
||||
result->padding = length_add(edit.new_end, length_sub(result->padding, edit.old_end));
|
||||
} else if (edit.start.bytes < result->padding.bytes) {
|
||||
result->size = length_sub(result->size, length_sub(old_end, result->padding));
|
||||
result->padding = new_end;
|
||||
} else if (edit.start.bytes == result->padding.bytes && edit.removed.bytes == 0) {
|
||||
result->padding = length_add(result->padding, edit.added);
|
||||
result->size = length_sub(result->size, length_sub(edit.old_end, result->padding));
|
||||
result->padding = edit.new_end;
|
||||
} else if (edit.start.bytes == result->padding.bytes && pure_insertion) {
|
||||
result->padding = edit.new_end;
|
||||
} else {
|
||||
Length new_total_size = length_add(new_end, length_sub(ts_subtree_total_size(result), old_end));
|
||||
result->size = length_sub(new_total_size, result->padding);
|
||||
result->size = length_add(
|
||||
length_sub(edit.new_end, result->padding),
|
||||
length_sub(result->size, length_sub(edit.old_end, result->padding))
|
||||
);
|
||||
}
|
||||
|
||||
Length child_left, child_right = length_zero();
|
||||
|
|
@ -515,27 +516,23 @@ const Subtree *ts_subtree__edit(const Subtree *self, Edit edit, SubtreePool *poo
|
|||
child_left = child_right;
|
||||
child_right = length_add(child_left, child_size);
|
||||
|
||||
if (child_left.bytes > old_end.bytes ||
|
||||
(child_left.bytes == old_end.bytes && child_size.bytes > 0 && i > 0)) break;
|
||||
if (child_left.bytes > edit.old_end.bytes ||
|
||||
(child_left.bytes == edit.old_end.bytes && child_size.bytes > 0 && i > 0)) break;
|
||||
|
||||
if (child_right.bytes > edit.start.bytes ||
|
||||
(child_right.bytes == edit.start.bytes && edit.removed.bytes == 0)) {
|
||||
(child_right.bytes == edit.start.bytes && pure_insertion)) {
|
||||
Edit child_edit = {
|
||||
.start = length_sub(edit.start, child_left),
|
||||
.added = edit.added,
|
||||
.removed = edit.removed,
|
||||
.old_end = length_sub(edit.old_end, child_left),
|
||||
.new_end = length_sub(edit.new_end, child_left),
|
||||
};
|
||||
|
||||
if (edit.start.bytes < child_left.bytes) {
|
||||
child_edit.start = length_zero();
|
||||
}
|
||||
if (edit.start.bytes < child_left.bytes) child_edit.start = length_zero();
|
||||
if (edit.old_end.bytes < child_left.bytes) child_edit.old_end = length_zero();
|
||||
if (edit.new_end.bytes < child_left.bytes) child_edit.new_end = length_zero();
|
||||
if (edit.old_end.bytes > child_right.bytes) child_edit.old_end = child_size;
|
||||
|
||||
if (old_end.bytes > child_right.bytes) {
|
||||
child_edit.removed = length_sub(child_size, child_edit.start);
|
||||
}
|
||||
|
||||
edit.added = length_zero();
|
||||
edit.removed = length_sub(edit.removed, child_edit.removed);
|
||||
edit.new_end = edit.start;
|
||||
|
||||
*child = ts_subtree__edit(*child, child_edit, pool);
|
||||
} else if (child_left.bytes <= edit.start.bytes) {
|
||||
|
|
@ -549,8 +546,8 @@ const Subtree *ts_subtree__edit(const Subtree *self, Edit edit, SubtreePool *poo
|
|||
const Subtree *ts_subtree_edit(const Subtree *self, const TSInputEdit *edit, SubtreePool *pool) {
|
||||
return ts_subtree__edit(self, (Edit) {
|
||||
.start = {edit->start_byte, edit->start_point},
|
||||
.added = {edit->bytes_added, edit->extent_added},
|
||||
.removed = {edit->bytes_removed, edit->extent_removed},
|
||||
.old_end = {edit->old_end_byte, edit->old_end_point},
|
||||
.new_end = {edit->new_end_byte, edit->new_end_point},
|
||||
}, pool);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "helpers/spy_input.h"
|
||||
#include "helpers/encoding_helpers.h"
|
||||
#include "runtime/point.h"
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
|
@ -20,6 +21,14 @@ SpyInput::~SpyInput() {
|
|||
delete[] buffer;
|
||||
}
|
||||
|
||||
static TSPoint operator+(TSPoint a, TSPoint b) {
|
||||
if (b.row > 0) {
|
||||
return TSPoint {a.row + b.row, b.column};
|
||||
} else {
|
||||
return TSPoint {a.row, a.column + b.column};
|
||||
}
|
||||
}
|
||||
|
||||
static void add_byte_range(vector<pair<uint32_t, uint32_t>> *ranges,
|
||||
uint32_t start, uint32_t count) {
|
||||
uint32_t end = start + count;
|
||||
|
|
@ -112,11 +121,11 @@ TSInputEdit SpyInput::replace(size_t start_byte, size_t bytes_removed, string te
|
|||
undo_stack.push_back(SpyInputEdit{start_byte, bytes_added, swap.first});
|
||||
TSInputEdit result = {};
|
||||
result.start_byte = start_byte;
|
||||
result.bytes_added = bytes_added;
|
||||
result.bytes_removed = bytes_removed;
|
||||
result.old_end_byte = start_byte + bytes_removed;
|
||||
result.new_end_byte = start_byte + bytes_added;
|
||||
result.start_point = swap.second;
|
||||
result.extent_removed = get_extent(swap.first);
|
||||
result.extent_added = get_extent(text);
|
||||
result.old_end_point = result.start_point + get_extent(swap.first);
|
||||
result.new_end_point = result.start_point + get_extent(text);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -126,11 +135,11 @@ TSInputEdit SpyInput::undo() {
|
|||
auto swap = swap_substr(entry.start_byte, entry.bytes_removed, entry.text_inserted);
|
||||
TSInputEdit result;
|
||||
result.start_byte = entry.start_byte;
|
||||
result.bytes_removed = entry.bytes_removed;
|
||||
result.bytes_added = entry.text_inserted.size();
|
||||
result.old_end_byte = entry.start_byte + entry.bytes_removed;
|
||||
result.new_end_byte = entry.start_byte + entry.text_inserted.size();
|
||||
result.start_point = swap.second;
|
||||
result.extent_removed = get_extent(swap.first);
|
||||
result.extent_added = get_extent(entry.text_inserted);
|
||||
result.old_end_point = result.start_point + get_extent(swap.first);
|
||||
result.new_end_point = result.start_point + get_extent(entry.text_inserted);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,11 +202,11 @@ describe("Subtree", []() {
|
|||
it("does not mutate the argument", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 1;
|
||||
edit.bytes_removed = 0;
|
||||
edit.bytes_added = 1;
|
||||
edit.old_end_byte = 1;
|
||||
edit.new_end_byte = 2;
|
||||
edit.start_point = {0, 1};
|
||||
edit.extent_removed = {0, 0};
|
||||
edit.extent_added = {0, 1};
|
||||
edit.old_end_point = {0, 1};
|
||||
edit.new_end_point = {0, 2};
|
||||
|
||||
ts_subtree_retain(tree);
|
||||
const Subtree *new_tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
|
|
@ -232,11 +232,12 @@ describe("Subtree", []() {
|
|||
it("resizes the padding of the tree and its leftmost descendants", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 1;
|
||||
edit.bytes_removed = 0;
|
||||
edit.bytes_added = 1;
|
||||
edit.old_end_byte = 1;
|
||||
edit.new_end_byte = 2;
|
||||
edit.start_point = {0, 1};
|
||||
edit.extent_removed = {0, 0};
|
||||
edit.extent_added = {0, 1};
|
||||
edit.old_end_point = {0, 1};
|
||||
edit.new_end_point = {0, 2};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
@ -258,11 +259,12 @@ describe("Subtree", []() {
|
|||
it("shrinks the content to compensate for the expanded padding", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 1;
|
||||
edit.bytes_removed = 3;
|
||||
edit.bytes_added = 4;
|
||||
edit.old_end_byte = 4;
|
||||
edit.new_end_byte = 5;
|
||||
edit.start_point = {0, 1};
|
||||
edit.extent_removed = {0, 3};
|
||||
edit.extent_added = {0, 4};
|
||||
edit.old_end_point = {0, 4};
|
||||
edit.new_end_point = {0, 5};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
@ -280,11 +282,12 @@ describe("Subtree", []() {
|
|||
it("expands the tree's padding", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 2;
|
||||
edit.bytes_removed = 0;
|
||||
edit.bytes_added = 2;
|
||||
edit.old_end_byte = 2;
|
||||
edit.new_end_byte = 4;
|
||||
edit.start_point = {0, 2};
|
||||
edit.extent_removed = {0, 0};
|
||||
edit.extent_added = {0, 2};
|
||||
edit.old_end_point = {0, 2};
|
||||
edit.new_end_point = {0, 4};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
@ -304,11 +307,12 @@ describe("Subtree", []() {
|
|||
it("resizes the content and not the padding", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 2;
|
||||
edit.bytes_removed = 2;
|
||||
edit.bytes_added = 5;
|
||||
edit.old_end_byte = 4;
|
||||
edit.new_end_byte = 7;
|
||||
edit.start_point = {0, 2};
|
||||
edit.extent_removed = {0, 2};
|
||||
edit.extent_added = {0, 5};
|
||||
edit.old_end_point = {0, 4};
|
||||
edit.new_end_point = {0, 7};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
@ -328,11 +332,12 @@ describe("Subtree", []() {
|
|||
it("shrinks subsequent child nodes", [&]() {
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 1;
|
||||
edit.bytes_removed = 10;
|
||||
edit.bytes_added = 3;
|
||||
edit.old_end_byte = 11;
|
||||
edit.new_end_byte = 4;
|
||||
edit.start_point = {0, 1};
|
||||
edit.extent_removed = {0, 10};
|
||||
edit.extent_added = {0, 3};
|
||||
edit.old_end_point = {0, 11};
|
||||
edit.new_end_point = {0, 4};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
@ -361,11 +366,12 @@ describe("Subtree", []() {
|
|||
|
||||
TSInputEdit edit;
|
||||
edit.start_byte = 6;
|
||||
edit.bytes_removed = 1;
|
||||
edit.bytes_added = 1;
|
||||
edit.old_end_byte = 7;
|
||||
edit.new_end_byte = 7;
|
||||
edit.start_point = {0, 6};
|
||||
edit.extent_removed = {0, 1};
|
||||
edit.extent_added = {0, 1};
|
||||
edit.old_end_point = {0, 7};
|
||||
edit.new_end_point = {0, 7};
|
||||
|
||||
tree = ts_subtree_edit(tree, &edit, &pool);
|
||||
assert_consistent(tree);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue