Skip to content

Commit dafe747

Browse files
committed
upstream basic tree algorithms to rowan
1 parent d1b2422 commit dafe747

File tree

4 files changed

+13
-110
lines changed

4 files changed

+13
-110
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/ra_syntax/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ unicode-xid = "0.1.0"
1212
itertools = "0.7.8"
1313
drop_bomb = "0.1.4"
1414
parking_lot = "0.6.0"
15-
rowan = "0.1.1"
15+
rowan = "0.1.2"
1616
text_unit = "0.1.5"
1717

1818
[dev-dependencies]

crates/ra_syntax/src/algo/mod.rs

Lines changed: 8 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,116 +1,19 @@
11
pub mod visit;
2-
// pub mod walk;
32

4-
use crate::{text_utils::contains_offset_nonstrict, SyntaxNodeRef, TextRange, TextUnit};
3+
use crate::{SyntaxNode, SyntaxNodeRef, TextRange, TextUnit};
54

6-
pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset {
7-
let range = node.range();
8-
assert!(
9-
contains_offset_nonstrict(range, offset),
10-
"Bad offset: range {:?} offset {:?}",
11-
range,
12-
offset
13-
);
14-
if range.is_empty() {
15-
return LeafAtOffset::None;
16-
}
17-
18-
if node.is_leaf() {
19-
return LeafAtOffset::Single(node);
20-
}
21-
22-
let mut children = node.children().filter(|child| {
23-
let child_range = child.range();
24-
!child_range.is_empty() && contains_offset_nonstrict(child_range, offset)
25-
});
26-
27-
let left = children.next().unwrap();
28-
let right = children.next();
29-
assert!(children.next().is_none());
30-
31-
if let Some(right) = right {
32-
match (
33-
find_leaf_at_offset(left, offset),
34-
find_leaf_at_offset(right, offset),
35-
) {
36-
(LeafAtOffset::Single(left), LeafAtOffset::Single(right)) => {
37-
LeafAtOffset::Between(left, right)
38-
}
39-
_ => unreachable!(),
40-
}
41-
} else {
42-
find_leaf_at_offset(left, offset)
43-
}
44-
}
45-
46-
#[derive(Clone, Debug)]
47-
pub enum LeafAtOffset<'a> {
48-
None,
49-
Single(SyntaxNodeRef<'a>),
50-
Between(SyntaxNodeRef<'a>, SyntaxNodeRef<'a>),
51-
}
5+
pub use rowan::LeafAtOffset;
526

53-
impl<'a> LeafAtOffset<'a> {
54-
pub fn right_biased(self) -> Option<SyntaxNodeRef<'a>> {
55-
match self {
56-
LeafAtOffset::None => None,
57-
LeafAtOffset::Single(node) => Some(node),
58-
LeafAtOffset::Between(_, right) => Some(right),
59-
}
60-
}
61-
62-
pub fn left_biased(self) -> Option<SyntaxNodeRef<'a>> {
63-
match self {
64-
LeafAtOffset::None => None,
65-
LeafAtOffset::Single(node) => Some(node),
66-
LeafAtOffset::Between(left, _) => Some(left),
67-
}
68-
}
69-
}
70-
71-
impl<'f> Iterator for LeafAtOffset<'f> {
72-
type Item = SyntaxNodeRef<'f>;
73-
74-
fn next(&mut self) -> Option<SyntaxNodeRef<'f>> {
75-
match *self {
76-
LeafAtOffset::None => None,
77-
LeafAtOffset::Single(node) => {
78-
*self = LeafAtOffset::None;
79-
Some(node)
80-
}
81-
LeafAtOffset::Between(left, right) => {
82-
*self = LeafAtOffset::Single(right);
83-
Some(left)
84-
}
85-
}
7+
pub fn find_leaf_at_offset(node: SyntaxNodeRef, offset: TextUnit) -> LeafAtOffset<SyntaxNodeRef> {
8+
match node.0.leaf_at_offset(offset) {
9+
LeafAtOffset::None => LeafAtOffset::None,
10+
LeafAtOffset::Single(n) => LeafAtOffset::Single(SyntaxNode(n)),
11+
LeafAtOffset::Between(l, r) => LeafAtOffset::Between(SyntaxNode(l), SyntaxNode(r)),
8612
}
8713
}
8814

8915
pub fn find_covering_node(root: SyntaxNodeRef, range: TextRange) -> SyntaxNodeRef {
90-
assert!(
91-
range.is_subrange(&root.range()),
92-
"node range: {:?}, target range: {:?}",
93-
root.range(),
94-
range,
95-
);
96-
let (left, right) = match (
97-
find_leaf_at_offset(root, range.start()).right_biased(),
98-
find_leaf_at_offset(root, range.end()).left_biased(),
99-
) {
100-
(Some(l), Some(r)) => (l, r),
101-
_ => return root,
102-
};
103-
104-
common_ancestor(left, right)
105-
}
106-
107-
fn common_ancestor<'a>(n1: SyntaxNodeRef<'a>, n2: SyntaxNodeRef<'a>) -> SyntaxNodeRef<'a> {
108-
for p in n1.ancestors() {
109-
if n2.ancestors().any(|a| a == p) {
110-
return p;
111-
}
112-
}
113-
panic!("Can't find common ancestor of {:?} and {:?}", n1, n2)
16+
SyntaxNode(root.0.covering_node(range))
11417
}
11518

11619
pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item = T> {

crates/ra_syntax/src/yellow/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub type RefRoot<'a> = ::rowan::RefRoot<'a, RaTypes>;
2727
pub type GreenNode = ::rowan::GreenNode<RaTypes>;
2828

2929
#[derive(Clone, Copy)]
30-
pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(::rowan::SyntaxNode<RaTypes, R>);
30+
pub struct SyntaxNode<R: TreeRoot<RaTypes> = OwnedRoot>(pub(crate) ::rowan::SyntaxNode<RaTypes, R>);
3131
pub type SyntaxNodeRef<'a> = SyntaxNode<RefRoot<'a>>;
3232

3333
impl<R1, R2> PartialEq<SyntaxNode<R1>> for SyntaxNode<R2>

0 commit comments

Comments
 (0)