|
|
|
@ -90,6 +90,19 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_parent_with<P>(&mut self, predicate: P) -> bool
|
|
|
|
|
where
|
|
|
|
|
P: Fn(&Node) -> bool,
|
|
|
|
|
{
|
|
|
|
|
while self.goto_parent() {
|
|
|
|
|
if predicate(&self.node()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Finds the injection layer that has exactly the same range as the given `range`.
|
|
|
|
|
fn layer_id_of_byte_range(&self, search_range: Range<usize>) -> Option<LayerId> {
|
|
|
|
|
let start_idx = self
|
|
|
|
@ -102,7 +115,7 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
.find_map(|range| (range.start == search_range.start).then_some(range.layer_id))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_first_child(&mut self) -> bool {
|
|
|
|
|
fn goto_first_child_impl(&mut self, named: bool) -> bool {
|
|
|
|
|
// Check if the current node's range is an exact injection layer range.
|
|
|
|
|
if let Some(layer_id) = self
|
|
|
|
|
.layer_id_of_byte_range(self.node().byte_range())
|
|
|
|
@ -111,8 +124,16 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
// Switch to the child layer.
|
|
|
|
|
self.current = layer_id;
|
|
|
|
|
self.cursor = self.layers[self.current].tree().root_node();
|
|
|
|
|
true
|
|
|
|
|
} else if let Some(child) = self.cursor.child(0) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let child = if named {
|
|
|
|
|
self.cursor.named_child(0)
|
|
|
|
|
} else {
|
|
|
|
|
self.cursor.child(0)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if let Some(child) = child {
|
|
|
|
|
// Otherwise descend in the current tree.
|
|
|
|
|
self.cursor = child;
|
|
|
|
|
true
|
|
|
|
@ -121,8 +142,22 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_next_sibling(&mut self) -> bool {
|
|
|
|
|
if let Some(sibling) = self.cursor.next_sibling() {
|
|
|
|
|
pub fn goto_first_child(&mut self) -> bool {
|
|
|
|
|
self.goto_first_child_impl(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_first_named_child(&mut self) -> bool {
|
|
|
|
|
self.goto_first_child_impl(true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn goto_next_sibling_impl(&mut self, named: bool) -> bool {
|
|
|
|
|
let sibling = if named {
|
|
|
|
|
self.cursor.next_named_sibling()
|
|
|
|
|
} else {
|
|
|
|
|
self.cursor.next_sibling()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if let Some(sibling) = sibling {
|
|
|
|
|
self.cursor = sibling;
|
|
|
|
|
true
|
|
|
|
|
} else {
|
|
|
|
@ -130,8 +165,22 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_prev_sibling(&mut self) -> bool {
|
|
|
|
|
if let Some(sibling) = self.cursor.prev_sibling() {
|
|
|
|
|
pub fn goto_next_sibling(&mut self) -> bool {
|
|
|
|
|
self.goto_next_sibling_impl(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_next_named_sibling(&mut self) -> bool {
|
|
|
|
|
self.goto_next_sibling_impl(true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn goto_prev_sibling_impl(&mut self, named: bool) -> bool {
|
|
|
|
|
let sibling = if named {
|
|
|
|
|
self.cursor.prev_named_sibling()
|
|
|
|
|
} else {
|
|
|
|
|
self.cursor.prev_sibling()
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if let Some(sibling) = sibling {
|
|
|
|
|
self.cursor = sibling;
|
|
|
|
|
true
|
|
|
|
|
} else {
|
|
|
|
@ -139,6 +188,14 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_prev_sibling(&mut self) -> bool {
|
|
|
|
|
self.goto_prev_sibling_impl(false)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn goto_prev_named_sibling(&mut self) -> bool {
|
|
|
|
|
self.goto_prev_sibling_impl(true)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Finds the injection layer that contains the given start-end range.
|
|
|
|
|
fn layer_id_containing_byte_range(&self, start: usize, end: usize) -> LayerId {
|
|
|
|
|
let start_idx = self
|
|
|
|
@ -157,4 +214,51 @@ impl<'a> TreeCursor<'a> {
|
|
|
|
|
let root = self.layers[self.current].tree().root_node();
|
|
|
|
|
self.cursor = root.descendant_for_byte_range(start, end).unwrap_or(root);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over the children of the node the TreeCursor is on
|
|
|
|
|
/// at the time this is called.
|
|
|
|
|
pub fn children(&'a mut self) -> ChildIter {
|
|
|
|
|
let parent = self.node();
|
|
|
|
|
|
|
|
|
|
ChildIter {
|
|
|
|
|
cursor: self,
|
|
|
|
|
parent,
|
|
|
|
|
named: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over the named children of the node the TreeCursor is on
|
|
|
|
|
/// at the time this is called.
|
|
|
|
|
pub fn named_children(&'a mut self) -> ChildIter {
|
|
|
|
|
let parent = self.node();
|
|
|
|
|
|
|
|
|
|
ChildIter {
|
|
|
|
|
cursor: self,
|
|
|
|
|
parent,
|
|
|
|
|
named: true,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub struct ChildIter<'n> {
|
|
|
|
|
cursor: &'n mut TreeCursor<'n>,
|
|
|
|
|
parent: Node<'n>,
|
|
|
|
|
named: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'n> Iterator for ChildIter<'n> {
|
|
|
|
|
type Item = Node<'n>;
|
|
|
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
|
// first iteration, just visit the first child
|
|
|
|
|
if self.cursor.node() == self.parent {
|
|
|
|
|
self.cursor
|
|
|
|
|
.goto_first_child_impl(self.named)
|
|
|
|
|
.then(|| self.cursor.node())
|
|
|
|
|
} else {
|
|
|
|
|
self.cursor
|
|
|
|
|
.goto_next_sibling_impl(self.named)
|
|
|
|
|
.then(|| self.cursor.node())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|