Skip to content

Commit

Permalink
feat(solc): store source files with their solc version (gakonst#1231)
Browse files Browse the repository at this point in the history
* feat(solc): add versioned sources

* feat(solc): support versioned sources
  • Loading branch information
mattsse committed May 6, 2022
1 parent c7765e1 commit 44cbbc7
Show file tree
Hide file tree
Showing 8 changed files with 298 additions and 30 deletions.
24 changes: 14 additions & 10 deletions ethers-solc/src/artifact_output/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Output artifact handling

use crate::{
artifacts::FileToContractsMap, contracts::VersionedContracts, error::Result, utils,
HardhatArtifact, ProjectPathsConfig, SolcError,
artifacts::FileToContractsMap, error::Result, utils, HardhatArtifact, ProjectPathsConfig,
SolcError,
};
use ethers_core::{abi::Abi, types::Bytes};
use semver::Version;
Expand All @@ -15,10 +15,13 @@ use std::{
};

mod configurable;
use crate::artifacts::{
contract::{CompactContract, CompactContractBytecode, Contract},
BytecodeObject, CompactBytecode, CompactContractBytecodeCow, CompactDeployedBytecode,
SourceFile,
use crate::{
artifacts::{
contract::{CompactContract, CompactContractBytecode, Contract},
BytecodeObject, CompactBytecode, CompactContractBytecodeCow, CompactDeployedBytecode,
SourceFile,
},
compile::output::{contracts::VersionedContracts, sources::VersionedSourceFiles},
};
pub use configurable::*;

Expand Down Expand Up @@ -447,7 +450,7 @@ pub trait ArtifactOutput {
fn on_output(
&self,
contracts: &VersionedContracts,
sources: &BTreeMap<String, SourceFile>,
sources: &VersionedSourceFiles,
layout: &ProjectPathsConfig,
) -> Result<Artifacts<Self::Artifact>> {
let mut artifacts = self.output_to_artifacts(contracts, sources);
Expand Down Expand Up @@ -609,16 +612,17 @@ pub trait ArtifactOutput {
fn output_to_artifacts(
&self,
contracts: &VersionedContracts,
sources: &BTreeMap<String, SourceFile>,
sources: &VersionedSourceFiles,
) -> Artifacts<Self::Artifact> {
let mut artifacts = ArtifactsMap::new();
for (file, contracts) in contracts.as_ref().iter() {
let source_file = sources.get(file);
let mut entries = BTreeMap::new();
for (name, versioned_contracts) in contracts {
let mut contracts = Vec::with_capacity(versioned_contracts.len());
// check if the same contract compiled with multiple solc versions
for contract in versioned_contracts {
let source_file = sources.find_file_and_version(file, &contract.version);

let artifact_path = if versioned_contracts.len() > 1 {
Self::output_file_versioned(file, name, &contract.version)
} else {
Expand Down Expand Up @@ -689,7 +693,7 @@ impl ArtifactOutput for MinimalCombinedArtifactsHardhatFallback {
fn on_output(
&self,
output: &VersionedContracts,
sources: &BTreeMap<String, SourceFile>,
sources: &VersionedSourceFiles,
layout: &ProjectPathsConfig,
) -> Result<Artifacts<Self::Artifact>> {
MinimalCombinedArtifacts::default().on_output(output, sources, layout)
Expand Down
4 changes: 2 additions & 2 deletions ethers-solc/src/artifacts/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ pub type Contracts = FileToContractsMap<Contract>;
pub type Sources = BTreeMap<PathBuf, Source>;

/// A set of different Solc installations with their version and the sources to be compiled
pub type VersionedSources = BTreeMap<Solc, (Version, Sources)>;
pub(crate) type VersionedSources = BTreeMap<Solc, (Version, Sources)>;

/// A set of different Solc installations with their version and the sources to be compiled
pub type VersionedFilteredSources = BTreeMap<Solc, (Version, FilteredSources)>;
pub(crate) type VersionedFilteredSources = BTreeMap<Solc, (Version, FilteredSources)>;

const SOLIDITY: &str = "Solidity";

Expand Down
4 changes: 1 addition & 3 deletions ethers-solc/src/compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,16 @@ use crate::{
};
use semver::{Version, VersionReq};
use serde::{de::DeserializeOwned, Deserialize, Serialize};

use std::{
fmt,
io::BufRead,
path::{Path, PathBuf},
process::{Command, Output, Stdio},
str::FromStr,
};

pub mod contracts;
pub mod many;
pub mod output;
pub use output::{contracts, sources};
pub mod project;

/// The name of the `solc` binary on the system
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,18 @@
use crate::{
artifacts::{
contract::{CompactContractBytecode, CompactContractRef, Contract},
Error, SourceFile, SourceFiles,
Error,
},
contracts::{VersionedContract, VersionedContracts},
sources::{VersionedSourceFile, VersionedSourceFiles},
ArtifactId, ArtifactOutput, Artifacts, CompilerOutput, ConfigurableArtifacts,
};
use contracts::{VersionedContract, VersionedContracts};
use semver::Version;
use std::{collections::BTreeMap, fmt, path::Path};

pub mod contracts;
pub mod sources;

/// Contains a mixture of already compiled/cached artifacts and the input set of sources that still
/// need to be compiled.
#[derive(Debug, Clone, PartialEq, Default)]
Expand Down Expand Up @@ -69,15 +73,17 @@ impl<T: ArtifactOutput> ProjectCompileOutput<T> {
}

/// All artifacts together with their ID and the sources of the project.
pub fn into_artifacts_with_sources(self) -> (BTreeMap<ArtifactId, T::Artifact>, SourceFiles) {
pub fn into_artifacts_with_sources(
self,
) -> (BTreeMap<ArtifactId, T::Artifact>, VersionedSourceFiles) {
let Self { cached_artifacts, compiled_artifacts, compiler_output, .. } = self;

(
cached_artifacts
.into_artifacts::<T>()
.chain(compiled_artifacts.into_artifacts::<T>())
.collect(),
SourceFiles(compiler_output.sources),
compiler_output.sources,
)
}

Expand Down Expand Up @@ -228,8 +234,8 @@ impl<T: ArtifactOutput> fmt::Display for ProjectCompileOutput<T> {
pub struct AggregatedCompilerOutput {
/// all errors from all `CompilerOutput`
pub errors: Vec<Error>,
/// All source files
pub sources: BTreeMap<String, SourceFile>,
/// 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,
}
Expand Down Expand Up @@ -274,10 +280,15 @@ impl AggregatedCompilerOutput {

/// adds a new `CompilerOutput` to the aggregated output
pub fn extend(&mut self, version: Version, output: CompilerOutput) {
self.errors.extend(output.errors);
self.sources.extend(output.sources);
let CompilerOutput { errors, sources, contracts } = output;
self.errors.extend(errors);

for (path, source_file) in sources {
let sources = self.sources.as_mut().entry(path).or_default();
sources.push(VersionedSourceFile { source_file, version: version.clone() });
}

for (file_name, new_contracts) in output.contracts {
for (file_name, new_contracts) in contracts {
let contracts = self.contracts.as_mut().entry(file_name).or_default();
for (contract_name, contract) in new_contracts {
let versioned = contracts.entry(contract_name).or_default();
Expand Down Expand Up @@ -346,8 +357,8 @@ impl AggregatedCompilerOutput {
/// let (sources, contracts) = output.split();
/// # }
/// ```
pub fn split(self) -> (SourceFiles, VersionedContracts) {
(SourceFiles(self.sources), self.contracts)
pub fn split(self) -> (VersionedSourceFiles, VersionedContracts) {
(self.sources, self.contracts)
}
}

Expand Down
Loading

0 comments on commit 44cbbc7

Please sign in to comment.