Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/base-db/src/input.rs')
| -rw-r--r-- | crates/base-db/src/input.rs | 58 |
1 files changed, 31 insertions, 27 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs index ffb7f78be6..5149d2d005 100644 --- a/crates/base-db/src/input.rs +++ b/crates/base-db/src/input.rs @@ -482,6 +482,37 @@ impl Crate { } deps.into_boxed_slice() } + + /// Returns all transitive reverse dependencies of the given crate, + /// including the crate itself. + /// + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. + pub fn transitive_rev_deps(self, db: &dyn RootQueryDb) -> Box<[Crate]> { + let mut worklist = vec![self]; + let mut rev_deps = FxHashSet::default(); + rev_deps.insert(self); + + let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); + db.all_crates().iter().for_each(|&krate| { + krate + .data(db) + .dependencies + .iter() + .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) + }); + + while let Some(krate) = worklist.pop() { + if let Some(crate_rev_deps) = inverted_graph.get(&krate) { + crate_rev_deps + .iter() + .copied() + .filter(|&rev_dep| rev_deps.insert(rev_dep)) + .for_each(|rev_dep| worklist.push(rev_dep)); + } + } + + rev_deps.into_iter().collect::<Box<_>>() + } } /// The mapping from [`UniqueCrateData`] to their [`Crate`] input. @@ -826,33 +857,6 @@ impl CrateGraphBuilder { } } -pub(crate) fn transitive_rev_deps(db: &dyn RootQueryDb, of: Crate) -> FxHashSet<Crate> { - let mut worklist = vec![of]; - let mut rev_deps = FxHashSet::default(); - rev_deps.insert(of); - - let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); - db.all_crates().iter().for_each(|&krate| { - krate - .data(db) - .dependencies - .iter() - .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) - }); - - while let Some(krate) = worklist.pop() { - if let Some(crate_rev_deps) = inverted_graph.get(&krate) { - crate_rev_deps - .iter() - .copied() - .filter(|&rev_dep| rev_deps.insert(rev_dep)) - .for_each(|rev_dep| worklist.push(rev_dep)); - } - } - - rev_deps -} - impl BuiltCrateData { pub fn root_file_id(&self, db: &dyn salsa::Database) -> EditionedFileId { EditionedFileId::new(db, self.root_file_id, self.edition) |