From 66be735aa98c32fb062d1c756fa9303ff2d13002 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 12 Aug 2018 18:50:16 +0300 Subject: flip comma --- crates/libsyntax2/src/algo/mod.rs | 48 +++++++++++++++++++------------ crates/libsyntax2/src/syntax_kinds/mod.rs | 2 +- crates/libsyntax2/src/yellow/syntax.rs | 11 +++++++ 3 files changed, 41 insertions(+), 20 deletions(-) (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/algo/mod.rs b/crates/libsyntax2/src/algo/mod.rs index 263b58d97..6efdff12f 100644 --- a/crates/libsyntax2/src/algo/mod.rs +++ b/crates/libsyntax2/src/algo/mod.rs @@ -74,7 +74,6 @@ impl<'f> Iterator for LeafAtOffset<'f> { } } - pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { assert!(is_subrange(root.range(), range)); let (left, right) = match ( @@ -88,31 +87,33 @@ pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRe common_ancestor(left, right) } -fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { - for p in ancestors(n1) { - if ancestors(n2).any(|a| a == p) { - return p; - } - } - panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) -} - pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator> { - Ancestors(Some(node)) + generate(Some(node), |&node| node.parent()) } #[derive(Debug)] -struct Ancestors<'a>(Option>); +pub enum Direction { + Forward, + Backward, +} -impl<'a> Iterator for Ancestors<'a> { - type Item = SyntaxNodeRef<'a>; +pub fn siblings<'a>( + node: SyntaxNodeRef<'a>, + direction: Direction +) -> impl Iterator> { + generate(Some(node), move |&node| match direction { + Direction::Forward => node.next_sibling(), + Direction::Backward => node.prev_sibling(), + }) +} - fn next(&mut self) -> Option { - self.0.take().map(|n| { - self.0 = n.parent(); - n - }) +fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> { + for p in ancestors(n1) { + if ancestors(n2).any(|a| a == p) { + return p; + } } + panic!("Can't find common ancestor of {:?} and {:?}", n1, n2) } fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { @@ -122,3 +123,12 @@ fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { fn is_subrange(range: TextRange, subrange: TextRange) -> bool { range.start() <= subrange.start() && subrange.end() <= range.end() } + +fn generate(seed: Option, step: impl Fn(&T) -> Option) -> impl Iterator { + ::itertools::unfold(seed, move |slot| { + slot.take().map(|curr| { + *slot = step(&curr); + curr + }) + }) +} diff --git a/crates/libsyntax2/src/syntax_kinds/mod.rs b/crates/libsyntax2/src/syntax_kinds/mod.rs index ed4fa5d4d..332cd13ac 100644 --- a/crates/libsyntax2/src/syntax_kinds/mod.rs +++ b/crates/libsyntax2/src/syntax_kinds/mod.rs @@ -17,7 +17,7 @@ pub(crate) struct SyntaxInfo { } impl SyntaxKind { - pub(crate) fn is_trivia(self) -> bool { + pub fn is_trivia(self) -> bool { match self { WHITESPACE | COMMENT | DOC_COMMENT => true, _ => false, diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs index a22275ed9..00f76e51c 100644 --- a/crates/libsyntax2/src/yellow/syntax.rs +++ b/crates/libsyntax2/src/yellow/syntax.rs @@ -101,6 +101,17 @@ impl SyntaxNode { }) } + pub fn prev_sibling(&self) -> Option> { + let red = self.red(); + let parent = self.parent()?; + let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?; + let sibling_red = parent.red().get_child(prev_sibling_idx)?; + Some(SyntaxNode { + root: self.root.clone(), + red: sibling_red, + }) + } + pub fn is_leaf(&self) -> bool { self.first_child().is_none() } -- cgit v1.2.3