fix(solc): allow cyclic imports (#766)
This commit is contained in:
parent
88b342287a
commit
eeb2a84df4
|
@ -268,21 +268,22 @@ impl Graph {
|
||||||
traversed: &mut std::collections::HashSet<(usize, usize)>,
|
traversed: &mut std::collections::HashSet<(usize, usize)>,
|
||||||
) -> std::result::Result<(), String> {
|
) -> std::result::Result<(), String> {
|
||||||
let node = self.node(idx);
|
let node = self.node(idx);
|
||||||
|
|
||||||
if let Some(ref req) = node.data.version_req {
|
if let Some(ref req) = node.data.version_req {
|
||||||
candidates.retain(|v| req.matches(v.as_ref()));
|
candidates.retain(|v| req.matches(v.as_ref()));
|
||||||
}
|
}
|
||||||
for dep in self.imported_nodes(idx).iter().copied() {
|
for dep in self.imported_nodes(idx).iter().copied() {
|
||||||
// check for circular deps which would result in endless recursion SO here
|
// check for circular deps which would result in endless recursion SO here
|
||||||
// a circular dependency exists, if there was already a `dependency imports current
|
// a circular dependency exists, if there was already a `dependency imports current
|
||||||
// node` relationship in the traversed path
|
// node` relationship in the traversed path we skip this node
|
||||||
if traversed.contains(&(dep, idx)) {
|
|
||||||
let mut msg = String::new();
|
|
||||||
self.format_imports_list(dep, &mut msg).unwrap();
|
|
||||||
return Err(format!("Encountered circular dependencies in:\n{}", msg))
|
|
||||||
}
|
|
||||||
traversed.insert((idx, dep));
|
traversed.insert((idx, dep));
|
||||||
|
if traversed.contains(&(dep, idx)) {
|
||||||
|
tracing::warn!(
|
||||||
|
"Detected cyclic imports {} <-> {}",
|
||||||
|
utils::source_name(&self.nodes[idx].path, &self.root).display(),
|
||||||
|
utils::source_name(&self.nodes[dep].path, &self.root).display()
|
||||||
|
);
|
||||||
|
continue
|
||||||
|
}
|
||||||
self.retain_compatible_versions(dep, candidates, traversed)?;
|
self.retain_compatible_versions(dep, candidates, traversed)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -308,6 +309,7 @@ impl Graph {
|
||||||
&self,
|
&self,
|
||||||
offline: bool,
|
offline: bool,
|
||||||
) -> Result<HashMap<crate::SolcVersion, Vec<usize>>> {
|
) -> Result<HashMap<crate::SolcVersion, Vec<usize>>> {
|
||||||
|
tracing::trace!("resolving input node versions");
|
||||||
// this is likely called by an application and will be eventually printed so we don't exit
|
// this is likely called by an application and will be eventually printed so we don't exit
|
||||||
// on first error, instead gather all the errors and return a bundled error message instead
|
// on first error, instead gather all the errors and return a bundled error message instead
|
||||||
let mut errors = Vec::new();
|
let mut errors = Vec::new();
|
||||||
|
@ -349,8 +351,14 @@ impl Graph {
|
||||||
}
|
}
|
||||||
|
|
||||||
if errors.is_empty() {
|
if errors.is_empty() {
|
||||||
|
tracing::trace!(
|
||||||
|
"resolved {} versions {:?}",
|
||||||
|
versioned_nodes.len(),
|
||||||
|
versioned_nodes.keys()
|
||||||
|
);
|
||||||
Ok(versioned_nodes)
|
Ok(versioned_nodes)
|
||||||
} else {
|
} else {
|
||||||
|
tracing::error!("failed to resolve versions");
|
||||||
Err(crate::error::SolcError::msg(errors.join("\n")))
|
Err(crate::error::SolcError::msg(errors.join("\n")))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue