aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/algo/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/algo/mod.rs')
-rw-r--r--crates/libsyntax2/src/algo/mod.rs48
1 files changed, 29 insertions, 19 deletions
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> {
74 } 74 }
75} 75}
76 76
77
78pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { 77pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef {
79 assert!(is_subrange(root.range(), range)); 78 assert!(is_subrange(root.range(), range));
80 let (left, right) = match ( 79 let (left, right) = match (
@@ -88,31 +87,33 @@ pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRe
88 common_ancestor(left, right) 87 common_ancestor(left, right)
89} 88}
90 89
91fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
92 for p in ancestors(n1) {
93 if ancestors(n2).any(|a| a == p) {
94 return p;
95 }
96 }
97 panic!("Can't find common ancestor of {:?} and {:?}", n1, n2)
98}
99
100pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> { 90pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
101 Ancestors(Some(node)) 91 generate(Some(node), |&node| node.parent())
102} 92}
103 93
104#[derive(Debug)] 94#[derive(Debug)]
105struct Ancestors<'a>(Option<SyntaxNodeRef<'a>>); 95pub enum Direction {
96 Forward,
97 Backward,
98}
106 99
107impl<'a> Iterator for Ancestors<'a> { 100pub fn siblings<'a>(
108 type Item = SyntaxNodeRef<'a>; 101 node: SyntaxNodeRef<'a>,
102 direction: Direction
103) -> impl Iterator<Item=SyntaxNodeRef<'a>> {
104 generate(Some(node), move |&node| match direction {
105 Direction::Forward => node.next_sibling(),
106 Direction::Backward => node.prev_sibling(),
107 })
108}
109 109
110 fn next(&mut self) -> Option<Self::Item> { 110fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
111 self.0.take().map(|n| { 111 for p in ancestors(n1) {
112 self.0 = n.parent(); 112 if ancestors(n2).any(|a| a == p) {
113 n 113 return p;
114 }) 114 }
115 } 115 }
116 panic!("Can't find common ancestor of {:?} and {:?}", n1, n2)
116} 117}
117 118
118fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { 119fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool {
@@ -122,3 +123,12 @@ fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool {
122fn is_subrange(range: TextRange, subrange: TextRange) -> bool { 123fn is_subrange(range: TextRange, subrange: TextRange) -> bool {
123 range.start() <= subrange.start() && subrange.end() <= range.end() 124 range.start() <= subrange.start() && subrange.end() <= range.end()
124} 125}
126
127fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item=T> {
128 ::itertools::unfold(seed, move |slot| {
129 slot.take().map(|curr| {
130 *slot = step(&curr);
131 curr
132 })
133 })
134}