Files
revive/crates/solc-json-interface/src/standard_json/input/mod.rs
T
xermicus 497dae2494 factor out solc JSON interface crate (#264)
The differential testing framework will make a second consumer. There
seems to be no re-usable Rust crate for this. But we already have
everything here, just needs a small refactor to make it fully re-usable.

- Mostly decouple the solc JSON-input-output interface types from the
`solidity` frontend crate
- Expose the JSON-input-output interface types in a dedicated crate

---------

Signed-off-by: Cyrill Leutwiler <bigcyrill@hotmail.com>
2025-03-20 17:11:40 +01:00

142 lines
4.7 KiB
Rust

//! The `solc --standard-json` input.
pub mod language;
pub mod settings;
pub mod source;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::path::PathBuf;
#[cfg(all(feature = "parallel", feature = "resolc"))]
use rayon::iter::{IntoParallelIterator, ParallelIterator};
use serde::Deserialize;
use serde::Serialize;
use crate::standard_json::input::settings::metadata::Metadata as SolcStandardJsonInputSettingsMetadata;
use crate::standard_json::input::settings::optimizer::Optimizer as SolcStandardJsonInputSettingsOptimizer;
use crate::standard_json::input::settings::selection::Selection as SolcStandardJsonInputSettingsSelection;
#[cfg(feature = "resolc")]
use crate::warning::Warning;
use self::language::Language;
use self::settings::Settings;
use self::source::Source;
/// The `solc --standard-json` input.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Input {
/// The input language.
pub language: Language,
/// The input source code files hashmap.
pub sources: BTreeMap<String, Source>,
/// The compiler settings.
pub settings: Settings,
/// The suppressed warnings.
#[cfg(feature = "resolc")]
#[serde(skip_serializing)]
pub suppressed_warnings: Option<Vec<Warning>>,
}
impl Input {
/// A shortcut constructor from stdin.
pub fn try_from_stdin() -> anyhow::Result<Self> {
let mut input: Self = serde_json::from_reader(std::io::BufReader::new(std::io::stdin()))?;
input
.settings
.output_selection
.get_or_insert_with(SolcStandardJsonInputSettingsSelection::default)
.extend_with_required();
Ok(input)
}
/// A shortcut constructor from paths.
#[allow(clippy::too_many_arguments)]
pub fn try_from_paths(
language: Language,
evm_version: Option<revive_common::EVMVersion>,
paths: &[PathBuf],
library_map: Vec<String>,
remappings: Option<BTreeSet<String>>,
output_selection: SolcStandardJsonInputSettingsSelection,
optimizer: SolcStandardJsonInputSettingsOptimizer,
metadata: Option<SolcStandardJsonInputSettingsMetadata>,
#[cfg(feature = "resolc")] suppressed_warnings: Option<Vec<Warning>>,
) -> anyhow::Result<Self> {
let mut paths: BTreeSet<PathBuf> = paths.iter().cloned().collect();
let libraries = Settings::parse_libraries(library_map)?;
for library_file in libraries.keys() {
paths.insert(PathBuf::from(library_file));
}
let sources = paths
.iter()
.map(|path| {
let source = Source::try_from(path.as_path()).unwrap_or_else(|error| {
panic!("Source code file {path:?} reading error: {error}")
});
(path.to_string_lossy().to_string(), source)
})
.collect();
Ok(Self {
language,
sources,
settings: Settings::new(
evm_version,
libraries,
remappings,
output_selection,
optimizer,
metadata,
),
#[cfg(feature = "resolc")]
suppressed_warnings,
})
}
/// A shortcut constructor from source code.
/// Only for the integration test purposes.
#[cfg(feature = "resolc")]
#[allow(clippy::too_many_arguments)]
pub fn try_from_sources(
evm_version: Option<revive_common::EVMVersion>,
sources: BTreeMap<String, String>,
libraries: BTreeMap<String, BTreeMap<String, String>>,
remappings: Option<BTreeSet<String>>,
output_selection: SolcStandardJsonInputSettingsSelection,
optimizer: SolcStandardJsonInputSettingsOptimizer,
metadata: Option<SolcStandardJsonInputSettingsMetadata>,
suppressed_warnings: Option<Vec<Warning>>,
) -> anyhow::Result<Self> {
#[cfg(feature = "parallel")]
let iter = sources.into_par_iter(); // Parallel iterator
#[cfg(not(feature = "parallel"))]
let iter = sources.into_iter(); // Sequential iterator
let sources = iter
.map(|(path, content)| (path, Source::from(content)))
.collect();
Ok(Self {
language: Language::Solidity,
sources,
settings: Settings::new(
evm_version,
libraries,
remappings,
output_selection,
optimizer,
metadata,
),
suppressed_warnings,
})
}
/// Sets the necessary defaults.
pub fn normalize(&mut self, version: &semver::Version) {
self.settings.normalize(version);
}
}