mirror of
https://github.com/icewind1991/ivory.git
synced 2026-06-03 10:44:09 +02:00
work towards type hints in function exports
once const traits are a thing the zvaltype can be determined
This commit is contained in:
parent
9c4f3ab8a0
commit
5eb8082d86
3 changed files with 70 additions and 10 deletions
|
|
@ -7,9 +7,7 @@ mod cache;
|
|||
use proc_macro2::{Span, TokenStream, TokenTree};
|
||||
use quote::quote;
|
||||
use syn::spanned::Spanned;
|
||||
use syn::{
|
||||
parse_macro_input, AttributeArgs, FnArg, Ident, Item, ItemFn, LitStr, Pat, ReturnType, Type,
|
||||
};
|
||||
use syn::{parse_macro_input, AttributeArgs, FnArg, Ident, Item, ItemFn, LitStr, Pat, ReturnType, Type, parse_str};
|
||||
|
||||
/// See the [crate documentation](index.html) for details
|
||||
#[proc_macro_attribute]
|
||||
|
|
@ -34,6 +32,7 @@ pub fn ivory_export(
|
|||
#[derive(Clone)]
|
||||
pub(crate) struct ArgumentDefinition {
|
||||
name: String,
|
||||
ty: String,
|
||||
is_ref: bool,
|
||||
}
|
||||
|
||||
|
|
@ -115,6 +114,7 @@ fn get_arg_info(arg: FnArg) -> (ArgumentDefinition, Type) {
|
|||
Pat::Ident(ident_pat) => (
|
||||
ArgumentDefinition {
|
||||
name: ident_pat.ident.to_string(),
|
||||
ty: format!("{}", quote!(#arg_type)),
|
||||
is_ref: ident_pat.by_ref.is_some(),
|
||||
},
|
||||
arg_type,
|
||||
|
|
@ -164,7 +164,7 @@ pub fn ivory_module(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
|||
entry.set_info_func(php_module_info);
|
||||
|
||||
|
||||
entry.set_functions(&IVORY_FUCTIONS);
|
||||
entry.set_functions(&IVORY_FUNCTIONS);
|
||||
|
||||
Box::into_raw(entry)
|
||||
}
|
||||
|
|
@ -215,7 +215,8 @@ fn get_funcs(funcs: Vec<FunctionDefinition>, span: Span) -> TokenStream {
|
|||
let arg_defs = func.args.iter().map(|arg| {
|
||||
let name = &arg.name;
|
||||
let is_ref = &arg.is_ref;
|
||||
quote!(::ivory::zend::ArgInfo::new(::ivory::c_str!(#name), false, false, #is_ref))
|
||||
let ty = parse_str::<Type>(&arg.ty).unwrap();
|
||||
quote!(::ivory::zend::ArgInfo::from_type::<#ty>(::ivory::c_str!(#name), #is_ref))
|
||||
});
|
||||
|
||||
if num_args > 0 {
|
||||
|
|
@ -223,7 +224,7 @@ fn get_funcs(funcs: Vec<FunctionDefinition>, span: Span) -> TokenStream {
|
|||
::ivory::zend::Function::new_with_args(
|
||||
{concat!(#name, "\0").as_ptr() as *const ::std::os::raw::c_char},
|
||||
#name_ident as *const ::std::os::raw::c_void,
|
||||
&[::ivory::zend::ArgInfo::new(#num_args as *const ::std::os::raw::c_char, false, false, false),
|
||||
&[::ivory::zend::ArgInfo::arg_count(#num_args),
|
||||
#(#arg_defs),*
|
||||
],
|
||||
#num_args as u32
|
||||
|
|
@ -240,7 +241,7 @@ fn get_funcs(funcs: Vec<FunctionDefinition>, span: Span) -> TokenStream {
|
|||
});
|
||||
|
||||
quote! {
|
||||
const IVORY_FUCTIONS: [::ivory::zend::Function; #func_count] = [
|
||||
const IVORY_FUNCTIONS: [::ivory::zend::Function; #func_count] = [
|
||||
#(#definitions),*,
|
||||
::ivory::zend::Function::end()
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use crate::zend::zval::GetTypeHint;
|
||||
use crate::zend::ZValType;
|
||||
use std;
|
||||
use std::os::raw::{c_char, c_uchar, c_void};
|
||||
|
||||
|
|
@ -6,7 +8,9 @@ use std::os::raw::{c_char, c_uchar, c_void};
|
|||
pub struct ArgInfo {
|
||||
pub name: *const c_char,
|
||||
pub class_name: *const c_char,
|
||||
pub type_hint: c_uchar,
|
||||
// *const c_char
|
||||
pub type_hint: ZValType,
|
||||
// *const c_char
|
||||
pub pass_by_reference: c_uchar,
|
||||
pub allow_null: c_uchar,
|
||||
pub is_variadic: c_uchar,
|
||||
|
|
@ -15,6 +19,7 @@ pub struct ArgInfo {
|
|||
impl ArgInfo {
|
||||
pub const fn new(
|
||||
name: *const c_char,
|
||||
ty: ZValType,
|
||||
allow_null: bool,
|
||||
is_variadic: bool,
|
||||
by_reference: bool,
|
||||
|
|
@ -22,12 +27,36 @@ impl ArgInfo {
|
|||
ArgInfo {
|
||||
name,
|
||||
class_name: std::ptr::null(),
|
||||
type_hint: 0,
|
||||
type_hint: ty,
|
||||
pass_by_reference: by_reference as c_uchar,
|
||||
allow_null: allow_null as c_uchar,
|
||||
is_variadic: is_variadic as c_uchar,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn arg_count(count: usize) -> Self {
|
||||
ArgInfo::new(count as *const c_char, ZValType::Undef, false, false, false)
|
||||
}
|
||||
|
||||
pub const fn from_type<T>(name: *const c_char, is_ref: bool) -> Self {
|
||||
ArgInfo::new(name, ZValType::Undef, false, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait GetArgInfo {
|
||||
fn get_arg_info(name: *const c_char, is_ref: bool) -> ArgInfo;
|
||||
}
|
||||
|
||||
impl<T: GetTypeHint> GetArgInfo for T {
|
||||
fn get_arg_info(name: *const c_char, is_ref: bool) -> ArgInfo {
|
||||
ArgInfo::new(name, Self::get_type_hint(), false, false, is_ref)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: GetTypeHint> GetArgInfo for Option<T> {
|
||||
fn get_arg_info(name: *const c_char, is_ref: bool) -> ArgInfo {
|
||||
ArgInfo::new(name, T::get_type_hint(), true, false, is_ref)
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ impl ZVal {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum ZValType {
|
||||
Undef = 0,
|
||||
|
|
@ -159,6 +159,36 @@ impl Display for ZValType {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait GetTypeHint {
|
||||
fn get_type_hint() -> ZValType;
|
||||
}
|
||||
|
||||
macro_rules! impl_get_type_hint {
|
||||
($type:ty, $hint:expr) => {
|
||||
impl GetTypeHint for $type {
|
||||
#[inline]
|
||||
fn get_type_hint() -> ZValType {
|
||||
$hint
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_get_type_hint!(String, ZValType::String);
|
||||
impl_get_type_hint!(bool, ZValType::Bool);
|
||||
impl_get_type_hint!(f64, ZValType::Double);
|
||||
impl_get_type_hint!(f32, ZValType::Double);
|
||||
impl_get_type_hint!(u8, ZValType::Long);
|
||||
impl_get_type_hint!(u16, ZValType::Long);
|
||||
impl_get_type_hint!(u32, ZValType::Long);
|
||||
impl_get_type_hint!(u64, ZValType::Long);
|
||||
impl_get_type_hint!(usize, ZValType::Long);
|
||||
impl_get_type_hint!(i8, ZValType::Long);
|
||||
impl_get_type_hint!(i16, ZValType::Long);
|
||||
impl_get_type_hint!(i32, ZValType::Long);
|
||||
impl_get_type_hint!(i64, ZValType::Long);
|
||||
impl_get_type_hint!(isize, ZValType::Long);
|
||||
|
||||
impl From<ZValType> for u8 {
|
||||
fn from(val: ZValType) -> Self {
|
||||
unsafe { transmute(val) }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue