diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_mbe/src/subtree_source.rs | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/crates/ra_mbe/src/subtree_source.rs b/crates/ra_mbe/src/subtree_source.rs index 20da1e9f7..3229cfa8f 100644 --- a/crates/ra_mbe/src/subtree_source.rs +++ b/crates/ra_mbe/src/subtree_source.rs | |||
@@ -219,17 +219,33 @@ pub(crate) trait Querier { | |||
219 | #[derive(Debug)] | 219 | #[derive(Debug)] |
220 | pub(crate) struct WalkerOwner<'a> { | 220 | pub(crate) struct WalkerOwner<'a> { |
221 | walker: RefCell<SubTreeWalker<'a>>, | 221 | walker: RefCell<SubTreeWalker<'a>>, |
222 | cached: RefCell<Vec<Option<TtToken>>>, | ||
222 | } | 223 | } |
223 | 224 | ||
224 | impl<'a> WalkerOwner<'a> { | 225 | impl<'a> WalkerOwner<'a> { |
225 | fn new<I: Into<TokenSeq<'a>>>(ts: I) -> Self { | 226 | fn new<I: Into<TokenSeq<'a>>>(ts: I) -> Self { |
226 | WalkerOwner { walker: RefCell::new(SubTreeWalker::new(ts.into())) } | 227 | WalkerOwner { |
228 | walker: RefCell::new(SubTreeWalker::new(ts.into())), | ||
229 | cached: RefCell::new(Vec::with_capacity(10)), | ||
230 | } | ||
227 | } | 231 | } |
228 | 232 | ||
229 | fn get<'b>(&self, pos: usize) -> Option<TtToken> { | 233 | fn get<'b>(&self, pos: usize) -> Option<TtToken> { |
230 | self.set_pos(pos); | 234 | let mut cached = self.cached.borrow_mut(); |
231 | let walker = self.walker.borrow(); | 235 | if pos < cached.len() { |
232 | walker.current().cloned() | 236 | return cached[pos].clone(); |
237 | } | ||
238 | |||
239 | while pos >= cached.len() { | ||
240 | let len = cached.len(); | ||
241 | cached.push({ | ||
242 | self.set_pos(len); | ||
243 | let walker = self.walker.borrow(); | ||
244 | walker.current().cloned() | ||
245 | }); | ||
246 | } | ||
247 | |||
248 | return cached[pos].clone(); | ||
233 | } | 249 | } |
234 | 250 | ||
235 | fn set_pos(&self, pos: usize) { | 251 | fn set_pos(&self, pos: usize) { |