From 75f005be23eca8b38d88ed56dc6dee52c6f174c7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 21 Sep 2018 17:34:41 -0700 Subject: [PATCH] Support `#[wasm_bindgen(setter, js_name = ...)]` Previously we'd require the explicit `js_name` to *also* start with `set_`, but when explicitly specified it shouldn't be mangled at all! Closes #584 --- crates/backend/src/ast.rs | 9 +++++++++ crates/macro-support/src/parser.rs | 1 + crates/macro/ui-tests/invalid-setter.stderr | 8 +------- crates/webidl/src/util.rs | 4 +++- tests/wasm/import_class.rs | 6 ++++++ 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 6787c758..51eabd56 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -168,6 +168,7 @@ pub struct ImportEnum { pub struct Function { pub name: String, pub name_span: Span, + pub renamed_via_js_name: bool, pub arguments: Vec, pub ret: Option, pub rust_attrs: Vec, @@ -393,6 +394,14 @@ impl ImportFunction { /// for a setter in javascript (in this case `xxx`, so you can write `obj.xxx = val`) fn infer_setter_property(&self) -> Result { let name = self.function.name.to_string(); + + // if `#[wasm_bindgen(js_name = "...")]` is used then that explicitly + // because it was hand-written anyway. + if self.function.renamed_via_js_name { + return Ok(name) + } + + // Otherwise we infer names based on the Rust function name. if !name.starts_with("set_") { bail_span!( syn::token::Pub(self.function.name_span), diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index eafc6de1..9ed487ec 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -689,6 +689,7 @@ fn function_from_decl( ast::Function { name: js_name.map(|s| s.0.to_string()).unwrap_or(decl_name.to_string()), name_span: js_name.map(|s| s.1).unwrap_or(decl_name.span()), + renamed_via_js_name: js_name.is_some(), arguments, ret, rust_vis: vis, diff --git a/crates/macro/ui-tests/invalid-setter.stderr b/crates/macro/ui-tests/invalid-setter.stderr index b4e0d2f1..16422489 100644 --- a/crates/macro/ui-tests/invalid-setter.stderr +++ b/crates/macro/ui-tests/invalid-setter.stderr @@ -4,11 +4,5 @@ error: setters must start with `set_`, found: a 10 | fn a(this: &A, b: i32); | ^ -error: setters must start with `set_`, found: x - --> $DIR/invalid-setter.rs:15:46 - | -15 | #[wasm_bindgen(setter, method, js_name = x)] - | ^ - -error: aborting due to 2 previous errors +error: aborting due to previous error diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index 7ed04a2d..055d3fc2 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -4,7 +4,7 @@ use std::ptr; use backend; use backend::util::{ident_ty, leading_colon_path_ty, raw_ident, rust_ident}; use heck::{CamelCase, ShoutySnakeCase, SnakeCase}; -use proc_macro2::Ident; +use proc_macro2::{Ident, Span}; use syn; use weedle; use weedle::attribute::{ExtendedAttributeList, ExtendedAttribute}; @@ -304,6 +304,8 @@ impl<'src> FirstPassRecord<'src> { Some(backend::ast::ImportFunction { function: backend::ast::Function { name: js_name.to_string(), + name_span: Span::call_site(), + renamed_via_js_name: false, arguments, ret: ret.clone(), rust_attrs: vec![], diff --git a/tests/wasm/import_class.rs b/tests/wasm/import_class.rs index 64c97d14..d0ae1f21 100644 --- a/tests/wasm/import_class.rs +++ b/tests/wasm/import_class.rs @@ -53,8 +53,12 @@ extern { fn new() -> RenameProperties; #[wasm_bindgen(getter = a, method)] fn test(this: &RenameProperties) -> i32; + #[wasm_bindgen(getter, method, js_name = a)] + fn test2(this: &RenameProperties) -> i32; #[wasm_bindgen(setter = a, method)] fn another(this: &RenameProperties, a: i32); + #[wasm_bindgen(setter, method, js_name = a)] + fn another2(this: &RenameProperties, a: i32); /// dox pub type AssertImportDenyDocsWorks; @@ -154,6 +158,8 @@ fn rename_setter_getter() { assert_eq!(a.test(), 1); a.another(2); assert_eq!(a.test(), 2); + a.another2(3); + assert_eq!(a.test2(), 3); } /// dox