diff options
Diffstat (limited to 'crates/base_db')
-rw-r--r-- | crates/base_db/src/input.rs | 28 |
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> { |