mirror of
https://github.com/pezkuwichain/revive.git
synced 2026-06-14 22:41:07 +00:00
Fix output selection issues for Foundry (#386)
### Description Fixes output selection issues for `Foundry` usage. - pruning to look at per file settings - source to include `ast` ### Note `Selection.files` field is reintroduced because that's the way `foundry` functions. it uses per-file output selection --------- Co-authored-by: xermicus <cyrill@parity.io>
This commit is contained in:
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- `standard_json.output_selection` to also look at per file settings.
|
||||||
|
|
||||||
This is a development pre-release.
|
This is a development pre-release.
|
||||||
|
|
||||||
Supported `polkadot-sdk` rev: `2503.0.1`
|
Supported `polkadot-sdk` rev: `2503.0.1`
|
||||||
|
|||||||
@@ -2,18 +2,71 @@
|
|||||||
|
|
||||||
pub mod file;
|
pub mod file;
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use self::file::flag::Flag;
|
use self::file::flag::Flag;
|
||||||
use self::file::File as FileSelection;
|
use self::file::File as FileSelection;
|
||||||
|
|
||||||
|
/// The `solc --standard-json` per-file output selection.
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
|
||||||
|
pub struct PerFileSelection {
|
||||||
|
/// Individual file selection configuration, required for foundry.
|
||||||
|
#[serde(skip_serializing_if = "BTreeMap::is_empty", flatten)]
|
||||||
|
pub files: BTreeMap<String, FileSelection>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PerFileSelection {
|
||||||
|
/// Extends the output selection with another one.
|
||||||
|
pub fn extend(&mut self, other: Self) {
|
||||||
|
for (entry, file) in other.files {
|
||||||
|
self.files
|
||||||
|
.entry(entry)
|
||||||
|
.and_modify(|v| {
|
||||||
|
v.extend(file.clone());
|
||||||
|
})
|
||||||
|
.or_insert(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns flags that are going to be automatically added by the compiler,
|
||||||
|
/// but were not explicitly requested by the user.
|
||||||
|
///
|
||||||
|
/// Afterwards, the flags are used to prune JSON output before returning it.
|
||||||
|
pub fn selection_to_prune(&self) -> Self {
|
||||||
|
let files = self
|
||||||
|
.files
|
||||||
|
.iter()
|
||||||
|
.map(|(k, v)| (k.to_owned(), v.selection_to_prune()))
|
||||||
|
.collect();
|
||||||
|
Self { files }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether `path` contains the `flag` or `None` if there is no selection for `path`.
|
||||||
|
pub fn contains(&self, path: &String, flag: &Flag) -> Option<bool> {
|
||||||
|
if let Some(file) = self.files.get(path) {
|
||||||
|
return Some(file.contains(flag));
|
||||||
|
};
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether this is the empty per file selection.
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.files.is_empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The `solc --standard-json` output selection.
|
/// The `solc --standard-json` output selection.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, Default, PartialEq)]
|
||||||
pub struct Selection {
|
pub struct Selection {
|
||||||
/// Only the 'all' wildcard is available for robustness reasons.
|
/// Only the 'all' wildcard is available for robustness reasons.
|
||||||
#[serde(default, rename = "*", skip_serializing_if = "FileSelection::is_empty")]
|
#[serde(default, rename = "*", skip_serializing_if = "FileSelection::is_empty")]
|
||||||
|
/// Individual file selection configuration, required for foundry.
|
||||||
pub all: FileSelection,
|
pub all: FileSelection,
|
||||||
|
#[serde(skip_serializing_if = "PerFileSelection::is_empty", flatten)]
|
||||||
|
files: PerFileSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Selection {
|
impl Selection {
|
||||||
@@ -21,6 +74,7 @@ impl Selection {
|
|||||||
pub fn new(flags: Vec<Flag>) -> Self {
|
pub fn new(flags: Vec<Flag>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
all: FileSelection::new(flags),
|
all: FileSelection::new(flags),
|
||||||
|
files: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +92,7 @@ impl Selection {
|
|||||||
pub fn new_required_for_tests() -> Self {
|
pub fn new_required_for_tests() -> Self {
|
||||||
Self {
|
Self {
|
||||||
all: FileSelection::new_required_for_tests(),
|
all: FileSelection::new_required_for_tests(),
|
||||||
|
files: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +104,7 @@ impl Selection {
|
|||||||
/// Extends the output selection with another one.
|
/// Extends the output selection with another one.
|
||||||
pub fn extend(&mut self, other: Self) -> &mut Self {
|
pub fn extend(&mut self, other: Self) -> &mut Self {
|
||||||
self.all.extend(other.all);
|
self.all.extend(other.all);
|
||||||
|
self.files.extend(other.files);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,11 +115,14 @@ impl Selection {
|
|||||||
pub fn selection_to_prune(&self) -> Self {
|
pub fn selection_to_prune(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
all: self.all.selection_to_prune(),
|
all: self.all.selection_to_prune(),
|
||||||
|
files: self.files.selection_to_prune(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether the flag is requested.
|
/// Whether the flag is requested.
|
||||||
pub fn contains(&self, flag: &Flag) -> bool {
|
pub fn contains(&self, path: &String, flag: &Flag) -> bool {
|
||||||
self.all.contains(flag)
|
self.files
|
||||||
|
.contains(path, flag)
|
||||||
|
.unwrap_or(self.all.contains(flag))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,14 +56,22 @@ impl Output {
|
|||||||
messages: &mut Vec<SolcStandardJsonOutputError>,
|
messages: &mut Vec<SolcStandardJsonOutputError>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let sources = sources
|
let sources = sources
|
||||||
.keys()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, path)| (path.to_owned(), Source::new(index)))
|
.map(|(index, (path, source))| {
|
||||||
|
(
|
||||||
|
path.to_owned(),
|
||||||
|
Source {
|
||||||
|
id: index,
|
||||||
|
ast: source.content().map(|x| serde_json::to_value(x).unwrap()),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
.collect::<BTreeMap<String, Source>>();
|
.collect::<BTreeMap<String, Source>>();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
contracts: BTreeMap::new(),
|
contracts: BTreeMap::new(),
|
||||||
sources,
|
sources: sources.clone(),
|
||||||
errors: std::mem::take(messages),
|
errors: std::mem::take(messages),
|
||||||
|
|
||||||
version: None,
|
version: None,
|
||||||
@@ -92,27 +100,27 @@ impl Output {
|
|||||||
mut self,
|
mut self,
|
||||||
selection_to_prune: SolcStandardJsonInputSettingsSelection,
|
selection_to_prune: SolcStandardJsonInputSettingsSelection,
|
||||||
) -> ! {
|
) -> ! {
|
||||||
let contracts = self
|
for (path, contracts) in self.contracts.iter_mut() {
|
||||||
.contracts
|
for contract in contracts.values_mut() {
|
||||||
.values_mut()
|
|
||||||
.flat_map(|contracts| contracts.values_mut())
|
|
||||||
.collect::<Vec<&mut Contract>>();
|
|
||||||
for contract in contracts.into_iter() {
|
|
||||||
if selection_to_prune
|
|
||||||
.contains(&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Metadata)
|
|
||||||
{
|
|
||||||
contract.metadata = serde_json::Value::Null;
|
|
||||||
}
|
|
||||||
if selection_to_prune
|
|
||||||
.contains(&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Yul)
|
|
||||||
{
|
|
||||||
contract.ir_optimized = String::new();
|
|
||||||
}
|
|
||||||
if let Some(ref mut evm) = contract.evm {
|
|
||||||
if selection_to_prune.contains(
|
if selection_to_prune.contains(
|
||||||
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::MethodIdentifiers,
|
path,
|
||||||
|
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Metadata,
|
||||||
) {
|
) {
|
||||||
evm.method_identifiers.clear();
|
contract.metadata = serde_json::Value::Null;
|
||||||
|
}
|
||||||
|
if selection_to_prune.contains(
|
||||||
|
path,
|
||||||
|
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::Yul,
|
||||||
|
) {
|
||||||
|
contract.ir_optimized = String::new();
|
||||||
|
}
|
||||||
|
if let Some(ref mut evm) = contract.evm {
|
||||||
|
if selection_to_prune.contains(
|
||||||
|
path,
|
||||||
|
&crate::SolcStandardJsonInputSettingsSelectionFileFlag::MethodIdentifiers,
|
||||||
|
) {
|
||||||
|
evm.method_identifiers.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user