After review
This commit is contained in:
parent
8d5462cea4
commit
8c789bf7d5
4 changed files with 48 additions and 15 deletions
|
|
@ -480,14 +480,15 @@ extern "C" {
|
|||
pub fn ts_tree_cursor_goto_next_sibling(arg1: *mut TSTreeCursor) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Move the cursor to the previous sibling of its current node.\n\n This returns `true` if the cursor successfully moved, and returns `false` if\n there was no previous sibling node."]
|
||||
#[doc = " Move the cursor to the previous sibling of its current node.\n\n This returns `true` if the cursor successfully moved, and returns `false` if\n there was no previous sibling node.\n\n Note, that this function may be slower than\n `ts_tree_cursor_goto_next_sibling` due to how node positions are stored. In\n the worst case, this will need to iterate through all the children upto the\n previous sibling node to recalculate its position."]
|
||||
pub fn ts_tree_cursor_goto_previous_sibling(arg1: *mut TSTreeCursor) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Move the cursor to the first/last child of its current node.\n\n This returns `true` if the cursor successfully moved, and returns `false`\n if there were no children."]
|
||||
#[doc = " Move the cursor to the first child of its current node.\n\n This returns `true` if the cursor successfully moved, and returns `false`\n if there were no children."]
|
||||
pub fn ts_tree_cursor_goto_first_child(arg1: *mut TSTreeCursor) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
#[doc = " Move the cursor to the last child of its current node.\n\n This returns `true` if the cursor successfully moved, and returns `false` if\n there were no children.\n\n Note that this function may be slower than `ts_tree_cursor_goto_first_child`\n because it needs to iterate through all the children to compute the child's\n position."]
|
||||
pub fn ts_tree_cursor_goto_last_child(arg1: *mut TSTreeCursor) -> bool;
|
||||
}
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -1380,8 +1380,12 @@ impl<'a> TreeCursor<'a> {
|
|||
|
||||
/// Move this cursor to the last child of its current node.
|
||||
///
|
||||
/// This returns `true` if the cursor successfully moved, and returns `false`
|
||||
/// if there were no children.
|
||||
/// This returns `true` if the cursor successfully moved, and returns
|
||||
/// `false` if there were no children.
|
||||
///
|
||||
/// Note that this function may be slower than
|
||||
/// [`goto_first_child`](TreeCursor::goto_first_child) because it needs to
|
||||
/// iterate through all the children to compute the child's position.
|
||||
#[doc(alias = "ts_tree_cursor_goto_last_child")]
|
||||
pub fn goto_last_child(&mut self) -> bool {
|
||||
return unsafe { ffi::ts_tree_cursor_goto_last_child(&mut self.0) };
|
||||
|
|
@ -1419,6 +1423,12 @@ impl<'a> TreeCursor<'a> {
|
|||
///
|
||||
/// This returns `true` if the cursor successfully moved, and returns
|
||||
/// `false` if there was no previous sibling node.
|
||||
///
|
||||
/// Note, that this function may be slower than
|
||||
/// [`goto_next_sibling`](TreeCursor::goto_next_sibling) due to how node
|
||||
/// positions are stored. In the worst case, this will need to iterate
|
||||
/// through all the children upto the previous sibling node to recalculate
|
||||
/// its position.
|
||||
#[doc(alias = "ts_tree_cursor_goto_previous_sibling")]
|
||||
pub fn goto_previous_sibling(&mut self) -> bool {
|
||||
return unsafe { ffi::ts_tree_cursor_goto_previous_sibling(&mut self.0) };
|
||||
|
|
|
|||
|
|
@ -720,16 +720,32 @@ bool ts_tree_cursor_goto_next_sibling(TSTreeCursor *);
|
|||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns `false` if
|
||||
* there was no previous sibling node.
|
||||
*
|
||||
* Note, that this function may be slower than
|
||||
* `ts_tree_cursor_goto_next_sibling` due to how node positions are stored. In
|
||||
* the worst case, this will need to iterate through all the children upto the
|
||||
* previous sibling node to recalculate its position.
|
||||
*/
|
||||
bool ts_tree_cursor_goto_previous_sibling(TSTreeCursor *);
|
||||
|
||||
/**
|
||||
* Move the cursor to the first/last child of its current node.
|
||||
* Move the cursor to the first child of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns `false`
|
||||
* if there were no children.
|
||||
*/
|
||||
bool ts_tree_cursor_goto_first_child(TSTreeCursor *);
|
||||
|
||||
/**
|
||||
* Move the cursor to the last child of its current node.
|
||||
*
|
||||
* This returns `true` if the cursor successfully moved, and returns `false` if
|
||||
* there were no children.
|
||||
*
|
||||
* Note that this function may be slower than `ts_tree_cursor_goto_first_child`
|
||||
* because it needs to iterate through all the children to compute the child's
|
||||
* position.
|
||||
*/
|
||||
bool ts_tree_cursor_goto_last_child(TSTreeCursor *);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -97,13 +97,19 @@ static inline bool ts_tree_cursor_child_iterator_next(
|
|||
return true;
|
||||
}
|
||||
|
||||
static inline Length length_sub_zero(Length a, Length b) {
|
||||
// length_sub doesn't account for 0 row subtraction, i.e. only columns
|
||||
// should be subtracted, but changing point_sub breaks other tests
|
||||
Length result = length_sub(a, b);
|
||||
if (b.extent.row == 0 && a.extent.row != 0) {
|
||||
result.extent.column -= b.extent.column;
|
||||
// Return a position that, when `b` is added to it, yields `a`. This
|
||||
// can only be computed if `b` has zero rows. Otherwise, this function
|
||||
// returns `LENGTH_UNDEFINED`, and the caller needs to recompute
|
||||
// the position some other way.
|
||||
static inline Length length_backtrack(Length a, Length b) {
|
||||
if (length_is_undefined(a) || b.extent.row != 0) {
|
||||
return LENGTH_UNDEFINED;
|
||||
}
|
||||
|
||||
Length result;
|
||||
result.bytes = a.bytes - b.bytes;
|
||||
result.extent.row = a.extent.row;
|
||||
result.extent.column = a.extent.column - b.extent.column;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -129,14 +135,14 @@ static inline bool ts_tree_cursor_child_iterator_previous(
|
|||
self->structural_child_index--;
|
||||
}
|
||||
|
||||
self->position = length_sub_zero(self->position, ts_subtree_padding(*child));
|
||||
self->position = length_backtrack(self->position, ts_subtree_padding(*child));
|
||||
self->child_index--;
|
||||
|
||||
// unsigned can underflow so compare it to child_count
|
||||
if (self->child_index < self->parent.ptr->child_count) {
|
||||
Subtree previous_child = ts_subtree_children(self->parent)[self->child_index];
|
||||
Length size = ts_subtree_size(previous_child);
|
||||
self->position = length_sub_zero(self->position, size);
|
||||
self->position = length_backtrack(self->position, size);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -362,8 +368,8 @@ TreeCursorStep ts_tree_cursor_goto_previous_sibling_internal(TSTreeCursor *_self
|
|||
if (step == TreeCursorStepNone)
|
||||
return step;
|
||||
|
||||
// if row has not changed, column is still valid
|
||||
if (array_back(&self->stack)->position.extent.row == position.extent.row)
|
||||
// if length is already valid, there's no need to recompute it
|
||||
if (!length_is_undefined(array_back(&self->stack)->position))
|
||||
return step;
|
||||
|
||||
// restore position from the parent node
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue