aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ids.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r--crates/ra_hir/src/ids.rs21
1 files changed, 19 insertions, 2 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 3db757778..8ac49eba3 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -253,13 +253,17 @@ impl SourceFileItems {
253 } 253 }
254 254
255 fn init(&mut self, source_file: &SourceFile) { 255 fn init(&mut self, source_file: &SourceFile) {
256 source_file.syntax().descendants().for_each(|it| { 256 // By walking the tree in bread-first order we make sure that parents
257 // get lower ids then children. That is, addding a new child does not
258 // change parent's id. This means that, say, adding a new function to a
259 // trait does not chage ids of top-level items, which helps caching.
260 bfs(source_file.syntax(), |it| {
257 if let Some(module_item) = ast::ModuleItem::cast(it) { 261 if let Some(module_item) = ast::ModuleItem::cast(it) {
258 self.alloc(module_item.syntax().to_owned()); 262 self.alloc(module_item.syntax().to_owned());
259 } else if let Some(macro_call) = ast::MacroCall::cast(it) { 263 } else if let Some(macro_call) = ast::MacroCall::cast(it) {
260 self.alloc(macro_call.syntax().to_owned()); 264 self.alloc(macro_call.syntax().to_owned());
261 } 265 }
262 }); 266 })
263 } 267 }
264 268
265 fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId { 269 fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId {
@@ -305,3 +309,16 @@ impl std::ops::Index<SourceFileItemId> for SourceFileItems {
305 &self.arena[idx] 309 &self.arena[idx]
306 } 310 }
307} 311}
312
313/// Walks the subtree in bfs order, calling `f` for each node.
314fn bfs(node: &SyntaxNode, mut f: impl FnMut(&SyntaxNode)) {
315 let mut curr_layer = vec![node];
316 let mut next_layer = vec![];
317 while !curr_layer.is_empty() {
318 curr_layer.drain(..).for_each(|node| {
319 next_layer.extend(node.children());
320 f(node);
321 });
322 std::mem::swap(&mut curr_layer, &mut next_layer);
323 }
324}