Flatten types in functions.
This commit is contained in:
parent
5a37497a22
commit
235ad66d2b
@ -16,6 +16,7 @@ use quote::{quote, quote_spanned};
|
|||||||
use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
|
use syn::{parse::Parse, parse::ParseStream, parse::Parser, spanned::Spanned};
|
||||||
|
|
||||||
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
use crate::attrs::{ExportInfo, ExportScope, ExportedParams};
|
||||||
|
use crate::rhai_module::flatten_type_groups;
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
pub enum Index {
|
pub enum Index {
|
||||||
@ -223,27 +224,29 @@ impl Parse for ExportedFn {
|
|||||||
syn::FnArg::Receiver(syn::Receiver {
|
syn::FnArg::Receiver(syn::Receiver {
|
||||||
reference: Some(_), ..
|
reference: Some(_), ..
|
||||||
}) => true,
|
}) => true,
|
||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => match ty.as_ref() {
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
match flatten_type_groups(ty.as_ref()) {
|
||||||
mutability: Some(_),
|
&syn::Type::Reference(syn::TypeReference {
|
||||||
..
|
mutability: Some(_),
|
||||||
}) => true,
|
..
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
}) => true,
|
||||||
mutability: None,
|
&syn::Type::Reference(syn::TypeReference {
|
||||||
ref elem,
|
mutability: None,
|
||||||
..
|
ref elem,
|
||||||
}) => match elem.as_ref() {
|
..
|
||||||
&syn::Type::Path(ref p) if p.path == str_type_path => false,
|
}) => match flatten_type_groups(elem.as_ref()) {
|
||||||
_ => {
|
&syn::Type::Path(ref p) if p.path == str_type_path => false,
|
||||||
return Err(syn::Error::new(
|
_ => {
|
||||||
ty.span(),
|
return Err(syn::Error::new(
|
||||||
"references from Rhai in this position \
|
ty.span(),
|
||||||
|
"references from Rhai in this position \
|
||||||
must be mutable",
|
must be mutable",
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
}
|
||||||
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -257,7 +260,7 @@ impl Parse for ExportedFn {
|
|||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => ty,
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => ty,
|
||||||
_ => panic!("internal error: receiver argument outside of first position!?"),
|
_ => panic!("internal error: receiver argument outside of first position!?"),
|
||||||
};
|
};
|
||||||
let is_ok = match ty.as_ref() {
|
let is_ok = match flatten_type_groups(ty.as_ref()) {
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
&syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: Some(_),
|
mutability: Some(_),
|
||||||
..
|
..
|
||||||
@ -266,7 +269,9 @@ impl Parse for ExportedFn {
|
|||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
}) => matches!(elem.as_ref(), &syn::Type::Path(ref p) if p.path == str_type_path),
|
}) => {
|
||||||
|
matches!(flatten_type_groups(elem.as_ref()), &syn::Type::Path(ref p) if p.path == str_type_path)
|
||||||
|
}
|
||||||
&syn::Type::Verbatim(_) => false,
|
&syn::Type::Verbatim(_) => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
};
|
};
|
||||||
@ -605,13 +610,9 @@ impl ExportedFn {
|
|||||||
let var = syn::Ident::new("arg0", proc_macro2::Span::call_site());
|
let var = syn::Ident::new("arg0", proc_macro2::Span::call_site());
|
||||||
match first_arg {
|
match first_arg {
|
||||||
syn::FnArg::Typed(pattern) => {
|
syn::FnArg::Typed(pattern) => {
|
||||||
let arg_type: &syn::Type = {
|
let arg_type: &syn::Type = match flatten_type_groups(pattern.ty.as_ref()) {
|
||||||
match pattern.ty.as_ref() {
|
&syn::Type::Reference(syn::TypeReference { ref elem, .. }) => elem.as_ref(),
|
||||||
&syn::Type::Reference(syn::TypeReference { ref elem, .. }) => {
|
p => p,
|
||||||
elem.as_ref()
|
|
||||||
}
|
|
||||||
ref p => p,
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
let downcast_span = quote_spanned!(
|
let downcast_span = quote_spanned!(
|
||||||
arg_type.span()=> &mut args[0usize].write_lock::<#arg_type>().unwrap());
|
arg_type.span()=> &mut args[0usize].write_lock::<#arg_type>().unwrap());
|
||||||
@ -648,12 +649,12 @@ impl ExportedFn {
|
|||||||
match arg {
|
match arg {
|
||||||
syn::FnArg::Typed(pattern) => {
|
syn::FnArg::Typed(pattern) => {
|
||||||
let arg_type: &syn::Type = pattern.ty.as_ref();
|
let arg_type: &syn::Type = pattern.ty.as_ref();
|
||||||
let downcast_span = match pattern.ty.as_ref() {
|
let downcast_span = match flatten_type_groups(pattern.ty.as_ref()) {
|
||||||
&syn::Type::Reference(syn::TypeReference {
|
&syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
}) => match elem.as_ref() {
|
}) => match flatten_type_groups(elem.as_ref()) {
|
||||||
&syn::Type::Path(ref p) if p.path == str_type_path => {
|
&syn::Type::Path(ref p) if p.path == str_type_path => {
|
||||||
is_string = true;
|
is_string = true;
|
||||||
is_ref = true;
|
is_ref = true;
|
||||||
|
@ -85,22 +85,12 @@ pub(crate) fn generate_body(
|
|||||||
.map(|fnarg| match fnarg {
|
.map(|fnarg| match fnarg {
|
||||||
syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"),
|
syn::FnArg::Receiver(_) => panic!("internal error: receiver fn outside impl!?"),
|
||||||
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
|
||||||
fn flatten_groups(ty: &syn::Type) -> &syn::Type {
|
let arg_type = match flatten_type_groups(ty.as_ref()) {
|
||||||
match ty {
|
|
||||||
syn::Type::Group(syn::TypeGroup { ref elem, .. })
|
|
||||||
| syn::Type::Paren(syn::TypeParen { ref elem, .. }) => {
|
|
||||||
flatten_groups(elem.as_ref())
|
|
||||||
}
|
|
||||||
_ => ty,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let arg_type = match flatten_groups(ty.as_ref()) {
|
|
||||||
syn::Type::Reference(syn::TypeReference {
|
syn::Type::Reference(syn::TypeReference {
|
||||||
mutability: None,
|
mutability: None,
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
}) => match flatten_groups(elem.as_ref()) {
|
}) => match flatten_type_groups(elem.as_ref()) {
|
||||||
syn::Type::Path(ref p) if p.path == str_type_path => {
|
syn::Type::Path(ref p) if p.path == str_type_path => {
|
||||||
syn::parse2::<syn::Type>(quote! {
|
syn::parse2::<syn::Type>(quote! {
|
||||||
ImmutableString })
|
ImmutableString })
|
||||||
@ -117,7 +107,7 @@ pub(crate) fn generate_body(
|
|||||||
mutability: Some(_),
|
mutability: Some(_),
|
||||||
ref elem,
|
ref elem,
|
||||||
..
|
..
|
||||||
}) => match flatten_groups(elem.as_ref()) {
|
}) => match flatten_type_groups(elem.as_ref()) {
|
||||||
syn::Type::Path(ref p) => syn::parse2::<syn::Type>(quote! {
|
syn::Type::Path(ref p) => syn::parse2::<syn::Type>(quote! {
|
||||||
#p })
|
#p })
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
@ -184,6 +174,14 @@ pub(crate) fn generate_body(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn flatten_type_groups(ty: &syn::Type) -> &syn::Type {
|
||||||
|
match ty {
|
||||||
|
syn::Type::Group(syn::TypeGroup { ref elem, .. })
|
||||||
|
| syn::Type::Paren(syn::TypeParen { ref elem, .. }) => flatten_type_groups(elem.as_ref()),
|
||||||
|
_ => ty,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
|
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
|
||||||
let mut renames = HashMap::<String, proc_macro2::Span>::new();
|
let mut renames = HashMap::<String, proc_macro2::Span>::new();
|
||||||
let mut names = HashMap::<String, proc_macro2::Span>::new();
|
let mut names = HashMap::<String, proc_macro2::Span>::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user