Skip to content

Commit

Permalink
fix bug that prevented stubs with no dependencies from being included
Browse files Browse the repository at this point in the history
  • Loading branch information
evan-schott committed Dec 5, 2023
1 parent 7aa476f commit 0e78e23
Showing 1 changed file with 25 additions and 7 deletions.
32 changes: 25 additions & 7 deletions utils/retriever/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ pub struct Retriever {
path: PathBuf,
lock_file: IndexMap<Program, LockContents>,
stubs: IndexMap<Symbol, Stub>,
explored: IndexSet<Program>,
dependency_graph: DiGraph<Symbol>,
}

Expand Down Expand Up @@ -171,14 +170,15 @@ impl Retriever {
path: path.to_path_buf(),
stubs: IndexMap::new(),
lock_file: lock_file_map,
explored: IndexSet::new(),
dependency_graph: DiGraph::new(IndexSet::new()),
})
}

// Retrieve all dependencies for a program
pub fn retrieve(&mut self) -> Result<IndexMap<Symbol, Stub>, UtilError> {
let mut programs_to_retrieve = self.programs.clone();
let mut explored: IndexSet<Program> = IndexSet::new();
let mut solo_programs: IndexSet<Symbol> = IndexSet::new();

while !programs_to_retrieve.is_empty() {
let (mut results, mut dependencies) = (Vec::new(), Vec::new());
Expand All @@ -195,15 +195,15 @@ impl Retriever {
}

// Mark as visited
if !self.explored.insert(program.clone()) {
if !explored.insert(program.clone()) {
Err(UtilError::circular_dependency_error(Default::default()))?;
}
}

for (stub, program, entry) in results {
// Add dependencies to list of dependencies
entry.dependencies.clone().iter().for_each(|dep| {
if !self.explored.contains(dep) {
if !explored.contains(dep) {
dependencies.push(dep.clone());
// Trim off `.aleo` from end of the program names to be consistent with formatting in AST
self.dependency_graph.add_edge(
Expand All @@ -213,6 +213,11 @@ impl Retriever {
}
});

// Add programs that do not have any dependencies to list of solo programs since they are not being added to dependency graph
if entry.dependencies.is_empty() {
solo_programs.insert(Symbol::intern(&program.name.clone()[..program.name.len() - 5]));
}

// Add stub to list of stubs
if let Some(existing) = self.stubs.insert(stub.stub_id.name.name, stub.clone()) {
Err(UtilError::duplicate_dependency_name_error(existing.stub_id.name.name, Default::default()))?;
Expand All @@ -231,14 +236,27 @@ impl Retriever {
// Check for dependency cycles
match self.dependency_graph.post_order() {
Ok(order) => {
// Return stubs in post order
Ok(order
// Collect all the stubs in the order specified by the dependency graph
let mut stubs: IndexMap<Symbol, Stub> = order
.iter()
.map(|id| match self.stubs.get(id) {
Some(s) => (*id, s.clone()),
None => panic!("Stub {id} not found"),
})
.collect())
.collect();

// Add all the stubs that do not have any dependencies
solo_programs.iter().for_each(|id| {
match self.stubs.get(id) {
Some(s) => {
if stubs.insert(*id, s.clone()).is_some() {
panic!("Stub {id} cannot both have dependencies and not have dependencies")
}
}
None => panic!("Stub {id} not found"),
};
});
Ok(stubs)
}
Err(DiGraphError::CycleDetected(_)) => Err(UtilError::circular_dependency_error(Default::default()))?,
}
Expand Down

0 comments on commit 0e78e23

Please sign in to comment.