|
1 | 1 | pub mod visit;
|
2 |
| -// pub mod walk; |
3 | 2 |
|
4 |
| -use crate::{text_utils::contains_offset_nonstrict, SyntaxNodeRef, TextRange, TextUnit}; |
| 3 | +use crate::{SyntaxNode, SyntaxNodeRef, TextRange, TextUnit}; |
5 | 4 |
|
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; |
52 | 6 |
|
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)), |
86 | 12 | }
|
87 | 13 | }
|
88 | 14 |
|
89 | 15 | 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)) |
114 | 17 | }
|
115 | 18 |
|
116 | 19 | pub fn generate<T>(seed: Option<T>, step: impl Fn(&T) -> Option<T>) -> impl Iterator<Item = T> {
|
|
0 commit comments