Skip to content

Commit 0b1a763

Browse files
committed
Merge branch 'main' of github.com:foundry-rs/compilers into elfedy-compiler-output
2 parents 0133c3b + b5c2a49 commit 0b1a763

File tree

27 files changed

+1070
-600
lines changed

27 files changed

+1070
-600
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ semver = { version = "1.0", features = ["serde"] }
5151
serde = { version = "1", features = ["derive", "rc"] }
5252
serde_json = "1.0"
5353
similar-asserts = "1"
54-
solang-parser = { version = "=0.3.3", default-features = false }
54+
solar-parse = { version = "=0.1.0", default-features = false }
5555
svm = { package = "svm-rs", version = "0.5", default-features = false }
5656
tempfile = "3.9"
5757
thiserror = "1"

crates/artifacts/solc/src/contract.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -455,7 +455,7 @@ pub struct CompactContractRefSome<'a> {
455455
pub bin_runtime: &'a BytecodeObject,
456456
}
457457

458-
impl<'a> CompactContractRefSome<'a> {
458+
impl CompactContractRefSome<'_> {
459459
/// Returns the individual parts of this contract.
460460
///
461461
/// If the values are `None`, then `Default` is returned.

crates/artifacts/solc/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ impl<'de> Deserialize<'de> for LosslessMetadata {
11501150
{
11511151
struct LosslessMetadataVisitor;
11521152

1153-
impl<'de> Visitor<'de> for LosslessMetadataVisitor {
1153+
impl Visitor<'_> for LosslessMetadataVisitor {
11541154
type Value = LosslessMetadata;
11551155

11561156
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {

crates/artifacts/solc/src/sourcemap.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ enum Token<'a> {
9292
Regular,
9393
}
9494

95-
impl<'a> fmt::Debug for Token<'a> {
95+
impl fmt::Debug for Token<'_> {
9696
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9797
match self {
9898
Token::Number(s) => write!(f, "NUMBER({s:?})"),
@@ -105,7 +105,7 @@ impl<'a> fmt::Debug for Token<'a> {
105105
}
106106
}
107107

108-
impl<'a> fmt::Display for Token<'a> {
108+
impl fmt::Display for Token<'_> {
109109
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110110
match self {
111111
Token::Number(_) => write!(f, "number"),
@@ -531,7 +531,7 @@ impl<'input> Parser<'input> {
531531
}
532532
}
533533

534-
impl<'input> Iterator for Parser<'input> {
534+
impl Iterator for Parser<'_> {
535535
type Item = Result<SourceElement, SyntaxError>;
536536

537537
fn next(&mut self) -> Option<Self::Item> {

crates/compilers/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ md-5.workspace = true
2828
thiserror.workspace = true
2929
path-slash.workspace = true
3030
yansi.workspace = true
31-
solang-parser.workspace = true
31+
solar-parse.workspace = true
3232
once_cell = { workspace = true, optional = true }
3333
futures-util = { workspace = true, optional = true }
3434
tokio = { workspace = true, optional = true }

crates/compilers/src/artifact_output/mod.rs

Lines changed: 75 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ mod hh;
3232
pub use hh::*;
3333

3434
use crate::{
35-
cache::{CachedArtifact, CompilerCache},
35+
cache::{CachedArtifacts, CompilerCache},
3636
output::{
3737
contracts::VersionedContracts,
3838
sources::{VersionedSourceFile, VersionedSourceFiles},
@@ -52,6 +52,7 @@ pub struct ArtifactId {
5252
pub version: Version,
5353
/// `solc` build id
5454
pub build_id: String,
55+
pub profile: String,
5556
}
5657

5758
impl ArtifactId {
@@ -119,6 +120,7 @@ pub struct ArtifactFile<T> {
119120
/// `solc` version that produced this artifact
120121
pub version: Version,
121122
pub build_id: String,
123+
pub profile: String,
122124
}
123125

124126
impl<T: Serialize> ArtifactFile<T> {
@@ -298,6 +300,7 @@ impl<T> Artifacts<T> {
298300
source: source.clone(),
299301
version: artifact.version.clone(),
300302
build_id: artifact.build_id.clone(),
303+
profile: artifact.profile.clone(),
301304
}
302305
.with_slashed_paths(),
303306
&artifact.artifact,
@@ -324,6 +327,7 @@ impl<T> Artifacts<T> {
324327
source: source.clone(),
325328
version: artifact.version,
326329
build_id: artifact.build_id.clone(),
330+
profile: artifact.profile.clone(),
327331
}
328332
.with_slashed_paths(),
329333
artifact.artifact,
@@ -643,14 +647,22 @@ pub trait ArtifactOutput {
643647

644648
/// Returns the file name for the contract's artifact
645649
/// `Greeter.json`
646-
fn output_file_name(name: &str) -> PathBuf {
647-
format!("{name}.json").into()
648-
}
649-
650-
/// Returns the file name for the contract's artifact and the given version
651-
/// `Greeter.0.8.11.json`
652-
fn output_file_name_versioned(name: &str, version: &Version) -> PathBuf {
653-
format!("{}.{}.{}.{}.json", name, version.major, version.minor, version.patch).into()
650+
fn output_file_name(
651+
name: &str,
652+
version: &Version,
653+
profile: &str,
654+
with_version: bool,
655+
with_profile: bool,
656+
) -> PathBuf {
657+
let mut name = name.to_string();
658+
if with_version {
659+
name.push_str(&format!(".{}.{}.{}", version.major, version.minor, version.patch));
660+
}
661+
if with_profile {
662+
name.push_str(&format!(".{profile}"));
663+
}
664+
name.push_str(".json");
665+
name.into()
654666
}
655667

656668
/// Returns the appropriate file name for the conflicting file.
@@ -725,24 +737,23 @@ pub trait ArtifactOutput {
725737
/// Returns the path to the contract's artifact location based on the contract's file and name
726738
///
727739
/// This returns `contract.sol/contract.json` by default
728-
fn output_file(contract_file: &Path, name: &str) -> PathBuf {
729-
contract_file
730-
.file_name()
731-
.map(Path::new)
732-
.map(|p| p.join(Self::output_file_name(name)))
733-
.unwrap_or_else(|| Self::output_file_name(name))
734-
}
735-
736-
/// Returns the path to the contract's artifact location based on the contract's file, name and
737-
/// version
738-
///
739-
/// This returns `contract.sol/contract.0.8.11.json` by default
740-
fn output_file_versioned(contract_file: &Path, name: &str, version: &Version) -> PathBuf {
740+
fn output_file(
741+
contract_file: &Path,
742+
name: &str,
743+
version: &Version,
744+
profile: &str,
745+
with_version: bool,
746+
with_profile: bool,
747+
) -> PathBuf {
741748
contract_file
742749
.file_name()
743750
.map(Path::new)
744-
.map(|p| p.join(Self::output_file_name_versioned(name, version)))
745-
.unwrap_or_else(|| Self::output_file_name_versioned(name, version))
751+
.map(|p| {
752+
p.join(Self::output_file_name(name, version, profile, with_version, with_profile))
753+
})
754+
.unwrap_or_else(|| {
755+
Self::output_file_name(name, version, profile, with_version, with_profile)
756+
})
746757
}
747758

748759
/// The inverse of `contract_file_name`
@@ -753,11 +764,6 @@ pub trait ArtifactOutput {
753764
file.file_stem().and_then(|s| s.to_str().map(|s| s.to_string()))
754765
}
755766

756-
/// Whether the corresponding artifact of the given contract file and name exists
757-
fn output_exists(contract_file: &Path, name: &str, root: &Path) -> bool {
758-
root.join(Self::output_file(contract_file, name)).exists()
759-
}
760-
761767
/// Read the artifact that's stored at the given path
762768
///
763769
/// # Errors
@@ -801,28 +807,27 @@ pub trait ArtifactOutput {
801807

802808
/// Generates a path for an artifact based on already taken paths by either cached or compiled
803809
/// artifacts.
810+
#[allow(clippy::too_many_arguments)]
804811
fn get_artifact_path(
805812
ctx: &OutputContext<'_>,
806813
already_taken: &HashSet<String>,
807814
file: &Path,
808815
name: &str,
809816
artifacts_folder: &Path,
810817
version: &Version,
811-
versioned: bool,
818+
profile: &str,
819+
with_version: bool,
820+
with_profile: bool,
812821
) -> PathBuf {
813822
// if an artifact for the contract already exists (from a previous compile job)
814823
// we reuse the path, this will make sure that even if there are conflicting
815824
// files (files for witch `T::output_file()` would return the same path) we use
816825
// consistent output paths
817-
if let Some(existing_artifact) = ctx.existing_artifact(file, name, version) {
826+
if let Some(existing_artifact) = ctx.existing_artifact(file, name, version, profile) {
818827
trace!("use existing artifact file {:?}", existing_artifact,);
819828
existing_artifact.to_path_buf()
820829
} else {
821-
let path = if versioned {
822-
Self::output_file_versioned(file, name, version)
823-
} else {
824-
Self::output_file(file, name)
825-
};
830+
let path = Self::output_file(file, name, version, profile, with_version, with_profile);
826831

827832
let path = artifacts_folder.join(path);
828833

@@ -855,7 +860,9 @@ pub trait ArtifactOutput {
855860
let mut taken_paths_lowercase = ctx
856861
.existing_artifacts
857862
.values()
858-
.flat_map(|artifacts| artifacts.values().flat_map(|artifacts| artifacts.values()))
863+
.flat_map(|artifacts| artifacts.values())
864+
.flat_map(|artifacts| artifacts.values())
865+
.flat_map(|artifacts| artifacts.values())
859866
.map(|a| a.path.to_slash_lossy().to_lowercase())
860867
.collect::<HashSet<_>>();
861868

@@ -866,22 +873,26 @@ pub trait ArtifactOutput {
866873
});
867874
for file in files {
868875
for (name, versioned_contracts) in &contracts[file] {
876+
let unique_versions =
877+
versioned_contracts.iter().map(|c| &c.version).collect::<HashSet<_>>();
878+
let unique_profiles =
879+
versioned_contracts.iter().map(|c| &c.profile).collect::<HashSet<_>>();
869880
for contract in versioned_contracts {
881+
non_standalone_sources.insert(file);
882+
870883
// track `SourceFile`s that can be mapped to contracts
871884
let source_file = sources.find_file_and_version(file, &contract.version);
872885

873-
if let Some(source) = source_file {
874-
non_standalone_sources.insert((source.id, &contract.version));
875-
}
876-
877886
let artifact_path = Self::get_artifact_path(
878887
&ctx,
879888
&taken_paths_lowercase,
880889
file,
881890
name,
882891
layout.artifacts.as_path(),
883892
&contract.version,
884-
versioned_contracts.len() > 1,
893+
&contract.profile,
894+
unique_versions.len() > 1,
895+
unique_profiles.len() > 1,
885896
);
886897

887898
taken_paths_lowercase.insert(artifact_path.to_slash_lossy().to_lowercase());
@@ -905,6 +916,7 @@ pub trait ArtifactOutput {
905916
file: artifact_path,
906917
version: contract.version.clone(),
907918
build_id: contract.build_id.clone(),
919+
profile: contract.profile.clone(),
908920
};
909921

910922
artifacts
@@ -922,8 +934,10 @@ pub trait ArtifactOutput {
922934
// any contract definition, which are not included in the `CompilerOutput` but we want to
923935
// create Artifacts for them regardless
924936
for (file, sources) in sources.as_ref().iter() {
937+
let unique_versions = sources.iter().map(|s| &s.version).collect::<HashSet<_>>();
938+
let unique_profiles = sources.iter().map(|s| &s.profile).collect::<HashSet<_>>();
925939
for source in sources {
926-
if !non_standalone_sources.contains(&(source.source_file.id, &source.version)) {
940+
if !non_standalone_sources.contains(file) {
927941
// scan the ast as a safe measure to ensure this file does not include any
928942
// source units
929943
// there's also no need to create a standalone artifact for source files that
@@ -946,26 +960,26 @@ pub trait ArtifactOutput {
946960
name,
947961
&layout.artifacts,
948962
&source.version,
949-
sources.len() > 1,
963+
&source.profile,
964+
unique_versions.len() > 1,
965+
unique_profiles.len() > 1,
950966
);
951967

952-
let entries = artifacts
968+
taken_paths_lowercase
969+
.insert(artifact_path.to_slash_lossy().to_lowercase());
970+
971+
artifacts
953972
.entry(file.clone())
954973
.or_default()
955974
.entry(name.to_string())
956-
.or_default();
957-
958-
if entries.iter().all(|entry| entry.version != source.version) {
959-
taken_paths_lowercase
960-
.insert(artifact_path.to_slash_lossy().to_lowercase());
961-
962-
entries.push(ArtifactFile {
975+
.or_default()
976+
.push(ArtifactFile {
963977
artifact,
964978
file: artifact_path,
965979
version: source.version.clone(),
966980
build_id: source.build_id.clone(),
981+
profile: source.profile.clone(),
967982
});
968-
}
969983
}
970984
}
971985
}
@@ -1016,8 +1030,7 @@ pub struct OutputContext<'a> {
10161030
/// └── inner
10171031
/// └── a.sol
10181032
/// ```
1019-
pub existing_artifacts:
1020-
BTreeMap<&'a Path, &'a BTreeMap<String, BTreeMap<Version, CachedArtifact>>>,
1033+
pub existing_artifacts: BTreeMap<&'a Path, &'a CachedArtifacts>,
10211034
}
10221035

10231036
// === impl OutputContext
@@ -1043,13 +1056,14 @@ impl<'a> OutputContext<'a> {
10431056
file: &Path,
10441057
contract: &str,
10451058
version: &Version,
1059+
profile: &str,
10461060
) -> Option<&Path> {
1047-
self.existing_artifacts.get(file).and_then(|contracts| {
1048-
contracts
1049-
.get(contract)
1050-
.and_then(|versions| versions.get(version))
1051-
.map(|a| a.path.as_path())
1052-
})
1061+
self.existing_artifacts
1062+
.get(file)
1063+
.and_then(|contracts| contracts.get(contract))
1064+
.and_then(|versions| versions.get(version))
1065+
.and_then(|profiles| profiles.get(profile))
1066+
.map(|a| a.path.as_path())
10531067
}
10541068
}
10551069

0 commit comments

Comments
 (0)