Skip to content

Commit c6f7d3d

Browse files
committed
Fix methods returning Self
Rewrite any instance of `Self` to the name of the class Closes #137
1 parent 542b3a2 commit c6f7d3d

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

crates/backend/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ Backend code generation of the wasm-bindgen tool
1414
quote = '0.5'
1515
proc-macro2 = { version = "0.3", features = ["nightly"] }
1616
wasm-bindgen-shared = { path = "../shared", version = "=0.2.4" }
17-
syn = { version = '0.13', features = ['full', 'visit'] }
17+
syn = { version = '0.13', features = ['full', 'visit-mut'] }
1818
serde_json = "1.0"

crates/backend/src/ast.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -179,12 +179,13 @@ impl Program {
179179
},
180180
_ => panic!("unsupported self type in impl"),
181181
};
182-
for mut item in item.items.iter_mut() {
183-
self.push_impl_item(name, &mut item);
182+
for item in item.items.iter_mut() {
183+
self.push_impl_item(name, item);
184184
}
185185
}
186186

187187
fn push_impl_item(&mut self, class: syn::Ident, item: &mut syn::ImplItem) {
188+
replace_self(class, item);
188189
let method = match item {
189190
syn::ImplItem::Const(_) => panic!("const definitions aren't supported"),
190191
syn::ImplItem::Type(_) => panic!("type definitions in impls aren't supported"),
@@ -458,7 +459,7 @@ impl Function {
458459

459460
pub fn from_decl(
460461
name: syn::Ident,
461-
decl: Box<syn::FnDecl>,
462+
mut decl: Box<syn::FnDecl>,
462463
attrs: Vec<syn::Attribute>,
463464
opts: BindgenAttrs,
464465
vis: syn::Visibility,
@@ -471,7 +472,7 @@ impl Function {
471472
panic!("can't bindgen functions with lifetime or type parameters")
472473
}
473474

474-
assert_no_lifetimes(&decl);
475+
assert_no_lifetimes(&mut decl);
475476

476477
let mut mutable = None;
477478
let arguments = decl.inputs
@@ -928,15 +929,29 @@ fn term<'a>(cursor: syn::buffer::Cursor<'a>, name: &str) -> syn::synom::PResult<
928929
syn::parse_error()
929930
}
930931

931-
fn assert_no_lifetimes(decl: &syn::FnDecl) {
932+
fn assert_no_lifetimes(decl: &mut syn::FnDecl) {
932933
struct Walk;
933934

934-
impl<'ast> syn::visit::Visit<'ast> for Walk {
935-
fn visit_lifetime(&mut self, _i: &'ast syn::Lifetime) {
935+
impl<'ast> syn::visit_mut::VisitMut for Walk {
936+
fn visit_lifetime_mut(&mut self, _i: &mut syn::Lifetime) {
936937
panic!("it is currently not sound to use lifetimes in function \
937938
signatures");
938939
}
939940
}
940941

941-
syn::visit::Visit::visit_fn_decl(&mut Walk, decl);
942+
syn::visit_mut::VisitMut::visit_fn_decl_mut(&mut Walk, decl);
943+
}
944+
945+
fn replace_self(name: syn::Ident, item: &mut syn::ImplItem) {
946+
struct Walk(syn::Ident);
947+
948+
impl syn::visit_mut::VisitMut for Walk {
949+
fn visit_ident_mut(&mut self, i: &mut syn::Ident) {
950+
if i.as_ref() == "Self" {
951+
*i = self.0;
952+
}
953+
}
954+
}
955+
956+
syn::visit_mut::VisitMut::visit_impl_item_mut(&mut Walk(name), item);
942957
}

tests/all/classes.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,3 +526,35 @@ fn public_fields() {
526526
"#)
527527
.test();
528528
}
529+
530+
#[test]
531+
fn using_self() {
532+
project()
533+
.debug(false)
534+
.file("src/lib.rs", r#"
535+
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
536+
537+
extern crate wasm_bindgen;
538+
539+
use wasm_bindgen::prelude::*;
540+
541+
#[wasm_bindgen]
542+
pub struct Foo {
543+
}
544+
545+
#[wasm_bindgen]
546+
impl Foo {
547+
pub fn new() -> Self {
548+
Foo {}
549+
}
550+
}
551+
"#)
552+
.file("test.ts", r#"
553+
import { Foo } from "./out";
554+
555+
export function test() {
556+
Foo.new().free();
557+
}
558+
"#)
559+
.test();
560+
}

0 commit comments

Comments
 (0)