perf(solc): wrap source content in Arc (#2138)
This commit is contained in:
parent
bfe3ba9d5f
commit
c7547cb1d5
|
@ -18,7 +18,7 @@ keywords = ["ethereum", "web3", "solc", "solidity", "ethers"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false }
|
ethers-core = { version = "^1.0.0", path = "../ethers-core", default-features = false }
|
||||||
serde_json = "1.0.68"
|
serde_json = "1.0.68"
|
||||||
serde = { version = "1.0.130", features = ["derive"] }
|
serde = { version = "1.0.130", features = ["derive", "rc"] }
|
||||||
semver = { version = "1.0.16", features = ["serde"] }
|
semver = { version = "1.0.16", features = ["serde"] }
|
||||||
walkdir = "2.3.2"
|
walkdir = "2.3.2"
|
||||||
tokio = { version = "1.18", default-features = false, features = ["rt"] }
|
tokio = { version = "1.18", default-features = false, features = ["rt"] }
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::{
|
||||||
fmt, fs,
|
fmt, fs,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use tracing::warn;
|
use tracing::warn;
|
||||||
use yansi::Paint;
|
use yansi::Paint;
|
||||||
|
@ -1195,16 +1196,29 @@ pub struct DocLibraries {
|
||||||
pub libs: BTreeMap<String, serde_json::Value>,
|
pub libs: BTreeMap<String, serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Content of a solidity file
|
||||||
|
///
|
||||||
|
/// This contains the actual source code of a file
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
pub struct Source {
|
pub struct Source {
|
||||||
pub content: String,
|
/// Content of the file
|
||||||
|
///
|
||||||
|
/// This is an `Arc` because it may be cloned. If the [Graph](crate::resolver::Graph) of the
|
||||||
|
/// project contains multiple conflicting versions then the same [Source] may be required by
|
||||||
|
/// conflicting versions and needs to be duplicated.
|
||||||
|
pub content: Arc<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Source {
|
impl Source {
|
||||||
/// Reads the file content
|
/// Creates a new instance of [Source] with the given content.
|
||||||
|
pub fn new(content: impl Into<String>) -> Self {
|
||||||
|
Self { content: Arc::new(content.into()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the file's content
|
||||||
pub fn read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
|
pub fn read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
|
||||||
let file = file.as_ref();
|
let file = file.as_ref();
|
||||||
Ok(Self { content: fs::read_to_string(file).map_err(|err| SolcIoError::new(err, file))? })
|
Ok(Self::new(fs::read_to_string(file).map_err(|err| SolcIoError::new(err, file))?))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively finds all source files under the given dir path and reads them all
|
/// Recursively finds all source files under the given dir path and reads them all
|
||||||
|
@ -1254,7 +1268,7 @@ impl Source {
|
||||||
/// Generate a non-cryptographically secure checksum of the file's content
|
/// Generate a non-cryptographically secure checksum of the file's content
|
||||||
pub fn content_hash(&self) -> String {
|
pub fn content_hash(&self) -> String {
|
||||||
let mut hasher = md5::Md5::new();
|
let mut hasher = md5::Md5::new();
|
||||||
hasher.update(&self.content);
|
hasher.update(self);
|
||||||
let result = hasher.finalize();
|
let result = hasher.finalize();
|
||||||
hex::encode(result)
|
hex::encode(result)
|
||||||
}
|
}
|
||||||
|
@ -1270,11 +1284,9 @@ impl Source {
|
||||||
/// async version of `Self::read`
|
/// async version of `Self::read`
|
||||||
pub async fn async_read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
|
pub async fn async_read(file: impl AsRef<Path>) -> Result<Self, SolcIoError> {
|
||||||
let file = file.as_ref();
|
let file = file.as_ref();
|
||||||
Ok(Self {
|
Ok(Self::new(
|
||||||
content: tokio::fs::read_to_string(file)
|
tokio::fs::read_to_string(file).await.map_err(|err| SolcIoError::new(err, file))?,
|
||||||
.await
|
))
|
||||||
.map_err(|err| SolcIoError::new(err, file))?,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds all source files under the given dir path and reads them all
|
/// Finds all source files under the given dir path and reads them all
|
||||||
|
@ -1306,6 +1318,12 @@ impl AsRef<str> for Source {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for Source {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
self.content.as_bytes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Output type `solc` produces
|
/// Output type `solc` produces
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Default)]
|
||||||
pub struct CompilerOutput {
|
pub struct CompilerOutput {
|
||||||
|
|
|
@ -104,7 +104,7 @@ mod tests {
|
||||||
fn build_info_serde() {
|
fn build_info_serde() {
|
||||||
let inputs = CompilerInput::with_sources(BTreeMap::from([(
|
let inputs = CompilerInput::with_sources(BTreeMap::from([(
|
||||||
PathBuf::from("input.sol"),
|
PathBuf::from("input.sol"),
|
||||||
Source { content: "".to_string() },
|
Source::new(""),
|
||||||
)]));
|
)]));
|
||||||
let output = CompilerOutput::default();
|
let output = CompilerOutput::default();
|
||||||
let v: Version = "0.8.4+commit.c7e474f2".parse().unwrap();
|
let v: Version = "0.8.4+commit.c7e474f2".parse().unwrap();
|
||||||
|
|
|
@ -909,6 +909,6 @@ mod tests {
|
||||||
///// helpers
|
///// helpers
|
||||||
|
|
||||||
fn source(version: &str) -> Source {
|
fn source(version: &str) -> Source {
|
||||||
Source { content: format!("pragma solidity {version};\n") }
|
Source::new(format!("pragma solidity {version};\n"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue