Get the import-class test working

This commit is contained in:
Alex Crichton 2018-02-06 08:23:51 -08:00
parent d5ff725913
commit d2f2ed8c1a
3 changed files with 180 additions and 136 deletions

View File

@ -483,6 +483,7 @@ impl<'a> Js<'a> {
self.gen_import_shim(&shared::mangled_import_name(None, &import.name), self.gen_import_shim(&shared::mangled_import_name(None, &import.name),
&imported_name, &imported_name,
false,
import) import)
} }
@ -493,10 +494,10 @@ impl<'a> Js<'a> {
", import.name, module)); ", import.name, module));
} }
for import in import.functions.iter() { for f in import.functions.iter() {
self.generate_import_struct_function(&import.function.name, self.generate_import_struct_function(&import.name,
import.method, f.method,
&import.function); &f.function);
} }
} }
@ -513,6 +514,7 @@ impl<'a> Js<'a> {
}; };
self.gen_import_shim(&shared::mangled_import_name(Some(class), &function.name), self.gen_import_shim(&shared::mangled_import_name(Some(class), &function.name),
&delegate, &delegate,
is_method,
function) function)
} }
@ -520,18 +522,25 @@ impl<'a> Js<'a> {
&mut self, &mut self,
shim_name: &str, shim_name: &str,
shim_delegate: &str, shim_delegate: &str,
is_method: bool,
import: &shared::Function, import: &shared::Function,
) { ) {
let mut dst = String::new(); let mut dst = String::new();
dst.push_str(&format!("function {}(", shim_name)); dst.push_str(&format!("function {}(", shim_name));
let mut invocation = String::new(); let mut invocation = String::new();
if is_method {
dst.push_str("ptr");
invocation.push_str("getObject(ptr)");
self.expose_get_object();
}
for (i, arg) in import.arguments.iter().enumerate() { for (i, arg) in import.arguments.iter().enumerate() {
if invocation.len() > 0 { if invocation.len() > 0 {
invocation.push_str(", "); invocation.push_str(", ");
} }
if i > 0 { if i > 0 || is_method {
dst.push_str(", "); dst.push_str(", ");
} }
match *arg { match *arg {

View File

@ -431,11 +431,6 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) { fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
let name = import.name; let name = import.name;
(my_quote! {
pub struct #name {
obj: ::wasm_bindgen::JsObject,
}
}).to_tokens(tokens);
let mut methods = Tokens::new(); let mut methods = Tokens::new();
@ -448,9 +443,28 @@ fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
} }
(my_quote! { (my_quote! {
pub struct #name {
obj: ::wasm_bindgen::JsObject,
}
impl #name { impl #name {
#methods #methods
} }
impl ::wasm_bindgen::convert::WasmBoundary for #name {
type Js = <::wasm_bindgen::JsObject as
::wasm_bindgen::convert::WasmBoundary>::Js;
const DESCRIPTOR: char = <::wasm_bindgen::JsObject as
::wasm_bindgen::convert::WasmBoundary>::DESCRIPTOR;
fn into_js(self) -> Self::Js {
self.obj.into_js()
}
unsafe fn from_js(js: Self::Js) -> Self {
#name { obj: ::wasm_bindgen::JsObject::from_js(js) }
}
}
}).to_tokens(tokens); }).to_tokens(tokens);
} }
@ -467,10 +481,26 @@ fn bindgen_import_function(import: &ast::ImportFunction,
let mut arg_conversions = Vec::new(); let mut arg_conversions = Vec::new();
let ret_ident = syn::Ident::from("_ret"); let ret_ident = syn::Ident::from("_ret");
let names = import.rust_decl.inputs let inputs = import.rust_decl.inputs.iter().collect::<Vec<_>>();
let (is_method, inputs) = match inputs.get(0) {
Some(&&syn::FnArg::Captured(_)) => (false, &inputs[..]),
Some(_) => (true, &inputs[1..]),
None => (false, &inputs[..]),
};
if is_method {
let ptr = syn::Ident::from("ptr");
abi_argument_names.push(ptr);
abi_arguments.push(my_quote! { #ptr: u32 });
arg_conversions.push(my_quote! {
let #ptr = ::wasm_bindgen::convert::ToRefWasmBoundary::to_js_ref(&self.obj);
});
}
let names = inputs
.iter() .iter()
.map(|arg| { .map(|arg| {
match *arg { match **arg {
syn::FnArg::Captured(ref c) => c, syn::FnArg::Captured(ref c) => c,
_ => panic!("arguments cannot be `self` or ignored"), _ => panic!("arguments cannot be `self` or ignored"),
} }

View File

@ -1,125 +1,130 @@
extern crate test_support; extern crate test_support;
// #[test] #[test]
// fn simple() { fn simple() {
// test_support::project() test_support::project()
// .file("src/lib.rs", r#" .file("src/lib.rs", r#"
// #![feature(proc_macro)] #![feature(proc_macro)]
//
// extern crate wasm_bindgen; extern crate wasm_bindgen;
//
// use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
//
// wasm_bindgen! { wasm_bindgen! {
// extern struct Math { extern struct Math {
// fn random() -> f64; fn random() -> f64;
// fn log(a: f64) -> f64; fn log(a: f64) -> f64;
// } }
//
// pub fn get_random() -> f64 { pub fn get_random() -> f64 {
// Math::random() Math::random()
// } }
//
// pub fn do_log(a: f64) -> f64 { pub fn do_log(a: f64) -> f64 {
// Math::log(a) Math::log(a)
// } }
// } }
// "#) "#)
// .file("test.ts", r#" .file("test.ts", r#"
// import * as wasm from "./out"; import * as wasm from "./out";
// import * as assert from "assert"; import * as assert from "assert";
//
// export function test() { export function test() {
// wasm.get_random(); wasm.get_random();
// assert.strictEqual(wasm.do_log(1.0), Math.log(1.0)); assert.strictEqual(wasm.do_log(1.0), Math.log(1.0));
// } }
// "#) "#)
// .test(); .test();
// } }
//
// #[test] #[test]
// fn import_class() { fn import_class() {
// test_support::project() test_support::project()
// .file("src/lib.rs", r#" .file("src/lib.rs", r#"
// #![feature(proc_macro)] #![feature(proc_macro)]
//
// extern crate wasm_bindgen; extern crate wasm_bindgen;
//
// use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
//
// wasm_bindgen! { wasm_bindgen! {
// #[wasm_module = "./test"] #[wasm_module = "./test"]
// extern struct Foo { extern struct Foo {
// fn bar(); fn bar();
// } }
//
// pub fn bar() { pub fn bar() {
// Foo::bar(); Foo::bar();
// } }
// } }
// "#) "#)
// .file("test.ts", r#" .file("test.ts", r#"
// import * as wasm from "./out"; import * as wasm from "./out";
// import * as assert from "assert"; import * as assert from "assert";
//
// let called = false; let called = false;
//
// export class Foo { export class Foo {
// static bar() { static bar() {
// called = true; called = true;
// } }
// } }
//
// export function test() { export function test() {
// wasm.bar(); wasm.bar();
// assert.strictEqual(called, true); assert.strictEqual(called, true);
// } }
// "#) "#)
// .test(); .test();
// } }
//
// #[test] #[test]
// fn construct() { fn construct() {
// test_support::project() test_support::project()
// .file("src/lib.rs", r#" .file("src/lib.rs", r#"
// #![feature(proc_macro)] #![feature(proc_macro)]
//
// extern crate wasm_bindgen; extern crate wasm_bindgen;
//
// use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
//
// wasm_bindgen! { wasm_bindgen! {
// #[wasm_module = "./test"] #[wasm_module = "./test"]
// extern struct Foo { extern struct Foo {
// fn create() -> Foo; fn create() -> Foo;
// fn doit(&self); fn doit(&self);
// } }
//
// pub fn bar() { pub fn bar() {
// let foo = Foo::bar(); Foo::create().doit();
// } }
// } }
// "#) "#)
// .file("test.ts", r#" .file("test.ts", r#"
// import * as wasm from "./out"; import * as wasm from "./out";
// import * as assert from "assert"; import * as assert from "assert";
//
// let called = false; let called = false;
//
// export class Foo { export class Foo {
// static create() { private random_property: string = '';
// return new Foo();
// } static create() {
// const ret = new Foo();
// doit() { ret.random_property = 'this';
// called = true; return ret;
// } }
// }
// doit() {
// export function test() { assert.strictEqual(this.random_property, 'this');
// wasm.bar(); called = true;
// assert.strictEqual(called, true); }
// } }
// "#)
// .test(); export function test() {
// } wasm.bar();
assert.strictEqual(called, true);
}
"#)
.test();
}