Simplify rename checking.

This commit is contained in:
Stephen Chung 2020-09-26 12:08:15 +08:00
parent 371b7fd00b
commit 0d7d54e21c

View File

@ -183,23 +183,24 @@ pub(crate) fn flatten_type_groups(ty: &syn::Type) -> &syn::Type {
} }
pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> { pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::Error> {
fn make_key(name: String, itemfn: &ExportedFn) -> String { fn make_key(name: impl ToString, itemfn: &ExportedFn) -> String {
itemfn.arg_list().fold(name, |mut argstr, fnarg| { itemfn
let type_string: String = match fnarg { .arg_list()
syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"), .fold(name.to_string(), |mut argstr, fnarg| {
syn::FnArg::Typed(syn::PatType { ref ty, .. }) => { let type_string: String = match fnarg {
ty.as_ref().to_token_stream().to_string() syn::FnArg::Receiver(_) => unimplemented!("receiver rhai_fns not implemented"),
} syn::FnArg::Typed(syn::PatType { ref ty, .. }) => {
}; ty.as_ref().to_token_stream().to_string()
argstr.push('.'); }
argstr.push_str(&type_string); };
argstr argstr.push('.');
}) argstr.push_str(&type_string);
argstr
})
} }
let mut renames = HashMap::<String, proc_macro2::Span>::new(); let mut renames = HashMap::<String, proc_macro2::Span>::new();
let mut fn_names = HashMap::<String, proc_macro2::Span>::new(); let mut fn_defs = HashMap::<String, proc_macro2::Span>::new();
let mut fn_sig = HashMap::<String, proc_macro2::Span>::new();
for itemfn in fns.iter() { for itemfn in fns.iter() {
if itemfn.params().name.is_some() || itemfn.params().special != FnSpecialAccess::None { if itemfn.params().name.is_some() || itemfn.params().special != FnSpecialAccess::None {
@ -216,7 +217,7 @@ pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::
for (name, fn_name) in names { for (name, fn_name) in names {
let current_span = itemfn.params().span.as_ref().unwrap(); let current_span = itemfn.params().span.as_ref().unwrap();
let key = make_key(name.clone(), itemfn); let key = make_key(&name, itemfn);
if let Some(other_span) = renames.insert(key, *current_span) { if let Some(other_span) = renames.insert(key, *current_span) {
let mut err = syn::Error::new( let mut err = syn::Error::new(
*current_span, *current_span,
@ -231,7 +232,7 @@ pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::
} }
} else { } else {
let ident = itemfn.name(); let ident = itemfn.name();
if let Some(other_span) = fn_names.insert(ident.to_string(), ident.span()) { if let Some(other_span) = fn_defs.insert(ident.to_string(), ident.span()) {
let mut err = syn::Error::new( let mut err = syn::Error::new(
ident.span(), ident.span(),
format!("duplicate function '{}'", ident.to_string()), format!("duplicate function '{}'", ident.to_string()),
@ -242,24 +243,20 @@ pub(crate) fn check_rename_collisions(fns: &Vec<ExportedFn>) -> Result<(), syn::
)); ));
return Err(err); return Err(err);
} }
let key = make_key(ident.to_string(), itemfn); let key = make_key(ident, itemfn);
fn_sig.insert(key, ident.span()); if let Some(fn_span) = renames.get(&key) {
let mut err = syn::Error::new(
ident.span(),
format!("duplicate Rhai signature for '{}'", &ident),
);
err.combine(syn::Error::new(
*fn_span,
format!("duplicated function '{}'", &ident),
));
return Err(err);
}
} }
} }
for (new_name, attr_span) in renames.drain() {
let fn_name = new_name.split('.').next().unwrap();
if let Some(fn_span) = fn_sig.get(&new_name) {
let mut err = syn::Error::new(
attr_span,
format!("duplicate Rhai signature for '{}'", &fn_name),
);
err.combine(syn::Error::new(
*fn_span,
format!("duplicated function '{}'", &fn_name),
));
return Err(err);
}
}
Ok(()) Ok(())
} }