fix(solc): use lowercase when comparing paths (#1041)
* fix(solc): use lowercase when comparing paths * trace keys * test: add lowercase contract test
This commit is contained in:
parent
a2960a847d
commit
5314c4e618
|
@ -741,12 +741,16 @@ impl CompilerOutput {
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = &'a str>,
|
I: IntoIterator<Item = &'a str>,
|
||||||
{
|
{
|
||||||
let files: HashSet<_> = files.into_iter().collect();
|
// Note: use `to_lowercase` here because solc not necessarily emits the exact file name,
|
||||||
|
// e.g. `src/utils/upgradeProxy.sol` is emitted as `src/utils/UpgradeProxy.sol`
|
||||||
self.contracts.retain(|f, _| files.contains(f.as_str()));
|
let files: HashSet<_> = files.into_iter().map(|s| s.to_lowercase()).collect();
|
||||||
self.sources.retain(|f, _| files.contains(f.as_str()));
|
self.contracts.retain(|f, _| files.contains(f.to_lowercase().as_str()));
|
||||||
|
self.sources.retain(|f, _| files.contains(f.to_lowercase().as_str()));
|
||||||
self.errors.retain(|err| {
|
self.errors.retain(|err| {
|
||||||
err.source_location.as_ref().map(|s| files.contains(s.file.as_str())).unwrap_or(true)
|
err.source_location
|
||||||
|
.as_ref()
|
||||||
|
.map(|s| files.contains(s.file.to_lowercase().as_str()))
|
||||||
|
.unwrap_or(true)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2050,8 +2054,38 @@ impl SourceFiles {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::AggregatedCompilerOutput;
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_parse_declaration_error() {
|
||||||
|
let s = r#"{
|
||||||
|
"errors": [
|
||||||
|
{
|
||||||
|
"component": "general",
|
||||||
|
"errorCode": "7576",
|
||||||
|
"formattedMessage": "DeclarationError: Undeclared identifier. Did you mean \"revert\"?\n --> /Users/src/utils/UpgradeProxy.sol:35:17:\n |\n35 | refert(\"Transparent ERC1967 proxies do not have upgradeable implementations\");\n | ^^^^^^\n\n",
|
||||||
|
"message": "Undeclared identifier. Did you mean \"revert\"?",
|
||||||
|
"severity": "error",
|
||||||
|
"sourceLocation": {
|
||||||
|
"end": 1623,
|
||||||
|
"file": "/Users/src/utils/UpgradeProxy.sol",
|
||||||
|
"start": 1617
|
||||||
|
},
|
||||||
|
"type": "DeclarationError"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"sources": { }
|
||||||
|
}"#;
|
||||||
|
|
||||||
|
let out: CompilerOutput = serde_json::from_str(s).unwrap();
|
||||||
|
assert_eq!(out.errors.len(), 1);
|
||||||
|
|
||||||
|
let mut aggregated = AggregatedCompilerOutput::default();
|
||||||
|
aggregated.extend("0.8.12".parse().unwrap(), out);
|
||||||
|
assert!(!aggregated.is_unchanged());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_link_bytecode() {
|
fn can_link_bytecode() {
|
||||||
// test cases taken from https://github.com/ethereum/solc-js/blob/master/test/linker.js
|
// test cases taken from https://github.com/ethereum/solc-js/blob/master/test/linker.js
|
||||||
|
|
|
@ -331,7 +331,7 @@ impl CompilerSources {
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
"Detected {} dirty sources {:?}",
|
"Detected {} dirty sources {:?}",
|
||||||
sources.dirty().count(),
|
sources.dirty().count(),
|
||||||
sources.dirty_files()
|
sources.dirty_files().collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
(solc, (version, sources))
|
(solc, (version, sources))
|
||||||
})
|
})
|
||||||
|
@ -454,6 +454,7 @@ fn compile_sequential(
|
||||||
let output = solc.compile_exact(&input)?;
|
let output = solc.compile_exact(&input)?;
|
||||||
report::solc_success(&solc, &version, &output);
|
report::solc_success(&solc, &version, &output);
|
||||||
tracing::trace!("compiled input, output has error: {}", output.has_error());
|
tracing::trace!("compiled input, output has error: {}", output.has_error());
|
||||||
|
tracing::trace!("received compiler output: {:?}", output.contracts.keys());
|
||||||
aggregated.extend(version.clone(), output);
|
aggregated.extend(version.clone(), output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,7 @@ pub(crate) fn create_contract_file(path: PathBuf, content: impl AsRef<str>) -> R
|
||||||
}
|
}
|
||||||
|
|
||||||
fn contract_file_name(name: impl AsRef<str>) -> String {
|
fn contract_file_name(name: impl AsRef<str>) -> String {
|
||||||
let name = name.as_ref();
|
let name = name.as_ref().trim();
|
||||||
if name.ends_with(".sol") {
|
if name.ends_with(".sol") {
|
||||||
name.to_string()
|
name.to_string()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -684,6 +684,67 @@ fn can_recompile_with_changes() {
|
||||||
assert!(compiled.find("B").is_some());
|
assert!(compiled.find("B").is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_recompile_with_lowercase_names() {
|
||||||
|
init_tracing();
|
||||||
|
let tmp = TempProject::dapptools().unwrap();
|
||||||
|
|
||||||
|
tmp.add_source(
|
||||||
|
"deployProxy.sol",
|
||||||
|
r#"
|
||||||
|
pragma solidity =0.8.12;
|
||||||
|
contract DeployProxy {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let upgrade = r#"
|
||||||
|
pragma solidity =0.8.12;
|
||||||
|
import "./deployProxy.sol";
|
||||||
|
import "./ProxyAdmin.sol";
|
||||||
|
contract UpgradeProxy {}
|
||||||
|
"#;
|
||||||
|
tmp.add_source("upgradeProxy.sol", upgrade).unwrap();
|
||||||
|
|
||||||
|
tmp.add_source(
|
||||||
|
"ProxyAdmin.sol",
|
||||||
|
r#"
|
||||||
|
pragma solidity =0.8.12;
|
||||||
|
contract ProxyAdmin {}
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let compiled = tmp.compile().unwrap();
|
||||||
|
assert!(!compiled.has_compiler_errors());
|
||||||
|
assert!(compiled.find("DeployProxy").is_some());
|
||||||
|
assert!(compiled.find("UpgradeProxy").is_some());
|
||||||
|
assert!(compiled.find("ProxyAdmin").is_some());
|
||||||
|
|
||||||
|
let artifacts = tmp.artifacts_snapshot().unwrap();
|
||||||
|
assert_eq!(artifacts.artifacts.as_ref().len(), 3);
|
||||||
|
artifacts.assert_artifacts_essentials_present();
|
||||||
|
|
||||||
|
let compiled = tmp.compile().unwrap();
|
||||||
|
assert!(compiled.find("DeployProxy").is_some());
|
||||||
|
assert!(compiled.find("UpgradeProxy").is_some());
|
||||||
|
assert!(compiled.find("ProxyAdmin").is_some());
|
||||||
|
assert!(compiled.is_unchanged());
|
||||||
|
|
||||||
|
// modify upgradeProxy.sol
|
||||||
|
tmp.add_source("upgradeProxy.sol", format!("{}\n", upgrade)).unwrap();
|
||||||
|
let compiled = tmp.compile().unwrap();
|
||||||
|
assert!(!compiled.has_compiler_errors());
|
||||||
|
assert!(!compiled.is_unchanged());
|
||||||
|
assert!(compiled.find("DeployProxy").is_some());
|
||||||
|
assert!(compiled.find("UpgradeProxy").is_some());
|
||||||
|
assert!(compiled.find("ProxyAdmin").is_some());
|
||||||
|
|
||||||
|
let artifacts = tmp.artifacts_snapshot().unwrap();
|
||||||
|
assert_eq!(artifacts.artifacts.as_ref().len(), 3);
|
||||||
|
artifacts.assert_artifacts_essentials_present();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_recompile_unchanged_with_empty_files() {
|
fn can_recompile_unchanged_with_empty_files() {
|
||||||
let tmp = TempProject::dapptools().unwrap();
|
let tmp = TempProject::dapptools().unwrap();
|
||||||
|
|
Loading…
Reference in New Issue