Commit ea19d24a authored by Qinxuan Chen's avatar Qinxuan Chen Committed by Hero Bird
Browse files

[lang] Update proc-macro2, quote, syn to 1.0 (#221)



* [lang] Update proc-macro2, quote, syn to 1.0

Signed-off-by: default avatarkoushiro <koushiro.cqx@gmail.com>

* Remove old deps

Signed-off-by: default avatarkoushiro <koushiro.cqx@gmail.com>

* Format

Signed-off-by: default avatarkoushiro <koushiro.cqx@gmail.com>

* Revert .gitignore

Signed-off-by: default avatarkoushiro <koushiro.cqx@gmail.com>

* Fix parse_from_attr

Signed-off-by: default avatarkoushiro <koushiro.cqx@gmail.com>
parent 4251a26c
Pipeline #56860 failed with stages
in 22 seconds
......@@ -83,7 +83,8 @@ where
LayoutStruct::new(
Self::meta_type(),
vec![LayoutField::of("sync_chunk", &self.0)],
).into()
)
.into()
}
}
......
......@@ -22,9 +22,9 @@ ink_utils = { path = "../utils/", default-features = false }
ink_model = { path = "../model/", default-features = false }
scale = { package = "parity-scale-codec", version = "1.1", default-features = false, features = ["derive"] }
quote = "0.6"
syn = { version = "0.15", features = ["parsing", "full", "extra-traits"] }
proc-macro2 = "0.4"
quote = "1.0"
syn = { version = "1.0", features = ["parsing", "full", "extra-traits"] }
proc-macro2 = "1.0"
heck = "0.3"
itertools = { version = "0.8", default-features = false }
either = { version = "1.5", default-features = false }
......
......@@ -14,8 +14,6 @@
// You should have received a copy of the GNU General Public License
// along with ink!. If not, see <http://www.gnu.org/licenses/>.
use crate::parser::keywords;
use proc_macro2::{
Ident,
TokenStream as TokenStream2,
......@@ -27,6 +25,8 @@ use syn::{
Token,
};
use crate::parser::keywords;
#[derive(Debug)]
pub struct Contract {
pub items: Vec<Item>,
......@@ -131,7 +131,7 @@ impl EventArg {
self.attrs.iter().any(|attr| {
attr.style == syn::AttrStyle::Outer
&& attr.path.is_ident("indexed")
&& attr.tts.is_empty()
&& attr.tokens.is_empty()
})
}
}
......@@ -159,7 +159,7 @@ pub struct ItemDeployImpl {
pub struct DeployItemMethod {
pub attrs: Vec<syn::Attribute>,
pub deploy_tok: keywords::deploy,
pub decl: FnDecl,
pub sig: Signature,
pub block: syn::Block,
}
......@@ -176,7 +176,7 @@ pub struct ItemImpl {
pub struct ItemImplMethod {
pub attrs: Vec<syn::Attribute>,
pub vis: MethodVisibility,
pub sig: MethodSig,
pub sig: Signature,
pub block: syn::Block,
}
......@@ -208,18 +208,13 @@ pub struct ExternalVisibility {
}
#[derive(Debug, Clone)]
pub struct MethodSig {
pub struct Signature {
pub ident: Ident,
pub decl: FnDecl,
}
#[derive(Debug, Clone)]
pub struct FnDecl {
pub fn_tok: token::Fn,
pub generics: syn::Generics,
pub paren_tok: token::Paren,
pub inputs: Punctuated<FnArg, token::Comma>,
pub output: ReturnType,
pub generics: syn::Generics,
}
pub struct FnInputs {
......@@ -229,14 +224,14 @@ pub struct FnInputs {
impl FnInputs {
pub fn to_actual_params(&self) -> Punctuated<syn::Pat, Token![,]> {
let mut params: Punctuated<syn::Pat, Token![,]> = Default::default();
for captured in self.punct.iter().filter_map(|fn_arg| {
if let FnArg::Captured(captured) = fn_arg {
Some(captured)
for pat_ty in self.punct.iter().filter_map(|fn_arg| {
if let FnArg::Typed(pat_ty) = fn_arg {
Some(pat_ty)
} else {
None
}
}) {
params.push(captured.pat.clone())
params.push((*pat_ty.pat).clone())
}
params
}
......@@ -256,17 +251,29 @@ pub enum FnDeclKind {
Static,
}
impl FnDecl {
impl Signature {
pub fn kind(&self) -> FnDeclKind {
match self.inputs.iter().next().unwrap() {
FnArg::SelfRef(self_ref) => {
if self_ref.mutability.is_some() {
FnDeclKind::SelfRefMut
} else {
FnDeclKind::SelfRef
}
}
FnArg::SelfValue(_) => FnDeclKind::SelfVal,
FnArg::Receiver(syn::Receiver {
mutability: Some(_),
reference: Some(_),
..
}) => FnDeclKind::SelfRefMut,
FnArg::Receiver(syn::Receiver {
mutability: None,
reference: Some(_),
..
}) => FnDeclKind::SelfRef,
FnArg::Receiver(syn::Receiver {
mutability: None,
reference: None,
..
})
| FnArg::Receiver(syn::Receiver {
mutability: Some(_),
reference: None,
..
}) => FnDeclKind::SelfVal,
_ => FnDeclKind::Static,
}
}
......@@ -303,12 +310,12 @@ impl FnDecl {
let self_arg = inputs_iter.next().unwrap();
inputs_with_env.push_value(self_arg.clone());
inputs_with_env.push_punct(Default::default());
let custom_arg_captured: ArgCaptured = if self.kind() == FnDeclKind::SelfRefMut {
let custom_pat_ty: PatType = if self.kind() == FnDeclKind::SelfRefMut {
syn::parse_quote! { env: &mut #env_handler }
} else {
syn::parse_quote! { env: &#env_handler }
};
inputs_with_env.push(FnArg::Captured(custom_arg_captured.into_arg_captured()));
inputs_with_env.push(FnArg::Typed(custom_pat_ty.into_pat_type()));
for input in inputs_iter {
inputs_with_env.push(input.clone())
}
......@@ -321,18 +328,17 @@ impl FnDecl {
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone)]
pub enum FnArg {
SelfRef(syn::ArgSelfRef),
SelfValue(syn::ArgSelf),
Captured(syn::ArgCaptured),
Receiver(syn::Receiver),
Typed(syn::PatType),
}
impl FnArg {
/// Returns the ident if available.
pub fn ident(&self) -> Option<proc_macro2::Ident> {
match self {
FnArg::SelfRef(_) | FnArg::SelfValue(_) => None,
FnArg::Captured(captured) => {
match &captured.pat {
FnArg::Receiver(_) => None,
FnArg::Typed(pat_ty) => {
match &*pat_ty.pat {
syn::Pat::Ident(pat_ident) => Some(pat_ident.ident.clone()),
_ => None,
}
......@@ -340,10 +346,10 @@ impl FnArg {
}
}
/// Returns `true` if the fn argument is captured.
pub fn is_captured(&self) -> Option<&syn::ArgCaptured> {
/// Returns `true` if the fn argument is accepted by pattern and type.
pub fn is_typed(&self) -> Option<&syn::PatType> {
match self {
FnArg::Captured(capt) => Some(capt),
FnArg::Typed(pat_ty) => Some(pat_ty),
_ => None,
}
}
......@@ -352,26 +358,28 @@ impl FnArg {
impl quote::ToTokens for FnArg {
fn to_tokens(&self, tokens: &mut TokenStream2) {
match self {
FnArg::SelfRef(arg_self_ref) => arg_self_ref.to_tokens(tokens),
FnArg::SelfValue(arg_self_value) => arg_self_value.to_tokens(tokens),
FnArg::Captured(arg_captured) => arg_captured.to_tokens(tokens),
FnArg::Receiver(receiver) => receiver.to_tokens(tokens),
FnArg::Typed(pat_ty) => pat_ty.to_tokens(tokens),
}
}
}
#[derive(Debug)]
pub struct ArgCaptured {
pub pat: syn::Pat,
pub struct PatType {
pub attrs: Vec<syn::Attribute>,
pub pat: Box<syn::Pat>,
pub colon_token: Token![:],
pub ty: syn::Type,
pub ty: Box<syn::Type>,
}
impl syn::parse::Parse for ArgCaptured {
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
impl syn::parse::Parse for PatType {
fn parse(input: syn::parse::ParseStream<'_>) -> syn::parse::Result<Self> {
let attrs = syn::Attribute::parse_outer(input)?;
let pat = input.parse()?;
let colon_token = input.parse()?;
let ty = input.parse()?;
Ok(Self {
attrs,
pat,
colon_token,
ty,
......@@ -379,9 +387,10 @@ impl syn::parse::Parse for ArgCaptured {
}
}
impl ArgCaptured {
pub fn into_arg_captured(self) -> syn::ArgCaptured {
syn::ArgCaptured {
impl PatType {
pub fn into_pat_type(self) -> syn::PatType {
syn::PatType {
attrs: self.attrs,
pat: self.pat,
colon_token: self.colon_token,
ty: self.ty,
......
......@@ -19,25 +19,21 @@
//! This two-steps process is required because Rust macros (and thus `ink_lang`)
//! are not able to access type information or anything that is related to that.
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::{
ast,
gen::selector_to_expr,
hir,
};
use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use syn::{
self,
punctuated::Punctuated,
Token,
};
/// Trims a doc string obtained from an attribute token stream into the actual doc string.
///
/// Practically speaking this method removes the trailing start `" = \""` and end `\"`
/// of documentation strings coming from Syn attribute token streams.
fn trim_doc_string(attr: &syn::Attribute) -> String {
attr.tts
attr.tokens
.to_string()
.trim_start_matches('=')
.trim_start()
......@@ -76,12 +72,12 @@ fn generate_abi_constructor(contract: &hir::Contract) -> TokenStream2 {
let constructor = &contract.on_deploy;
let args = constructor
.decl
.sig
.inputs
.iter()
.filter_map(ast::FnArg::is_captured)
.filter_map(ast::FnArg::is_typed)
.map(|capt| {
let name = match &capt.pat {
let name = match &*capt.pat {
syn::Pat::Ident(pat_ident) => {
if pat_ident.by_ref.is_none()
&& pat_ident.mutability.is_none()
......@@ -116,8 +112,7 @@ fn generate_abi_constructor(contract: &hir::Contract) -> TokenStream2 {
.of_type(#type_spec)
.done()
}
})
.collect::<Punctuated<_, Token![,]>>();
});
let docs = constructor.docs().map(trim_doc_string);
quote! {
......@@ -143,12 +138,11 @@ fn generate_abi_messages<'a>(
let name = message.sig.ident.to_string();
let inputs = message
.sig
.decl
.inputs
.iter()
.filter_map(ast::FnArg::is_captured)
.filter_map(ast::FnArg::is_typed)
.map(|capt| {
let name: String = match &capt.pat {
let name: String = match &*capt.pat {
syn::Pat::Ident(pat_ident) => {
if pat_ident.by_ref.is_none()
&& pat_ident.mutability.is_none()
......@@ -180,14 +174,14 @@ fn generate_abi_messages<'a>(
.done()
}
});
let ret_type = match &message.sig.decl.output {
let ret_type = match &message.sig.output {
syn::ReturnType::Default => {
quote! {
ink_abi::ReturnTypeSpec::new(None)
}
}
syn::ReturnType::Type(_, ty) => {
let type_spec = generate_type_spec_code(ty);
let type_spec = generate_type_spec_code(&*ty);
quote! {
ink_abi::ReturnTypeSpec::new(#type_spec)
}
......
......@@ -22,17 +22,18 @@
//! However, it requires special treatment for all public messages since their bodies are completely
//! replaced by direct forwards to the remote call infrastructure going through SRML contracts.
use crate::{
ast,
gen::selector_to_expr,
hir,
};
use proc_macro2::TokenStream as TokenStream2;
use quote::{
quote,
quote_spanned,
};
use crate::{
ast,
gen::selector_to_expr,
hir,
};
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Mutability {
Immutable,
......@@ -133,14 +134,14 @@ fn generate_state_as_dependency(contract: &hir::Contract) -> TokenStream2 {
fn generate_create(contract: &hir::Contract) -> TokenStream2 {
let deploy_handler = &contract.on_deploy;
let attrs = &deploy_handler.attrs;
let args = deploy_handler.decl.inputs.iter().skip(1);
let args = deploy_handler.sig.inputs.iter().skip(1);
let inputs = deploy_handler
.decl
.sig
.inputs
.iter()
.filter_map(ast::FnArg::ident)
.map(|ident| quote! { #ident });
quote_spanned! { deploy_handler.decl.fn_tok.span =>
quote_spanned! { deploy_handler.sig.fn_tok.span =>
#(#attrs)*
pub fn new(
code_hash: Hash,
......@@ -161,7 +162,7 @@ fn generate_messages_as_dependency<'a>(
contract.messages.iter().map(move |message| {
let ident = &message.sig.ident;
let attrs = &message.attrs;
let args = message.sig.decl.inputs.iter().skip(1);
let args = message.sig.inputs.iter().skip(1);
let (self_arg, call_fn) = if message.is_mut() {
(quote! { &mut self }, quote! { call_mut() })
} else {
......@@ -169,14 +170,13 @@ fn generate_messages_as_dependency<'a>(
};
let inputs = message
.sig
.decl
.inputs
.iter()
.filter_map(ast::FnArg::ident)
.map(|ident| quote! { #ident });
let output = &message.sig.decl.output;
let output = &message.sig.output;
let (_impl_generics, type_generics, where_clause) =
message.sig.decl.generics.split_for_impl();
message.sig.generics.split_for_impl();
match output {
syn::ReturnType::Default => {
quote_spanned! { ident.span() =>
......@@ -195,6 +195,7 @@ fn generate_messages_as_dependency<'a>(
}
}
syn::ReturnType::Type(_, ty) => {
let ty = &*ty;
quote_spanned! { ident.span() =>
#(#attrs)*
pub fn #ident #type_generics (
......@@ -230,13 +231,13 @@ fn generate_call_enhancer_messages<'a>(
.map(|message| {
let ident = &message.sig.ident;
let attrs = &message.attrs;
let args = message.sig.decl.inputs.iter().skip(1);
let inputs = message.sig.decl.inputs
let args = message.sig.inputs.iter().skip(1);
let inputs = message.sig.inputs
.iter()
.filter_map(ast::FnArg::ident)
.map(|ident| quote! { #ident });
let output = &message.sig.decl.output;
let (_impl_generics, type_generics, where_clause) = message.sig.decl.generics.split_for_impl();
let output = &message.sig.output;
let (_impl_generics, type_generics, where_clause) = message.sig.generics.split_for_impl();
let selector = selector_to_expr(message.selector());
match output {
syn::ReturnType::Default => quote_spanned! { ident.span() =>
......@@ -251,16 +252,19 @@ fn generate_call_enhancer_messages<'a>(
)*
}
},
syn::ReturnType::Type(_, ty) => quote_spanned! { ident.span() =>
#(#attrs)*
pub fn #ident #type_generics (
self,
#(#args ,)*
) -> ink_core::env::CallBuilder<Env, ink_core::env::ReturnType<#ty>> #where_clause {
ink_core::env::CallBuilder::eval(self.contract.account_id.clone(), #selector)
#(
.push_arg(&#inputs)
)*
syn::ReturnType::Type(_, ty) => {
let ty = &*ty;
quote_spanned! { ident.span() =>
#(#attrs)*
pub fn #ident #type_generics (
self,
#(#args ,)*
) -> ink_core::env::CallBuilder<Env, ink_core::env::ReturnType<#ty>> #where_clause {
ink_core::env::CallBuilder::eval(self.contract.account_id.clone(), #selector)
#(
.push_arg(&#inputs)
)*
}
}
}
}
......
......@@ -19,11 +19,8 @@
//! Generated code that conflicts with specialized `test` or `doc`
//! code needs to be guarded by `#[cfg(..)]`.
use crate::{
ast,
gen::selector_to_expr,
hir,
};
use std::iter;
use proc_macro2::{
Ident,
TokenStream as TokenStream2,
......@@ -32,12 +29,17 @@ use quote::{
quote,
ToTokens,
};
use std::iter;
use syn::{
punctuated::Punctuated,
Token,
};
use crate::{
ast,
gen::selector_to_expr,
hir,
};
pub fn generate_code(tokens: &mut TokenStream2, contract: &hir::Contract) {
let env_items = {
let mut result = quote! {};
......@@ -254,21 +256,21 @@ fn codegen_for_instantiate(tokens: &mut TokenStream2, contract: &hir::Contract)
let deploy_handler_toks = {
let deploy_fn_args = {
let mut deploy_fn_args: Punctuated<ast::FnArg, Token![,]> = Punctuated::new();
for input in contract.on_deploy.decl.inputs.iter().skip(1) {
for input in contract.on_deploy.sig.inputs.iter().skip(1) {
deploy_fn_args.push(input.clone())
}
deploy_fn_args
};
let deploy_call_args = {
let mut deploy_call_args: Punctuated<syn::Pat, Token![,]> = Punctuated::new();
for captured in deploy_fn_args.iter().filter_map(|fn_arg| {
if let ast::FnArg::Captured(captured) = fn_arg {
Some(captured)
for pat_ty in deploy_fn_args.iter().filter_map(|fn_arg| {
if let ast::FnArg::Typed(pat_ty) = fn_arg {
Some(pat_ty)
} else {
None
}
}) {
deploy_call_args.push(captured.pat.clone())
deploy_call_args.push((*pat_ty.pat).clone())
}
deploy_call_args
};
......@@ -305,7 +307,7 @@ fn codegen_for_instantiate(tokens: &mut TokenStream2, contract: &hir::Contract)
let msg_fn_args = {
let mut msg_fn_args: Punctuated<ast::FnArg, Token![,]> =
Default::default();
for input in message.sig.decl.inputs.iter().skip(1) {
for input in message.sig.inputs.iter().skip(1) {
msg_fn_args.push(input.clone())
}
msg_fn_args
......@@ -314,14 +316,14 @@ fn codegen_for_instantiate(tokens: &mut TokenStream2, contract: &hir::Contract)
let msg_call_args = {
let mut msg_call_args: Punctuated<syn::Pat, Token![,]> =
Default::default();
for captured in msg_fn_args.iter().filter_map(|fn_arg| {
if let ast::FnArg::Captured(captured) = fn_arg {
Some(captured)
for pat_ty in msg_fn_args.iter().filter_map(|fn_arg| {
if let ast::FnArg::Typed(pat_ty) = fn_arg {
Some(pat_ty)
} else {
None
}
}) {
msg_call_args.push(captured.pat.clone())
msg_call_args.push((*pat_ty.pat).clone())
}
msg_call_args
};
......@@ -388,14 +390,14 @@ fn codegen_for_message_impls(tokens: &mut TokenStream2, contract: &hir::Contract
attr.to_tokens(&mut content)
}
<Token![pub]>::default().to_tokens(&mut content);
let fn_decl = &message.sig.decl;
fn_decl.fn_tok.to_tokens(&mut content);
let sig = &message.sig;
sig.fn_tok.to_tokens(&mut content);
message.sig.ident.to_tokens(&mut content);
fn_decl.paren_tok.surround(&mut content, |inner_toks| {
let inputs_with_env = fn_decl.inputs_with_env(&env_handler);
sig.paren_tok.surround(&mut content, |inner_toks| {
let inputs_with_env = sig.inputs_with_env(&env_handler);
inputs_with_env.to_tokens(inner_toks);
});
fn_decl.output.to_tokens(&mut content);
sig.output.to_tokens(&mut content);
message.block.to_tokens(&mut content);
}
content
......@@ -415,17 +417,17 @@ fn codegen_for_method_impls(tokens: &mut TokenStream2, contract: &hir::Contract)
for attr in &method.attrs {
attr.to_tokens(&mut content)
}
let fn_decl = &method.sig.decl;
fn_decl.fn_tok.to_tokens(&mut content);
let sig = &method.sig;
sig.fn_tok.to_tokens(&mut content);
method.sig.ident.to_tokens(&mut content);
let generics = &fn_decl.generics;
let generics = &sig.generics;
generics.lt_token.to_tokens(&mut content);
generics.params.to_tokens(&mut content);
generics.gt_token.to_tokens(&mut content);
fn_decl.paren_tok.surround(&mut content, |inner_toks| {
fn_decl.inputs.to_tokens(inner_toks);
sig.paren_tok.surround(&mut content, |inner_toks| {
sig.inputs.to_tokens(inner_toks);
});
fn_decl.output.to_tokens(&mut content);
sig.output.to_tokens(&mut content);
generics.where_clause.to_tokens(&mut content);
method.block.to_tokens(&mut content);
}
......@@ -482,12 +484,12 @@ fn codegen_for_messages(tokens: &mut TokenStream2, contract: &hir::Contract) {
message.sig.ident.span(),
);
camel_case_ident.to_tokens(&mut content);
let fn_decl = &message.sig.decl;
fn_decl.paren_tok.surround(&mut content, |inner_toks| {
let sig = &message.sig;
sig.paren_tok.surround(&mut content, |inner_toks| {
let args_without_self = {
let mut args_without_self: Punctuated<ast::FnArg, Token![,]> =
Punctuated::new();
for fn_arg in fn_decl
for fn_arg in sig
.inputs.iter()
// Performing `skip(1)` here works because we already asserted
// that all messages have to start with either `&self` or `&mut self`.
......@@ -499,7 +501,7 @@ fn codegen_for_messages(tokens: &mut TokenStream2, contract: &hir::Contract) {
};
args_without_self.to_tokens(inner_toks)
});
fn_decl.output.to_tokens(&mut content);
sig.output.to_tokens(&mut content);
<Token![;]>::default().to_tokens(&mut content);
}
content
......
......@@ -20,7 +20,8 @@
//! compiling a crate in order to generate special code that is only used
//! for documentation purposes.