aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src')
-rw-r--r--crates/libsyntax2/src/algo/mod.rs48
-rw-r--r--crates/libsyntax2/src/syntax_kinds/mod.rs2
-rw-r--r--crates/libsyntax2/src/yellow/syntax.rs11
3 files changed, 41 insertions, 20 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}
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 {
17} 17}
18 18
19impl SyntaxKind { 19impl SyntaxKind {
20 pub(crate) fn is_trivia(self) -> bool { 20 pub fn is_trivia(self) -> bool {
21 match self { 21 match self {
22 WHITESPACE | COMMENT | DOC_COMMENT => true, 22 WHITESPACE | COMMENT | DOC_COMMENT => true,
23 _ => false, 23 _ => 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<R: TreeRoot> SyntaxNode<R> {
101 }) 101 })
102 } 102 }
103 103
104 pub fn prev_sibling(&self) -> Option<SyntaxNode<R>> {
105 let red = self.red();
106 let parent = self.parent()?;
107 let prev_sibling_idx = red.index_in_parent()?.checked_sub(1)?;
108 let sibling_red = parent.red().get_child(prev_sibling_idx)?;
109 Some(SyntaxNode {
110 root: self.root.clone(),
111 red: sibling_red,
112 })
113 }
114
104 pub fn is_leaf(&self) -> bool { 115 pub fn is_leaf(&self) -> bool {
105 self.first_child().is_none() 116 self.first_child().is_none()
106 } 117 }