From a2551a4650b76abe9998b3a36852a938419dfc4e Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Sat, 26 Sep 2020 00:30:30 +0800 Subject: [PATCH] Check rename collisions with special names. --- codegen/src/function.rs | 42 ++++++++++++------- codegen/src/rhai_module.rs | 26 ++++++++---- ...n_rename_collision_oneattr_multiple.stderr | 14 +++---- 3 files changed, 52 insertions(+), 30 deletions(-) diff --git a/codegen/src/function.rs b/codegen/src/function.rs index 2126fd73..72ad2b64 100644 --- a/codegen/src/function.rs +++ b/codegen/src/function.rs @@ -43,6 +43,30 @@ impl Default for FnSpecialAccess { } } +impl FnSpecialAccess { + pub fn get_fn_name(&self) -> Option<(String, String, proc_macro2::Span)> { + match self { + FnSpecialAccess::None => None, + FnSpecialAccess::Property(Property::Get(ref g)) => { + Some((format!("get${}", g.to_string()), g.to_string(), g.span())) + } + FnSpecialAccess::Property(Property::Set(ref s)) => { + Some((format!("set${}", s.to_string()), s.to_string(), s.span())) + } + FnSpecialAccess::Index(Index::Get) => Some(( + FN_IDX_GET.to_string(), + "index_get".to_string(), + proc_macro2::Span::call_site(), + )), + FnSpecialAccess::Index(Index::Set) => Some(( + FN_IDX_SET.to_string(), + "index_set".to_string(), + proc_macro2::Span::call_site(), + )), + } + } +} + #[derive(Debug, Default)] pub(crate) struct ExportedFnParams { pub name: Option>, @@ -363,22 +387,8 @@ impl ExportedFn { }) .unwrap_or_else(|| Vec::new()); - match self.params.special { - FnSpecialAccess::None => {} - FnSpecialAccess::Property(Property::Get(ref g)) => literals.push(syn::LitStr::new( - &format!("get${}", g.to_string()), - g.span(), - )), - FnSpecialAccess::Property(Property::Set(ref s)) => literals.push(syn::LitStr::new( - &format!("set${}", s.to_string()), - s.span(), - )), - FnSpecialAccess::Index(Index::Get) => { - literals.push(syn::LitStr::new(FN_IDX_GET, proc_macro2::Span::call_site())) - } - FnSpecialAccess::Index(Index::Set) => { - literals.push(syn::LitStr::new(FN_IDX_SET, proc_macro2::Span::call_site())) - } + if let Some((s, _, span)) = self.params.special.get_fn_name() { + literals.push(syn::LitStr::new(&s, span)); } if literals.is_empty() { diff --git a/codegen/src/rhai_module.rs b/codegen/src/rhai_module.rs index 473c3398..ab0dd117 100644 --- a/codegen/src/rhai_module.rs +++ b/codegen/src/rhai_module.rs @@ -3,7 +3,7 @@ use std::collections::HashMap; use quote::{quote, ToTokens}; use crate::attrs::ExportScope; -use crate::function::ExportedFn; +use crate::function::{ExportedFn, FnSpecialAccess}; use crate::module::Module; pub(crate) type ExportedConst = (String, Box, syn::Expr); @@ -202,18 +202,29 @@ pub(crate) fn check_rename_collisions(fns: &Vec) -> Result<(), syn:: let mut fn_sig = HashMap::::new(); for itemfn in fns.iter() { - if let Some(ref names) = itemfn.params().name { - for name in names { + if itemfn.params().name.is_some() || itemfn.params().special != FnSpecialAccess::None { + let mut names = itemfn + .params() + .name + .as_ref() + .map(|v| v.iter().map(|n| (n.clone(), n.clone())).collect()) + .unwrap_or_else(|| Vec::new()); + + if let Some((s, n, _)) = itemfn.params().special.get_fn_name() { + names.push((s, n)); + } + + for (name, fn_name) in names { let current_span = itemfn.params().span.as_ref().unwrap(); let key = make_key(name.clone(), itemfn); if let Some(other_span) = renames.insert(key, *current_span) { let mut err = syn::Error::new( *current_span, - format!("duplicate Rhai signature for '{}'", &name), + format!("duplicate Rhai signature for '{}'", &fn_name), ); err.combine(syn::Error::new( other_span, - format!("duplicated function renamed '{}'", &name), + format!("duplicated function renamed '{}'", &fn_name), )); return Err(err); } @@ -237,14 +248,15 @@ pub(crate) fn check_rename_collisions(fns: &Vec) -> Result<(), syn:: } 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 '{}'", &new_name), + format!("duplicate Rhai signature for '{}'", &fn_name), ); err.combine(syn::Error::new( *fn_span, - format!("duplicated function '{}'", &new_name), + format!("duplicated function '{}'", &fn_name), )); return Err(err); } diff --git a/codegen/ui_tests/rhai_fn_rename_collision_oneattr_multiple.stderr b/codegen/ui_tests/rhai_fn_rename_collision_oneattr_multiple.stderr index 77375279..78770b8d 100644 --- a/codegen/ui_tests/rhai_fn_rename_collision_oneattr_multiple.stderr +++ b/codegen/ui_tests/rhai_fn_rename_collision_oneattr_multiple.stderr @@ -1,15 +1,15 @@ -error: duplicate Rhai signature for 'foo' +error: duplicate Rhai signature for 'bar' + --> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:17:15 + | +17 | #[rhai_fn(get = "bar")] + | ^^^ + +error: duplicated function renamed 'bar' --> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:12:15 | 12 | #[rhai_fn(name = "foo", get = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^ -error: duplicated function 'foo' - --> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:18:12 - | -18 | pub fn foo(input: Point) -> bool { - | ^^^ - error[E0433]: failed to resolve: use of undeclared crate or module `test_module` --> $DIR/rhai_fn_rename_collision_oneattr_multiple.rs:25:8 |