Make `build_py_proto` and `build_py_methods` only accept `ImplItem`
This commit is contained in:
parent
758d30abbd
commit
580e50f727
|
@ -6,15 +6,11 @@ use quote::Tokens;
|
|||
use py_method;
|
||||
|
||||
|
||||
pub fn build_py_methods(ast: &mut syn::Item) -> Tokens {
|
||||
if let syn::Item::Impl(ref mut iimpl) = ast {
|
||||
if iimpl.trait_.is_some() {
|
||||
panic!("#[methods] can not be used only with trait impl block");
|
||||
} else {
|
||||
impl_methods(&iimpl.self_ty, &mut iimpl.items)
|
||||
}
|
||||
pub fn build_py_methods(ast: &mut syn::ItemImpl) -> Tokens {
|
||||
if ast.trait_.is_some() {
|
||||
panic!("#[methods] can not be used only with trait impl block");
|
||||
} else {
|
||||
panic!("#[methods] can only be used with Impl blocks")
|
||||
impl_methods(&iimpl.self_ty, &mut iimpl.items)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,56 +9,52 @@ use method::FnSpec;
|
|||
use func::impl_method_proto;
|
||||
|
||||
|
||||
pub fn build_py_proto(ast: &mut syn::Item) -> Tokens {
|
||||
match ast {
|
||||
syn::Item::Impl(ref mut expr) => {
|
||||
if let Some((_, ref mut path, _)) = expr.trait_ {
|
||||
let tokens = if let Some(ref mut segment) = path.segments.last() {
|
||||
let ty = &expr.self_ty;
|
||||
let items = &mut expr.items;
|
||||
match segment.value().ident.as_ref() {
|
||||
"PyObjectProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::OBJECT),
|
||||
"PyAsyncProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::ASYNC),
|
||||
"PyMappingProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::MAPPING),
|
||||
"PyIterProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::ITER),
|
||||
"PyContextProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::CONTEXT),
|
||||
"PySequenceProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::SEQ),
|
||||
"PyNumberProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::NUM),
|
||||
"PyDescrProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::DESCR),
|
||||
"PyBufferProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::BUFFER),
|
||||
"PyGCProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::GC),
|
||||
_ => {
|
||||
warn!("#[proto] can not be used with this block");
|
||||
return Tokens::new()
|
||||
}
|
||||
pub fn build_py_proto(ast: &mut syn::ItemImpl) -> Tokens {
|
||||
if let Some((_, ref mut path, _)) = ast.trait_ {
|
||||
|
||||
let tokens = if let Some(ref mut segment) = path.segments.last() {
|
||||
let ty = &ast.self_ty;
|
||||
let items = &mut ast.items;
|
||||
match segment.value().ident.as_ref() {
|
||||
"PyObjectProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::OBJECT),
|
||||
"PyAsyncProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::ASYNC),
|
||||
"PyMappingProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::MAPPING),
|
||||
"PyIterProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::ITER),
|
||||
"PyContextProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::CONTEXT),
|
||||
"PySequenceProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::SEQ),
|
||||
"PyNumberProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::NUM),
|
||||
"PyDescrProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::DESCR),
|
||||
"PyBufferProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::BUFFER),
|
||||
"PyGCProtocol" =>
|
||||
impl_proto_impl(ty, items, &defs::GC),
|
||||
_ => {
|
||||
warn!("#[proto] can not be used with this block");
|
||||
return Tokens::new()
|
||||
}
|
||||
} else {
|
||||
panic!("#[proto] can only be used with protocol trait implementations")
|
||||
};
|
||||
|
||||
// attach lifetime
|
||||
let mut seg = path.segments.pop().unwrap().into_value();
|
||||
seg.arguments = syn::PathArguments::AngleBracketed(parse_quote!{<'p>});
|
||||
path.segments.push(seg);
|
||||
expr.generics.params = parse_quote!{'p};
|
||||
|
||||
tokens
|
||||
}
|
||||
} else {
|
||||
panic!("#[proto] can only be used with protocol trait implementations")
|
||||
}
|
||||
},
|
||||
_ => panic!("#[proto] can only be used with Impl blocks"),
|
||||
}
|
||||
};
|
||||
|
||||
// attach lifetime
|
||||
let mut seg = path.segments.pop().unwrap().into_value();
|
||||
seg.arguments = syn::PathArguments::AngleBracketed(parse_quote!{<'p>});
|
||||
path.segments.push(seg);
|
||||
expr.generics.params = parse_quote!{'p};
|
||||
|
||||
tokens
|
||||
} else {
|
||||
panic!("#[proto] can only be used with protocol trait implementations")
|
||||
}
|
||||
}
|
||||
|
||||
fn impl_proto_impl(
|
||||
|
|
|
@ -64,7 +64,7 @@ pub fn mod3init(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn proto(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// Parse the token stream into a syntax tree
|
||||
let mut ast: syn::Item = syn::parse(input)
|
||||
let mut ast: syn::ItemImpl = syn::parse(input)
|
||||
.expect("#[proto] must be used on an `impl` block");
|
||||
|
||||
// Build the output
|
||||
|
@ -80,7 +80,7 @@ pub fn proto(_: TokenStream, input: TokenStream) -> TokenStream {
|
|||
pub fn class(attr: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// Parse the token stream into a syntax tree
|
||||
let mut ast: syn::DeriveInput = syn::parse(input)
|
||||
.expect("#[class] must be used on an ");
|
||||
.expect("#[class] must be used on a `struct`");
|
||||
|
||||
// Parse the macro arguments into a list of expressions
|
||||
let args: Vec<syn::Expr> = {
|
||||
|
@ -101,7 +101,7 @@ pub fn class(attr: TokenStream, input: TokenStream) -> TokenStream {
|
|||
#[proc_macro_attribute]
|
||||
pub fn methods(_: TokenStream, input: TokenStream) -> TokenStream {
|
||||
// Parse the token stream into a syntax tree
|
||||
let mut ast: syn::Item = syn::parse(input)
|
||||
let mut ast: syn::ItemImpl = syn::parse(input)
|
||||
.expect("#[methods] must be used on an `impl` block");
|
||||
|
||||
// Build the output
|
||||
|
|
Loading…
Reference in New Issue