1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
pub mod dependency_graph;
use crate::dependency_graph::DependencyGraph;
use move_binary_format::{access::ModuleAccess, file_format::CompiledModule};
use move_core_types::language_storage::ModuleId;
use anyhow::{anyhow, Result};
use std::collections::BTreeMap;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Modules<'a>(BTreeMap<ModuleId, &'a CompiledModule>);
impl<'a> Modules<'a> {
pub fn new(modules: impl IntoIterator<Item = &'a CompiledModule>) -> Self {
let mut map = BTreeMap::new();
for m in modules {
assert!(
map.insert(m.self_id(), m).is_none(),
"Duplicate module found"
);
}
Modules(map)
}
pub fn iter_modules(&self) -> Vec<&CompiledModule> {
self.0.values().copied().collect()
}
pub fn compute_dependency_graph(&self) -> DependencyGraph {
DependencyGraph::new(self.0.values().copied())
}
pub fn get_map(&self) -> &BTreeMap<ModuleId, &CompiledModule> {
&self.0
}
pub fn get_module(&self, module_id: &ModuleId) -> Result<&CompiledModule> {
self.0
.get(module_id)
.copied()
.ok_or_else(|| anyhow!("Can't find module {:?}", module_id))
}
pub fn get_immediate_dependencies(&self, module_id: &ModuleId) -> Result<Vec<&CompiledModule>> {
self.get_module(module_id)?
.immediate_dependencies()
.into_iter()
.map(|mid| self.get_module(&mid))
.collect::<Result<Vec<_>>>()
}
fn get_transitive_dependencies_(
&'a self,
all_deps: &mut Vec<&'a CompiledModule>,
module: &'a CompiledModule,
loader: &'a Modules,
) -> Result<()> {
let next_deps = module.immediate_dependencies();
all_deps.push(module);
for next in next_deps {
let next_module = self.get_module(&next)?;
self.get_transitive_dependencies_(all_deps, next_module, loader)?;
}
Ok(())
}
pub fn get_transitive_dependencies(
&self,
module_id: &ModuleId,
) -> Result<Vec<&CompiledModule>> {
let mut all_deps = vec![];
for dep in self.get_immediate_dependencies(module_id)? {
self.get_transitive_dependencies_(&mut all_deps, dep, self)?;
}
Ok(all_deps)
}
}