diff options
author | Aleksey Kladov <[email protected]> | 2019-01-08 22:57:40 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-01-08 22:57:40 +0000 |
commit | 5609989368e5cd5137e8860b7a78859b98e89085 (patch) | |
tree | 55b931a5fdd3f65734bbc7a46bc23b92161adf66 /crates/ra_hir/src | |
parent | 2dc85619beaa3cd9fc47bb8ac1791820691e1205 (diff) |
more stable DefIds via bfs tree walking
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 21 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 17 |
2 files changed, 31 insertions, 7 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. | ||
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 | } | ||
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index a19a6fe51..17de54b44 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -368,7 +368,7 @@ fn typing_inside_a_function_should_not_invalidate_item_map() { | |||
368 | mod foo; | 368 | mod foo; |
369 | 369 | ||
370 | use crate::foo::bar::Baz; | 370 | use crate::foo::bar::Baz; |
371 | { | 371 | |
372 | fn foo() -> i32 { 92 } | 372 | fn foo() -> i32 { 92 } |
373 | ", | 373 | ", |
374 | ); | 374 | ); |
@@ -380,12 +380,15 @@ fn adding_inner_items_should_not_invalidate_item_map() { | |||
380 | " | 380 | " |
381 | //- /lib.rs | 381 | //- /lib.rs |
382 | struct S { a: i32} | 382 | struct S { a: i32} |
383 | mod foo;<|> | ||
384 | enum E { A } | 383 | enum E { A } |
385 | use crate::foo::bar::Baz; | ||
386 | trait T { | 384 | trait T { |
387 | fn a() {} | 385 | fn a() {} |
388 | } | 386 | } |
387 | mod foo;<|> | ||
388 | impl S { | ||
389 | fn a() {} | ||
390 | } | ||
391 | use crate::foo::bar::Baz; | ||
389 | //- /foo/mod.rs | 392 | //- /foo/mod.rs |
390 | pub mod bar; | 393 | pub mod bar; |
391 | 394 | ||
@@ -394,13 +397,17 @@ fn adding_inner_items_should_not_invalidate_item_map() { | |||
394 | ", | 397 | ", |
395 | " | 398 | " |
396 | struct S { a: i32, b: () } | 399 | struct S { a: i32, b: () } |
397 | mod foo;<|> | ||
398 | enum E { A, B } | 400 | enum E { A, B } |
399 | use crate::foo::bar::Baz; | ||
400 | trait T { | 401 | trait T { |
401 | fn a() {} | 402 | fn a() {} |
402 | fn b() {} | 403 | fn b() {} |
403 | } | 404 | } |
405 | mod foo;<|> | ||
406 | impl S { | ||
407 | fn a() {} | ||
408 | fn b() {} | ||
409 | } | ||
410 | use crate::foo::bar::Baz; | ||
404 | ", | 411 | ", |
405 | ); | 412 | ); |
406 | } | 413 | } |