Skip to content

Commit

Permalink
Add support for renaming a struct field with js_name (#2360)
Browse files Browse the repository at this point in the history
* Add support for renaming a field on the JS side using js_name

* Fix cargo fmt
  • Loading branch information
CraftSpider authored Nov 19, 2020
1 parent 316c5a7 commit eb0ff9b
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 13 deletions.
3 changes: 2 additions & 1 deletion crates/backend/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ pub struct Struct {
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
#[derive(Clone)]
pub struct StructField {
pub name: syn::Member,
pub rust_name: syn::Member,
pub js_name: String,
pub struct_name: Ident,
pub readonly: bool,
pub ty: syn::Type,
Expand Down
6 changes: 3 additions & 3 deletions crates/backend/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ impl ToTokens for ast::Struct {

impl ToTokens for ast::StructField {
fn to_tokens(&self, tokens: &mut TokenStream) {
let name = &self.name;
let rust_name = &self.rust_name;
let struct_name = &self.struct_name;
let ty = &self.ty;
let getter = &self.getter;
Expand All @@ -287,7 +287,7 @@ impl ToTokens for ast::StructField {

let js = js as *mut WasmRefCell<#struct_name>;
assert_not_null(js);
let val = (*js).borrow().#name;
let val = (*js).borrow().#rust_name;
<#ty as IntoWasmAbi>::into_abi(val)
}
})
Expand Down Expand Up @@ -321,7 +321,7 @@ impl ToTokens for ast::StructField {
let js = js as *mut WasmRefCell<#struct_name>;
assert_not_null(js);
let val = <#ty as FromWasmAbi>::from_abi(val);
(*js).borrow_mut().#name = val;
(*js).borrow_mut().#rust_name = val;
}
})
.to_tokens(tokens);
Expand Down
7 changes: 2 additions & 5 deletions crates/backend/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,12 +314,9 @@ 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> {
fn shared_struct_field<'a>(s: &'a ast::StructField, _intern: &'a Interner) -> StructField<'a> {
StructField {
name: match &s.name {
syn::Member::Named(ident) => intern.intern(ident),
syn::Member::Unnamed(index) => intern.intern_str(&index.index.to_string()),
},
name: &s.js_name,
readonly: s.readonly,
comments: s.comments.iter().map(|s| &**s).collect(),
generate_typescript: s.generate_typescript,
Expand Down
14 changes: 10 additions & 4 deletions crates/macro-support/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
syn::Visibility::Public(..) => {}
_ => continue,
}
let (name_str, member) = match &field.ident {
let (js_field_name, member) = match &field.ident {
Some(ident) => (ident.to_string(), syn::Member::Named(ident.clone())),
None => (i.to_string(), syn::Member::Unnamed(i.into())),
};
Expand All @@ -392,12 +392,18 @@ impl<'a> ConvertToAst<BindgenAttrs> for &'a mut syn::ItemStruct {
continue;
}

let js_field_name = match attrs.js_name() {
Some((name, _)) => name.to_string(),
None => js_field_name,
};

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);
let getter = shared::struct_field_get(&js_name, &js_field_name);
let setter = shared::struct_field_set(&js_name, &js_field_name);

fields.push(ast::StructField {
name: member,
rust_name: member,
js_name: js_field_name,
struct_name: self.ident.clone(),
readonly: attrs.readonly().is_some(),
ty: field.ty.clone(),
Expand Down
7 changes: 7 additions & 0 deletions tests/wasm/classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ exports.js_renamed_export = () => {
x.bar(x);
};

exports.js_renamed_field = () => {
const x = new wasm.RenamedField();
assert.ok(x.bar === 3);

x.foo();
}

exports.js_conditional_bindings = () => {
const x = new wasm.ConditionalBindings();
x.free();
Expand Down
22 changes: 22 additions & 0 deletions tests/wasm/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ extern "C" {
fn js_js_rename();
fn js_access_fields();
fn js_renamed_export();
fn js_renamed_field();
fn js_conditional_bindings();

fn js_assert_none(a: Option<OptionClass>);
Expand Down Expand Up @@ -426,6 +427,27 @@ fn renamed_export() {
js_renamed_export();
}

#[wasm_bindgen]
pub struct RenamedField {
#[wasm_bindgen(js_name = bar)]
pub foo: u32,
}

#[wasm_bindgen(js_class = RenamedField)]
impl RenamedField {
#[wasm_bindgen(constructor)]
pub fn new() -> RenamedField {
RenamedField { foo: 3 }
}

pub fn foo(&self) {}
}

#[wasm_bindgen_test]
fn renamed_field() {
js_renamed_field();
}

#[cfg_attr(target_arch = "wasm32", wasm_bindgen)]
pub struct ConditionalBindings {}

Expand Down

0 comments on commit eb0ff9b

Please sign in to comment.