diff options
Diffstat (limited to 'crates/libsyntax2/src')
-rw-r--r-- | crates/libsyntax2/src/algo/mod.rs | 48 | ||||
-rw-r--r-- | crates/libsyntax2/src/syntax_kinds/mod.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/src/yellow/syntax.rs | 11 |
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 | |||
78 | pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef { | 77 | pub 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 | ||
91 | fn 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 | |||
100 | pub fn ancestors<'a>(node: SyntaxNodeRef<'a>) -> impl Iterator<Item=SyntaxNodeRef<'a>> { | 90 | pub 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)] |
105 | struct Ancestors<'a>(Option<SyntaxNodeRef<'a>>); | 95 | pub enum Direction { |
96 | Forward, | ||
97 | Backward, | ||
98 | } | ||
106 | 99 | ||
107 | impl<'a> Iterator for Ancestors<'a> { | 100 | pub 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> { | 110 | fn 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 | ||
118 | fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { | 119 | fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { |
@@ -122,3 +123,12 @@ fn contains_offset_nonstrict(range: TextRange, offset: TextUnit) -> bool { | |||
122 | fn is_subrange(range: TextRange, subrange: TextRange) -> bool { | 123 | fn 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 | |||
127 | fn 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 | ||
19 | impl SyntaxKind { | 19 | impl 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 | } |