mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 18:20:51 +00:00
Merge pull request #952 from alexcrichton/field-export
Fix bindings for classes only referenced through struct fields
This commit is contained in:
commit
70e13705b4
@ -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…
x
Reference in New Issue
Block a user