Skip to content

Commit

Permalink
fix: re-add version regex parsing (#223)
Browse files Browse the repository at this point in the history
Removed in #215
Fixes after bump foundry-rs/foundry#9349
  • Loading branch information
DaniPopes authored Nov 19, 2024
1 parent 7a151d3 commit 05dc674
Showing 1 changed file with 121 additions and 0 deletions.
121 changes: 121 additions & 0 deletions crates/compilers/src/resolver/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,19 @@ impl SolData {
let e = e.to_string();
trace!("failed parsing {file:?}: {e}");
parse_result = Err(e);

if version.is_none() {
version = utils::capture_outer_and_inner(
content,
&utils::RE_SOL_PRAGMA_VERSION,
&["version"],
)
.first()
.map(|(cap, name)| Spanned::new(name.as_str().to_owned(), cap.range()));
}
if !imports.is_empty() {
imports = capture_imports(content);
}
}
let license = content.lines().next().and_then(|line| {
utils::capture_outer_and_inner(
Expand Down Expand Up @@ -264,3 +277,111 @@ fn library_is_inlined(contract: &ast::ItemContract<'_>) -> bool {
)
})
}

/// Capture the import statement information together with aliases
pub fn capture_imports(content: &str) -> Vec<Spanned<SolImport>> {
let mut imports = vec![];
for cap in utils::RE_SOL_IMPORT.captures_iter(content) {
if let Some(name_match) = ["p1", "p2", "p3", "p4"].iter().find_map(|name| cap.name(name)) {
let statement_match = cap.get(0).unwrap();
let mut aliases = vec![];
for alias_cap in utils::RE_SOL_IMPORT_ALIAS.captures_iter(statement_match.as_str()) {
if let Some(alias) = alias_cap.name("alias") {
let alias = alias.as_str().to_owned();
let import_alias = match alias_cap.name("target") {
Some(target) => SolImportAlias::Contract(alias, target.as_str().to_owned()),
None => SolImportAlias::File(alias),
};
aliases.push(import_alias);
}
}
let sol_import =
SolImport::new(PathBuf::from(name_match.as_str())).set_aliases(aliases);
imports.push(Spanned::new(sol_import, statement_match.range()));
}
}
imports
}

#[cfg(test)]
mod tests {
use super::*;

#[track_caller]
fn assert_version(version_req: Option<&str>, src: &str) {
let data = SolData::parse(src, "test.sol".as_ref());
assert_eq!(data.version_req, version_req.map(|v| v.parse().unwrap()), "src:\n{src}");
}

#[test]
fn soldata_parsing() {
assert_version(None, "");
assert_version(None, "contract C { }");

// https://github.com/foundry-rs/foundry/issues/9349
assert_version(
Some(">=0.4.22, <0.6"),
r#"
pragma solidity >=0.4.22 <0.6;
contract BugReport {
function() external payable {
deposit();
}
function deposit() public payable {}
}
"#,
);
}

#[test]
fn can_capture_curly_imports() {
let content = r#"
import { T } from "../Test.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import {DsTest} from "ds-test/test.sol";
"#;

let captured_imports =
capture_imports(content).into_iter().map(|s| s.data.path).collect::<Vec<_>>();

let expected =
utils::find_import_paths(content).map(|m| m.as_str().into()).collect::<Vec<PathBuf>>();

assert_eq!(captured_imports, expected);

assert_eq!(
captured_imports,
vec![
PathBuf::from("../Test.sol"),
"@openzeppelin/contracts/utils/ReentrancyGuard.sol".into(),
"ds-test/test.sol".into(),
],
);
}

#[test]
fn cap_capture_aliases() {
let content = r#"
import * as T from "./Test.sol";
import { DsTest as Test } from "ds-test/test.sol";
import "ds-test/test.sol" as Test;
import { FloatMath as Math, Math as FloatMath } from "./Math.sol";
"#;

let caputred_imports =
capture_imports(content).into_iter().map(|s| s.data.aliases).collect::<Vec<_>>();
assert_eq!(
caputred_imports,
vec![
vec![SolImportAlias::File("T".into())],
vec![SolImportAlias::Contract("Test".into(), "DsTest".into())],
vec![SolImportAlias::File("Test".into())],
vec![
SolImportAlias::Contract("Math".into(), "FloatMath".into()),
SolImportAlias::Contract("FloatMath".into(), "Math".into()),
],
]
);
}
}

0 comments on commit 05dc674

Please sign in to comment.