From 073cf7455be8e18caebd93ad40f814d7def7496e Mon Sep 17 00:00:00 2001 From: gaurikholkar Date: Wed, 27 Jun 2018 10:44:43 +0530 Subject: [PATCH 01/48] binding for Math.floor --- src/js.rs | 7 +++++++ tests/all/js_globals/Math.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/js.rs b/src/js.rs index 6ece49ac..c96f0ed1 100644 --- a/src/js.rs +++ b/src/js.rs @@ -360,6 +360,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32 #[wasm_bindgen(static_method_of = Math)] pub fn clz32(x: i32) -> Number; + + /// The Math.floor() function returns the largest integer less than or + /// equal to a given number. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor + #[wasm_bindgen(static_method_of = Math)] + pub fn floor(x: f32) -> Number; } // Number. diff --git a/tests/all/js_globals/Math.rs b/tests/all/js_globals/Math.rs index 1fbf9502..df3038f4 100644 --- a/tests/all/js_globals/Math.rs +++ b/tests/all/js_globals/Math.rs @@ -292,3 +292,30 @@ fn clz32() { "#) .test() } + +#[test] +fn floor() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn floor(x: f32) -> js::Number { + js::Math::floor(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.floor(5.95), 5); + assert.equal(wasm.floor(-5.05), -6); + } + "#) + .test() +} From c99c0f8483c652b2b3576dfd0fd572e90cdacd2b Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 27 Jun 2018 08:33:37 +0200 Subject: [PATCH 02/48] test(js) Fix file permissions, and update a comment. --- src/js.rs | 7 ++++--- tests/all/js_globals/Array.rs | 0 tests/all/js_globals/Object.rs | 0 3 files changed, 4 insertions(+), 3 deletions(-) mode change 100755 => 100644 tests/all/js_globals/Array.rs mode change 100755 => 100644 tests/all/js_globals/Object.rs diff --git a/src/js.rs b/src/js.rs index 6ece49ac..6ba627cf 100644 --- a/src/js.rs +++ b/src/js.rs @@ -35,9 +35,10 @@ if_std! { // * If a function or method can throw an exception, make it catchable by adding // `#[wasm_bindgen(catch)]`. // -// * Add a new `#[test]` to the `tests/all/js_globals.rs` file. If the imported -// function or method can throw an exception, make sure to also add test -// coverage for that case. +// * Add a new `#[test]` into the appropriate file in the +// `tests/all/js_globals/` directory. If the imported function or +// method can throw an exception, make sure to also add test coverage +// for that case. #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/Array.rs b/tests/all/js_globals/Array.rs old mode 100755 new mode 100644 diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs old mode 100755 new mode 100644 From 91bc7a199c33fe313ebbb4c2453234ea3a73f664 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 27 Jun 2018 09:07:47 +0200 Subject: [PATCH 03/48] feat(js) Implement `Boolean` bindings. Cf https://github.com/rustwasm/wasm-bindgen/issues/275. --- src/js.rs | 18 +++++++++++ tests/all/js_globals/Boolean.rs | 55 +++++++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 74 insertions(+) create mode 100644 tests/all/js_globals/Boolean.rs diff --git a/src/js.rs b/src/js.rs index 6ece49ac..6b4bd2fa 100644 --- a/src/js.rs +++ b/src/js.rs @@ -243,6 +243,24 @@ extern { pub fn entries(this: &Array) -> ArrayIterator; } +// Boolean +#[wasm_bindgen] +extern { + pub type Boolean; + + /// The `Boolean()` constructor creates an object wrapper for a boolean value. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean + #[wasm_bindgen(constructor)] + pub fn new(value: JsValue) -> Boolean; + + /// The `valueOf()` method returns the primitive value of a `Boolean` object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean/valueOf + #[wasm_bindgen(method, js_name = valueOf)] + pub fn value_of(this: &Boolean) -> bool; +} + // Function #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/Boolean.rs b/tests/all/js_globals/Boolean.rs new file mode 100644 index 00000000..323029f4 --- /dev/null +++ b/tests/all/js_globals/Boolean.rs @@ -0,0 +1,55 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn new_undefined() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_boolean() -> js::Boolean { + js::Boolean::new(JsValue::undefined()) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_boolean().valueOf(), false); + } + "#) + .test() +} + +#[test] +fn new_truely() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_boolean() -> js::Boolean { + js::Boolean::new(JsValue::from("foo")) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.new_boolean().valueOf(), true); + } + "#) + .test() +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 453c407c..bd95f579 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -4,6 +4,7 @@ use super::project; mod Array; mod ArrayIterator; +mod Boolean; mod Date; mod Function; mod JsString; From a0dda505d954a29c07b3f596a2024f5d0819aebb Mon Sep 17 00:00:00 2001 From: Dimitrii Nemkov Date: Wed, 27 Jun 2018 13:15:47 +0500 Subject: [PATCH 04/48] Added WeakSet constructor --- src/js.rs | 11 +++++++++++ tests/all/js_globals/WeakSet.rs | 29 +++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 41 insertions(+) create mode 100644 tests/all/js_globals/WeakSet.rs diff --git a/src/js.rs b/src/js.rs index 6ece49ac..934000f4 100644 --- a/src/js.rs +++ b/src/js.rs @@ -619,6 +619,17 @@ extern { pub fn delete(this: &WeakMap, key: Object) -> bool; } +#[wasm_bindgen] +extern { + pub type WeakSet; + + /// The WeakSet object lets you store weakly held objects in a collection. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet + #[wasm_bindgen(constructor)] + pub fn new() -> WeakSet; +} + // JsString #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/WeakSet.rs b/tests/all/js_globals/WeakSet.rs new file mode 100644 index 00000000..46f829fd --- /dev/null +++ b/tests/all/js_globals/WeakSet.rs @@ -0,0 +1,29 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn new() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_weak_set() -> js::WeakSet { + js::WeakSet::new() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(typeof wasm.new_weak_set(), "object"); + } + "#) + .test() +} \ No newline at end of file diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 453c407c..5f1ea8fe 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -9,6 +9,7 @@ mod Function; mod JsString; mod Math; mod WeakMap; +mod WeakSet; mod Number; mod Object; mod TypedArray; From 846e5aaacccf73161de6b88dfacbce0ef022f074 Mon Sep 17 00:00:00 2001 From: Dimitrii Nemkov Date: Wed, 27 Jun 2018 13:26:53 +0500 Subject: [PATCH 05/48] Added WeakSet has method --- src/js.rs | 6 ++++++ tests/all/js_globals/WeakSet.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/js.rs b/src/js.rs index 934000f4..b35ef08a 100644 --- a/src/js.rs +++ b/src/js.rs @@ -628,6 +628,12 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet #[wasm_bindgen(constructor)] pub fn new() -> WeakSet; + + /// The has() method returns a boolean indicating whether an object exists in a WeakSet or not. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has + #[wasm_bindgen(method)] + pub fn has(this: &WeakSet, value: Object) -> bool; } // JsString diff --git a/tests/all/js_globals/WeakSet.rs b/tests/all/js_globals/WeakSet.rs index 46f829fd..40b4be5a 100644 --- a/tests/all/js_globals/WeakSet.rs +++ b/tests/all/js_globals/WeakSet.rs @@ -26,4 +26,36 @@ fn new() { } "#) .test() +} + +#[test] +fn has() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn has_value(this: &js::WeakSet, value: js::Object) -> bool { + this.has(value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new WeakSet(); + let value = {some: "value"}; + set.add(value); + assert.equal(wasm.has_value(set, value), true); + + let nonex = {nonexistent: "value"}; + assert.equal(wasm.has_value(set, nonex), false); + } + "#) + .test() } \ No newline at end of file From 6b798a350841cf200811f2ebcb531ce158a707e4 Mon Sep 17 00:00:00 2001 From: Dimitrii Nemkov Date: Wed, 27 Jun 2018 13:38:33 +0500 Subject: [PATCH 06/48] Added WeakSet add method --- src/js.rs | 6 ++++++ tests/all/js_globals/WeakSet.rs | 35 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/js.rs b/src/js.rs index b35ef08a..c39d3716 100644 --- a/src/js.rs +++ b/src/js.rs @@ -634,6 +634,12 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has #[wasm_bindgen(method)] pub fn has(this: &WeakSet, value: Object) -> bool; + + /// The add() method appends a new object to the end of a WeakSet object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add + #[wasm_bindgen(method)] + pub fn add(this: &WeakSet, value: Object) -> WeakSet; } // JsString diff --git a/tests/all/js_globals/WeakSet.rs b/tests/all/js_globals/WeakSet.rs index 40b4be5a..2788acc3 100644 --- a/tests/all/js_globals/WeakSet.rs +++ b/tests/all/js_globals/WeakSet.rs @@ -58,4 +58,39 @@ fn has() { } "#) .test() +} + +#[test] +fn add() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn add_value(this: &js::WeakSet, value: js::Object) -> js::WeakSet { + this.add(value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new WeakSet(); + let value = {some: "value"}; + wasm.add_value(set, value); + assert.equal(set.has(value), true); + + assert.throws(() => { wasm.add_value(set, 1) }, TypeError); + assert.throws(() => { wasm.add_value(set, true) }, TypeError); + assert.throws(() => { wasm.add_value(set, "fail") }, TypeError); + assert.throws(() => { wasm.add_value(set, null) }, TypeError); + assert.throws(() => { wasm.add_value(set, undefined) }, TypeError); + } + "#) + .test() } \ No newline at end of file From 761a9272caaa29fa5ea0047264f7032fa5226ea9 Mon Sep 17 00:00:00 2001 From: Dimitrii Nemkov Date: Wed, 27 Jun 2018 13:44:01 +0500 Subject: [PATCH 07/48] Added WeakSet delete method --- src/js.rs | 6 ++++++ tests/all/js_globals/WeakSet.rs | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/js.rs b/src/js.rs index c39d3716..2c8ce61e 100644 --- a/src/js.rs +++ b/src/js.rs @@ -640,6 +640,12 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add #[wasm_bindgen(method)] pub fn add(this: &WeakSet, value: Object) -> WeakSet; + + /// The delete() method removes the specified element from a WeakSet object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/delete + #[wasm_bindgen(method)] + pub fn delete(this: &WeakSet, value: Object) -> bool; } // JsString diff --git a/tests/all/js_globals/WeakSet.rs b/tests/all/js_globals/WeakSet.rs index 2788acc3..5201df1a 100644 --- a/tests/all/js_globals/WeakSet.rs +++ b/tests/all/js_globals/WeakSet.rs @@ -93,4 +93,41 @@ fn add() { } "#) .test() +} + +#[test] +fn delete() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn delete_value(this: &js::WeakSet, value: js::Object) -> bool { + this.delete(value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new WeakSet(); + let value = {some: "value"}; + set.add(value); + assert.equal(wasm.delete_value(set, value), true); + assert.equal(set.has(value), false); + assert.equal(wasm.delete_value(set, value), false); + + assert.equal(wasm.delete_value(set, 1), false); + assert.equal(wasm.delete_value(set, true), false); + assert.equal(wasm.delete_value(set, "false"), false); + assert.equal(wasm.delete_value(set, null), false); + assert.equal(wasm.delete_value(set, undefined), false); + } + "#) + .test() } \ No newline at end of file From 72be16c8ff9d60f0d69c4f8b8ef0b04b162d2959 Mon Sep 17 00:00:00 2001 From: Dimitrii Nemkov Date: Wed, 27 Jun 2018 13:48:32 +0500 Subject: [PATCH 08/48] Forgotten comment --- src/js.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/js.rs b/src/js.rs index 2c8ce61e..5a3a13be 100644 --- a/src/js.rs +++ b/src/js.rs @@ -619,6 +619,7 @@ extern { pub fn delete(this: &WeakMap, key: Object) -> bool; } +// WeakSet #[wasm_bindgen] extern { pub type WeakSet; From dacf406dbdad92a56e68f658af73a5c9b6cad15f Mon Sep 17 00:00:00 2001 From: belfz Date: Wed, 27 Jun 2018 13:45:47 +0200 Subject: [PATCH 09/48] implements Array.prototype.every() --- src/js.rs | 7 +++++++ tests/all/js_globals/Array.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/js.rs b/src/js.rs index 6ece49ac..49c5e565 100644 --- a/src/js.rs +++ b/src/js.rs @@ -103,6 +103,13 @@ extern { #[wasm_bindgen(method)] pub fn concat(this: &Array, array: &Array) -> Array; + /// The every() method tests whether all elements in the array pass the test + /// implemented by the provided function. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every + #[wasm_bindgen(method)] + pub fn every(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> bool; + /// The fill() method fills all the elements of an array from a start index /// to an end index with a static value. The end index is not included. /// diff --git a/tests/all/js_globals/Array.rs b/tests/all/js_globals/Array.rs index c2569cfe..8e8173de 100755 --- a/tests/all/js_globals/Array.rs +++ b/tests/all/js_globals/Array.rs @@ -589,3 +589,35 @@ fn length() { "#) .test() } + +#[test] +fn every() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn array_every_number_is_even(array: &js::Array) -> bool { + array.every(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const arrayEven = [2, 4, 6, 8]; + const arrayOdd = [1, 3, 5, 7]; + const arrayMixed = [2, 3, 4, 5]; + + assert(wasm.array_every_number_is_even(arrayEven)); + assert(!wasm.array_every_number_is_even(arrayOdd)); + assert(!wasm.array_every_number_is_even(arrayMixed)); + } + "#) + .test() +} From d3201a11af7ac6d2430c502245e69d11cbac7b18 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 27 Jun 2018 14:58:53 -0700 Subject: [PATCH 10/48] guide: Add note about `static_method_of` attribute to design doc --- guide/src/design.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guide/src/design.md b/guide/src/design.md index 62026dc5..4ebe657a 100644 --- a/guide/src/design.md +++ b/guide/src/design.md @@ -706,6 +706,9 @@ let's go through one-by-one: this function must be a bare type, like `Bar`. * `#[wasm_bindgen(js_namespace = Bar)]` - this attribute indicates that the function declaration is namespaced through the `Bar` class in JS. +* `#[wasm_bindgen(static_method_of = SomeJsClass)]` - this attribute is similar + to `js_namespace`, but instead of producing a free function, produces a static + method of `SomeJsClass`. * `#[wasm_bindgen(method)]` - and finally, this attribute indicates that a method call is going to happen. The first argument must be a JS struct, like `Bar`, and the call in JS looks like `Bar.prototype.set.call(...)`. From a29e71ec49f470c35ad76c6e3e8ae388330135eb Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Wed, 27 Jun 2018 22:38:16 -0700 Subject: [PATCH 11/48] ci: check formatting --- .travis.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.travis.yml b/.travis.yml index 23bf094c..3892b09f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,11 @@ matrix: install: true script: cargo build --manifest-path crates/cli/Cargo.toml + # check formatting + - rust: nightly + before_install: rustup component add rustfmt-preview --toolchain nightly + script: cargo fmt -- --check + # Tests pass on nightly - rust: nightly before_install: @@ -41,6 +46,7 @@ matrix: # Check JS output from all tests against eslint - ./node_modules/.bin/eslint ./target/generated-tests/*/out*.js env: RUST_BACKTRACE=1 + # WebIDL tests pass on nightly - rust: nightly before_install: rustup component add rustfmt-preview --toolchain nightly From 9127a0419fbc174b802bd9c7c021a98359f905c3 Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Wed, 27 Jun 2018 22:42:34 -0700 Subject: [PATCH 12/48] rustfmt all the things --- crates/backend/src/ast.rs | 5 +- crates/cli-support/src/descriptor.rs | 45 +- crates/cli-support/src/js/js2rust.rs | 176 +++--- crates/cli-support/src/js/mod.rs | 755 ++++++++++++++++---------- crates/cli-support/src/js/rust2js.rs | 160 +++--- crates/cli-support/src/lib.rs | 62 ++- crates/cli-support/src/wasm2es6js.rs | 203 ++++--- crates/cli/src/bin/wasm-bindgen.rs | 2 +- crates/cli/src/bin/wasm2es6js.rs | 8 +- crates/macro/src/lib.rs | 4 +- crates/typescript/src/definitions.rs | 1 - crates/typescript/src/lib.rs | 3 +- crates/typescript/src/parser.rs | 58 +- examples/asm.js/src/lib.rs | 2 +- examples/char/src/lib.rs | 11 +- examples/closures/src/lib.rs | 24 +- examples/comments/src/lib.rs | 3 +- examples/console_log/src/lib.rs | 2 +- examples/dom/src/lib.rs | 2 +- examples/hello_world/src/lib.rs | 2 +- examples/import_js/src/lib.rs | 4 +- examples/math/src/lib.rs | 2 +- examples/no_modules/src/lib.rs | 2 +- examples/performance/src/lib.rs | 4 +- examples/smorgasboard/src/lib.rs | 12 +- examples/wasm-in-wasm/src/lib.rs | 2 +- src/convert.rs | 36 +- src/describe.rs | 16 +- src/js.rs | 81 ++- src/lib.rs | 76 +-- tests/all/api.rs | 29 +- tests/all/char.rs | 14 +- tests/all/classes.rs | 175 ++++-- tests/all/closures.rs | 141 +++-- tests/all/comments.rs | 39 +- tests/all/enums.rs | 28 +- tests/all/import_class.rs | 140 +++-- tests/all/imports.rs | 168 ++++-- tests/all/js_globals/Array.rs | 254 ++++++--- tests/all/js_globals/ArrayIterator.rs | 28 +- tests/all/js_globals/Boolean.rs | 28 +- tests/all/js_globals/Date.rs | 126 +++-- tests/all/js_globals/Function.rs | 56 +- tests/all/js_globals/JsString.rs | 156 ++++-- tests/all/js_globals/Math.rs | 169 ++++-- tests/all/js_globals/Number.rs | 71 ++- tests/all/js_globals/Object.rs | 112 ++-- tests/all/js_globals/TypedArray.rs | 28 +- tests/all/js_globals/WeakMap.rs | 73 ++- tests/all/js_globals/WeakSet.rs | 58 +- tests/all/js_globals/mod.rs | 25 +- tests/all/jsobjects.rs | 98 +++- tests/all/main.rs | 22 +- tests/all/math.rs | 15 +- tests/all/node.rs | 14 +- tests/all/non_debug.rs | 14 +- tests/all/non_wasm.rs | 39 +- tests/all/simple.rs | 112 ++-- tests/all/slice.rs | 85 ++- tests/all/structural.rs | 16 +- tests/all/u64.rs | 14 +- tests/all/validate_prt.rs | 14 +- 62 files changed, 2724 insertions(+), 1400 deletions(-) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index f62a3ebd..158e8210 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -405,7 +405,10 @@ impl Program { }; let class_name = extract_path_ident(class_name) .expect("first argument of method must be a bare type"); - let class_name = wasm.opts.js_class().map(Into::into) + let class_name = wasm + .opts + .js_class() + .map(Into::into) .unwrap_or_else(|| class_name.to_string()); ImportFunctionKind::Method { diff --git a/crates/cli-support/src/descriptor.rs b/crates/cli-support/src/descriptor.rs index d43324d3..a1f6938f 100644 --- a/crates/cli-support/src/descriptor.rs +++ b/crates/cli-support/src/descriptor.rs @@ -138,15 +138,15 @@ impl Descriptor { pub fn is_number(&self) -> bool { match *self { - Descriptor::I8 | - Descriptor::U8 | - Descriptor::I16 | - Descriptor::U16 | - Descriptor::I32 | - Descriptor::U32 | - Descriptor::F32 | - Descriptor::F64 | - Descriptor::Enum => true, + Descriptor::I8 + | Descriptor::U8 + | Descriptor::I16 + | Descriptor::U16 + | Descriptor::I32 + | Descriptor::U32 + | Descriptor::F32 + | Descriptor::F64 + | Descriptor::Enum => true, _ => return false, } } @@ -191,19 +191,15 @@ impl Descriptor { let inner = match *self { Descriptor::String => return Some(VectorKind::String), Descriptor::Vector(ref d) => &**d, - Descriptor::Ref(ref d) => { - match **d { - Descriptor::Slice(ref d) => &**d, - Descriptor::String => return Some(VectorKind::String), - _ => return None, - } - } - Descriptor::RefMut(ref d) => { - match **d { - Descriptor::Slice(ref d) => &**d, - _ => return None, - } - } + Descriptor::Ref(ref d) => match **d { + Descriptor::Slice(ref d) => &**d, + Descriptor::String => return Some(VectorKind::String), + _ => return None, + }, + Descriptor::RefMut(ref d) => match **d { + Descriptor::Slice(ref d) => &**d, + _ => return None, + }, _ => return None, }; match *inner { @@ -218,7 +214,7 @@ impl Descriptor { Descriptor::F32 => Some(VectorKind::F32), Descriptor::F64 => Some(VectorKind::F64), Descriptor::Anyref => Some(VectorKind::Anyref), - _ => None + _ => None, } } @@ -248,8 +244,7 @@ impl Descriptor { pub fn is_by_ref(&self) -> bool { match *self { - Descriptor::Ref(_) | - Descriptor::RefMut(_) => true, + Descriptor::Ref(_) | Descriptor::RefMut(_) => true, _ => false, } } diff --git a/crates/cli-support/src/js/js2rust.rs b/crates/cli-support/src/js/js2rust.rs index 00c24fdf..0a4eeb7c 100644 --- a/crates/cli-support/src/js/js2rust.rs +++ b/crates/cli-support/src/js/js2rust.rs @@ -68,9 +68,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> { /// passed should be `this.ptr`. pub fn method(&mut self, method: bool) -> &mut Self { if method { - self.prelude("if (this.ptr === 0) { + self.prelude( + "if (this.ptr === 0) { throw new Error('Attempt to use a moved value'); - }"); + }", + ); self.rust_arguments.insert(0, "this.ptr".to_string()); } self @@ -111,30 +113,46 @@ impl<'a, 'b> Js2Rust<'a, 'b> { let name = self.abi_arg(); if let Some(kind) = arg.vector_kind() { - self.js_arguments.push((name.clone(), kind.js_ty().to_string())); + self.js_arguments + .push((name.clone(), kind.js_ty().to_string())); let func = self.cx.pass_to_wasm_function(kind)?; - self.prelude(&format!("\ - const [ptr{i}, len{i}] = {func}({arg});\n\ - ", i = i, func = func, arg = name)); + self.prelude(&format!( + "\ + const [ptr{i}, len{i}] = {func}({arg});\n\ + ", + i = i, + func = func, + arg = name + )); if arg.is_by_ref() { if arg.is_mut_ref() { let get = self.cx.memview_function(kind); - self.finally(&format!("\ - {arg}.set({get}().subarray(\ - ptr{i} / {size}, \ - ptr{i} / {size} + len{i}\ - ));\n\ - ", i = i, arg = name, get = get, size = kind.size())); + self.finally(&format!( + "\ + {arg}.set({get}().subarray(\ + ptr{i} / {size}, \ + ptr{i} / {size} + len{i}\ + ));\n\ + ", + i = i, + arg = name, + get = get, + size = kind.size() + )); } - self.finally(&format!("\ - wasm.__wbindgen_free(ptr{i}, len{i} * {size});\n\ - ", i = i, size = kind.size())); + self.finally(&format!( + "\ + wasm.__wbindgen_free(ptr{i}, len{i} * {size});\n\ + ", + i = i, + size = kind.size() + )); self.cx.require_internal_export("__wbindgen_free")?; } self.rust_arguments.push(format!("ptr{}", i)); self.rust_arguments.push(format!("len{}", i)); - return Ok(self) + return Ok(self); } if let Some(s) = arg.rust_struct() { @@ -142,24 +160,32 @@ impl<'a, 'b> Js2Rust<'a, 'b> { if self.cx.config.debug { self.cx.expose_assert_class(); - self.prelude(&format!("\ - _assertClass({arg}, {struct_});\n\ - ", arg = name, struct_ = s)); + self.prelude(&format!( + "\ + _assertClass({arg}, {struct_});\n\ + ", + arg = name, + struct_ = s + )); } if arg.is_by_ref() { self.rust_arguments.push(format!("{}.ptr", name)); } else { - self.prelude(&format!("\ + self.prelude(&format!( + "\ const ptr{i} = {arg}.ptr;\n\ if (ptr{i} === 0) {{ throw new Error('Attempt to use a moved value'); }} {arg}.ptr = 0;\n\ - ", i = i, arg = name)); + ", + i = i, + arg = name + )); self.rust_arguments.push(format!("ptr{}", i)); } - return Ok(self) + return Ok(self); } if arg.is_number() { @@ -171,7 +197,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> { } self.rust_arguments.push(name); - return Ok(self) + return Ok(self); } if let Some(signed) = arg.get_64bit() { @@ -183,51 +209,55 @@ impl<'a, 'b> Js2Rust<'a, 'b> { self.cx.expose_uint32_memory(); self.cx.expose_global_argument_ptr()?; self.js_arguments.push((name.clone(), "BigInt".to_string())); - self.prelude(&format!("\ - {f}[0] = {name};\n\ - const lo{i} = u32CvtShim[0];\n\ - const hi{i} = u32CvtShim[1];\n\ - ", + self.prelude(&format!( + "\ + {f}[0] = {name};\n\ + const lo{i} = u32CvtShim[0];\n\ + const hi{i} = u32CvtShim[1];\n\ + ", i = i, f = f, name = name, )); self.rust_arguments.push(format!("lo{}", i)); self.rust_arguments.push(format!("hi{}", i)); - return Ok(self) + return Ok(self); } if arg.is_ref_anyref() { self.js_arguments.push((name.clone(), "any".to_string())); self.cx.expose_borrowed_objects(); self.finally("stack.pop();"); - self.rust_arguments.push(format!("addBorrowedObject({})", name)); - return Ok(self) + self.rust_arguments + .push(format!("addBorrowedObject({})", name)); + return Ok(self); } match *arg { Descriptor::Boolean => { - self.js_arguments.push((name.clone(), "boolean".to_string())); + self.js_arguments + .push((name.clone(), "boolean".to_string())); if self.cx.config.debug { self.cx.expose_assert_bool(); - self.prelude(&format!("\ - _assertBoolean({name});\n\ - ", name = name)); + self.prelude(&format!( + "\ + _assertBoolean({name});\n\ + ", + name = name + )); } self.rust_arguments.push(format!("{} ? 1 : 0", name)); } Descriptor::Char => { self.js_arguments.push((name.clone(), "string".to_string())); self.rust_arguments.push(format!("{}.codePointAt(0)", name)) - }, + } Descriptor::Anyref => { self.js_arguments.push((name.clone(), "any".to_string())); self.cx.expose_add_heap_object(); self.rust_arguments.push(format!("addHeapObject({})", name)); } - _ => { - bail!("unsupported argument to rust function {:?}", arg) - } + _ => bail!("unsupported argument to rust function {:?}", arg), } Ok(self) } @@ -238,7 +268,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> { None => { self.ret_ty = "void".to_string(); self.ret_expr = format!("return RET;"); - return Ok(self) + return Ok(self); } }; @@ -246,7 +276,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> { self.ret_ty = "any".to_string(); self.cx.expose_get_object(); self.ret_expr = format!("return getObject(RET);"); - return Ok(self) + return Ok(self); } if ty.is_by_ref() { @@ -261,28 +291,32 @@ impl<'a, 'b> Js2Rust<'a, 'b> { self.cx.require_internal_export("__wbindgen_free")?; self.prelude("const retptr = globalArgumentPtr();"); self.rust_arguments.insert(0, "retptr".to_string()); - self.ret_expr = format!("\ - RET;\n\ - const mem = getUint32Memory();\n\ - const ptr = mem[retptr / 4];\n\ - const len = mem[retptr / 4 + 1];\n\ - const realRet = {}(ptr, len).slice();\n\ - wasm.__wbindgen_free(ptr, len * {});\n\ - return realRet;\n\ - ", f, ty.size()); - return Ok(self) + self.ret_expr = format!( + "\ + RET;\n\ + const mem = getUint32Memory();\n\ + const ptr = mem[retptr / 4];\n\ + const len = mem[retptr / 4 + 1];\n\ + const realRet = {}(ptr, len).slice();\n\ + wasm.__wbindgen_free(ptr, len * {});\n\ + return realRet;\n\ + ", + f, + ty.size() + ); + return Ok(self); } if let Some(name) = ty.rust_struct() { self.ret_ty = name.to_string(); self.ret_expr = format!("return {name}.__construct(RET);", name = name); - return Ok(self) + return Ok(self); } if ty.is_number() { self.ret_ty = "number".to_string(); self.ret_expr = format!("return RET;"); - return Ok(self) + return Ok(self); } if let Some(signed) = ty.get_64bit() { @@ -297,11 +331,14 @@ impl<'a, 'b> Js2Rust<'a, 'b> { }; self.prelude("const retptr = globalArgumentPtr();"); self.rust_arguments.insert(0, "retptr".to_string()); - self.ret_expr = format!("\ - RET;\n\ - return {}()[retptr / 8];\n\ - ", f); - return Ok(self) + self.ret_expr = format!( + "\ + RET;\n\ + return {}()[retptr / 8];\n\ + ", + f + ); + return Ok(self); } match *ty { @@ -333,7 +370,8 @@ impl<'a, 'b> Js2Rust<'a, 'b> { /// generated function shim and the second is a TypeScript signature of the /// JS expression. pub fn finish(&self, prefix: &str, invoc: &str) -> (String, String) { - let js_args = self.js_arguments + let js_args = self + .js_arguments .iter() .map(|s| &s.0[..]) .collect::>() @@ -342,29 +380,35 @@ impl<'a, 'b> Js2Rust<'a, 'b> { js.push_str(&self.prelude); let rust_args = self.rust_arguments.join(", "); - let invoc = self.ret_expr.replace("RET", &format!("{}({})", invoc, rust_args)); + let invoc = self + .ret_expr + .replace("RET", &format!("{}({})", invoc, rust_args)); let invoc = if self.finally.len() == 0 { invoc } else { - format!("\ + format!( + "\ try {{\n\ {} \n}} finally {{\n\ {} }}\n\ ", - &invoc, - &self.finally, + &invoc, &self.finally, ) }; js.push_str(&invoc); js.push_str("\n}"); - let ts_args = self.js_arguments + let ts_args = self + .js_arguments .iter() .map(|s| format!("{}: {}", s.0, s.1)) .collect::>() .join(", "); - let ts = format!("{} {}({}): {};\n", prefix, self.js_name, ts_args, self.ret_ty); + let ts = format!( + "{} {}({}): {};\n", + prefix, self.js_name, ts_args, self.ret_ty + ); (js, ts) } -} \ No newline at end of file +} diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index fde0e40a..74ad6255 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1,10 +1,10 @@ -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; use std::fmt::Write; use std::mem; use failure::{Error, ResultExt}; -use parity_wasm::elements::*; use parity_wasm; +use parity_wasm::elements::*; use serde_json; use shared; use wasm_gc; @@ -84,22 +84,22 @@ impl<'a> Context<'a> { self.global(&global); } - fn require_internal_export(&mut self, name: &'static str) - -> Result<(), Error> - { + fn require_internal_export(&mut self, name: &'static str) -> Result<(), Error> { if !self.required_internal_exports.insert(name) { - return Ok(()) + return Ok(()); } if let Some(s) = self.module.export_section() { if s.entries().iter().any(|e| e.field() == name) { - return Ok(()) + return Ok(()); } } - bail!("the exported function `{}` is required to generate bindings \ - but it was not found in the wasm file, perhaps the `std` feature \ - of the `wasm-bindgen` crate needs to be enabled?", - name); + bail!( + "the exported function `{}` is required to generate bindings \ + but it was not found in the wasm file, perhaps the `std` feature \ + of the `wasm-bindgen` crate needs to be enabled?", + name + ); } pub fn finalize(&mut self, module_name: &str) -> Result<(String, String), Error> { @@ -109,14 +109,17 @@ impl<'a> Context<'a> { me.expose_add_heap_object(); me.expose_get_object(); let bump_cnt = if me.config.debug { - String::from(" + String::from( + " if (typeof(val) === 'number') throw new Error('corrupt slab'); val.cnt += 1; - ") + ", + ) } else { String::from("val.cnt += 1;") }; - Ok(format!(" + Ok(format!( + " function(idx) {{ // If this object is on the stack promote it to the heap. if ((idx & 1) === 1) return addHeapObject(getObject(idx)); @@ -127,92 +130,112 @@ impl<'a> Context<'a> { {} return idx; }} - ", bump_cnt)) + ", + bump_cnt + )) })?; self.bind("__wbindgen_object_drop_ref", &|me| { me.expose_drop_ref(); Ok("function(i) { dropRef(i); - }".to_string()) + }" + .to_string()) })?; self.bind("__wbindgen_string_new", &|me| { me.expose_add_heap_object(); me.expose_get_string_from_wasm(); - Ok(String::from(" + Ok(String::from( + " function(p, l) { return addHeapObject(getStringFromWasm(p, l)); } - ")) + ", + )) })?; self.bind("__wbindgen_number_new", &|me| { me.expose_add_heap_object(); - Ok(String::from("function(i) { + Ok(String::from( + "function(i) { return addHeapObject(i); - }")) + }", + )) })?; self.bind("__wbindgen_number_get", &|me| { me.expose_get_object(); me.expose_uint8_memory(); - Ok(format!(" + Ok(format!( + " function(n, invalid) {{ let obj = getObject(n); if (typeof(obj) === 'number') return obj; getUint8Memory()[invalid] = 1; return 0; }} - ")) + " + )) })?; self.bind("__wbindgen_undefined_new", &|me| { me.expose_add_heap_object(); - Ok(String::from("function() { + Ok(String::from( + "function() { return addHeapObject(undefined); - }")) + }", + )) })?; self.bind("__wbindgen_null_new", &|me| { me.expose_add_heap_object(); - Ok(String::from(" + Ok(String::from( + " function() { return addHeapObject(null); } - ")) + ", + )) })?; self.bind("__wbindgen_is_null", &|me| { me.expose_get_object(); - Ok(String::from(" + Ok(String::from( + " function(idx) { return getObject(idx) === null ? 1 : 0; } - ")) + ", + )) })?; self.bind("__wbindgen_is_undefined", &|me| { me.expose_get_object(); - Ok(String::from(" + Ok(String::from( + " function(idx) { return getObject(idx) === undefined ? 1 : 0; } - ")) + ", + )) })?; self.bind("__wbindgen_boolean_new", &|me| { me.expose_add_heap_object(); - Ok(String::from(" + Ok(String::from( + " function(v) { return addHeapObject(v === 1); } - ")) + ", + )) })?; self.bind("__wbindgen_boolean_get", &|me| { me.expose_get_object(); - Ok(String::from(" + Ok(String::from( + " function(i) { let v = getObject(i); if (typeof(v) === 'boolean') { @@ -221,13 +244,15 @@ impl<'a> Context<'a> { return 2; } } - ")) + ", + )) })?; self.bind("__wbindgen_symbol_new", &|me| { me.expose_get_string_from_wasm(); me.expose_add_heap_object(); - Ok(format!(" + Ok(format!( + " function(ptr, len) {{ let a; if (ptr === 0) {{ @@ -237,23 +262,27 @@ impl<'a> Context<'a> { }} return addHeapObject(a); }} - ")) + " + )) })?; self.bind("__wbindgen_is_symbol", &|me| { me.expose_get_object(); - Ok(String::from(" + Ok(String::from( + " function(i) { return typeof(getObject(i)) === 'symbol' ? 1 : 0; } - ")) + ", + )) })?; self.bind("__wbindgen_string_get", &|me| { me.expose_pass_string_to_wasm()?; me.expose_get_object(); me.expose_uint32_memory(); - Ok(String::from(" + Ok(String::from( + " function(i, len_ptr) { let obj = getObject(i); if (typeof(obj) !== 'string') return 0; @@ -261,59 +290,70 @@ impl<'a> Context<'a> { getUint32Memory()[len_ptr / 4] = len; return ptr; } - ")) + ", + )) })?; self.bind("__wbindgen_cb_drop", &|me| { me.expose_drop_ref(); - Ok(String::from(" + Ok(String::from( + " function(i) { let obj = getObject(i).original; obj.a = obj.b = 0; dropRef(i); } - ")) + ", + )) })?; self.bind("__wbindgen_cb_forget", &|me| { me.expose_drop_ref(); - Ok(String::from(" + Ok(String::from( + " function(i) { dropRef(i); } - ")) + ", + )) })?; self.bind("__wbindgen_json_parse", &|me| { me.expose_add_heap_object(); me.expose_get_string_from_wasm(); - Ok(String::from(" + Ok(String::from( + " function(ptr, len) { return addHeapObject(JSON.parse(getStringFromWasm(ptr, len))); } - ")) + ", + )) })?; self.bind("__wbindgen_json_serialize", &|me| { me.expose_get_object(); me.expose_pass_string_to_wasm()?; me.expose_uint32_memory(); - Ok(String::from(" + Ok(String::from( + " function(idx, ptrptr) { const [ptr, len] = passStringToWasm(JSON.stringify(getObject(idx))); getUint32Memory()[ptrptr / 4] = ptr; return len; } - ")) + ", + )) })?; self.bind("__wbindgen_jsval_eq", &|me| { me.expose_get_object(); - Ok(String::from(" + Ok(String::from( + " function(a, b) { return getObject(a) === getObject(b) ? 1 : 0; } - ")) + ", + )) })?; self.unexport_unused_internal_exports(); @@ -325,11 +365,13 @@ impl<'a> Context<'a> { // isn't gc'd). self.bind("__wbindgen_throw", &|me| { me.expose_get_string_from_wasm(); - Ok(format!(" + Ok(format!( + " function(ptr, len) {{ throw new Error(getStringFromWasm(ptr, len)); }} - ")) + " + )) })?; self.rewrite_imports(module_name); @@ -361,24 +403,25 @@ impl<'a> Context<'a> { ) } else { let import_wasm = if self.config.nodejs { - self.footer.push_str(&format!("wasm = require('./{}_bg');", - module_name)); + self.footer + .push_str(&format!("wasm = require('./{}_bg');", module_name)); format!("var wasm;") } else { format!("import * as wasm from './{}_bg.wasm';", module_name) }; - format!("\ + format!( + "\ /* tslint:disable */\n\ {import_wasm}\n\ {imports}\n\ {globals}\n\ {footer}", - import_wasm = import_wasm, - globals = self.globals, - imports = self.imports, - footer = self.footer, + import_wasm = import_wasm, + globals = self.globals, + imports = self.imports, + footer = self.footer, ) }; @@ -393,16 +436,16 @@ impl<'a> Context<'a> { Ok((js, self.typescript.clone())) } - fn bind(&mut self, name: &str, f: &Fn(&mut Self) -> Result) - -> Result<(), Error> - { + fn bind( + &mut self, + name: &str, + f: &Fn(&mut Self) -> Result, + ) -> Result<(), Error> { if !self.wasm_import_needed(name) { return Ok(()); } let contents = f(self) - .with_context(|_| { - format!("failed to generate internal JS function `{}`", name) - })?; + .with_context(|_| format!("failed to generate internal JS function `{}`", name))?; self.export(name, &contents, None); Ok(()) } @@ -422,7 +465,8 @@ impl<'a> Context<'a> { if self.config.debug || class.constructor.is_some() { self.expose_constructor_token(); - dst.push_str(&format!(" + dst.push_str(&format!( + " static __construct(ptr) {{ return new {}(new ConstructorToken(ptr)); }} @@ -432,24 +476,33 @@ impl<'a> Context<'a> { this.ptr = args[0].ptr; return; }} - ", name)); + ", + name + )); if let Some(ref constructor) = class.constructor { ts_dst.push_str(&format!("constructor(...args: any[]);\n")); - dst.push_str(&format!(" + dst.push_str(&format!( + " // This invocation of new will call this constructor with a ConstructorToken let instance = {class}.{constructor}(...args); this.ptr = instance.ptr; - ", class = name, constructor = constructor)); + ", + class = name, + constructor = constructor + )); } else { - dst.push_str("throw new Error('you cannot invoke `new` directly without having a \ - method annotated a constructor');\n"); + dst.push_str( + "throw new Error('you cannot invoke `new` directly without having a \ + method annotated a constructor');\n", + ); } dst.push_str("}"); } else { - dst.push_str(&format!(" + dst.push_str(&format!( + " static __construct(ptr) {{ return new {}(ptr); }} @@ -457,18 +510,27 @@ impl<'a> Context<'a> { constructor(ptr) {{ this.ptr = ptr; }} - ", name)); + ", + name + )); } let new_name = shared::new_function(&name); if self.wasm_import_needed(&new_name) { self.expose_add_heap_object(); - self.export(&new_name, &format!(" + self.export( + &new_name, + &format!( + " function(ptr) {{ return addHeapObject({}.__construct(ptr)); }} - ", name), None); + ", + name + ), + None, + ); } for field in class.fields.iter() { @@ -481,13 +543,13 @@ impl<'a> Context<'a> { let set = { let mut cx = Js2Rust::new(&field.name, self); - cx.method(true) - .argument(&descriptor)? - .ret(&None)?; - ts_dst.push_str(&format!("{}{}: {}\n", - if field.readonly { "readonly " } else { "" }, - field.name, - &cx.js_arguments[0].1)); + cx.method(true).argument(&descriptor)?.ret(&None)?; + ts_dst.push_str(&format!( + "{}{}: {}\n", + if field.readonly { "readonly " } else { "" }, + field.name, + &cx.js_arguments[0].1 + )); cx.finish("", &format!("wasm.{}", wasm_setter)).0 }; let (get, _ts) = Js2Rust::new(&field.name, self) @@ -509,13 +571,16 @@ impl<'a> Context<'a> { } } - dst.push_str(&format!(" + dst.push_str(&format!( + " free() {{ const ptr = this.ptr; this.ptr = 0; wasm.{}(ptr); }} - ", shared::free_function(&name))); + ", + shared::free_function(&name) + )); ts_dst.push_str("free(): void;\n"); dst.push_str(&class.contents); ts_dst.push_str(&class.typescript); @@ -530,17 +595,16 @@ impl<'a> Context<'a> { fn export_table(&mut self) { if !self.function_table_needed { - return + return; } for section in self.module.sections_mut() { let exports = match *section { Section::Export(ref mut s) => s, _ => continue, }; - let entry = ExportEntry::new("__wbg_function_table".to_string(), - Internal::Table(0)); + let entry = ExportEntry::new("__wbg_function_table".to_string(), Internal::Table(0)); exports.entries_mut().push(entry); - break + break; } } @@ -550,17 +614,15 @@ impl<'a> Context<'a> { } } - fn _rewrite_imports(&mut self, module_name: &str) - -> Vec<(String, String)> - { + fn _rewrite_imports(&mut self, module_name: &str) -> Vec<(String, String)> { let mut math_imports = Vec::new(); - let imports = self.module.sections_mut() + let imports = self + .module + .sections_mut() .iter_mut() - .filter_map(|s| { - match *s { - Section::Import(ref mut s) => Some(s), - _ => None, - } + .filter_map(|s| match *s { + Section::Import(ref mut s) => Some(s), + _ => None, }) .flat_map(|s| s.entries_mut()); @@ -578,10 +640,7 @@ impl<'a> Context<'a> { let renamed_import = format!("__wbindgen_{}", import.field()); let mut bind_math = |expr: &str| { - math_imports.push(( - renamed_import.clone(), - format!("function{}", expr), - )); + math_imports.push((renamed_import.clone(), format!("function{}", expr))); }; // FIXME(#32): try to not use function shims @@ -640,8 +699,7 @@ impl<'a> Context<'a> { _ => continue, }; exports.entries_mut().retain(|export| { - !export.field().starts_with("__wbindgen") || - required.contains(export.field()) + !export.field().starts_with("__wbindgen") || required.contains(export.field()) }); } } @@ -653,25 +711,32 @@ impl<'a> Context<'a> { self.expose_global_slab(); self.expose_global_slab_next(); let validate_owned = if self.config.debug { - String::from(" + String::from( + " if ((idx & 1) === 1) throw new Error('cannot drop ref of stack objects'); - ") + ", + ) } else { String::new() }; let dec_ref = if self.config.debug { - String::from(" + String::from( + " if (typeof(obj) === 'number') throw new Error('corrupt slab'); obj.cnt -= 1; if (obj.cnt > 0) return; - ") + ", + ) } else { - String::from(" + String::from( + " obj.cnt -= 1; if (obj.cnt > 0) return; - ") + ", + ) }; - self.global(&format!(" + self.global(&format!( + " function dropRef(idx) {{ {} let obj = slab[idx >> 1]; @@ -680,23 +745,31 @@ impl<'a> Context<'a> { slab[idx >> 1] = slab_next; slab_next = idx >> 1; }} - ", validate_owned, dec_ref)); + ", + validate_owned, dec_ref + )); } fn expose_global_stack(&mut self) { if !self.exposed_globals.insert("stack") { return; } - self.global(&format!(" + self.global(&format!( + " let stack = []; - ")); + " + )); if self.config.debug { - self.export("assertStackEmpty", " + self.export( + "assertStackEmpty", + " function() { if (stack.length === 0) return; throw new Error('stack is not currently empty'); } - ", None); + ", + None, + ); } } @@ -712,14 +785,21 @@ impl<'a> Context<'a> { ]; self.global(&format!("let slab = [{}];", initial_values.join(", "))); if self.config.debug { - self.export("assertSlabEmpty", &format!(" + self.export( + "assertSlabEmpty", + &format!( + " function() {{ for (let i = {}; i < slab.length; i++) {{ if (typeof(slab[i]) === 'number') continue; throw new Error('slab is not currently empty'); }} }} - ", initial_values.len()), None); + ", + initial_values.len() + ), + None, + ); } } @@ -728,9 +808,11 @@ impl<'a> Context<'a> { return; } self.expose_global_slab(); - self.global(&format!(" + self.global(&format!( + " let slab_next = slab.length; - ")); + " + )); } fn expose_get_object(&mut self) { @@ -741,16 +823,21 @@ impl<'a> Context<'a> { self.expose_global_slab(); let get_obj = if self.config.debug { - String::from(" + String::from( + " if (typeof(val) === 'number') throw new Error('corrupt slab'); return val.obj; - ") + ", + ) } else { - String::from(" + String::from( + " return val.obj; - ") + ", + ) }; - self.global(&format!(" + self.global(&format!( + " function getObject(idx) {{ if ((idx & 1) === 1) {{ return stack[idx >> 1]; @@ -759,31 +846,37 @@ impl<'a> Context<'a> { {} }} }} - ", get_obj)); + ", + get_obj + )); } fn expose_assert_num(&mut self) { if !self.exposed_globals.insert("assert_num") { return; } - self.global(&format!(" + self.global(&format!( + " function _assertNum(n) {{ if (typeof(n) !== 'number') throw new Error('expected a number argument'); }} - ")); + " + )); } fn expose_assert_bool(&mut self) { if !self.exposed_globals.insert("assert_bool") { return; } - self.global(&format!(" + self.global(&format!( + " function _assertBoolean(n) {{ if (typeof(n) !== 'boolean') {{ throw new Error('expected a boolean argument'); }} }} - ")); + " + )); } fn expose_pass_string_to_wasm(&mut self) -> Result<(), Error> { @@ -800,7 +893,8 @@ impl<'a> Context<'a> { } else { "" }; - self.global(&format!(" + self.global(&format!( + " function passStringToWasm(arg) {{ {} const buf = cachedEncoder.encode(arg); @@ -808,7 +902,9 @@ impl<'a> Context<'a> { getUint8Memory().set(buf, ptr); return [ptr, buf.length]; }} - ", debug)); + ", + debug + )); Ok(()) } @@ -842,23 +938,29 @@ impl<'a> Context<'a> { self.pass_array_to_wasm("passArrayF64ToWasm", "getFloat64Memory", 8) } - fn pass_array_to_wasm(&mut self, - name: &'static str, - delegate: &str, - size: usize) -> Result<(), Error> - { + fn pass_array_to_wasm( + &mut self, + name: &'static str, + delegate: &str, + size: usize, + ) -> Result<(), Error> { if !self.exposed_globals.insert(name) { - return Ok(()) + return Ok(()); } self.require_internal_export("__wbindgen_malloc")?; self.expose_uint64_memory(); - self.global(&format!(" + self.global(&format!( + " function {}(arg) {{ const ptr = wasm.__wbindgen_malloc(arg.length * {size}); {}().set(arg, ptr / {size}); return [ptr, arg.length]; }} - ", name, delegate, size = size)); + ", + name, + delegate, + size = size + )); Ok(()) } @@ -867,19 +969,25 @@ impl<'a> Context<'a> { return; } if self.config.nodejs { - self.global(&format!(" + self.global(&format!( + " const TextEncoder = require('util').TextEncoder; - ")); + " + )); } else if !(self.config.browser || self.config.no_modules) { - self.global(&format!(" + self.global(&format!( + " const TextEncoder = typeof self === 'object' && self.TextEncoder ? self.TextEncoder : require('util').TextEncoder; - ")); + " + )); } - self.global(&format!(" + self.global(&format!( + " let cachedEncoder = new TextEncoder('utf-8'); - ")); + " + )); } fn expose_text_decoder(&mut self) { @@ -887,19 +995,25 @@ impl<'a> Context<'a> { return; } if self.config.nodejs { - self.global(&format!(" + self.global(&format!( + " const TextDecoder = require('util').TextDecoder; - ")); + " + )); } else if !(self.config.browser || self.config.no_modules) { - self.global(&format!(" + self.global(&format!( + " const TextDecoder = typeof self === 'object' && self.TextDecoder ? self.TextDecoder : require('util').TextDecoder; - ")); + " + )); } - self.global(&format!(" + self.global(&format!( + " let cachedDecoder = new TextDecoder('utf-8'); - ")); + " + )); } fn expose_constructor_token(&mut self) { @@ -907,13 +1021,15 @@ impl<'a> Context<'a> { return; } - self.global(" + self.global( + " class ConstructorToken { constructor(ptr) { this.ptr = ptr; } } - "); + ", + ); } fn expose_get_string_from_wasm(&mut self) { @@ -922,11 +1038,13 @@ impl<'a> Context<'a> { } self.expose_text_decoder(); self.expose_uint8_memory(); - self.global(&format!(" + self.global(&format!( + " function getStringFromWasm(ptr, len) {{ return cachedDecoder.decode(getUint8Memory().subarray(ptr, ptr + len)); }} - ")); + " + )); } fn expose_get_array_js_value_from_wasm(&mut self) { @@ -935,7 +1053,8 @@ impl<'a> Context<'a> { } self.expose_get_array_u32_from_wasm(); self.expose_take_object(); - self.global(&format!(" + self.global(&format!( + " function getArrayJsValueFromWasm(ptr, len) {{ const mem = getUint32Memory(); const slice = mem.subarray(ptr / 4, ptr / 4 + len); @@ -945,7 +1064,8 @@ impl<'a> Context<'a> { }} return result; }} - ")); + " + )); } fn expose_get_array_i8_from_wasm(&mut self) { @@ -1002,7 +1122,8 @@ impl<'a> Context<'a> { if !self.exposed_globals.insert(name) { return; } - self.global(&format!(" + self.global(&format!( + " function {name}(ptr, len) {{ return {mem}().subarray(ptr / {size}, ptr / {size} + len); }} @@ -1106,12 +1227,12 @@ impl<'a> Context<'a> { } } - fn memview(&mut self, name: &'static str, js: &str) { if !self.exposed_globals.insert(name) { return; } - self.global(&format!(" + self.global(&format!( + " let cache{name} = null; function {name}() {{ if (cache{name} === null || cache{name}.buffer !== wasm.memory.buffer) {{ @@ -1129,14 +1250,16 @@ impl<'a> Context<'a> { if !self.exposed_globals.insert("assert_class") { return; } - self.global(&format!(" + self.global(&format!( + " function _assertClass(instance, klass) {{ if (!(instance instanceof klass)) {{ throw new Error(`expected instance of ${{klass.name}}`); }} return instance.ptr; }} - ")); + " + )); } fn expose_borrowed_objects(&mut self) { @@ -1144,12 +1267,14 @@ impl<'a> Context<'a> { return; } self.expose_global_stack(); - self.global(&format!(" + self.global(&format!( + " function addBorrowedObject(obj) {{ stack.push(obj); return ((stack.length - 1) << 1) | 1; }} - ")); + " + )); } fn expose_take_object(&mut self) { @@ -1158,13 +1283,15 @@ impl<'a> Context<'a> { } self.expose_get_object(); self.expose_drop_ref(); - self.global(&format!(" + self.global(&format!( + " function takeObject(idx) {{ const ret = getObject(idx); dropRef(idx); return ret; }} - ")); + " + )); } fn expose_add_heap_object(&mut self) { @@ -1174,16 +1301,21 @@ impl<'a> Context<'a> { self.expose_global_slab(); self.expose_global_slab_next(); let set_slab_next = if self.config.debug { - String::from(" + String::from( + " if (typeof(next) !== 'number') throw new Error('corrupt slab'); slab_next = next; - ") + ", + ) } else { - String::from(" + String::from( + " slab_next = next; - ") + ", + ) }; - self.global(&format!(" + self.global(&format!( + " function addHeapObject(obj) {{ if (slab_next === slab.length) slab.push(slab.length + 1); const idx = slab_next; @@ -1192,7 +1324,9 @@ impl<'a> Context<'a> { slab[idx] = {{ obj, cnt: 1 }}; return idx << 1; }} - ", set_slab_next)); + ", + set_slab_next + )); } fn wasm_import_needed(&self, name: &str) -> bool { @@ -1201,9 +1335,10 @@ impl<'a> Context<'a> { None => return false, }; - imports.entries().iter().any(|i| { - i.module() == "__wbindgen_placeholder__" && i.field() == name - }) + imports + .entries() + .iter() + .any(|i| i.module() == "__wbindgen_placeholder__" && i.field() == name) } fn pass_to_wasm_function(&mut self, t: VectorKind) -> Result<&'static str, Error> { @@ -1212,23 +1347,19 @@ impl<'a> Context<'a> { self.expose_pass_string_to_wasm()?; "passStringToWasm" } - VectorKind::I8 | - VectorKind::U8 => { + VectorKind::I8 | VectorKind::U8 => { self.expose_pass_array8_to_wasm()?; "passArray8ToWasm" } - VectorKind::U16 | - VectorKind::I16 => { + VectorKind::U16 | VectorKind::I16 => { self.expose_pass_array16_to_wasm()?; "passArray16ToWasm" } - VectorKind::I32 | - VectorKind::U32 => { + VectorKind::I32 | VectorKind::U32 => { self.expose_pass_array32_to_wasm()?; "passArray32ToWasm" } - VectorKind::I64 | - VectorKind::U64 => { + VectorKind::I64 | VectorKind::U64 => { self.expose_pass_array64_to_wasm()?; "passArray64ToWasm" } @@ -1240,9 +1371,7 @@ impl<'a> Context<'a> { self.expose_pass_array_f64_to_wasm()?; "passArrayF64ToWasm" } - VectorKind::Anyref => { - bail!("cannot pass list of JsValue to wasm yet") - } + VectorKind::Anyref => bail!("cannot pass list of JsValue to wasm yet"), }; Ok(s) } @@ -1306,12 +1435,14 @@ impl<'a> Context<'a> { } self.expose_uint32_memory(); self.expose_global_argument_ptr()?; - self.global(" + self.global( + " function getGlobalArgument(arg) { const idx = globalArgumentPtr() / 4 + arg; return getUint32Memory()[idx]; } - "); + ", + ); Ok(()) } @@ -1320,7 +1451,8 @@ impl<'a> Context<'a> { return Ok(()); } self.require_internal_export("__wbindgen_global_argument_ptr")?; - self.global(" + self.global( + " let cachedGlobalArgumentPtr = null; function globalArgumentPtr() { if (cachedGlobalArgumentPtr === null) {{ @@ -1328,13 +1460,14 @@ impl<'a> Context<'a> { }} return cachedGlobalArgumentPtr; } - "); + ", + ); Ok(()) } fn expose_get_inherited_descriptor(&mut self) { if !self.exposed_globals.insert("get_inherited_descriptor") { - return + return; } // It looks like while rare some browsers will move descriptors up the // property chain which runs the risk of breaking wasm-bindgen-generated @@ -1345,7 +1478,8 @@ impl<'a> Context<'a> { // As a result we have a small helper here which will walk the prototype // chain looking for a descriptor. For some more information on this see // #109 - self.global(" + self.global( + " function GetOwnOrInheritedPropertyDescriptor(obj, id) { while (obj) { let desc = Object.getOwnPropertyDescriptor(obj, id); @@ -1354,13 +1488,14 @@ impl<'a> Context<'a> { } throw new Error('descriptor not found'); } - "); + ", + ); } fn expose_u32_cvt_shim(&mut self) -> &'static str { let name = "u32CvtShim"; if !self.exposed_globals.insert(name) { - return name + return name; } self.global(&format!("const {} = new Uint32Array(2);", name)); name @@ -1369,20 +1504,26 @@ impl<'a> Context<'a> { fn expose_int64_cvt_shim(&mut self) -> &'static str { let name = "int64CvtShim"; if !self.exposed_globals.insert(name) { - return name + return name; } let n = self.expose_u32_cvt_shim(); - self.global(&format!("const {} = new BigInt64Array({}.buffer);", name, n)); + self.global(&format!( + "const {} = new BigInt64Array({}.buffer);", + name, n + )); name } fn expose_uint64_cvt_shim(&mut self) -> &'static str { let name = "uint64CvtShim"; if !self.exposed_globals.insert(name) { - return name + return name; } let n = self.expose_u32_cvt_shim(); - self.global(&format!("const {} = new BigUint64Array({}.buffer);", name, n)); + self.global(&format!( + "const {} = new BigUint64Array({}.buffer);", + name, n + )); name } @@ -1416,7 +1557,7 @@ impl<'a> Context<'a> { fn add_wasm_pack_section(&mut self) { if self.module_versions.len() == 0 { - return + return; } #[derive(Serialize)] @@ -1440,11 +1581,12 @@ impl<'a> Context<'a> { impl<'a, 'b> SubContext<'a, 'b> { pub fn generate(&mut self) -> Result<(), Error> { for f in self.program.exports.iter() { - self.generate_export(f) - .with_context(|_| { - format!("failed to generate bindings for Rust export `{}`", - f.function.name) - })?; + self.generate_export(f).with_context(|_| { + format!( + "failed to generate bindings for Rust export `{}`", + f.function.name + ) + })?; } for f in self.program.imports.iter() { self.generate_import(f)?; @@ -1453,26 +1595,23 @@ impl<'a, 'b> SubContext<'a, 'b> { self.generate_enum(e); } for s in self.program.structs.iter() { - let mut class = self.cx.exported_classes + let mut class = self + .cx + .exported_classes .entry(s.name.clone()) .or_insert_with(Default::default); class.comments = format_doc_comments(&s.comments); - class.fields - .extend(s.fields.iter().map(|f| { - ClassField { - name: f.name.clone(), - readonly: f.readonly, - comments: format_doc_comments(&f.comments), - } - })); + class.fields.extend(s.fields.iter().map(|f| ClassField { + name: f.name.clone(), + readonly: f.readonly, + comments: format_doc_comments(&f.comments), + })); } Ok(()) } - fn generate_export(&mut self, export: &shared::Export) - -> Result<(), Error> - { + fn generate_export(&mut self, export: &shared::Export) -> Result<(), Error> { if let Some(ref class) = export.class { return self.generate_export_for_class(class, export); } @@ -1485,7 +1624,11 @@ impl<'a, 'b> SubContext<'a, 'b> { let (js, ts) = Js2Rust::new(&export.function.name, self.cx) .process(descriptor.unwrap_function())? .finish("function", &format!("wasm.{}", export.function.name)); - self.cx.export(&export.function.name, &js, Some(format_doc_comments(&export.comments))); + self.cx.export( + &export.function.name, + &js, + Some(format_doc_comments(&export.comments)), + ); self.cx.globals.push_str("\n"); self.cx.typescript.push_str("export "); self.cx.typescript.push_str(&ts); @@ -1509,15 +1652,22 @@ impl<'a, 'b> SubContext<'a, 'b> { .method(export.method) .process(descriptor.unwrap_function())? .finish("", &format!("wasm.{}", wasm_name)); - let class = self.cx.exported_classes.entry(class_name.to_string()) + let class = self + .cx + .exported_classes + .entry(class_name.to_string()) .or_insert(ExportedClass::default()); - class.contents.push_str(&format_doc_comments(&export.comments)); + class + .contents + .push_str(&format_doc_comments(&export.comments)); if !export.method { class.contents.push_str("static "); class.typescript.push_str("static "); } - let constructors: Vec = self.program.exports + let constructors: Vec = self + .program + .exports .iter() .filter(|x| x.class == Some(class_name.to_string())) .filter_map(|x| x.constructor.clone()) @@ -1540,27 +1690,24 @@ impl<'a, 'b> SubContext<'a, 'b> { self.validate_import_module(import)?; match import.kind { shared::ImportKind::Function(ref f) => { - self.generate_import_function(import, f) - .with_context(|_| { - format!("failed to generate bindings for JS import `{}`", - f.function.name) - })?; + self.generate_import_function(import, f).with_context(|_| { + format!( + "failed to generate bindings for JS import `{}`", + f.function.name + ) + })?; } shared::ImportKind::Static(ref s) => { - self.generate_import_static(import, s) - .with_context(|_| { - format!("failed to generate bindings for JS import `{}`", - s.name) - })?; + self.generate_import_static(import, s).with_context(|_| { + format!("failed to generate bindings for JS import `{}`", s.name) + })?; } shared::ImportKind::Type(_) => {} } Ok(()) } - fn validate_import_module(&mut self, import: &shared::Import) - -> Result<(), Error> - { + fn validate_import_module(&mut self, import: &shared::Import) -> Result<(), Error> { let version = match import.version { Some(ref s) => s, None => return Ok(()), @@ -1570,16 +1717,17 @@ impl<'a, 'b> SubContext<'a, 'b> { None => return Ok(()), }; if module.starts_with("./") { - return Ok(()) + return Ok(()); } let pkg = if module.starts_with("@") { // Translate `@foo/bar/baz` to `@foo/bar` and `@foo/bar` to itself let first_slash = match module.find('/') { Some(i) => i, - None => { - bail!("packages starting with `@` must be of the form \ - `@foo/bar`, but found: `{}`", module) - } + None => bail!( + "packages starting with `@` must be of the form \ + `@foo/bar`, but found: `{}`", + module + ), }; match module[first_slash + 1..].find('/') { Some(i) => &module[..i], @@ -1588,7 +1736,9 @@ impl<'a, 'b> SubContext<'a, 'b> { } else { module.split('/').next().unwrap() }; - self.cx.module_versions.push((pkg.to_string(), version.clone())); + self.cx + .module_versions + .push((pkg.to_string(), version.clone())); Ok(()) } @@ -1596,32 +1746,42 @@ impl<'a, 'b> SubContext<'a, 'b> { &mut self, info: &shared::Import, import: &shared::ImportStatic, - ) - -> Result<(), Error> - { + ) -> Result<(), Error> { // TODO: should support more types to import here let obj = self.import_name(info, &import.name)?; self.cx.expose_add_heap_object(); - self.cx.export(&import.shim, &format!(" + self.cx.export( + &import.shim, + &format!( + " function() {{ return addHeapObject({}); }} - ", obj), None); + ", + obj + ), + None, + ); Ok(()) } - fn generate_import_function(&mut self, - info: &shared::Import, - import: &shared::ImportFunction) - -> Result<(), Error> - { + fn generate_import_function( + &mut self, + info: &shared::Import, + import: &shared::ImportFunction, + ) -> Result<(), Error> { let descriptor = match self.cx.describe(&import.shim) { None => return Ok(()), Some(d) => d, }; let target = match &import.method { - Some(shared::MethodData { class, kind, getter, setter }) => { + Some(shared::MethodData { + class, + kind, + getter, + setter, + }) => { let class = self.import_name(info, class)?; if let shared::MethodKind::Constructor = kind { format!("new {}", class) @@ -1634,31 +1794,37 @@ impl<'a, 'b> SubContext<'a, 'b> { let target = if let Some(g) = getter { if import.structural { - format!("function(y) {{ + format!( + "function(y) {{ return this.{}; - }}", g) + }}", + g + ) } else { self.cx.expose_get_inherited_descriptor(); format!( "GetOwnOrInheritedPropertyDescriptor\ - ({}{}, '{}').get", + ({}{}, '{}').get", class, - if is_static { "" } else { ".prototype "}, + if is_static { "" } else { ".prototype " }, g, ) } } else if let Some(s) = setter { if import.structural { - format!("function(y) {{ + format!( + "function(y) {{ this.{} = y; - }}", s) + }}", + s + ) } else { self.cx.expose_get_inherited_descriptor(); format!( "GetOwnOrInheritedPropertyDescriptor\ - ({}{}, '{}').set", + ({}{}, '{}').set", class, - if is_static { "" } else { ".prototype "}, + if is_static { "" } else { ".prototype " }, s, ) } @@ -1684,21 +1850,36 @@ impl<'a, 'b> SubContext<'a, 'b> { s.push_str(");\n}"); s } else { - format!("{}{}.{}", class, if is_static { "" } else { ".prototype" }, import.function.name) + format!( + "{}{}.{}", + class, + if is_static { "" } else { ".prototype" }, + import.function.name + ) } }; - self.cx.global(&format!(" + self.cx.global(&format!( + " const {}_target = {}; - ", import.shim, target)); - format!("{}_target{}", import.shim, if is_static { "" } else { ".call" }) + ", + import.shim, target + )); + format!( + "{}_target{}", + import.shim, + if is_static { "" } else { ".call" } + ) } } None => { let name = self.import_name(info, &import.function.name)?; if name.contains(".") { - self.cx.global(&format!(" + self.cx.global(&format!( + " const {}_target = {}; - ", import.shim, name)); + ", + import.shim, name + )); format!("{}_target", import.shim) } else { name @@ -1720,8 +1901,14 @@ impl<'a, 'b> SubContext<'a, 'b> { for variant in enum_.variants.iter() { variants.push_str(&format!("{}:{},", variant.name, variant.value)); } - self.cx.export(&enum_.name, &format!("Object.freeze({{ {} }})", variants), Some(format_doc_comments(&enum_.comments))); - self.cx.typescript.push_str(&format!("export enum {} {{", enum_.name)); + self.cx.export( + &enum_.name, + &format!("Object.freeze({{ {} }})", variants), + Some(format_doc_comments(&enum_.comments)), + ); + self.cx + .typescript + .push_str(&format!("export enum {} {{", enum_.name)); variants.clear(); for variant in enum_.variants.iter() { @@ -1731,26 +1918,33 @@ impl<'a, 'b> SubContext<'a, 'b> { self.cx.typescript.push_str("}\n"); } - fn import_name(&mut self, import: &shared::Import, item: &str) - -> Result - { + fn import_name(&mut self, import: &shared::Import, item: &str) -> Result { if let Some(ref module) = import.module { if self.cx.config.no_modules { - bail!("import from `{}` module not allowed with `--no-modules`; \ - use `--nodejs` or `--browser` instead", module); + bail!( + "import from `{}` module not allowed with `--no-modules`; \ + use `--nodejs` or `--browser` instead", + module + ); } let name = import.js_namespace.as_ref().map(|s| &**s).unwrap_or(item); if self.cx.imported_names.insert(name.to_string()) { if self.cx.config.nodejs { - self.cx.imports.push_str(&format!("\ - const {} = require('{}').{};\n\ - ", name, module, name)); + self.cx.imports.push_str(&format!( + "\ + const {} = require('{}').{};\n\ + ", + name, module, name + )); } else { - self.cx.imports.push_str(&format!("\ - import {{ {} }} from '{}';\n\ - ", name, module)); + self.cx.imports.push_str(&format!( + "\ + import {{ {} }} from '{}';\n\ + ", + name, module + )); } } } @@ -1762,6 +1956,9 @@ impl<'a, 'b> SubContext<'a, 'b> { } fn format_doc_comments(comments: &Vec) -> String { - let body: String = comments.iter().map(|c| format!("*{}\n", c.trim_matches('"'))).collect(); + let body: String = comments + .iter() + .map(|c| format!("*{}\n", c.trim_matches('"'))) + .collect(); format!("/**\n{}*/\n", body) -} \ No newline at end of file +} diff --git a/crates/cli-support/src/js/rust2js.rs b/crates/cli-support/src/js/rust2js.rs index 3860e307..36bd591e 100644 --- a/crates/cli-support/src/js/rust2js.rs +++ b/crates/cli-support/src/js/rust2js.rs @@ -1,7 +1,7 @@ use failure::Error; -use descriptor::{Descriptor, Function}; use super::{Context, Js2Rust}; +use descriptor::{Descriptor, Function}; /// Helper struct for manufacturing a shim in JS used to translate Rust types to /// JS, then invoking an imported JS function. @@ -85,18 +85,27 @@ impl<'a, 'b> Rust2Js<'a, 'b> { if let Some(ty) = arg.vector_kind() { let abi2 = self.shim_argument(); let f = self.cx.expose_get_vector_from_wasm(ty); - self.prelude(&format!("let v{0} = {func}({0}, {1});", - abi, abi2, func = f)); + self.prelude(&format!( + "let v{0} = {func}({0}, {1});", + abi, + abi2, + func = f + )); if !arg.is_by_ref() { - self.prelude(&format!("\ - v{0} = v{0}.slice();\n\ - wasm.__wbindgen_free({0}, {1} * {size});\ - ", abi, abi2, size = ty.size())); + self.prelude(&format!( + "\ + v{0} = v{0}.slice();\n\ + wasm.__wbindgen_free({0}, {1} * {size});\ + ", + abi, + abi2, + size = ty.size() + )); self.cx.require_internal_export("__wbindgen_free")?; } self.js_arguments.push(format!("v{}", abi)); - return Ok(()) + return Ok(()); } if let Some(signed) = arg.get_64bit() { @@ -107,18 +116,19 @@ impl<'a, 'b> Rust2Js<'a, 'b> { }; let hi = self.shim_argument(); let name = format!("n{}", abi); - self.prelude(&format!("\ - u32CvtShim[0] = {lo};\n\ - u32CvtShim[1] = {hi};\n\ - const {name} = {f}[0];\n\ - ", + self.prelude(&format!( + "\ + u32CvtShim[0] = {lo};\n\ + u32CvtShim[1] = {hi};\n\ + const {name} = {f}[0];\n\ + ", lo = abi, hi = hi, f = f, name = name, )); self.js_arguments.push(name); - return Ok(()) + return Ok(()); } if let Some(class) = arg.rust_struct() { @@ -128,14 +138,15 @@ impl<'a, 'b> Rust2Js<'a, 'b> { let assign = format!("let c{0} = {1}.__construct({0});", abi, class); self.prelude(&assign); self.js_arguments.push(format!("c{}", abi)); - return Ok(()) + return Ok(()); } if let Some((f, mutable)) = arg.stack_closure() { let (js, _ts) = { let mut builder = Js2Rust::new("", self.cx); if mutable { - builder.prelude("let a = this.a;\n") + builder + .prelude("let a = this.a;\n") .prelude("this.a = 0;\n") .rust_argument("a") .finally("this.a = a;\n"); @@ -151,22 +162,28 @@ impl<'a, 'b> Rust2Js<'a, 'b> { self.cx.function_table_needed = true; let next_global = self.global_idx(); self.global_idx(); - self.prelude(&format!("\ - let cb{0} = {js};\n\ - cb{0}.f = wasm.__wbg_function_table.get({0});\n\ - cb{0}.a = getGlobalArgument({next_global});\n\ - cb{0}.b = getGlobalArgument({next_global} + 1);\n\ - ", abi, js = js, next_global = next_global)); + self.prelude(&format!( + "\ + let cb{0} = {js};\n\ + cb{0}.f = wasm.__wbg_function_table.get({0});\n\ + cb{0}.a = getGlobalArgument({next_global});\n\ + cb{0}.b = getGlobalArgument({next_global} + 1);\n\ + ", + abi, + js = js, + next_global = next_global + )); self.finally(&format!("cb{0}.a = cb{0}.b = 0;", abi)); self.js_arguments.push(format!("cb{0}.bind(cb{0})", abi)); - return Ok(()) + return Ok(()); } if let Some(closure) = arg.ref_closure() { let (js, _ts) = { let mut builder = Js2Rust::new("", self.cx); if closure.mutable { - builder.prelude("let a = this.a;\n") + builder + .prelude("let a = this.a;\n") .prelude("this.a = 0;\n") .rust_argument("a") .finally("this.a = a;\n"); @@ -182,38 +199,40 @@ impl<'a, 'b> Rust2Js<'a, 'b> { self.cx.expose_uint32_memory(); self.cx.expose_add_heap_object(); self.cx.function_table_needed = true; - let reset_idx = format!("\ - let cb{0} = {js};\n\ - cb{0}.a = getGlobalArgument({a});\n\ - cb{0}.b = getGlobalArgument({b});\n\ - cb{0}.f = wasm.__wbg_function_table.get(getGlobalArgument({c}));\n\ - let real = cb{0}.bind(cb{0});\n\ - real.original = cb{0};\n\ - idx{0} = getUint32Memory()[{0} / 4] = addHeapObject(real);\n\ - ", + let reset_idx = format!( + "\ + let cb{0} = {js};\n\ + cb{0}.a = getGlobalArgument({a});\n\ + cb{0}.b = getGlobalArgument({b});\n\ + cb{0}.f = wasm.__wbg_function_table.get(getGlobalArgument({c}));\n\ + let real = cb{0}.bind(cb{0});\n\ + real.original = cb{0};\n\ + idx{0} = getUint32Memory()[{0} / 4] = addHeapObject(real);\n\ + ", abi, js = js, a = self.global_idx(), b = self.global_idx(), c = self.global_idx(), ); - self.prelude(&format!("\ - let idx{0} = getUint32Memory()[{0} / 4];\n\ - if (idx{0} === 0xffffffff) {{\n\ - {1}\ - }}\n\ - ", abi, &reset_idx)); + self.prelude(&format!( + "\ + let idx{0} = getUint32Memory()[{0} / 4];\n\ + if (idx{0} === 0xffffffff) {{\n\ + {1}\ + }}\n\ + ", + abi, &reset_idx + )); self.cx.expose_get_object(); self.js_arguments.push(format!("getObject(idx{})", abi)); - return Ok(()) + return Ok(()); } let invoc_arg = match *arg { ref d if d.is_number() => abi, Descriptor::Boolean => format!("{} !== 0", abi), - Descriptor::Char => { - format!("String.fromCodePoint({})", abi) - } + Descriptor::Char => format!("String.fromCodePoint({})", abi), Descriptor::Anyref => { self.cx.expose_take_object(); format!("takeObject({})", abi) @@ -222,7 +241,10 @@ impl<'a, 'b> Rust2Js<'a, 'b> { self.cx.expose_get_object(); format!("getObject({})", abi) } - _ => bail!("unimplemented argument type in imported function: {:?}", arg), + _ => bail!( + "unimplemented argument type in imported function: {:?}", + arg + ), }; self.js_arguments.push(invoc_arg); Ok(()) @@ -233,7 +255,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> { Some(ref t) => t, None => { self.ret_expr = "JS;".to_string(); - return Ok(()) + return Ok(()); } }; if ty.is_by_ref() { @@ -243,17 +265,20 @@ impl<'a, 'b> Rust2Js<'a, 'b> { let f = self.cx.pass_to_wasm_function(ty)?; self.cx.expose_uint32_memory(); self.shim_arguments.insert(0, "ret".to_string()); - self.ret_expr = format!("\ + self.ret_expr = format!( + "\ const [retptr, retlen] = {}(JS);\n\ const mem = getUint32Memory(); mem[ret / 4] = retptr; mem[ret / 4 + 1] = retlen; - ", f); - return Ok(()) + ", + f + ); + return Ok(()); } if ty.is_number() { self.ret_expr = "return JS;".to_string(); - return Ok(()) + return Ok(()); } if let Some(signed) = ty.get_64bit() { let f = if signed { @@ -264,11 +289,14 @@ impl<'a, 'b> Rust2Js<'a, 'b> { "getUint64Memory" }; self.shim_arguments.insert(0, "ret".to_string()); - self.ret_expr = format!("\ - const val = JS;\n\ - {}()[ret / 8] = val;\n\ - ", f); - return Ok(()) + self.ret_expr = format!( + "\ + const val = JS;\n\ + {}()[ret / 8] = val;\n\ + ", + f + ); + return Ok(()); } self.ret_expr = match *ty { Descriptor::Boolean => "return JS ? 1 : 0;".to_string(), @@ -301,33 +329,39 @@ impl<'a, 'b> Rust2Js<'a, 'b> { ); if self.catch { let catch = "\ - const view = getUint32Memory();\n\ - view[exnptr / 4] = 1;\n\ - view[exnptr / 4 + 1] = addHeapObject(e);\n\ - "; + const view = getUint32Memory();\n\ + view[exnptr / 4] = 1;\n\ + view[exnptr / 4 + 1] = addHeapObject(e);\n\ + "; - invoc = format!("\ + invoc = format!( + "\ try {{\n\ {} }} catch (e) {{\n\ {} }}\ - ", &invoc, catch); + ", + &invoc, catch + ); }; if self.finally.len() > 0 { - invoc = format!("\ + invoc = format!( + "\ try {{\n\ {} }} finally {{\n\ {} }}\ - ", &invoc, &self.finally); + ", + &invoc, &self.finally + ); } ret.push_str(&invoc); ret.push_str("\n}\n"); - return ret + return ret; } fn global_idx(&mut self) -> usize { diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index da74b3d2..5af6fe17 100644 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -17,8 +17,8 @@ use std::path::{Path, PathBuf}; use failure::{Error, ResultExt}; use parity_wasm::elements::*; -mod js; mod descriptor; +mod js; pub mod wasm2es6js; pub struct Bindgen { @@ -142,11 +142,9 @@ impl Bindgen { let mut v = MyExternals(Vec::new()); match instance.invoke_export(name, &[], &mut v) { Ok(None) => Some(v.0), - Ok(Some(_)) => { - unreachable!( - "there is only one export, and we only return None from it" - ) - }, + Ok(Some(_)) => unreachable!( + "there is only one export, and we only return None from it" + ), // Allow missing exported describe functions. This can // happen when a nested dependency crate exports things // but the root crate doesn't use them. @@ -207,13 +205,16 @@ impl Bindgen { shim.push_str(&format!("imports['{0}'] = require('{0}');\n", module)); } - shim.push_str(&format!(" + shim.push_str(&format!( + " const join = require('path').join; const bytes = require('fs').readFileSync(join(__dirname, '{}')); const wasmModule = new WebAssembly.Module(bytes); const wasmInstance = new WebAssembly.Instance(wasmModule, imports); module.exports = wasmInstance.exports; - ", path.file_name().unwrap().to_str().unwrap())); + ", + path.file_name().unwrap().to_str().unwrap() + )); reset_indentation(&shim) } @@ -230,27 +231,25 @@ fn extract_programs(module: &mut Module) -> Result, Error> _ => continue, }; if custom.name() != "__wasm_bindgen_unstable" { - continue + continue; } to_remove.push(i); let mut payload = custom.payload(); while payload.len() > 0 { - let len = - ((payload[0] as usize) << 0) | - ((payload[1] as usize) << 8) | - ((payload[2] as usize) << 16) | - ((payload[3] as usize) << 24); + let len = ((payload[0] as usize) << 0) + | ((payload[1] as usize) << 8) + | ((payload[2] as usize) << 16) + | ((payload[3] as usize) << 24); let (a, b) = payload[4..].split_at(len as usize); payload = b; let p: shared::ProgramOnlySchema = match serde_json::from_slice(&a) { Ok(f) => f, - Err(e) => { - bail!("failed to decode what looked like wasm-bindgen data: {}", e) - } + Err(e) => bail!("failed to decode what looked like wasm-bindgen data: {}", e), }; if p.schema_version != shared::SCHEMA_VERSION { - bail!(" + bail!( + " it looks like the Rust project used to create this wasm file was linked against a different version of wasm-bindgen than this binary: @@ -272,13 +271,13 @@ or you can update the binary with if this warning fails to go away though and you're not sure what to do feel free to open an issue at https://github.com/alexcrichton/wasm-bindgen/issues! ", - p.version, version); + p.version, + version + ); } let p: shared::Program = match serde_json::from_slice(&a) { Ok(f) => f, - Err(e) => { - bail!("failed to decode what looked like wasm-bindgen data: {}", e) - } + Err(e) => bail!("failed to decode what looked like wasm-bindgen data: {}", e), }; ret.push(p); } @@ -297,13 +296,13 @@ impl wasmi::ImportResolver for MyResolver { &self, module_name: &str, field_name: &str, - signature: &wasmi::Signature + signature: &wasmi::Signature, ) -> Result { // Route our special "describe" export to 1 and everything else to 0. // That way whenever the function 1 is invoked we know what to do and // when 0 is invoked (by accident) we'll trap and produce an error. - let idx = (module_name == "__wbindgen_placeholder__" && - field_name == "__wbindgen_describe") as usize; + let idx = (module_name == "__wbindgen_placeholder__" && field_name == "__wbindgen_describe") + as usize; Ok(wasmi::FuncInstance::alloc_host(signature.clone(), idx)) } @@ -311,7 +310,7 @@ impl wasmi::ImportResolver for MyResolver { &self, _module_name: &str, _field_name: &str, - descriptor: &wasmi::GlobalDescriptor + descriptor: &wasmi::GlobalDescriptor, ) -> Result { // dummy implementation to ensure instantiation succeeds let val = match descriptor.value_type() { @@ -340,7 +339,7 @@ impl wasmi::ImportResolver for MyResolver { &self, _module_name: &str, _field_name: &str, - descriptor: &wasmi::TableDescriptor + descriptor: &wasmi::TableDescriptor, ) -> Result { // dummy implementation to ensure instantiation succeeds let initial = descriptor.initial(); @@ -358,7 +357,7 @@ impl wasmi::Externals for MyExternals { fn invoke_index( &mut self, index: usize, - args: wasmi::RuntimeArgs + args: wasmi::RuntimeArgs, ) -> Result, wasmi::Trap> { macro_rules! bail { ($($t:tt)*) => ({ @@ -413,7 +412,12 @@ fn indent_recurse(mut lines: ::std::str::Lines, current_indent: usize) -> String if trimmed.starts_with('?') || trimmed.starts_with(':') { current_indent += 1; } - format!("\n{}{}{}", " ".repeat(current_indent), &trimmed, &indent_recurse(lines, next_indent)) + format!( + "\n{}{}{}", + " ".repeat(current_indent), + &trimmed, + &indent_recurse(lines, next_indent) + ) } else { String::new() } diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index d58b502c..9ab1aeee 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -1,13 +1,13 @@ extern crate base64; extern crate tempfile; -use std::collections::{HashSet, HashMap}; +use std::collections::{HashMap, HashSet}; use std::fs::File; -use std::io::{self, Write, Read}; +use std::io::{self, Read, Write}; use std::process::Command; -use parity_wasm::elements::*; use failure::{Error, ResultExt}; +use parity_wasm::elements::*; pub struct Config { base64: bool, @@ -65,31 +65,36 @@ impl Output { let mut exports = format!("/* tslint:disable */\n"); if let Some(i) = self.module.export_section() { - let imported_functions = self.module.import_section() + let imported_functions = self + .module + .import_section() .map(|m| m.functions() as u32) .unwrap_or(0); for entry in i.entries() { let idx = match *entry.internal() { Internal::Function(i) => i - imported_functions, Internal::Memory(_) => { - exports.push_str(&format!(" + exports.push_str(&format!( + " export const {}: WebAssembly.Memory; - ", entry.field())); - continue - } - Internal::Table(_) => { - continue - } - Internal::Global(_) => { - continue + ", + entry.field() + )); + continue; } + Internal::Table(_) => continue, + Internal::Global(_) => continue, }; - let functions = self.module.function_section() + let functions = self + .module + .function_section() .expect("failed to find function section"); let idx = functions.entries()[idx as usize].type_ref(); - let types = self.module.type_section() + let types = self + .module + .type_section() .expect("failed to find type section"); let ty = match types.types()[idx as usize] { Type::Function(ref f) => f, @@ -103,12 +108,17 @@ impl Output { args.push_str(": number"); } - exports.push_str(&format!(" + exports.push_str(&format!( + " export function {name}({args}): {ret}; ", name = entry.field(), args = args, - ret = if ty.return_type().is_some() { "number" } else { "void" }, + ret = if ty.return_type().is_some() { + "number" + } else { + "void" + }, )); } } @@ -117,7 +127,7 @@ impl Output { exports.push_str("export const booted: Promise;"); } - return exports + return exports; } pub fn js(self) -> Result { @@ -146,19 +156,23 @@ impl Output { } if !set.insert(entry.module()) { - continue + continue; } let name = (b'a' + (set.len() as u8)) as char; - js_imports.push_str(&format!("import * as import_{} from '{}';", - name, - entry.module())); + js_imports.push_str(&format!( + "import * as import_{} from '{}';", + name, + entry.module() + )); imports.push_str(&format!("'{}': import_{}, ", entry.module(), name)); } } if let Some(i) = self.module.export_section() { - let imported_functions = self.module.import_section() + let imported_functions = self + .module + .import_section() .map(|m| m.functions() as u32) .unwrap_or(0); for entry in i.entries() { @@ -166,21 +180,21 @@ impl Output { Internal::Function(i) => i - imported_functions, Internal::Memory(_) => { export_mem = true; - continue - } - Internal::Table(_) => { - continue - } - Internal::Global(_) => { - continue + continue; } + Internal::Table(_) => continue, + Internal::Global(_) => continue, }; - let functions = self.module.function_section() + let functions = self + .module + .function_section() .expect("failed to find function section"); let idx = functions.entries()[idx as usize].type_ref(); - let types = self.module.type_section() + let types = self + .module + .type_section() .expect("failed to find type section"); let ty = match types.types()[idx as usize] { Type::Function(ref f) => f, @@ -193,50 +207,67 @@ impl Output { args.push((b'a' + (i as u8)) as char); } - exports.push_str(&format!(" + exports.push_str(&format!( + " export function {name}({args}) {{ {ret} wasm.exports.{name}({args}); }} ", name = entry.field(), args = args, - ret = if ty.return_type().is_some() { "return" } else { "" }, + ret = if ty.return_type().is_some() { + "return" + } else { + "" + }, )); } } - let inst = format!("WebAssembly.instantiate(bytes,{{ {imports} }}) + let inst = format!( + "WebAssembly.instantiate(bytes,{{ {imports} }}) .then(obj => {{ wasm = obj.instance; {memory} }})", - imports = imports, - memory = if export_mem { "memory = wasm.exports.memory;" } else { "" }, - ); + imports = imports, + memory = if export_mem { + "memory = wasm.exports.memory;" + } else { + "" + }, + ); let (bytes, booted) = if self.base64 { - let wasm = serialize(self.module) - .expect("failed to serialize"); + let wasm = serialize(self.module).expect("failed to serialize"); ( - format!(" + format!( + " let bytes; const base64 = \"{base64}\"; if (typeof Buffer === 'undefined') {{ bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); }} else {{ bytes = Buffer.from(base64, 'base64'); - }}", base64 = base64::encode(&wasm)), - inst + }}", + base64 = base64::encode(&wasm) + ), + inst, ) } else if let Some(ref path) = self.fetch_path { ( String::new(), - format!("fetch('{path}') + format!( + "fetch('{path}') .then(res => res.arrayBuffer()) - .then(bytes => {inst})", path = path, inst = inst) + .then(bytes => {inst})", + path = path, + inst = inst + ), ) } else { bail!("the option --base64 or --fetch is required"); }; - Ok(format!(" + Ok(format!( + " {js_imports} let wasm; {bytes} @@ -273,16 +304,20 @@ impl Output { let m = name_map.entry(entry.field()).or_insert(entry.module()); if *m != entry.module() { - bail!("the name `{}` is imported from two differnet \ - modules which currently isn't supported in `wasm2asm` \ - mode"); + bail!( + "the name `{}` is imported from two differnet \ + modules which currently isn't supported in `wasm2asm` \ + mode" + ); } let name = format!("import{}", i); - js_imports.push_str(&format!("import {{ {} as {} }} from '{}';\n", - entry.field(), - name, - entry.module())); + js_imports.push_str(&format!( + "import {{ {} as {} }} from '{}';\n", + entry.field(), + name, + entry.module() + )); imported_items.push((entry.field().to_string(), name)); } } @@ -298,18 +333,17 @@ impl Output { Internal::Global(_) => continue, }; - js_exports.push_str(&format!("export const {0} = ret.{0};\n", - entry.field())); + js_exports.push_str(&format!("export const {0} = ret.{0};\n", entry.field())); } if !export_mem { - bail!("the `wasm2asm` mode is currently only compatible with \ - modules that export memory") + bail!( + "the `wasm2asm` mode is currently only compatible with \ + modules that export memory" + ) } } - let memory_size = self.module.memory_section() - .unwrap() - .entries()[0] + let memory_size = self.module.memory_section().unwrap().entries()[0] .limits() .initial(); @@ -329,9 +363,7 @@ impl Output { }; let base64 = base64::encode(entry.value()); - js_init_mem.push_str(&format!("_assign({}, \"{}\");\n", - offset, - base64)); + js_init_mem.push_str(&format!("_assign({}, \"{}\");\n", offset, base64)); } } @@ -340,9 +372,7 @@ impl Output { let wasm_file = td.as_ref().join("foo.wasm"); File::create(&wasm_file) .and_then(|mut f| f.write_all(&wasm)) - .with_context(|_| { - format!("failed to write wasm to `{}`", wasm_file.display()) - })?; + .with_context(|_| format!("failed to write wasm to `{}`", wasm_file.display()))?; let wast_file = td.as_ref().join("foo.wast"); run( @@ -364,19 +394,19 @@ impl Output { let mut asm_func = String::new(); File::open(&js_file) .and_then(|mut f| f.read_to_string(&mut asm_func)) - .with_context(|_| { - format!("failed to read `{}`", js_file.display()) - })?; + .with_context(|_| format!("failed to read `{}`", js_file.display()))?; - - let mut make_imports = String::from(" + let mut make_imports = String::from( + " var imports = {}; - "); + ", + ); for (name, import) in imported_items { make_imports.push_str(&format!("imports['{}'] = {};\n", name, import)); } - Ok(format!("\ + Ok(format!( + "\ {js_imports} {asm_func} @@ -424,28 +454,31 @@ impl Output { fn run(cmd: &mut Command, program: &str) -> Result<(), Error> { let output = cmd.output().with_context(|e| { if e.kind() == io::ErrorKind::NotFound { - format!("failed to execute `{}`, is the tool installed \ - from the binaryen project?\ncommand line: {:?}", - program, - cmd) + format!( + "failed to execute `{}`, is the tool installed \ + from the binaryen project?\ncommand line: {:?}", + program, cmd + ) } else { format!("failed to execute: {:?}", cmd) } })?; if output.status.success() { - return Ok(()) + return Ok(()); } - let mut s = format!("failed to execute: {:?}\nstatus: {}\n", - cmd, - output.status); + let mut s = format!("failed to execute: {:?}\nstatus: {}\n", cmd, output.status); if !output.stdout.is_empty() { - s.push_str(&format!("----- stdout ------\n{}\n", - String::from_utf8_lossy(&output.stdout))); + s.push_str(&format!( + "----- stdout ------\n{}\n", + String::from_utf8_lossy(&output.stdout) + )); } if !output.stderr.is_empty() { - s.push_str(&format!("----- stderr ------\n{}\n", - String::from_utf8_lossy(&output.stderr))); + s.push_str(&format!( + "----- stderr ------\n{}\n", + String::from_utf8_lossy(&output.stderr) + )); } bail!("{}", s) } diff --git a/crates/cli/src/bin/wasm-bindgen.rs b/crates/cli/src/bin/wasm-bindgen.rs index 3dd4bfd4..606a3fee 100644 --- a/crates/cli/src/bin/wasm-bindgen.rs +++ b/crates/cli/src/bin/wasm-bindgen.rs @@ -10,8 +10,8 @@ use std::path::PathBuf; use std::process; use docopt::Docopt; -use wasm_bindgen_cli_support::Bindgen; use failure::Error; +use wasm_bindgen_cli_support::Bindgen; const USAGE: &'static str = " Generating JS bindings for a wasm file diff --git a/crates/cli/src/bin/wasm2es6js.rs b/crates/cli/src/bin/wasm2es6js.rs index 4178d8a2..736c9b55 100644 --- a/crates/cli/src/bin/wasm2es6js.rs +++ b/crates/cli/src/bin/wasm2es6js.rs @@ -1,12 +1,12 @@ #[macro_use] extern crate serde_derive; extern crate docopt; +extern crate failure; extern crate parity_wasm; extern crate wasm_bindgen_cli_support; -extern crate failure; use std::fs::File; -use std::io::{Write, Read}; +use std::io::{Read, Write}; use std::path::PathBuf; use std::process; @@ -76,9 +76,7 @@ fn rmain(args: &Args) -> Result<(), Error> { let ts = object.typescript(); File::create(&dst) .and_then(|mut f| f.write_all(ts.as_bytes())) - .with_context(|_| { - format!("failed to write `{}`", dst.display()) - })?; + .with_context(|_| format!("failed to write `{}`", dst.display()))?; } } diff --git a/crates/macro/src/lib.rs b/crates/macro/src/lib.rs index d37412e4..c53c8c45 100755 --- a/crates/macro/src/lib.rs +++ b/crates/macro/src/lib.rs @@ -1,9 +1,9 @@ #![feature(proc_macro)] -extern crate syn; -extern crate quote; extern crate proc_macro; extern crate proc_macro2; +extern crate quote; +extern crate syn; extern crate wasm_bindgen_backend as backend; use proc_macro::TokenStream; diff --git a/crates/typescript/src/definitions.rs b/crates/typescript/src/definitions.rs index 11a55694..6530946d 100644 --- a/crates/typescript/src/definitions.rs +++ b/crates/typescript/src/definitions.rs @@ -26,7 +26,6 @@ pub(crate) enum TsExport { #[serde(rename = "returnValue")] return_value: TsReturnValue, }, - //TODO: implement ... //{ "$ref": "#/definitions/interfaceApiItem" }, //{ "$ref": "#/definitions/namespaceApiItem" }, diff --git a/crates/typescript/src/lib.rs b/crates/typescript/src/lib.rs index 10f9c15b..0cfd591e 100644 --- a/crates/typescript/src/lib.rs +++ b/crates/typescript/src/lib.rs @@ -1,6 +1,7 @@ extern crate proc_macro2; extern crate serde; -#[macro_use] extern crate serde_derive; +#[macro_use] +extern crate serde_derive; extern crate serde_json; extern crate syn; extern crate wasm_bindgen_backend as backend; diff --git a/crates/typescript/src/parser.rs b/crates/typescript/src/parser.rs index cc765542..0421e551 100644 --- a/crates/typescript/src/parser.rs +++ b/crates/typescript/src/parser.rs @@ -2,11 +2,11 @@ use std::collections::HashMap; use std::fs::File; use std::io::Read; -use backend::{self}; +use backend; use backend::ast::{BindgenAttrs, Export, Function}; -use proc_macro2::{self}; -use serde_json::{self}; -use syn::{self}; +use proc_macro2; +use serde_json; +use syn; use api_extractor; use definitions::*; @@ -25,7 +25,11 @@ pub fn ts_to_program(file_name: &str) -> backend::ast::Program { match member { TsClassMembers::TsProperty { .. } => {} TsClassMembers::TsConstructor { .. } => {} - TsClassMembers::TsMethod { parameters, return_value, .. } => { + TsClassMembers::TsMethod { + parameters, + return_value, + .. + } => { let function = build_function(member_name, parameters, return_value); program.exports.push(Export { @@ -33,14 +37,17 @@ pub fn ts_to_program(file_name: &str) -> backend::ast::Program { method: true, mutable: false, constructor: None, - function, + function, }); } } } } - TsExport::TsFunction { parameters, return_value } => { + TsExport::TsFunction { + parameters, + return_value, + } => { let function = build_function(name, parameters, return_value); program.exports.push(Export { @@ -65,22 +72,29 @@ fn parse_json(file_name: &str) -> TsPackage { serde_json::from_str(&data).unwrap() } -fn build_function(name: String, parameters: HashMap, return_value: TsReturnValue) -> Function { - let arguments = parameters.iter().map( |(_name, property)| { - let mut segments = syn::punctuated::Punctuated::new(); - segments.push(syn::PathSegment { - ident: syn::Ident::new(&property.property_type, proc_macro2::Span::call_site()), - arguments: syn::PathArguments::None, - }); +fn build_function( + name: String, + parameters: HashMap, + return_value: TsReturnValue, +) -> Function { + let arguments = parameters + .iter() + .map(|(_name, property)| { + let mut segments = syn::punctuated::Punctuated::new(); + segments.push(syn::PathSegment { + ident: syn::Ident::new(&property.property_type, proc_macro2::Span::call_site()), + arguments: syn::PathArguments::None, + }); - syn::Type::Path(syn::TypePath { - qself: None, - path: syn::Path { - leading_colon: None, - segments, - } + syn::Type::Path(syn::TypePath { + qself: None, + path: syn::Path { + leading_colon: None, + segments, + }, + }) }) - }).collect::>(); + .collect::>(); let mut ret_segments = syn::punctuated::Punctuated::new(); ret_segments.push(syn::PathSegment { @@ -93,7 +107,7 @@ fn build_function(name: String, parameters: HashMap, r path: syn::Path { leading_colon: None, segments: ret_segments, - } + }, }); let rust_decl = Box::new(syn::FnDecl { diff --git a/examples/asm.js/src/lib.rs b/examples/asm.js/src/lib.rs index 076139d3..c5a4eae2 100644 --- a/examples/asm.js/src/lib.rs +++ b/examples/asm.js/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } diff --git a/examples/char/src/lib.rs b/examples/char/src/lib.rs index b15d0ed3..915ccd35 100644 --- a/examples/char/src/lib.rs +++ b/examples/char/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } @@ -14,7 +14,7 @@ extern { #[wasm_bindgen] pub struct Counter { key: char, - count: i32 + count: i32, } #[wasm_bindgen] @@ -25,7 +25,10 @@ impl Counter { } pub fn new(key: char, count: i32) -> Counter { log(&format!("Counter::new({}, {})", key, count)); - Counter { key: key, count: count } + Counter { + key: key, + count: count, + } } pub fn key(&self) -> char { @@ -46,4 +49,4 @@ impl Counter { pub fn update_key(&mut self, key: char) { self.key = key; } -} \ No newline at end of file +} diff --git a/examples/closures/src/lib.rs b/examples/closures/src/lib.rs index de4b04ea..3c32e438 100644 --- a/examples/closures/src/lib.rs +++ b/examples/closures/src/lib.rs @@ -2,12 +2,12 @@ extern crate wasm_bindgen; -use wasm_bindgen::prelude::*; use wasm_bindgen::js::Date; use wasm_bindgen::js::JsString; +use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { // Binding for the `setInverval` method in JS. This function takes a "long // lived" closure as the first argument so we use `Closure` instead of // a bare `&Fn()` which only surives for that one stack frame. @@ -51,12 +51,11 @@ pub fn run() { set_interval(&a, 1000); update_time(); fn update_time() { - document.get_element_by_id("current-time") - .set_inner_html( - &String::from( - Date::new() - .to_locale_string( - JsString::from("en-GB"), JsValue::undefined()))); + document + .get_element_by_id("current-time") + .set_inner_html(&String::from( + Date::new().to_locale_string(JsString::from("en-GB"), JsValue::undefined()), + )); } // We also want to count the number of times that our green square has been @@ -65,7 +64,8 @@ pub fn run() { let mut clicks = 0; let b = Closure::new(move || { clicks += 1; - document.get_element_by_id("num-clicks") + document + .get_element_by_id("num-clicks") .set_inner_html(&clicks.to_string()); }); square.set_onclick(&b); @@ -84,10 +84,12 @@ pub fn run() { // And finally now that our demo is ready to go let's switch things up so // everything is displayed and our loading prompt is hidden. - document.get_html_element_by_id("loading") + document + .get_html_element_by_id("loading") .style() .set_display("none"); - document.get_html_element_by_id("script") + document + .get_html_element_by_id("script") .style() .set_display("block"); } diff --git a/examples/comments/src/lib.rs b/examples/comments/src/lib.rs index aaabd7e1..7f680b2e 100644 --- a/examples/comments/src/lib.rs +++ b/examples/comments/src/lib.rs @@ -15,7 +15,6 @@ pub struct Comment { color: Color, } - #[wasm_bindgen] impl Comment { #[wasm_bindgen(method)] @@ -57,4 +56,4 @@ impl Comment { pub enum Color { Blue, Pink, -} \ No newline at end of file +} diff --git a/examples/console_log/src/lib.rs b/examples/console_log/src/lib.rs index 27a203dd..7330b8fa 100644 --- a/examples/console_log/src/lib.rs +++ b/examples/console_log/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); #[wasm_bindgen(js_namespace = console, js_name = log)] diff --git a/examples/dom/src/lib.rs b/examples/dom/src/lib.rs index 5fd85916..de953406 100644 --- a/examples/dom/src/lib.rs +++ b/examples/dom/src/lib.rs @@ -15,7 +15,7 @@ use wasm_bindgen::prelude::*; // In the meantime these are written out by hand and correspond to the names and // signatures documented on MDN, for example #[wasm_bindgen] -extern { +extern "C" { type HTMLDocument; static document: HTMLDocument; #[wasm_bindgen(method)] diff --git a/examples/hello_world/src/lib.rs b/examples/hello_world/src/lib.rs index 6a83b6bf..bd53db52 100644 --- a/examples/hello_world/src/lib.rs +++ b/examples/hello_world/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { fn alert(s: &str); } diff --git a/examples/import_js/src/lib.rs b/examples/import_js/src/lib.rs index 43697899..91f4864c 100644 --- a/examples/import_js/src/lib.rs +++ b/examples/import_js/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen(module = "./defined-in-js")] -extern { +extern "C" { fn name() -> String; type MyClass; @@ -23,7 +23,7 @@ extern { // Import `console.log` so we can log something to the console #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_namespace = console)] fn log(s: &str); } diff --git a/examples/math/src/lib.rs b/examples/math/src/lib.rs index d970aa0c..f187484a 100644 --- a/examples/math/src/lib.rs +++ b/examples/math/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_namespace = Math)] fn log2(a: f64) -> f64; #[wasm_bindgen(js_namespace = Math)] diff --git a/examples/no_modules/src/lib.rs b/examples/no_modules/src/lib.rs index 6a83b6bf..bd53db52 100644 --- a/examples/no_modules/src/lib.rs +++ b/examples/no_modules/src/lib.rs @@ -5,7 +5,7 @@ extern crate wasm_bindgen; use wasm_bindgen::prelude::*; #[wasm_bindgen] -extern { +extern "C" { fn alert(s: &str); } diff --git a/examples/performance/src/lib.rs b/examples/performance/src/lib.rs index 612bf51f..256fb76f 100644 --- a/examples/performance/src/lib.rs +++ b/examples/performance/src/lib.rs @@ -1,7 +1,7 @@ #![feature(proc_macro, wasm_custom_section, wasm_import_module)] -extern crate wasm_bindgen; extern crate humantime; +extern crate wasm_bindgen; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -10,7 +10,7 @@ use wasm_bindgen::prelude::*; // Like with the `dom` example this block will eventually be auto-generated, but // for now we can write it by hand to get by! #[wasm_bindgen] -extern { +extern "C" { type Performance; static performance: Performance; #[wasm_bindgen(method)] diff --git a/examples/smorgasboard/src/lib.rs b/examples/smorgasboard/src/lib.rs index d73cc566..942584b8 100644 --- a/examples/smorgasboard/src/lib.rs +++ b/examples/smorgasboard/src/lib.rs @@ -7,10 +7,10 @@ use wasm_bindgen::prelude::*; // Strings can both be passed in and received #[wasm_bindgen] #[no_mangle] -pub extern fn concat(a: &str, b: &str) -> String { +pub extern "C" fn concat(a: &str, b: &str) -> String { let mut a = a.to_string(); a.push_str(b); - return a + return a; } // A struct will show up as a class on the JS side of things @@ -29,7 +29,7 @@ impl Foo { // can pass to a normal free function also all work in methods. pub fn add(&mut self, amt: u32) -> u32 { self.contents += amt; - return self.contents + return self.contents; } // You can also take a limited set of references to other types as well. @@ -50,7 +50,7 @@ pub struct Bar { } #[wasm_bindgen(module = "./awesome")] // what ES6 module to import from -extern { +extern "C" { fn bar_on_reset(to: &str, opaque: &JsValue); // We can import classes and annotate functionality on those classes as well @@ -64,9 +64,7 @@ extern { #[wasm_bindgen] impl Bar { pub fn from_str(s: &str, opaque: JsValue) -> Bar { - let contents = s.parse().unwrap_or_else(|_| { - Awesome::new().get_internal() - }); + let contents = s.parse().unwrap_or_else(|_| Awesome::new().get_internal()); Bar { contents, opaque } } diff --git a/examples/wasm-in-wasm/src/lib.rs b/examples/wasm-in-wasm/src/lib.rs index 3cd6304a..1fa27a84 100644 --- a/examples/wasm-in-wasm/src/lib.rs +++ b/examples/wasm-in-wasm/src/lib.rs @@ -7,7 +7,7 @@ use wasm_bindgen::prelude::*; // Like with the `dom` example this block will eventually be auto-generated, but // for now we can write it by hand to get by! #[wasm_bindgen] -extern { +extern "C" { type Module; #[wasm_bindgen(constructor, js_namespace = WebAssembly)] fn new(data: &[u8]) -> Module; diff --git a/src/convert.rs b/src/convert.rs index d7afeec1..c73a553f 100644 --- a/src/convert.rs +++ b/src/convert.rs @@ -1,14 +1,14 @@ //! This is mostly an internal module, no stability guarantees are provided. Use //! at your own risk. +use core::char; use core::mem::{self, ManuallyDrop}; use core::ops::{Deref, DerefMut}; use core::slice; use core::str; -use core::char; -use {JsValue, throw}; use describe::*; +use {throw, JsValue}; #[cfg(feature = "std")] use std::prelude::v1::*; @@ -59,7 +59,7 @@ pub trait RefFromWasmAbi: WasmDescribe { /// invocation of the function that has an `&Self` parameter. This is /// required to ensure that the lifetimes don't persist beyond one function /// call, and so that they remain anonymous. - type Anchor: Deref; + type Anchor: Deref; /// Recover a `Self::Anchor` from `Self::Abi`. /// @@ -71,7 +71,7 @@ pub trait RefFromWasmAbi: WasmDescribe { pub trait RefMutFromWasmAbi: WasmDescribe { type Abi: WasmAbi; - type Anchor: DerefMut; + type Anchor: DerefMut; unsafe fn ref_mut_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor; } @@ -159,18 +159,24 @@ as_u32!(i8 u8 i16 u16 isize usize); impl IntoWasmAbi for bool { type Abi = u32; - fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } + fn into_abi(self, _extra: &mut Stack) -> u32 { + self as u32 + } } impl FromWasmAbi for bool { type Abi = u32; - unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool { js != 0 } + unsafe fn from_abi(js: u32, _extra: &mut Stack) -> bool { + js != 0 + } } impl IntoWasmAbi for char { type Abi = u32; - fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } + fn into_abi(self, _extra: &mut Stack) -> u32 { + self as u32 + } } impl FromWasmAbi for char { @@ -183,7 +189,9 @@ impl FromWasmAbi for char { impl IntoWasmAbi for *const T { type Abi = u32; - fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } + fn into_abi(self, _extra: &mut Stack) -> u32 { + self as u32 + } } impl FromWasmAbi for *const T { @@ -197,7 +205,9 @@ impl FromWasmAbi for *const T { impl IntoWasmAbi for *mut T { type Abi = u32; - fn into_abi(self, _extra: &mut Stack) -> u32 { self as u32 } + fn into_abi(self, _extra: &mut Stack) -> u32 { + self as u32 + } } impl FromWasmAbi for *mut T { @@ -343,7 +353,7 @@ impl IntoWasmAbi for JsValue { fn into_abi(self, _extra: &mut Stack) -> u32 { let ret = self.idx; mem::forget(self); - return ret + return ret; } } @@ -397,7 +407,9 @@ if_std! { } } -pub struct GlobalStack { next: usize } +pub struct GlobalStack { + next: usize, +} const GLOBAL_STACK_CAP: usize = 16; static mut GLOBAL_STACK: [u32; GLOBAL_STACK_CAP] = [0; GLOBAL_STACK_CAP]; @@ -429,7 +441,7 @@ impl Stack for GlobalStack { #[doc(hidden)] #[no_mangle] -pub unsafe extern fn __wbindgen_global_argument_ptr() -> *mut u32 { +pub unsafe extern "C" fn __wbindgen_global_argument_ptr() -> *mut u32 { GLOBAL_STACK.as_mut_ptr() } diff --git a/src/describe.rs b/src/describe.rs index bc98c980..b88438f2 100644 --- a/src/describe.rs +++ b/src/describe.rs @@ -41,9 +41,7 @@ tys! { } pub fn inform(a: u32) { - unsafe { - super::__wbindgen_describe(a) - } + unsafe { super::__wbindgen_describe(a) } } pub trait WasmDescribe { @@ -78,11 +76,15 @@ simple! { } impl WasmDescribe for *const T { - fn describe() { inform(I32) } + fn describe() { + inform(I32) + } } impl WasmDescribe for *mut T { - fn describe() { inform(I32) } + fn describe() { + inform(I32) + } } impl WasmDescribe for [T] { @@ -127,7 +129,9 @@ if_std! { } } -fn _cnt() -> u32 { 1 } +fn _cnt() -> u32 { + 1 +} macro_rules! doit { ($( ($($var:ident)*))*) => ($( diff --git a/src/js.rs b/src/js.rs index fd16b23e..9c6d8c1d 100644 --- a/src/js.rs +++ b/src/js.rs @@ -41,7 +41,7 @@ if_std! { // for that case. #[wasm_bindgen] -extern { +extern "C" { /// The `decodeURI()` function decodes a Uniform Resource Identifier (URI) /// previously created by `encodeURI` or by a similar routine. /// @@ -68,7 +68,7 @@ extern { // UInt8Array #[wasm_bindgen] -extern { +extern "C" { pub type Uint8Array; /// The `Uint8Array()` constructor creates an array of unsigned 8-bit integers. @@ -87,7 +87,7 @@ extern { // Array #[wasm_bindgen] -extern { +extern "C" { pub type Array; /// The copyWithin() method shallow copies part of an array to another @@ -106,7 +106,7 @@ extern { /// The every() method tests whether all elements in the array pass the test /// implemented by the provided function. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every #[wasm_bindgen(method)] pub fn every(this: &Array, predicate: &mut FnMut(JsValue, u32, Array) -> bool) -> bool; @@ -233,7 +233,7 @@ extern { // Array Iterator #[wasm_bindgen] -extern { +extern "C" { pub type ArrayIterator; /// The keys() method returns a new Array Iterator object that contains the @@ -253,7 +253,7 @@ extern { // Boolean #[wasm_bindgen] -extern { +extern "C" { pub type Boolean; /// The `Boolean()` constructor creates an object wrapper for a boolean value. @@ -271,12 +271,12 @@ extern { // Function #[wasm_bindgen] -extern { +extern "C" { pub type Function; /// The apply() method calls a function with a given this value, and arguments provided as an array /// (or an array-like object). - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply #[wasm_bindgen(method)] pub fn apply(this: &Function, context: &JsValue, args: &Array) -> Function; @@ -296,7 +296,7 @@ extern { pub fn name(this: &Function) -> JsString; /// The toString() method returns a string representing the source code of the function. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString #[wasm_bindgen(method, js_name = toString)] pub fn to_string(this: &Function) -> JsString; @@ -304,7 +304,7 @@ extern { // Math #[wasm_bindgen] -extern { +extern "C" { pub type Math; /// The Math.abs() function returns the absolute value of a number, that is /// Math.abs(x) = |x| @@ -365,7 +365,6 @@ extern { #[wasm_bindgen(static_method_of = Math)] pub fn atanh(x: i32) -> Number; - /// The Math.cbrt() function returns the cube root of a number, that is /// Math.cbrt(x) = x^3 = the unique y such that y^3 = x /// @@ -397,7 +396,7 @@ extern { // Number. #[wasm_bindgen] -extern { +extern "C" { pub type Number; /// The toLocaleString() method returns a string with a language sensitive @@ -445,35 +444,35 @@ extern { // Date. #[wasm_bindgen] -extern { +extern "C" { pub type Date; - /// Creates a JavaScript Date instance that represents - /// a single moment in time. Date objects are based on a time value that is + /// Creates a JavaScript Date instance that represents + /// a single moment in time. Date objects are based on a time value that is /// the number of milliseconds since 1 January 1970 UTC. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date #[wasm_bindgen(constructor)] pub fn new() -> Date; /// The toDateString() method returns the date portion of a Date object /// in human readable form in American English. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toDateString #[wasm_bindgen(method, js_name = toDateString)] pub fn to_date_string(this: &Date) -> JsString; /// The toISOString() method returns a string in simplified extended ISO format (ISO /// 8601), which is always 24 or 27 characters long (YYYY-MM-DDTHH:mm:ss.sssZ or - /// ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, + /// ±YYYYYY-MM-DDTHH:mm:ss.sssZ, respectively). The timezone is always zero UTC offset, /// as denoted by the suffix "Z" - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString #[wasm_bindgen(method, js_name = toISOString)] pub fn to_iso_string(this: &Date) -> JsString; /// The toJSON() method returns a string representation of the Date object. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON #[wasm_bindgen(method, js_name = toJSON)] pub fn to_json(this: &Date) -> JsString; @@ -485,17 +484,17 @@ extern { /// In older implementations, which ignore the locales and options arguments, /// the locale used and the form of the string /// returned are entirely implementation dependent. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString #[wasm_bindgen(method, js_name = toLocaleDateString)] pub fn to_locale_date_string(this: &Date, locale: JsString, options: JsValue) -> JsString; - /// The toLocaleString() method returns a string with a language sensitive - /// representation of this date. The new locales and options arguments - /// let applications specify the language whose formatting conventions - /// should be used and customize the behavior of the function. - /// In older implementations, which ignore the locales - /// and options arguments, the locale used and the form of the string + /// The toLocaleString() method returns a string with a language sensitive + /// representation of this date. The new locales and options arguments + /// let applications specify the language whose formatting conventions + /// should be used and customize the behavior of the function. + /// In older implementations, which ignore the locales + /// and options arguments, the locale used and the form of the string /// returned are entirely implementation dependent. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString @@ -544,7 +543,7 @@ extern { // Object. #[wasm_bindgen] -extern { +extern "C" { pub type Object; /// The `hasOwnProperty()` method returns a boolean indicating whether the @@ -585,7 +584,7 @@ extern { /// The Object.seal() method seals an object, preventing new properties /// from being added to it and marking all existing properties as non-configurable. /// Values of present properties can still be changed as long as they are writable. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal #[wasm_bindgen(static_method_of = Object)] pub fn seal(value: &JsValue) -> JsValue; @@ -614,7 +613,7 @@ extern { // WeakMap #[wasm_bindgen] -extern { +extern "C" { pub type WeakMap; /// The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced. @@ -624,21 +623,21 @@ extern { #[wasm_bindgen(constructor)] pub fn new() -> WeakMap; - /// The set() method sets the value for the key in the WeakMap object. Returns + /// The set() method sets the value for the key in the WeakMap object. Returns /// the WeakMap object. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set - #[wasm_bindgen(method, js_class="WeakMap")] + #[wasm_bindgen(method, js_class = "WeakMap")] pub fn set(this: &WeakMap, key: Object, value: JsValue) -> WeakMap; - /// The get() method returns a specified by key element + /// The get() method returns a specified by key element /// from a WeakMap object. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/get #[wasm_bindgen(method)] pub fn get(this: &WeakMap, key: Object) -> JsValue; - /// The has() method returns a boolean indicating whether an element with + /// The has() method returns a boolean indicating whether an element with /// the specified key exists in the WeakMap object or not. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/has @@ -654,29 +653,29 @@ extern { // WeakSet #[wasm_bindgen] -extern { +extern "C" { pub type WeakSet; /// The WeakSet object lets you store weakly held objects in a collection. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet #[wasm_bindgen(constructor)] pub fn new() -> WeakSet; /// The has() method returns a boolean indicating whether an object exists in a WeakSet or not. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/has #[wasm_bindgen(method)] pub fn has(this: &WeakSet, value: Object) -> bool; /// The add() method appends a new object to the end of a WeakSet object. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/add #[wasm_bindgen(method)] pub fn add(this: &WeakSet, value: Object) -> WeakSet; /// The delete() method removes the specified element from a WeakSet object. - /// + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/delete #[wasm_bindgen(method)] pub fn delete(this: &WeakSet, value: Object) -> bool; @@ -684,7 +683,7 @@ extern { // JsString #[wasm_bindgen] -extern { +extern "C" { #[wasm_bindgen(js_name = JsString)] pub type JsString; @@ -737,7 +736,7 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf #[wasm_bindgen(method, js_class = "String", js_name = indexOf)] pub fn index_of(this: &JsString, search_value: &JsString, from_index: i32) -> i32; - + /// The slice() method extracts a section of a string and returns it as a /// new string, without modifying the original string. /// diff --git a/src/lib.rs b/src/lib.rs index c1f3b266..5049e9e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -76,16 +76,18 @@ const JSIDX_RESERVED: u32 = 8; impl JsValue { /// The `null` JS value constant. - pub const NULL: JsValue = JsValue { idx: JSIDX_NULL }; + pub const NULL: JsValue = JsValue { idx: JSIDX_NULL }; /// The `undefined` JS value constant. - pub const UNDEFINED: JsValue = JsValue { idx: JSIDX_UNDEFINED }; + pub const UNDEFINED: JsValue = JsValue { + idx: JSIDX_UNDEFINED, + }; /// The `true` JS value constant. - pub const TRUE: JsValue = JsValue { idx: JSIDX_TRUE }; + pub const TRUE: JsValue = JsValue { idx: JSIDX_TRUE }; /// The `false` JS value constant. - pub const FALSE: JsValue = JsValue { idx: JSIDX_FALSE }; + pub const FALSE: JsValue = JsValue { idx: JSIDX_FALSE }; /// Creates a new JS value which is a string. /// @@ -93,7 +95,9 @@ impl JsValue { /// be owned by the JS garbage collector. pub fn from_str(s: &str) -> JsValue { unsafe { - JsValue { idx: __wbindgen_string_new(s.as_ptr(), s.len()) } + JsValue { + idx: __wbindgen_string_new(s.as_ptr(), s.len()), + } } } @@ -103,7 +107,9 @@ impl JsValue { /// allocated number) and returns a handle to the JS version of it. pub fn from_f64(n: f64) -> JsValue { unsafe { - JsValue { idx: __wbindgen_number_new(n) } + JsValue { + idx: __wbindgen_number_new(n), + } } } @@ -112,12 +118,16 @@ impl JsValue { /// This function creates a JS object representing a boolean (a heap /// allocated boolean) and returns a handle to the JS version of it. pub fn from_bool(b: bool) -> JsValue { - JsValue { idx: if b { JSIDX_TRUE } else { JSIDX_FALSE } } + JsValue { + idx: if b { JSIDX_TRUE } else { JSIDX_FALSE }, + } } /// Creates a new JS value representing `undefined`. pub fn undefined() -> JsValue { - JsValue { idx: JSIDX_UNDEFINED } + JsValue { + idx: JSIDX_UNDEFINED, + } } /// Creates a new JS value representing `null`. @@ -133,7 +143,9 @@ impl JsValue { unsafe { let ptr = description.map(|s| s.as_ptr()).unwrap_or(ptr::null()); let len = description.map(|s| s.len()).unwrap_or(0); - JsValue { idx: __wbindgen_symbol_new(ptr, len) } + JsValue { + idx: __wbindgen_symbol_new(ptr, len), + } } } @@ -154,7 +166,8 @@ impl JsValue { /// Returns any error encountered when serializing `T` into JSON. #[cfg(feature = "serde-serialize")] pub fn from_serde(t: &T) -> serde_json::Result - where T: serde::ser::Serialize + ?Sized, + where + T: serde::ser::Serialize + ?Sized, { let s = serde_json::to_string(t)?; unsafe { @@ -179,7 +192,8 @@ impl JsValue { /// Returns any error encountered when parsing the JSON into a `T`. #[cfg(feature = "serde-serialize")] pub fn into_serde(&self) -> serde_json::Result - where T: for<'a> serde::de::Deserialize<'a>, + where + T: for<'a> serde::de::Deserialize<'a>, { unsafe { let mut ptr = ptr::null_mut(); @@ -243,31 +257,23 @@ impl JsValue { /// Tests whether this JS value is `null` pub fn is_null(&self) -> bool { - unsafe { - __wbindgen_is_null(self.idx) == 1 - } + unsafe { __wbindgen_is_null(self.idx) == 1 } } /// Tests whether this JS value is `undefined` pub fn is_undefined(&self) -> bool { - unsafe { - __wbindgen_is_undefined(self.idx) == 1 - } + unsafe { __wbindgen_is_undefined(self.idx) == 1 } } /// Tests whether the type of this JS value is `symbol` pub fn is_symbol(&self) -> bool { - unsafe { - __wbindgen_is_symbol(self.idx) == 1 - } + unsafe { __wbindgen_is_symbol(self.idx) == 1 } } } impl PartialEq for JsValue { fn eq(&self, other: &JsValue) -> bool { - unsafe { - __wbindgen_jsval_eq(self.idx, other.idx) != 0 - } + unsafe { __wbindgen_jsval_eq(self.idx, other.idx) != 0 } } } @@ -421,7 +427,7 @@ impl Deref for JsStatic { // `JsStatic` a bit as well. let ptr = self.__inner.get(); if let Some(ref t) = *ptr { - return t + return t; } let init = Some((self.__init)()); debug_assert!((*ptr).is_none()); @@ -455,7 +461,7 @@ pub mod __rt { #[macro_export] #[cfg(feature = "std")] macro_rules! __wbindgen_if_not_std { - ($($i:item)*) => () + ($($i:item)*) => {}; } #[macro_export] @@ -500,7 +506,10 @@ pub mod __rt { } impl WasmRefCell { - pub fn new(value: T) -> WasmRefCell where T: Sized { + pub fn new(value: T) -> WasmRefCell + where + T: Sized, + { WasmRefCell { value: UnsafeCell::new(value), borrow: Cell::new(0), @@ -508,9 +517,7 @@ pub mod __rt { } pub fn get_mut(&mut self) -> &mut T { - unsafe { - &mut *self.value.get() - } + unsafe { &mut *self.value.get() } } pub fn borrow(&self) -> Ref { @@ -539,7 +546,10 @@ pub mod __rt { } } - pub fn into_inner(self) -> T where T: Sized { + pub fn into_inner(self) -> T + where + T: Sized, + { self.value.into_inner() } } @@ -592,8 +602,10 @@ pub mod __rt { } fn borrow_fail() -> ! { - super::throw("recursive use of an object detected which would lead to \ - unsafe aliasing in rust"); + super::throw( + "recursive use of an object detected which would lead to \ + unsafe aliasing in rust", + ); } if_std! { diff --git a/tests/all/api.rs b/tests/all/api.rs index a385a46d..87f8d133 100644 --- a/tests/all/api.rs +++ b/tests/all/api.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -108,8 +110,11 @@ fn works() { pub fn acquire_string2(a: &JsValue) -> String { a.as_string().unwrap_or("wrong".to_string()) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -138,14 +143,17 @@ fn works() { assert.strictEqual(wasm.acquire_string2(''), ''); assert.strictEqual(wasm.acquire_string2('a'), 'a'); } - "#) + "#, + ) .test(); } #[test] fn eq_works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -161,8 +169,11 @@ fn eq_works() { pub fn test1(a: &JsValue) -> bool { a == a } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -176,7 +187,7 @@ fn eq_works() { assert.strictEqual(wasm.test(x, x), true); assert.strictEqual(wasm.test1(x), true); } - "#) + "#, + ) .test(); } - diff --git a/tests/all/char.rs b/tests/all/char.rs index ce4fb7dd..5e330701 100644 --- a/tests/all/char.rs +++ b/tests/all/char.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -30,8 +32,11 @@ fn works() { #[wasm_bindgen] pub fn char_round(c: char)-> char { js_parrot(c) } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" import * as wasm from './out'; function assertEq(a, b) { @@ -55,6 +60,7 @@ fn works() { } export function js_parrot(a) { return a; } - "#) + "#, + ) .test(); } diff --git a/tests/all/classes.rs b/tests/all/classes.rs index 8188c5fb..5946af2d 100644 --- a/tests/all/classes.rs +++ b/tests/all/classes.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn simple() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -31,8 +33,11 @@ fn simple() { self.contents } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import { Foo } from "./out"; @@ -53,14 +58,17 @@ fn simple() { assert.strictEqual(r3.add(42), 42); r3.free(); } - "#) + "#, + ) .test(); } #[test] fn strings() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -98,8 +106,11 @@ fn strings() { self.contents.clone() } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import { Foo } from "./out"; @@ -111,14 +122,17 @@ fn strings() { assert.strictEqual(bar.name(), "foo-baz-3"); bar.free(); } - "#) + "#, + ) .test(); } #[test] fn exceptions() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -152,8 +166,11 @@ fn exceptions() { B {} } } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" import * as assert from "assert"; import { A, B } from "./out"; @@ -173,17 +190,23 @@ fn exceptions() { d.free(); c.free(); }; - "#) - .file("test.d.ts", r#" + "#, + ) + .file( + "test.d.ts", + r#" export function test(): void; - "#) + "#, + ) .test(); } #[test] fn pass_one_to_another() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -215,8 +238,11 @@ fn pass_one_to_another() { B {} } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { A, B } from "./out"; export function test() { @@ -226,14 +252,17 @@ fn pass_one_to_another() { a.bar(b); a.free(); } - "#) + "#, + ) .test(); } #[test] fn pass_into_js() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -259,8 +288,11 @@ fn pass_into_js() { pub fn run() { take_foo(Foo(13)); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run, Foo } from "./out"; import * as assert from "assert"; @@ -273,14 +305,17 @@ fn pass_into_js() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn issue_27() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -309,21 +344,27 @@ fn issue_27() { pub fn context() -> Context { Context {} } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { context } from "./out"; export function test() { context(); } - "#) + "#, + ) .test(); } #[test] fn pass_into_js_as_js_class() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -349,8 +390,11 @@ fn pass_into_js_as_js_class() { pub fn run() { take_foo(Foo(13).into()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run, Foo } from "./out"; import * as assert from "assert"; @@ -363,14 +407,17 @@ fn pass_into_js_as_js_class() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn constructors() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -416,8 +463,11 @@ fn constructors() { self.number + self.number2 } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import { Foo, Bar, cross_item_construction } from "./out"; @@ -440,7 +490,8 @@ fn constructors() { assert.strictEqual(cross_item_construction().get_sum(), 15); } - "#) + "#, + ) .test(); } @@ -448,7 +499,9 @@ fn constructors() { fn empty_structs() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -463,14 +516,18 @@ fn empty_structs() { #[wasm_bindgen] impl Other { pub fn return_a_value() -> MissingClass { MissingClass {} } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { Other } from "./out"; export function test() { Other.return_a_value(); } - "#) + "#, + ) .test(); } @@ -478,7 +535,9 @@ fn empty_structs() { fn public_fields() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -500,8 +559,11 @@ fn public_fields() { Foo::default() } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { Foo } from "./out"; import * as assert from "assert"; @@ -523,7 +585,8 @@ fn public_fields() { a.d = 3.3; assert.strictEqual(a.d, 3); } - "#) + "#, + ) .test(); } @@ -531,7 +594,9 @@ fn public_fields() { fn using_self() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -548,14 +613,18 @@ fn using_self() { Foo {} } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { Foo } from "./out"; export function test() { Foo.new().free(); } - "#) + "#, + ) .test(); } @@ -563,7 +632,9 @@ fn using_self() { fn readonly_fields() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -583,8 +654,11 @@ fn readonly_fields() { Foo::default() } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { Foo } from "./out"; import * as assert from "assert"; @@ -594,6 +668,7 @@ fn readonly_fields() { assert.throws(() => (a as any).a = 3, /has only a getter/); a.free(); } - "#) + "#, + ) .test(); } diff --git a/tests/all/closures.rs b/tests/all/closures.rs index d965091c..a85ba9bd 100644 --- a/tests/all/closures.rs +++ b/tests/all/closures.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -25,8 +27,11 @@ fn works() { assert_eq!(thread(&|a| a + 1), 3); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function call(a: any) { @@ -40,14 +45,17 @@ fn works() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn cannot_reuse() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -66,8 +74,11 @@ fn cannot_reuse() { call(&|| {}); assert!(call_again().is_err()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; let CACHE: any = null; @@ -83,14 +94,17 @@ fn cannot_reuse() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn long_lived() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -125,8 +139,11 @@ fn long_lived() { } assert!(hit.get()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function call1(a: any) { @@ -140,14 +157,17 @@ fn long_lived() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn many_arity() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -219,8 +239,11 @@ fn many_arity() { assert_eq!((a, b, c, d, e, f, g), (1, 2, 3, 4, 5, 6, 7)) })); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function call1(a: any) { a() } @@ -235,14 +258,17 @@ fn many_arity() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn long_lived_dropping() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -270,8 +296,11 @@ fn long_lived_dropping() { drop(a); assert!(call().is_err()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; let CACHE: any = null; @@ -282,14 +311,17 @@ fn long_lived_dropping() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn long_fnmut_recursive() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -311,8 +343,11 @@ fn long_fnmut_recursive() { cache(&a); assert!(call().is_ok()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; let CACHE: any = null; @@ -323,14 +358,17 @@ fn long_fnmut_recursive() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn fnmut() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -356,8 +394,11 @@ fn fnmut() { }), 3); assert!(x); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function call(a: any) { @@ -371,14 +412,17 @@ fn fnmut() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn fnmut_bad() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -408,8 +452,11 @@ fn fnmut_bad() { assert!(again(true).is_err()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; let F: any = null; @@ -426,14 +473,17 @@ fn fnmut_bad() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn string_arguments() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -454,8 +504,11 @@ fn string_arguments() { }); assert!(x); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function call(a: any) { @@ -465,14 +518,17 @@ fn string_arguments() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn string_ret() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -495,8 +551,11 @@ fn string_ret() { }); assert!(x); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; import * as assert from "assert"; @@ -508,7 +567,7 @@ fn string_ret() { export function test() { run(); } - "#) + "#, + ) .test(); } - diff --git a/tests/all/comments.rs b/tests/all/comments.rs index f9e1dc21..89956337 100644 --- a/tests/all/comments.rs +++ b/tests/all/comments.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { let mut p = project(); - p.file("src/lib.rs", r#" + p.file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -33,24 +35,27 @@ fn works() { self.a.clone() } } - "#); + "#, + ); - let (root, target) = p.cargo_build(); - p.gen_bindings(&root, &target); - let js = p.read_js(); - let comments = extract_doc_comments(&js); - assert!(comments.iter().all(|c| c == "This comment should exist")); + let (root, target) = p.cargo_build(); + p.gen_bindings(&root, &target); + let js = p.read_js(); + let comments = extract_doc_comments(&js); + assert!(comments.iter().all(|c| c == "This comment should exist")); } /// Pull out all lines in a js string that start with /// '* ', all other lines will either be comment start, comment -/// end or actual js lines. +/// end or actual js lines. fn extract_doc_comments(js: &str) -> Vec { - js.lines().filter_map(|l| { - let trimmed = l.trim(); - if trimmed.starts_with("* ") { - Some(trimmed[2..].to_owned()) - } else { - None - } - }).collect() -} \ No newline at end of file + js.lines() + .filter_map(|l| { + let trimmed = l.trim(); + if trimmed.starts_with("* ") { + Some(trimmed[2..].to_owned()) + } else { + None + } + }) + .collect() +} diff --git a/tests/all/enums.rs b/tests/all/enums.rs index e6dd7b90..0ad10fd4 100644 --- a/tests/all/enums.rs +++ b/tests/all/enums.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn c_style_enum() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -25,8 +27,11 @@ fn c_style_enum() { Color::Red => Color::Green, } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -38,14 +43,17 @@ fn c_style_enum() { assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow); } - "#) + "#, + ) .test(); } #[test] fn c_style_enum_with_custom_values() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -73,8 +81,11 @@ fn c_style_enum_with_custom_values() { Color::Red => Color::Green, } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -86,6 +97,7 @@ fn c_style_enum_with_custom_values() { assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow); } - "#) + "#, + ) .test(); } diff --git a/tests/all/import_class.rs b/tests/all/import_class.rs index 6d97a779..b0b7d010 100644 --- a/tests/all/import_class.rs +++ b/tests/all/import_class.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn simple() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -27,8 +29,11 @@ fn simple() { #[wasm_bindgen(js_namespace = Math)] fn log(a: f64) -> f64; } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -36,14 +41,17 @@ fn simple() { wasm.get_random(); assert.strictEqual(wasm.do_log(1.0), Math.log(1.0)); } - "#) + "#, + ) .test(); } #[test] fn import_class() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -60,8 +68,11 @@ fn import_class() { pub fn baz() { bar(); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { baz } from "./out"; import { called } from "./another"; import * as assert from "assert"; @@ -70,8 +81,11 @@ fn import_class() { baz(); assert.strictEqual(called, true); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" export let called = false; export class Foo { @@ -79,14 +93,17 @@ fn import_class() { called = true; } } - "#) + "#, + ) .test(); } #[test] fn construct() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -113,8 +130,11 @@ fn construct() { f.append_to_internal_string(" foo"); f.assert_internal_string("this foo"); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; import { called } from "./another"; import * as assert from "assert"; @@ -123,8 +143,11 @@ fn construct() { run(); assert.strictEqual(called, true); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" import * as assert from "assert"; export let called = false; @@ -151,14 +174,17 @@ fn construct() { called = true; } } - "#) + "#, + ) .test(); } #[test] fn new_constructors() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -179,15 +205,21 @@ fn new_constructors() { let f = Foo::new(1); assert_eq!(f.get(), 2); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function test() { run(); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" export class Foo { constructor(private field: number) { } @@ -196,14 +228,17 @@ fn new_constructors() { return this.field + 1; } } - "#) + "#, + ) .test(); } #[test] fn switch_methods() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -233,8 +268,11 @@ fn switch_methods() { pub fn b() { Foo::new().b(); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { a, b } from "./out"; import { Foo, called } from "./another"; import * as assert from "assert"; @@ -259,8 +297,11 @@ fn switch_methods() { b(); assert.strictEqual(called.a, true); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" export let called = { a: false }; export class Foo { @@ -275,14 +316,17 @@ fn switch_methods() { called.a = true; } } - "#) + "#, + ) .test(); } #[test] fn properties() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -310,15 +354,21 @@ fn properties() { a.set_a(2); assert_eq!(a.a(), 2); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function test() { run(); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" export class Foo { constructor(private num: number) { this.num = 1; @@ -332,14 +382,17 @@ fn properties() { this.num = val; } } - "#) + "#, + ) .test(); } #[test] fn rename_setter_getter() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -367,15 +420,21 @@ fn rename_setter_getter() { a.another(2); assert_eq!(a.test(), 2); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function test() { run(); } - "#) - .file("another.ts", r#" + "#, + ) + .file( + "another.ts", + r#" export class Foo { constructor(private num: number) { this.num = 1; @@ -389,6 +448,7 @@ fn rename_setter_getter() { this.num = val; } } - "#) + "#, + ) .test(); } diff --git a/tests/all/imports.rs b/tests/all/imports.rs index 915a01e2..630737e3 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn simple() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -37,8 +39,11 @@ fn simple() { pub fn get_the_object() -> JsValue { return_object() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -78,14 +83,17 @@ fn simple() { assert.strictEqual(wasm.get_the_object(), SYM); } - "#) + "#, + ) .test(); } #[test] fn unused() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![allow(dead_code)] @@ -100,8 +108,11 @@ fn unused() { #[wasm_bindgen] pub fn bar() {} - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; export function debug_print() {} @@ -109,14 +120,17 @@ fn unused() { export function test() { wasm.bar(); } - "#) + "#, + ) .test(); } #[test] fn string_ret() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -132,8 +146,11 @@ fn string_ret() { pub fn run() { assert_eq!(foo(), "bar"); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; export function foo(): string { @@ -143,14 +160,17 @@ fn string_ret() { export function test() { wasm.run(); } - "#) + "#, + ) .test(); } #[test] fn strings() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -171,8 +191,11 @@ fn strings() { pub fn bar2(a: String) -> String { foo(a) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -184,14 +207,17 @@ fn strings() { assert.strictEqual(wasm.bar('a'), 'ab'); assert.strictEqual(wasm.bar2('a'), 'ab'); } - "#) + "#, + ) .test(); } #[test] fn exceptions() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -217,8 +243,11 @@ fn exceptions() { assert!(baz().is_err()); bar(); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run, run2 } from "./out"; import * as assert from "assert"; @@ -242,14 +271,17 @@ fn exceptions() { run2(); assert.strictEqual(called, true); } - "#) + "#, + ) .test(); } #[test] fn exn_caught() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -266,8 +298,11 @@ fn exn_caught() { pub fn run() -> JsValue { foo().unwrap_err() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; import * as assert from "assert"; @@ -280,14 +315,17 @@ fn exn_caught() { assert.strictEqual(obj instanceof Error, true); assert.strictEqual(obj.message, 'error!'); } - "#) + "#, + ) .test(); } #[test] fn free_imports() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -303,14 +341,18 @@ fn free_imports() { pub fn run() { assert_eq!(parseInt("3"), 3); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function test() { run(); } - "#) + "#, + ) .test(); } @@ -318,7 +360,9 @@ fn free_imports() { fn import_a_field() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -334,8 +378,11 @@ fn import_a_field() { pub fn run() { assert_eq!(IMPORT.as_f64(), Some(1.0)); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export const IMPORT = 1.0; @@ -343,14 +390,17 @@ fn import_a_field() { export function test() { run(); } - "#) + "#, + ) .test(); } #[test] fn rename() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -367,8 +417,11 @@ fn rename() { pub fn run() { foo(); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -382,14 +435,17 @@ fn rename() { wasm.run(); assert.strictEqual(called, true); } - "#) + "#, + ) .test(); } #[test] fn versions() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -405,8 +461,11 @@ fn versions() { pub fn run() { foo(); } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" const fs = require("fs"); const assert = require("assert"); @@ -426,14 +485,17 @@ fn versions() { ] }); }; - "#) + "#, + ) .test(); } #[test] fn rust_keyword() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -450,8 +512,11 @@ fn rust_keyword() { pub fn run() { assert_eq!(foo(), 2); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export function self() { @@ -461,7 +526,8 @@ fn rust_keyword() { export function test() { run(); } - "#) + "#, + ) .test(); } @@ -469,7 +535,9 @@ fn rust_keyword() { fn rust_keyword2() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -487,8 +555,11 @@ fn rust_keyword2() { pub fn run() { assert_eq!(FOO.as_f64(), Some(3.0)); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run } from "./out"; export const bar = { @@ -498,6 +569,7 @@ fn rust_keyword2() { export function test() { run(); } - "#) + "#, + ) .test(); } diff --git a/tests/all/js_globals/Array.rs b/tests/all/js_globals/Array.rs index 8e8173de..828c7d1d 100644 --- a/tests/all/js_globals/Array.rs +++ b/tests/all/js_globals/Array.rs @@ -5,7 +5,9 @@ use project; #[test] fn filter() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -17,8 +19,11 @@ fn filter() { array.filter(&mut |x, _, _| x.as_f64().is_some()) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -31,14 +36,17 @@ fn filter() { assert.deepStrictEqual(wasm.keep_numbers(numbers), numbers); assert.deepStrictEqual(wasm.keep_numbers(mixed), [1, 2]); } - "#) + "#, + ) .test() } #[test] fn index_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -50,8 +58,11 @@ fn index_of() { this.index_of(value, from_index) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -69,14 +80,17 @@ fn index_of() { assert.equal(withFromIndex, 2); assert.equal(withFromIndexNotFound, -1); } - "#) + "#, + ) .test() } #[test] fn is_array() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -87,8 +101,11 @@ fn is_array() { pub fn is_array(value: &JsValue) -> bool { js::Array::is_array(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -109,14 +126,17 @@ fn is_array() { assert(!wasm.is_array(false)); assert(!wasm.is_array({ __proto__: Array.prototype })); } - "#) + "#, + ) .test() } #[test] fn sort() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -128,8 +148,11 @@ fn sort() { this.sort() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -139,14 +162,17 @@ fn sort() { assert.deepStrictEqual(sorted, [1, 2, 3, 6]) } - "#) + "#, + ) .test() } #[test] fn last_index_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -158,8 +184,11 @@ fn last_index_of() { this.last_index_of(value, from_index) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -177,14 +206,17 @@ fn last_index_of() { assert.equal(withFromIndex, 1); assert.equal(withFromIndexNotFound, -1); } - "#) + "#, + ) .test() } #[test] fn join() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -196,8 +228,11 @@ fn join() { this.join(delimiter) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -209,14 +244,17 @@ fn join() { let withForwardSlash = wasm.join_array(characters, "/"); assert.equal("a/c/x/n", withForwardSlash); } - "#) + "#, + ) .test() } #[test] fn slice() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -227,8 +265,11 @@ fn slice() { pub fn create_slice(this: &js::Array, start: u32, end: u32) -> js::Array { this.slice(start, end) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -239,14 +280,17 @@ fn slice() { assert.equal(subset[0], "c"); assert.equal(subset[1], "x"); } - "#) + "#, + ) .test() } #[test] fn fill() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -257,8 +301,11 @@ fn fill() { pub fn fill_with(this: &js::Array, value: JsValue, start: u32, end: u32) -> js::Array { this.fill(value, start, end) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -269,7 +316,8 @@ fn fill() { assert.equal(subset[0], 0); assert.equal(subset[4], 1); } - "#) + "#, + ) .test() } @@ -310,7 +358,9 @@ fn copy_within() { #[test] fn pop() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -322,8 +372,11 @@ fn pop() { this.pop() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -333,15 +386,17 @@ fn pop() { assert.equal(item, 2); assert.equal(characters.length, 5); } - "#) + "#, + ) .test() } - #[test] fn push() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -353,8 +408,11 @@ fn push() { this.push(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -364,14 +422,17 @@ fn push() { assert.equal(length, 7); assert.equal(characters[6], "a"); } - "#) + "#, + ) .test() } #[test] fn reverse() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -383,8 +444,11 @@ fn reverse() { this.reverse() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -394,14 +458,17 @@ fn reverse() { assert.equal(reversed[0], 2); assert.equal(reversed[5], 8); } - "#) + "#, + ) .test() } #[test] fn shift() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -413,8 +480,11 @@ fn shift() { this.shift() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -425,14 +495,17 @@ fn shift() { assert.equal(shiftedItem, 8); assert.equal(characters.length, 5); } - "#) + "#, + ) .test() } #[test] fn unshift() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -444,8 +517,11 @@ fn unshift() { this.unshift(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -456,14 +532,17 @@ fn unshift() { assert.equal(length, 7); assert.equal(characters[0], "abba"); } - "#) + "#, + ) .test() } #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -475,8 +554,11 @@ fn to_string() { this.to_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -486,15 +568,17 @@ fn to_string() { assert.equal(arrayString, "8,5,4,3,1,2"); } - "#) + "#, + ) .test() } - #[test] fn includes() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -506,8 +590,11 @@ fn includes() { this.includes(value, from_index) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -522,14 +609,17 @@ fn includes() { let isThreeIncluded = wasm.array_includes(characters, 3, 4); assert.ok(!isThreeIncluded); } - "#) + "#, + ) .test() } #[test] fn concat() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -541,8 +631,11 @@ fn concat() { this.concat(arr) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -553,14 +646,17 @@ fn concat() { let new_array = wasm.array_concat(arr1, arr2) assert.deepStrictEqual(new_array, [1, 2, 3, 4, 5, 6]); } - "#) + "#, + ) .test() } #[test] fn length() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -572,8 +668,11 @@ fn length() { this.length() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -586,14 +685,17 @@ fn length() { let emptyLength = wasm.array_length(empty); assert.equal(emptyLength, 0); } - "#) + "#, + ) .test() } #[test] fn every() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -604,8 +706,11 @@ fn every() { pub fn array_every_number_is_even(array: &js::Array) -> bool { array.every(&mut |el, _, _| el.as_f64().unwrap() % 2f64 == 0f64) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -618,6 +723,7 @@ fn every() { assert(!wasm.array_every_number_is_even(arrayOdd)); assert(!wasm.array_every_number_is_even(arrayMixed)); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/ArrayIterator.rs b/tests/all/js_globals/ArrayIterator.rs index 09755cc8..c31912f6 100644 --- a/tests/all/js_globals/ArrayIterator.rs +++ b/tests/all/js_globals/ArrayIterator.rs @@ -5,7 +5,9 @@ use project; #[test] fn keys() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -17,8 +19,11 @@ fn keys() { this.keys() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -30,14 +35,17 @@ fn keys() { assert.equal(iterator.toString(), wasmIterator.toString()); assert.equal(Array.from(iterator)[0], Array.from(wasmIterator)[0]); } - "#) + "#, + ) .test() } #[test] fn entries() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -49,8 +57,11 @@ fn entries() { this.entries() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -64,6 +75,7 @@ fn entries() { assert.equal(iterator.toString(), wasmIterator.toString()); assert.equal(jsItem.value[1], wasmItem.value[1]); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/Boolean.rs b/tests/all/js_globals/Boolean.rs index 323029f4..aea23d36 100644 --- a/tests/all/js_globals/Boolean.rs +++ b/tests/all/js_globals/Boolean.rs @@ -5,7 +5,9 @@ use project; #[test] fn new_undefined() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,22 +18,28 @@ fn new_undefined() { pub fn new_boolean() -> js::Boolean { js::Boolean::new(JsValue::undefined()) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.new_boolean().valueOf(), false); } - "#) + "#, + ) .test() } #[test] fn new_truely() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -42,14 +50,18 @@ fn new_truely() { pub fn new_boolean() -> js::Boolean { js::Boolean::new(JsValue::from("foo")) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.new_boolean().valueOf(), true); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/Date.rs b/tests/all/js_globals/Date.rs index 82ed7009..6a8a66f1 100644 --- a/tests/all/js_globals/Date.rs +++ b/tests/all/js_globals/Date.rs @@ -5,7 +5,9 @@ use super::project; #[test] fn new() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,22 +18,28 @@ fn new() { pub fn new_date() -> Date { Date::new() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(typeof wasm.new_date(), "object"); } - "#) + "#, + ) .test() } #[test] fn to_date_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -42,8 +50,11 @@ fn to_date_string() { pub fn to_date_string(this: &Date) -> JsString { this.to_date_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -52,14 +63,17 @@ fn to_date_string() { assert.equal(wasm.to_date_string(date), 'Wed Jul 28 1993'); } - "#) + "#, + ) .test() } #[test] fn to_iso_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -70,8 +84,11 @@ fn to_iso_string() { pub fn to_iso_string(this: &Date) -> JsString { this.to_iso_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -80,14 +97,17 @@ fn to_iso_string() { assert.equal(wasm.to_iso_string(date), '2011-10-05T14:48:00.000Z'); } - "#) + "#, + ) .test() } #[test] fn to_json() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -98,8 +118,11 @@ fn to_json() { pub fn to_json(this: &Date) -> JsString { this.to_json() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -108,7 +131,8 @@ fn to_json() { assert.equal(wasm.to_json(date), '1975-08-19T23:15:30.000Z'); } - "#) + "#, + ) .test() } @@ -173,7 +197,9 @@ fn to_locale_string() { #[test] fn to_locale_time_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -184,8 +210,11 @@ fn to_locale_time_string() { pub fn to_locale_time_string(this: &Date, locale: JsString) -> JsString { this.to_locale_time_string(locale) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -193,14 +222,17 @@ fn to_locale_time_string() { let date = new Date('August 19, 1975 23:15:30'); assert.equal(wasm.to_locale_time_string(date, 'en-US'), "11:15:30 PM"); } - "#) + "#, + ) .test() } #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -211,8 +243,11 @@ fn to_string() { pub fn to_string(this: &Date) -> JsString { this.to_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -220,14 +255,17 @@ fn to_string() { let date = new Date('August 19, 1975 23:15:30'); assert.equal(wasm.to_string(date).substring(0, 15), "Tue Aug 19 1975"); } - "#) + "#, + ) .test() } #[test] fn to_time_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -238,8 +276,11 @@ fn to_time_string() { pub fn to_time_string(this: &Date) -> JsString { this.to_time_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -247,14 +288,17 @@ fn to_time_string() { let date = new Date('August 19, 1975 23:15:30'); assert.equal(wasm.to_time_string(date).substring(0, 8), "23:15:30"); } - "#) + "#, + ) .test() } #[test] fn to_utc_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -265,8 +309,11 @@ fn to_utc_string() { pub fn to_utc_string(this: &Date) -> JsString { this.to_utc_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -274,14 +321,17 @@ fn to_utc_string() { let date = new Date('14 Jun 2017 00:00:00 PDT'); assert.equal(wasm.to_utc_string(date), "Wed, 14 Jun 2017 07:00:00 GMT"); } - "#) + "#, + ) .test() } #[test] fn value_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -292,8 +342,11 @@ fn value_of() { pub fn js_value_of(this: &Date) -> Date { this.value_of() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -301,6 +354,7 @@ fn value_of() { let date = new Date(Date.UTC(96, 1, 2, 3, 4, 5)); assert.equal(wasm.js_value_of(date), 823230245000); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/Function.rs b/tests/all/js_globals/Function.rs index b835b569..b54a2629 100644 --- a/tests/all/js_globals/Function.rs +++ b/tests/all/js_globals/Function.rs @@ -5,7 +5,9 @@ use project; #[test] fn apply() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,8 +18,11 @@ fn apply() { pub fn apply(this: &js::Function, context: &JsValue, args: &js::Array) -> js::Function { this.apply(context, args) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -28,14 +33,17 @@ fn apply() { wasm.apply(Array.prototype.push, arr, [3]); assert.equal(arr[2], 3); } - "#) + "#, + ) .test() } #[test] fn length() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -46,8 +54,11 @@ fn length() { pub fn fn_length(this: &js::Function) -> u32 { this.length() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -68,14 +79,17 @@ fn length() { assert.equal(wasm.fn_length(fn1), 1); assert.equal(wasm.fn_length(fn2), 2); } - "#) + "#, + ) .test() } #[test] fn name() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -86,8 +100,11 @@ fn name() { pub fn fn_name(this: &js::Function) -> js::JsString { this.name() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -109,14 +126,17 @@ fn name() { const closure = () => {}; assert.equal(wasm.fn_name(closure), 'closure'); } - "#) + "#, + ) .test() } #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -127,8 +147,11 @@ fn to_string() { pub fn get_source_code(this: &js::Function) -> js::JsString { this.to_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -139,6 +162,7 @@ fn to_string() { assert.equal(wasm.get_source_code(fn1), 'function fn1(a, b) { return a + b; }'); assert.equal(wasm.get_source_code(fn2), 'function (a) { return console.log(a); }'); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index 07579b7c..28ca0943 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -5,7 +5,9 @@ use project; #[test] fn length() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -17,8 +19,11 @@ fn length() { this.length() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -29,14 +34,17 @@ fn length() { let empty = ''; assert.equal(wasm.string_length(empty), 0); } - "#) + "#, + ) .test() } #[test] fn char_at() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -47,8 +55,11 @@ fn char_at() { pub fn string_char_at(this: &js::JsString, index: u32) -> js::JsString { this.char_at(index) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -58,14 +69,17 @@ fn char_at() { assert.equal(wasm.string_char_at(anyString, 0), "B"); assert.equal(wasm.string_char_at(anyString, 999), ""); } - "#) + "#, + ) .test() } #[test] fn char_code_at() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -76,8 +90,11 @@ fn char_code_at() { pub fn string_char_code_at(this: &js::JsString, index: u32) -> js::Number { this.char_code_at(index) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -87,14 +104,17 @@ fn char_code_at() { assert.equal(wasm.string_char_code_at(anyString, 0), 66); assert.ok(isNaN(wasm.string_char_code_at(anyString, 999))); } - "#) + "#, + ) .test() } #[test] fn code_point_at() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -105,8 +125,11 @@ fn code_point_at() { pub fn string_code_point_at(this: &js::JsString, pos: u32) -> JsValue { this.code_point_at(pos) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -115,14 +138,17 @@ fn code_point_at() { assert.equal(wasm.string_code_point_at('\uD800\uDC00', 0), 65536); assert.equal(wasm.string_code_point_at('XYZ', 42), undefined); } - "#) + "#, + ) .test() } #[test] fn concat() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -133,8 +159,11 @@ fn concat() { pub fn string_concat(this: &js::JsString, string_2: &js::JsString) -> js::JsString { this.concat(string_2) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -147,7 +176,8 @@ fn concat() { assert.equal(wasm.string_concat('foo', true), 'footrue'); assert.equal(wasm.string_concat('foo', 1234), 'foo1234'); } - "#) + "#, + ) .test() } @@ -228,7 +258,9 @@ fn index_of() { #[test] fn slice() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -239,8 +271,11 @@ fn slice() { pub fn create_slice(this: &js::JsString, start: u32, end: u32) -> js::JsString { this.slice(start, end) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -250,7 +285,8 @@ fn slice() { assert.equal(subset, "cx"); } - "#) + "#, + ) .test() } @@ -363,7 +399,9 @@ fn substr() { #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -374,8 +412,11 @@ fn to_string() { pub fn string_to_string(this: &js::JsString) -> js::JsString { this.to_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -383,14 +424,17 @@ fn to_string() { let greeting = 'Hello world!'; assert.equal(wasm.string_to_string(greeting), 'Hello world!'); } - "#) + "#, + ) .test() } #[test] fn trim() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -401,8 +445,11 @@ fn trim() { pub fn string_trim(this: &js::JsString) -> js::JsString { this.trim() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -411,14 +458,17 @@ fn trim() { // Another example of .trim() removing whitespace from just one side. assert.equal(wasm.string_trim('foo '), 'foo'); } - "#) + "#, + ) .test() } #[test] fn trim_end_and_trim_right() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -434,8 +484,11 @@ fn trim_end_and_trim_right() { pub fn string_trim_right(this: &js::JsString) -> js::JsString { this.trim_right() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -445,14 +498,17 @@ fn trim_end_and_trim_right() { assert.equal(wasm.string_trim_end(greeting), trimmed); assert.equal(wasm.string_trim_right(greeting), trimmed); } - "#) + "#, + ) .test() } #[test] fn trim_start_and_trim_left() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -468,8 +524,11 @@ fn trim_start_and_trim_left() { pub fn string_trim_left(this: &js::JsString) -> js::JsString { this.trim_left() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -479,14 +538,17 @@ fn trim_start_and_trim_left() { assert.equal(wasm.string_trim_start(greeting), trimmed); assert.equal(wasm.string_trim_left(greeting), trimmed); } - "#) + "#, + ) .test() } #[test] fn value_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -497,8 +559,11 @@ fn value_of() { pub fn string_value_of(this: &js::JsString) -> js::JsString { this.value_of() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -506,6 +571,7 @@ fn value_of() { let greeting = new String('Hello world!'); assert.equal(wasm.string_value_of(greeting), 'Hello world!'); } - "#) + "#, + ) .test() -} \ No newline at end of file +} diff --git a/tests/all/js_globals/Math.rs b/tests/all/js_globals/Math.rs index df3038f4..ef5558ef 100644 --- a/tests/all/js_globals/Math.rs +++ b/tests/all/js_globals/Math.rs @@ -2,11 +2,12 @@ use super::project; - #[test] fn abs() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -17,8 +18,11 @@ fn abs() { pub fn abs(number: i32) -> js::Number { js::Math::abs(number) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -26,14 +30,17 @@ fn abs() { assert.equal(wasm.abs(-32), Math.abs(-32)); assert.equal(wasm.abs(32), 32); } - "#) + "#, + ) .test() } #[test] fn acos() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -44,22 +51,28 @@ fn acos() { pub fn acos(adjacent: i32, hypotenuse: i32) -> js::Number { js::Math::acos(adjacent, hypotenuse) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.acos(-1, 1), Math.PI); } - "#) + "#, + ) .test() } #[test] fn acosh() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -70,8 +83,11 @@ fn acosh() { pub fn acosh(number: i32) -> js::Number { js::Math::acosh(number) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -79,14 +95,17 @@ fn acosh() { assert.equal(wasm.acosh(1), 0); assert.equal(wasm.acosh(2), Math.acosh(2)); } - "#) + "#, + ) .test() } #[test] fn asin() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -97,22 +116,28 @@ fn asin() { pub fn asin(opposite: i32, hypotenuse: i32) -> js::Number { js::Math::asin(opposite / hypotenuse) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.asin(1, 1), Math.asin(1)); } - "#) + "#, + ) .test() } #[test] fn asinh() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -123,22 +148,28 @@ fn asinh() { pub fn asinh(number: i32) -> js::Number { js::Math::asinh(number) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.asinh(1), Math.asinh(1)); } - "#) + "#, + ) .test() } #[test] fn atan() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -149,22 +180,28 @@ fn atan() { pub fn atan(number: i32) -> js::Number { js::Math::atan(number) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.atan(1), Math.atan(1)); } - "#) + "#, + ) .test() } #[test] fn atan2() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -175,22 +212,28 @@ fn atan2() { pub fn atan2(x: i32, y: i32) -> js::Number { js::Math::atan2(x, y) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.atan2(1, 2), Math.atan2(1, 2)); } - "#) + "#, + ) .test() } #[test] fn atanh() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -201,22 +244,28 @@ fn atanh() { pub fn atanh(x: i32) -> js::Number { js::Math::atanh(x) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.atanh(1), Math.atanh(1)); } - "#) + "#, + ) .test() } #[test] fn cbrt() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -227,22 +276,28 @@ fn cbrt() { pub fn cbrt(x: i32) -> js::Number { js::Math::cbrt(x) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.cbrt(27), 3); } - "#) + "#, + ) .test() } #[test] fn ceil() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -253,8 +308,11 @@ fn ceil() { pub fn ceil(x: f32) -> js::Number { js::Math::ceil(x) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -262,14 +320,17 @@ fn ceil() { assert.equal(wasm.ceil(1.1), 2); assert.equal(wasm.ceil(-1.1), -1); } - "#) + "#, + ) .test() } #[test] fn clz32() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -280,8 +341,11 @@ fn clz32() { pub fn clz32(x: i32) -> js::Number { js::Math::clz32(x) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -289,14 +353,17 @@ fn clz32() { assert.equal(wasm.clz32(1), 31); assert.equal(wasm.clz32(1000), 22); } - "#) + "#, + ) .test() } #[test] fn floor() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -307,8 +374,11 @@ fn floor() { pub fn floor(x: f32) -> js::Number { js::Math::floor(x) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -316,6 +386,7 @@ fn floor() { assert.equal(wasm.floor(5.95), 5); assert.equal(wasm.floor(-5.05), -6); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/Number.rs b/tests/all/js_globals/Number.rs index 362832e4..05b64674 100644 --- a/tests/all/js_globals/Number.rs +++ b/tests/all/js_globals/Number.rs @@ -2,7 +2,6 @@ use super::project; - #[test] fn to_locale_string() { project() @@ -36,7 +35,9 @@ fn to_locale_string() { #[test] fn to_precision() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -52,8 +53,11 @@ fn to_precision() { }; result } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -61,14 +65,17 @@ fn to_precision() { assert.equal(wasm.to_precision(0.1, 3), "0.100"); assert.equal(wasm.to_precision(10, 101), "RangeError"); } - "#) + "#, + ) .test() } #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -84,8 +91,11 @@ fn to_string() { }; result } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -95,14 +105,17 @@ fn to_string() { assert.equal(wasm.to_string(233, 16), "e9"); assert.equal(wasm.to_string(number, 100), "RangeError"); } - "#) + "#, + ) .test() } #[test] fn value_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -113,8 +126,11 @@ fn value_of() { pub fn js_value_of(this: &js::Number) -> js::Number { this.value_of() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -123,14 +139,17 @@ fn value_of() { assert.equal(wasm.js_value_of(number), 42); assert.equal(typeof wasm.js_value_of(number), "number"); } - "#) + "#, + ) .test() } #[test] fn to_fixed() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -146,8 +165,11 @@ fn to_fixed() { }; result } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -155,14 +177,17 @@ fn to_fixed() { assert.equal(wasm.to_fixed(123.456, 2), "123.46"); assert.equal(wasm.to_fixed(10, 101), "RangeError"); } - "#) + "#, + ) .test() } #[test] fn to_exponential() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -178,8 +203,11 @@ fn to_exponential() { }; result } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -187,6 +215,7 @@ fn to_exponential() { assert.equal(wasm.to_exponential(123456, 2), "1.23e+5"); assert.equal(wasm.to_exponential(10, 101), "RangeError"); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 48526636..6b268956 100644 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -5,7 +5,9 @@ use project; #[test] fn new() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,22 +18,28 @@ fn new() { pub fn new_object() -> js::Object { js::Object::new() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(typeof wasm.new_object(), "object"); } - "#) + "#, + ) .test() } #[test] fn has_own_property() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -42,8 +50,11 @@ fn has_own_property() { pub fn has_own_foo_property(obj: &js::Object, property: &JsValue) -> bool { obj.has_own_property(&property) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -55,14 +66,17 @@ fn has_own_property() { const s = Symbol(); assert(wasm.has_own_foo_property({ [s]: "foo" }, s)); } - "#) + "#, + ) .test() } #[test] fn to_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -79,8 +93,11 @@ fn to_string() { let object = js::Object::new(); assert_eq!(String::from(object.to_string()), "[object Object]"); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -88,14 +105,17 @@ fn to_string() { assert.equal(wasm.to_string({ foo: 42 }), "[object Object]"); wasm.test(); } - "#) + "#, + ) .test() } #[test] fn is_prototype_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -106,8 +126,11 @@ fn is_prototype_of() { pub fn obj_is_prototype_of_value(obj: &js::Object, value: &JsValue) -> bool { obj.is_prototype_of(&value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -119,14 +142,17 @@ fn is_prototype_of() { assert(wasm.obj_is_prototype_of_value(Foo.prototype, foo)); assert(!wasm.obj_is_prototype_of_value(Bar.prototype, foo)); } - "#) + "#, + ) .test() } #[test] fn keys() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -137,8 +163,11 @@ fn keys() { pub fn keys(obj: &js::Object) -> js::Array { js::Object::keys(obj) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -146,14 +175,17 @@ fn keys() { const obj = { a: 1, b: 2, c: 3 }; assert.deepStrictEqual(wasm.keys(obj), ["a", "b", "c"]); } - "#) + "#, + ) .test() } #[test] fn property_is_enumerable() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -164,8 +196,11 @@ fn property_is_enumerable() { pub fn property_is_enumerable(obj: &js::Object, property: &JsValue) -> bool { obj.property_is_enumerable(&property) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -181,7 +216,8 @@ fn property_is_enumerable() { const s = Symbol(); assert.ok(wasm.property_is_enumerable({ [s]: true }, s)); } - "#) + "#, + ) .test() } @@ -239,7 +275,9 @@ fn seal() { #[test] fn to_locale_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -251,22 +289,28 @@ fn to_locale_string() { let object = js::Object::new(); object.to_locale_string() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.to_locale_string(), "[object Object]"); } - "#) + "#, + ) .test() } #[test] fn value_of() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -277,8 +321,11 @@ fn value_of() { pub fn value_of(obj: &js::Object) -> js::Object { obj.value_of() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -287,6 +334,7 @@ fn value_of() { assert.strictEqual(wasm.value_of(obj), obj); assert.notStrictEqual(wasm.value_of(obj), { foo: 42 }); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/TypedArray.rs b/tests/all/js_globals/TypedArray.rs index 139c4371..618e8e16 100644 --- a/tests/all/js_globals/TypedArray.rs +++ b/tests/all/js_globals/TypedArray.rs @@ -5,7 +5,9 @@ use project; #[test] fn new_undefined() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,22 +18,28 @@ fn new_undefined() { pub fn new_array() -> js::Uint8Array { js::Uint8Array::new(JsValue::undefined()) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.new_array().length, 0); } - "#) + "#, + ) .test() } #[test] fn new_length() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -42,15 +50,19 @@ fn new_length() { pub fn new_array() -> js::Uint8Array { js::Uint8Array::new(JsValue::from_f64(4.0)) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(wasm.new_array().length, 4); } - "#) + "#, + ) .test() } diff --git a/tests/all/js_globals/WeakMap.rs b/tests/all/js_globals/WeakMap.rs index 94b02a6b..da189a7c 100644 --- a/tests/all/js_globals/WeakMap.rs +++ b/tests/all/js_globals/WeakMap.rs @@ -5,7 +5,9 @@ use project; #[test] fn new() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,23 +18,28 @@ fn new() { pub fn new_weak_map() -> js::WeakMap { js::WeakMap::new() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(typeof wasm.new_weak_map(), "object"); } - "#) + "#, + ) .test() } - #[test] fn get() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -43,8 +50,11 @@ fn get() { pub fn get_value(this: &js::WeakMap, key: js::Object) -> JsValue { this.get(key) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -57,14 +67,17 @@ fn get() { let undef = "unexisting_key"; assert.equal(typeof wasm.get_value(map, undef), "undefined"); } - "#) + "#, + ) .test() } #[test] fn set() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -75,8 +88,11 @@ fn set() { pub fn set_value(this: &js::WeakMap, key: js::Object, value: JsValue) -> js::WeakMap { this.set(key, value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -86,14 +102,17 @@ fn set() { wasm.set_value(map, key, "value"); assert.equal(map.get(key), "value"); } - "#) + "#, + ) .test() } #[test] fn has() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -104,8 +123,11 @@ fn has() { pub fn has_value(this: &js::WeakMap, key: js::Object) -> bool { this.has(key) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -118,14 +140,17 @@ fn has() { let undef = "unexisting_key"; assert.equal(wasm.has_value(map, undef), false); } - "#) + "#, + ) .test() } #[test] fn delete() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -136,8 +161,11 @@ fn delete() { pub fn delete_key(this: &js::WeakMap, key: js::Object) -> bool { this.delete(key) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -149,6 +177,7 @@ fn delete() { assert.equal(map.has(key), false); assert.equal(wasm.delete_key(map, key), false); } - "#) + "#, + ) .test() -} \ No newline at end of file +} diff --git a/tests/all/js_globals/WeakSet.rs b/tests/all/js_globals/WeakSet.rs index 5201df1a..7957e7f9 100644 --- a/tests/all/js_globals/WeakSet.rs +++ b/tests/all/js_globals/WeakSet.rs @@ -5,7 +5,9 @@ use project; #[test] fn new() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -16,22 +18,28 @@ fn new() { pub fn new_weak_set() -> js::WeakSet { js::WeakSet::new() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; export function test() { assert.equal(typeof wasm.new_weak_set(), "object"); } - "#) + "#, + ) .test() } #[test] fn has() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -42,8 +50,11 @@ fn has() { pub fn has_value(this: &js::WeakSet, value: js::Object) -> bool { this.has(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -56,14 +67,17 @@ fn has() { let nonex = {nonexistent: "value"}; assert.equal(wasm.has_value(set, nonex), false); } - "#) + "#, + ) .test() } #[test] fn add() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -74,8 +88,11 @@ fn add() { pub fn add_value(this: &js::WeakSet, value: js::Object) -> js::WeakSet { this.add(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -91,14 +108,17 @@ fn add() { assert.throws(() => { wasm.add_value(set, null) }, TypeError); assert.throws(() => { wasm.add_value(set, undefined) }, TypeError); } - "#) + "#, + ) .test() } #[test] fn delete() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -109,8 +129,11 @@ fn delete() { pub fn delete_value(this: &js::WeakSet, value: js::Object) -> bool { this.delete(value) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -128,6 +151,7 @@ fn delete() { assert.equal(wasm.delete_value(set, null), false); assert.equal(wasm.delete_value(set, undefined), false); } - "#) + "#, + ) .test() -} \ No newline at end of file +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 4090fe04..fda83062 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -9,17 +9,19 @@ mod Date; mod Function; mod JsString; mod Math; -mod WeakMap; -mod WeakSet; mod Number; mod Object; mod TypedArray; +mod WeakMap; +mod WeakSet; #[test] #[cfg(feature = "std")] fn decode_uri() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -35,7 +37,8 @@ fn decode_uri() { assert!(js::decode_uri("%E0%A4%A").is_err()); } - "#) + "#, + ) .test(); } @@ -43,7 +46,9 @@ fn decode_uri() { #[cfg(feature = "std")] fn encode_uri() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -55,14 +60,17 @@ fn encode_uri() { let x = js::encode_uri("ABC abc 123"); assert_eq!(String::from(x), "ABC%20abc%20123"); } - "#) + "#, + ) .test(); } #[test] fn eval() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -79,6 +87,7 @@ fn eval() { .expect("eval should throw"); assert_eq!(err.as_f64().unwrap(), 42.0); } - "#) + "#, + ) .test(); } diff --git a/tests/all/jsobjects.rs b/tests/all/jsobjects.rs index 491f0522..3ae8723a 100644 --- a/tests/all/jsobjects.rs +++ b/tests/all/jsobjects.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn simple() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -19,8 +21,11 @@ fn simple() { pub fn bar(s: &JsValue) { foo(s); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -37,14 +42,17 @@ fn simple() { wasm.bar(sym); assert.strictEqual(ARG, sym); } - "#) + "#, + ) .test(); } #[test] fn owned() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -60,8 +68,11 @@ fn owned() { pub fn bar(s: JsValue) { foo(s); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -78,14 +89,17 @@ fn owned() { wasm.bar(sym); assert.strictEqual(ARG, sym); } - "#) + "#, + ) .test(); } #[test] fn clone() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -109,8 +123,11 @@ fn clone() { foo4(&s); foo5(s); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -125,14 +142,17 @@ fn clone() { export function test() { wasm.bar(ARG); } - "#) + "#, + ) .test(); } #[test] fn promote() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -154,8 +174,11 @@ fn promote() { foo3(s); foo4(s.clone()); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -169,14 +192,17 @@ fn promote() { export function test() { wasm.bar(ARG); } - "#) + "#, + ) .test(); } #[test] fn returning_vector() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -196,8 +222,11 @@ fn returning_vector() { } res } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; import * as assert from "assert"; @@ -207,14 +236,17 @@ fn returning_vector() { const result = wasm.bar(); assert.strictEqual(result.length, 10); } - "#) + "#, + ) .test(); } #[test] fn another_vector_return() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -233,15 +265,19 @@ fn another_vector_return() { JsValue::from(6), ] } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { get_array } from "./out"; import * as assert from "assert"; export function test() { assert.deepStrictEqual(get_array(), [1, 2, 3, 4, 5, 6]); } - "#) + "#, + ) .test(); } @@ -251,7 +287,9 @@ fn serde() { .serde(true) .depend("serde = '1.0'") .depend("serde_derive = '1.0'") - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -303,8 +341,11 @@ fn serde() { let s = j.into_serde::().unwrap(); assert_eq!(s, "bar"); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { run, parse } from "./out"; import * as assert from "assert"; @@ -328,6 +369,7 @@ fn serde() { run(); parse('bar'); } - "#) + "#, + ) .test(); } diff --git a/tests/all/main.rs b/tests/all/main.rs index 79002bb5..c7c872ff 100644 --- a/tests/all/main.rs +++ b/tests/all/main.rs @@ -411,15 +411,19 @@ impl Project { self.gen_bindings(&root, &target_dir); let mut wasm = Vec::new(); - File::open(root.join("out_bg.wasm")).unwrap() - .read_to_end(&mut wasm).unwrap(); + File::open(root.join("out_bg.wasm")) + .unwrap() + .read_to_end(&mut wasm) + .unwrap(); let obj = cli::wasm2es6js::Config::new() .base64(true) .generate(&wasm) .expect("failed to convert wasm to js"); - - File::create(root.join("out_bg.d.ts")).unwrap() - .write_all(obj.typescript().as_bytes()).unwrap(); + + File::create(root.join("out_bg.d.ts")) + .unwrap() + .write_all(obj.typescript().as_bytes()) + .unwrap(); // move files from the root into each test, it looks like this may be // needed for webpack to work well when invoked concurrently. @@ -473,7 +477,6 @@ impl Project { } panic!("failed"); } - } fn read_js(&self) -> String { let path = root().join("out.js"); @@ -522,12 +525,14 @@ mod api; mod char; mod classes; mod closures; +mod comments; mod dependencies; mod enums; mod import_class; mod imports; +#[cfg(feature = "js_globals")] +mod js_globals; mod jsobjects; -#[cfg(feature = "js_globals")] mod js_globals; mod math; mod node; mod non_debug; @@ -536,6 +541,5 @@ mod simple; mod slice; mod structural; mod u64; -mod webidl; -mod comments; mod validate_prt; +mod webidl; diff --git a/tests/all/math.rs b/tests/all/math.rs index c3ca9e49..07f5bd9b 100644 --- a/tests/all/math.rs +++ b/tests/all/math.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn auto_bind_math() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -64,14 +66,17 @@ fn auto_bind_math() { (a % (b as f32))) as f64) + (b + 2.0f64.powf(a as f64)) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import { math } from "./out"; export function test() { math(1.0, 2.0); } - "#) + "#, + ) .test(); } - diff --git a/tests/all/node.rs b/tests/all/node.rs index c8ddc2ee..2f98eb35 100644 --- a/tests/all/node.rs +++ b/tests/all/node.rs @@ -4,7 +4,9 @@ use super::project; fn works() { project() .node(true) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -111,8 +113,11 @@ fn works() { (a % (b as f32))) as f64) + (b + 2.0f64.powf(a as f64)) } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" const assert = require('assert'); var called = false; @@ -149,6 +154,7 @@ fn works() { math(1.0, 2.0); }; - "#) + "#, + ) .test(); } diff --git a/tests/all/non_debug.rs b/tests/all/non_debug.rs index 70688b54..c6afd316 100644 --- a/tests/all/non_debug.rs +++ b/tests/all/non_debug.rs @@ -4,7 +4,9 @@ use super::project; fn works() { project() .debug(false) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -26,8 +28,11 @@ fn works() { drop(a.clone()); a.clone() } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -37,6 +42,7 @@ fn works() { let a = wasm.A.new(); a.free(); } - "#) + "#, + ) .test(); } diff --git a/tests/all/non_wasm.rs b/tests/all/non_wasm.rs index dcb23b67..89ecaf6e 100644 --- a/tests/all/non_wasm.rs +++ b/tests/all/non_wasm.rs @@ -1,13 +1,14 @@ +use super::{project, run}; use std::process::Command; -use super::{run, project}; #[test] fn works() { let mut p = project(); let name = p.crate_name(); - p - .rlib(true) - .file("src/lib.rs", r#" + p.rlib(true) + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -54,8 +55,12 @@ fn works() { #[wasm_bindgen] pub fn baz(_: JsValue) { } - "#) - .file("tests/foo.rs", &format!(" + "#, + ) + .file( + "tests/foo.rs", + &format!( + " extern crate {} as mytest; #[test] @@ -63,8 +68,14 @@ fn works() { mytest::foo(false); mytest::A::new().foo(); }} - ", name)) - .file("benches/foo.rs", &format!(" + ", + name + ), + ) + .file( + "benches/foo.rs", + &format!( + " #![feature(test)] extern crate test; extern crate {} as mytest; @@ -73,14 +84,18 @@ fn works() { fn foo(b: &mut test::Bencher) {{ b.iter(|| mytest::foo(false)); }} - ", name)); + ", + name + ), + ); let (root, target_dir) = p.build(); let mut cmd = Command::new("cargo"); cmd.arg("test") - .arg("--test").arg("foo") - .arg("--bench").arg("foo") + .arg("--test") + .arg("foo") + .arg("--bench") + .arg("foo") .current_dir(&root) .env("CARGO_TARGET_DIR", &target_dir); run(&mut cmd, "cargo"); } - diff --git a/tests/all/simple.rs b/tests/all/simple.rs index f0b43da0..69afbf4f 100644 --- a/tests/all/simple.rs +++ b/tests/all/simple.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn add() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -37,8 +39,11 @@ fn add() { return a } } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -49,14 +54,17 @@ fn add() { assert.strictEqual(wasm.get2(true), 2); assert.strictEqual(wasm.return_and_take_bool(true, false), false); } - "#) + "#, + ) .test(); } #[test] fn string_arguments() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -73,22 +81,28 @@ fn string_arguments() { pub fn assert_foo(a: &str) { assert_eq!(a, "foo"); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out"; export function test() { wasm.assert_foo("foo"); wasm.assert_foo_and_bar("foo2", "bar"); } - "#) + "#, + ) .test(); } #[test] fn return_a_string() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -104,8 +118,11 @@ fn return_a_string() { pub fn concat(a: &str, b: &str, c: i8) -> String { format!("{} {} {}", a, b, c) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -115,14 +132,17 @@ fn return_a_string() { assert.strictEqual(wasm.concat("a", "b", 3), "a b 3"); assert.strictEqual(wasm.concat("c", "d", -2), "c d -2"); } - "#) + "#, + ) .test(); } #[test] fn exceptions() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -134,8 +154,11 @@ fn exceptions() { #[wasm_bindgen] pub fn bar(_a: &str) {} - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -143,10 +166,14 @@ fn exceptions() { assert.throws(() => wasm.foo('a'), /expected a number argument/); assert.throws(() => wasm.bar(3), /expected a string argument/); } - "#) - .file("test.d.ts", r#" + "#, + ) + .file( + "test.d.ts", + r#" export function test(): void; - "#) + "#, + ) .test(); } @@ -187,18 +214,24 @@ fn exceptions() { #[test] fn other_exports() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #[no_mangle] pub extern fn foo(_a: u32) { } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out_bg"; export function test() { wasm.foo(2); } - "#) + "#, + ) .test(); } @@ -206,7 +239,9 @@ fn other_exports() { fn no_std() { project() .no_std(true) - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![no_std] #![allow(dead_code)] @@ -229,28 +264,37 @@ fn no_std() { #[wasm_bindgen] pub fn foo(_a: u32) {} - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out_bg"; export function test() { // mostly just testing the project compiles here wasm.foo(1); } - "#) - .file("foo.js", r#" + "#, + ) + .file( + "foo.js", + r#" export class Js { init() { } } - "#) + "#, + ) .test(); } #[test] fn no_std_class() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] #![no_std] #![allow(dead_code)] @@ -282,14 +326,18 @@ fn no_std_class() { pub fn foo(&self) {} pub fn bar(&mut self) {} } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as wasm from "./out_bg"; export function test() { // mostly just testing the project compiles here wasm.foo(1); } - "#) + "#, + ) .test(); } diff --git a/tests/all/slice.rs b/tests/all/slice.rs index 617802af..200edac9 100644 --- a/tests/all/slice.rs +++ b/tests/all/slice.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn export() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -24,8 +26,11 @@ fn export() { doit! { i8 u8 i16 u16 i32 u32 f32 f64 } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -76,14 +81,17 @@ fn export() { f64[1] = 2; assert_arrays_equal(wasm.f64(f64), f64); } - "#) + "#, + ) .test(); } #[test] fn import() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -118,8 +126,11 @@ fn import() { (rust_f32, js_f32, f32) (rust_f64, js_f64, f64) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -225,14 +236,17 @@ fn import() { f64[1] = 2; assert_arrays_equal(wasm.rust_f64(f64), f64); } - "#) + "#, + ) .test(); } #[test] fn pass_array_works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -261,8 +275,11 @@ fn pass_array_works() { (rust_f32, f32) (rust_f64, f64) } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" const wasm = require("./out"); module.exports.test = function() { @@ -275,14 +292,17 @@ fn pass_array_works() { wasm.rust_f32([1, 2]); wasm.rust_f64([1, 2]); }; - "#) + "#, + ) .test(); } #[test] fn import_mut() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -328,8 +348,11 @@ fn import_mut() { (rust_f32, js_f32, f32) (rust_f64, js_f64, f64) } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -353,14 +376,17 @@ fn import_mut() { export function test() { wasm.run(); } - "#) + "#, + ) .test(); } #[test] fn export_mut() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section)] extern crate wasm_bindgen; @@ -383,8 +409,11 @@ fn export_mut() { doit! { i8 u8 i16 u16 i32 u32 f32 f64 } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -412,14 +441,17 @@ fn export_mut() { run(new Float32Array(3), wasm.f32); run(new Float64Array(3), wasm.f64); } - "#) + "#, + ) .test(); } #[test] fn return_vec_ok() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -461,8 +493,11 @@ fn return_vec_ok() { pub fn main() { } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import * as wasm from "./out"; @@ -485,7 +520,7 @@ fn return_vec_ok() { assert.strictEqual(bad[8], 9); } } - "#) + "#, + ) .test(); } - diff --git a/tests/all/structural.rs b/tests/all/structural.rs index 4cffe525..6d7ad574 100644 --- a/tests/all/structural.rs +++ b/tests/all/structural.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -28,8 +30,11 @@ fn works() { a.set_baz(2); assert_eq!(a.baz(), 2); } - "#) - .file("test.ts", r#" + "#, + ) + .file( + "test.ts", + r#" import * as assert from "assert"; import { run } from "./out"; @@ -41,8 +46,7 @@ fn works() { }); assert.strictEqual(called, true); } - "#) + "#, + ) .test(); } - - diff --git a/tests/all/u64.rs b/tests/all/u64.rs index 6fc4cc6c..725897a5 100644 --- a/tests/all/u64.rs +++ b/tests/all/u64.rs @@ -4,7 +4,9 @@ use super::project; fn works() { project() .requires_bigint() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; @@ -42,8 +44,11 @@ fn works() { #[wasm_bindgen] pub fn u64_slice(a: &[u64]) -> Vec { a.to_vec() } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" import * as wasm from './out'; function assertEq(a, b) { @@ -95,6 +100,7 @@ fn works() { export function js_i64_round(a) { return a; } export function js_u64_round(a) { return a; } - "#) + "#, + ) .test(); } diff --git a/tests/all/validate_prt.rs b/tests/all/validate_prt.rs index 53c59a65..01b62b43 100644 --- a/tests/all/validate_prt.rs +++ b/tests/all/validate_prt.rs @@ -3,7 +3,9 @@ use super::project; #[test] fn works() { project() - .file("src/lib.rs", r#" + .file( + "src/lib.rs", + r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] extern crate wasm_bindgen; use wasm_bindgen::prelude::*; @@ -26,8 +28,11 @@ fn works() { } #[wasm_bindgen] pub fn eat(_fruit: Fruit) { } - "#) - .file("test.js", r#" + "#, + ) + .file( + "test.js", + r#" import * as wasm from './out'; const targetMessage = 'Attempt to use a moved value'; function assertEq(a, b) { @@ -64,6 +69,7 @@ fn works() { assertEq(e.message, targetMessage); } } - "#) + "#, + ) .test(); } From 7626b55d0062bb051d646e041974efdc7e966a1d Mon Sep 17 00:00:00 2001 From: "R. Andrew Ohana" Date: Fri, 15 Jun 2018 23:39:51 -0700 Subject: [PATCH 13/48] fix up some strings that looked funky after rustfmt --- crates/cli-support/src/js/js2rust.rs | 2 +- crates/cli-support/src/js/mod.rs | 316 ++++++++++++++------------- crates/cli-support/src/js/rust2js.rs | 26 +-- crates/cli-support/src/lib.rs | 2 +- crates/cli-support/src/wasm2es6js.rs | 27 ++- 5 files changed, 193 insertions(+), 180 deletions(-) diff --git a/crates/cli-support/src/js/js2rust.rs b/crates/cli-support/src/js/js2rust.rs index 0a4eeb7c..10448747 100644 --- a/crates/cli-support/src/js/js2rust.rs +++ b/crates/cli-support/src/js/js2rust.rs @@ -393,7 +393,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> { \n}} finally {{\n\ {} }}\n\ - ", + ", &invoc, &self.finally, ) }; diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 74ad6255..7ac84b6e 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -113,7 +113,7 @@ impl<'a> Context<'a> { " if (typeof(val) === 'number') throw new Error('corrupt slab'); val.cnt += 1; - ", + ", ) } else { String::from("val.cnt += 1;") @@ -130,17 +130,20 @@ impl<'a> Context<'a> { {} return idx; }} - ", + ", bump_cnt )) })?; self.bind("__wbindgen_object_drop_ref", &|me| { me.expose_drop_ref(); - Ok("function(i) { - dropRef(i); - }" - .to_string()) + Ok(String::from( + " + function(i) { + dropRef(i); + } + ", + )) })?; self.bind("__wbindgen_string_new", &|me| { @@ -151,40 +154,44 @@ impl<'a> Context<'a> { function(p, l) { return addHeapObject(getStringFromWasm(p, l)); } - ", + ", )) })?; self.bind("__wbindgen_number_new", &|me| { me.expose_add_heap_object(); Ok(String::from( - "function(i) { - return addHeapObject(i); - }", + " + function(i) { + return addHeapObject(i); + } + ", )) })?; self.bind("__wbindgen_number_get", &|me| { me.expose_get_object(); me.expose_uint8_memory(); - Ok(format!( + Ok(String::from( " - function(n, invalid) {{ + function(n, invalid) { let obj = getObject(n); if (typeof(obj) === 'number') return obj; getUint8Memory()[invalid] = 1; return 0; - }} - " + } + ", )) })?; self.bind("__wbindgen_undefined_new", &|me| { me.expose_add_heap_object(); Ok(String::from( - "function() { - return addHeapObject(undefined); - }", + " + function() { + return addHeapObject(undefined); + } + ", )) })?; @@ -195,7 +202,7 @@ impl<'a> Context<'a> { function() { return addHeapObject(null); } - ", + ", )) })?; @@ -206,7 +213,7 @@ impl<'a> Context<'a> { function(idx) { return getObject(idx) === null ? 1 : 0; } - ", + ", )) })?; @@ -217,7 +224,7 @@ impl<'a> Context<'a> { function(idx) { return getObject(idx) === undefined ? 1 : 0; } - ", + ", )) })?; @@ -228,7 +235,7 @@ impl<'a> Context<'a> { function(v) { return addHeapObject(v === 1); } - ", + ", )) })?; @@ -244,25 +251,25 @@ impl<'a> Context<'a> { return 2; } } - ", + ", )) })?; self.bind("__wbindgen_symbol_new", &|me| { me.expose_get_string_from_wasm(); me.expose_add_heap_object(); - Ok(format!( + Ok(String::from( " - function(ptr, len) {{ + function(ptr, len) { let a; - if (ptr === 0) {{ + if (ptr === 0) { a = Symbol(); - }} else {{ + } else { a = Symbol(getStringFromWasm(ptr, len)); - }} + } return addHeapObject(a); - }} - " + } + ", )) })?; @@ -273,7 +280,7 @@ impl<'a> Context<'a> { function(i) { return typeof(getObject(i)) === 'symbol' ? 1 : 0; } - ", + ", )) })?; @@ -290,7 +297,7 @@ impl<'a> Context<'a> { getUint32Memory()[len_ptr / 4] = len; return ptr; } - ", + ", )) })?; @@ -303,7 +310,7 @@ impl<'a> Context<'a> { obj.a = obj.b = 0; dropRef(i); } - ", + ", )) })?; @@ -314,7 +321,7 @@ impl<'a> Context<'a> { function(i) { dropRef(i); } - ", + ", )) })?; @@ -326,7 +333,7 @@ impl<'a> Context<'a> { function(ptr, len) { return addHeapObject(JSON.parse(getStringFromWasm(ptr, len))); } - ", + ", )) })?; @@ -341,7 +348,7 @@ impl<'a> Context<'a> { getUint32Memory()[ptrptr / 4] = ptr; return len; } - ", + ", )) })?; @@ -352,7 +359,7 @@ impl<'a> Context<'a> { function(a, b) { return getObject(a) === getObject(b) ? 1 : 0; } - ", + ", )) })?; @@ -365,35 +372,36 @@ impl<'a> Context<'a> { // isn't gc'd). self.bind("__wbindgen_throw", &|me| { me.expose_get_string_from_wasm(); - Ok(format!( + Ok(String::from( " - function(ptr, len) {{ + function(ptr, len) { throw new Error(getStringFromWasm(ptr, len)); - }} - " + } + ", )) })?; self.rewrite_imports(module_name); let mut js = if self.config.no_modules { - format!(" - (function() {{ - var wasm; - const __exports = {{}}; - {globals} - function init(wasm_path) {{ - return fetch(wasm_path) - .then(response => response.arrayBuffer()) - .then(buffer => WebAssembly.instantiate(buffer, {{ './{module}': __exports }})) - .then(({{instance}}) => {{ - wasm = init.wasm = instance.exports; - return; - }}); - }}; - self.{global_name} = Object.assign(init, __exports); - }})(); - ", + format!( + " + (function() {{ + var wasm; + const __exports = {{}}; + {globals} + function init(wasm_path) {{ + return fetch(wasm_path) + .then(response => response.arrayBuffer()) + .then(buffer => WebAssembly.instantiate(buffer, {{ './{module}': __exports }})) + .then(({{instance}}) => {{ + wasm = init.wasm = instance.exports; + return; + }}); + }}; + self.{global_name} = Object.assign(init, __exports); + }})(); + ", globals = self.globals, module = module_name, global_name = self.config.no_modules_global @@ -476,7 +484,7 @@ impl<'a> Context<'a> { this.ptr = args[0].ptr; return; }} - ", + ", name )); @@ -488,7 +496,7 @@ impl<'a> Context<'a> { // This invocation of new will call this constructor with a ConstructorToken let instance = {class}.{constructor}(...args); this.ptr = instance.ptr; - ", + ", class = name, constructor = constructor )); @@ -510,7 +518,7 @@ impl<'a> Context<'a> { constructor(ptr) {{ this.ptr = ptr; }} - ", + ", name )); } @@ -523,10 +531,10 @@ impl<'a> Context<'a> { &new_name, &format!( " - function(ptr) {{ - return addHeapObject({}.__construct(ptr)); - }} - ", + function(ptr) {{ + return addHeapObject({}.__construct(ptr)); + }} + ", name ), None, @@ -578,7 +586,7 @@ impl<'a> Context<'a> { this.ptr = 0; wasm.{}(ptr); }} - ", + ", shared::free_function(&name) )); ts_dst.push_str("free(): void;\n"); @@ -714,7 +722,7 @@ impl<'a> Context<'a> { String::from( " if ((idx & 1) === 1) throw new Error('cannot drop ref of stack objects'); - ", + ", ) } else { String::new() @@ -725,14 +733,14 @@ impl<'a> Context<'a> { if (typeof(obj) === 'number') throw new Error('corrupt slab'); obj.cnt -= 1; if (obj.cnt > 0) return; - ", + ", ) } else { String::from( " obj.cnt -= 1; if (obj.cnt > 0) return; - ", + ", ) }; self.global(&format!( @@ -745,7 +753,7 @@ impl<'a> Context<'a> { slab[idx >> 1] = slab_next; slab_next = idx >> 1; }} - ", + ", validate_owned, dec_ref )); } @@ -767,7 +775,7 @@ impl<'a> Context<'a> { if (stack.length === 0) return; throw new Error('stack is not currently empty'); } - ", + ", None, ); } @@ -789,13 +797,13 @@ impl<'a> Context<'a> { "assertSlabEmpty", &format!( " - function() {{ - for (let i = {}; i < slab.length; i++) {{ - if (typeof(slab[i]) === 'number') continue; - throw new Error('slab is not currently empty'); + function() {{ + for (let i = {}; i < slab.length; i++) {{ + if (typeof(slab[i]) === 'number') continue; + throw new Error('slab is not currently empty'); + }} }} - }} - ", + ", initial_values.len() ), None, @@ -808,11 +816,11 @@ impl<'a> Context<'a> { return; } self.expose_global_slab(); - self.global(&format!( + self.global( " let slab_next = slab.length; - " - )); + ", + ); } fn expose_get_object(&mut self) { @@ -827,13 +835,13 @@ impl<'a> Context<'a> { " if (typeof(val) === 'number') throw new Error('corrupt slab'); return val.obj; - ", + ", ) } else { String::from( " return val.obj; - ", + ", ) }; self.global(&format!( @@ -846,7 +854,7 @@ impl<'a> Context<'a> { {} }} }} - ", + ", get_obj )); } @@ -860,7 +868,7 @@ impl<'a> Context<'a> { function _assertNum(n) {{ if (typeof(n) !== 'number') throw new Error('expected a number argument'); }} - " + " )); } @@ -875,7 +883,7 @@ impl<'a> Context<'a> { throw new Error('expected a boolean argument'); }} }} - " + " )); } @@ -902,7 +910,7 @@ impl<'a> Context<'a> { getUint8Memory().set(buf, ptr); return [ptr, buf.length]; }} - ", + ", debug )); Ok(()) @@ -956,7 +964,7 @@ impl<'a> Context<'a> { {}().set(arg, ptr / {size}); return [ptr, arg.length]; }} - ", + ", name, delegate, size = size @@ -969,25 +977,25 @@ impl<'a> Context<'a> { return; } if self.config.nodejs { - self.global(&format!( + self.global( " const TextEncoder = require('util').TextEncoder; - " - )); + ", + ); } else if !(self.config.browser || self.config.no_modules) { - self.global(&format!( + self.global( " const TextEncoder = typeof self === 'object' && self.TextEncoder ? self.TextEncoder : require('util').TextEncoder; - " - )); + ", + ); } - self.global(&format!( + self.global( " let cachedEncoder = new TextEncoder('utf-8'); - " - )); + ", + ); } fn expose_text_decoder(&mut self) { @@ -995,25 +1003,25 @@ impl<'a> Context<'a> { return; } if self.config.nodejs { - self.global(&format!( + self.global( " const TextDecoder = require('util').TextDecoder; - " - )); + ", + ); } else if !(self.config.browser || self.config.no_modules) { - self.global(&format!( + self.global( " const TextDecoder = typeof self === 'object' && self.TextDecoder ? self.TextDecoder : require('util').TextDecoder; - " - )); + ", + ); } - self.global(&format!( + self.global( " let cachedDecoder = new TextDecoder('utf-8'); - " - )); + ", + ); } fn expose_constructor_token(&mut self) { @@ -1028,7 +1036,7 @@ impl<'a> Context<'a> { this.ptr = ptr; } } - ", + ", ); } @@ -1038,13 +1046,13 @@ impl<'a> Context<'a> { } self.expose_text_decoder(); self.expose_uint8_memory(); - self.global(&format!( + self.global( " - function getStringFromWasm(ptr, len) {{ + function getStringFromWasm(ptr, len) { return cachedDecoder.decode(getUint8Memory().subarray(ptr, ptr + len)); - }} - " - )); + } + ", + ); } fn expose_get_array_js_value_from_wasm(&mut self) { @@ -1053,19 +1061,19 @@ impl<'a> Context<'a> { } self.expose_get_array_u32_from_wasm(); self.expose_take_object(); - self.global(&format!( + self.global( " - function getArrayJsValueFromWasm(ptr, len) {{ + function getArrayJsValueFromWasm(ptr, len) { const mem = getUint32Memory(); const slice = mem.subarray(ptr / 4, ptr / 4 + len); const result = []; - for (let i = 0; i < slice.length; i++) {{ + for (let i = 0; i < slice.length; i++) { result.push(takeObject(slice[i])); - }} + } return result; - }} - " - )); + } + ", + ); } fn expose_get_array_i8_from_wasm(&mut self) { @@ -1127,7 +1135,7 @@ impl<'a> Context<'a> { function {name}(ptr, len) {{ return {mem}().subarray(ptr / {size}, ptr / {size} + len); }} - ", + ", name = name, mem = mem, size = size, @@ -1240,7 +1248,7 @@ impl<'a> Context<'a> { }} return cache{name}; }} - ", + ", name = name, js = js, )); @@ -1250,16 +1258,16 @@ impl<'a> Context<'a> { if !self.exposed_globals.insert("assert_class") { return; } - self.global(&format!( + self.global( " - function _assertClass(instance, klass) {{ - if (!(instance instanceof klass)) {{ - throw new Error(`expected instance of ${{klass.name}}`); - }} + function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } return instance.ptr; - }} - " - )); + } + ", + ); } fn expose_borrowed_objects(&mut self) { @@ -1267,14 +1275,14 @@ impl<'a> Context<'a> { return; } self.expose_global_stack(); - self.global(&format!( + self.global( " - function addBorrowedObject(obj) {{ + function addBorrowedObject(obj) { stack.push(obj); return ((stack.length - 1) << 1) | 1; - }} - " - )); + } + ", + ); } fn expose_take_object(&mut self) { @@ -1283,15 +1291,15 @@ impl<'a> Context<'a> { } self.expose_get_object(); self.expose_drop_ref(); - self.global(&format!( + self.global( " - function takeObject(idx) {{ + function takeObject(idx) { const ret = getObject(idx); dropRef(idx); return ret; - }} - " - )); + } + ", + ); } fn expose_add_heap_object(&mut self) { @@ -1305,13 +1313,13 @@ impl<'a> Context<'a> { " if (typeof(next) !== 'number') throw new Error('corrupt slab'); slab_next = next; - ", + ", ) } else { String::from( " slab_next = next; - ", + ", ) }; self.global(&format!( @@ -1324,7 +1332,7 @@ impl<'a> Context<'a> { slab[idx] = {{ obj, cnt: 1 }}; return idx << 1; }} - ", + ", set_slab_next )); } @@ -1441,7 +1449,7 @@ impl<'a> Context<'a> { const idx = globalArgumentPtr() / 4 + arg; return getUint32Memory()[idx]; } - ", + ", ); Ok(()) } @@ -1455,12 +1463,12 @@ impl<'a> Context<'a> { " let cachedGlobalArgumentPtr = null; function globalArgumentPtr() { - if (cachedGlobalArgumentPtr === null) {{ + if (cachedGlobalArgumentPtr === null) { cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr(); - }} + } return cachedGlobalArgumentPtr; } - ", + ", ); Ok(()) } @@ -1488,7 +1496,7 @@ impl<'a> Context<'a> { } throw new Error('descriptor not found'); } - ", + ", ); } @@ -1754,10 +1762,10 @@ impl<'a, 'b> SubContext<'a, 'b> { &import.shim, &format!( " - function() {{ - return addHeapObject({}); - }} - ", + function() {{ + return addHeapObject({}); + }} + ", obj ), None, @@ -1797,7 +1805,7 @@ impl<'a, 'b> SubContext<'a, 'b> { format!( "function(y) {{ return this.{}; - }}", + }}", g ) } else { @@ -1806,7 +1814,7 @@ impl<'a, 'b> SubContext<'a, 'b> { "GetOwnOrInheritedPropertyDescriptor\ ({}{}, '{}').get", class, - if is_static { "" } else { ".prototype " }, + if is_static { "" } else { ".prototype" }, g, ) } @@ -1824,7 +1832,7 @@ impl<'a, 'b> SubContext<'a, 'b> { "GetOwnOrInheritedPropertyDescriptor\ ({}{}, '{}').set", class, - if is_static { "" } else { ".prototype " }, + if is_static { "" } else { ".prototype" }, s, ) } @@ -1861,7 +1869,7 @@ impl<'a, 'b> SubContext<'a, 'b> { self.cx.global(&format!( " const {}_target = {}; - ", + ", import.shim, target )); format!( @@ -1877,7 +1885,7 @@ impl<'a, 'b> SubContext<'a, 'b> { self.cx.global(&format!( " const {}_target = {}; - ", + ", import.shim, name )); format!("{}_target", import.shim) diff --git a/crates/cli-support/src/js/rust2js.rs b/crates/cli-support/src/js/rust2js.rs index 36bd591e..3687c948 100644 --- a/crates/cli-support/src/js/rust2js.rs +++ b/crates/cli-support/src/js/rust2js.rs @@ -271,7 +271,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> { const mem = getUint32Memory(); mem[ret / 4] = retptr; mem[ret / 4 + 1] = retlen; - ", + ", f ); return Ok(()); @@ -336,12 +336,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> { invoc = format!( "\ - try {{\n\ - {} - }} catch (e) {{\n\ - {} - }}\ - ", + try {{\n\ + {} + }} catch (e) {{\n\ + {} + }}\ + ", &invoc, catch ); }; @@ -349,12 +349,12 @@ impl<'a, 'b> Rust2Js<'a, 'b> { if self.finally.len() > 0 { invoc = format!( "\ - try {{\n\ - {} - }} finally {{\n\ - {} - }}\ - ", + try {{\n\ + {} + }} finally {{\n\ + {} + }}\ + ", &invoc, &self.finally ); } diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index 5af6fe17..df7ce473 100644 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -212,7 +212,7 @@ impl Bindgen { const wasmModule = new WebAssembly.Module(bytes); const wasmInstance = new WebAssembly.Instance(wasmModule, imports); module.exports = wasmInstance.exports; - ", + ", path.file_name().unwrap().to_str().unwrap() )); diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index 9ab1aeee..45fb63ec 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -77,7 +77,7 @@ impl Output { exports.push_str(&format!( " export const {}: WebAssembly.Memory; - ", + ", entry.field() )); continue; @@ -111,7 +111,7 @@ impl Output { exports.push_str(&format!( " export function {name}({args}): {ret}; - ", + ", name = entry.field(), args = args, ret = if ty.return_type().is_some() { @@ -212,7 +212,7 @@ impl Output { export function {name}({args}) {{ {ret} wasm.exports.{name}({args}); }} - ", + ", name = entry.field(), args = args, ret = if ty.return_type().is_some() { @@ -224,11 +224,13 @@ impl Output { } } let inst = format!( - "WebAssembly.instantiate(bytes,{{ {imports} }}) + " + WebAssembly.instantiate(bytes,{{ {imports} }}) .then(obj => {{ wasm = obj.instance; {memory} - }})", + }}) + ", imports = imports, memory = if export_mem { "memory = wasm.exports.memory;" @@ -247,7 +249,8 @@ impl Output { bytes = Uint8Array.from(atob(base64), c => c.charCodeAt(0)); }} else {{ bytes = Buffer.from(base64, 'base64'); - }}", + }} + ", base64 = base64::encode(&wasm) ), inst, @@ -256,9 +259,11 @@ impl Output { ( String::new(), format!( - "fetch('{path}') - .then(res => res.arrayBuffer()) - .then(bytes => {inst})", + " + fetch('{path}') + .then(res => res.arrayBuffer()) + .then(bytes => {inst}) + ", path = path, inst = inst ), @@ -274,7 +279,7 @@ impl Output { {mem_export} export const booted = {booted}; {exports} - ", + ", bytes = bytes, booted = booted, js_imports = js_imports, @@ -440,7 +445,7 @@ impl Output { Infinity, }}, imports, mem); {js_exports} - ", + ", js_imports = js_imports, js_init_mem = js_init_mem, asm_func = asm_func, From 3e84b97de2511a760e31624533ad2fcc27abd1d6 Mon Sep 17 00:00:00 2001 From: Kevin Hoffman Date: Thu, 28 Jun 2018 12:46:53 -0400 Subject: [PATCH 14/48] Binding for Math.cos,cosh,exp,expml,fround,imul,log,log10,log1p,log2 --- .gitignore | 1 + src/js.rs | 59 ++++++++ tests/all/js_globals/Math.rs | 282 +++++++++++++++++++++++++++++++++++ 3 files changed, 342 insertions(+) diff --git a/.gitignore b/.gitignore index c4ab28c3..3e7a542c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea /target/ **/*.rs.bk Cargo.lock diff --git a/src/js.rs b/src/js.rs index fd16b23e..9028f640 100644 --- a/src/js.rs +++ b/src/js.rs @@ -387,12 +387,71 @@ extern { #[wasm_bindgen(static_method_of = Math)] pub fn clz32(x: i32) -> Number; + /// The Math.cos() static function returns the cosine of the specified angle, + /// which must be specified in radians. This value is length(adjacent)/length(hypotenuse). + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos + #[wasm_bindgen(static_method_of = Math)] + pub fn cos(x: f32) -> Number; + + + /// The Math.cosh() function returns the hyperbolic cosine of a number, + /// that can be expressed using the constant e. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh + #[wasm_bindgen(static_method_of = Math)] + pub fn cosh(x: f32) -> Number; + + /// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number + /// (also known as Napier's constant), the base of the natural logarithms. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp + #[wasm_bindgen(static_method_of = Math)] + pub fn exp(x: f32) -> Number; + + /// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the + /// natural logarithms. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 + #[wasm_bindgen(static_method_of = Math)] + pub fn expm1(x: f32) -> Number; + /// The Math.floor() function returns the largest integer less than or /// equal to a given number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor #[wasm_bindgen(static_method_of = Math)] pub fn floor(x: f32) -> Number; + + /// The Math.fround() function returns the nearest 32-bit single precision float representation + /// of a Number. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround + #[wasm_bindgen(static_method_of = Math)] + pub fn fround(x: f32) -> Number; + + /// The Math.imul() function returns the result of the C-like 32-bit multiplication of the + /// two parameters. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul + #[wasm_bindgen(static_method_of = Math)] + pub fn imul(x: i32, y: i32) -> Number; + + /// The Math.log() function returns the natural logarithm (base e) of a number. + /// The JavaScript Math.log() function is equivalent to ln(x) in mathematics. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log + #[wasm_bindgen(static_method_of = Math)] + pub fn log(x: f32) -> Number; + + /// The Math.log10() function returns the base 10 logarithm of a number. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 + #[wasm_bindgen(static_method_of = Math)] + pub fn log10(x: f32) -> Number; + + /// The Math.log1p() function returns the natural logarithm (base e) of 1 + a number. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p + #[wasm_bindgen(static_method_of = Math)] + pub fn log1p(x: f32) -> Number; + + /// The Math.log2() function returns the base 2 logarithm of a number. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 + #[wasm_bindgen(static_method_of = Math)] + pub fn log2(x: f32) -> Number; + } // Number. diff --git a/tests/all/js_globals/Math.rs b/tests/all/js_globals/Math.rs index df3038f4..e578bf82 100644 --- a/tests/all/js_globals/Math.rs +++ b/tests/all/js_globals/Math.rs @@ -78,6 +78,7 @@ fn acosh() { export function test() { assert.equal(wasm.acosh(1), 0); assert.equal(wasm.acosh(2), Math.acosh(2)); + assert.equal(wasm.acosh(2), Math.acosh(2)); } "#) .test() @@ -293,6 +294,117 @@ fn clz32() { .test() } +#[test] +fn cos() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn cos(x: f32) -> js::Number { + js::Math::cos(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.cos(0), 1); + // other assertions failing due to rounding errors + } + "#) + .test() +} + +#[test] +fn cosh() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn cosh(x: f32) -> js::Number { + js::Math::cosh(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.cosh(0), 1); + assert.equal(wasm.cosh(2), 3.7621956910836314); + } + "#) + .test() +} + +#[test] +fn exp() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn exp(x: f32) -> js::Number { + js::Math::exp(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.exp(0), 1); + assert.equal(wasm.exp(-1), 0.36787944117144233); + assert.equal(wasm.exp(2), 7.38905609893065); + } + "#) + .test() +} + +#[test] +fn expm1() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn expm1(x: f32) -> js::Number { + js::Math::expm1(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.expm1(0), 0); + assert.equal(wasm.expm1(1), 1.718281828459045); + assert.equal(wasm.expm1(-1), -0.6321205588285577); + assert.equal(wasm.expm1(2), 6.38905609893065); + } + "#) + .test() +} + #[test] fn floor() { project() @@ -319,3 +431,173 @@ fn floor() { "#) .test() } + +#[test] +fn fround() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn fround(x: f32) -> js::Number { + js::Math::fround(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.fround(5.5), 5.5); + assert.equal(wasm.fround(5.05), 5.050000190734863); + assert.equal(wasm.fround(5), 5); + assert.equal(wasm.fround(-5.05), -5.050000190734863); + } + "#) + .test() +} + +#[test] +fn imul() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn imul(x: i32, y:i32) -> js::Number { + js::Math::imul(x, y) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.imul(3, 4), 12); + assert.equal(wasm.imul(-5, 12), -60); + assert.equal(wasm.imul(0xffffffff, 5), Math.imul(0xffffffff, 5)); + } + "#) + .test() +} + +#[test] +fn log() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn log(x: f32) -> js::Number { + js::Math::log(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.log(8) / wasm.log(2), 3); + assert.equal(wasm.log(625) / wasm.log(5), 4); + } + "#) + .test() +} + +#[test] +fn log10() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn log10(x: f32) -> js::Number { + js::Math::log10(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.log10(100000), 5); + assert.equal(wasm.log10(1), 0); + assert.equal(wasm.log10(2), 0.3010299956639812); + } + "#) + .test() +} + +#[test] +fn log1p() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn log1p(x: f32) -> js::Number { + js::Math::log1p(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.log1p(1), 0.6931471805599453); + assert.equal(wasm.log1p(0), 0); + assert.equal(wasm.log1p(-1), -Infinity); + assert(isNaN(wasm.log1p(-2))); + } + "#) + .test() +} + +#[test] +fn log2() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn log2(x: f32) -> js::Number { + js::Math::log2(x) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.log2(3), 1.584962500721156); + assert.equal(wasm.log2(2), 1); + assert.equal(wasm.log2(1), 0); + assert.equal(wasm.log2(0), -Infinity); + } + "#) + .test() +} \ No newline at end of file From 9dd950a1cbe8970921c581f261a0c2f0ee8c8ac5 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 28 Jun 2018 09:53:36 -0700 Subject: [PATCH 15/48] Add @jonathan-s to the team! \o/ --- guide/src/team.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/guide/src/team.md b/guide/src/team.md index 261be7f2..af30ec67 100644 --- a/guide/src/team.md +++ b/guide/src/team.md @@ -20,11 +20,12 @@ img { } -| [![](https://github.com/alexcrichton.png?size=117)][alexcrichton] | [![](https://github.com/fitzgen.png?size=117)][fitzgen] | [![](https://github.com/spastorino.png?size=117)][spastorino] | [![](https://github.com/ohanar.png?size=117)][ohanar] | +| [![](https://github.com/alexcrichton.png?size=117)][alexcrichton] | [![](https://github.com/fitzgen.png?size=117)][fitzgen] | [![](https://github.com/spastorino.png?size=117)][spastorino] | [![](https://github.com/ohanar.png?size=117)][ohanar] | [![](https://github.com/jonathan-s.png?size=117)][jonathan-s] | |:---:|:---:|:---:|:---:| -| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] | +| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] | [`jonathan-s`][jonathan-s] | [alexcrichton]: https://github.com/alexcrichton [fitzgen]: https://github.com/fitzgen [spastorino]: https://github.com/spastorino [ohanar]: https://github.com/ohanar +[jonathan-s]: https://github.com/jonathan-s From 81e68517f26f34ee8d2dd52aa2bf76e166855f37 Mon Sep 17 00:00:00 2001 From: Kevin Hoffman Date: Thu, 28 Jun 2018 15:05:10 -0400 Subject: [PATCH 16/48] Adding line separator in code docs above MDN URLs. --- src/js.rs | 11 ++++++++++- tests/all/js_globals/Math.rs | 3 +-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/js.rs b/src/js.rs index 9028f640..61ca9d52 100644 --- a/src/js.rs +++ b/src/js.rs @@ -389,6 +389,7 @@ extern { /// The Math.cos() static function returns the cosine of the specified angle, /// which must be specified in radians. This value is length(adjacent)/length(hypotenuse). + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos #[wasm_bindgen(static_method_of = Math)] pub fn cos(x: f32) -> Number; @@ -396,18 +397,21 @@ extern { /// The Math.cosh() function returns the hyperbolic cosine of a number, /// that can be expressed using the constant e. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh #[wasm_bindgen(static_method_of = Math)] pub fn cosh(x: f32) -> Number; /// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number /// (also known as Napier's constant), the base of the natural logarithms. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp #[wasm_bindgen(static_method_of = Math)] pub fn exp(x: f32) -> Number; /// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the /// natural logarithms. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 #[wasm_bindgen(static_method_of = Math)] pub fn expm1(x: f32) -> Number; @@ -421,23 +425,27 @@ extern { /// The Math.fround() function returns the nearest 32-bit single precision float representation /// of a Number. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround #[wasm_bindgen(static_method_of = Math)] pub fn fround(x: f32) -> Number; - + /// The Math.imul() function returns the result of the C-like 32-bit multiplication of the /// two parameters. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul #[wasm_bindgen(static_method_of = Math)] pub fn imul(x: i32, y: i32) -> Number; /// The Math.log() function returns the natural logarithm (base e) of a number. /// The JavaScript Math.log() function is equivalent to ln(x) in mathematics. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log #[wasm_bindgen(static_method_of = Math)] pub fn log(x: f32) -> Number; /// The Math.log10() function returns the base 10 logarithm of a number. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 #[wasm_bindgen(static_method_of = Math)] pub fn log10(x: f32) -> Number; @@ -448,6 +456,7 @@ extern { pub fn log1p(x: f32) -> Number; /// The Math.log2() function returns the base 2 logarithm of a number. + /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 #[wasm_bindgen(static_method_of = Math)] pub fn log2(x: f32) -> Number; diff --git a/tests/all/js_globals/Math.rs b/tests/all/js_globals/Math.rs index e578bf82..dc19c122 100644 --- a/tests/all/js_globals/Math.rs +++ b/tests/all/js_globals/Math.rs @@ -78,7 +78,6 @@ fn acosh() { export function test() { assert.equal(wasm.acosh(1), 0); assert.equal(wasm.acosh(2), Math.acosh(2)); - assert.equal(wasm.acosh(2), Math.acosh(2)); } "#) .test() @@ -315,7 +314,7 @@ fn cos() { export function test() { assert.equal(wasm.cos(0), 1); - // other assertions failing due to rounding errors + assert.equal(wasm.cos(1.5), Math.cos(1.5)); } "#) .test() From ab0546963b32f6870ab9aa8c724f24b2498b7b9a Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:51:39 +0200 Subject: [PATCH 17/48] feat(Map): add Map.clear --- src/js.rs | 12 ++++++++++++ tests/all/js_globals/Map.rs | 35 +++++++++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 48 insertions(+) create mode 100644 tests/all/js_globals/Map.rs diff --git a/src/js.rs b/src/js.rs index fd16b23e..bd7104a6 100644 --- a/src/js.rs +++ b/src/js.rs @@ -302,6 +302,18 @@ extern { pub fn to_string(this: &Function) -> JsString; } +// Map +#[wasm_bindgen] +extern { + pub type Map; + + /// The clear() method removes all elements from a Map object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear + #[wasm_bindgen(method)] + pub fn clear(this: &Map); +} + // Math #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs new file mode 100644 index 00000000..8b2b2df2 --- /dev/null +++ b/tests/all/js_globals/Map.rs @@ -0,0 +1,35 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn clear() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn map_clear(this: &js::Map) { + this.clear(); + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + map.set('foo', 'bar'); + map.set('bar', 'baz'); + assert.equal(map.size, 2); + wasm.map_clear(map); + assert.equal(map.size, 0); + + } + "#) + .test() +} \ No newline at end of file diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 4090fe04..f634773e 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -8,6 +8,7 @@ mod Boolean; mod Date; mod Function; mod JsString; +mod Map; mod Math; mod WeakMap; mod WeakSet; From f7e4019e72e5136e1e2a6f3a9edec0f87a43ac1d Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:52:27 +0200 Subject: [PATCH 18/48] feat(Map): add Map.delete --- src/js.rs | 6 ++++++ tests/all/js_globals/Map.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/js.rs b/src/js.rs index bd7104a6..b6a55114 100644 --- a/src/js.rs +++ b/src/js.rs @@ -312,6 +312,12 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear #[wasm_bindgen(method)] pub fn clear(this: &Map); + + /// The delete() method removes the specified element from a Map object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete + #[wasm_bindgen(method)] + pub fn delete(this: &Map, key: &str) -> bool; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index 8b2b2df2..a8a7ace3 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -32,4 +32,36 @@ fn clear() { } "#) .test() +} + +#[test] +fn delete() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn map_delete(this: &js::Map, key: &str) -> bool { + this.delete(key) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + map.set('foo', 'bar'); + assert.equal(map.size, 1); + assert.equal(wasm.map_delete(map, 'foo'), true); + assert.equal(wasm.map_delete(map, 'bar'), false); + assert.equal(map.size, 0); + + } + "#) + .test() } \ No newline at end of file From e0b399643aa42e15462b1aaddb2b30233fe3dfd5 Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:53:20 +0200 Subject: [PATCH 19/48] feat(Map): add Map.get --- src/js.rs | 6 ++++++ tests/all/js_globals/Map.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/js.rs b/src/js.rs index b6a55114..e53ae6da 100644 --- a/src/js.rs +++ b/src/js.rs @@ -318,6 +318,12 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete #[wasm_bindgen(method)] pub fn delete(this: &Map, key: &str) -> bool; + + /// The get() method returns a specified element from a Map object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get + #[wasm_bindgen(method)] + pub fn get(this: &Map, key: &JsValue) -> JsValue; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index a8a7ace3..1279c482 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -64,4 +64,35 @@ fn delete() { } "#) .test() +} + +#[test] +fn get() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn map_get(this: &js::Map, key: &JsValue) -> JsValue { + this.get(key) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + map.set('foo', 'bar'); + map.set(1, 2) + assert.equal(wasm.map_get(map, 'foo'), 'bar'); + assert.equal(wasm.map_get(map, 1), 2); + assert.equal(wasm.map_get(map, 2), undefined); + } + "#) + .test() } \ No newline at end of file From 07e61e11750efd2fae16d3f32afebd5a68cf9f49 Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:54:10 +0200 Subject: [PATCH 20/48] feat(Map): add Map.has --- src/js.rs | 7 +++++++ tests/all/js_globals/Map.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/js.rs b/src/js.rs index e53ae6da..171c9632 100644 --- a/src/js.rs +++ b/src/js.rs @@ -324,6 +324,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/get #[wasm_bindgen(method)] pub fn get(this: &Map, key: &JsValue) -> JsValue; + + /// The has() method returns a boolean indicating whether an element with + /// the specified key exists or not. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has + #[wasm_bindgen(method)] + pub fn has(this: &Map, key: &JsValue) -> bool; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index 1279c482..5c31c4c2 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -95,4 +95,33 @@ fn get() { } "#) .test() +} + +#[test] +fn has() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn has(this: &js::Map, key: &JsValue) -> bool { + this.has(key) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + map.set('foo', 'bar'); + assert.equal(wasm.has(map, 'foo'), true); + assert.equal(wasm.has(map, 'bar'), false); + } + "#) + .test() } \ No newline at end of file From 27ee57175ae8f41ba54c441a5d8409b4bfd12e37 Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:55:10 +0200 Subject: [PATCH 21/48] feat(Map): add Map.new --- src/js.rs | 7 +++++++ tests/all/js_globals/Map.rs | 28 ++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/src/js.rs b/src/js.rs index 171c9632..1e5d5f97 100644 --- a/src/js.rs +++ b/src/js.rs @@ -331,6 +331,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/has #[wasm_bindgen(method)] pub fn has(this: &Map, key: &JsValue) -> bool; + + /// The Map object holds key-value pairs. Any value (both objects and + /// primitive values) maybe used as either a key or a value. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map + #[wasm_bindgen(constructor)] + pub fn new() -> Map; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index 5c31c4c2..2bbdddd9 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -124,4 +124,32 @@ fn has() { } "#) .test() +} + +#[test] +fn new() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_map() -> js::Map { + js::Map::new() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = wasm.new_map(); + + assert.equal(map.size, 0); + } + "#) + .test() } \ No newline at end of file From 6f90bd677b4665418dd8dfd4f61197b496473cb7 Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:55:55 +0200 Subject: [PATCH 22/48] feat(Map): add Map.set --- src/js.rs | 7 +++++++ tests/all/js_globals/Map.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/src/js.rs b/src/js.rs index 1e5d5f97..fae6379d 100644 --- a/src/js.rs +++ b/src/js.rs @@ -338,6 +338,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map #[wasm_bindgen(constructor)] pub fn new() -> Map; + + /// The set() method adds or updates an element with a specified key + /// and value to a Map object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set + #[wasm_bindgen(method)] + pub fn set(this: &Map, key: &JsValue, value: &JsValue) -> Map; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index 2bbdddd9..049b0df6 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -152,4 +152,33 @@ fn new() { } "#) .test() +} + +#[test] +fn set() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn set(this: &js::Map, key: &JsValue, value: &JsValue) -> js::Map { + this.set(key, value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + const newMap = wasm.set(map, 'foo', 'bar'); + assert.equal(map.has('foo'), true); + assert.equal(newMap.has('foo'), true); + } + "#) + .test() } \ No newline at end of file From ea19775639eedb05ef8c274efa07b8b5627d80dc Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:56:49 +0200 Subject: [PATCH 23/48] feat(Map): add Map.size --- src/js.rs | 8 ++++++++ tests/all/js_globals/Map.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/js.rs b/src/js.rs index fae6379d..0b04b6d3 100644 --- a/src/js.rs +++ b/src/js.rs @@ -345,6 +345,14 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/set #[wasm_bindgen(method)] pub fn set(this: &Map, key: &JsValue, value: &JsValue) -> Map; + + /// The value of size is an integer representing how many entries + /// the Map object has. A set accessor function for size is undefined; + /// you can not change this property. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size + #[wasm_bindgen(method, getter, structural)] + pub fn size(this: &Map) -> Number; } // Math diff --git a/tests/all/js_globals/Map.rs b/tests/all/js_globals/Map.rs index 049b0df6..522e7fde 100644 --- a/tests/all/js_globals/Map.rs +++ b/tests/all/js_globals/Map.rs @@ -181,4 +181,33 @@ fn set() { } "#) .test() +} + +#[test] +fn size() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn map_size(this: &js::Map) -> js::Number { + this.size() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + map.set('foo', 'bar'); + map.set('bar', 'baz'); + assert.equal(wasm.map_size(map), 2); + } + "#) + .test() } \ No newline at end of file From 228abaa4ae8bb0bcf12ce984cd8d7e43eac819fa Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:58:34 +0200 Subject: [PATCH 24/48] feat(Map/MapIterator): add Map.entries --- src/js.rs | 14 +++++++++++ tests/all/js_globals/MapIterator.rs | 36 +++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 51 insertions(+) create mode 100644 tests/all/js_globals/MapIterator.rs diff --git a/src/js.rs b/src/js.rs index 0b04b6d3..21b51203 100644 --- a/src/js.rs +++ b/src/js.rs @@ -355,6 +355,20 @@ extern { pub fn size(this: &Map) -> Number; } +// Map Iterator +#[wasm_bindgen] +extern { + pub type MapIterator; + + /// The entries() method returns a new Iterator object that contains + /// the [key, value] pairs for each element in the Map object in + /// insertion order. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries + #[wasm_bindgen(method)] + pub fn entries(this: &Map) -> MapIterator; +} + // Math #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/MapIterator.rs b/tests/all/js_globals/MapIterator.rs new file mode 100644 index 00000000..54a4f4ab --- /dev/null +++ b/tests/all/js_globals/MapIterator.rs @@ -0,0 +1,36 @@ +#![allow(non_snake_case)] + +use project; + + +#[test] +fn entries() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn get_entries(this: &js::Map) -> js::MapIterator { + this.entries() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + const iterator = map.entries(); + const wasmIterator = wasm.get_entries(map); + map.set('foo', 'bar'); + map.set('bar', 'baz'); + + assert.equal(iterator.toString(), wasmIterator.toString()); + } + "#) + .test() +} \ No newline at end of file diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index f634773e..799ef023 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -9,6 +9,7 @@ mod Date; mod Function; mod JsString; mod Map; +mod MapIterator; mod Math; mod WeakMap; mod WeakSet; From fc131ee97e6c778a2568fe89f5eccb579418be4a Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 21:59:11 +0200 Subject: [PATCH 25/48] feat(Map/MapIterator): add Map.keys --- src/js.rs | 7 +++++++ tests/all/js_globals/MapIterator.rs | 32 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/js.rs b/src/js.rs index 21b51203..7336d658 100644 --- a/src/js.rs +++ b/src/js.rs @@ -367,6 +367,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries #[wasm_bindgen(method)] pub fn entries(this: &Map) -> MapIterator; + + /// The keys() method returns a new Iterator object that contains the + /// keys for each element in the Map object in insertion order. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys + #[wasm_bindgen(method)] + pub fn keys(this: &Map) -> MapIterator; } // Math diff --git a/tests/all/js_globals/MapIterator.rs b/tests/all/js_globals/MapIterator.rs index 54a4f4ab..bb560e42 100644 --- a/tests/all/js_globals/MapIterator.rs +++ b/tests/all/js_globals/MapIterator.rs @@ -33,4 +33,36 @@ fn entries() { } "#) .test() +} + +#[test] +fn keys() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn get_keys(this: &js::Map) -> js::MapIterator { + this.keys() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + const iterator = map.keys(); + const wasmIterator = wasm.get_keys(map); + map.set('foo', 'bar'); + map.set('bar', 'baz'); + + assert.equal(iterator.toString(), wasmIterator.toString()); + } + "#) + .test() } \ No newline at end of file From e0a70417ce46c792134082711c6ef4065302b07d Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 22:00:02 +0200 Subject: [PATCH 26/48] feat(Map/MapIterator): add Map.values --- src/js.rs | 7 +++++++ tests/all/js_globals/MapIterator.rs | 32 +++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/js.rs b/src/js.rs index 7336d658..3e59b63f 100644 --- a/src/js.rs +++ b/src/js.rs @@ -374,6 +374,13 @@ extern { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys #[wasm_bindgen(method)] pub fn keys(this: &Map) -> MapIterator; + + /// The values() method returns a new Iterator object that contains the + /// values for each element in the Map object in insertion order. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values + #[wasm_bindgen(method)] + pub fn values(this: &Map) -> MapIterator; } // Math diff --git a/tests/all/js_globals/MapIterator.rs b/tests/all/js_globals/MapIterator.rs index bb560e42..0bc79e25 100644 --- a/tests/all/js_globals/MapIterator.rs +++ b/tests/all/js_globals/MapIterator.rs @@ -65,4 +65,36 @@ fn keys() { } "#) .test() +} + +#[test] +fn values() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn get_values(this: &js::Map) -> js::MapIterator { + this.values() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const map = new Map(); + const iterator = map.keys(); + const wasmIterator = wasm.get_values(map); + map.set('foo', 'bar'); + map.set('bar', 'baz'); + + assert.equal(iterator.toString(), wasmIterator.toString()); + } + "#) + .test() } \ No newline at end of file From 9193218648a6e4f1c3e4254bb5433f59c53de219 Mon Sep 17 00:00:00 2001 From: Chris Kolodin Date: Thu, 28 Jun 2018 13:57:01 -0700 Subject: [PATCH 27/48] add bindings for array.prototype.some() (#341) following the example set in https://github.com/rustwasm/wasm-bindgen/pull/314 --- src/js.rs | 7 +++++++ tests/all/js_globals/Array.rs | 31 +++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/js.rs b/src/js.rs index fd16b23e..677f7a32 100644 --- a/src/js.rs +++ b/src/js.rs @@ -205,6 +205,13 @@ extern { #[wasm_bindgen(method)] pub fn slice(this: &Array, start: u32, end: u32) -> Array; + /// The some() method tests whether at least one element in the array passes the test implemented + /// by the provided function. + /// Note: This method returns false for any condition put on an empty array. + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some + #[wasm_bindgen(method)] + pub fn some(this: &Array, predicate: &mut FnMut(JsValue) -> bool) -> bool; + /// The sort() method sorts the elements of an array in place and returns /// the array. The sort is not necessarily stable. The default sort /// order is according to string Unicode code points. diff --git a/tests/all/js_globals/Array.rs b/tests/all/js_globals/Array.rs index 8e8173de..af11ce9c 100644 --- a/tests/all/js_globals/Array.rs +++ b/tests/all/js_globals/Array.rs @@ -143,6 +143,37 @@ fn sort() { .test() } +#[test] +fn some() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn has_elem(array: &js::Array, arg: JsValue) -> bool { + array.some(&mut |elem| arg == elem) + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let elements = ["z", 1, "y", 2]; + + assert.deepStrictEqual(wasm.has_elem(elements, 2), true); + assert.deepStrictEqual(wasm.has_elem(elements, "y"), true); + assert.deepStrictEqual(wasm.has_elem(elements, "not an element"), false); + } + "#) + .test() +} + #[test] fn last_index_of() { project() From d868ff26ef9875c302147304bc0363bcd86ab3b2 Mon Sep 17 00:00:00 2001 From: Jannik Keye Date: Thu, 28 Jun 2018 22:57:49 +0200 Subject: [PATCH 28/48] Add bindings for Set.xx (#347) * feat(Set): add Set.add * feat(Set): add Set.clear * feat(Set): add Set.delete * feat(Set): add Set.has * feat(Set): add Set.new * feat(Set): add Set.size * feat(Set/SetIterator): add Set.entries * feat(Set/SetIterator): add Set.keys * feat(Set/SetIterator): add Set.values --- src/js.rs | 77 ++++++++++++ tests/all/js_globals/Set.rs | 182 ++++++++++++++++++++++++++++ tests/all/js_globals/SetIterator.rs | 97 +++++++++++++++ tests/all/js_globals/mod.rs | 2 + 4 files changed, 358 insertions(+) create mode 100644 tests/all/js_globals/Set.rs create mode 100644 tests/all/js_globals/SetIterator.rs diff --git a/src/js.rs b/src/js.rs index 677f7a32..2114fa5b 100644 --- a/src/js.rs +++ b/src/js.rs @@ -619,6 +619,83 @@ extern { pub fn value_of(this: &Object) -> Object; } +// Set +#[wasm_bindgen] +extern { + pub type Set; + + /// The add() method appends a new element with a specified value to the + /// end of a Set object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/add + #[wasm_bindgen(method)] + pub fn add(this: &Set, value: &JsValue) -> Set; + + /// The clear() method removes all elements from a Set object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear + #[wasm_bindgen(method)] + pub fn clear(this: &Set); + + /// The delete() method removes the specified element from a Set object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete + #[wasm_bindgen(method)] + pub fn delete(this: &Set, value: &JsValue) -> bool; + + /// The has() method returns a boolean indicating whether an element + /// with the specified value exists in a Set object or not. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has + #[wasm_bindgen(method)] + pub fn has(this: &Set, value: &JsValue) -> bool; + + /// The Set object lets you store unique values of any type, whether primitive + /// values or object references. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set + #[wasm_bindgen(constructor)] + pub fn new() -> Set; + + /// The size accessor property returns the number of elements in a Set object. + /// + /// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Set/size + #[wasm_bindgen(method, getter, structural)] + pub fn size(this: &Set) -> Number; +} + +// SetIterator +#[wasm_bindgen] +extern { + pub type SetIterator; + + /// The entries() method returns a new Iterator object that contains + /// an array of [value, value] for each element in the Set object, + /// in insertion order. For Set objects there is no key like in + /// Map objects. However, to keep the API similar to the Map object, + /// each entry has the same value for its key and value here, so that + /// an array [value, value] is returned. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries + #[wasm_bindgen(method)] + pub fn entries(set: &Set) -> SetIterator; + + /// The keys() method is an alias for this method (for similarity with + /// Map objects); it behaves exactly the same and returns values + /// of Set elements. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values + #[wasm_bindgen(method)] + pub fn keys(set: &Set) -> SetIterator; + + /// The values() method returns a new Iterator object that contains the + /// values for each element in the Set object in insertion order. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values + #[wasm_bindgen(method)] + pub fn values(set: &Set) -> SetIterator; +} + // WeakMap #[wasm_bindgen] extern { diff --git a/tests/all/js_globals/Set.rs b/tests/all/js_globals/Set.rs new file mode 100644 index 00000000..8d1bdb15 --- /dev/null +++ b/tests/all/js_globals/Set.rs @@ -0,0 +1,182 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn add() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn add(this: &js::Set, value: &JsValue) -> js::Set { + this.add(value) + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([]); + + wasm.add(set, 100); + + + assert.equal(set.size, 1); + assert.equal(Array.from(set)[0], 100); + } + "#) + .test() +} + +#[test] +fn clear() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn clear(this: &js::Set) { + this.clear(); + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([1, 2, 3]); + + wasm.clear(set); + + assert.equal(set.size, 0); + } + "#) + .test() +} + +#[test] +fn delete() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn set_delete(this: &js::Set, value: &JsValue) -> bool { + this.delete(value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([1, 2, 3]); + + assert.equal(wasm.set_delete(set, 4), false); + assert.equal(wasm.set_delete(set, 2), true); + } + "#) + .test() +} + +#[test] +fn has() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn has(this: &js::Set, value: &JsValue) -> bool { + this.has(value) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([1, 2, 3]); + + assert.equal(wasm.has(set, 4), false); + assert.equal(wasm.has(set, 2), true); + } + "#) + .test() +} + +#[test] +fn new() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn new_set() -> js::Set { + js::Set::new() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = wasm.new_set(); + + assert.equal(set.size, 0); + } + "#) + .test() +} + +#[test] +fn size() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn size(this: &js::Set) -> js::Number { + this.size() + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([8, 5, 4, 3, 1, 2]); + + assert.equal(wasm.size(set), 6); + } + "#) + .test() +} \ No newline at end of file diff --git a/tests/all/js_globals/SetIterator.rs b/tests/all/js_globals/SetIterator.rs new file mode 100644 index 00000000..33e910df --- /dev/null +++ b/tests/all/js_globals/SetIterator.rs @@ -0,0 +1,97 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn entries() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn entries(this: &js::Set) -> js::SetIterator { + this.entries() + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([8, 5, 4, 3, 1, 2]); + let wasmIterator = wasm.entries(set); + let nextValue = wasmIterator.next().value; + + assert.equal(nextValue[0], 8); + assert.equal(nextValue[1], 8); + } + "#) + .test() +} + +#[test] +fn keys() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn keys(this: &js::Set) -> js::SetIterator { + this.keys() + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([8, 5, 4, 3, 1, 2]); + let wasmIterator = wasm.keys(set); + let nextValue = wasmIterator.next().value; + + assert.equal(nextValue, 8); + } + "#) + .test() +} + +#[test] +fn values() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn values(this: &js::Set) -> js::SetIterator { + this.values() + } + + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + let set = new Set([8, 5, 4, 3, 1, 2]); + let wasmIterator = wasm.values(set); + let nextValue = wasmIterator.next().value; + + assert.equal(nextValue, 8); + } + "#) + .test() +} \ No newline at end of file diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 4090fe04..b3908ddf 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -13,6 +13,8 @@ mod WeakMap; mod WeakSet; mod Number; mod Object; +mod Set; +mod SetIterator; mod TypedArray; #[test] From d8a98755e2a25ea7978cdae8d98e3b42c4309417 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Thu, 28 Jun 2018 15:00:33 -0700 Subject: [PATCH 29/48] Add @sendilkumarn to the team! \o/ (#352) --- guide/src/team.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/guide/src/team.md b/guide/src/team.md index af30ec67..2fe01605 100644 --- a/guide/src/team.md +++ b/guide/src/team.md @@ -23,9 +23,12 @@ img { | [![](https://github.com/alexcrichton.png?size=117)][alexcrichton] | [![](https://github.com/fitzgen.png?size=117)][fitzgen] | [![](https://github.com/spastorino.png?size=117)][spastorino] | [![](https://github.com/ohanar.png?size=117)][ohanar] | [![](https://github.com/jonathan-s.png?size=117)][jonathan-s] | |:---:|:---:|:---:|:---:| | [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] | [`jonathan-s`][jonathan-s] | +| [![](https://github.com/sendilkumarn.png?size=117)][sendilkumarn] | | | | | +| [`sendilkumarn`][sendilkumarn] | | | | | [alexcrichton]: https://github.com/alexcrichton [fitzgen]: https://github.com/fitzgen [spastorino]: https://github.com/spastorino [ohanar]: https://github.com/ohanar [jonathan-s]: https://github.com/jonathan-s +[sendilkumarn]: https://github.com/sendilkumarn From 4138583dff702794d3210729991d9afde79870e0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 Jun 2018 20:06:35 -0500 Subject: [PATCH 30/48] Support wildcard arguments in foreign functions (#351) No real reason to not support them! Closes #346 --- crates/backend/src/codegen.rs | 12 ++++++------ tests/all/imports.rs | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index ecede1ee..5e0b7414 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -573,6 +573,7 @@ impl ToTokens for ast::ImportFunction { let mut abi_argument_names = Vec::new(); let mut abi_arguments = Vec::new(); let mut arg_conversions = Vec::new(); + let mut arguments = Vec::new(); let ret_ident = Ident::new("_ret", Span::call_site()); for (i, syn::ArgCaptured { pat, ty, .. }) in self.function.arguments.iter().enumerate() { @@ -583,6 +584,9 @@ impl ToTokens for ast::ImportFunction { subpat: None, .. }) => ident.clone(), + syn::Pat::Wild(_) => { + syn::Ident::new(&format!("__genarg_{}", i), Span::call_site()) + } _ => panic!("unsupported pattern in foreign function"), }; @@ -593,6 +597,7 @@ impl ToTokens for ast::ImportFunction { let var = if i == 0 && is_method { quote! { self } } else { + arguments.push(quote! { #name: #ty }); quote! { #name } }; arg_conversions.push(quote! { @@ -651,12 +656,7 @@ impl ToTokens for ast::ImportFunction { let rust_name = &self.rust_name; let import_name = &self.shim; let attrs = &self.function.rust_attrs; - - let arguments = if is_method { - &self.function.arguments[1..] - } else { - &self.function.arguments[..] - }; + let arguments = &arguments; let me = if is_method { quote! { &self, } diff --git a/tests/all/imports.rs b/tests/all/imports.rs index 630737e3..f4a3e881 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -490,6 +490,40 @@ fn versions() { .test(); } +#[test] +fn underscore_pattern() { + project() + .debug(false) + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + #[wasm_bindgen(module = "./test")] + extern { + fn foo(_: u8); + } + + #[wasm_bindgen] + pub fn run() { + foo(1); + } + "#) + .file("test.ts", r#" + import { run } from "./out"; + + export function foo(_a: number) { + } + + export function test() { + run(); + } + "#) + .test(); +} + #[test] fn rust_keyword() { project() From 9a3ff77ea9f011b1f8e4296c63b9710e8e9b5a3b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 Jun 2018 20:08:02 -0500 Subject: [PATCH 31/48] Support returning custom types in imports (#350) Closes #320 --- crates/cli-support/src/js/rust2js.rs | 28 +++++++++++-- tests/all/imports.rs | 61 ++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 4 deletions(-) diff --git a/crates/cli-support/src/js/rust2js.rs b/crates/cli-support/src/js/rust2js.rs index 3687c948..1b672602 100644 --- a/crates/cli-support/src/js/rust2js.rs +++ b/crates/cli-support/src/js/rust2js.rs @@ -298,6 +298,26 @@ impl<'a, 'b> Rust2Js<'a, 'b> { ); return Ok(()); } + + if let Some(class) = ty.rust_struct() { + if ty.is_by_ref() { + bail!("cannot invoke JS functions returning custom ref types yet") + } + // Insert an assertion to the type of the returned value as + // otherwise this will cause memory unsafety on the Rust side of + // things. + self.ret_expr = format!("\ + const val = JS; + if (!(val instanceof {0})) {{ + throw new Error('expected value of type {0}'); + }} + const ret = val.ptr; + val.ptr = 0; + return ret;\ + ", class); + return Ok(()) + } + self.ret_expr = match *ty { Descriptor::Boolean => "return JS ? 1 : 0;".to_string(), Descriptor::Char => "return JS.codePointAt(0);".to_string(), @@ -337,9 +357,9 @@ impl<'a, 'b> Rust2Js<'a, 'b> { invoc = format!( "\ try {{\n\ - {} + {} }} catch (e) {{\n\ - {} + {} }}\ ", &invoc, catch @@ -350,9 +370,9 @@ impl<'a, 'b> Rust2Js<'a, 'b> { invoc = format!( "\ try {{\n\ - {} + {} }} finally {{\n\ - {} + {} }}\ ", &invoc, &self.finally diff --git a/tests/all/imports.rs b/tests/all/imports.rs index f4a3e881..bc09154b 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -607,3 +607,64 @@ fn rust_keyword2() { ) .test(); } + +#[test] +fn custom_type() { + project() + .debug(false) + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + #[wasm_bindgen(module = "./test")] + extern { + fn foo(f: Foo) -> Foo; + fn bad2() -> Foo; + } + + #[wasm_bindgen] + pub struct Foo(()); + + #[wasm_bindgen] + impl Foo { + pub fn touch(&self) { + panic!() + } + } + + #[wasm_bindgen] + pub fn run() { + foo(Foo(())); + } + + #[wasm_bindgen] + pub fn bad() { + bad2(); + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import { run, Foo, bad } from "./out"; + + let VAL: any = null; + + export function foo(f: Foo): Foo { + VAL = f; + return f; + } + + export function bad2(): number { + return 2; + } + + export function test() { + run(); + assert.throws(() => VAL.touch(), /Attempt to use a moved value/); + assert.throws(bad, /expected value of type Foo/); + } + "#) + .test(); +} From e55af85edc0cfb22534aaa3dba7ecae18007888b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 Jun 2018 20:09:11 -0500 Subject: [PATCH 32/48] Support by-value self methods (#348) Refactor slightly to use the same internal support that the other reference conversions are using. Closes #329 --- crates/backend/src/ast.rs | 44 +++++++++++------ crates/backend/src/codegen.rs | 72 ++++++++++++++++++++-------- crates/cli-support/src/js/js2rust.rs | 16 +++++-- crates/cli-support/src/js/mod.rs | 6 +-- crates/shared/src/lib.rs | 3 +- tests/all/classes.rs | 45 ++++++++++++++++- 6 files changed, 143 insertions(+), 43 deletions(-) diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 158e8210..962df0f8 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -17,13 +17,19 @@ pub struct Program { #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] pub struct Export { pub class: Option, - pub method: bool, - pub mutable: bool, + pub method_self: Option, pub constructor: Option, pub function: Function, pub comments: Vec, } +#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] +pub enum MethodSelf { + ByValue, + RefMutable, + RefShared, +} + #[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))] pub struct Import { pub module: Option, @@ -170,8 +176,7 @@ impl Program { f.to_tokens(tokens); self.exports.push(Export { class: None, - method: false, - mutable: false, + method_self: None, constructor: None, function: Function::from(f, opts), comments, @@ -263,7 +268,7 @@ impl Program { None }; - let (function, mutable) = Function::from_decl( + let (function, method_self) = Function::from_decl( &method.sig.ident, Box::new(method.sig.decl.clone()), method.attrs.clone(), @@ -274,8 +279,7 @@ impl Program { self.exports.push(Export { class: Some(class.clone()), - method: mutable.is_some(), - mutable: mutable.unwrap_or(false), + method_self, constructor, function, comments, @@ -529,7 +533,7 @@ impl Function { opts: BindgenAttrs, vis: syn::Visibility, allow_self: bool, - ) -> (Function, Option) { + ) -> (Function, Option) { if decl.variadic.is_some() { panic!("can't bindgen variadic functions") } @@ -541,17 +545,23 @@ impl Function { let syn::FnDecl { inputs, output, .. } = { *decl }; - let mut mutable = None; + let mut method_self = None; let arguments = inputs .into_iter() .filter_map(|arg| match arg { syn::FnArg::Captured(c) => Some(c), syn::FnArg::SelfValue(_) => { - panic!("by-value `self` not yet supported"); + assert!(method_self.is_none()); + method_self = Some(MethodSelf::ByValue); + None } syn::FnArg::SelfRef(ref a) if allow_self => { - assert!(mutable.is_none()); - mutable = Some(a.mutability.is_some()); + assert!(method_self.is_none()); + if a.mutability.is_some() { + method_self = Some(MethodSelf::RefMutable); + } else { + method_self = Some(MethodSelf::RefShared); + } None } _ => panic!("arguments cannot be `self` or ignored"), @@ -572,7 +582,7 @@ impl Function { rust_vis: vis, rust_attrs: attrs, }, - mutable, + method_self, ) } @@ -618,9 +628,15 @@ impl Export { } fn shared(&self) -> shared::Export { + let (method, consumed) = match self.method_self { + Some(MethodSelf::ByValue) => (true, true), + Some(_) => (true, false), + None => (false, false), + }; shared::Export { class: self.class.as_ref().map(|s| s.to_string()), - method: self.method, + method, + consumed, constructor: self.constructor.clone(), function: self.function.shared(), comments: self.comments.clone(), diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index 5e0b7414..d19e0431 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -309,16 +309,61 @@ impl ToTokens for ast::Export { let ret = Ident::new("_ret", Span::call_site()); let mut offset = 0; - if self.method { - let class = self.class.as_ref().unwrap(); - args.push(quote! { me: *mut ::wasm_bindgen::__rt::WasmRefCell<#class> }); - arg_conversions.push(quote! { - ::wasm_bindgen::__rt::assert_not_null(me); - let me = unsafe { &*me }; - }); + if self.method_self.is_some() { + args.push(quote! { me: u32 }); offset = 1; } + let name = &self.function.name; + let receiver = match self.method_self { + Some(ast::MethodSelf::ByValue) => { + let class = self.class.as_ref().unwrap(); + arg_conversions.push(quote! { + let me = unsafe { + <#class as ::wasm_bindgen::convert::FromWasmAbi>::from_abi( + me, + &mut ::wasm_bindgen::convert::GlobalStack::new(), + ) + }; + }); + quote! { me.#name } + } + Some(ast::MethodSelf::RefMutable) => { + let class = self.class.as_ref().unwrap(); + arg_conversions.push(quote! { + let mut me = unsafe { + <#class as ::wasm_bindgen::convert::RefMutFromWasmAbi> + ::ref_mut_from_abi( + me, + &mut ::wasm_bindgen::convert::GlobalStack::new(), + ) + }; + let me = &mut *me; + }); + quote! { me.#name } + } + Some(ast::MethodSelf::RefShared) => { + let class = self.class.as_ref().unwrap(); + arg_conversions.push(quote! { + let me = unsafe { + <#class as ::wasm_bindgen::convert::RefFromWasmAbi> + ::ref_from_abi( + me, + &mut ::wasm_bindgen::convert::GlobalStack::new(), + ) + }; + let me = &*me; + }); + quote! { me.#name } + } + None => { + match &self.class { + Some(class) => quote! { #class::#name }, + None => quote! { #name } + } + } + }; + for (i, syn::ArgCaptured { ty, .. }) in self.function.arguments.iter().enumerate() { let i = i + offset; let ident = Ident::new(&format!("arg{}", i), Span::call_site()); @@ -394,19 +439,6 @@ impl ToTokens for ast::Export { } None => quote! { inform(0); }, }; - - let name = &self.function.name; - let receiver = match &self.class { - Some(_) if self.method => { - if self.mutable { - quote! { me.borrow_mut().#name } - } else { - quote! { me.borrow().#name } - } - } - Some(class) => quote! { #class::#name }, - None => quote!{ #name }, - }; let descriptor_name = format!("__wbindgen_describe_{}", export_name); let descriptor_name = Ident::new(&descriptor_name, Span::call_site()); let nargs = self.function.arguments.len() as u32; diff --git a/crates/cli-support/src/js/js2rust.rs b/crates/cli-support/src/js/js2rust.rs index 10448747..b67352fb 100644 --- a/crates/cli-support/src/js/js2rust.rs +++ b/crates/cli-support/src/js/js2rust.rs @@ -66,14 +66,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> { /// Flag this shim as a method call into Rust, so the first Rust argument /// passed should be `this.ptr`. - pub fn method(&mut self, method: bool) -> &mut Self { + pub fn method(&mut self, method: bool, consumed: bool) -> &mut Self { if method { self.prelude( "if (this.ptr === 0) { - throw new Error('Attempt to use a moved value'); - }", + throw new Error('Attempt to use a moved value'); + }" ); - self.rust_arguments.insert(0, "this.ptr".to_string()); + if consumed { + self.prelude("\ + const ptr = this.ptr;\n\ + this.ptr = 0;\n\ + "); + self.rust_arguments.insert(0, "ptr".to_string()); + } else { + self.rust_arguments.insert(0, "this.ptr".to_string()); + } } self } diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 7ac84b6e..e3f11466 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -551,7 +551,7 @@ impl<'a> Context<'a> { let set = { let mut cx = Js2Rust::new(&field.name, self); - cx.method(true).argument(&descriptor)?.ret(&None)?; + cx.method(true, false).argument(&descriptor)?.ret(&None)?; ts_dst.push_str(&format!( "{}{}: {}\n", if field.readonly { "readonly " } else { "" }, @@ -561,7 +561,7 @@ impl<'a> Context<'a> { cx.finish("", &format!("wasm.{}", wasm_setter)).0 }; let (get, _ts) = Js2Rust::new(&field.name, self) - .method(true) + .method(true, false) .ret(&Some(descriptor))? .finish("", &format!("wasm.{}", wasm_getter)); if !dst.ends_with("\n") { @@ -1657,7 +1657,7 @@ impl<'a, 'b> SubContext<'a, 'b> { }; let (js, ts) = Js2Rust::new(&export.function.name, self.cx) - .method(export.method) + .method(export.method, export.consumed) .process(descriptor.unwrap_function())? .finish("", &format!("wasm.{}", wasm_name)); let class = self diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 6d1da854..66f624d7 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -1,7 +1,7 @@ #[macro_use] extern crate serde_derive; -pub const SCHEMA_VERSION: &str = "4"; +pub const SCHEMA_VERSION: &str = "5"; #[derive(Deserialize)] pub struct ProgramOnlySchema { @@ -72,6 +72,7 @@ pub struct ImportType {} pub struct Export { pub class: Option, pub method: bool, + pub consumed: bool, pub constructor: Option, pub function: Function, pub comments: Vec, diff --git a/tests/all/classes.rs b/tests/all/classes.rs index 5946af2d..1abb6bf1 100644 --- a/tests/all/classes.rs +++ b/tests/all/classes.rs @@ -32,6 +32,10 @@ fn simple() { self.contents += amt; self.contents } + + pub fn consume(self) -> u32 { + self.contents + } } "#, ) @@ -46,7 +50,9 @@ fn simple() { assert.strictEqual(r.add(0), 0); assert.strictEqual(r.add(1), 1); assert.strictEqual(r.add(1), 2); - r.free(); + r.add(2); + assert.strictEqual(r.consume(), 4); + assert.throws(() => r.free(), /null pointer passed to rust/); const r2 = Foo.with_contents(10); assert.strictEqual(r2.add(1), 11); @@ -672,3 +678,40 @@ fn readonly_fields() { ) .test(); } + +#[test] +fn double_consume() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + pub struct Foo { } + + #[wasm_bindgen] + impl Foo { + #[wasm_bindgen(constructor)] + pub fn new() -> Foo { + Foo {} + } + + pub fn consume(self, other: Foo) { + drop(other); + } + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import { Foo } from "./out"; + + export function test() { + const r = Foo.new(); + assert.throws(() => r.consume(r), /Attempt to use a moved value/); + } + "#) + .test(); +} From 942673e15f86dfd8971a35f990da4a543c49b0a3 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 28 Jun 2018 18:35:15 -0700 Subject: [PATCH 33/48] Disable formatting on Travis --- .travis.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3892b09f..109e76fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,11 +8,6 @@ matrix: install: true script: cargo build --manifest-path crates/cli/Cargo.toml - # check formatting - - rust: nightly - before_install: rustup component add rustfmt-preview --toolchain nightly - script: cargo fmt -- --check - # Tests pass on nightly - rust: nightly before_install: From f9c804db20a635de68bd9bbb9575878c4e58237c Mon Sep 17 00:00:00 2001 From: Satoshi Amemiya Date: Fri, 29 Jun 2018 22:46:27 +0900 Subject: [PATCH 34/48] Add support for js::Error --- src/js.rs | 37 +++++++ tests/all/js_globals/Error.rs | 197 ++++++++++++++++++++++++++++++++++ tests/all/js_globals/mod.rs | 1 + 3 files changed, 235 insertions(+) create mode 100644 tests/all/js_globals/Error.rs diff --git a/src/js.rs b/src/js.rs index b6c5598f..ced94305 100644 --- a/src/js.rs +++ b/src/js.rs @@ -276,6 +276,43 @@ extern "C" { pub fn value_of(this: &Boolean) -> bool; } +// Error +#[wasm_bindgen] +extern "C" { + pub type Error; + + /// The Error constructor creates an error object. + /// Instances of Error objects are thrown when runtime errors occur. + /// The Error object can also be used as a base object for user-defined exceptions. + /// See below for standard built-in error types. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error + #[wasm_bindgen(constructor)] + pub fn new(message: &JsString) -> Error; + + /// The message property is a human-readable description of the error. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/message + #[wasm_bindgen(method, getter, structural)] + pub fn message(this: &Error) -> JsString; + #[wasm_bindgen(method, setter, structural)] + pub fn set_message(this: &Error, message: &JsString); + + /// The name property represents a name for the type of error. The initial value is "Error". + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name + #[wasm_bindgen(method, getter, structural)] + pub fn name(this: &Error) -> JsString; + #[wasm_bindgen(method, setter, structural)] + pub fn set_name(this: &Error, name: &JsString); + + /// The toString() method returns a string representing the specified Error object + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/toString + #[wasm_bindgen(method, js_name = toString)] + pub fn to_string(this: &Error) -> JsString; +} + // Function #[wasm_bindgen] extern "C" { diff --git a/tests/all/js_globals/Error.rs b/tests/all/js_globals/Error.rs new file mode 100644 index 00000000..bf2918a0 --- /dev/null +++ b/tests/all/js_globals/Error.rs @@ -0,0 +1,197 @@ +#![allow(non_snake_case)] + +use project; + +#[test] +fn new() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn new_error(message: &js::JsString) -> Error { + Error::new(message) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const message = 'any error message'; + const error = wasm.new_error(message); + + assert.equal(error.message, message); + } + "#) + .test() +} + +#[test] +fn message() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn error_message(this: &Error) -> js::JsString { + this.message() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const message = 'any error message'; + const error = new Error(message); + + assert.equal(wasm.error_message(error), message); + } + "#) + .test() +} + +#[test] +fn set_message() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn error_set_message(this: &Error, message: &js::JsString) { + this.set_message(message); + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const message = 'any error message'; + const error = new Error(); + wasm.error_set_message(error, message); + + assert.equal(error.message, message); + } + "#) + .test() +} + +#[test] +fn name() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn error_name(this: &Error) -> js::JsString { + this.name() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const name = 'any error name'; + const error = new Error(); + error.name = name; + + assert.equal(wasm.error_name(error), name); + } + "#) + .test() +} + +#[test] +fn set_name() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn error_set_name(this: &Error, name: &js::JsString) { + this.set_name(name); + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const name = 'any error name'; + const error = new Error(); + wasm.error_set_name(error, name); + + assert.equal(error.name, name); + } + "#) + .test() +} + +#[test] +fn to_string() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + use wasm_bindgen::js::Error; + + #[wasm_bindgen] + pub fn error_to_string(this: &Error) -> js::JsString { + this.to_string() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const error = new Error('error message 1'); + + assert.equal(wasm.error_to_string(error), 'Error: error message 1'); + + (error.name as any) = undefined; + assert.equal(wasm.error_to_string(error), 'Error: error message 1'); + + error.name = 'error_name_1'; + assert.equal(wasm.error_to_string(error), 'error_name_1: error message 1'); + + (error.message as any) = undefined; + assert.equal(wasm.error_to_string(error), 'error_name_1'); + + error.name = 'error_name_2'; + assert.equal(wasm.error_to_string(error), 'error_name_2'); + } + "#) + .test() +} diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index 8685aeb7..e33d9d6d 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -7,6 +7,7 @@ mod ArrayIterator; mod Boolean; mod Date; mod Function; +mod Error; mod JsString; mod Map; mod MapIterator; From e06255fba5baa45e8b8d8e1e54f47e0e7cfc1d4c Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 29 Jun 2018 15:52:31 -0700 Subject: [PATCH 35/48] Don't generate JS bindings for unused imports If a JS import's shim isn't actually imported that means that somewhere along the way it was optimized out or it was never used in the first place! In that case we can skip generation of the JS bindings for it as it's not needed. --- crates/cli-support/src/js/mod.rs | 4 ++++ tests/all/imports.rs | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index e3f11466..3a42fd2d 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1778,6 +1778,10 @@ impl<'a, 'b> SubContext<'a, 'b> { info: &shared::Import, import: &shared::ImportFunction, ) -> Result<(), Error> { + if !self.cx.wasm_import_needed(&import.shim) { + return Ok(()) + } + let descriptor = match self.cx.describe(&import.shim) { None => return Ok(()), Some(d) => d, diff --git a/tests/all/imports.rs b/tests/all/imports.rs index bc09154b..334dc700 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -1,3 +1,6 @@ +use std::fs::File; +use std::io::Read; + use super::project; #[test] @@ -668,3 +671,40 @@ fn custom_type() { "#) .test(); } + +#[test] +fn unused_imports_not_generated() { + project() + .debug(false) + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section, wasm_import_module)] + + extern crate wasm_bindgen; + + use wasm_bindgen::prelude::*; + + #[wasm_bindgen] + extern { + pub fn foo(); + } + + #[wasm_bindgen] + pub fn run() { + } + "#) + .file("test.ts", r#" + import { run } from "./out"; + + export function test() { + run(); + } + "#) + .test(); + + let out = ::root().join("out.js"); + let mut contents = String::new(); + File::open(&out).unwrap() + .read_to_string(&mut contents).unwrap(); + assert!(contents.contains("run"), "didn't find `run` in {}", contents); + assert!(!contents.contains("foo"), "found `foo` in {}", contents); +} From cf08aee341838e2faa355c8a2a53be72fcbee3a1 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 29 Jun 2018 15:52:31 -0700 Subject: [PATCH 36/48] Tidy up a test --- tests/all/imports.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/all/imports.rs b/tests/all/imports.rs index 334dc700..6117dcfd 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -674,7 +674,9 @@ fn custom_type() { #[test] fn unused_imports_not_generated() { - project() + let mut project = project(); + + project .debug(false) .file("src/lib.rs", r#" #![feature(proc_macro, wasm_custom_section, wasm_import_module)] @@ -701,10 +703,7 @@ fn unused_imports_not_generated() { "#) .test(); - let out = ::root().join("out.js"); - let mut contents = String::new(); - File::open(&out).unwrap() - .read_to_string(&mut contents).unwrap(); + let contents = project.read_js(); assert!(contents.contains("run"), "didn't find `run` in {}", contents); assert!(!contents.contains("foo"), "found `foo` in {}", contents); } From ce9b95635d24657a5616e3ecfe09125a832e42e4 Mon Sep 17 00:00:00 2001 From: belfz Date: Sun, 1 Jul 2018 11:52:22 +0200 Subject: [PATCH 37/48] implements Object.setPrototypeOf() binding --- src/js.rs | 7 +++++++ tests/all/js_globals/Object.rs | 30 ++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/js.rs b/src/js.rs index ced94305..96b542e2 100644 --- a/src/js.rs +++ b/src/js.rs @@ -782,6 +782,13 @@ extern "C" { #[wasm_bindgen(static_method_of = Object)] pub fn seal(value: &JsValue) -> JsValue; + /// The Object.setPrototypeOf() method sets the prototype (i.e., the internal + /// [[Prototype]] property) of a specified object to another object or null. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf + #[wasm_bindgen(static_method_of = Object, js_name = setPrototypeOf)] + pub fn set_prototype_of(object: &Object, prototype: &Object) -> Object; + /// The toLocaleString() method returns a string representing the object. /// This method is meant to be overridden by derived objects for /// locale-specific purposes. diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 6b268956..8787cf91 100644 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -272,6 +272,36 @@ fn seal() { .test() } +#[test] +fn set_prototype_of() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn set_prototype_of(object: &js::Object, prototype: &js::Object) -> js::Object { + js::Object::set_prototype_of(&object, &prototype) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = { foo: 42 }; + const newPrototype = { bar: 'baz' }; + + const modifiedObject = wasm.set_prototype_of(object, newPrototype); + assert(newPrototype.isPrototypeOf(modifiedObject)); + } + "#) + .test() +} + #[test] fn to_locale_string() { project() From f850a6fafc6cae76b57601cef891460fb3598064 Mon Sep 17 00:00:00 2001 From: Alexander Kryvomaz Date: Sun, 1 Jul 2018 15:44:36 +0300 Subject: [PATCH 38/48] bindings for Function.prototype.bind() --- src/js.rs | 7 ++++++ tests/all/js_globals/Function.rs | 40 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/js.rs b/src/js.rs index ced94305..e10d8d88 100644 --- a/src/js.rs +++ b/src/js.rs @@ -325,6 +325,13 @@ extern "C" { #[wasm_bindgen(method)] pub fn apply(this: &Function, context: &JsValue, args: &Array) -> Function; + /// The bind() method creates a new function that, when called, has its this keyword set to the provided value, + /// with a given sequence of arguments preceding any provided when the new function is called. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind + #[wasm_bindgen(method)] + pub fn bind(this: &Function, context: &JsValue) -> Function; + /// The length property indicates the number of arguments expected by the function. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/length diff --git a/tests/all/js_globals/Function.rs b/tests/all/js_globals/Function.rs index b54a2629..b5f32d5b 100644 --- a/tests/all/js_globals/Function.rs +++ b/tests/all/js_globals/Function.rs @@ -38,6 +38,46 @@ fn apply() { .test() } +#[test] +fn bind() { + project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn bind(this: &js::Function, context: &JsValue) -> js::Function { + this.bind(context) + } + "#, + ) + .file( + "test.ts", + r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const obj = { + a: 0, + fn: function () { + return this.a + 1; + } + } + + const boundFn = wasm.bind(obj.fn, { a: 41 }); + assert.equal(boundFn(), 42); + } + "#, + ) + .test() +} + #[test] fn length() { project() From 0f07dd9048625365acd236e1be75088c73efc7a4 Mon Sep 17 00:00:00 2001 From: Alexander Kryvomaz Date: Sun, 1 Jul 2018 15:53:44 +0300 Subject: [PATCH 39/48] bindings for decodeURIComponent --- src/js.rs | 7 +++++++ tests/all/js_globals/mod.rs | 28 +++++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/js.rs b/src/js.rs index e10d8d88..465edac3 100644 --- a/src/js.rs +++ b/src/js.rs @@ -49,6 +49,13 @@ extern "C" { #[wasm_bindgen(catch, js_name = decodeURI)] pub fn decode_uri(encoded: &str) -> Result; + /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI) + /// component previously created by encodeURIComponent or by a similar routine. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent + #[wasm_bindgen(catch, js_name = decodeURIComponent)] + pub fn decode_uri_component(encoded: &str) -> Result; + /// The `encodeURI()` function encodes a Uniform Resource Identifier (URI) /// by replacing each instance of certain characters by one, two, three, or /// four escape sequences representing the UTF-8 encoding of the character diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index e33d9d6d..b365c6ce 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -6,8 +6,8 @@ mod Array; mod ArrayIterator; mod Boolean; mod Date; -mod Function; mod Error; +mod Function; mod JsString; mod Map; mod MapIterator; @@ -47,6 +47,32 @@ fn decode_uri() { .test(); } +#[test] +fn decode_uri_component() { + project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn test() { + let x = js::decode_uri_component("%3Fx%3Dtest") + .ok() + .expect("should decode URI OK"); + assert_eq!(String::from(x), "?x=test"); + + assert!(js::decode_uri_component("%E0%A4%A").is_err()); + } + "#, + ) + .test(); +} + #[test] #[cfg(feature = "std")] fn encode_uri() { From 609bf34d602a4b9b2c7cb942ef242cb36abb10bd Mon Sep 17 00:00:00 2001 From: Alexander Kryvomaz Date: Sun, 1 Jul 2018 15:59:12 +0300 Subject: [PATCH 40/48] bindings for encodeURIComponent --- src/js.rs | 13 +++++++++++-- tests/all/js_globals/mod.rs | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/js.rs b/src/js.rs index 465edac3..7d957f74 100644 --- a/src/js.rs +++ b/src/js.rs @@ -49,8 +49,8 @@ extern "C" { #[wasm_bindgen(catch, js_name = decodeURI)] pub fn decode_uri(encoded: &str) -> Result; - /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI) - /// component previously created by encodeURIComponent or by a similar routine. + /// The decodeURIComponent() function decodes a Uniform Resource Identifier (URI) component + /// previously created by encodeURIComponent or by a similar routine. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent #[wasm_bindgen(catch, js_name = decodeURIComponent)] @@ -66,6 +66,15 @@ extern "C" { #[wasm_bindgen(js_name = encodeURI)] pub fn encode_uri(decoded: &str) -> JsString; + /// The encodeURIComponent() function encodes a Uniform Resource Identifier (URI) component + /// by replacing each instance of certain characters by one, two, three, or four escape sequences + /// representing the UTF-8 encoding of the character + /// (will only be four escape sequences for characters composed of two "surrogate" characters). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent + #[wasm_bindgen(js_name = encodeURIComponent)] + pub fn encode_uri_component(decoded: &str) -> JsString; + /// The `eval()` function evaluates JavaScript code represented as a string. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval diff --git a/tests/all/js_globals/mod.rs b/tests/all/js_globals/mod.rs index b365c6ce..632898e0 100644 --- a/tests/all/js_globals/mod.rs +++ b/tests/all/js_globals/mod.rs @@ -96,6 +96,28 @@ fn encode_uri() { .test(); } +#[test] +fn encode_uri_component() { + project() + .file( + "src/lib.rs", + r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn test() { + let x = js::encode_uri_component("?x=шеллы"); + assert_eq!(String::from(x), "%3Fx%3D%D1%88%D0%B5%D0%BB%D0%BB%D1%8B"); + } + "#, + ) + .test(); +} + #[test] fn eval() { project() From 58560f1408a8083ef96dda7b3376a1b84e674931 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Sun, 1 Jul 2018 23:11:13 +0200 Subject: [PATCH 41/48] Add binding for String.prototype.toLowerCase --- src/js.rs | 7 +++++++ tests/all/js_globals/JsString.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/js.rs b/src/js.rs index f6a110d7..1e26d59f 100644 --- a/src/js.rs +++ b/src/js.rs @@ -1065,6 +1065,13 @@ extern "C" { #[wasm_bindgen(method, js_class = "String")] pub fn substr(this: &JsString, start: i32, length: i32) -> JsString; + /// The toLowerCase() method returns the calling string value + /// converted to lower case. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase + #[wasm_bindgen(method, js_class = "String", js_name = toLowerCase)] + pub fn to_lower_case(this: &JsString) -> JsString; + /// The toString() method returns a string representing the specified object. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toString diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index 28ca0943..b6656bc5 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -396,6 +396,32 @@ fn substr() { .test() } +#[test] +fn to_lower_case() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn string_to_lower_case(this: &js::JsString) -> js::JsString { + this.to_lower_case() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.string_to_lower_case("Mozilla"), "mozilla"); + } + "#) + .test() +} + #[test] fn to_string() { project() From d5d451b94b67b25aa88fa00de057440f31a5fca4 Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Sun, 1 Jul 2018 23:12:42 +0200 Subject: [PATCH 42/48] Add binding for String.prototype.toUpperCase --- src/js.rs | 8 ++++++++ tests/all/js_globals/JsString.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/src/js.rs b/src/js.rs index 1e26d59f..e8d7f170 100644 --- a/src/js.rs +++ b/src/js.rs @@ -1078,6 +1078,14 @@ extern "C" { #[wasm_bindgen(method, js_class = "String", js_name = toString)] pub fn to_string(this: &JsString) -> JsString; + /// The toUpperCase() method returns the calling string value + /// converted to uppercase (the value will be converted to a + /// string if it isn't one). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase + #[wasm_bindgen(method, js_class = "String", js_name = toUpperCase)] + pub fn to_upper_case(this: &JsString) -> JsString; + /// The trim() method removes whitespace from both ends of a string. /// Whitespace in this context is all the whitespace characters /// (space, tab, no-break space, etc.) and all the line terminator characters (LF, CR, etc.). diff --git a/tests/all/js_globals/JsString.rs b/tests/all/js_globals/JsString.rs index b6656bc5..0c937444 100644 --- a/tests/all/js_globals/JsString.rs +++ b/tests/all/js_globals/JsString.rs @@ -455,6 +455,32 @@ fn to_string() { .test() } +#[test] +fn to_upper_case() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn string_to_upper_case(this: &js::JsString) -> js::JsString { + this.to_upper_case() + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + assert.equal(wasm.string_to_upper_case("Mozilla"), "MOZILLA"); + } + "#) + .test() +} + #[test] fn trim() { project() From 1d04203e8961fad185fa5dd05409cbc76f3b21bb Mon Sep 17 00:00:00 2001 From: belfz Date: Sun, 1 Jul 2018 23:50:10 +0200 Subject: [PATCH 43/48] implements Object.values() binding --- src/js.rs | 9 +++++++++ tests/all/js_globals/Object.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/js.rs b/src/js.rs index f6a110d7..f18ab446 100644 --- a/src/js.rs +++ b/src/js.rs @@ -832,6 +832,15 @@ extern "C" { /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf #[wasm_bindgen(method, js_name = valueOf)] pub fn value_of(this: &Object) -> Object; + + /// The Object.values() method returns an array of a given object's + /// own enumerable property values, in the same order as that provided + /// by a for...in loop (the difference being that a for-in loop + /// enumerates properties in the prototype chain as well). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values + #[wasm_bindgen(static_method_of = Object)] + pub fn values(object: &Object) -> Array; } // Set diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 8787cf91..b3ceb312 100644 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -368,3 +368,32 @@ fn value_of() { ) .test() } + +#[test] +fn values() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn values(obj: &js::Object) -> js::Array { + js::Object::values(&obj) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = { foo: 'bar', baz: 'qux' }; + const values = wasm.values(object); + assert.equal(values.length, 2); + assert.deepEqual(values.sort(), ['bar', 'qux']); + } + "#) + .test() +} From 37fc159061a1a8cc7b4eb4182decc0bc8a65be73 Mon Sep 17 00:00:00 2001 From: Marcin Baraniecki Date: Mon, 2 Jul 2018 17:31:40 +0200 Subject: [PATCH 44/48] implements Object.preventExtensions() binding (#364) --- src/js.rs | 8 ++++++++ tests/all/js_globals/Object.rs | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/src/js.rs b/src/js.rs index 91a5af7a..e4df40b6 100644 --- a/src/js.rs +++ b/src/js.rs @@ -790,6 +790,14 @@ extern "C" { #[wasm_bindgen(constructor)] pub fn new() -> Object; + /// The Object.preventExtensions() method prevents + /// new properties from ever being added to an object + /// (i.e. prevents future extensions to the object). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions + #[wasm_bindgen(static_method_of = Object, js_name = preventExtensions)] + pub fn prevent_extensions(object: &Object); + /// The propertyIsEnumerable() method returns a Boolean indicating /// whether the specified property is enumerable. /// diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index b3ceb312..1357fbf2 100644 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -180,6 +180,39 @@ fn keys() { .test() } +#[test] +fn prevent_extensions() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn prevent_extensions(obj: &js::Object) { + js::Object::prevent_extensions(obj); + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = {}; + wasm.prevent_extensions(object); + + assert(!Object.isExtensible(object)); + assert.throws(() => { + 'use strict'; + Object.defineProperty(object, 'foo', { value: 42 }); + }, TypeError); + } + "#) + .test() +} + #[test] fn property_is_enumerable() { project() From dcb3415da8650b918e5b7f6d65ab071fff7aa6fa Mon Sep 17 00:00:00 2001 From: Marcin Baraniecki Date: Mon, 2 Jul 2018 17:32:16 +0200 Subject: [PATCH 45/48] Expose bindings/object is* methods (#363) * implements Object.isExtensible() binding * implements Object.isFrozen() binding * implements Object.isSealed() binding --- src/js.rs | 19 +++++++ tests/all/js_globals/Object.rs | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/src/js.rs b/src/js.rs index e4df40b6..3c17ef2b 100644 --- a/src/js.rs +++ b/src/js.rs @@ -770,6 +770,25 @@ extern "C" { #[wasm_bindgen(method, js_name = hasOwnProperty)] pub fn has_own_property(this: &Object, property: &JsValue) -> bool; + /// The Object.isExtensible() method determines if an object is extensible + /// (whether it can have new properties added to it). + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + #[wasm_bindgen(static_method_of = Object, js_name = isExtensible)] + pub fn is_extensible(object: &Object) -> bool; + + /// The Object.isFrozen() determines if an object is frozen. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + #[wasm_bindgen(static_method_of = Object, js_name = isFrozen)] + pub fn is_frozen(object: &Object) -> bool; + + /// The Object.isSealed() method determines if an object is sealed. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + #[wasm_bindgen(static_method_of = Object, js_name = isSealed)] + pub fn is_sealed(object: &Object) -> bool; + /// The isPrototypeOf() method checks if an object exists in another /// object's prototype chain. /// diff --git a/tests/all/js_globals/Object.rs b/tests/all/js_globals/Object.rs index 1357fbf2..402e247c 100644 --- a/tests/all/js_globals/Object.rs +++ b/tests/all/js_globals/Object.rs @@ -110,6 +110,96 @@ fn to_string() { .test() } +#[test] +fn is_extensible() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn is_extensible(obj: &js::Object) -> bool { + js::Object::is_extensible(&obj) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = {}; + assert(wasm.is_extensible(object)); + + Object.preventExtensions(object); + assert(!wasm.is_extensible(object)); + } + "#) + .test() +} + +#[test] +fn is_frozen() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn is_frozen(obj: &js::Object) -> bool { + js::Object::is_frozen(&obj) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = {}; + assert(!wasm.is_frozen(object)); + + Object.freeze(object); + assert(wasm.is_frozen(object)); + } + "#) + .test() +} + +#[test] +fn is_sealed() { + project() + .file("src/lib.rs", r#" + #![feature(proc_macro, wasm_custom_section)] + + extern crate wasm_bindgen; + use wasm_bindgen::prelude::*; + use wasm_bindgen::js; + + #[wasm_bindgen] + pub fn is_sealed(obj: &js::Object) -> bool { + js::Object::is_sealed(&obj) + } + "#) + .file("test.ts", r#" + import * as assert from "assert"; + import * as wasm from "./out"; + + export function test() { + const object = {}; + assert(!wasm.is_sealed(object)); + + Object.seal(object); + assert(wasm.is_sealed(object)); + } + "#) + .test() +} + #[test] fn is_prototype_of() { project() From 4ceaf3e0f47442db01ac3bdb1220b5f706bf958f Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 2 Jul 2018 11:57:39 -0500 Subject: [PATCH 46/48] Some small cleanups (#366) * No need for version deps in dev-deps These are all internal so we can drop the version * Remove wasm-bindgen-cli's parity-wasm dep No longer needed * Tweak file hierarchy in webidl tests Use Cargo's conventions to avoid the need to define `[[test]]` sections * Remove unused imports --- crates/cli/Cargo.toml | 1 - crates/cli/src/bin/wasm2es6js.rs | 1 - crates/webidl/Cargo.toml | 12 ++---------- crates/webidl/src/lib.rs | 0 crates/webidl/tests/all/{lib.rs => main.rs} | 0 crates/webidl/tests/expected/{lib.rs => main.rs} | 0 tests/all/imports.rs | 3 --- 7 files changed, 2 insertions(+), 15 deletions(-) mode change 100755 => 100644 crates/webidl/src/lib.rs rename crates/webidl/tests/all/{lib.rs => main.rs} (100%) rename crates/webidl/tests/expected/{lib.rs => main.rs} (100%) mode change 100755 => 100644 diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index b10e4606..230d2caa 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,7 +15,6 @@ information see https://github.com/alexcrichton/wasm-bindgen. [dependencies] docopt = "0.8" failure = "0.1" -parity-wasm = "0.28" serde = "1.0" serde_derive = "1.0" wasm-bindgen-cli-support = { path = "../cli-support", version = "=0.2.11" } diff --git a/crates/cli/src/bin/wasm2es6js.rs b/crates/cli/src/bin/wasm2es6js.rs index 736c9b55..50b16ca8 100644 --- a/crates/cli/src/bin/wasm2es6js.rs +++ b/crates/cli/src/bin/wasm2es6js.rs @@ -2,7 +2,6 @@ extern crate serde_derive; extern crate docopt; extern crate failure; -extern crate parity_wasm; extern crate wasm_bindgen_cli_support; use std::fs::File; diff --git a/crates/webidl/Cargo.toml b/crates/webidl/Cargo.toml index 874c60ab..98a00e3a 100644 --- a/crates/webidl/Cargo.toml +++ b/crates/webidl/Cargo.toml @@ -3,19 +3,11 @@ name = "wasm-bindgen-webidl" version = "0.2.11" authors = ["Nick Fitzgerald "] -[[test]] -name = "webidl-all" -path = "tests/all/lib.rs" - -[[test]] -name = "webidl-expected" -path = "tests/expected/lib.rs" - [dev-dependencies] diff = "0.1.11" env_logger = "0.5.10" -wasm-bindgen = { version = "=0.2.11", path = "../..", default-features = false } -wasm-bindgen-backend = { version = "=0.2.11", path = "../backend", features = ["extra-traits"] } +wasm-bindgen = { path = "../..", default-features = false } +wasm-bindgen-backend = { path = "../backend", features = ["extra-traits"] } [dependencies] failure = "0.1" diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs old mode 100755 new mode 100644 diff --git a/crates/webidl/tests/all/lib.rs b/crates/webidl/tests/all/main.rs similarity index 100% rename from crates/webidl/tests/all/lib.rs rename to crates/webidl/tests/all/main.rs diff --git a/crates/webidl/tests/expected/lib.rs b/crates/webidl/tests/expected/main.rs old mode 100755 new mode 100644 similarity index 100% rename from crates/webidl/tests/expected/lib.rs rename to crates/webidl/tests/expected/main.rs diff --git a/tests/all/imports.rs b/tests/all/imports.rs index 6117dcfd..9094bcdf 100644 --- a/tests/all/imports.rs +++ b/tests/all/imports.rs @@ -1,6 +1,3 @@ -use std::fs::File; -use std::io::Read; - use super::project; #[test] From 7cd3ca02a26f604972e33e65cac84cd1be1eb9a5 Mon Sep 17 00:00:00 2001 From: teovoinea Date: Mon, 2 Jul 2018 20:35:05 -0700 Subject: [PATCH 47/48] Update with masters and fix PR changes --- crates/webidl/src/lib.rs | 24 ++++++ crates/webidl/src/util.rs | 30 +++++++ crates/webidl/tests/expected/Event.rs | 116 ++++---------------------- 3 files changed, 68 insertions(+), 102 deletions(-) diff --git a/crates/webidl/src/lib.rs b/crates/webidl/src/lib.rs index 950207eb..3d589cf9 100644 --- a/crates/webidl/src/lib.rs +++ b/crates/webidl/src/lib.rs @@ -128,6 +128,10 @@ impl WebidlParse<()> for webidl::ast::Interface { impl WebidlParse<()> for webidl::ast::Typedef { fn webidl_parse(&self, program: &mut backend::ast::Program, _: ()) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + let dest = rust_ident(&self.name); let src = match webidl_ty_to_syn_ty(&self.type_, TypePosition::Return) { Some(src) => src, @@ -154,6 +158,10 @@ impl WebidlParse<()> for webidl::ast::Typedef { impl WebidlParse<()> for webidl::ast::NonPartialInterface { fn webidl_parse(&self, program: &mut backend::ast::Program, _: ()) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + program.imports.push(backend::ast::Import { module: None, version: None, @@ -293,6 +301,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::Operation { impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute { fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + create_getter( &self.name, &self.type_, @@ -317,6 +329,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute { impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute { fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + create_getter( &self.name, &self.type_, @@ -341,6 +357,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute { impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation { fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + create_basic_method( &self.arguments, self.name.as_ref(), @@ -356,6 +376,10 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation { impl<'a> WebidlParse<&'a str> for webidl::ast::StaticOperation { fn webidl_parse(&self, program: &mut backend::ast::Program, self_name: &'a str) -> Result<()> { + if util::is_chrome_only(&self.extended_attributes) { + return Ok(()) + } + create_basic_method( &self.arguments, self.name.as_ref(), diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index 5b197dde..aeeb29f3 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -6,6 +6,7 @@ use heck::SnakeCase; use proc_macro2::Ident; use syn; use webidl; +use webidl::ast::ExtendedAttribute; fn shared_ref(ty: syn::Type) -> syn::Type { syn::TypeReference { @@ -285,3 +286,32 @@ pub fn create_setter( vec![backend::ast::BindgenAttr::Setter(Some(raw_ident(name)))], ) } + +/// ChromeOnly is for things that are only exposed to priveleged code in Firefox. +pub fn is_chrome_only(ext_attrs: &[Box]) -> bool { + ext_attrs.iter().any(|external_attribute| { + return match &**external_attribute { + ExtendedAttribute::ArgumentList(al) => { + println!("ArgumentList"); + al.name == "ChromeOnly" + }, + ExtendedAttribute::Identifier(i) => { + println!("Identifier"); + i.lhs == "ChromeOnly" + }, + ExtendedAttribute::IdentifierList(il) => { + println!("IdentifierList"); + il.lhs == "ChromeOnly" + }, + ExtendedAttribute::NamedArgumentList(nal) => { + println!("NamedArgumentList"); + nal.lhs_name == "ChromeOnly" + }, + ExtendedAttribute::NoArguments(webidl::ast::Other::Identifier(name)) => name == "ChromeOnly", + ExtendedAttribute::NoArguments(_na) => { + println!("NoArguments"); + false + } + }; + }) +} \ No newline at end of file diff --git a/crates/webidl/tests/expected/Event.rs b/crates/webidl/tests/expected/Event.rs index 2bcf0b3f..bc171810 100644 --- a/crates/webidl/tests/expected/Event.rs +++ b/crates/webidl/tests/expected/Event.rs @@ -99,7 +99,7 @@ impl Event { pub extern "C" fn new(type_: &str, event_init_dict: EventInit) -> Event { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -143,7 +143,7 @@ impl Event { pub extern "C" fn event_phase(&self) -> u16 { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -183,7 +183,7 @@ impl Event { pub extern "C" fn stop_propagation(&self) { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -223,7 +223,7 @@ impl Event { pub extern "C" fn stop_immediate_propagation(&self) { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -267,7 +267,7 @@ impl Event { pub extern "C" fn bubbles(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -311,7 +311,7 @@ impl Event { pub extern "C" fn cancelable(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -351,7 +351,7 @@ impl Event { pub extern "C" fn prevent_default(&self) { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -395,95 +395,7 @@ impl Event { pub extern "C" fn default_prevented(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" - ); - } -} -#[no_mangle] -#[allow(non_snake_case)] -#[doc(hidden)] -pub extern "C" fn __wbindgen_describe___widl_f_default_prevented_by_chrome_Event() { - use wasm_bindgen::describe::*; - inform(FUNCTION); - inform(1u32); - <&Event as WasmDescribe>::describe(); - inform(1); - ::describe(); -} -impl Event { - #[allow(bad_style)] - #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] - pub extern "C" fn default_prevented_by_chrome(&self) -> bool { - ::wasm_bindgen::__rt::link_this_library(); - #[wasm_import_module = "__wbindgen_placeholder__"] - extern "C" { - fn __widl_f_default_prevented_by_chrome_Event( - self_: <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::Abi, - ) -> ::Abi; - } - unsafe { - let _ret = { - let mut __stack = ::wasm_bindgen::convert::GlobalStack::new(); - let self_ = - <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::into_abi(self, &mut __stack); - __widl_f_default_prevented_by_chrome_Event(self_) - }; - ::from_abi( - _ret, - &mut ::wasm_bindgen::convert::GlobalStack::new(), - ) - } - } - #[allow(bad_style, unused_variables)] - #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] - pub extern "C" fn default_prevented_by_chrome(&self) -> bool { - panic!( - "cannot call wasm-bindgen imported functions on \ - non-wasm targets" - ); - } -} -#[no_mangle] -#[allow(non_snake_case)] -#[doc(hidden)] -pub extern "C" fn __wbindgen_describe___widl_f_default_prevented_by_content_Event() { - use wasm_bindgen::describe::*; - inform(FUNCTION); - inform(1u32); - <&Event as WasmDescribe>::describe(); - inform(1); - ::describe(); -} -impl Event { - #[allow(bad_style)] - #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] - pub extern "C" fn default_prevented_by_content(&self) -> bool { - ::wasm_bindgen::__rt::link_this_library(); - #[wasm_import_module = "__wbindgen_placeholder__"] - extern "C" { - fn __widl_f_default_prevented_by_content_Event( - self_: <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::Abi, - ) -> ::Abi; - } - unsafe { - let _ret = { - let mut __stack = ::wasm_bindgen::convert::GlobalStack::new(); - let self_ = - <&Event as ::wasm_bindgen::convert::IntoWasmAbi>::into_abi(self, &mut __stack); - __widl_f_default_prevented_by_content_Event(self_) - }; - ::from_abi( - _ret, - &mut ::wasm_bindgen::convert::GlobalStack::new(), - ) - } - } - #[allow(bad_style, unused_variables)] - #[cfg(not(all(target_arch = "wasm32", not(target_os = "emscripten"))))] - pub extern "C" fn default_prevented_by_content(&self) -> bool { - panic!( - "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -527,7 +439,7 @@ impl Event { pub extern "C" fn composed(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -571,7 +483,7 @@ impl Event { pub extern "C" fn is_trusted(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -615,7 +527,7 @@ impl Event { pub extern "C" fn time_stamp(&self) -> DOMHighResTimeStamp { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -669,7 +581,7 @@ impl Event { pub extern "C" fn init_event(&self, type_: &str, bubbles: bool, cancelable: bool) { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -713,7 +625,7 @@ impl Event { pub extern "C" fn cancel_bubble(&self) -> bool { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } @@ -759,7 +671,7 @@ impl Event { pub extern "C" fn set_cancel_bubble(&self, cancel_bubble: bool) { panic!( "cannot call wasm-bindgen imported functions on \ - non-wasm targets" + non-wasm targets" ); } } From 6dede6f20f7d8cc3e7a6a9edff40a7887c8354ad Mon Sep 17 00:00:00 2001 From: Johannes Henninger Date: Tue, 3 Jul 2018 06:41:57 +0200 Subject: [PATCH 48/48] Use f64 for most Math.* bindings (#369) --- src/js.rs | 40 ++++++++++----------- tests/all/js_globals/Math.rs | 70 +++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 49 deletions(-) diff --git a/src/js.rs b/src/js.rs index 3c17ef2b..38293d92 100644 --- a/src/js.rs +++ b/src/js.rs @@ -459,7 +459,7 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs #[wasm_bindgen(static_method_of = Math)] - pub fn abs(number: i32) -> Number; + pub fn abs(x: f64) -> Number; /// The Math.acos() function returns the arccosine (in radians) of a /// number, that is ∀x∊[-1;1] @@ -467,7 +467,7 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos #[wasm_bindgen(static_method_of = Math)] - pub fn acos(adjacent: i32, hypotenuse: i32) -> Number; + pub fn acos(x: f64) -> Number; /// The Math.acosh() function returns the hyperbolic arc-cosine of a /// number, that is ∀x ≥ 1 @@ -475,7 +475,7 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh #[wasm_bindgen(static_method_of = Math)] - pub fn acosh(number: i32) -> Number; + pub fn acosh(x: f64) -> Number; /// The Math.asin() function returns the arcsine (in radians) of a /// number, that is ∀x ∊ [-1;1] @@ -483,27 +483,27 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin #[wasm_bindgen(static_method_of = Math)] - pub fn asin(number: i32) -> Number; + pub fn asin(x: f64) -> Number; /// The Math.asinh() function returns the hyperbolic arcsine of a /// number, that is Math.asinh(x) = arsinh(x) = the unique y such that sinh(y) = x /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh #[wasm_bindgen(static_method_of = Math)] - pub fn asinh(number: i32) -> Number; + pub fn asinh(x: f64) -> Number; /// The Math.atan() function returns the arctangent (in radians) of a /// number, that is Math.atan(x) = arctan(x) = the unique y ∊ [-π2;π2]such that /// tan(y) = x #[wasm_bindgen(static_method_of = Math)] - pub fn atan(number: i32) -> Number; + pub fn atan(x: f64) -> Number; /// The Math.atan2() function returns the arctangent of the quotient of /// its arguments. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2 #[wasm_bindgen(static_method_of = Math)] - pub fn atan2(y: i32, x: i32) -> Number; + pub fn atan2(y: f64, x: f64) -> Number; /// The Math.atanh() function returns the hyperbolic arctangent of a number, /// that is ∀x ∊ (-1,1), Math.atanh(x) = arctanh(x) = the unique y such that @@ -511,21 +511,21 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh #[wasm_bindgen(static_method_of = Math)] - pub fn atanh(x: i32) -> Number; + pub fn atanh(x: f64) -> Number; /// The Math.cbrt() function returns the cube root of a number, that is /// Math.cbrt(x) = x^3 = the unique y such that y^3 = x /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt #[wasm_bindgen(static_method_of = Math)] - pub fn cbrt(x: i32) -> Number; + pub fn cbrt(x: f64) -> Number; /// The Math.ceil() function returns the smallest integer greater than /// or equal to a given number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil #[wasm_bindgen(static_method_of = Math)] - pub fn ceil(x: f32) -> Number; + pub fn ceil(x: f64) -> Number; /// The Math.clz32() function returns the number of leading zero bits in /// the 32-bit binary representation of a number. @@ -539,7 +539,7 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos #[wasm_bindgen(static_method_of = Math)] - pub fn cos(x: f32) -> Number; + pub fn cos(x: f64) -> Number; /// The Math.cosh() function returns the hyperbolic cosine of a number, @@ -547,35 +547,35 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh #[wasm_bindgen(static_method_of = Math)] - pub fn cosh(x: f32) -> Number; + pub fn cosh(x: f64) -> Number; /// The Math.exp() function returns e^x, where x is the argument, and e is Euler's number /// (also known as Napier's constant), the base of the natural logarithms. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp #[wasm_bindgen(static_method_of = Math)] - pub fn exp(x: f32) -> Number; + pub fn exp(x: f64) -> Number; /// The Math.expm1() function returns e^x - 1, where x is the argument, and e the base of the /// natural logarithms. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1 #[wasm_bindgen(static_method_of = Math)] - pub fn expm1(x: f32) -> Number; + pub fn expm1(x: f64) -> Number; /// The Math.floor() function returns the largest integer less than or /// equal to a given number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor #[wasm_bindgen(static_method_of = Math)] - pub fn floor(x: f32) -> Number; + pub fn floor(x: f64) -> Number; /// The Math.fround() function returns the nearest 32-bit single precision float representation /// of a Number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/fround #[wasm_bindgen(static_method_of = Math)] - pub fn fround(x: f32) -> Number; + pub fn fround(x: f64) -> Number; /// The Math.imul() function returns the result of the C-like 32-bit multiplication of the /// two parameters. @@ -589,24 +589,24 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log #[wasm_bindgen(static_method_of = Math)] - pub fn log(x: f32) -> Number; + pub fn log(x: f64) -> Number; /// The Math.log10() function returns the base 10 logarithm of a number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log10 #[wasm_bindgen(static_method_of = Math)] - pub fn log10(x: f32) -> Number; + pub fn log10(x: f64) -> Number; /// The Math.log1p() function returns the natural logarithm (base e) of 1 + a number. /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log1p #[wasm_bindgen(static_method_of = Math)] - pub fn log1p(x: f32) -> Number; + pub fn log1p(x: f64) -> Number; /// The Math.log2() function returns the base 2 logarithm of a number. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/log2 #[wasm_bindgen(static_method_of = Math)] - pub fn log2(x: f32) -> Number; + pub fn log2(x: f64) -> Number; } diff --git a/tests/all/js_globals/Math.rs b/tests/all/js_globals/Math.rs index 3ebab39b..e85305b0 100644 --- a/tests/all/js_globals/Math.rs +++ b/tests/all/js_globals/Math.rs @@ -15,8 +15,8 @@ fn abs() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn abs(number: i32) -> js::Number { - js::Math::abs(number) + pub fn abs(x: f64) -> js::Number { + js::Math::abs(x) } "#, ) @@ -29,6 +29,7 @@ fn abs() { export function test() { assert.equal(wasm.abs(-32), Math.abs(-32)); assert.equal(wasm.abs(32), 32); + assert.equal(wasm.abs(-4.7), Math.abs(-4.7)); } "#, ) @@ -48,8 +49,8 @@ fn acos() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn acos(adjacent: i32, hypotenuse: i32) -> js::Number { - js::Math::acos(adjacent, hypotenuse) + pub fn acos(x: f64) -> js::Number { + js::Math::acos(x) } "#, ) @@ -60,7 +61,9 @@ fn acos() { import * as wasm from "./out"; export function test() { - assert.equal(wasm.acos(-1, 1), Math.PI); + assert.equal(wasm.acos(-1), Math.PI); + assert.equal(wasm.acos(0.5), 1.0471975511965979); + assert(Number.isNaN(wasm.acos(2))); } "#, ) @@ -80,8 +83,8 @@ fn acosh() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn acosh(number: i32) -> js::Number { - js::Math::acosh(number) + pub fn acosh(x: f64) -> js::Number { + js::Math::acosh(x) } "#, ) @@ -94,6 +97,7 @@ fn acosh() { export function test() { assert.equal(wasm.acosh(1), 0); assert.equal(wasm.acosh(2), Math.acosh(2)); + assert(Number.isNaN(wasm.acosh(0.5))); } "#, ) @@ -113,8 +117,8 @@ fn asin() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn asin(opposite: i32, hypotenuse: i32) -> js::Number { - js::Math::asin(opposite / hypotenuse) + pub fn asin(x: f64) -> js::Number { + js::Math::asin(x) } "#, ) @@ -125,7 +129,9 @@ fn asin() { import * as wasm from "./out"; export function test() { - assert.equal(wasm.asin(1, 1), Math.asin(1)); + assert.equal(wasm.asin(1), Math.asin(1)); + assert.equal(wasm.asin(0.5), Math.asin(0.5)); + assert(Number.isNaN(wasm.asin(2))); } "#, ) @@ -145,8 +151,8 @@ fn asinh() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn asinh(number: i32) -> js::Number { - js::Math::asinh(number) + pub fn asinh(x: f64) -> js::Number { + js::Math::asinh(x) } "#, ) @@ -158,6 +164,7 @@ fn asinh() { export function test() { assert.equal(wasm.asinh(1), Math.asinh(1)); + assert.equal(wasm.asinh(0.5), Math.asinh(0.5)); } "#, ) @@ -177,8 +184,8 @@ fn atan() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn atan(number: i32) -> js::Number { - js::Math::atan(number) + pub fn atan(x: f64) -> js::Number { + js::Math::atan(x) } "#, ) @@ -190,6 +197,7 @@ fn atan() { export function test() { assert.equal(wasm.atan(1), Math.atan(1)); + assert.equal(wasm.atan(0.5), Math.atan(0.5)); } "#, ) @@ -209,8 +217,8 @@ fn atan2() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn atan2(x: i32, y: i32) -> js::Number { - js::Math::atan2(x, y) + pub fn atan2(y: f64, x: f64) -> js::Number { + js::Math::atan2(y, x) } "#, ) @@ -222,6 +230,7 @@ fn atan2() { export function test() { assert.equal(wasm.atan2(1, 2), Math.atan2(1, 2)); + assert.equal(wasm.atan2(0.7, 3.8), Math.atan2(0.7, 3.8)); } "#, ) @@ -241,7 +250,7 @@ fn atanh() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn atanh(x: i32) -> js::Number { + pub fn atanh(x: f64) -> js::Number { js::Math::atanh(x) } "#, @@ -254,6 +263,8 @@ fn atanh() { export function test() { assert.equal(wasm.atanh(1), Math.atanh(1)); + assert.equal(wasm.atanh(0.5), Math.atanh(0.5)); + assert(Number.isNaN(wasm.atanh(2))); } "#, ) @@ -273,7 +284,7 @@ fn cbrt() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn cbrt(x: i32) -> js::Number { + pub fn cbrt(x: f64) -> js::Number { js::Math::cbrt(x) } "#, @@ -286,6 +297,7 @@ fn cbrt() { export function test() { assert.equal(wasm.cbrt(27), 3); + assert.equal(wasm.cbrt(12.3), Math.cbrt(12.3)); } "#, ) @@ -305,7 +317,7 @@ fn ceil() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn ceil(x: f32) -> js::Number { + pub fn ceil(x: f64) -> js::Number { js::Math::ceil(x) } "#, @@ -369,7 +381,7 @@ fn cos() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn cos(x: f32) -> js::Number { + pub fn cos(x: f64) -> js::Number { js::Math::cos(x) } "#) @@ -396,7 +408,7 @@ fn cosh() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn cosh(x: f32) -> js::Number { + pub fn cosh(x: f64) -> js::Number { js::Math::cosh(x) } "#) @@ -423,7 +435,7 @@ fn exp() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn exp(x: f32) -> js::Number { + pub fn exp(x: f64) -> js::Number { js::Math::exp(x) } "#) @@ -451,7 +463,7 @@ fn expm1() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn expm1(x: f32) -> js::Number { + pub fn expm1(x: f64) -> js::Number { js::Math::expm1(x) } "#) @@ -482,7 +494,7 @@ fn floor() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn floor(x: f32) -> js::Number { + pub fn floor(x: f64) -> js::Number { js::Math::floor(x) } "#, @@ -513,7 +525,7 @@ fn fround() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn fround(x: f32) -> js::Number { + pub fn fround(x: f64) -> js::Number { js::Math::fround(x) } "#) @@ -570,7 +582,7 @@ fn log() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn log(x: f32) -> js::Number { + pub fn log(x: f64) -> js::Number { js::Math::log(x) } "#) @@ -597,7 +609,7 @@ fn log10() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn log10(x: f32) -> js::Number { + pub fn log10(x: f64) -> js::Number { js::Math::log10(x) } "#) @@ -625,7 +637,7 @@ fn log1p() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn log1p(x: f32) -> js::Number { + pub fn log1p(x: f64) -> js::Number { js::Math::log1p(x) } "#) @@ -654,7 +666,7 @@ fn log2() { use wasm_bindgen::js; #[wasm_bindgen] - pub fn log2(x: f32) -> js::Number { + pub fn log2(x: f64) -> js::Number { js::Math::log2(x) } "#)