Remove the __inside_vm hack for procedural macros

This commit is contained in:
coolreader18 committed 2019-04-15 20:24:16 -05:00
1 parent 78db5ea311
commit 08babef619
10 files changed
+32 -77

No files matched your search

+11 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
-1
View File
@@ -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>,
+2
View File
@@ -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::*;
+2 -2
View File
@@ -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(
+4 -4
View File
@@ -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 {
+2 -2
View File
@@ -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)
+2 -3
View File
@@ -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>,
+2 -2
View File
@@ -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='')