Skip to content
This repository has been archived by the owner on Oct 19, 2024. It is now read-only.

fix(solc): flatten import aliases #1192

Merged
merged 8 commits into from
May 4, 2022
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions ethers-solc/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::{
cache::SOLIDITY_FILES_CACHE_FILENAME,
error::{Result, SolcError, SolcIoError},
remappings::Remapping,
resolver::Graph,
resolver::{Graph, SolImportAlias},
utils, Source, Sources,
};

Expand Down Expand Up @@ -281,43 +281,69 @@ impl ProjectPathsConfig {
let target_node = graph.node(*target_index);

let mut imports = target_node.imports().clone();
imports.sort_by_key(|x| x.loc().0);
imports.sort_by_key(|x| x.loc().start);

let mut content = target_node.content().to_owned();

for alias in imports.iter().flat_map(|i| i.data().aliases()) {
let (alias, target) = match alias {
SolImportAlias::Contract(alias, target) => (alias.clone(), target.clone()),
_ => continue,
};
let name_regex = utils::create_contract_or_lib_name_regex(&alias);
let target_len = target.len() as isize;
let mut replace_offset = 0;
for cap in name_regex.captures_iter(&content.clone()) {
if cap.name("ignore").is_some() {
continue
}
if let Some(name_match) =
vec!["n1", "n2", "n3"].iter().find_map(|name| cap.name(name))
{
let name_match_range =
utils::range_by_offset(&name_match.range(), replace_offset);
replace_offset += target_len - (name_match_range.len() as isize);
content.replace_range(name_match_range, &target);
}
}
}

let mut content = target_node.content().as_bytes().to_vec();
let mut content = content.as_bytes().to_vec();
let mut offset = 0_isize;

if strip_license {
if let Some(license) = target_node.license() {
let (start, end) = license.loc_by_offset(offset);
content.splice(start..end, std::iter::empty());
offset -= (end - start) as isize;
let license_range = license.loc_by_offset(offset);
offset -= license_range.len() as isize;
content.splice(license_range, std::iter::empty());
}
}

if strip_version_pragma {
if let Some(version) = target_node.version() {
let (start, end) = version.loc_by_offset(offset);
content.splice(start..end, std::iter::empty());
offset -= (end - start) as isize;
let version_range = version.loc_by_offset(offset);
offset -= version_range.len() as isize;
content.splice(version_range, std::iter::empty());
}
}

if strip_experimental_pragma {
if let Some(experiment) = target_node.experimental() {
let (start, end) = experiment.loc_by_offset(offset);
content.splice(start..end, std::iter::empty());
offset -= (end - start) as isize;
let experimental_pragma_range = experiment.loc_by_offset(offset);
offset -= experimental_pragma_range.len() as isize;
content.splice(experimental_pragma_range, std::iter::empty());
}
}

for import in imports.iter() {
let import_path = self.resolve_import(target_dir, import.data())?;
let import_path = self.resolve_import(target_dir, import.data().path())?;
let s = self.flatten_node(&import_path, graph, imported, true, true, true)?;

let import_content = s.as_bytes();
let import_content_len = import_content.len() as isize;
let (start, end) = import.loc_by_offset(offset);
content.splice(start..end, import_content.iter().copied());
offset += import_content_len - ((end - start) as isize);
let import_range = import.loc_by_offset(offset);
offset += import_content_len - (import_range.len() as isize);
content.splice(import_range, import_content.iter().copied());
}

let result = String::from_utf8(content).map_err(|err| {
Expand Down
14 changes: 8 additions & 6 deletions ethers-solc/src/resolver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use std::{
path::{Path, PathBuf},
};

use parse::{SolData, SolDataUnit};
use parse::{SolData, SolDataUnit, SolImport};
use rayon::prelude::*;

use semver::VersionReq;
Expand All @@ -62,6 +62,7 @@ use crate::{error::Result, utils, ProjectPathsConfig, SolcError, Source, Sources
mod parse;
mod tree;

pub use parse::SolImportAlias;
pub use tree::{print, Charset, TreeOptions};

/// The underlying edges of the graph which only contains the raw relationship data.
Expand Down Expand Up @@ -339,13 +340,14 @@ impl Graph {
};

for import in node.data.imports.iter() {
match paths.resolve_import(cwd, import.data()) {
let import_path = import.data().path();
match paths.resolve_import(cwd, import_path) {
Ok(import) => {
add_node(&mut unresolved, &mut index, &mut resolved_imports, import)?;
}
Err(err) => {
if unresolved_paths.insert(import.data().to_path_buf()) {
crate::report::unresolved_import(import.data(), &paths.remappings);
if unresolved_paths.insert(import_path.to_path_buf()) {
crate::report::unresolved_import(import_path, &paths.remappings);
}
tracing::trace!(
"failed to resolve import component \"{:?}\" for {:?}",
Expand Down Expand Up @@ -772,7 +774,7 @@ impl Node {
&self.source.content
}

pub fn imports(&self) -> &Vec<SolDataUnit<PathBuf>> {
pub fn imports(&self) -> &Vec<SolDataUnit<SolImport>> {
&self.data.imports
}

Expand Down Expand Up @@ -854,7 +856,7 @@ mod tests {
let dapp_test = graph.node(1);
assert_eq!(dapp_test.path, paths.sources.join("Dapp.t.sol"));
assert_eq!(
dapp_test.data.imports.iter().map(|i| i.data()).collect::<Vec<&PathBuf>>(),
dapp_test.data.imports.iter().map(|i| i.data().path()).collect::<Vec<&PathBuf>>(),
vec![&PathBuf::from("ds-test/test.sol"), &PathBuf::from("./Dapp.sol")]
);
assert_eq!(graph.imported_nodes(1).to_vec(), vec![2, 0]);
Expand Down
Loading