aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_mbe/src/subtree_source.rs24
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)]
220pub(crate) struct WalkerOwner<'a> { 220pub(crate) struct WalkerOwner<'a> {
221 walker: RefCell<SubTreeWalker<'a>>, 221 walker: RefCell<SubTreeWalker<'a>>,
222 cached: RefCell<Vec<Option<TtToken>>>,
222} 223}
223 224
224impl<'a> WalkerOwner<'a> { 225impl<'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) {