diff options
author | Edwin Cheng <[email protected]> | 2019-04-08 11:21:48 +0100 |
---|---|---|
committer | Edwin Cheng <[email protected]> | 2019-04-08 11:21:48 +0100 |
commit | 184e9ea230ecbc468eda9309888e6abefbc70aaa (patch) | |
tree | a527a2b4772dab2204450fc44aa47abe947fedbc | |
parent | 2697ecaa64570841f0ed2a3ca5bc02cf41dccc4a (diff) |
Fixed empty node bug
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 59 |
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)] | ||
22 | struct 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 | |||
21 | impl<'a> SubTreeWalker<'a> { | 30 | impl<'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)] | ||
216 | pub(crate) struct WalkerOwner<'a> { | 237 | pub(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 | ||
221 | impl<'a> WalkerOwner<'a> { | 243 | impl<'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 | ||
428 | struct 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 | |||
436 | fn convert_delim(d: tt::Delimiter, closing: bool) -> Option<TtToken> { | 475 | fn 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], "()"), |