Construct a dependency graph from a set of `modules`. Panics if `modules` contains duplicates or is not closed under the depedency relation
(module_iter: impl IntoIterator<Item = &'a CompiledModule>)
| 21 | /// Construct a dependency graph from a set of `modules`. |
| 22 | /// Panics if `modules` contains duplicates or is not closed under the depedency relation |
| 23 | pub fn new(module_iter: impl IntoIterator<Item = &'a CompiledModule>) -> Self { |
| 24 | let mut modules = vec![]; |
| 25 | let mut reverse_modules = BTreeMap::new(); |
| 26 | for (i, m) in module_iter.into_iter().enumerate() { |
| 27 | modules.push(m); |
| 28 | assert!( |
| 29 | reverse_modules |
| 30 | .insert(m.self_id(), ModuleIndex(i)) |
| 31 | .is_none(), |
| 32 | "Duplicate module found" |
| 33 | ); |
| 34 | } |
| 35 | let mut graph = DiGraphMap::new(); |
| 36 | for module in &modules { |
| 37 | let module_idx: ModuleIndex = *reverse_modules.get(&module.self_id()).unwrap(); |
| 38 | let deps = module.immediate_dependencies(); |
| 39 | if deps.is_empty() { |
| 40 | graph.add_node(module_idx); |
| 41 | } else { |
| 42 | for dep in deps { |
| 43 | let dep_idx = *reverse_modules |
| 44 | .get(&dep) |
| 45 | .unwrap_or_else(|| panic!("Missing dependency {}", dep)); |
| 46 | graph.add_edge(dep_idx, module_idx, ()); |
| 47 | } |
| 48 | } |
| 49 | } |
| 50 | DependencyGraph { modules, graph } |
| 51 | } |
| 52 | |
| 53 | /// Return an iterator over the modules in `self` in topological order--modules with least deps first. |
| 54 | /// Fails with an error if `self` contains circular dependencies |