mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-30 22:25:35 +03:00
Fix bindings for classes only referenced through struct fields
The bindings generation for a class would accidentally omit the `__wrap` function if it was only discovered very late in the process that `__wrap` was needed, after we'd already passed the point where we needed to have decided that. This commit moves struct field generation of bindings much earlier in the binding generation process which should ensure everything is all hooked up by the time we generate the classes themselves. Closes #949
This commit is contained in:
parent
35eeb711ad
commit
f6cb73442a
@ -56,13 +56,6 @@ pub struct ExportedClass {
|
||||
typescript: String,
|
||||
has_constructor: bool,
|
||||
wrap_needed: bool,
|
||||
fields: Vec<ClassField>,
|
||||
}
|
||||
|
||||
struct ClassField {
|
||||
comments: Vec<String>,
|
||||
name: String,
|
||||
readonly: bool,
|
||||
}
|
||||
|
||||
pub struct SubContext<'a, 'b: 'a> {
|
||||
@ -590,46 +583,6 @@ impl<'a> Context<'a> {
|
||||
));
|
||||
}
|
||||
|
||||
for field in class.fields.iter() {
|
||||
let wasm_getter = shared::struct_field_get(name, &field.name);
|
||||
let wasm_setter = shared::struct_field_set(name, &field.name);
|
||||
let descriptor = match self.describe(&wasm_getter) {
|
||||
None => continue,
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
let set = {
|
||||
let mut cx = Js2Rust::new(&field.name, self);
|
||||
cx.method(true, false)
|
||||
.argument(&descriptor)?
|
||||
.ret(&Descriptor::Unit)?;
|
||||
ts_dst.push_str(&format!(
|
||||
"{}{}: {}\n",
|
||||
if field.readonly { "readonly " } else { "" },
|
||||
field.name,
|
||||
&cx.js_arguments[0].1
|
||||
));
|
||||
cx.finish("", &format!("wasm.{}", wasm_setter)).0
|
||||
};
|
||||
let (get, _ts, js_doc) = Js2Rust::new(&field.name, self)
|
||||
.method(true, false)
|
||||
.ret(&descriptor)?
|
||||
.finish("", &format!("wasm.{}", wasm_getter));
|
||||
if !dst.ends_with("\n") {
|
||||
dst.push_str("\n");
|
||||
}
|
||||
dst.push_str(&format_doc_comments(&field.comments, Some(js_doc)));
|
||||
dst.push_str("get ");
|
||||
dst.push_str(&field.name);
|
||||
dst.push_str(&get);
|
||||
dst.push_str("\n");
|
||||
if !field.readonly {
|
||||
dst.push_str("set ");
|
||||
dst.push_str(&field.name);
|
||||
dst.push_str(&set);
|
||||
}
|
||||
}
|
||||
|
||||
self.global(&format!(
|
||||
"
|
||||
function free{}(ptr) {{
|
||||
@ -1748,17 +1701,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
self.generate_enum(e);
|
||||
}
|
||||
for s in self.program.structs.iter() {
|
||||
let mut class = self
|
||||
.cx
|
||||
.exported_classes
|
||||
.entry(s.name.clone())
|
||||
.or_insert_with(Default::default);
|
||||
class.comments = format_doc_comments(&s.comments, None);
|
||||
class.fields.extend(s.fields.iter().map(|f| ClassField {
|
||||
name: f.name.clone(),
|
||||
readonly: f.readonly,
|
||||
comments: f.comments.clone(),
|
||||
}));
|
||||
self.generate_struct(s);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -2116,6 +2059,62 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
self.cx.typescript.push_str("}\n");
|
||||
}
|
||||
|
||||
fn generate_struct(&mut self, struct_: &shared::Struct) -> Result<(), Error> {
|
||||
let mut dst = String::new();
|
||||
let mut ts_dst = String::new();
|
||||
for field in struct_.fields.iter() {
|
||||
let wasm_getter = shared::struct_field_get(&struct_.name, &field.name);
|
||||
let wasm_setter = shared::struct_field_set(&struct_.name, &field.name);
|
||||
let descriptor = match self.cx.describe(&wasm_getter) {
|
||||
None => continue,
|
||||
Some(d) => d,
|
||||
};
|
||||
|
||||
let set = {
|
||||
let mut cx = Js2Rust::new(&field.name, self.cx);
|
||||
cx.method(true, false)
|
||||
.argument(&descriptor)?
|
||||
.ret(&Descriptor::Unit)?;
|
||||
ts_dst.push_str(&format!(
|
||||
"{}{}: {}\n",
|
||||
if field.readonly { "readonly " } else { "" },
|
||||
field.name,
|
||||
&cx.js_arguments[0].1
|
||||
));
|
||||
cx.finish("", &format!("wasm.{}", wasm_setter)).0
|
||||
};
|
||||
let (get, _ts, js_doc) = Js2Rust::new(&field.name, self.cx)
|
||||
.method(true, false)
|
||||
.ret(&descriptor)?
|
||||
.finish("", &format!("wasm.{}", wasm_getter));
|
||||
if !dst.ends_with("\n") {
|
||||
dst.push_str("\n");
|
||||
}
|
||||
dst.push_str(&format_doc_comments(&field.comments, Some(js_doc)));
|
||||
dst.push_str("get ");
|
||||
dst.push_str(&field.name);
|
||||
dst.push_str(&get);
|
||||
dst.push_str("\n");
|
||||
if !field.readonly {
|
||||
dst.push_str("set ");
|
||||
dst.push_str(&field.name);
|
||||
dst.push_str(&set);
|
||||
}
|
||||
}
|
||||
|
||||
let class = self
|
||||
.cx
|
||||
.exported_classes
|
||||
.entry(struct_.name.clone())
|
||||
.or_insert_with(Default::default);
|
||||
class.comments = format_doc_comments(&struct_.comments, None);
|
||||
class.contents.push_str(&dst);
|
||||
class.contents.push_str("\n");
|
||||
class.typescript.push_str(&ts_dst);
|
||||
class.typescript.push_str("\n");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn register_vendor_prefix(
|
||||
&mut self,
|
||||
info: &shared::ImportType,
|
||||
|
@ -132,3 +132,7 @@ exports.js_js_rename = () => {
|
||||
(new wasm.JsRename()).bar();
|
||||
wasm.classes_foo();
|
||||
};
|
||||
|
||||
exports.js_access_fields = () => {
|
||||
assert.ok((new wasm.AccessFieldFoo()).bar instanceof wasm.AccessFieldBar);
|
||||
};
|
||||
|
@ -20,6 +20,7 @@ extern "C" {
|
||||
fn js_readonly_fields();
|
||||
fn js_double_consume();
|
||||
fn js_js_rename();
|
||||
fn js_access_fields();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
@ -351,3 +352,30 @@ impl JsRename {
|
||||
|
||||
#[wasm_bindgen(js_name = classes_foo)]
|
||||
pub fn foo() {}
|
||||
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct AccessFieldFoo {
|
||||
pub bar: AccessFieldBar,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct AccessFieldBar {
|
||||
value: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl AccessFieldFoo {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> AccessFieldFoo {
|
||||
AccessFieldFoo {
|
||||
bar: AccessFieldBar { value: 2 },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn access_fields() {
|
||||
js_access_fields();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user