From 9e9c7ec1b5cacd9735aad0f554c9df027f638c4f Mon Sep 17 00:00:00 2001 From: elfedy Date: Thu, 7 Nov 2024 18:01:50 -0300 Subject: [PATCH 01/11] refactor: make Contract generic for Compiler --- .../src/artifact_output/configurable.rs | 3 +- crates/compilers/src/artifact_output/hh.rs | 1 + crates/compilers/src/artifact_output/mod.rs | 19 +++-- crates/compilers/src/buildinfo.rs | 16 ++-- crates/compilers/src/cache.rs | 22 +++-- .../compilers/src/compile/output/contracts.rs | 81 ++++++++++++------- crates/compilers/src/compile/output/mod.rs | 50 +++++++----- crates/compilers/src/compile/project.rs | 45 ++++++++--- crates/compilers/src/compilers/mod.rs | 58 +++++++++++-- crates/compilers/src/compilers/multi.rs | 8 +- crates/compilers/src/compilers/solc/mod.rs | 8 +- crates/compilers/src/compilers/vyper/mod.rs | 8 +- .../compilers/src/compilers/vyper/output.rs | 4 +- crates/compilers/src/flatten.rs | 6 +- crates/compilers/src/lib.rs | 42 ++++++---- 15 files changed, 256 insertions(+), 115 deletions(-) diff --git a/crates/compilers/src/artifact_output/configurable.rs b/crates/compilers/src/artifact_output/configurable.rs index 699a5fbc..12574afc 100644 --- a/crates/compilers/src/artifact_output/configurable.rs +++ b/crates/compilers/src/artifact_output/configurable.rs @@ -169,11 +169,12 @@ impl ConfigurableArtifacts { impl ArtifactOutput for ConfigurableArtifacts { type Artifact = ConfigurableContractArtifact; + type CompilerContract = Contract; /// Writes extra files for compiled artifact based on [Self::additional_files] fn handle_artifacts( &self, - contracts: &crate::VersionedContracts, + contracts: &crate::VersionedContracts, artifacts: &crate::Artifacts, ) -> Result<(), SolcError> { for (file, contracts) in contracts.as_ref().iter() { diff --git a/crates/compilers/src/artifact_output/hh.rs b/crates/compilers/src/artifact_output/hh.rs index fe47a9ed..8c85cf2d 100644 --- a/crates/compilers/src/artifact_output/hh.rs +++ b/crates/compilers/src/artifact_output/hh.rs @@ -13,6 +13,7 @@ pub struct HardhatArtifacts { impl ArtifactOutput for HardhatArtifacts { type Artifact = HardhatArtifact; + type CompilerContract = Contract; fn contract_to_artifact( &self, diff --git a/crates/compilers/src/artifact_output/mod.rs b/crates/compilers/src/artifact_output/mod.rs index 681cd45a..6fe41a35 100644 --- a/crates/compilers/src/artifact_output/mod.rs +++ b/crates/compilers/src/artifact_output/mod.rs @@ -37,7 +37,7 @@ use crate::{ contracts::VersionedContracts, sources::{VersionedSourceFile, VersionedSourceFiles}, }, - ProjectPathsConfig, + CompilerContract, ProjectPathsConfig, }; /// Represents unique artifact metadata for identifying artifacts on output @@ -605,16 +605,17 @@ where pub trait ArtifactOutput { /// Represents the artifact that will be stored for a `Contract` type Artifact: Artifact + DeserializeOwned + Serialize + fmt::Debug + Send + Sync; + type CompilerContract: CompilerContract; /// Handle the aggregated set of compiled contracts from the solc [`crate::CompilerOutput`]. /// /// This will be invoked with all aggregated contracts from (multiple) solc `CompilerOutput`. /// See [`crate::AggregatedCompilerOutput`] - fn on_output( + fn on_output( &self, - contracts: &VersionedContracts, + contracts: &VersionedContracts, sources: &VersionedSourceFiles, - layout: &ProjectPathsConfig, + layout: &ProjectPathsConfig, ctx: OutputContext<'_>, ) -> Result> { let mut artifacts = self.output_to_artifacts(contracts, sources, ctx, layout); @@ -634,7 +635,7 @@ pub trait ArtifactOutput { /// Invoked after artifacts has been written to disk for additional processing. fn handle_artifacts( &self, - _contracts: &VersionedContracts, + _contracts: &VersionedContracts, _artifacts: &Artifacts, ) -> Result<()> { Ok(()) @@ -794,7 +795,7 @@ pub trait ArtifactOutput { &self, _file: &Path, _name: &str, - contract: Contract, + contract: Self::CompilerContract, source_file: Option<&SourceFile>, ) -> Self::Artifact; @@ -840,7 +841,7 @@ pub trait ArtifactOutput { /// [`Self::on_output()`] fn output_to_artifacts( &self, - contracts: &VersionedContracts, + contracts: &VersionedContracts, sources: &VersionedSourceFiles, ctx: OutputContext<'_>, layout: &ProjectPathsConfig, @@ -1069,6 +1070,7 @@ pub struct MinimalCombinedArtifacts { impl ArtifactOutput for MinimalCombinedArtifacts { type Artifact = CompactContractBytecode; + type CompilerContract = Contract; fn contract_to_artifact( &self, @@ -1098,10 +1100,11 @@ pub struct MinimalCombinedArtifactsHardhatFallback { impl ArtifactOutput for MinimalCombinedArtifactsHardhatFallback { type Artifact = CompactContractBytecode; + type CompilerContract = Contract; fn on_output( &self, - output: &VersionedContracts, + output: &VersionedContracts, sources: &VersionedSourceFiles, layout: &ProjectPathsConfig, ctx: OutputContext<'_>, diff --git a/crates/compilers/src/buildinfo.rs b/crates/compilers/src/buildinfo.rs index 571e8471..0d6a82f5 100644 --- a/crates/compilers/src/buildinfo.rs +++ b/crates/compilers/src/buildinfo.rs @@ -1,6 +1,8 @@ //! Represents an entire build -use crate::compilers::{CompilationError, CompilerInput, CompilerOutput, Language}; +use crate::compilers::{ + CompilationError, CompilerContract, CompilerInput, CompilerOutput, Language, +}; use alloy_primitives::hex; use foundry_compilers_core::{error::Result, utils}; use md5::Digest; @@ -43,7 +45,7 @@ pub struct BuildContext { } impl BuildContext { - pub fn new(input: &I, output: &CompilerOutput) -> Result + pub fn new(input: &I, output: &CompilerOutput) -> Result where I: CompilerInput, { @@ -87,9 +89,9 @@ pub struct RawBuildInfo { impl RawBuildInfo { /// Serializes a `BuildInfo` object - pub fn new, E: CompilationError>( + pub fn new, E: CompilationError, C: CompilerContract>( input: &I, - output: &CompilerOutput, + output: &CompilerOutput, full_build_info: bool, ) -> Result { let version = input.version().clone(); @@ -130,7 +132,7 @@ impl RawBuildInfo { mod tests { use super::*; use crate::compilers::solc::SolcVersionedInput; - use foundry_compilers_artifacts::{sources::Source, Error, SolcLanguage, Sources}; + use foundry_compilers_artifacts::{sources::Source, Contract, Error, SolcLanguage, Sources}; use std::path::PathBuf; #[test] @@ -142,9 +144,9 @@ mod tests { SolcLanguage::Solidity, v, ); - let output = CompilerOutput::::default(); + let output = CompilerOutput::::default(); let raw_info = RawBuildInfo::new(&input, &output, true).unwrap(); - let _info: BuildInfo> = + let _info: BuildInfo> = serde_json::from_str(&serde_json::to_string(&raw_info).unwrap()).unwrap(); } } diff --git a/crates/compilers/src/cache.rs b/crates/compilers/src/cache.rs index 0d5d1613..a41f604b 100644 --- a/crates/compilers/src/cache.rs +++ b/crates/compilers/src/cache.rs @@ -593,7 +593,11 @@ impl GroupedSources { /// A helper abstraction over the [`CompilerCache`] used to determine what files need to compiled /// and which `Artifacts` can be reused. #[derive(Debug)] -pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput, C: Compiler> { +pub(crate) struct ArtifactsCacheInner< + 'a, + T: ArtifactOutput, + C: Compiler, +> { /// The preexisting cache file. pub cache: CompilerCache, @@ -622,7 +626,9 @@ pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput, C: Compiler> { pub content_hashes: HashMap, } -impl<'a, T: ArtifactOutput, C: Compiler> ArtifactsCacheInner<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + ArtifactsCacheInner<'a, T, C> +{ /// Creates a new cache entry for the file fn create_cache_entry(&mut self, file: PathBuf, source: &Source) { let imports = self @@ -845,20 +851,26 @@ impl<'a, T: ArtifactOutput, C: Compiler> ArtifactsCacheInner<'a, T, C> { /// Abstraction over configured caching which can be either non-existent or an already loaded cache #[allow(clippy::large_enum_variant)] #[derive(Debug)] -pub(crate) enum ArtifactsCache<'a, T: ArtifactOutput, C: Compiler> { +pub(crate) enum ArtifactsCache< + 'a, + T: ArtifactOutput, + C: Compiler, +> { /// Cache nothing on disk Ephemeral(GraphEdges, &'a Project), /// Handles the actual cached artifacts, detects artifacts that can be reused Cached(ArtifactsCacheInner<'a, T, C>), } -impl<'a, T: ArtifactOutput, C: Compiler> ArtifactsCache<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + ArtifactsCache<'a, T, C> +{ /// Create a new cache instance with the given files pub fn new(project: &'a Project, edges: GraphEdges) -> Result { /// Returns the [CompilerCache] to use /// /// Returns a new empty cache if the cache does not exist or `invalidate_cache` is set. - fn get_cache( + fn get_cache, C: Compiler>( project: &Project, invalidate_cache: bool, ) -> CompilerCache { diff --git a/crates/compilers/src/compile/output/contracts.rs b/crates/compilers/src/compile/output/contracts.rs index 99a0e0bd..739cb30e 100644 --- a/crates/compilers/src/compile/output/contracts.rs +++ b/crates/compilers/src/compile/output/contracts.rs @@ -1,6 +1,6 @@ -use crate::ArtifactId; +use crate::{compilers::CompilerContract, ArtifactId}; use foundry_compilers_artifacts::{ - CompactContractBytecode, CompactContractRef, Contract, FileToContractsMap, + CompactContractBytecode, CompactContractRef, FileToContractsMap, }; use semver::Version; use serde::{Deserialize, Deserializer, Serialize, Serializer}; @@ -11,11 +11,25 @@ use std::{ }; /// file -> [(contract name -> Contract + solc version)] -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(transparent)] -pub struct VersionedContracts(pub FileToContractsMap>); +pub struct VersionedContracts( + pub FileToContractsMap>>, +); + +impl Default for VersionedContracts +where + C: CompilerContract, +{ + fn default() -> Self { + Self(BTreeMap::new()) + } +} -impl VersionedContracts { +impl VersionedContracts +where + C: CompilerContract, +{ /// Converts all `\\` separators in _all_ paths to `/` pub fn slash_paths(&mut self) { #[cfg(windows)] @@ -53,7 +67,8 @@ impl VersionedContracts { /// ``` pub fn find_first(&self, contract_name: &str) -> Option> { self.contracts().find_map(|(name, contract)| { - (name == contract_name).then(|| CompactContractRef::from(contract)) + //(name == contract_name).then(|| CompactContractRef::from(contract)) + (name == contract_name).then(|| contract.as_compact_contract_ref()) }) } @@ -75,7 +90,7 @@ impl VersionedContracts { ) -> Option> { self.contracts_with_files().find_map(|(path, name, contract)| { (path == contract_path && name == contract_name) - .then(|| CompactContractRef::from(contract)) + .then(|| contract.as_compact_contract_ref()) }) } @@ -90,7 +105,7 @@ impl VersionedContracts { /// let contract = contracts.remove_first("Greeter").unwrap(); /// # Ok::<_, Box>(()) /// ``` - pub fn remove_first(&mut self, contract_name: &str) -> Option { + pub fn remove_first(&mut self, contract_name: &str) -> Option { self.0.values_mut().find_map(|all_contracts| { let mut contract = None; if let Some((c, mut contracts)) = all_contracts.remove_entry(contract_name) { @@ -116,7 +131,7 @@ impl VersionedContracts { /// let contract = contracts.remove("src/Greeter.sol".as_ref(), "Greeter").unwrap(); /// # Ok::<_, Box>(()) /// ``` - pub fn remove(&mut self, path: &Path, contract_name: &str) -> Option { + pub fn remove(&mut self, path: &Path, contract_name: &str) -> Option { let (key, mut all_contracts) = self.0.remove_entry(path)?; let mut contract = None; if let Some((c, mut contracts)) = all_contracts.remove_entry(contract_name) { @@ -142,18 +157,18 @@ impl VersionedContracts { .and_then(|contracts| { contracts.get(contract).and_then(|c| c.first().map(|c| &c.contract)) }) - .map(CompactContractRef::from) + .map(|c| c.as_compact_contract_ref()) } /// Returns an iterator over all contracts and their names. - pub fn contracts(&self) -> impl Iterator { + pub fn contracts(&self) -> impl Iterator { self.0 .values() .flat_map(|c| c.iter().flat_map(|(name, c)| c.iter().map(move |c| (name, &c.contract)))) } /// Returns an iterator over (`file`, `name`, `Contract`). - pub fn contracts_with_files(&self) -> impl Iterator { + pub fn contracts_with_files(&self) -> impl Iterator { self.0.iter().flat_map(|(file, contracts)| { contracts .iter() @@ -164,7 +179,7 @@ impl VersionedContracts { /// Returns an iterator over (`file`, `name`, `Contract`, `Version`). pub fn contracts_with_files_and_version( &self, - ) -> impl Iterator { + ) -> impl Iterator { self.0.iter().flat_map(|(file, contracts)| { contracts.iter().flat_map(move |(name, c)| { c.iter().map(move |c| (file, name, &c.contract, &c.version)) @@ -173,7 +188,7 @@ impl VersionedContracts { } /// Returns an iterator over all contracts and their source names. - pub fn into_contracts(self) -> impl Iterator { + pub fn into_contracts(self) -> impl Iterator { self.0.into_values().flat_map(|c| { c.into_iter() .flat_map(|(name, c)| c.into_iter().map(move |c| (name.clone(), c.contract))) @@ -181,7 +196,7 @@ impl VersionedContracts { } /// Returns an iterator over (`file`, `name`, `Contract`) - pub fn into_contracts_with_files(self) -> impl Iterator { + pub fn into_contracts_with_files(self) -> impl Iterator { self.0.into_iter().flat_map(|(file, contracts)| { contracts.into_iter().flat_map(move |(name, c)| { let file = file.clone(); @@ -193,7 +208,7 @@ impl VersionedContracts { /// Returns an iterator over (`file`, `name`, `Contract`, `Version`) pub fn into_contracts_with_files_and_version( self, - ) -> impl Iterator { + ) -> impl Iterator { self.0.into_iter().flat_map(|(file, contracts)| { contracts.into_iter().flat_map(move |(name, c)| { let file = file.clone(); @@ -226,30 +241,42 @@ impl VersionedContracts { } } -impl AsRef>> for VersionedContracts { - fn as_ref(&self) -> &FileToContractsMap> { +impl AsRef>>> for VersionedContracts +where + C: CompilerContract, +{ + fn as_ref(&self) -> &FileToContractsMap>> { &self.0 } } -impl AsMut>> for VersionedContracts { - fn as_mut(&mut self) -> &mut FileToContractsMap> { +impl AsMut>>> for VersionedContracts +where + C: CompilerContract, +{ + fn as_mut(&mut self) -> &mut FileToContractsMap>> { &mut self.0 } } -impl Deref for VersionedContracts { - type Target = FileToContractsMap>; +impl Deref for VersionedContracts +where + C: CompilerContract, +{ + type Target = FileToContractsMap>>; fn deref(&self) -> &Self::Target { &self.0 } } -impl IntoIterator for VersionedContracts { - type Item = (PathBuf, BTreeMap>); +impl IntoIterator for VersionedContracts +where + C: CompilerContract, +{ + type Item = (PathBuf, BTreeMap>>); type IntoIter = - std::collections::btree_map::IntoIter>>; + std::collections::btree_map::IntoIter>>>; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() @@ -258,8 +285,8 @@ impl IntoIterator for VersionedContracts { /// A contract and the compiler version used to compile it #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct VersionedContract { - pub contract: Contract, +pub struct VersionedContract { + pub contract: C, pub version: Version, pub build_id: String, } diff --git a/crates/compilers/src/compile/output/mod.rs b/crates/compilers/src/compile/output/mod.rs index 06b5224d..deaebd6d 100644 --- a/crates/compilers/src/compile/output/mod.rs +++ b/crates/compilers/src/compile/output/mod.rs @@ -1,8 +1,6 @@ //! The output of a compiled project use contracts::{VersionedContract, VersionedContracts}; -use foundry_compilers_artifacts::{ - CompactContractBytecode, CompactContractRef, Contract, Severity, -}; +use foundry_compilers_artifacts::{CompactContractBytecode, CompactContractRef, Severity}; use foundry_compilers_core::error::{SolcError, SolcIoError}; use info::ContractInfoRef; use semver::Version; @@ -18,7 +16,9 @@ use yansi::Paint; use crate::{ buildinfo::{BuildContext, RawBuildInfo}, - compilers::{multi::MultiCompiler, CompilationError, Compiler, CompilerOutput}, + compilers::{ + multi::MultiCompiler, CompilationError, Compiler, CompilerContract, CompilerOutput, + }, Artifact, ArtifactId, ArtifactOutput, Artifacts, ConfigurableArtifacts, }; @@ -65,7 +65,7 @@ impl IntoIterator for Builds { #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct ProjectCompileOutput< C: Compiler = MultiCompiler, - T: ArtifactOutput = ConfigurableArtifacts, + T: ArtifactOutput = ConfigurableArtifacts, > { /// contains the aggregated `CompilerOutput` pub(crate) compiler_output: AggregatedCompilerOutput, @@ -83,7 +83,9 @@ pub struct ProjectCompileOutput< pub(crate) builds: Builds, } -impl ProjectCompileOutput { +impl, C: Compiler> + ProjectCompileOutput +{ /// Converts all `\\` separators in _all_ paths to `/` pub fn slash_paths(&mut self) { self.compiler_output.slash_paths(); @@ -304,7 +306,7 @@ impl ProjectCompileOutput { /// `Contract` pub fn compiled_contracts_by_compiler_version( &self, - ) -> BTreeMap> { + ) -> BTreeMap> { let mut contracts: BTreeMap<_, Vec<_>> = BTreeMap::new(); let versioned_contracts = &self.compiler_output.contracts; for (_, name, contract, version) in versioned_contracts.contracts_with_files_and_version() { @@ -459,7 +461,9 @@ impl ProjectCompileOutput { } } -impl ProjectCompileOutput { +impl> + ProjectCompileOutput +{ /// Returns whether any errors were emitted by the compiler. pub fn has_compiler_errors(&self) -> bool { self.compiler_output.has_error( @@ -488,7 +492,9 @@ impl ProjectCompileOutput { } } -impl fmt::Display for ProjectCompileOutput { +impl> fmt::Display + for ProjectCompileOutput +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if self.compiler_output.is_unchanged() { f.write_str("Nothing to compile") @@ -514,7 +520,7 @@ pub struct AggregatedCompilerOutput { /// All source files combined with the solc version used to compile them pub sources: VersionedSourceFiles, /// All compiled contracts combined with the solc version used to compile them - pub contracts: VersionedContracts, + pub contracts: VersionedContracts, // All the `BuildInfo`s of solc invocations. pub build_infos: Vec>, } @@ -564,7 +570,7 @@ impl AggregatedCompilerOutput { &mut self, version: Version, build_info: RawBuildInfo, - output: CompilerOutput, + output: CompilerOutput, ) { let build_id = build_info.id.clone(); self.build_infos.push(build_info); @@ -642,7 +648,7 @@ impl AggregatedCompilerOutput { /// let contract = output.remove_first("Greeter").unwrap(); /// # Ok::<_, Box>(()) /// ``` - pub fn remove_first(&mut self, contract: &str) -> Option { + pub fn remove_first(&mut self, contract: &str) -> Option { self.contracts.remove_first(contract) } @@ -657,7 +663,7 @@ impl AggregatedCompilerOutput { /// let contract = output.remove("src/Greeter.sol".as_ref(), "Greeter").unwrap(); /// # Ok::<_, Box>(()) /// ``` - pub fn remove(&mut self, path: &Path, contract: &str) -> Option { + pub fn remove(&mut self, path: &Path, contract: &str) -> Option { self.contracts.remove(path, contract) } @@ -680,7 +686,7 @@ impl AggregatedCompilerOutput { pub fn remove_contract<'a>( &mut self, info: impl Into>, - ) -> Option { + ) -> Option { let ContractInfoRef { path, name } = info.into(); if let Some(path) = path { self.remove(path[..].as_ref(), &name) @@ -690,40 +696,40 @@ impl AggregatedCompilerOutput { } /// Iterate over all contracts and their names - pub fn contracts_iter(&self) -> impl Iterator { + pub fn contracts_iter(&self) -> impl Iterator { self.contracts.contracts() } /// Iterate over all contracts and their names - pub fn contracts_into_iter(self) -> impl Iterator { + pub fn contracts_into_iter(self) -> impl Iterator { self.contracts.into_contracts() } /// Returns an iterator over (`file`, `name`, `Contract`) pub fn contracts_with_files_iter( &self, - ) -> impl Iterator { + ) -> impl Iterator { self.contracts.contracts_with_files() } /// Returns an iterator over (`file`, `name`, `Contract`) pub fn contracts_with_files_into_iter( self, - ) -> impl Iterator { + ) -> impl Iterator { self.contracts.into_contracts_with_files() } /// Returns an iterator over (`file`, `name`, `Contract`, `Version`) pub fn contracts_with_files_and_version_iter( &self, - ) -> impl Iterator { + ) -> impl Iterator { self.contracts.contracts_with_files_and_version() } /// Returns an iterator over (`file`, `name`, `Contract`, `Version`) pub fn contracts_with_files_and_version_into_iter( self, - ) -> impl Iterator { + ) -> impl Iterator { self.contracts.into_contracts_with_files_and_version() } @@ -755,7 +761,7 @@ impl AggregatedCompilerOutput { /// let (sources, contracts) = output.split(); /// # Ok::<_, Box>(()) /// ``` - pub fn split(self) -> (VersionedSourceFiles, VersionedContracts) { + pub fn split(self) -> (VersionedSourceFiles, VersionedContracts) { (self.sources, self.contracts) } @@ -869,7 +875,7 @@ impl AggregatedCompilerOutput { self.contracts.contracts_with_files().filter(|(path, _, _)| *path == contract_path).any( |(_, _, contract)| { - contract.abi.as_ref().map_or(false, |abi| abi.functions.contains_key("IS_TEST")) + contract.abi_ref().map_or(false, |abi| abi.functions.contains_key("IS_TEST")) }, ) } diff --git a/crates/compilers/src/compile/project.rs b/crates/compilers/src/compile/project.rs index b76c47a5..7c2a5d9b 100644 --- a/crates/compilers/src/compile/project.rs +++ b/crates/compilers/src/compile/project.rs @@ -120,7 +120,11 @@ use std::{collections::HashMap, path::PathBuf, time::Instant}; pub(crate) type VersionedSources = HashMap>; #[derive(Debug)] -pub struct ProjectCompiler<'a, T: ArtifactOutput, C: Compiler> { +pub struct ProjectCompiler< + 'a, + T: ArtifactOutput, + C: Compiler, +> { /// Contains the relationship of the source files and their imports edges: GraphEdges, project: &'a Project, @@ -128,7 +132,9 @@ pub struct ProjectCompiler<'a, T: ArtifactOutput, C: Compiler> { sources: CompilerSources, } -impl<'a, T: ArtifactOutput, C: Compiler> ProjectCompiler<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + ProjectCompiler<'a, T, C> +{ /// Create a new `ProjectCompiler` to bootstrap the compilation process of the project's /// sources. pub fn new(project: &'a Project) -> Result { @@ -215,7 +221,8 @@ impl<'a, T: ArtifactOutput, C: Compiler> ProjectCompiler<'a, T, C> { /// /// The main reason is to debug all states individually #[derive(Debug)] -struct PreprocessedState<'a, T: ArtifactOutput, C: Compiler> { +struct PreprocessedState<'a, T: ArtifactOutput, C: Compiler> +{ /// Contains all the sources to compile. sources: CompilerSources, @@ -223,7 +230,9 @@ struct PreprocessedState<'a, T: ArtifactOutput, C: Compiler> { cache: ArtifactsCache<'a, T, C>, } -impl<'a, T: ArtifactOutput, C: Compiler> PreprocessedState<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + PreprocessedState<'a, T, C> +{ /// advance to the next state by compiling all sources fn compile(self) -> Result> { trace!("compiling"); @@ -244,12 +253,14 @@ impl<'a, T: ArtifactOutput, C: Compiler> PreprocessedState<'a, T, C> { /// Represents the state after `solc` was successfully invoked #[derive(Debug)] -struct CompiledState<'a, T: ArtifactOutput, C: Compiler> { +struct CompiledState<'a, T: ArtifactOutput, C: Compiler> { output: AggregatedCompilerOutput, cache: ArtifactsCache<'a, T, C>, } -impl<'a, T: ArtifactOutput, C: Compiler> CompiledState<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + CompiledState<'a, T, C> +{ /// advance to the next state by handling all artifacts /// /// Writes all output contracts to disk if enabled in the `Project` and if the build was @@ -307,13 +318,15 @@ impl<'a, T: ArtifactOutput, C: Compiler> CompiledState<'a, T, C> { /// Represents the state after all artifacts were written to disk #[derive(Debug)] -struct ArtifactsState<'a, T: ArtifactOutput, C: Compiler> { +struct ArtifactsState<'a, T: ArtifactOutput, C: Compiler> { output: AggregatedCompilerOutput, cache: ArtifactsCache<'a, T, C>, compiled_artifacts: Artifacts, } -impl<'a, T: ArtifactOutput, C: Compiler> ArtifactsState<'a, T, C> { +impl<'a, T: ArtifactOutput, C: Compiler> + ArtifactsState<'a, T, C> +{ /// Writes the cache file /// /// this concludes the [`Project::compile()`] statemachine @@ -388,7 +401,10 @@ impl CompilerSources { } /// Filters out all sources that don't need to be compiled, see [`ArtifactsCache::filter`] - fn filter>( + fn filter< + T: ArtifactOutput, + C: Compiler, + >( &mut self, cache: &mut ArtifactsCache<'_, T, C>, ) { @@ -407,7 +423,10 @@ impl CompilerSources { } /// Compiles all the files with `Solc` - fn compile, T: ArtifactOutput>( + fn compile< + C: Compiler, + T: ArtifactOutput, + >( self, cache: &mut ArtifactsCache<'_, T, C>, ) -> Result> { @@ -492,13 +511,13 @@ impl CompilerSources { } } -type CompilationResult = Result, Vec)>>; +type CompilationResult = Result, Vec)>>; /// Compiles the input set sequentially and returns a [Vec] of outputs. fn compile_sequential( compiler: &C, jobs: Vec<(C::Input, Vec)>, -) -> CompilationResult { +) -> CompilationResult { jobs.into_iter() .map(|(input, actually_dirty)| { let start = Instant::now(); @@ -520,7 +539,7 @@ fn compile_parallel( compiler: &C, jobs: Vec<(C::Input, Vec)>, num_jobs: usize, -) -> CompilationResult { +) -> CompilationResult { // need to get the currently installed reporter before installing the pool, otherwise each new // thread in the pool will get initialized with the default value of the `thread_local!`'s // localkey. This way we keep access to the reporter in the rayon pool diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index 506ea7ca..f2b365c0 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -1,11 +1,12 @@ use crate::ProjectPathsConfig; +use alloy_json_abi::JsonAbi; use core::fmt; use foundry_compilers_artifacts::{ error::SourceLocation, output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - Contract, FileToContractsMap, Severity, SourceFile, + BytecodeObject, CompactContractRef, Contract, FileToContractsMap, Severity, SourceFile, }; use foundry_compilers_core::error::Result; use semver::{Version, VersionReq}; @@ -183,16 +184,16 @@ pub trait CompilationError: /// Output of the compiler, including contracts, sources and errors. Currently only generic over the /// error but might be extended in the future. #[derive(Debug, Serialize, Deserialize)] -pub struct CompilerOutput { +pub struct CompilerOutput { #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] pub errors: Vec, - #[serde(default)] - pub contracts: FileToContractsMap, + #[serde(default = "BTreeMap::new")] + pub contracts: FileToContractsMap, #[serde(default)] pub sources: BTreeMap, } -impl CompilerOutput { +impl CompilerOutput { /// Retains only those files the given iterator yields /// /// In other words, removes all contracts for files not included in the iterator @@ -226,7 +227,7 @@ impl CompilerOutput { .collect(); } - pub fn map_err F>(self, op: O) -> CompilerOutput { + pub fn map_err F>(self, op: O) -> CompilerOutput { CompilerOutput { errors: self.errors.into_iter().map(op).collect(), contracts: self.contracts, @@ -235,7 +236,7 @@ impl CompilerOutput { } } -impl Default for CompilerOutput { +impl Default for CompilerOutput { fn default() -> Self { Self { errors: Vec::new(), contracts: BTreeMap::new(), sources: BTreeMap::new() } } @@ -249,6 +250,42 @@ pub trait Language: const FILE_EXTENSIONS: &'static [&'static str]; } +pub trait CompilerContract: Serialize + Send + Sync + Debug + Clone + Eq + Sized { + fn abi_ref(&self) -> Option<&JsonAbi>; + fn bin_ref(&self) -> Option<&BytecodeObject>; + fn bin_runtime_ref(&self) -> Option<&BytecodeObject>; + + fn as_compact_contract_ref(&self) -> CompactContractRef<'_> { + CompactContractRef { + abi: self.abi_ref(), + bin: self.bin_ref(), + bin_runtime: self.bin_runtime_ref(), + } + } +} + +impl CompilerContract for Contract { + fn abi_ref(&self) -> Option<&JsonAbi> { + self.abi.as_ref() + } + fn bin_ref(&self) -> Option<&BytecodeObject> { + if let Some(ref evm) = self.evm { + evm.bytecode.as_ref().map(|c| &c.object) + } else { + None + } + } + fn bin_runtime_ref(&self) -> Option<&BytecodeObject> { + if let Some(ref evm) = self.evm { + evm.deployed_bytecode + .as_ref() + .and_then(|deployed| deployed.bytecode.as_ref().map(|evm| &evm.object)) + } else { + None + } + } +} + /// The main compiler abstraction trait. /// /// Currently mostly represents a wrapper around compiler binary aware of the version and able to @@ -259,6 +296,8 @@ pub trait Compiler: Send + Sync + Clone { type Input: CompilerInput; /// Error type returned by the compiler. type CompilationError: CompilationError; + /// Output data for each contract + type CompilerContract: CompilerContract; /// Source parser used for resolving imports and version requirements. type ParsedSource: ParsedSource; /// Compiler settings. @@ -269,7 +308,10 @@ pub trait Compiler: Send + Sync + Clone { /// Main entrypoint for the compiler. Compiles given input into [CompilerOutput]. Takes /// ownership over the input and returns back version with potential modifications made to it. /// Returned input is always the one which was seen by the binary. - fn compile(&self, input: &Self::Input) -> Result>; + fn compile( + &self, + input: &Self::Input, + ) -> Result>; /// Returns all versions available locally and remotely. Should return versions with stripped /// metadata. diff --git a/crates/compilers/src/compilers/multi.rs b/crates/compilers/src/compilers/multi.rs index 832cdf62..5a005633 100644 --- a/crates/compilers/src/compilers/multi.rs +++ b/crates/compilers/src/compilers/multi.rs @@ -17,7 +17,7 @@ use foundry_compilers_artifacts::{ output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - Error, Severity, SolcLanguage, + Contract, Error, Severity, SolcLanguage, }; use foundry_compilers_core::error::{Result, SolcError}; use semver::Version; @@ -259,8 +259,12 @@ impl Compiler for MultiCompiler { type ParsedSource = MultiCompilerParsedSource; type Settings = MultiCompilerSettings; type Language = MultiCompilerLanguage; + type CompilerContract = Contract; - fn compile(&self, input: &Self::Input) -> Result> { + fn compile( + &self, + input: &Self::Input, + ) -> Result> { match input { MultiCompilerInput::Solc(input) => { if let Some(solc) = &self.solc { diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index 0bdb6f42..2714c611 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -9,7 +9,7 @@ use foundry_compilers_artifacts::{ output_selection::OutputSelection, remappings::Remapping, sources::{Source, Sources}, - Error, Settings, Severity, SolcInput, + Contract, Error, Settings, Severity, SolcInput, }; use foundry_compilers_core::error::Result; use itertools::Itertools; @@ -44,8 +44,12 @@ impl Compiler for SolcCompiler { type ParsedSource = SolData; type Settings = SolcSettings; type Language = SolcLanguage; + type CompilerContract = Contract; - fn compile(&self, input: &Self::Input) -> Result> { + fn compile( + &self, + input: &Self::Input, + ) -> Result> { let mut solc = match self { Self::Specific(solc) => solc.clone(), diff --git a/crates/compilers/src/compilers/vyper/mod.rs b/crates/compilers/src/compilers/vyper/mod.rs index 1b351124..a9cc7f3b 100644 --- a/crates/compilers/src/compilers/vyper/mod.rs +++ b/crates/compilers/src/compilers/vyper/mod.rs @@ -2,7 +2,7 @@ use self::{input::VyperVersionedInput, parser::VyperParsedSource}; use super::{Compiler, CompilerOutput, Language}; pub use crate::artifacts::vyper::{VyperCompilationError, VyperInput, VyperOutput, VyperSettings}; use core::fmt; -use foundry_compilers_artifacts::sources::Source; +use foundry_compilers_artifacts::{sources::Source, Contract}; use foundry_compilers_core::error::{Result, SolcError}; use semver::Version; use serde::{de::DeserializeOwned, Serialize}; @@ -197,8 +197,12 @@ impl Compiler for Vyper { type ParsedSource = VyperParsedSource; type Input = VyperVersionedInput; type Language = VyperLanguage; + type CompilerContract = Contract; - fn compile(&self, input: &Self::Input) -> Result> { + fn compile( + &self, + input: &Self::Input, + ) -> Result> { self.compile(input).map(Into::into) } diff --git a/crates/compilers/src/compilers/vyper/output.rs b/crates/compilers/src/compilers/vyper/output.rs index c4f739dd..909fe099 100644 --- a/crates/compilers/src/compilers/vyper/output.rs +++ b/crates/compilers/src/compilers/vyper/output.rs @@ -1,6 +1,8 @@ +use foundry_compilers_artifacts::Contract; + use crate::artifacts::vyper::{VyperCompilationError, VyperOutput}; -impl From for super::CompilerOutput { +impl From for super::CompilerOutput { fn from(output: VyperOutput) -> Self { Self { errors: output.errors, diff --git a/crates/compilers/src/flatten.rs b/crates/compilers/src/flatten.rs index e1fdcc4b..12bb0145 100644 --- a/crates/compilers/src/flatten.rs +++ b/crates/compilers/src/flatten.rs @@ -2,7 +2,7 @@ use crate::{ compilers::{Compiler, ParsedSource}, filter::MaybeSolData, resolver::parse::SolData, - CompilerSettings, Graph, Project, ProjectPathsConfig, + ArtifactOutput, CompilerSettings, Graph, Project, ProjectPathsConfig, }; use foundry_compilers_artifacts::{ ast::{visitor::Visitor, *}, @@ -204,8 +204,8 @@ pub struct Flattener { impl Flattener { /// Compiles the target file and prepares AST and analysis data for flattening. - pub fn new( - mut project: Project, + pub fn new>( + mut project: Project, target: &Path, ) -> std::result::Result where diff --git a/crates/compilers/src/lib.rs b/crates/compilers/src/lib.rs index fc2f8c3a..d8bc8a33 100644 --- a/crates/compilers/src/lib.rs +++ b/crates/compilers/src/lib.rs @@ -52,7 +52,7 @@ use derivative::Derivative; use foundry_compilers_artifacts::solc::{ output_selection::OutputSelection, sources::{Source, SourceCompilationKind, Sources}, - Contract, Severity, SourceFile, StandardJsonCompilerInput, + Severity, SourceFile, StandardJsonCompilerInput, }; use foundry_compilers_core::error::{Result, SolcError, SolcIoError}; use output::sources::{VersionedSourceFile, VersionedSourceFiles}; @@ -69,7 +69,10 @@ use std::{ /// Represents a project workspace and handles `solc` compiling of all contracts in that workspace. #[derive(Clone, Derivative)] #[derivative(Debug)] -pub struct Project { +pub struct Project< + C: Compiler = MultiCompiler, + T: ArtifactOutput = ConfigurableArtifacts, +> { pub compiler: C, /// Compiler versions locked for specific languages. pub locked_versions: HashMap, @@ -137,14 +140,14 @@ impl Project { } } -impl Project { +impl, C: Compiler> Project { /// Returns the handler that takes care of processing all artifacts pub fn artifacts_handler(&self) -> &T { &self.artifacts } } -impl Project +impl> Project where C::Settings: Into, { @@ -190,7 +193,7 @@ where } } -impl Project { +impl, C: Compiler> Project { /// Returns the path to the artifacts directory pub fn artifacts_path(&self) -> &PathBuf { &self.paths.artifacts @@ -443,7 +446,10 @@ impl Project { } } -pub struct ProjectBuilder { +pub struct ProjectBuilder< + C: Compiler = MultiCompiler, + T: ArtifactOutput = ConfigurableArtifacts, +> { /// The layout of the paths: Option>, /// Compiler versions locked for specific languages. @@ -473,7 +479,7 @@ pub struct ProjectBuilder>, } -impl ProjectBuilder { +impl> ProjectBuilder { /// Create a new builder with the given artifacts handler pub fn new(artifacts: T) -> Self { Self { @@ -628,7 +634,10 @@ impl ProjectBuilder { } /// Set arbitrary `ArtifactOutputHandler` - pub fn artifacts(self, artifacts: A) -> ProjectBuilder { + pub fn artifacts>( + self, + artifacts: A, + ) -> ProjectBuilder { let Self { paths, cached, @@ -710,18 +719,23 @@ impl ProjectBuilder { } } -impl Default for ProjectBuilder { +impl + Default> Default + for ProjectBuilder +{ fn default() -> Self { Self::new(T::default()) } } -impl ArtifactOutput for Project { +impl, C: Compiler> ArtifactOutput + for Project +{ type Artifact = T::Artifact; + type CompilerContract = C::CompilerContract; fn on_output( &self, - contracts: &VersionedContracts, + contracts: &VersionedContracts, sources: &VersionedSourceFiles, layout: &ProjectPathsConfig, ctx: OutputContext<'_>, @@ -731,7 +745,7 @@ impl ArtifactOutput for Project { fn handle_artifacts( &self, - contracts: &VersionedContracts, + contracts: &VersionedContracts, artifacts: &Artifacts, ) -> Result<()> { self.artifacts_handler().handle_artifacts(contracts, artifacts) @@ -777,7 +791,7 @@ impl ArtifactOutput for Project { &self, file: &Path, name: &str, - contract: Contract, + contract: C::CompilerContract, source_file: Option<&SourceFile>, ) -> Self::Artifact { self.artifacts_handler().contract_to_artifact(file, name, contract, source_file) @@ -785,7 +799,7 @@ impl ArtifactOutput for Project { fn output_to_artifacts( &self, - contracts: &VersionedContracts, + contracts: &VersionedContracts, sources: &VersionedSourceFiles, ctx: OutputContext<'_>, layout: &ProjectPathsConfig, From 0133c3b4d2ca6a6650af02950ca764806a276db5 Mon Sep 17 00:00:00 2001 From: elfedy Date: Fri, 15 Nov 2024 16:16:11 -0300 Subject: [PATCH 02/11] Make build info work --- crates/compilers/src/compile/output/mod.rs | 2 +- crates/compilers/src/compilers/mod.rs | 10 +++++- crates/compilers/src/compilers/solc/mod.rs | 4 ++- .../compilers/src/compilers/vyper/output.rs | 1 + crates/compilers/src/project_util/mod.rs | 31 ++++++++++++++----- crates/compilers/tests/project.rs | 10 +++--- 6 files changed, 44 insertions(+), 14 deletions(-) diff --git a/crates/compilers/src/compile/output/mod.rs b/crates/compilers/src/compile/output/mod.rs index deaebd6d..16181db5 100644 --- a/crates/compilers/src/compile/output/mod.rs +++ b/crates/compilers/src/compile/output/mod.rs @@ -575,7 +575,7 @@ impl AggregatedCompilerOutput { let build_id = build_info.id.clone(); self.build_infos.push(build_info); - let CompilerOutput { errors, sources, contracts } = output; + let CompilerOutput { errors, sources, contracts, .. } = output; self.errors.extend(errors); for (path, source_file) in sources { diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index f2b365c0..689c78c0 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -191,6 +191,8 @@ pub struct CompilerOutput { pub contracts: FileToContractsMap, #[serde(default)] pub sources: BTreeMap, + #[serde(default)] + pub metadata: BTreeMap, } impl CompilerOutput { @@ -232,13 +234,19 @@ impl CompilerOutput { errors: self.errors.into_iter().map(op).collect(), contracts: self.contracts, sources: self.sources, + metadata: self.metadata, } } } impl Default for CompilerOutput { fn default() -> Self { - Self { errors: Vec::new(), contracts: BTreeMap::new(), sources: BTreeMap::new() } + Self { + errors: Vec::new(), + contracts: BTreeMap::new(), + sources: BTreeMap::new(), + metadata: BTreeMap::new(), + } } } diff --git a/crates/compilers/src/compilers/solc/mod.rs b/crates/compilers/src/compilers/solc/mod.rs index 2714c611..ec4b2c56 100644 --- a/crates/compilers/src/compilers/solc/mod.rs +++ b/crates/compilers/src/compilers/solc/mod.rs @@ -17,7 +17,7 @@ use semver::Version; use serde::{Deserialize, Serialize}; use std::{ borrow::Cow, - collections::BTreeSet, + collections::{BTreeMap, BTreeSet}, ops::{Deref, DerefMut}, path::{Path, PathBuf}, }; @@ -67,6 +67,7 @@ impl Compiler for SolcCompiler { errors: solc_output.errors, contracts: solc_output.contracts, sources: solc_output.sources, + metadata: BTreeMap::new(), }; Ok(output) @@ -354,6 +355,7 @@ mod tests { errors: out.errors, contracts: Default::default(), sources: Default::default(), + metadata: Default::default(), }; let v: Version = "0.8.12".parse().unwrap(); diff --git a/crates/compilers/src/compilers/vyper/output.rs b/crates/compilers/src/compilers/vyper/output.rs index 909fe099..822891c5 100644 --- a/crates/compilers/src/compilers/vyper/output.rs +++ b/crates/compilers/src/compilers/vyper/output.rs @@ -12,6 +12,7 @@ impl From for super::CompilerOutput { +pub struct TempProject< + C: Compiler = MultiCompiler, + T: ArtifactOutput = ConfigurableArtifacts, +> { /// temporary workspace root _root: TempDir, /// actual project workspace with the `root` tempdir as its root inner: Project, } -impl TempProject { +impl< + T: ArtifactOutput::CompilerContract> + Default, + > TempProject +{ /// Creates a new temp project using the provided paths and artifacts handler. /// sets the project root to a temp dir #[cfg(feature = "svm-solc")] @@ -69,7 +75,10 @@ impl TempProject { } } -impl TempProject { +impl< + T: ArtifactOutput::CompilerContract> + Default, + > TempProject +{ /// Creates a new temp project for the given `PathStyle` #[cfg(feature = "svm-solc")] pub fn with_style(prefix: &str, style: PathStyle) -> Result { @@ -81,7 +90,10 @@ impl TempProject { } } -impl fmt::Debug for TempProject { +impl< + T: ArtifactOutput::CompilerContract> + Default, + > fmt::Debug for TempProject +{ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("TempProject").field("paths", &self.inner.paths).finish() } @@ -121,7 +133,11 @@ impl TempProject { } } -impl TempProject { +impl< + C: Compiler + Default, + T: ArtifactOutput + Default, + > TempProject +{ /// Makes sure all resources are created pub fn create_new( root: TempDir, @@ -466,8 +482,9 @@ impl TempProject { } } -impl AsRef> - for TempProject +impl< + T: ArtifactOutput::CompilerContract> + Default, + > AsRef> for TempProject { fn as_ref(&self) -> &Project { self.project() diff --git a/crates/compilers/tests/project.rs b/crates/compilers/tests/project.rs index 7a89c463..331c695e 100644 --- a/crates/compilers/tests/project.rs +++ b/crates/compilers/tests/project.rs @@ -20,8 +20,8 @@ use foundry_compilers::{ ProjectBuilder, ProjectCompileOutput, ProjectPathsConfig, TestFileFilter, }; use foundry_compilers_artifacts::{ - output_selection::OutputSelection, remappings::Remapping, BytecodeHash, DevDoc, Error, - ErrorDoc, EventDoc, Libraries, MethodDoc, ModelCheckerEngine::CHC, ModelCheckerSettings, + output_selection::OutputSelection, remappings::Remapping, BytecodeHash, Contract, DevDoc, + Error, ErrorDoc, EventDoc, Libraries, MethodDoc, ModelCheckerEngine::CHC, ModelCheckerSettings, Settings, Severity, SolcInput, UserDoc, UserDocNotice, }; use foundry_compilers_core::{ @@ -403,7 +403,8 @@ contract B { } let mut build_info_count = 0; for entry in fs::read_dir(info_dir).unwrap() { let _info = - BuildInfo::>::read(&entry.unwrap().path()).unwrap(); + BuildInfo::>::read(&entry.unwrap().path()) + .unwrap(); build_info_count += 1; } assert_eq!(build_info_count, 1); @@ -445,7 +446,8 @@ contract B { } let mut build_info_count = 0; for entry in fs::read_dir(info_dir).unwrap() { let _info = - BuildInfo::>::read(&entry.unwrap().path()).unwrap(); + BuildInfo::>::read(&entry.unwrap().path()) + .unwrap(); build_info_count += 1; } assert_eq!(build_info_count, 1); From ec5ba21ca29dc499a5f96ec4d407e8af1364b3c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Rodr=C3=ADguez?= Date: Tue, 19 Nov 2024 14:08:44 -0300 Subject: [PATCH 03/11] Update crates/compilers/src/compile/output/contracts.rs Co-authored-by: Nisheeth Barthwal --- crates/compilers/src/compile/output/contracts.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/crates/compilers/src/compile/output/contracts.rs b/crates/compilers/src/compile/output/contracts.rs index 38b6a48c..857caba3 100644 --- a/crates/compilers/src/compile/output/contracts.rs +++ b/crates/compilers/src/compile/output/contracts.rs @@ -67,7 +67,6 @@ where /// ``` pub fn find_first(&self, contract_name: &str) -> Option> { self.contracts().find_map(|(name, contract)| { - //(name == contract_name).then(|| CompactContractRef::from(contract)) (name == contract_name).then(|| contract.as_compact_contract_ref()) }) } From 5b2c96418937451f948922e91d352088edbd26ec Mon Sep 17 00:00:00 2001 From: elfedy Date: Tue, 19 Nov 2024 17:17:06 -0300 Subject: [PATCH 04/11] fix docs --- crates/compilers/src/artifact_output/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/compilers/src/artifact_output/mod.rs b/crates/compilers/src/artifact_output/mod.rs index 770c9521..777a0ca4 100644 --- a/crates/compilers/src/artifact_output/mod.rs +++ b/crates/compilers/src/artifact_output/mod.rs @@ -110,7 +110,7 @@ impl ArtifactId { } } -/// Represents an artifact file representing a [`crate::Contract`] +/// Represents an artifact file representing a [`crate::compilers::CompilerContract`] #[derive(Clone, Debug, PartialEq, Eq)] pub struct ArtifactFile { /// The Artifact that was written @@ -428,7 +428,7 @@ impl Artifacts { } } -/// A trait representation for a [`crate::Contract`] artifact +/// A trait representation for a [`crate::compilers::CompilerContract`] artifact pub trait Artifact { /// Returns the artifact's [`JsonAbi`] and bytecode. fn into_inner(self) -> (Option, Option); @@ -596,7 +596,7 @@ where /// Handler invoked with the output of `solc` /// -/// Implementers of this trait are expected to take care of [`crate::Contract`] to +/// Implementers of this trait are expected to take care of [`crate::compilers::CompilerContract`] to /// [`crate::ArtifactOutput::Artifact`] conversion and how that `Artifact` type is stored on disk, /// this includes artifact file location and naming. /// From 2be52cf83b50e1fe19b101aba19f9c4aec0627da Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 27 Nov 2024 14:31:36 -0300 Subject: [PATCH 05/11] chore: relax trait bounds for VersionedContract --- crates/compilers/src/compile/output/contracts.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/crates/compilers/src/compile/output/contracts.rs b/crates/compilers/src/compile/output/contracts.rs index 857caba3..9717b857 100644 --- a/crates/compilers/src/compile/output/contracts.rs +++ b/crates/compilers/src/compile/output/contracts.rs @@ -13,14 +13,9 @@ use std::{ /// file -> [(contract name -> Contract + solc version)] #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(transparent)] -pub struct VersionedContracts( - pub FileToContractsMap>>, -); +pub struct VersionedContracts(pub FileToContractsMap>>); -impl Default for VersionedContracts -where - C: CompilerContract, -{ +impl Default for VersionedContracts { fn default() -> Self { Self(BTreeMap::new()) } @@ -284,7 +279,7 @@ where /// A contract and the compiler version used to compile it #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct VersionedContract { +pub struct VersionedContract { pub contract: C, pub version: Version, pub build_id: String, From 0a36f5798f8bb92dea9acacac3cef072b2c665ae Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 27 Nov 2024 14:41:14 -0300 Subject: [PATCH 06/11] chore: add docs to CompilerContract trait --- crates/compilers/src/compilers/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index f62e7dc2..741035bd 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -276,6 +276,7 @@ pub trait Language: const FILE_EXTENSIONS: &'static [&'static str]; } +/// Represents a compiled contract pub trait CompilerContract: Serialize + Send + Sync + Debug + Clone + Eq + Sized { fn abi_ref(&self) -> Option<&JsonAbi>; fn bin_ref(&self) -> Option<&BytecodeObject>; From 2cf53af8e4ac0bd226eb04c1b845d9f288359830 Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 27 Nov 2024 14:43:08 -0300 Subject: [PATCH 07/11] chore: update compiler output generalization comment --- crates/compilers/src/compilers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index 741035bd..e3f8d2e5 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -199,8 +199,8 @@ pub trait CompilationError: fn error_code(&self) -> Option; } -/// Output of the compiler, including contracts, sources and errors. Currently only generic over the -/// error but might be extended in the future. +/// Output of the compiler, including contracts, sources, errors and metadata. might be +/// extended to be more generic in the future. #[derive(Debug, Serialize, Deserialize)] pub struct CompilerOutput { #[serde(default = "Vec::new", skip_serializing_if = "Vec::is_empty")] From c2a6c688ae8048c3b02db8f3268c72017893000f Mon Sep 17 00:00:00 2001 From: elfedy Date: Wed, 27 Nov 2024 16:18:19 -0300 Subject: [PATCH 08/11] chore: make metadata values json objects and do not serialize if empty --- crates/compilers/src/compilers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index e3f8d2e5..73657086 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -209,8 +209,8 @@ pub struct CompilerOutput { pub contracts: FileToContractsMap, #[serde(default)] pub sources: BTreeMap, - #[serde(default)] - pub metadata: BTreeMap, + #[serde(default, skip_serializing_if = "::std::collections::BTreeMap::is_empty")] + pub metadata: BTreeMap, } impl CompilerOutput { From e36260af8acde9bbb8f2519ac7247b89d9a01c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Federico=20Rodr=C3=ADguez?= Date: Thu, 28 Nov 2024 11:30:26 -0300 Subject: [PATCH 09/11] Update crates/compilers/src/compilers/mod.rs Co-authored-by: Arsenii Kulikov --- crates/compilers/src/compilers/mod.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index 73657086..e1614859 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -278,8 +278,13 @@ pub trait Language: /// Represents a compiled contract pub trait CompilerContract: Serialize + Send + Sync + Debug + Clone + Eq + Sized { + /// Reference to contract ABI fn abi_ref(&self) -> Option<&JsonAbi>; + + //// Reference to contract bytecode fn bin_ref(&self) -> Option<&BytecodeObject>; + + //// Reference to contract runtime bytecode fn bin_runtime_ref(&self) -> Option<&BytecodeObject>; fn as_compact_contract_ref(&self) -> CompactContractRef<'_> { From 83738c1f64f1b08032667f175654ba1c07ca70c4 Mon Sep 17 00:00:00 2001 From: elfedy Date: Fri, 29 Nov 2024 10:32:34 -0300 Subject: [PATCH 10/11] chore: cargo fmt --- crates/compilers/src/compilers/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/compilers/src/compilers/mod.rs b/crates/compilers/src/compilers/mod.rs index e1614859..5abb74b7 100644 --- a/crates/compilers/src/compilers/mod.rs +++ b/crates/compilers/src/compilers/mod.rs @@ -280,10 +280,10 @@ pub trait Language: pub trait CompilerContract: Serialize + Send + Sync + Debug + Clone + Eq + Sized { /// Reference to contract ABI fn abi_ref(&self) -> Option<&JsonAbi>; - + //// Reference to contract bytecode fn bin_ref(&self) -> Option<&BytecodeObject>; - + //// Reference to contract runtime bytecode fn bin_runtime_ref(&self) -> Option<&BytecodeObject>; From 3bfee72bdb801a52e2e8b0c69fbff98fe534f052 Mon Sep 17 00:00:00 2001 From: elfedy Date: Fri, 29 Nov 2024 18:39:04 -0300 Subject: [PATCH 11/11] chore: cargo fmt (nightly) --- crates/compilers/src/artifact_output/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/compilers/src/artifact_output/mod.rs b/crates/compilers/src/artifact_output/mod.rs index 777a0ca4..d111d07c 100644 --- a/crates/compilers/src/artifact_output/mod.rs +++ b/crates/compilers/src/artifact_output/mod.rs @@ -596,9 +596,9 @@ where /// Handler invoked with the output of `solc` /// -/// Implementers of this trait are expected to take care of [`crate::compilers::CompilerContract`] to -/// [`crate::ArtifactOutput::Artifact`] conversion and how that `Artifact` type is stored on disk, -/// this includes artifact file location and naming. +/// Implementers of this trait are expected to take care of [`crate::compilers::CompilerContract`] +/// to [`crate::ArtifactOutput::Artifact`] conversion and how that `Artifact` type is stored on +/// disk, this includes artifact file location and naming. /// /// Depending on the [`crate::Project`] contracts and their compatible versions, /// The project compiler may invoke different `solc` executables on the same