Skip to content

Commit b52e3d5

Browse files
authored
fix: resolve imports at the end (#326)
Needs solar release for paradigmxyz/solar#531. Fixes\ foundry-rs/foundry#11668.
1 parent 77c1e24 commit b52e3d5

File tree

5 files changed

+83
-20
lines changed

5 files changed

+83
-20
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ semver = { version = "1.0", features = ["serde"] }
5555
serde = { version = "1", features = ["derive", "rc"] }
5656
serde_json = "1.0"
5757
similar-asserts = "1"
58-
solar = { package = "solar-compiler", version = "=0.1.7", default-features = false }
58+
solar = { package = "solar-compiler", version = "=0.1.8", default-features = false }
5959
svm = { package = "svm-rs", version = "0.5", default-features = false }
6060
tempfile = "3.20"
6161
thiserror = "2"

crates/compilers/src/compilers/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,14 @@ pub trait SourceParser: Clone + Debug + Send + Sync {
166166
})
167167
.collect::<Result<_>>()
168168
}
169+
170+
fn finalize_imports(
171+
&mut self,
172+
_nodes: &mut Vec<Node<Self::ParsedSource>>,
173+
_include_paths: &BTreeSet<PathBuf>,
174+
) -> Result<()> {
175+
Ok(())
176+
}
169177
}
170178

171179
/// Parser of the source files which is used to identify imports and version requirements of the

crates/compilers/src/compilers/multi.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,43 @@ impl SourceParser for MultiCompilerParser {
412412
)
413413
.collect())
414414
}
415+
416+
fn finalize_imports(
417+
&mut self,
418+
all_nodes: &mut Vec<crate::resolver::Node<Self::ParsedSource>>,
419+
include_paths: &BTreeSet<PathBuf>,
420+
) -> Result<()> {
421+
let mut solc_nodes = Vec::new();
422+
let mut vyper_nodes = Vec::new();
423+
for node in std::mem::take(all_nodes) {
424+
match node.data {
425+
MultiCompilerParsedSource::Solc(_) => {
426+
solc_nodes.push(node.map_data(|data| match data {
427+
MultiCompilerParsedSource::Solc(data) => data,
428+
_ => unreachable!(),
429+
}))
430+
}
431+
MultiCompilerParsedSource::Vyper(_) => {
432+
vyper_nodes.push(node.map_data(|data| match data {
433+
MultiCompilerParsedSource::Vyper(data) => data,
434+
_ => unreachable!(),
435+
}))
436+
}
437+
}
438+
}
439+
440+
self.solc.finalize_imports(&mut solc_nodes, include_paths)?;
441+
self.vyper.finalize_imports(&mut vyper_nodes, include_paths)?;
442+
443+
all_nodes.extend(
444+
solc_nodes.into_iter().map(|node| node.map_data(MultiCompilerParsedSource::Solc)),
445+
);
446+
all_nodes.extend(
447+
vyper_nodes.into_iter().map(|node| node.map_data(MultiCompilerParsedSource::Vyper)),
448+
);
449+
450+
Ok(())
451+
}
415452
}
416453

417454
impl ParsedSource for MultiCompilerParsedSource {

crates/compilers/src/compilers/solc/mod.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,9 @@ impl SourceParser for SolParser {
399399
&mut self,
400400
sources: &mut Sources,
401401
) -> Result<Vec<(PathBuf, Node<Self::ParsedSource>)>> {
402-
self.compiler_mut().enter_mut(|compiler| {
402+
self.compiler.enter_mut(|compiler| {
403403
let mut pcx = compiler.parse();
404+
pcx.set_resolve_imports(false);
404405
let files = sources
405406
.par_iter()
406407
.map(|(path, source)| {
@@ -423,29 +424,44 @@ impl SourceParser for SolParser {
423424
);
424425
(path.clone(), node)
425426
});
426-
let mut parsed = parsed.collect::<Vec<_>>();
427+
let parsed = parsed.collect::<Vec<_>>();
427428

428-
// Set error on the first successful source, if any. This doesn't really have to be
429-
// exact, as long as at least one source has an error set it should be enough.
430-
if let Some(Err(diag)) = compiler.gcx().sess.emitted_errors() {
431-
if let Some(idx) = parsed
432-
.iter()
433-
.position(|(_, node)| node.data.parse_result.is_ok())
434-
.or_else(|| parsed.first().map(|_| 0))
435-
{
436-
let (_, node) = &mut parsed[idx];
437-
node.data.parse_result = Err(diag.to_string());
438-
}
429+
Ok(parsed)
430+
})
431+
}
432+
433+
fn finalize_imports(
434+
&mut self,
435+
nodes: &mut Vec<Node<Self::ParsedSource>>,
436+
include_paths: &BTreeSet<PathBuf>,
437+
) -> Result<()> {
438+
let compiler = &mut self.compiler;
439+
compiler.sess_mut().opts.include_paths.extend(include_paths.iter().cloned());
440+
compiler.enter_mut(|compiler| {
441+
let mut pcx = compiler.parse();
442+
pcx.set_resolve_imports(true);
443+
pcx.force_resolve_all_imports();
444+
});
445+
446+
// Set error on the first successful source, if any. This doesn't really have to be
447+
// exact, as long as at least one source has an error set it should be enough.
448+
if let Some(Err(diag)) = compiler.sess().emitted_errors() {
449+
if let Some(idx) = nodes
450+
.iter()
451+
.position(|node| node.data.parse_result.is_ok())
452+
.or_else(|| nodes.first().map(|_| 0))
453+
{
454+
nodes[idx].data.parse_result = Err(diag.to_string());
439455
}
456+
}
440457

441-
for (path, node) in &parsed {
442-
if let Err(e) = &node.data.parse_result {
443-
debug!("failed parsing {}: {e}", path.display());
444-
}
458+
for node in nodes.iter() {
459+
if let Err(e) = &node.data.parse_result {
460+
debug!("failed parsing:\n{e}");
445461
}
462+
}
446463

447-
Ok(parsed)
448-
})
464+
Ok(())
449465
}
450466
}
451467

crates/compilers/src/resolver/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ impl<P: SourceParser> Graph<P> {
484484
);
485485
}
486486

487+
parser.finalize_imports(&mut nodes, &resolved_solc_include_paths)?;
488+
487489
let edges = GraphEdges {
488490
edges,
489491
rev_edges,

0 commit comments

Comments
 (0)