Skip to content

Commit

Permalink
Merge pull request #1467 from RReverser/tuple-structs
Browse files Browse the repository at this point in the history
Generate bindings for indexed struct properties
  • Loading branch information
alexcrichton authored Apr 26, 2019
2 parents 38fcfc3 + a0a3a14 commit cd7aa71
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 50 deletions.
2 changes: 1 addition & 1 deletion crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ pub struct Struct {
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Clone)]
pub struct StructField {
pub name: Ident,
pub name: syn::Member,
pub struct_name: Ident,
pub readonly: bool,
pub ty: syn::Type,
Expand Down
5 changes: 4 additions & 1 deletion crates/backend/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,10 @@ fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> {

fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) -> StructField<'a> {
StructField {
name: intern.intern(&s.name),
name: match &s.name {
syn::Member::Named(ident) => intern.intern(ident),
syn::Member::Unnamed(index) => intern.intern_str(&index.index.to_string()),
},
readonly: s.readonly,
comments: s.comments.iter().map(|s| &**s).collect(),
}
Expand Down
59 changes: 28 additions & 31 deletions crates/macro-support/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,40 +309,37 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
.js_name()
.map(|s| s.0.to_string())
.unwrap_or(self.ident.to_string());
if let syn::Fields::Named(names) = &mut self.fields {
for field in names.named.iter_mut() {
match field.vis {
syn::Visibility::Public(..) => {}
_ => continue,
}
let name = match &field.ident {
Some(n) => n,
None => continue,
};

let attrs = BindgenAttrs::find(&mut field.attrs)?;
assert_not_variadic(&attrs)?;
if attrs.skip().is_some() {
attrs.check_used()?;
continue;
}
for (i, field) in self.fields.iter_mut().enumerate() {
match field.vis {
syn::Visibility::Public(..) => {}
_ => continue,
}
let (name_str, member) = match &field.ident {
Some(ident) => (ident.to_string(), syn::Member::Named(ident.clone())),
None => (i.to_string(), syn::Member::Unnamed(i.into())),
};

let comments = extract_doc_comments(&field.attrs);
let name_str = name.to_string();
let getter = shared::struct_field_get(&js_name, &name_str);
let setter = shared::struct_field_set(&js_name, &name_str);

fields.push(ast::StructField {
name: name.clone(),
struct_name: self.ident.clone(),
readonly: attrs.readonly().is_some(),
ty: field.ty.clone(),
getter: Ident::new(&getter, Span::call_site()),
setter: Ident::new(&setter, Span::call_site()),
comments,
});
let attrs = BindgenAttrs::find(&mut field.attrs)?;
assert_not_variadic(&attrs)?;
if attrs.skip().is_some() {
attrs.check_used()?;
continue;
}

let comments = extract_doc_comments(&field.attrs);
let getter = shared::struct_field_get(&js_name, &name_str);
let setter = shared::struct_field_set(&js_name, &name_str);

fields.push(ast::StructField {
name: member,
struct_name: self.ident.clone(),
readonly: attrs.readonly().is_some(),
ty: field.ty.clone(),
getter: Ident::new(&getter, Span::call_site()),
setter: Ident::new(&setter, Span::call_site()),
comments,
});
attrs.check_used()?;
}
let comments: Vec<String> = extract_doc_comments(&self.attrs);
attrs.check_used()?;
Expand Down
28 changes: 18 additions & 10 deletions examples/guide-supported-types-examples/exported_types.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import {
ExportedRustType,
exported_type_by_value,
exported_type_by_shared_ref,
exported_type_by_exclusive_ref,
return_exported_type,
ExportedNamedStruct,
named_struct_by_value,
named_struct_by_shared_ref,
named_struct_by_exclusive_ref,
return_named_struct,

ExportedTupleStruct,
return_tuple_struct
} from './guide_supported_types_examples';

let rustThing = return_exported_type();
console.log(rustThing instanceof ExportedRustType); // true
let namedStruct = return_named_struct(42);
console.log(namedStruct instanceof ExportedNamedStruct); // true
console.log(namedStruct.inner); // 42

named_struct_by_value(namedStruct);
named_struct_by_shared_ref(namedStruct);
named_struct_by_exclusive_ref(namedStruct);

exported_type_by_value(rustThing);
exported_type_by_shared_ref(rustThing);
exported_type_by_exclusive_ref(rustThing);
let tupleStruct = return_tuple_struct(10, 20);
console.log(tupleStruct instanceof ExportedTupleStruct); // true
console.log(tupleStruct[0], tupleStruct[1]); // 10, 20
22 changes: 15 additions & 7 deletions examples/guide-supported-types-examples/src/exported_types.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,28 @@
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub struct ExportedRustType {
inner: u32,
pub struct ExportedNamedStruct {
pub inner: u32,
}

#[wasm_bindgen]
pub fn exported_type_by_value(x: ExportedRustType) {}
pub fn named_struct_by_value(x: ExportedNamedStruct) {}

#[wasm_bindgen]
pub fn exported_type_by_shared_ref(x: &ExportedRustType) {}
pub fn named_struct_by_shared_ref(x: &ExportedNamedStruct) {}

#[wasm_bindgen]
pub fn exported_type_by_exclusive_ref(x: &mut ExportedRustType) {}
pub fn named_struct_by_exclusive_ref(x: &mut ExportedNamedStruct) {}

#[wasm_bindgen]
pub fn return_exported_type() -> ExportedRustType {
unimplemented!()
pub fn return_named_struct(inner: u32) -> ExportedNamedStruct {
ExportedNamedStruct { inner }
}

#[wasm_bindgen]
pub struct ExportedTupleStruct(pub u32, pub u32);

#[wasm_bindgen]
pub fn return_tuple_struct(x: u32, y: u32) -> ExportedTupleStruct {
ExportedTupleStruct(x, y)
}
1 change: 1 addition & 0 deletions tests/wasm/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ exports.js_js_rename = () => {

exports.js_access_fields = () => {
assert.ok((new wasm.AccessFieldFoo()).bar instanceof wasm.AccessFieldBar);
assert.ok((new wasm.AccessField0())[0] instanceof wasm.AccessFieldBar);
};

exports.js_renamed_export = () => {
Expand Down
11 changes: 11 additions & 0 deletions tests/wasm/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ pub struct AccessFieldFoo {
pub bar: AccessFieldBar,
}

#[wasm_bindgen]
pub struct AccessField0(pub AccessFieldBar);

#[wasm_bindgen]
#[derive(Copy, Clone)]
pub struct AccessFieldBar {
Expand All @@ -385,6 +388,14 @@ impl AccessFieldFoo {
}
}

#[wasm_bindgen]
impl AccessField0 {
#[wasm_bindgen(constructor)]
pub fn new() -> AccessField0 {
AccessField0(AccessFieldBar { _value: 2 })
}
}

#[wasm_bindgen_test]
fn access_fields() {
js_access_fields();
Expand Down

0 comments on commit cd7aa71

Please sign in to comment.