feat(abigen): use prettyplease (#2027)
This commit is contained in:
parent
c439566625
commit
0187bedd11
|
@ -1378,6 +1378,7 @@ dependencies = [
|
|||
"eyre",
|
||||
"getrandom 0.2.8",
|
||||
"hex",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
|
@ -3162,6 +3163,16 @@ dependencies = [
|
|||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e97e3215779627f01ee256d2fad52f3d95e8e1c11e9fc6fd08f7cd455d5d5c78"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primitive-types"
|
||||
version = "0.12.1"
|
||||
|
|
|
@ -16,10 +16,12 @@ keywords = ["ethereum", "web3", "celo", "ethers"]
|
|||
[dependencies]
|
||||
ethers-core = { version = "^1.0.0", path = "../../ethers-core", features = ["macros"] }
|
||||
|
||||
Inflector = "0.11"
|
||||
proc-macro2 = "1.0"
|
||||
quote = "1.0"
|
||||
syn = "1.0.12"
|
||||
syn = { version = "1.0.12", default-features = false, features = ["full"] }
|
||||
prettyplease = "0.1.23"
|
||||
|
||||
Inflector = "0.11"
|
||||
url = "2.1"
|
||||
serde_json = "1.0.61"
|
||||
serde = { version = "1.0.124", features = ["derive"] }
|
||||
|
|
|
@ -16,7 +16,6 @@ pub mod contract;
|
|||
pub use contract::structs::InternalStructs;
|
||||
use contract::Context;
|
||||
|
||||
mod rustfmt;
|
||||
mod source;
|
||||
mod util;
|
||||
|
||||
|
@ -69,8 +68,8 @@ pub struct Abigen {
|
|||
/// Derives added to event structs and enums.
|
||||
event_derives: Vec<String>,
|
||||
|
||||
/// Format the code using a locally installed copy of `rustfmt`.
|
||||
rustfmt: bool,
|
||||
/// Whether to format the code. Uses [`prettyplease`].
|
||||
format: bool,
|
||||
|
||||
/// Manually specified event name aliases.
|
||||
event_aliases: HashMap<String, String>,
|
||||
|
@ -89,7 +88,7 @@ impl Abigen {
|
|||
method_aliases: HashMap::new(),
|
||||
event_derives: Vec::new(),
|
||||
event_aliases: HashMap::new(),
|
||||
rustfmt: true,
|
||||
format: true,
|
||||
error_aliases: Default::default(),
|
||||
})
|
||||
}
|
||||
|
@ -147,14 +146,20 @@ impl Abigen {
|
|||
self
|
||||
}
|
||||
|
||||
/// Specify whether or not to format the code using a locally installed copy
|
||||
/// of `rustfmt`.
|
||||
///
|
||||
/// Note that in case `rustfmt` does not exist or produces an error, the
|
||||
/// unformatted code will be used.
|
||||
#[must_use]
|
||||
#[deprecated = "Use format instead"]
|
||||
#[doc(hidden)]
|
||||
pub fn rustfmt(mut self, rustfmt: bool) -> Self {
|
||||
self.rustfmt = rustfmt;
|
||||
self.format = rustfmt;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify whether to format the code or not. True by default.
|
||||
///
|
||||
/// This will use [`prettyplease`], so the resulting formatted code **will not** be affected by
|
||||
/// the local `rustfmt` version or config.
|
||||
pub fn format(mut self, format: bool) -> Self {
|
||||
self.format = format;
|
||||
self
|
||||
}
|
||||
|
||||
|
@ -173,10 +178,10 @@ impl Abigen {
|
|||
|
||||
/// Generates the contract bindings.
|
||||
pub fn generate(self) -> Result<ContractBindings> {
|
||||
let rustfmt = self.rustfmt;
|
||||
let format = self.format;
|
||||
let name = self.contract_name.clone();
|
||||
let (expanded, _) = self.expand()?;
|
||||
Ok(ContractBindings { tokens: expanded.into_tokens(), rustfmt, name })
|
||||
Ok(ContractBindings { tokens: expanded.into_tokens(), format, name })
|
||||
}
|
||||
|
||||
/// Expands the `Abigen` and returns the [`ExpandedContract`] that holds all tokens and the
|
||||
|
@ -193,7 +198,7 @@ pub struct ContractBindings {
|
|||
/// The TokenStream representing the contract bindings.
|
||||
tokens: TokenStream,
|
||||
/// The output options used for serialization.
|
||||
rustfmt: bool,
|
||||
format: bool,
|
||||
/// The contract name
|
||||
name: String,
|
||||
}
|
||||
|
@ -204,14 +209,11 @@ impl ContractBindings {
|
|||
where
|
||||
W: Write,
|
||||
{
|
||||
let source = {
|
||||
let raw = self.tokens.to_string();
|
||||
|
||||
if self.rustfmt {
|
||||
rustfmt::format(&raw).unwrap_or(raw)
|
||||
let source = if self.format {
|
||||
let syntax_tree = syn::parse2::<syn::File>(self.tokens.clone()).unwrap();
|
||||
prettyplease::unparse(&syntax_tree)
|
||||
} else {
|
||||
raw
|
||||
}
|
||||
self.tokens.to_string()
|
||||
};
|
||||
|
||||
w.write_all(source.as_bytes())?;
|
||||
|
|
|
@ -139,11 +139,8 @@ impl MultiAbigen {
|
|||
|
||||
/// Build the contract bindings and prepare for writing
|
||||
pub fn build(self) -> Result<MultiBindings> {
|
||||
let rustfmt = self.abigens.iter().any(|gen| gen.rustfmt);
|
||||
Ok(MultiBindings {
|
||||
expansion: MultiExpansion::from_abigen(self.abigens)?.expand(),
|
||||
rustfmt,
|
||||
})
|
||||
let format = self.abigens.iter().any(|gen| gen.format);
|
||||
Ok(MultiBindings { expansion: MultiExpansion::from_abigen(self.abigens)?.expand(), format })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -298,14 +295,14 @@ impl MultiExpansionResult {
|
|||
}
|
||||
|
||||
/// Converts this result into [`MultiBindingsInner`]
|
||||
fn into_bindings(mut self, single_file: bool, rustfmt: bool) -> MultiBindingsInner {
|
||||
fn into_bindings(mut self, single_file: bool, format: bool) -> MultiBindingsInner {
|
||||
self.set_shared_import_path(single_file);
|
||||
let Self { contracts, shared_types, root, .. } = self;
|
||||
let bindings = contracts
|
||||
.into_iter()
|
||||
.map(|(expanded, ctx)| ContractBindings {
|
||||
tokens: expanded.into_tokens(),
|
||||
rustfmt,
|
||||
format,
|
||||
name: ctx.contract_name().to_string(),
|
||||
})
|
||||
.map(|v| (v.name.clone(), v))
|
||||
|
@ -325,7 +322,7 @@ impl MultiExpansionResult {
|
|||
};
|
||||
Some(ContractBindings {
|
||||
tokens: shared_types,
|
||||
rustfmt,
|
||||
format,
|
||||
name: "shared_types".to_string(),
|
||||
})
|
||||
} else {
|
||||
|
@ -364,7 +361,7 @@ impl MultiExpansionResult {
|
|||
/// changed)
|
||||
pub struct MultiBindings {
|
||||
expansion: MultiExpansionResult,
|
||||
rustfmt: bool,
|
||||
format: bool,
|
||||
}
|
||||
|
||||
impl MultiBindings {
|
||||
|
@ -378,18 +375,25 @@ impl MultiBindings {
|
|||
self.expansion.contracts.is_empty()
|
||||
}
|
||||
|
||||
/// Specify whether or not to format the code using a locally installed copy
|
||||
/// of `rustfmt`.
|
||||
///
|
||||
/// Note that in case `rustfmt` does not exist or produces an error, the
|
||||
/// unformatted code will be used.
|
||||
#[must_use]
|
||||
#[deprecated = "Use format instead"]
|
||||
#[doc(hidden)]
|
||||
pub fn rustfmt(mut self, rustfmt: bool) -> Self {
|
||||
self.rustfmt = rustfmt;
|
||||
self.format = rustfmt;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify whether to format the code or not. True by default.
|
||||
///
|
||||
/// This will use [`prettyplease`], so the resulting formatted code **will not** be affected by
|
||||
/// the local `rustfmt` version or config.
|
||||
pub fn format(mut self, format: bool) -> Self {
|
||||
self.format = format;
|
||||
self
|
||||
}
|
||||
|
||||
fn into_inner(self, single_file: bool) -> MultiBindingsInner {
|
||||
self.expansion.into_bindings(single_file, self.rustfmt)
|
||||
self.expansion.into_bindings(single_file, self.format)
|
||||
}
|
||||
|
||||
/// Generates all the bindings and writes them to the given module
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
//! This module implements basic `rustfmt` code formatting.
|
||||
|
||||
use eyre::{eyre, Result};
|
||||
use std::{
|
||||
io::Write,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
|
||||
/// Format the raw input source string and return formatted output.
|
||||
pub fn format<S>(source: S) -> Result<String>
|
||||
where
|
||||
S: AsRef<str>,
|
||||
{
|
||||
let mut rustfmt =
|
||||
Command::new("rustfmt").stdin(Stdio::piped()).stdout(Stdio::piped()).spawn()?;
|
||||
|
||||
{
|
||||
let stdin = rustfmt
|
||||
.stdin
|
||||
.as_mut()
|
||||
.ok_or_else(|| eyre!("stdin was not created for `rustfmt` child process"))?;
|
||||
stdin.write_all(source.as_ref().as_bytes())?;
|
||||
}
|
||||
|
||||
let output = rustfmt.wait_with_output()?;
|
||||
|
||||
eyre::ensure!(
|
||||
output.status.success(),
|
||||
"`rustfmt` exited with code {}:\n{}",
|
||||
output.status,
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
|
||||
let stdout = String::from_utf8(output.stdout)?;
|
||||
Ok(stdout)
|
||||
}
|
Loading…
Reference in New Issue