Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow passing extra cli args to solc + some cleanup #171

Merged
merged 6 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 12 additions & 17 deletions crates/artifacts/solc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,12 +133,12 @@ impl SolcInput {
/// This will remove/adjust values in the [`SolcInput`] that are not compatible with this
/// version
pub fn sanitize(&mut self, version: &Version) {
self.settings.sanitize(version)
self.settings.sanitize(version, self.language);
}

/// Consumes the type and returns a [SolcInput::sanitized] version
pub fn sanitized(mut self, version: &Version) -> Self {
self.settings.sanitize(version);
self.settings.sanitize(version, self.language);
self
}

Expand Down Expand Up @@ -178,18 +178,6 @@ impl SolcInput {
pub fn is_yul(&self) -> bool {
self.language == SolcLanguage::Yul
}

pub fn with_remappings(mut self, remappings: Vec<Remapping>) -> Self {
if self.language == SolcLanguage::Yul {
if !remappings.is_empty() {
warn!("omitting remappings supplied for the yul sources");
}
} else {
self.settings.remappings = remappings;
}

self
}
}

/// A `CompilerInput` representation used for verify
Expand Down Expand Up @@ -292,13 +280,13 @@ impl Settings {
}

/// Consumes the type and returns a [Settings::sanitize] version
pub fn sanitized(mut self, version: &Version) -> Self {
self.sanitize(version);
pub fn sanitized(mut self, version: &Version, language: SolcLanguage) -> Self {
self.sanitize(version, language);
self
}

/// This will remove/adjust values in the settings that are not compatible with this version.
pub fn sanitize(&mut self, version: &Version) {
pub fn sanitize(&mut self, version: &Version, language: SolcLanguage) {
const V0_6_0: Version = Version::new(0, 6, 0);
if *version < V0_6_0 {
if let Some(meta) = &mut self.metadata {
Expand Down Expand Up @@ -364,6 +352,13 @@ impl Settings {
if let Some(ref mut evm_version) = self.evm_version {
self.evm_version = evm_version.normalize_version_solc(version);
}

if language == SolcLanguage::Yul {
if !self.remappings.is_empty() {
warn!("omitting remappings supplied for the yul sources");
}
self.remappings = Vec::new();
}
}

/// Inserts a set of `ContractOutputSelection`
Expand Down
1 change: 1 addition & 0 deletions crates/artifacts/vyper/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ foundry-compilers-core.workspace = true
serde.workspace = true
alloy-primitives.workspace = true
alloy-json-abi.workspace = true
semver.workspace = true

[target.'cfg(windows)'.dependencies]
path-slash.workspace = true
Expand Down
13 changes: 13 additions & 0 deletions crates/artifacts/vyper/src/input.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::VyperSettings;
use foundry_compilers_artifacts_solc::sources::Sources;
use foundry_compilers_core::utils::strip_prefix_owned;
use semver::Version;
use serde::{Deserialize, Serialize};
use std::path::Path;

Expand Down Expand Up @@ -47,4 +48,16 @@ impl VyperInput {

self.settings.strip_prefix(base)
}

/// This will remove/adjust values in the [`VyperInput`] that are not compatible with this
/// version
pub fn sanitize(&mut self, version: &Version) {
self.settings.sanitize(version);
}

/// Consumes the type and returns a [VyperInput::sanitized] version
pub fn sanitized(mut self, version: &Version) -> Self {
self.sanitize(version);
self
}
}
18 changes: 18 additions & 0 deletions crates/artifacts/vyper/src/settings.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use foundry_compilers_artifacts_solc::{
output_selection::OutputSelection, serde_helpers, EvmVersion,
};
use semver::Version;
use serde::{Deserialize, Serialize};
use std::{
collections::BTreeSet,
path::{Path, PathBuf},
};

pub const VYPER_SEARCH_PATHS: Version = Version::new(0, 4, 0);

#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum VyperOptimizationMode {
Expand Down Expand Up @@ -68,4 +71,19 @@ impl VyperSettings {
})
});
}

/// Sanitize the settings based on the compiler version.
pub fn sanitize(&mut self, version: &Version) {
if version < &VYPER_SEARCH_PATHS {
self.search_paths = None;
}

self.sanitize_output_selection();
}

/// Sanitize the settings based on the compiler version.
pub fn sanitized(mut self, version: &Version) -> Self {
self.sanitize(version);
self
}
}
29 changes: 12 additions & 17 deletions crates/compilers/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::Settings, cache::CompilerCache, Project};
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
/// let project = Project::builder().build(Default::default())?;
/// let mut cache = CompilerCache::<Settings>::read(project.cache_path())?;
/// let mut cache = CompilerCache::<SolcSettings>::read(project.cache_path())?;
/// cache.join_artifacts_files(project.artifacts_path());
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
Expand All @@ -129,10 +129,10 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::Settings, cache::CompilerCache, Project};
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
/// let project = Project::builder().build(Default::default())?;
/// let cache: CompilerCache<Settings> = CompilerCache::read_joined(&project.paths)?;
/// let cache: CompilerCache<SolcSettings> = CompilerCache::read_joined(&project.paths)?;
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
pub fn read_joined<L>(paths: &ProjectPathsConfig<L>) -> Result<Self> {
Expand Down Expand Up @@ -210,13 +210,11 @@ impl<S: CompilerSettings> CompilerCache<S> {
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::{contract::CompactContract, Settings},
/// cache::CompilerCache,
/// Project,
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
/// };
///
/// let project = Project::builder().build(Default::default())?;
/// let cache: CompilerCache<Settings> =
/// let cache: CompilerCache<SolcSettings> =
/// CompilerCache::read(project.cache_path())?.with_stripped_file_prefixes(project.root());
/// let artifact: CompactContract = cache.read_artifact("src/Greeter.sol".as_ref(), "Greeter")?;
/// # Ok::<_, Box<dyn std::error::Error>>(())
Expand All @@ -237,10 +235,10 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::Settings, cache::CompilerCache, Project};
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
/// let project = Project::builder().build(Default::default())?;
/// let cache: CompilerCache<Settings> = CompilerCache::read_joined(&project.paths)?;
/// let cache: CompilerCache<SolcSettings> = CompilerCache::read_joined(&project.paths)?;
/// cache.find_artifact_path("/Users/git/myproject/src/Greeter.sol".as_ref(), "Greeter");
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
Expand All @@ -256,13 +254,11 @@ impl<S: CompilerSettings> CompilerCache<S> {
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::{contract::CompactContract, Settings},
/// cache::CompilerCache,
/// Project,
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
/// };
///
/// let project = Project::builder().build(Default::default())?;
/// let cache = CompilerCache::<Settings>::read_joined(&project.paths)?;
/// let cache = CompilerCache::<SolcSettings>::read_joined(&project.paths)?;
/// let artifact: CompactContract =
/// cache.read_artifact("/Users/git/myproject/src/Greeter.sol".as_ref(), "Greeter")?;
/// # Ok::<_, Box<dyn std::error::Error>>(())
Expand All @@ -288,13 +284,12 @@ impl<S: CompilerSettings> CompilerCache<S> {
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::{contract::CompactContractBytecode, Settings},
/// cache::CompilerCache,
/// artifacts::contract::CompactContractBytecode, cache::CompilerCache, solc::SolcSettings,
/// Project,
/// };
///
/// let project = Project::builder().build(Default::default())?;
/// let cache: CompilerCache<Settings> = CompilerCache::read_joined(&project.paths)?;
/// let cache: CompilerCache<SolcSettings> = CompilerCache::read_joined(&project.paths)?;
/// let artifacts = cache.read_artifacts::<CompactContractBytecode>()?;
/// # Ok::<_, Box<dyn std::error::Error>>(())
/// ```
Expand Down
14 changes: 8 additions & 6 deletions crates/compilers/src/compile/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ use crate::{
output::{AggregatedCompilerOutput, Builds},
report,
resolver::GraphEdges,
ArtifactOutput, Graph, Project, ProjectCompileOutput, Sources,
ArtifactOutput, CompilerSettings, Graph, Project, ProjectCompileOutput, Sources,
};
use foundry_compilers_core::error::Result;
use rayon::prelude::*;
Expand Down Expand Up @@ -447,11 +447,13 @@ impl<L: Language> CompilerSources<L> {

trace!("calling {} with {} sources {:?}", version, sources.len(), sources.keys());

let mut input = C::Input::build(sources, opt_settings, language, version.clone())
.with_base_path(project.paths.root.clone())
.with_allow_paths(project.paths.allowed_paths.clone())
.with_include_paths(include_paths.clone())
.with_remappings(project.paths.remappings.clone());
let settings = opt_settings
.with_base_path(&project.paths.root)
.with_allow_paths(&project.paths.allowed_paths)
.with_include_paths(&include_paths)
.with_remappings(&project.paths.remappings);

let mut input = C::Input::build(sources, settings, language, version.clone());

input.strip_prefix(project.paths.root.as_path());

Expand Down
46 changes: 23 additions & 23 deletions crates/compilers/src/compilers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@ pub trait CompilerSettings:
/// Ensures that all settings fields are equal except for `output_selection` which is required
/// to be a subset of `cached.output_selection`.
fn can_use_cached(&self, other: &Self) -> bool;

/// Method which might be invoked to add remappings to the input.
fn with_remappings(self, _remappings: &[Remapping]) -> Self {
self
}

/// Builder method to set the base path for the compiler. Primarily used by solc implementation
/// to se --base-path.
fn with_base_path(self, _base_path: &Path) -> Self {
self
}

/// Builder method to set the allowed paths for the compiler. Primarily used by solc
/// implementation to set --allow-paths.
fn with_allow_paths(self, _allowed_paths: &BTreeSet<PathBuf>) -> Self {
self
}

/// Builder method to set the include paths for the compiler. Primarily used by solc
/// implementation to set --include-paths.
fn with_include_paths(self, _include_paths: &BTreeSet<PathBuf>) -> Self {
self
}
}

/// Input of a compiler, including sources and settings used for their compilation.
Expand Down Expand Up @@ -101,29 +124,6 @@ pub trait CompilerInput: Serialize + Send + Sync + Sized + Debug {
/// Returns compiler name used by reporters to display output during compilation.
fn compiler_name(&self) -> Cow<'static, str>;

/// Method which might be invoked to add remappings to the input.
fn with_remappings(self, _remappings: Vec<Remapping>) -> Self {
self
}

/// Builder method to set the base path for the compiler. Primarily used by solc implementation
/// to se --base-path.
fn with_base_path(self, _base_path: PathBuf) -> Self {
self
}

/// Builder method to set the allowed paths for the compiler. Primarily used by solc
/// implementation to set --allow-paths.
fn with_allow_paths(self, _allowed_paths: BTreeSet<PathBuf>) -> Self {
self
}

/// Builder method to set the include paths for the compiler. Primarily used by solc
/// implementation to set --include-paths.
fn with_include_paths(self, _include_paths: BTreeSet<PathBuf>) -> Self {
self
}

/// Strips given prefix from all paths.
fn strip_prefix(&mut self, base: &Path);
}
Expand Down
63 changes: 32 additions & 31 deletions crates/compilers/src/compilers/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ use super::{
use crate::{
artifacts::vyper::{VyperCompilationError, VyperSettings},
resolver::parse::SolData,
solc::SolcSettings,
};
use foundry_compilers_artifacts::{
error::SourceLocation,
output_selection::OutputSelection,
remappings::Remapping,
sources::{Source, Sources},
Error, Settings as SolcSettings, Severity, SolcLanguage,
Error, Severity, SolcLanguage,
};
use foundry_compilers_core::error::{Result, SolcError};
use semver::Version;
Expand Down Expand Up @@ -137,8 +138,36 @@ impl CompilerSettings for MultiCompilerSettings {
}

fn update_output_selection(&mut self, f: impl FnOnce(&mut OutputSelection) + Copy) {
f(&mut self.solc.output_selection);
f(&mut self.vyper.output_selection);
self.solc.update_output_selection(f);
self.vyper.update_output_selection(f);
}

fn with_allow_paths(self, allowed_paths: &BTreeSet<PathBuf>) -> Self {
Self {
solc: self.solc.with_allow_paths(allowed_paths),
vyper: self.vyper.with_allow_paths(allowed_paths),
}
}

fn with_base_path(self, base_path: &Path) -> Self {
Self {
solc: self.solc.with_base_path(base_path),
vyper: self.vyper.with_base_path(base_path),
}
}

fn with_include_paths(self, include_paths: &BTreeSet<PathBuf>) -> Self {
Self {
solc: self.solc.with_include_paths(include_paths),
vyper: self.vyper.with_include_paths(include_paths),
}
}

fn with_remappings(self, remappings: &[Remapping]) -> Self {
Self {
solc: self.solc.with_remappings(remappings),
vyper: self.vyper.with_remappings(remappings),
}
}
}

Expand Down Expand Up @@ -210,34 +239,6 @@ impl CompilerInput for MultiCompilerInput {
}
}

fn with_allow_paths(self, allowed_paths: BTreeSet<PathBuf>) -> Self {
match self {
Self::Solc(input) => Self::Solc(input.with_allow_paths(allowed_paths)),
Self::Vyper(input) => Self::Vyper(input.with_allow_paths(allowed_paths)),
}
}

fn with_base_path(self, base_path: PathBuf) -> Self {
match self {
Self::Solc(input) => Self::Solc(input.with_base_path(base_path)),
Self::Vyper(input) => Self::Vyper(input.with_base_path(base_path)),
}
}

fn with_include_paths(self, include_paths: BTreeSet<PathBuf>) -> Self {
match self {
Self::Solc(input) => Self::Solc(input.with_include_paths(include_paths)),
Self::Vyper(input) => Self::Vyper(input.with_include_paths(include_paths)),
}
}

fn with_remappings(self, remappings: Vec<Remapping>) -> Self {
match self {
Self::Solc(input) => Self::Solc(input.with_remappings(remappings)),
Self::Vyper(input) => Self::Vyper(input.with_remappings(remappings)),
}
}

fn sources(&self) -> impl Iterator<Item = (&Path, &Source)> {
let ret: Box<dyn Iterator<Item = _>> = match self {
Self::Solc(input) => Box::new(input.sources()),
Expand Down
Loading