Skip to content

Commit

Permalink
[wip] feat: compilation restrictions
Browse files Browse the repository at this point in the history
  • Loading branch information
klkvr committed Sep 23, 2024
1 parent 07a1f67 commit ecb767d
Show file tree
Hide file tree
Showing 11 changed files with 194 additions and 56 deletions.
53 changes: 24 additions & 29 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ foundry-linking = { path = "crates/linking" }

# solc & compilation utilities
foundry-block-explorers = { version = "0.7.3", default-features = false }
foundry-compilers = { version = "0.11.1", default-features = false }
foundry-compilers = { version = "0.11", default-features = false }
foundry-fork-db = "0.3"
solang-parser = "=0.3.3"

Expand Down Expand Up @@ -276,7 +276,7 @@ soldeer = "=0.3.4"
proptest = "1"
comfy-table = "7"

# [patch.crates-io]
[patch.crates-io]
# alloy-consensus = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
# alloy-contract = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
# alloy-eips = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
Expand All @@ -300,3 +300,4 @@ comfy-table = "7"
# alloy-transport-http = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
# alloy-transport-ipc = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
# alloy-transport-ws = { git = "https://github.com/alloy-rs/alloy", rev = "7fab7ee" }
foundry-compilers = { git = "https://github.com/foundry-rs/compilers", rev = "5b42d05" }
4 changes: 2 additions & 2 deletions crates/cast/bin/cmd/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use foundry_compilers::{
artifacts::{ConfigurableContractArtifact, StorageLayout},
compilers::{
solc::{Solc, SolcCompiler},
Compiler, CompilerSettings,
Compiler,
},
Artifact, Project,
};
Expand Down Expand Up @@ -288,7 +288,7 @@ fn print_storage(layout: StorageLayout, values: Vec<StorageValue>, pretty: bool)

fn add_storage_layout_output<C: Compiler>(project: &mut Project<C>) {
project.artifacts.additional_values.storage_layout = true;
project.settings.update_output_selection(|selection| {
project.update_output_selection(|selection| {
selection.0.values_mut().for_each(|contract_selection| {
contract_selection
.values_mut()
Expand Down
76 changes: 76 additions & 0 deletions crates/config/src/compilation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use crate::{filter::GlobMatcher, serde_helpers};
use foundry_compilers::{
artifacts::EvmVersion,
multi::{MultiCompilerRestrictions, MultiCompilerSettings},
settings::VyperRestrictions,
solc::{EvmVersionRestriction, SolcRestrictions},
RestrictionsWithVersion,
};
use semver::VersionReq;
use serde::{Deserialize, Serialize};

/// Keeps possible overrides for default settings which users may configure to construct additional
/// settings profile.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SettingsOverrides {
pub name: String,
via_ir: Option<bool>,
#[serde(default, with = "serde_helpers::display_from_str_opt")]
evm_version: Option<EvmVersion>,
optimizer: Option<bool>,
optimizer_runs: Option<usize>,
}

impl SettingsOverrides {
/// Applies the overrides to the given settings.
pub fn apply(&self, settings: &mut MultiCompilerSettings) {
if let Some(via_ir) = self.via_ir {
settings.solc.via_ir = Some(via_ir);
}

if let Some(evm_version) = self.evm_version {
settings.solc.evm_version = Some(evm_version);
settings.vyper.evm_version = Some(evm_version);
}

if let Some(enabled) = self.optimizer {
settings.solc.optimizer.enabled = Some(enabled);
}

if let Some(optimizer_runs) = self.optimizer_runs {
settings.solc.optimizer.runs = Some(optimizer_runs);
}
}
}

/// Restrictions for compilation of given paths.
///
/// Only purpose of this type is to accept user input to later construct
/// `RestrictionsWithVersion<MultiCompilerRestrictions>`.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct CompilationRestrictions {
pub paths: GlobMatcher,
version: Option<VersionReq>,
via_ir: Option<bool>,
min_optimizer_runs: Option<usize>,
max_optimizer_runs: Option<usize>,
#[serde(flatten)]
evm_version: EvmVersionRestriction,
}

impl From<CompilationRestrictions> for RestrictionsWithVersion<MultiCompilerRestrictions> {
fn from(value: CompilationRestrictions) -> Self {
Self {
restrictions: MultiCompilerRestrictions {
solc: SolcRestrictions {
evm_version: value.evm_version,
via_ir: value.via_ir,
min_optimizer_runs: value.min_optimizer_runs,
max_optimizer_runs: value.max_optimizer_runs,
},
vyper: VyperRestrictions { evm_version: value.evm_version },
},
version: value.version,
}
}
}
76 changes: 72 additions & 4 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ use foundry_compilers::{
Compiler,
},
error::SolcError,
multi::{MultiCompilerParsedSource, MultiCompilerRestrictions},
solc::{CliSettings, SolcSettings},
ConfigurableArtifacts, Project, ProjectPathsConfig, VyperLanguage,
ConfigurableArtifacts, Graph, Project, ProjectPathsConfig, RestrictionsWithVersion,
VyperLanguage,
};
use inflector::Inflector;
use regex::Regex;
Expand All @@ -43,7 +45,7 @@ use semver::Version;
use serde::{Deserialize, Serialize, Serializer};
use std::{
borrow::Cow,
collections::HashMap,
collections::{BTreeMap, HashMap},
fs,
path::{Path, PathBuf},
str::FromStr,
Expand Down Expand Up @@ -115,6 +117,9 @@ use vyper::VyperConfig;
mod bind_json;
use bind_json::BindJsonConfig;

mod compilation;
use compilation::{CompilationRestrictions, SettingsOverrides};

/// Foundry configuration
///
/// # Defaults
Expand Down Expand Up @@ -469,6 +474,14 @@ pub struct Config {
#[serde(rename = "__warnings", default, skip_serializing)]
pub warnings: Vec<Warning>,

/// Additional settings profiles to use when compiling.
#[serde(default)]
pub additional_compiler_profiles: Vec<SettingsOverrides>,

/// Restrictions on compilation of certain files.
#[serde(default)]
pub compilation_restrictions: Vec<CompilationRestrictions>,

/// PRIVATE: This structure may grow, As such, constructing this structure should
/// _always_ be done using a public constructor or update syntax:
///
Expand Down Expand Up @@ -835,12 +848,65 @@ impl Config {
self.create_project(false, true)
}

/// Builds mapping with additional settings profiles.
fn additional_settings(
&self,
base: &MultiCompilerSettings,
) -> BTreeMap<String, MultiCompilerSettings> {
let mut map = BTreeMap::new();

for profile in &self.additional_compiler_profiles {
let mut settings = base.clone();
profile.apply(&mut settings);
map.insert(profile.name.clone(), settings);
}

map
}

/// Resolves globs and builds a mapping from individual source files to their restrictions
fn restrictions(
&self,
paths: &ProjectPathsConfig,
) -> Result<BTreeMap<PathBuf, RestrictionsWithVersion<MultiCompilerRestrictions>>, SolcError>
{
let mut map = BTreeMap::new();

let graph = Graph::<MultiCompilerParsedSource>::resolve(paths)?;
let (sources, _) = graph.into_sources();

for res in &self.compilation_restrictions {
for source in sources.keys().filter(|path| {
if res.paths.is_match(path) {
true
} else if let Ok(path) = path.strip_prefix(&paths.root) {
res.paths.is_match(path)
} else {
false
}
}) {
let res: RestrictionsWithVersion<_> = res.clone().into();
if !map.contains_key(source) {
map.insert(source.clone(), res);
} else {
map.get_mut(source.as_path()).unwrap().merge(res);
}
}
}

Ok(map)
}

/// Creates a [Project] with the given `cached` and `no_artifacts` flags
pub fn create_project(&self, cached: bool, no_artifacts: bool) -> Result<Project, SolcError> {
let settings = self.compiler_settings()?;
let paths = self.project_paths();
let mut builder = Project::builder()
.artifacts(self.configured_artifacts_handler())
.paths(self.project_paths())
.settings(self.compiler_settings()?)
.additional_settings(self.additional_settings(&settings))
.restrictions(self.restrictions(&paths)?)
.settings(settings)
.paths(paths)
.ignore_error_codes(self.ignored_error_codes.iter().copied().map(Into::into))
.ignore_paths(self.ignored_file_paths.clone())
.set_compiler_severity_filter(if self.deny_warnings {
Expand Down Expand Up @@ -2182,6 +2248,8 @@ impl Default for Config {
eof_version: None,
alphanet: false,
transaction_timeout: 120,
additional_compiler_profiles: Default::default(),
compilation_restrictions: vec![],
_non_exhaustive: (),
}
}
Expand Down
Loading

0 comments on commit ecb767d

Please sign in to comment.