aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_mbe/src/subtree_source.rs
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2019-04-08 11:21:48 +0100
committerEdwin Cheng <[email protected]>2019-04-08 11:21:48 +0100
commit184e9ea230ecbc468eda9309888e6abefbc70aaa (patch)
treea527a2b4772dab2204450fc44aa47abe947fedbc /crates/ra_mbe/src/subtree_source.rs
parent2697ecaa64570841f0ed2a3ca5bc02cf41dccc4a (diff)
Fixed empty node bug
Diffstat (limited to 'crates/ra_mbe/src/subtree_source.rs')
-rw-r--r--crates/ra_mbe/src/subtree_source.rs59
1 files changed, 49 insertions, 10 deletions
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs
index 9dd475f2c..997a600a5 100644
--- a/crates/ra_mbe/src/subtree_source.rs
+++ b/crates/ra_mbe/src/subtree_source.rs
@@ -18,6 +18,15 @@ enum WalkIndex {
18 Eof, 18 Eof,
19} 19}
20 20
21#[derive(Debug)]
22struct SubTreeWalker<'a> {
23 pos: usize,
24 stack: Vec<(&'a tt::Subtree, Option<usize>)>,
25 idx: WalkIndex,
26 last_steps: Vec<usize>,
27 subtree: &'a tt::Subtree,
28}
29
21impl<'a> SubTreeWalker<'a> { 30impl<'a> SubTreeWalker<'a> {
22 fn new(subtree: &tt::Subtree) -> SubTreeWalker { 31 fn new(subtree: &tt::Subtree) -> SubTreeWalker {
23 let mut res = SubTreeWalker { 32 let mut res = SubTreeWalker {
@@ -84,6 +93,13 @@ impl<'a> SubTreeWalker<'a> {
84 break; 93 break;
85 } 94 }
86 } 95 }
96
97 // Move forward a little bit
98 if self.last_steps.is_empty() {
99 while self.is_empty_delimiter() {
100 self.forward_unchecked();
101 }
102 }
87 } 103 }
88 104
89 fn backward_unchecked(&mut self) { 105 fn backward_unchecked(&mut self) {
@@ -133,6 +149,10 @@ impl<'a> SubTreeWalker<'a> {
133 } 149 }
134 150
135 fn forward(&mut self) { 151 fn forward(&mut self) {
152 if self.idx == WalkIndex::Eof {
153 return;
154 }
155
136 self.pos += 1; 156 self.pos += 1;
137 loop { 157 loop {
138 self.forward_unchecked(); 158 self.forward_unchecked();
@@ -213,15 +233,38 @@ pub(crate) trait Querier {
213} 233}
214 234
215// A wrapper class for ref cell 235// A wrapper class for ref cell
236#[derive(Debug)]
216pub(crate) struct WalkerOwner<'a> { 237pub(crate) struct WalkerOwner<'a> {
217 walker: RefCell<SubTreeWalker<'a>>, 238 walker: RefCell<SubTreeWalker<'a>>,
218 offset: usize, 239 offset: usize,
240 temp: RefCell<std::collections::HashMap<usize, Option<TtToken>>>,
219} 241}
220 242
221impl<'a> WalkerOwner<'a> { 243impl<'a> WalkerOwner<'a> {
222 fn token_idx<'b>(&self, pos: usize) -> Option<TtToken> { 244 fn token_idx<'b>(&self, pos: usize) -> Option<TtToken> {
223 self.set_walker_pos(pos); 245 self.set_walker_pos(pos);
224 self.walker.borrow().current().cloned() 246 let walker = self.walker.borrow();
247 let r = walker.current().cloned();
248
249 if walker.subtree.token_trees.len() == 1 {
250 if let tt::TokenTree::Leaf(_) = &walker.subtree.token_trees[0] {
251 let mut temp = self.temp.borrow_mut();
252
253 if r.is_none() {
254 if let Some(Some(p)) = temp.get(&pos) {
255 unreachable!(
256 "nWWWWWWWWWWWW~~~~~~~~~~~~~~,\n{:#?}\n{:#?}\n{:#?}",
257 pos, p, self
258 );
259 }
260 }
261
262 // eprintln!("===>{:#?}\n{:#?}\n{:#?}", pos, r, self);
263 temp.insert(pos, r.clone());
264 }
265 }
266
267 r
225 } 268 }
226 269
227 fn start_from_nth(&mut self, pos: usize) { 270 fn start_from_nth(&mut self, pos: usize) {
@@ -242,7 +285,11 @@ impl<'a> WalkerOwner<'a> {
242 } 285 }
243 286
244 fn new(subtree: &'a tt::Subtree) -> Self { 287 fn new(subtree: &'a tt::Subtree) -> Self {
245 WalkerOwner { walker: RefCell::new(SubTreeWalker::new(subtree)), offset: 0 } 288 WalkerOwner {
289 walker: RefCell::new(SubTreeWalker::new(subtree)),
290 offset: 0,
291 temp: RefCell::new(Default::default()),
292 }
246 } 293 }
247 294
248 fn collect_token_tree(&mut self, n: usize) -> Vec<&tt::TokenTree> { 295 fn collect_token_tree(&mut self, n: usize) -> Vec<&tt::TokenTree> {
@@ -425,14 +472,6 @@ where
425 None 472 None
426} 473}
427 474
428struct SubTreeWalker<'a> {
429 pos: usize,
430 stack: Vec<(&'a tt::Subtree, Option<usize>)>,
431 idx: WalkIndex,
432 last_steps: Vec<usize>,
433 subtree: &'a tt::Subtree,
434}
435
436fn convert_delim(d: tt::Delimiter, closing: bool) -> Option<TtToken> { 475fn convert_delim(d: tt::Delimiter, closing: bool) -> Option<TtToken> {
437 let (kinds, texts) = match d { 476 let (kinds, texts) = match d {
438 tt::Delimiter::Parenthesis => ([L_PAREN, R_PAREN], "()"), 477 tt::Delimiter::Parenthesis => ([L_PAREN, R_PAREN], "()"),