Skip to content

Commit 63d106e

Browse files
fix: re-add version regex parsing (#223)
Removed in foundry-rs/compilers#215 Fixes after bump foundry-rs/foundry#9349
1 parent d560a75 commit 63d106e

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

crates/compilers/src/resolver/parse.rs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ impl SolData {
120120
let e = e.to_string();
121121
trace!("failed parsing {file:?}: {e}");
122122
parse_result = Err(e);
123+
124+
if version.is_none() {
125+
version = utils::capture_outer_and_inner(
126+
content,
127+
&utils::RE_SOL_PRAGMA_VERSION,
128+
&["version"],
129+
)
130+
.first()
131+
.map(|(cap, name)| Spanned::new(name.as_str().to_owned(), cap.range()));
132+
}
133+
if !imports.is_empty() {
134+
imports = capture_imports(content);
135+
}
123136
}
124137
let license = content.lines().next().and_then(|line| {
125138
utils::capture_outer_and_inner(
@@ -264,3 +277,111 @@ fn library_is_inlined(contract: &ast::ItemContract<'_>) -> bool {
264277
)
265278
})
266279
}
280+
281+
/// Capture the import statement information together with aliases
282+
pub fn capture_imports(content: &str) -> Vec<Spanned<SolImport>> {
283+
let mut imports = vec![];
284+
for cap in utils::RE_SOL_IMPORT.captures_iter(content) {
285+
if let Some(name_match) = ["p1", "p2", "p3", "p4"].iter().find_map(|name| cap.name(name)) {
286+
let statement_match = cap.get(0).unwrap();
287+
let mut aliases = vec![];
288+
for alias_cap in utils::RE_SOL_IMPORT_ALIAS.captures_iter(statement_match.as_str()) {
289+
if let Some(alias) = alias_cap.name("alias") {
290+
let alias = alias.as_str().to_owned();
291+
let import_alias = match alias_cap.name("target") {
292+
Some(target) => SolImportAlias::Contract(alias, target.as_str().to_owned()),
293+
None => SolImportAlias::File(alias),
294+
};
295+
aliases.push(import_alias);
296+
}
297+
}
298+
let sol_import =
299+
SolImport::new(PathBuf::from(name_match.as_str())).set_aliases(aliases);
300+
imports.push(Spanned::new(sol_import, statement_match.range()));
301+
}
302+
}
303+
imports
304+
}
305+
306+
#[cfg(test)]
307+
mod tests {
308+
use super::*;
309+
310+
#[track_caller]
311+
fn assert_version(version_req: Option<&str>, src: &str) {
312+
let data = SolData::parse(src, "test.sol".as_ref());
313+
assert_eq!(data.version_req, version_req.map(|v| v.parse().unwrap()), "src:\n{src}");
314+
}
315+
316+
#[test]
317+
fn soldata_parsing() {
318+
assert_version(None, "");
319+
assert_version(None, "contract C { }");
320+
321+
// https://github.com/foundry-rs/foundry/issues/9349
322+
assert_version(
323+
Some(">=0.4.22, <0.6"),
324+
r#"
325+
pragma solidity >=0.4.22 <0.6;
326+
327+
contract BugReport {
328+
function() external payable {
329+
deposit();
330+
}
331+
function deposit() public payable {}
332+
}
333+
"#,
334+
);
335+
}
336+
337+
#[test]
338+
fn can_capture_curly_imports() {
339+
let content = r#"
340+
import { T } from "../Test.sol";
341+
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
342+
import {DsTest} from "ds-test/test.sol";
343+
"#;
344+
345+
let captured_imports =
346+
capture_imports(content).into_iter().map(|s| s.data.path).collect::<Vec<_>>();
347+
348+
let expected =
349+
utils::find_import_paths(content).map(|m| m.as_str().into()).collect::<Vec<PathBuf>>();
350+
351+
assert_eq!(captured_imports, expected);
352+
353+
assert_eq!(
354+
captured_imports,
355+
vec![
356+
PathBuf::from("../Test.sol"),
357+
"@openzeppelin/contracts/utils/ReentrancyGuard.sol".into(),
358+
"ds-test/test.sol".into(),
359+
],
360+
);
361+
}
362+
363+
#[test]
364+
fn cap_capture_aliases() {
365+
let content = r#"
366+
import * as T from "./Test.sol";
367+
import { DsTest as Test } from "ds-test/test.sol";
368+
import "ds-test/test.sol" as Test;
369+
import { FloatMath as Math, Math as FloatMath } from "./Math.sol";
370+
"#;
371+
372+
let caputred_imports =
373+
capture_imports(content).into_iter().map(|s| s.data.aliases).collect::<Vec<_>>();
374+
assert_eq!(
375+
caputred_imports,
376+
vec![
377+
vec![SolImportAlias::File("T".into())],
378+
vec![SolImportAlias::Contract("Test".into(), "DsTest".into())],
379+
vec![SolImportAlias::File("Test".into())],
380+
vec![
381+
SolImportAlias::Contract("Math".into(), "FloatMath".into()),
382+
SolImportAlias::Contract("FloatMath".into(), "Math".into()),
383+
],
384+
]
385+
);
386+
}
387+
}

0 commit comments

Comments
 (0)