Merge pull request #1467 from RReverser/tuple-structs

Generate bindings for indexed struct properties
This commit is contained in:
Alex Crichton 2019-04-26 09:21:36 -05:00 committed by GitHub
commit cd7aa717c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 80 additions and 52 deletions

View File

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

View File

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

View File

@ -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;
}
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,
});
attrs.check_used()?;
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 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()?;

View File

@ -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
exported_type_by_value(rustThing);
exported_type_by_shared_ref(rustThing);
exported_type_by_exclusive_ref(rustThing);
named_struct_by_value(namedStruct);
named_struct_by_shared_ref(namedStruct);
named_struct_by_exclusive_ref(namedStruct);
let tupleStruct = return_tuple_struct(10, 20);
console.log(tupleStruct instanceof ExportedTupleStruct); // true
console.log(tupleStruct[0], tupleStruct[1]); // 10, 20

View File

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

View File

@ -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 = () => {

View File

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