Skip to content

Commit 5609989

Browse files
committed
more stable DefIds via bfs tree walking
1 parent 2dc8561 commit 5609989

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

crates/ra_hir/src/ids.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,17 @@ impl SourceFileItems {
253253
}
254254

255255
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| {
257261
if let Some(module_item) = ast::ModuleItem::cast(it) {
258262
self.alloc(module_item.syntax().to_owned());
259263
} else if let Some(macro_call) = ast::MacroCall::cast(it) {
260264
self.alloc(macro_call.syntax().to_owned());
261265
}
262-
});
266+
})
263267
}
264268

265269
fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId {
@@ -305,3 +309,16 @@ impl std::ops::Index<SourceFileItemId> for SourceFileItems {
305309
&self.arena[idx]
306310
}
307311
}
312+
313+
/// Walks the subtree in bfs order, calling `f` for each node.
314+
fn 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+
}

crates/ra_hir/src/nameres/tests.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ fn typing_inside_a_function_should_not_invalidate_item_map() {
368368
mod foo;
369369
370370
use crate::foo::bar::Baz;
371-
{
371+
372372
fn foo() -> i32 { 92 }
373373
",
374374
);
@@ -380,12 +380,15 @@ fn adding_inner_items_should_not_invalidate_item_map() {
380380
"
381381
//- /lib.rs
382382
struct S { a: i32}
383-
mod foo;<|>
384383
enum E { A }
385-
use crate::foo::bar::Baz;
386384
trait T {
387385
fn a() {}
388386
}
387+
mod foo;<|>
388+
impl S {
389+
fn a() {}
390+
}
391+
use crate::foo::bar::Baz;
389392
//- /foo/mod.rs
390393
pub mod bar;
391394
@@ -394,13 +397,17 @@ fn adding_inner_items_should_not_invalidate_item_map() {
394397
",
395398
"
396399
struct S { a: i32, b: () }
397-
mod foo;<|>
398400
enum E { A, B }
399-
use crate::foo::bar::Baz;
400401
trait T {
401402
fn a() {}
402403
fn b() {}
403404
}
405+
mod foo;<|>
406+
impl S {
407+
fn a() {}
408+
fn b() {}
409+
}
410+
use crate::foo::bar::Baz;
404411
",
405412
);
406413
}

0 commit comments

Comments
 (0)