aboutsummaryrefslogtreecommitdiff
path: root/crates/base_db
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-03-15 16:43:46 +0000
committerLukas Wirth <[email protected]>2021-03-15 17:28:31 +0000
commite97cd709cd91ccfafbd45bab8b2bf01f3ddf6a04 (patch)
treebb6e1bcfae7fd44a7a63be31a17dc6e68799e7d5 /crates/base_db
parenteec64ec01b0553aca855df8146965ed6c6746e7d (diff)
Implement Crate::transitive_reverse_dependencies
Diffstat (limited to 'crates/base_db')
-rw-r--r--crates/base_db/src/input.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/crates/base_db/src/input.rs b/crates/base_db/src/input.rs
index b5f7e4200..06f1c14f5 100644
--- a/crates/base_db/src/input.rs
+++ b/crates/base_db/src/input.rs
@@ -274,6 +274,34 @@ impl CrateGraph {
274 deps.into_iter() 274 deps.into_iter()
275 } 275 }
276 276
277 /// Returns an iterator over all transitive reverse dependencies of the given crate.
278 pub fn transitive_reverse_dependencies(
279 &self,
280 of: CrateId,
281 ) -> impl Iterator<Item = CrateId> + '_ {
282 let mut worklist = vec![of];
283 let mut rev_deps = FxHashSet::default();
284 let mut inverted_graph = FxHashMap::default();
285 self.arena.iter().for_each(|(&krate, data)| {
286 data.dependencies.iter().for_each(|dep| {
287 inverted_graph.entry(dep.crate_id).or_insert_with(Vec::default).push(krate)
288 })
289 });
290
291 while let Some(krate) = worklist.pop() {
292 if !rev_deps.insert(krate) {
293 continue;
294 }
295
296 if let Some(rev_deps) = inverted_graph.get(&krate) {
297 worklist.extend(rev_deps);
298 }
299 }
300
301 rev_deps.remove(&of);
302 rev_deps.into_iter()
303 }
304
277 /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate 305 /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate
278 /// come before the crate itself). 306 /// come before the crate itself).
279 pub fn crates_in_topological_order(&self) -> Vec<CrateId> { 307 pub fn crates_in_topological_order(&self) -> Vec<CrateId> {