From e87b32fb2257d3e14162e698fb474a179dc0843e Mon Sep 17 00:00:00 2001 From: konstin Date: Sat, 14 Apr 2018 16:41:41 +0200 Subject: [PATCH] Allow arbitratry constructor names --- crates/backend/src/ast.rs | 18 ++++++++++-------- crates/cli-support/src/js.rs | 19 +++++++++++++------ crates/shared/src/lib.rs | 2 +- tests/all/classes.rs | 4 ++-- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 69a8a1f1e..ed759eff6 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -14,7 +14,7 @@ pub struct Export { pub class: Option, pub method: bool, pub mutable: bool, - pub constructor: bool, + pub constructor: Option, pub function: Function, } @@ -123,7 +123,7 @@ impl Program { class: None, method: false, mutable: false, - constructor: false, + constructor: None, function: Function::from(f, opts), }); } @@ -204,12 +204,14 @@ impl Program { } let mut opts = BindgenAttrs::find(&mut method.attrs); - let constructor = opts.constructor(); - if constructor { - if method.sig.ident != syn::Ident::from("new") { - panic!("The constructor must be called 'new' for now") - } + let is_constructor = opts.constructor(); + let constructor = if is_constructor { + Some(method.sig.ident.to_string()) + } else { + None + }; + if is_constructor { let pos = opts.attrs .iter() .enumerate() @@ -566,7 +568,7 @@ impl Export { shared::Export { class: self.class.map(|s| s.as_ref().to_string()), method: self.method, - constructor: self.constructor, + constructor: self.constructor.clone(), function: self.function.shared(), } } diff --git a/crates/cli-support/src/js.rs b/crates/cli-support/src/js.rs index 75f9c4571..a92a91438 100644 --- a/crates/cli-support/src/js.rs +++ b/crates/cli-support/src/js.rs @@ -29,7 +29,7 @@ pub struct Context<'a> { pub struct ExportedClass { pub contents: String, pub typescript: String, - pub constructor: bool, + pub constructor: Option, } pub struct SubContext<'a, 'b: 'a> { @@ -328,14 +328,14 @@ impl<'a> Context<'a> { }} ")); - if exports.constructor { + if let Some(constructor) = exports.constructor { ts_dst.push_str(&format!("constructor(...args: [any] | [ConstructorToken]);\n")); dst.push_str(&format!(" // This invocation of new will call this constructor with a ConstructorToken - let instance = {class}.new(...args); + let instance = {class}.{constructor}(...args); this.ptr = instance.ptr; - ", class = class)); + ", class = class, constructor = constructor)); } else { ts_dst.push_str(&format!("constructor(...args: [ConstructorToken]);\n")); @@ -1342,10 +1342,17 @@ impl<'a, 'b> SubContext<'a, 'b> { class.typescript.push_str("static "); } - class.constructor = self.program.exports + let constructors: Vec = self.program.exports .iter() .filter(|x| x.class == Some(class_name.to_string())) - .any(|x| x.constructor); + .filter_map(|x| x.constructor.clone()) + .collect(); + + class.constructor = match constructors.len() { + 0 => None, + 1 => Some(constructors[0].clone()), + x @ _ => panic!("There must be only one constructor, not {}", x), + }; class.contents.push_str(&export.function.name); class.contents.push_str(&js); diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 6e73fd075..b46f806b7 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -54,7 +54,7 @@ pub struct ImportType { pub struct Export { pub class: Option, pub method: bool, - pub constructor: bool, + pub constructor: Option, pub function: Function, } diff --git a/tests/all/classes.rs b/tests/all/classes.rs index a323f8508..10088f4cd 100644 --- a/tests/all/classes.rs +++ b/tests/all/classes.rs @@ -405,7 +405,7 @@ fn constructors() { #[wasm_bindgen] impl Bar { #[wasm_bindgen(constructor)] - pub fn new(number: u32, number2: u32) -> Bar { + pub fn other_name(number: u32, number2: u32) -> Bar { Bar { number, number2 } } @@ -431,7 +431,7 @@ fn constructors() { assert.strictEqual(bar.get_sum(), 7); bar.free(); - const bar2 = Bar.new(5, 6); + const bar2 = Bar.other_name(5, 6); assert.strictEqual(bar2.get_sum(), 11); bar2.free(); }