Merge pull request #952 from alexcrichton/field-export

Fix bindings for classes only referenced through struct fields
This commit is contained in:
Alex Crichton 2018-10-10 11:55:24 -07:00 committed by GitHub
commit 70e13705b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 89 additions and 58 deletions

View File

@ -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,

View File

@ -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);
};

View File

@ -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();
}