fix(solc): fix autodetection edge case (#2099)
This commit is contained in:
parent
7e7f9041b3
commit
847b2a4a05
|
@ -423,7 +423,7 @@ impl Candidate {
|
||||||
/// Which should be resolved to the top level dir `@openzeppelin`
|
/// Which should be resolved to the top level dir `@openzeppelin`
|
||||||
///
|
///
|
||||||
/// We also treat candidates with a `node_modules` parent directory differently and consider
|
/// We also treat candidates with a `node_modules` parent directory differently and consider
|
||||||
/// them to `hardhat` style. In which case the trailing library barrier `contracts` will be
|
/// them to be `hardhat` style. In which case the trailing library barrier `contracts` will be
|
||||||
/// stripped from the remapping path. This differs from dapptools style which does not include
|
/// stripped from the remapping path. This differs from dapptools style which does not include
|
||||||
/// the library barrier path `src` in the solidity import statements. For example, for
|
/// the library barrier path `src` in the solidity import statements. For example, for
|
||||||
/// dapptools you could have
|
/// dapptools you could have
|
||||||
|
@ -472,8 +472,23 @@ impl Candidate {
|
||||||
window_start: PathBuf,
|
window_start: PathBuf,
|
||||||
is_inside_node_modules: bool,
|
is_inside_node_modules: bool,
|
||||||
) {
|
) {
|
||||||
if let Some(pos) =
|
// if there's only a single source dir candidate then we use this
|
||||||
candidates.iter().position(|c| c.source_dir.ends_with(DAPPTOOLS_CONTRACTS_DIR))
|
if let Some(pos) = candidates
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.fold((0, None), |(mut contracts_dir_count, mut pos), (idx, c)| {
|
||||||
|
if c.source_dir.ends_with(DAPPTOOLS_CONTRACTS_DIR) {
|
||||||
|
contracts_dir_count += 1;
|
||||||
|
if contracts_dir_count == 1 {
|
||||||
|
pos = Some(idx)
|
||||||
|
} else {
|
||||||
|
pos = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(contracts_dir_count, pos)
|
||||||
|
})
|
||||||
|
.1
|
||||||
{
|
{
|
||||||
let c = candidates.remove(pos);
|
let c = candidates.remove(pos);
|
||||||
*candidates = vec![c];
|
*candidates = vec![c];
|
||||||
|
@ -630,6 +645,7 @@ fn find_remapping_candidates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// need to find the actual next window in the event `open` is a lib dir
|
// need to find the actual next window in the event `open` is a lib dir
|
||||||
let window_start = next_nested_window(open, current_dir);
|
let window_start = next_nested_window(open, current_dir);
|
||||||
// finally, we need to merge, adjust candidates from the same level and opening window
|
// finally, we need to merge, adjust candidates from the same level and opening window
|
||||||
|
@ -1227,4 +1243,37 @@ mod tests {
|
||||||
"/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test"
|
"/var/folders/l5/lprhf87s6xv8djgd017f0b2h0000gn/T/lib.Z6ODLZJQeJQa/repo1/lib/ds-test"
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn find_openzeppelin_remapping() {
|
||||||
|
let tmp_dir = tempdir("lib").unwrap();
|
||||||
|
let tmp_dir_path = tmp_dir.path();
|
||||||
|
let paths = [
|
||||||
|
"lib/ds-test/src/test.sol",
|
||||||
|
"lib/forge-std/src/test.sol",
|
||||||
|
"openzeppelin/contracts/interfaces/c.sol",
|
||||||
|
];
|
||||||
|
mkdir_or_touch(tmp_dir_path, &paths[..]);
|
||||||
|
|
||||||
|
let path = tmp_dir_path.display().to_string();
|
||||||
|
let mut remappings = Remapping::find_many(path);
|
||||||
|
remappings.sort_unstable();
|
||||||
|
|
||||||
|
let mut expected = vec![
|
||||||
|
Remapping {
|
||||||
|
name: "ds-test/".to_string(),
|
||||||
|
path: to_str(tmp_dir_path.join("lib/ds-test/src")),
|
||||||
|
},
|
||||||
|
Remapping {
|
||||||
|
name: "openzeppelin/".to_string(),
|
||||||
|
path: to_str(tmp_dir_path.join("openzeppelin/contracts")),
|
||||||
|
},
|
||||||
|
Remapping {
|
||||||
|
name: "forge-std/".to_string(),
|
||||||
|
path: to_str(tmp_dir_path.join("lib/forge-std/src")),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
expected.sort_unstable();
|
||||||
|
pretty_assertions::assert_eq!(remappings, expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -473,7 +473,7 @@ pub fn create_parent_dir_all(file: impl AsRef<Path>) -> Result<(), SolcError> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::resolver::Node;
|
|
||||||
use solang_parser::pt::SourceUnitPart;
|
use solang_parser::pt::SourceUnitPart;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashSet,
|
collections::HashSet,
|
||||||
|
@ -516,7 +516,7 @@ contract A {}
|
||||||
|
|
||||||
assert!(!non_existing.exists());
|
assert!(!non_existing.exists());
|
||||||
|
|
||||||
let found = Node::read(&non_existing).unwrap_err();
|
let found = crate::resolver::Node::read(&non_existing).unwrap_err();
|
||||||
matches!(found, SolcError::ResolveCaseSensitiveFileName { .. });
|
matches!(found, SolcError::ResolveCaseSensitiveFileName { .. });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue