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

Commit c2f969f

Browse files
committed
feat: config refactor, read evm_version from foundry.toml
1 parent a7403c9 commit c2f969f

File tree

10 files changed

+250
-195
lines changed

10 files changed

+250
-195
lines changed

foundry.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ optimizer = true
33
remappings = [
44
"examples/=huff-examples/",
55
]
6+
evm_version = "paris"

huff_cli/src/huffc.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use huff_tests::{
1717
HuffTester,
1818
};
1919
use huff_utils::{
20+
config::HuffConfig,
2021
file_provider::FileSystemFileProvider,
2122
prelude::{
2223
export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, BytecodeRes,
@@ -190,6 +191,9 @@ fn main() {
190191
.collect()
191192
});
192193

194+
// Parse external config
195+
let config = HuffConfig::new("./");
196+
193197
// Parse the EVM version
194198
let evm_version = EVMVersion::from(cli.evm_version);
195199

@@ -212,7 +216,7 @@ fn main() {
212216
};
213217

214218
let compiler: Compiler = Compiler {
215-
evm_version: &evm_version,
219+
huff_config: config,
216220
sources: Arc::clone(&sources),
217221
output,
218222
alternative_main: cli.alternative_main.clone(),

huff_core/src/lib.rs

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ use huff_parser::*;
1111
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
1212
use huff_utils::wasm::IntoParallelIterator;
1313
use huff_utils::{
14+
config::HuffConfig,
1415
file_provider::{FileProvider, FileSystemFileProvider, InMemoryFileProvider},
1516
prelude::*,
17+
remapper::Remapper,
1618
time,
1719
};
1820
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
@@ -59,9 +61,9 @@ pub(crate) mod cache;
5961
/// );
6062
/// ```
6163
#[derive(Debug, Clone)]
62-
pub struct Compiler<'a, 'l> {
63-
/// The EVM version to compile for
64-
pub evm_version: &'l EVMVersion,
64+
pub struct Compiler<'a> {
65+
/// Huff Config
66+
pub huff_config: HuffConfig,
6567
/// The location of the files to compile
6668
pub sources: Arc<Vec<String>>,
6769
/// The output location
@@ -84,11 +86,11 @@ pub struct Compiler<'a, 'l> {
8486
pub file_provider: Arc<dyn FileProvider<'a>>,
8587
}
8688

87-
impl<'a, 'l> Compiler<'a, 'l> {
89+
impl<'a> Compiler<'a> {
8890
/// Public associated function to instantiate a new compiler.
8991
#[allow(clippy::too_many_arguments)]
9092
pub fn new(
91-
evm_version: &'l EVMVersion,
93+
huff_config: HuffConfig,
9294
sources: Arc<Vec<String>>,
9395
output: Option<String>,
9496
alternative_main: Option<String>,
@@ -102,7 +104,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
102104
Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()]));
103105
}
104106
Self {
105-
evm_version,
107+
huff_config,
106108
sources,
107109
output,
108110
alternative_main,
@@ -120,7 +122,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
120122
/// map.
121123
#[allow(clippy::too_many_arguments)]
122124
pub fn new_in_memory(
123-
evm_version: &'l EVMVersion,
125+
evm_version: &EVMVersion,
124126
sources: Arc<Vec<String>>,
125127
file_sources: HashMap<String, String>,
126128
alternative_main: Option<String>,
@@ -132,8 +134,9 @@ impl<'a, 'l> Compiler<'a, 'l> {
132134
if cfg!(feature = "verbose") || verbose {
133135
Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()]));
134136
}
137+
let huff_config = HuffConfig::from_evm_version(evm_version.clone());
135138
Self {
136-
evm_version,
139+
huff_config,
137140
sources,
138141
output: None,
139142
alternative_main,
@@ -226,7 +229,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
226229
let recursed_file_sources: Vec<Result<Arc<FileSource>, Arc<CompilerError>>> = files
227230
.into_par_iter()
228231
.map(|v| {
229-
Self::recurse_deps(v, &Remapper::new("./"), self.file_provider.clone())
232+
Self::recurse_deps(v, self.huff_config.clone(), self.file_provider.clone())
230233
})
231234
.collect();
232235

@@ -307,13 +310,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
307310

308311
let recursed_file_sources: Vec<Result<Arc<FileSource>, Arc<CompilerError>>> = files
309312
.into_par_iter()
310-
.map(|f| {
311-
Self::recurse_deps(
312-
f,
313-
&huff_utils::files::Remapper::new("./"),
314-
self.file_provider.clone(),
315-
)
316-
})
313+
.map(|f| Self::recurse_deps(f, self.huff_config.clone(), self.file_provider.clone()))
317314
.collect();
318315

319316
// Collect Recurse Deps errors and try to resolve to the first one
@@ -358,7 +355,8 @@ impl<'a, 'l> Compiler<'a, 'l> {
358355
tracing::info!(target: "core", "└─ TOKEN COUNT: {}", tokens.len());
359356

360357
// Parser incantation
361-
let mut parser = Parser::new(tokens, Some(file.path.clone()));
358+
let mut parser =
359+
Parser::new(self.huff_config.clone(), tokens, Some(file.path.clone()));
362360

363361
// Parse into an AST
364362
let parse_res = parser.parse().map_err(CompilerError::ParserError);
@@ -396,7 +394,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
396394
tracing::info!(target: "core", "└─ TOKEN COUNT: {}", tokens.len());
397395

398396
// Parser incantation
399-
let mut parser = Parser::new(tokens, Some(file.path.clone()));
397+
let mut parser = Parser::new(self.huff_config.clone(), tokens, Some(file.path.clone()));
400398

401399
// Parse into an AST
402400
let parse_res = parser.parse().map_err(CompilerError::ParserError);
@@ -408,7 +406,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
408406
// Primary Bytecode Generation
409407
let mut cg = Codegen::new();
410408
let main_bytecode = match Codegen::generate_main_bytecode(
411-
self.evm_version,
409+
&self.huff_config.evm_version,
412410
&contract,
413411
self.alternative_main.clone(),
414412
) {
@@ -436,7 +434,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
436434
let inputs = self.get_constructor_args();
437435
let (constructor_bytecode, has_custom_bootstrap) =
438436
match Codegen::generate_constructor_bytecode(
439-
self.evm_version,
437+
&self.huff_config.evm_version,
440438
&contract,
441439
self.alternative_constructor.clone(),
442440
) {
@@ -515,7 +513,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
515513
/// Recurses file dependencies
516514
pub fn recurse_deps(
517515
fs: Arc<FileSource>,
518-
remapper: &Remapper,
516+
config: HuffConfig,
519517
reader: Arc<dyn FileProvider<'a>>,
520518
) -> Result<Arc<FileSource>, Arc<CompilerError>> {
521519
tracing::debug!(target: "core", "RECURSING DEPENDENCIES FOR {}", fs.path);
@@ -544,7 +542,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
544542
.into_iter()
545543
.map(|mut import| {
546544
// Check for foundry toml remappings
547-
match remapper.remap(&import) {
545+
match config.remap(&import) {
548546
Some(remapped) => {
549547
tracing::debug!(target: "core", "REMAPPED IMPORT PATH \"{}\"", import);
550548
import = remapped;
@@ -575,7 +573,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
575573
// Now that we have all the file sources, we have to recurse and get their source
576574
file_sources = file_sources
577575
.into_par_iter()
578-
.map(|inner_fs| match Self::recurse_deps(Arc::clone(&inner_fs), remapper, reader.clone()) {
576+
.map(|inner_fs| match Self::recurse_deps(Arc::clone(&inner_fs), config.clone(), reader.clone()) {
579577
Ok(new_fs) => new_fs,
580578
Err(e) => {
581579
tracing::error!(target: "core", "NESTED DEPENDENCY RESOLUTION FAILED: \"{:?}\"", e);

huff_parser/src/lib.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66

77
use huff_utils::{
88
ast::*,
9+
config::HuffConfig,
910
error::*,
10-
files,
1111
prelude::{bytes32_to_string, hash_bytes, str_to_bytes32, Span},
12+
remapper::Remapper,
1213
token::{Token, TokenKind},
1314
types::*,
1415
};
@@ -17,6 +18,8 @@ use regex::Regex;
1718
/// The Parser
1819
#[derive(Debug, Clone)]
1920
pub struct Parser {
21+
/// Config
22+
pub config: HuffConfig,
2023
/// Vector of the tokens
2124
pub tokens: Vec<Token>,
2225
/// Current position
@@ -27,16 +30,13 @@ pub struct Parser {
2730
pub base: Option<String>,
2831
/// A collection of current spans
2932
pub spans: Vec<Span>,
30-
/// Our remapper
31-
pub remapper: files::Remapper,
3233
}
3334

3435
impl Parser {
3536
/// Public associated function that instantiates a Parser.
36-
pub fn new(tokens: Vec<Token>, base: Option<String>) -> Self {
37+
pub fn new(config: HuffConfig, tokens: Vec<Token>, base: Option<String>) -> Self {
3738
let initial_token = tokens.get(0).unwrap().clone();
38-
let remapper = files::Remapper::new("./");
39-
Self { tokens, cursor: 0, current_token: initial_token, base, spans: vec![], remapper }
39+
Self { config, tokens, cursor: 0, current_token: initial_token, base, spans: vec![] }
4040
}
4141

4242
/// Resets the current token and cursor to the first token in the parser's token vec

huff_utils/src/config.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
use std::{collections::HashMap, fs::read_to_string, path::PathBuf};
2+
3+
use crate::{evm_version::EVMVersion, foundry::FoundryConfig, remapper::Remapper};
4+
5+
/// Stores external configuration options, such as remappings and evm version.
6+
7+
#[derive(Debug, Default, Clone)]
8+
pub struct HuffConfig {
9+
pub base_dir: String,
10+
pub evm_version: EVMVersion,
11+
pub remappings: HashMap<String, String>,
12+
}
13+
14+
impl HuffConfig {
15+
pub fn new(root: impl AsRef<str>) -> Self {
16+
let base_dir = root.as_ref().to_string();
17+
18+
// Parse foundry config and remappings
19+
let foundry_config = FoundryConfig::new(&base_dir);
20+
let file_remappings = remappings_from_file(&base_dir);
21+
22+
let mut remappings = HashMap::<String, String>::new();
23+
remappings.extend(file_remappings);
24+
remappings.extend(foundry_config.remappings);
25+
26+
let evm_version = EVMVersion::from(foundry_config.evm_version);
27+
28+
HuffConfig { base_dir, evm_version, remappings }
29+
}
30+
31+
pub fn from_evm_version(evm_version: EVMVersion) -> Self {
32+
HuffConfig { base_dir: "".to_string(), evm_version, remappings: HashMap::new() }
33+
}
34+
}
35+
36+
impl Remapper for HuffConfig {
37+
/// Tries to replace path segments in a string with our remappings
38+
fn remap(&self, path: &str) -> Option<String> {
39+
let mut path = path.to_string();
40+
for (k, v) in self.remappings.iter() {
41+
if path.starts_with(k) {
42+
tracing::debug!(target: "parser", "found key {} and value {}", k, v);
43+
path = path.replace(k, v);
44+
return Some(format!("{}{path}", self.base_dir))
45+
}
46+
}
47+
None
48+
}
49+
}
50+
51+
// Read remappings from remappings.txt
52+
fn remappings_from_file(root: &str) -> HashMap<String, String> {
53+
let mut remappings: HashMap<String, String> = HashMap::new();
54+
let remappings_file = PathBuf::new().join(root).join("remappings.txt");
55+
if remappings_file.is_file() {
56+
let content = read_to_string(remappings_file).map_err(|err| err.to_string()).unwrap();
57+
58+
let rem_lines = content.split('\n').collect::<Vec<&str>>();
59+
let rem = rem_lines
60+
.iter()
61+
.filter(|l| l != &&"")
62+
.map(|l| l.split_once('='))
63+
.collect::<Vec<Option<(&str, &str)>>>();
64+
rem.iter().for_each(|pair| {
65+
if let Some((lib, path)) = pair {
66+
remappings.insert(lib.to_string(), path.to_string());
67+
}
68+
});
69+
}
70+
remappings
71+
}

huff_utils/src/evm_version.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ use std::cmp::PartialOrd;
44
///
55
/// Determines which features will be available when compiling.
66
7-
#[derive(Debug, PartialEq, PartialOrd)]
7+
#[derive(Clone, Debug, PartialEq, PartialOrd)]
88
pub enum SupportedEVMVersions {
99
/// Introduced prevrandao, disallow difficulty opcode (does not affect codegen)
1010
Paris,
1111
/// Introduce Push0, compiler will use by default
1212
Shanghai,
1313
}
1414

15-
#[derive(Debug)]
15+
#[derive(Debug, Clone)]
1616
/// EVM Version
1717
pub struct EVMVersion {
1818
version: SupportedEVMVersions,

0 commit comments

Comments
 (0)