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

refactor: make Contract generic for Compiler and add metadata to CompilerOutput #224

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
3 changes: 2 additions & 1 deletion crates/compilers/src/artifact_output/configurable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Contract>,
artifacts: &crate::Artifacts<Self::Artifact>,
) -> Result<(), SolcError> {
for (file, contracts) in contracts.as_ref().iter() {
Expand Down
1 change: 1 addition & 0 deletions crates/compilers/src/artifact_output/hh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct HardhatArtifacts {

impl ArtifactOutput for HardhatArtifacts {
type Artifact = HardhatArtifact;
type CompilerContract = Contract;

fn contract_to_artifact(
&self,
Expand Down
25 changes: 14 additions & 11 deletions crates/compilers/src/artifact_output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use crate::{
contracts::VersionedContracts,
sources::{VersionedSourceFile, VersionedSourceFiles},
},
ProjectPathsConfig,
CompilerContract, ProjectPathsConfig,
};

/// Represents unique artifact metadata for identifying artifacts on output
Expand Down Expand Up @@ -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<T> {
/// The Artifact that was written
Expand Down Expand Up @@ -428,7 +428,7 @@ impl<T> Artifacts<T> {
}
}

/// 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<JsonAbi>, Option<Bytes>);
Expand Down Expand Up @@ -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.
///
Expand All @@ -609,16 +609,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<C>(
fn on_output<L>(
&self,
contracts: &VersionedContracts,
contracts: &VersionedContracts<Self::CompilerContract>,
sources: &VersionedSourceFiles,
layout: &ProjectPathsConfig<C>,
layout: &ProjectPathsConfig<L>,
ctx: OutputContext<'_>,
) -> Result<Artifacts<Self::Artifact>> {
let mut artifacts = self.output_to_artifacts(contracts, sources, ctx, layout);
Expand All @@ -638,7 +639,7 @@ pub trait ArtifactOutput {
/// Invoked after artifacts has been written to disk for additional processing.
fn handle_artifacts(
&self,
_contracts: &VersionedContracts,
_contracts: &VersionedContracts<Self::CompilerContract>,
_artifacts: &Artifacts<Self::Artifact>,
) -> Result<()> {
Ok(())
Expand Down Expand Up @@ -800,7 +801,7 @@ pub trait ArtifactOutput {
&self,
_file: &Path,
_name: &str,
contract: Contract,
contract: Self::CompilerContract,
source_file: Option<&SourceFile>,
) -> Self::Artifact;

Expand Down Expand Up @@ -845,7 +846,7 @@ pub trait ArtifactOutput {
/// [`Self::on_output()`]
fn output_to_artifacts<C>(
&self,
contracts: &VersionedContracts,
contracts: &VersionedContracts<Self::CompilerContract>,
sources: &VersionedSourceFiles,
ctx: OutputContext<'_>,
layout: &ProjectPathsConfig<C>,
Expand Down Expand Up @@ -1083,6 +1084,7 @@ pub struct MinimalCombinedArtifacts {

impl ArtifactOutput for MinimalCombinedArtifacts {
type Artifact = CompactContractBytecode;
type CompilerContract = Contract;

fn contract_to_artifact(
&self,
Expand Down Expand Up @@ -1112,10 +1114,11 @@ pub struct MinimalCombinedArtifactsHardhatFallback {

impl ArtifactOutput for MinimalCombinedArtifactsHardhatFallback {
type Artifact = CompactContractBytecode;
type CompilerContract = Contract;

fn on_output<C>(
&self,
output: &VersionedContracts,
output: &VersionedContracts<Contract>,
sources: &VersionedSourceFiles,
layout: &ProjectPathsConfig<C>,
ctx: OutputContext<'_>,
Expand Down
16 changes: 9 additions & 7 deletions crates/compilers/src/buildinfo.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -43,7 +45,7 @@ pub struct BuildContext<L> {
}

impl<L: Language> BuildContext<L> {
pub fn new<I, E>(input: &I, output: &CompilerOutput<E>) -> Result<Self>
pub fn new<I, E, C>(input: &I, output: &CompilerOutput<E, C>) -> Result<Self>
where
I: CompilerInput<Language = L>,
{
Expand Down Expand Up @@ -87,9 +89,9 @@ pub struct RawBuildInfo<L> {

impl<L: Language> RawBuildInfo<L> {
/// Serializes a `BuildInfo` object
pub fn new<I: CompilerInput<Language = L>, E: CompilationError>(
pub fn new<I: CompilerInput<Language = L>, E: CompilationError, C: CompilerContract>(
input: &I,
output: &CompilerOutput<E>,
output: &CompilerOutput<E, C>,
full_build_info: bool,
) -> Result<Self> {
let version = input.version().clone();
Expand Down Expand Up @@ -130,7 +132,7 @@ impl<L: Language> RawBuildInfo<L> {
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]
Expand All @@ -142,9 +144,9 @@ mod tests {
SolcLanguage::Solidity,
v,
);
let output = CompilerOutput::<Error>::default();
let output = CompilerOutput::<Error, Contract>::default();
let raw_info = RawBuildInfo::new(&input, &output, true).unwrap();
let _info: BuildInfo<SolcVersionedInput, CompilerOutput<Error>> =
let _info: BuildInfo<SolcVersionedInput, CompilerOutput<Error, Contract>> =
serde_json::from_str(&serde_json::to_string(&raw_info).unwrap()).unwrap();
}
}
22 changes: 17 additions & 5 deletions crates/compilers/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,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<CompilerContract = C::CompilerContract>,
C: Compiler,
> {
/// The preexisting cache file.
pub cache: CompilerCache<C::Settings>,

Expand Down Expand Up @@ -652,7 +656,9 @@ pub(crate) struct ArtifactsCacheInner<'a, T: ArtifactOutput, C: Compiler> {
pub content_hashes: HashMap<PathBuf, String>,
}

impl<T: ArtifactOutput, C: Compiler> ArtifactsCacheInner<'_, T, C> {
impl<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>
ArtifactsCacheInner<'_, T, C>
{
/// Creates a new cache entry for the file
fn create_cache_entry(&mut self, file: PathBuf, source: &Source) {
let imports = self
Expand Down Expand Up @@ -907,20 +913,26 @@ impl<T: ArtifactOutput, C: Compiler> ArtifactsCacheInner<'_, 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<CompilerContract = C::CompilerContract>,
C: Compiler,
> {
/// Cache nothing on disk
Ephemeral(GraphEdges<C::ParsedSource>, &'a Project<C, T>),
/// 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<CompilerContract = C::CompilerContract>, C: Compiler>
ArtifactsCache<'a, T, C>
{
/// Create a new cache instance with the given files
pub fn new(project: &'a Project<C, T>, edges: GraphEdges<C::ParsedSource>) -> Result<Self> {
/// Returns the [CompilerCache] to use
///
/// Returns a new empty cache if the cache does not exist or `invalidate_cache` is set.
fn get_cache<T: ArtifactOutput, C: Compiler>(
fn get_cache<T: ArtifactOutput<CompilerContract = C::CompilerContract>, C: Compiler>(
project: &Project<C, T>,
invalidate_cache: bool,
) -> CompilerCache<C::Settings> {
Expand Down
Loading