Fix bug in ts_node_prev_sibling w/ empty nodes
This commit is contained in:
parent
e56d17a806
commit
068c9841a1
2 changed files with 40 additions and 2 deletions
|
|
@ -153,7 +153,18 @@ static inline TSNode ts_node__child(TSNode self, uint32_t child_index, bool incl
|
|||
return ts_node__null();
|
||||
}
|
||||
|
||||
static bool ts_subtree_has_trailing_empty_descendant(const Subtree *self, const Subtree *other) {
|
||||
for (unsigned i = self->children.size - 1; i + 1 > 0; i--) {
|
||||
const Subtree *child = self->children.contents[i];
|
||||
if (child->size.bytes > 0 || child->padding.bytes > 0) break;
|
||||
if (child == other || ts_subtree_has_trailing_empty_descendant(child, other)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline TSNode ts_node__prev_sibling(TSNode self, bool include_anonymous) {
|
||||
const Subtree *self_subtree = ts_node__subtree(self);
|
||||
bool self_is_empty = self_subtree->size.bytes == 0 && self_subtree->padding.bytes == 0;
|
||||
uint32_t target_end_byte = ts_node_end_byte(self);
|
||||
|
||||
TSNode node = ts_node_parent(self);
|
||||
|
|
@ -168,8 +179,13 @@ static inline TSNode ts_node__prev_sibling(TSNode self, bool include_anonymous)
|
|||
TSNode child;
|
||||
ChildIterator iterator = ts_node_iterate_children(&node);
|
||||
while (ts_node_child_iterator_next(&iterator, &child)) {
|
||||
if (iterator.position.bytes >= target_end_byte) {
|
||||
found_child_containing_target = ts_node__subtree(child) != ts_node__subtree(self);
|
||||
if (child.id == self.id) break;
|
||||
|
||||
if (iterator.position.bytes > target_end_byte || (
|
||||
iterator.position.bytes == target_end_byte && (
|
||||
!self_is_empty ||
|
||||
ts_subtree_has_trailing_empty_descendant(ts_node__subtree(child), self_subtree)))) {
|
||||
found_child_containing_target = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -399,6 +399,28 @@ describe("Node", [&]() {
|
|||
AssertThat(ts_node_next_named_sibling(root_node), Equals(NULL_NODE));
|
||||
AssertThat(ts_node_prev_named_sibling(root_node), Equals(NULL_NODE));
|
||||
});
|
||||
|
||||
it("works for missing nodes", [&]() {
|
||||
ts_tree_delete(tree);
|
||||
|
||||
string input_string = "<div";
|
||||
ts_parser_set_language(parser, load_real_language("html"));
|
||||
tree = ts_parser_parse_string(parser, nullptr, input_string.c_str(), input_string.size());
|
||||
root_node = ts_tree_root_node(tree);
|
||||
|
||||
char *node_string = ts_node_string(root_node);
|
||||
AssertThat(node_string, Equals("(fragment (element (self_closing_tag (tag_name) (MISSING))))"));
|
||||
ts_free(node_string);
|
||||
|
||||
TSNode tag_node = ts_node_child(ts_node_child(root_node, 0), 0);
|
||||
TSNode missing_node = ts_node_child(tag_node, 2);
|
||||
AssertThat(ts_node_type(missing_node), Equals("/>"));
|
||||
AssertThat(ts_node_is_missing(missing_node), IsTrue());
|
||||
|
||||
TSNode tag_name_node = ts_node_prev_sibling(missing_node);
|
||||
AssertThat(ts_node_type(tag_name_node), Equals("tag_name"));
|
||||
AssertThat(ts_node_next_sibling(tag_name_node), Equals(missing_node));
|
||||
});
|
||||
});
|
||||
|
||||
describe("next_named_sibling(), prev_named_sibling()", [&]() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue