From dafe747dcc069084fc8bc771c5dcf72e7cb9ec23 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 6 Nov 2018 20:56:32 +0300 Subject: upstream basic tree algorithms to rowan --- crates/ra_syntax/src/algo/mod.rs | 113 +++------------------------------------ 1 file changed, 8 insertions(+), 105 deletions(-) (limited to 'crates/ra_syntax/src/algo/mod.rs') diff --git a/crates/ra_syntax/src/algo/mod.rs b/crates/ra_syntax/src/algo/mod.rs index faf5a6211..4b3548ea9 100644 --- a/crates/ra_syntax/src/algo/mod.rs +++ b/crates/ra_syntax/src/algo/mod.rs @@ -1,116 +1,19 @@ pub mod visit; -// pub mod walk; -use crate::{text_utils::contains_offset_nonstrict, SyntaxNodeRef, TextRange, TextUnit}; +use crate::{SyntaxNode, SyntaxNodeRef, TextRange, TextUnit}; -pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { - let range = node.range(); - assert!( - contains_offset_nonstrict(range, offset), - "Bad offset: range {:?} offset {:?}", - range, - offset - ); - if range.is_empty() { - return LeafAtOffset::None; - } - - if node.is_leaf() { - return LeafAtOffset::Single(node); - } - - let mut children = node.children().filter(|child| { - let child_range = child.range(); - !child_range.is_empty() && contains_offset_nonstrict(child_range, offset) - }); - - let left = children.next().unwrap(); - let right = children.next(); - assert!(children.next().is_none()); - - if let Some(right) = right { - match ( - find_leaf_at_offset(left, offset), - find_leaf_at_offset(right, offset), - ) { - (LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => { - LeafAtOffset::Between(left, right) - } - _ => unreachable!(), - } - } else { - find_leaf_at_offset(left, offset) - } -} - -#[derive(Clone, Debug)] -pub enum LeafAtOffset<'a> { - None, - Single(SyntaxNodeRef<'a>), - Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>), -} +pub use rowan::LeafAtOffset; -impl<'a> LeafAtOffset<'a> { - pub fn right_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(_, right) => Some(right), - } - } - - pub fn left_biased(self) -> Option> { - match self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => Some(node), - LeafAtOffset::Between(left, _) => Some(left), - } - } -} - -impl<'f> Iterator for LeafAtOffset<'f> { - type Item = SyntaxNodeRef<'f>; - - fn next(&mut self) -> Option> { - match *self { - LeafAtOffset::None => None, - LeafAtOffset::Single(node) => { - *self = LeafAtOffset::None; - Some(node) - } - LeafAtOffset::Between(left, right) => { - *self = LeafAtOffset::Single(right); - Some(left) - } - } +pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset { + match node.0.leaf_at_offset(offset) { + LeafAtOffset::None => LeafAtOffset::None, + LeafAtOffset::Single(n) => LeafAtOffset::Single(SyntaxNode(n)), + LeafAtOffset::Between(l, r) => LeafAtOffset::Between(SyntaxNode(l), SyntaxNode(r)), } } pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { - assert!( - range.is_subrange(&root.range()), - "node range: {:?}, target range: {:?}", - root.range(), - range, - ); - let (left, right) = match ( - find_leaf_at_offset(root, range.start()).right_biased(), - find_leaf_at_offset(root, range.end()).left_biased(), - ) { - (Some(l), Some(r)) => (l, r), - _ => return root, - }; - - common_ancestor(left, right) -} - -fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { - for p in n1.ancestors() { - if n2.ancestors().any(|a| a == p) { - return p; - } - } - panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) + SyntaxNode(root.0.covering_node(range)) } pub fn generate(seed: Option, step: impl Fn(&T) -> Option) -> impl Iterator { -- cgit v1.2.3