fix(solc): fix autodetection edge case (#2099)

This commit is contained in:
Matthias Seitz 2023-02-01 00:16:34 +01:00 committed by GitHub
parent 7e7f9041b3
commit 847b2a4a05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 5 deletions

View File

@ -423,7 +423,7 @@ impl Candidate {
/// Which should be resolved to the top level dir `@openzeppelin`
///
/// 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
/// the library barrier path `src` in the solidity import statements. For example, for
/// dapptools you could have
@ -472,8 +472,23 @@ impl Candidate {
window_start: PathBuf,
is_inside_node_modules: bool,
) {
if let Some(pos) =
candidates.iter().position(|c| c.source_dir.ends_with(DAPPTOOLS_CONTRACTS_DIR))
// if there's only a single source dir candidate then we use this
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);
*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
let window_start = next_nested_window(open, current_dir);
// 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"
));
}
#[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);
}
}

View File

@ -473,7 +473,7 @@ pub fn create_parent_dir_all(file: impl AsRef<Path>) -> Result<(), SolcError> {
#[cfg(test)]
mod tests {
use super::*;
use crate::resolver::Node;
use solang_parser::pt::SourceUnitPart;
use std::{
collections::HashSet,
@ -516,7 +516,7 @@ contract A {}
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 { .. });
}