Skip to content

Commit 451bca6

Browse files
DaniPopesmikelodder7
authored andcommitted
chore: avoid cloning CompileOutput to parse inline config (foundry-rs#5683)
* chore: avoid cloning `CompileOutput` to parse inline config * chore: clippy * use new solc methods * chore: bump ethers * chore: clippy * fmt
1 parent b999e3b commit 451bca6

File tree

6 files changed

+93
-145
lines changed

6 files changed

+93
-145
lines changed

Cargo.lock

Lines changed: 11 additions & 11 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/config/src/inline/conf_parser.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,8 @@ where
7171
fn validate_configs(natspec: &NatSpec) -> Result<(), InlineConfigError> {
7272
let config_key = Self::config_key();
7373

74-
let configs = natspec
75-
.config_lines()
76-
.into_iter()
77-
.filter(|l| l.contains(&config_key))
78-
.collect::<Vec<String>>();
74+
let configs =
75+
natspec.config_lines().filter(|l| l.contains(&config_key)).collect::<Vec<String>>();
7976

8077
Self::default().try_merge(&configs).map_err(|e| {
8178
let line = natspec.debug_context();

crates/config/src/inline/natspec.rs

Lines changed: 26 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
use std::{collections::BTreeMap, path::Path};
2-
1+
use super::{remove_whitespaces, INLINE_CONFIG_PREFIX, INLINE_CONFIG_PREFIX_SELECTED_PROFILE};
32
use ethers_solc::{
43
artifacts::{ast::NodeType, Node},
54
ProjectCompileOutput,
65
};
76
use serde_json::Value;
8-
9-
use super::{remove_whitespaces, INLINE_CONFIG_PREFIX, INLINE_CONFIG_PREFIX_SELECTED_PROFILE};
7+
use std::{collections::BTreeMap, path::Path};
108

119
/// Convenient struct to hold in-line per-test configurations
1210
pub struct NatSpec {
@@ -26,21 +24,19 @@ impl NatSpec {
2624
/// Factory function that extracts a vector of [`NatSpec`] instances from
2725
/// a solc compiler output. The root path is to express contract base dirs.
2826
/// That is essential to match per-test configs at runtime.
29-
pub fn parse<P>(output: &ProjectCompileOutput, root: &P) -> Vec<Self>
30-
where
31-
P: AsRef<Path>,
32-
{
27+
pub fn parse(output: &ProjectCompileOutput, root: &Path) -> Vec<Self> {
3328
let mut natspecs: Vec<Self> = vec![];
3429

35-
let output = output.clone();
36-
for artifact in output.with_stripped_file_prefixes(root).into_artifacts() {
37-
if let Some(ast) = artifact.1.ast.as_ref() {
38-
let contract: String = artifact.0.identifier();
39-
if let Some(node) = contract_root_node(&ast.nodes, &contract) {
40-
apply(&mut natspecs, &contract, node)
41-
}
42-
}
30+
for (id, artifact) in output.artifact_ids() {
31+
let Some(ast) = &artifact.ast else { continue };
32+
let path = id.source.as_path();
33+
let path = path.strip_prefix(root).unwrap_or(path);
34+
// id.identifier
35+
let contract = format!("{}:{}", path.display(), id.name);
36+
let Some(node) = contract_root_node(&ast.nodes, &contract) else { continue };
37+
apply(&mut natspecs, &contract, node)
4338
}
39+
4440
natspecs
4541
}
4642

@@ -52,24 +48,21 @@ impl NatSpec {
5248
}
5349

5450
/// Returns a list of configuration lines that match the current profile
55-
pub fn current_profile_configs(&self) -> Vec<String> {
56-
let prefix: &str = INLINE_CONFIG_PREFIX_SELECTED_PROFILE.as_ref();
57-
self.config_lines_with_prefix(prefix)
51+
pub fn current_profile_configs(&self) -> impl Iterator<Item = String> + '_ {
52+
self.config_lines_with_prefix(INLINE_CONFIG_PREFIX_SELECTED_PROFILE.as_str())
5853
}
5954

6055
/// Returns a list of configuration lines that match a specific string prefix
61-
pub fn config_lines_with_prefix<S: Into<String>>(&self, prefix: S) -> Vec<String> {
62-
let prefix: String = prefix.into();
63-
self.config_lines().into_iter().filter(|l| l.starts_with(&prefix)).collect()
56+
pub fn config_lines_with_prefix<'a>(
57+
&'a self,
58+
prefix: &'a str,
59+
) -> impl Iterator<Item = String> + 'a {
60+
self.config_lines().filter(move |l| l.starts_with(prefix))
6461
}
6562

6663
/// Returns a list of all the configuration lines available in the natspec
67-
pub fn config_lines(&self) -> Vec<String> {
68-
self.docs
69-
.split('\n')
70-
.map(remove_whitespaces)
71-
.filter(|line| line.contains(INLINE_CONFIG_PREFIX))
72-
.collect::<Vec<String>>()
64+
pub fn config_lines(&self) -> impl Iterator<Item = String> + '_ {
65+
self.docs.lines().map(remove_whitespaces).filter(|line| line.contains(INLINE_CONFIG_PREFIX))
7366
}
7467
}
7568

@@ -137,7 +130,7 @@ fn get_fn_docs(fn_data: &BTreeMap<String, Value>) -> Option<(String, String)> {
137130
let mut src_line = fn_docs
138131
.get("src")
139132
.map(|src| src.to_string())
140-
.unwrap_or(String::from("<no-src-line-available>"));
133+
.unwrap_or_else(|| String::from("<no-src-line-available>"));
141134

142135
src_line.retain(|c| c != '"');
143136
return Some((comment.into(), src_line))
@@ -158,7 +151,7 @@ mod tests {
158151
let natspec = natspec();
159152
let config_lines = natspec.config_lines();
160153
assert_eq!(
161-
config_lines,
154+
config_lines.collect::<Vec<_>>(),
162155
vec![
163156
"forge-config:default.fuzz.runs=600".to_string(),
164157
"forge-config:ci.fuzz.runs=500".to_string(),
@@ -173,7 +166,7 @@ mod tests {
173166
let config_lines = natspec.current_profile_configs();
174167

175168
assert_eq!(
176-
config_lines,
169+
config_lines.collect::<Vec<_>>(),
177170
vec![
178171
"forge-config:default.fuzz.runs=600".to_string(),
179172
"forge-config:default.invariant.runs=1".to_string()
@@ -186,9 +179,9 @@ mod tests {
186179
use super::INLINE_CONFIG_PREFIX;
187180
let natspec = natspec();
188181
let prefix = format!("{INLINE_CONFIG_PREFIX}:default");
189-
let config_lines = natspec.config_lines_with_prefix(prefix);
182+
let config_lines = natspec.config_lines_with_prefix(&prefix);
190183
assert_eq!(
191-
config_lines,
184+
config_lines.collect::<Vec<_>>(),
192185
vec![
193186
"forge-config:default.fuzz.runs=600".to_string(),
194187
"forge-config:default.invariant.runs=1".to_string()

crates/forge/bin/cmd/test/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,8 @@ impl TestArgs {
165165
let test_options: TestOptions = TestOptionsBuilder::default()
166166
.fuzz(config.fuzz)
167167
.invariant(config.invariant)
168-
.compile_output(&output)
169168
.profiles(profiles)
170-
.build(project_root)?;
169+
.build(&output, project_root)?;
171170

172171
// Determine print verbosity and executor verbosity
173172
let verbosity = evm_opts.verbosity;

0 commit comments

Comments
 (0)