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

Commit

Permalink
feat: config refactor, read evm_version from foundry.toml
Browse files Browse the repository at this point in the history
  • Loading branch information
Maddiaa0 committed May 27, 2023
1 parent cade7c8 commit a5bb0c2
Show file tree
Hide file tree
Showing 10 changed files with 250 additions and 195 deletions.
1 change: 1 addition & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ optimizer = true
remappings = [
"examples/=huff-examples/",
]
evm_version = "paris"
6 changes: 5 additions & 1 deletion huff_cli/src/huffc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use huff_tests::{
HuffTester,
};
use huff_utils::{
config::HuffConfig,
file_provider::FileSystemFileProvider,
prelude::{
export_interfaces, gen_sol_interfaces, str_to_bytes32, unpack_files, AstSpan, BytecodeRes,
Expand Down Expand Up @@ -183,6 +184,9 @@ fn main() {
.collect()
});

// Parse external config
let config = HuffConfig::new("./");

// Parse the EVM version
let evm_version = EVMVersion::from(cli.evm_version);

Expand All @@ -205,7 +209,7 @@ fn main() {
};

let compiler: Compiler = Compiler {
evm_version: &evm_version,
huff_config: config,
sources: Arc::clone(&sources),
output,
alternative_main: cli.alternative_main.clone(),
Expand Down
44 changes: 21 additions & 23 deletions huff_core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ use huff_parser::*;
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
use huff_utils::wasm::IntoParallelIterator;
use huff_utils::{
config::HuffConfig,
file_provider::{FileProvider, FileSystemFileProvider, InMemoryFileProvider},
prelude::*,
remapper::Remapper,
time,
};
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
Expand Down Expand Up @@ -59,9 +61,9 @@ pub(crate) mod cache;
/// );
/// ```
#[derive(Debug, Clone)]
pub struct Compiler<'a, 'l> {
/// The EVM version to compile for
pub evm_version: &'l EVMVersion,
pub struct Compiler<'a> {
/// Huff Config
pub huff_config: HuffConfig,
/// The location of the files to compile
pub sources: Arc<Vec<String>>,
/// The output location
Expand All @@ -84,11 +86,11 @@ pub struct Compiler<'a, 'l> {
pub file_provider: Arc<dyn FileProvider<'a>>,
}

impl<'a, 'l> Compiler<'a, 'l> {
impl<'a> Compiler<'a> {
/// Public associated function to instantiate a new compiler.
#[allow(clippy::too_many_arguments)]
pub fn new(
evm_version: &'l EVMVersion,
huff_config: HuffConfig,
sources: Arc<Vec<String>>,
output: Option<String>,
alternative_main: Option<String>,
Expand All @@ -102,7 +104,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()]));
}
Self {
evm_version,
huff_config,
sources,
output,
alternative_main,
Expand All @@ -120,7 +122,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
/// map.
#[allow(clippy::too_many_arguments)]
pub fn new_in_memory(
evm_version: &'l EVMVersion,
evm_version: &EVMVersion,
sources: Arc<Vec<String>>,
file_sources: HashMap<String, String>,
alternative_main: Option<String>,
Expand All @@ -132,8 +134,9 @@ impl<'a, 'l> Compiler<'a, 'l> {
if cfg!(feature = "verbose") || verbose {
Compiler::init_tracing_subscriber(Some(vec![tracing::Level::INFO.into()]));
}
let huff_config = HuffConfig::from_evm_version(evm_version.clone());
Self {
evm_version,
huff_config,
sources,
output: None,
alternative_main,
Expand Down Expand Up @@ -226,7 +229,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
let recursed_file_sources: Vec<Result<Arc<FileSource>, Arc<CompilerError>>> = files
.into_par_iter()
.map(|v| {
Self::recurse_deps(v, &Remapper::new("./"), self.file_provider.clone())
Self::recurse_deps(v, self.huff_config.clone(), self.file_provider.clone())
})
.collect();

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

let recursed_file_sources: Vec<Result<Arc<FileSource>, Arc<CompilerError>>> = files
.into_par_iter()
.map(|f| {
Self::recurse_deps(
f,
&huff_utils::files::Remapper::new("./"),
self.file_provider.clone(),
)
})
.map(|f| Self::recurse_deps(f, self.huff_config.clone(), self.file_provider.clone()))
.collect();

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

// Parser incantation
let mut parser = Parser::new(tokens, Some(file.path.clone()));
let mut parser =
Parser::new(self.huff_config.clone(), tokens, Some(file.path.clone()));

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

// Parser incantation
let mut parser = Parser::new(tokens, Some(file.path.clone()));
let mut parser = Parser::new(self.huff_config.clone(), tokens, Some(file.path.clone()));

// Parse into an AST
let parse_res = parser.parse().map_err(CompilerError::ParserError);
Expand All @@ -408,7 +406,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
// Primary Bytecode Generation
let mut cg = Codegen::new();
let main_bytecode = match Codegen::generate_main_bytecode(
self.evm_version,
&self.huff_config.evm_version,
&contract,
self.alternative_main.clone(),
) {
Expand Down Expand Up @@ -436,7 +434,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
let inputs = self.get_constructor_args();
let (constructor_bytecode, has_custom_bootstrap) =
match Codegen::generate_constructor_bytecode(
self.evm_version,
&self.huff_config.evm_version,
&contract,
self.alternative_constructor.clone(),
) {
Expand Down Expand Up @@ -515,7 +513,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
/// Recurses file dependencies
pub fn recurse_deps(
fs: Arc<FileSource>,
remapper: &Remapper,
config: HuffConfig,
reader: Arc<dyn FileProvider<'a>>,
) -> Result<Arc<FileSource>, Arc<CompilerError>> {
tracing::debug!(target: "core", "RECURSING DEPENDENCIES FOR {}", fs.path);
Expand Down Expand Up @@ -544,7 +542,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
.into_iter()
.map(|mut import| {
// Check for foundry toml remappings
match remapper.remap(&import) {
match config.remap(&import) {
Some(remapped) => {
tracing::debug!(target: "core", "REMAPPED IMPORT PATH \"{}\"", import);
import = remapped;
Expand Down Expand Up @@ -575,7 +573,7 @@ impl<'a, 'l> Compiler<'a, 'l> {
// Now that we have all the file sources, we have to recurse and get their source
file_sources = file_sources
.into_par_iter()
.map(|inner_fs| match Self::recurse_deps(Arc::clone(&inner_fs), remapper, reader.clone()) {
.map(|inner_fs| match Self::recurse_deps(Arc::clone(&inner_fs), config.clone(), reader.clone()) {
Ok(new_fs) => new_fs,
Err(e) => {
tracing::error!(target: "core", "NESTED DEPENDENCY RESOLUTION FAILED: \"{:?}\"", e);
Expand Down
12 changes: 6 additions & 6 deletions huff_parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

use huff_utils::{
ast::*,
config::HuffConfig,
error::*,
files,
prelude::{bytes32_to_string, hash_bytes, str_to_bytes32, Span},
remapper::Remapper,
token::{Token, TokenKind},
types::*,
};
Expand All @@ -17,6 +18,8 @@ use regex::Regex;
/// The Parser
#[derive(Debug, Clone)]
pub struct Parser {
/// Config
pub config: HuffConfig,
/// Vector of the tokens
pub tokens: Vec<Token>,
/// Current position
Expand All @@ -27,16 +30,13 @@ pub struct Parser {
pub base: Option<String>,
/// A collection of current spans
pub spans: Vec<Span>,
/// Our remapper
pub remapper: files::Remapper,
}

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

/// Resets the current token and cursor to the first token in the parser's token vec
Expand Down
71 changes: 71 additions & 0 deletions huff_utils/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::{collections::HashMap, fs::read_to_string, path::PathBuf};

use crate::{evm_version::EVMVersion, foundry::FoundryConfig, remapper::Remapper};

/// Stores external configuration options, such as remappings and evm version.

#[derive(Debug, Default, Clone)]
pub struct HuffConfig {
pub base_dir: String,
pub evm_version: EVMVersion,
pub remappings: HashMap<String, String>,
}

impl HuffConfig {
pub fn new(root: impl AsRef<str>) -> Self {
let base_dir = root.as_ref().to_string();

// Parse foundry config and remappings
let foundry_config = FoundryConfig::new(&base_dir);
let file_remappings = remappings_from_file(&base_dir);

let mut remappings = HashMap::<String, String>::new();
remappings.extend(file_remappings);
remappings.extend(foundry_config.remappings);

let evm_version = EVMVersion::from(foundry_config.evm_version);

HuffConfig { base_dir, evm_version, remappings }
}

pub fn from_evm_version(evm_version: EVMVersion) -> Self {
HuffConfig { base_dir: "".to_string(), evm_version, remappings: HashMap::new() }
}
}

impl Remapper for HuffConfig {
/// Tries to replace path segments in a string with our remappings
fn remap(&self, path: &str) -> Option<String> {
let mut path = path.to_string();
for (k, v) in self.remappings.iter() {
if path.starts_with(k) {
tracing::debug!(target: "parser", "found key {} and value {}", k, v);
path = path.replace(k, v);
return Some(format!("{}{path}", self.base_dir))
}
}
None
}
}

// Read remappings from remappings.txt
fn remappings_from_file(root: &str) -> HashMap<String, String> {
let mut remappings: HashMap<String, String> = HashMap::new();
let remappings_file = PathBuf::new().join(root).join("remappings.txt");
if remappings_file.is_file() {
let content = read_to_string(remappings_file).map_err(|err| err.to_string()).unwrap();

let rem_lines = content.split('\n').collect::<Vec<&str>>();
let rem = rem_lines
.iter()
.filter(|l| l != &&"")
.map(|l| l.split_once('='))
.collect::<Vec<Option<(&str, &str)>>>();
rem.iter().for_each(|pair| {
if let Some((lib, path)) = pair {
remappings.insert(lib.to_string(), path.to_string());
}
});
}
remappings
}
4 changes: 2 additions & 2 deletions huff_utils/src/evm_version.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use std::cmp::PartialOrd;
///
/// Determines which features will be available when compiling.

#[derive(Debug, PartialEq, PartialOrd)]
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub enum SupportedEVMVersions {
/// Introduced prevrandao, disallow difficulty opcode (does not affect codegen)
Paris,
/// Introduce Push0, compiler will use by default
Shanghai,
}

#[derive(Debug)]
#[derive(Debug, Clone)]
/// EVM Version
pub struct EVMVersion {
version: SupportedEVMVersions,
Expand Down
Loading

0 comments on commit a5bb0c2

Please sign in to comment.