forked from Rust-related/RustPython
pyattr for pyclass
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use super::Diagnostic;
|
||||
use crate::util::{
|
||||
path_eq, pyclass_ident_and_attrs, ClassItemMeta, ContentItem, ContentItemInner, ErrorVec,
|
||||
ItemMeta, ItemMetaInner, ItemNursery, ALL_ALLOWED_NAMES,
|
||||
ItemMeta, ItemMetaInner, ItemNursery, SimpleItemMeta, ALL_ALLOWED_NAMES,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{quote, quote_spanned, ToTokens};
|
||||
@@ -216,6 +216,11 @@ struct SlotItem {
|
||||
inner: ContentItemInner,
|
||||
}
|
||||
|
||||
/// #[pyattr]
|
||||
struct AttributeItem {
|
||||
inner: ContentItemInner,
|
||||
}
|
||||
|
||||
/// #[extend_class]
|
||||
struct ExtendClassItem {
|
||||
inner: ContentItemInner,
|
||||
@@ -236,6 +241,11 @@ impl ContentItem for SlotItem {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl ContentItem for AttributeItem {
|
||||
fn inner(&self) -> &ContentItemInner {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
impl ContentItem for ExtendClassItem {
|
||||
fn inner(&self) -> &ContentItemInner {
|
||||
&self.inner
|
||||
@@ -357,6 +367,51 @@ where
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Item> ImplItem<Item> for AttributeItem
|
||||
where
|
||||
Item: ItemLike + ToTokens + GetIdent,
|
||||
{
|
||||
fn gen_impl_item(&self, args: ImplItemArgs<'_, Item>) -> Result<()> {
|
||||
let cfgs = args.cfgs.to_vec();
|
||||
let attr = args.attrs.remove(self.index());
|
||||
|
||||
let get_py_name = |attr: &Attribute, ident: &Ident| -> Result<_> {
|
||||
let item_meta = SimpleItemMeta::from_attr(ident.clone(), attr)?;
|
||||
let py_name = item_meta.simple_name()?;
|
||||
Ok(py_name)
|
||||
};
|
||||
let (py_name, tokens) = if args.item.is_function_or_method() || args.item.is_const() {
|
||||
let ident = args.item.get_ident().unwrap();
|
||||
let py_name = get_py_name(&attr, &ident)?;
|
||||
|
||||
let value = if args.item.is_const() {
|
||||
// TODO: ctx.new_value
|
||||
quote_spanned!(ident.span() => ctx.new_int(Self::#ident))
|
||||
} else {
|
||||
quote_spanned!(ident.span() => Self::#ident(ctx))
|
||||
};
|
||||
(
|
||||
py_name.clone(),
|
||||
quote! {
|
||||
class.set_str_attr(#py_name, #value);
|
||||
},
|
||||
)
|
||||
} else {
|
||||
return Err(self.new_syn_error(
|
||||
args.item.span(),
|
||||
"can only be on a const or an associated method without argument",
|
||||
));
|
||||
};
|
||||
|
||||
args.context
|
||||
.impl_extend_items
|
||||
.add_item(py_name, cfgs, tokens)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Item> ImplItem<Item> for ExtendClassItem
|
||||
where
|
||||
Item: ItemLike + ToTokens + GetIdent,
|
||||
@@ -705,6 +760,9 @@ where
|
||||
"pyslot" => Box::new(SlotItem {
|
||||
inner: ContentItemInner { index, attr_name },
|
||||
}),
|
||||
"pyattr" => Box::new(AttributeItem {
|
||||
inner: ContentItemInner { index, attr_name },
|
||||
}),
|
||||
"extend_class" => Box::new(ExtendClassItem {
|
||||
inner: ContentItemInner { index, attr_name },
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user