Skip to content

Commit cd7aa71

Browse files
authored
Merge pull request #1467 from RReverser/tuple-structs
Generate bindings for indexed struct properties
2 parents 38fcfc3 + a0a3a14 commit cd7aa71

File tree

7 files changed

+78
-50
lines changed

7 files changed

+78
-50
lines changed

crates/backend/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ pub struct Struct {
227227
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
228228
#[derive(Clone)]
229229
pub struct StructField {
230-
pub name: Ident,
230+
pub name: syn::Member,
231231
pub struct_name: Ident,
232232
pub readonly: bool,
233233
pub ty: syn::Type,

crates/backend/src/encode.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,10 @@ fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> {
332332

333333
fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) -> StructField<'a> {
334334
StructField {
335-
name: intern.intern(&s.name),
335+
name: match &s.name {
336+
syn::Member::Named(ident) => intern.intern(ident),
337+
syn::Member::Unnamed(index) => intern.intern_str(&index.index.to_string()),
338+
},
336339
readonly: s.readonly,
337340
comments: s.comments.iter().map(|s| &**s).collect(),
338341
}

crates/macro-support/src/parser.rs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -309,40 +309,37 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
309309
.js_name()
310310
.map(|s| s.0.to_string())
311311
.unwrap_or(self.ident.to_string());
312-
if let syn::Fields::Named(names) = &mut self.fields {
313-
for field in names.named.iter_mut() {
314-
match field.vis {
315-
syn::Visibility::Public(..) => {}
316-
_ => continue,
317-
}
318-
let name = match &field.ident {
319-
Some(n) => n,
320-
None => continue,
321-
};
322-
323-
let attrs = BindgenAttrs::find(&mut field.attrs)?;
324-
assert_not_variadic(&attrs)?;
325-
if attrs.skip().is_some() {
326-
attrs.check_used()?;
327-
continue;
328-
}
312+
for (i, field) in self.fields.iter_mut().enumerate() {
313+
match field.vis {
314+
syn::Visibility::Public(..) => {}
315+
_ => continue,
316+
}
317+
let (name_str, member) = match &field.ident {
318+
Some(ident) => (ident.to_string(), syn::Member::Named(ident.clone())),
319+
None => (i.to_string(), syn::Member::Unnamed(i.into())),
320+
};
329321

330-
let comments = extract_doc_comments(&field.attrs);
331-
let name_str = name.to_string();
332-
let getter = shared::struct_field_get(&js_name, &name_str);
333-
let setter = shared::struct_field_set(&js_name, &name_str);
334-
335-
fields.push(ast::StructField {
336-
name: name.clone(),
337-
struct_name: self.ident.clone(),
338-
readonly: attrs.readonly().is_some(),
339-
ty: field.ty.clone(),
340-
getter: Ident::new(&getter, Span::call_site()),
341-
setter: Ident::new(&setter, Span::call_site()),
342-
comments,
343-
});
322+
let attrs = BindgenAttrs::find(&mut field.attrs)?;
323+
assert_not_variadic(&attrs)?;
324+
if attrs.skip().is_some() {
344325
attrs.check_used()?;
326+
continue;
345327
}
328+
329+
let comments = extract_doc_comments(&field.attrs);
330+
let getter = shared::struct_field_get(&js_name, &name_str);
331+
let setter = shared::struct_field_set(&js_name, &name_str);
332+
333+
fields.push(ast::StructField {
334+
name: member,
335+
struct_name: self.ident.clone(),
336+
readonly: attrs.readonly().is_some(),
337+
ty: field.ty.clone(),
338+
getter: Ident::new(&getter, Span::call_site()),
339+
setter: Ident::new(&setter, Span::call_site()),
340+
comments,
341+
});
342+
attrs.check_used()?;
346343
}
347344
let comments: Vec<String> = extract_doc_comments(&self.attrs);
348345
attrs.check_used()?;
Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import {
2-
ExportedRustType,
3-
exported_type_by_value,
4-
exported_type_by_shared_ref,
5-
exported_type_by_exclusive_ref,
6-
return_exported_type,
2+
ExportedNamedStruct,
3+
named_struct_by_value,
4+
named_struct_by_shared_ref,
5+
named_struct_by_exclusive_ref,
6+
return_named_struct,
7+
8+
ExportedTupleStruct,
9+
return_tuple_struct
710
} from './guide_supported_types_examples';
811

9-
let rustThing = return_exported_type();
10-
console.log(rustThing instanceof ExportedRustType); // true
12+
let namedStruct = return_named_struct(42);
13+
console.log(namedStruct instanceof ExportedNamedStruct); // true
14+
console.log(namedStruct.inner); // 42
15+
16+
named_struct_by_value(namedStruct);
17+
named_struct_by_shared_ref(namedStruct);
18+
named_struct_by_exclusive_ref(namedStruct);
1119

12-
exported_type_by_value(rustThing);
13-
exported_type_by_shared_ref(rustThing);
14-
exported_type_by_exclusive_ref(rustThing);
20+
let tupleStruct = return_tuple_struct(10, 20);
21+
console.log(tupleStruct instanceof ExportedTupleStruct); // true
22+
console.log(tupleStruct[0], tupleStruct[1]); // 10, 20
Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,28 @@
11
use wasm_bindgen::prelude::*;
22

33
#[wasm_bindgen]
4-
pub struct ExportedRustType {
5-
inner: u32,
4+
pub struct ExportedNamedStruct {
5+
pub inner: u32,
66
}
77

88
#[wasm_bindgen]
9-
pub fn exported_type_by_value(x: ExportedRustType) {}
9+
pub fn named_struct_by_value(x: ExportedNamedStruct) {}
1010

1111
#[wasm_bindgen]
12-
pub fn exported_type_by_shared_ref(x: &ExportedRustType) {}
12+
pub fn named_struct_by_shared_ref(x: &ExportedNamedStruct) {}
1313

1414
#[wasm_bindgen]
15-
pub fn exported_type_by_exclusive_ref(x: &mut ExportedRustType) {}
15+
pub fn named_struct_by_exclusive_ref(x: &mut ExportedNamedStruct) {}
1616

1717
#[wasm_bindgen]
18-
pub fn return_exported_type() -> ExportedRustType {
19-
unimplemented!()
18+
pub fn return_named_struct(inner: u32) -> ExportedNamedStruct {
19+
ExportedNamedStruct { inner }
20+
}
21+
22+
#[wasm_bindgen]
23+
pub struct ExportedTupleStruct(pub u32, pub u32);
24+
25+
#[wasm_bindgen]
26+
pub fn return_tuple_struct(x: u32, y: u32) -> ExportedTupleStruct {
27+
ExportedTupleStruct(x, y)
2028
}

tests/wasm/classes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ exports.js_js_rename = () => {
137137

138138
exports.js_access_fields = () => {
139139
assert.ok((new wasm.AccessFieldFoo()).bar instanceof wasm.AccessFieldBar);
140+
assert.ok((new wasm.AccessField0())[0] instanceof wasm.AccessFieldBar);
140141
};
141142

142143
exports.js_renamed_export = () => {

tests/wasm/classes.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,9 @@ pub struct AccessFieldFoo {
369369
pub bar: AccessFieldBar,
370370
}
371371

372+
#[wasm_bindgen]
373+
pub struct AccessField0(pub AccessFieldBar);
374+
372375
#[wasm_bindgen]
373376
#[derive(Copy, Clone)]
374377
pub struct AccessFieldBar {
@@ -385,6 +388,14 @@ impl AccessFieldFoo {
385388
}
386389
}
387390

391+
#[wasm_bindgen]
392+
impl AccessField0 {
393+
#[wasm_bindgen(constructor)]
394+
pub fn new() -> AccessField0 {
395+
AccessField0(AccessFieldBar { _value: 2 })
396+
}
397+
}
398+
388399
#[wasm_bindgen_test]
389400
fn access_fields() {
390401
js_access_fields();

0 commit comments

Comments
 (0)