mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-29 11:14:38 +08:00
Remove the __inside_vm hack for procedural macros
This commit is contained in:
10 files changed
+32
-77
No files matched your search
+11
-16
@@ -1,4 +1,3 @@
|
||||
use super::rustpython_path_derive;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use syn::{Attribute, Data, DeriveInput, Expr, Field, Fields, Ident, Lit, Meta, NestedMeta};
|
||||
@@ -109,7 +108,7 @@ impl ArgAttribute {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_field(field: &Field, rp_path: &syn::Path) -> TokenStream2 {
|
||||
fn generate_field(field: &Field) -> TokenStream2 {
|
||||
let mut pyarg_attrs = field
|
||||
.attrs
|
||||
.iter()
|
||||
@@ -132,7 +131,7 @@ fn generate_field(field: &Field, rp_path: &syn::Path) -> TokenStream2 {
|
||||
|
||||
let name = &field.ident;
|
||||
let middle = quote! {
|
||||
.map(|x| #rp_path::pyobject::TryFromObject::try_from_object(vm, x)).transpose()?
|
||||
.map(|x| ::rustpython_vm::pyobject::TryFromObject::try_from_object(vm, x)).transpose()?
|
||||
};
|
||||
let ending = if let Some(default) = attr.default {
|
||||
quote! {
|
||||
@@ -140,16 +139,16 @@ fn generate_field(field: &Field, rp_path: &syn::Path) -> TokenStream2 {
|
||||
}
|
||||
} else if attr.optional {
|
||||
quote! {
|
||||
.map(#rp_path::function::OptionalArg::Present)
|
||||
.unwrap_or(#rp_path::function::OptionalArg::Missing)
|
||||
.map(::rustpython_vm::function::OptionalArg::Present)
|
||||
.unwrap_or(::rustpython_vm::function::OptionalArg::Missing)
|
||||
}
|
||||
} else {
|
||||
let err = match attr.kind {
|
||||
ParameterKind::PositionalOnly | ParameterKind::PositionalOrKeyword => quote! {
|
||||
#rp_path::function::ArgumentError::TooFewArgs
|
||||
::rustpython_vm::function::ArgumentError::TooFewArgs
|
||||
},
|
||||
ParameterKind::KeywordOnly => quote! {
|
||||
#rp_path::function::ArgumentError::RequiredKeywordArgument(tringify!(#name))
|
||||
::rustpython_vm::function::ArgumentError::RequiredKeywordArgument(tringify!(#name))
|
||||
},
|
||||
};
|
||||
quote! {
|
||||
@@ -177,14 +176,10 @@ fn generate_field(field: &Field, rp_path: &syn::Path) -> TokenStream2 {
|
||||
}
|
||||
|
||||
pub fn impl_from_args(input: DeriveInput) -> TokenStream2 {
|
||||
let rp_path = rustpython_path_derive(&input);
|
||||
let fields = match input.data {
|
||||
Data::Struct(ref data) => {
|
||||
match data.fields {
|
||||
Fields::Named(ref fields) => fields
|
||||
.named
|
||||
.iter()
|
||||
.map(|field| generate_field(field, &rp_path)),
|
||||
Fields::Named(ref fields) => fields.named.iter().map(generate_field),
|
||||
Fields::Unnamed(_) | Fields::Unit => unimplemented!(), // TODO: better error message
|
||||
}
|
||||
}
|
||||
@@ -193,11 +188,11 @@ pub fn impl_from_args(input: DeriveInput) -> TokenStream2 {
|
||||
|
||||
let name = &input.ident;
|
||||
quote! {
|
||||
impl #rp_path::function::FromArgs for #name {
|
||||
impl ::rustpython_vm::function::FromArgs for #name {
|
||||
fn from_args(
|
||||
vm: &#rp_path::VirtualMachine,
|
||||
args: &mut #rp_path::function::PyFuncArgs
|
||||
) -> Result<Self, #rp_path::function::ArgumentError> {
|
||||
vm: &::rustpython_vm::VirtualMachine,
|
||||
args: &mut ::rustpython_vm::function::PyFuncArgs
|
||||
) -> Result<Self, ::rustpython_vm::function::ArgumentError> {
|
||||
Ok(#name { #(#fields)* })
|
||||
}
|
||||
}
|
||||
|
||||
+1
-36
@@ -1,47 +1,12 @@
|
||||
extern crate proc_macro;
|
||||
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{parse_macro_input, AttributeArgs, DeriveInput, Item};
|
||||
|
||||
mod from_args;
|
||||
mod pyclass;
|
||||
|
||||
fn rustpython_path(inside_vm: bool) -> syn::Path {
|
||||
let path = if inside_vm {
|
||||
quote!(crate)
|
||||
} else {
|
||||
quote!(::rustpython_vm)
|
||||
};
|
||||
syn::parse2(path).unwrap()
|
||||
}
|
||||
|
||||
/// Does the item have the #[__inside_vm] attribute on it, signifying that the derive target is
|
||||
/// being derived from inside the `rustpython_vm` crate.
|
||||
fn rustpython_path_derive(input: &DeriveInput) -> syn::Path {
|
||||
rustpython_path(
|
||||
input
|
||||
.attrs
|
||||
.iter()
|
||||
.any(|attr| attr.path.is_ident("__inside_vm")),
|
||||
)
|
||||
}
|
||||
|
||||
fn rustpython_path_attr(attr: &AttributeArgs) -> syn::Path {
|
||||
rustpython_path(attr.iter().any(|meta| {
|
||||
if let syn::NestedMeta::Meta(meta) = meta {
|
||||
if let syn::Meta::Word(ident) = meta {
|
||||
ident == "__inside_vm"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
#[proc_macro_derive(FromArgs, attributes(__inside_vm, pyarg))]
|
||||
#[proc_macro_derive(FromArgs, attributes(pyarg))]
|
||||
pub fn derive_from_args(input: TokenStream) -> TokenStream {
|
||||
let ast: DeriveInput = syn::parse(input).unwrap();
|
||||
|
||||
|
||||
+6
-11
@@ -1,4 +1,3 @@
|
||||
use super::rustpython_path_attr;
|
||||
use proc_macro2::TokenStream as TokenStream2;
|
||||
use quote::quote;
|
||||
use std::collections::HashMap;
|
||||
@@ -138,15 +137,13 @@ impl ClassItem {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn impl_pyimpl(attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
pub fn impl_pyimpl(_attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
let mut imp = if let Item::Impl(imp) = item {
|
||||
imp
|
||||
} else {
|
||||
return quote!(#item);
|
||||
};
|
||||
|
||||
let rp_path = rustpython_path_attr(&attr);
|
||||
|
||||
let items = imp
|
||||
.items
|
||||
.iter_mut()
|
||||
@@ -199,7 +196,7 @@ pub fn impl_pyimpl(attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
quote! {
|
||||
class.set_str_attr(
|
||||
#name,
|
||||
#rp_path::obj::objproperty::PropertyBuilder::new(ctx)
|
||||
::rustpython_vm::obj::objproperty::PropertyBuilder::new(ctx)
|
||||
.add_getter(Self::#getter)
|
||||
#add_setter
|
||||
.create(),
|
||||
@@ -209,10 +206,10 @@ pub fn impl_pyimpl(attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
|
||||
quote! {
|
||||
#imp
|
||||
impl #rp_path::pyobject::PyClassImpl for #ty {
|
||||
impl ::rustpython_vm::pyobject::PyClassImpl for #ty {
|
||||
fn impl_extend_class(
|
||||
ctx: &#rp_path::pyobject::PyContext,
|
||||
class: &#rp_path::obj::objtype::PyClassRef,
|
||||
ctx: &::rustpython_vm::pyobject::PyContext,
|
||||
class: &::rustpython_vm::obj::objtype::PyClassRef,
|
||||
) {
|
||||
#(#methods)*
|
||||
#(#properties)*
|
||||
@@ -228,8 +225,6 @@ pub fn impl_pyclass(attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
_ => panic!("#[pyclass] can only be on a struct or enum declaration"),
|
||||
};
|
||||
|
||||
let rp_path = rustpython_path_attr(&attr);
|
||||
|
||||
let mut class_name = None;
|
||||
for attr in attr {
|
||||
if let NestedMeta::Meta(meta) = attr {
|
||||
@@ -273,7 +268,7 @@ pub fn impl_pyclass(attr: AttributeArgs, item: Item) -> TokenStream2 {
|
||||
|
||||
quote! {
|
||||
#item
|
||||
impl #rp_path::pyobject::PyClassDef for #ident {
|
||||
impl ::rustpython_vm::pyobject::PyClassDef for #ident {
|
||||
const NAME: &'static str = #class_name;
|
||||
const DOC: Option<&'static str> = #doc;
|
||||
}
|
||||
|
||||
@@ -530,7 +530,6 @@ fn builtin_pow(vm: &VirtualMachine, args: PyFuncArgs) -> PyResult {
|
||||
}
|
||||
|
||||
#[derive(Debug, FromArgs)]
|
||||
#[__inside_vm]
|
||||
pub struct PrintOptions {
|
||||
#[pyarg(keyword_only, default = "None")]
|
||||
sep: Option<PyStringRef>,
|
||||
|
||||
@@ -32,6 +32,8 @@ extern crate rustpython_parser;
|
||||
#[macro_use]
|
||||
extern crate rustpython_derive;
|
||||
|
||||
extern crate self as rustpython_vm;
|
||||
|
||||
pub use rustpython_derive::*;
|
||||
|
||||
//extern crate eval; use eval::eval::*;
|
||||
|
||||
@@ -21,7 +21,7 @@ use super::objtype::PyClassRef;
|
||||
/// - a text string encoded using the specified encoding\n \
|
||||
/// - any object implementing the buffer API.\n \
|
||||
/// - an integer";
|
||||
#[pyclass(name = "bytes", __inside_vm)]
|
||||
#[pyclass(name = "bytes")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PyBytes {
|
||||
inner: PyByteInner,
|
||||
@@ -71,7 +71,7 @@ pub fn init(context: &PyContext) {
|
||||
});
|
||||
}
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl PyBytesRef {
|
||||
#[pymethod(name = "__new__")]
|
||||
fn bytes_new(
|
||||
|
||||
@@ -327,13 +327,13 @@ impl Iterator for DictIter {
|
||||
|
||||
macro_rules! dict_iterator {
|
||||
( $name: ident, $iter_name: ident, $class: ident, $iter_class: ident, $class_name: literal, $iter_class_name: literal, $result_fn: expr) => {
|
||||
#[pyclass(name = $class_name, __inside_vm)]
|
||||
#[pyclass(name = $class_name)]
|
||||
#[derive(Debug)]
|
||||
struct $name {
|
||||
pub dict: PyDictRef,
|
||||
}
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl $name {
|
||||
fn new(dict: PyDictRef) -> Self {
|
||||
$name { dict: dict }
|
||||
@@ -356,7 +356,7 @@ macro_rules! dict_iterator {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass(name = $iter_class_name, __inside_vm)]
|
||||
#[pyclass(name = $iter_class_name)]
|
||||
#[derive(Debug)]
|
||||
struct $iter_name {
|
||||
pub dict: PyDictRef,
|
||||
@@ -364,7 +364,7 @@ macro_rules! dict_iterator {
|
||||
pub position: Cell<usize>,
|
||||
}
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl $iter_name {
|
||||
fn new(dict: PyDictRef) -> Self {
|
||||
$iter_name {
|
||||
|
||||
@@ -9,7 +9,7 @@ use crate::vm::VirtualMachine;
|
||||
|
||||
pub type PyGeneratorRef = PyRef<PyGenerator>;
|
||||
|
||||
#[pyclass(name = "generator", __inside_vm)]
|
||||
#[pyclass(name = "generator")]
|
||||
#[derive(Debug)]
|
||||
pub struct PyGenerator {
|
||||
frame: FrameRef,
|
||||
@@ -21,7 +21,7 @@ impl PyValue for PyGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl PyGenerator {
|
||||
pub fn new(frame: FrameRef, vm: &VirtualMachine) -> PyGeneratorRef {
|
||||
PyGenerator { frame }.into_ref(vm)
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::obj::objtype::PyClassRef;
|
||||
/// Base 0 means to interpret the base from the string as an integer literal.
|
||||
/// >>> int('0b100', base=0)
|
||||
/// 4
|
||||
#[pyclass(__inside_vm)]
|
||||
#[pyclass]
|
||||
#[derive(Debug)]
|
||||
pub struct PyInt {
|
||||
value: BigInt,
|
||||
@@ -111,7 +111,7 @@ impl_try_from_object_int!(
|
||||
(u64, to_u64),
|
||||
);
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl PyInt {
|
||||
#[pymethod(name = "__eq__")]
|
||||
fn eq(&self, other: PyObjectRef, vm: &VirtualMachine) -> PyObjectRef {
|
||||
@@ -476,7 +476,6 @@ impl PyInt {
|
||||
}
|
||||
|
||||
#[derive(FromArgs)]
|
||||
#[__inside_vm]
|
||||
struct IntOptions {
|
||||
#[pyarg(positional_only, optional = true)]
|
||||
val_options: OptionalArg<PyObjectRef>,
|
||||
|
||||
@@ -30,7 +30,7 @@ use super::objtype::{self, PyClassRef};
|
||||
/// or repr(object).
|
||||
/// encoding defaults to sys.getdefaultencoding().
|
||||
/// errors defaults to 'strict'."
|
||||
#[pyclass(name = "str", __inside_vm)]
|
||||
#[pyclass(name = "str")]
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PyString {
|
||||
// TODO: shouldn't be public
|
||||
@@ -74,7 +74,7 @@ impl TryIntoRef<PyString> for &str {
|
||||
}
|
||||
}
|
||||
|
||||
#[pyimpl(__inside_vm)]
|
||||
#[pyimpl]
|
||||
impl PyString {
|
||||
// TODO: should with following format
|
||||
// class str(object='')
|
||||
|
||||
Reference in new issue
Block a user