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),
&imported_name,
false,
import)
}
@ -493,10 +494,10 @@ impl<'a> Js<'a> {
", import.name, module));
}
for import in import.functions.iter() {
self.generate_import_struct_function(&import.function.name,
import.method,
&import.function);
for f in import.functions.iter() {
self.generate_import_struct_function(&import.name,
f.method,
&f.function);
}
}
@ -513,6 +514,7 @@ impl<'a> Js<'a> {
};
self.gen_import_shim(&shared::mangled_import_name(Some(class), &function.name),
&delegate,
is_method,
function)
}
@ -520,18 +522,25 @@ impl<'a> Js<'a> {
&mut self,
shim_name: &str,
shim_delegate: &str,
is_method: bool,
import: &shared::Function,
) {
let mut dst = String::new();
dst.push_str(&format!("function {}(", shim_name));
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() {
if invocation.len() > 0 {
invocation.push_str(", ");
}
if i > 0 {
if i > 0 || is_method {
dst.push_str(", ");
}
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) {
let name = import.name;
(my_quote! {
pub struct #name {
obj: ::wasm_bindgen::JsObject,
}
}).to_tokens(tokens);
let mut methods = Tokens::new();
@ -448,9 +443,28 @@ fn bindgen_imported_struct(import: &ast::ImportStruct, tokens: &mut Tokens) {
}
(my_quote! {
pub struct #name {
obj: ::wasm_bindgen::JsObject,
}
impl #name {
#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);
}
@ -467,10 +481,26 @@ fn bindgen_import_function(import: &ast::ImportFunction,
let mut arg_conversions = Vec::new();
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()
.map(|arg| {
match *arg {
match **arg {
syn::FnArg::Captured(ref c) => c,
_ => panic!("arguments cannot be `self` or ignored"),
}

View File

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