mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 19:12:50 +00:00
more stable DefIds via bfs tree walking
This commit is contained in:
parent
2dc85619be
commit
5609989368
@ -253,13 +253,17 @@ impl SourceFileItems {
|
||||
}
|
||||
|
||||
fn init(&mut self, source_file: &SourceFile) {
|
||||
source_file.syntax().descendants().for_each(|it| {
|
||||
// By walking the tree in bread-first order we make sure that parents
|
||||
// get lower ids then children. That is, addding a new child does not
|
||||
// change parent's id. This means that, say, adding a new function to a
|
||||
// trait does not chage ids of top-level items, which helps caching.
|
||||
bfs(source_file.syntax(), |it| {
|
||||
if let Some(module_item) = ast::ModuleItem::cast(it) {
|
||||
self.alloc(module_item.syntax().to_owned());
|
||||
} else if let Some(macro_call) = ast::MacroCall::cast(it) {
|
||||
self.alloc(macro_call.syntax().to_owned());
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
fn alloc(&mut self, item: TreePtr<SyntaxNode>) -> SourceFileItemId {
|
||||
@ -305,3 +309,16 @@ impl std::ops::Index<SourceFileItemId> for SourceFileItems {
|
||||
&self.arena[idx]
|
||||
}
|
||||
}
|
||||
|
||||
/// Walks the subtree in bfs order, calling `f` for each node.
|
||||
fn bfs(node: &SyntaxNode, mut f: impl FnMut(&SyntaxNode)) {
|
||||
let mut curr_layer = vec![node];
|
||||
let mut next_layer = vec![];
|
||||
while !curr_layer.is_empty() {
|
||||
curr_layer.drain(..).for_each(|node| {
|
||||
next_layer.extend(node.children());
|
||||
f(node);
|
||||
});
|
||||
std::mem::swap(&mut curr_layer, &mut next_layer);
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ fn typing_inside_a_function_should_not_invalidate_item_map() {
|
||||
mod foo;
|
||||
|
||||
use crate::foo::bar::Baz;
|
||||
{
|
||||
|
||||
fn foo() -> i32 { 92 }
|
||||
",
|
||||
);
|
||||
@ -380,12 +380,15 @@ fn adding_inner_items_should_not_invalidate_item_map() {
|
||||
"
|
||||
//- /lib.rs
|
||||
struct S { a: i32}
|
||||
mod foo;<|>
|
||||
enum E { A }
|
||||
use crate::foo::bar::Baz;
|
||||
trait T {
|
||||
fn a() {}
|
||||
}
|
||||
mod foo;<|>
|
||||
impl S {
|
||||
fn a() {}
|
||||
}
|
||||
use crate::foo::bar::Baz;
|
||||
//- /foo/mod.rs
|
||||
pub mod bar;
|
||||
|
||||
@ -394,13 +397,17 @@ fn adding_inner_items_should_not_invalidate_item_map() {
|
||||
",
|
||||
"
|
||||
struct S { a: i32, b: () }
|
||||
mod foo;<|>
|
||||
enum E { A, B }
|
||||
use crate::foo::bar::Baz;
|
||||
trait T {
|
||||
fn a() {}
|
||||
fn b() {}
|
||||
}
|
||||
mod foo;<|>
|
||||
impl S {
|
||||
fn a() {}
|
||||
fn b() {}
|
||||
}
|
||||
use crate::foo::bar::Baz;
|
||||
",
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user