From 687412ec50a5babda2203b4411e9d6148d80fa0b Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 17 Aug 2018 13:09:30 -0700 Subject: [PATCH 01/32] Test for AsRef implementations Part of #670 --- crates/js-sys/tests/wasm/Array.rs | 1 + crates/js-sys/tests/wasm/ArrayBuffer.rs | 1 + crates/js-sys/tests/wasm/Boolean.rs | 1 + crates/js-sys/tests/wasm/DataView.rs | 2 ++ crates/js-sys/tests/wasm/Date.rs | 1 + crates/js-sys/tests/wasm/Error.rs | 1 + crates/js-sys/tests/wasm/EvalError.rs | 2 ++ crates/js-sys/tests/wasm/Function.rs | 1 + crates/js-sys/tests/wasm/Map.rs | 1 + crates/js-sys/tests/wasm/Number.rs | 1 + crates/js-sys/tests/wasm/RegExp.rs | 1 + crates/js-sys/tests/wasm/Set.rs | 1 + crates/js-sys/tests/wasm/WeakMap.rs | 1 + crates/js-sys/tests/wasm/WeakSet.rs | 1 + 14 files changed, 16 insertions(+) diff --git a/crates/js-sys/tests/wasm/Array.rs b/crates/js-sys/tests/wasm/Array.rs index 604bbf85..fe6d8867 100644 --- a/crates/js-sys/tests/wasm/Array.rs +++ b/crates/js-sys/tests/wasm/Array.rs @@ -306,4 +306,5 @@ fn array_inheritance() { let array = Array::new(); assert!(array.is_instance_of::()); assert!(array.is_instance_of::()); + let _: &Object = array.as_ref(); } diff --git a/crates/js-sys/tests/wasm/ArrayBuffer.rs b/crates/js-sys/tests/wasm/ArrayBuffer.rs index 21fa0491..a4a082a4 100644 --- a/crates/js-sys/tests/wasm/ArrayBuffer.rs +++ b/crates/js-sys/tests/wasm/ArrayBuffer.rs @@ -41,4 +41,5 @@ fn arraybuffer_inheritance() { let buf = ArrayBuffer::new(4); assert!(buf.is_instance_of::()); assert!(buf.is_instance_of::()); + let _: &Object = buf.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Boolean.rs b/crates/js-sys/tests/wasm/Boolean.rs index 34c53e01..c7aa9377 100644 --- a/crates/js-sys/tests/wasm/Boolean.rs +++ b/crates/js-sys/tests/wasm/Boolean.rs @@ -18,4 +18,5 @@ fn boolean_inheritance() { let b = Boolean::new(&JsValue::from(true)); assert!(b.is_instance_of::()); assert!(b.is_instance_of::()); + let _: &Object = b.as_ref(); } diff --git a/crates/js-sys/tests/wasm/DataView.rs b/crates/js-sys/tests/wasm/DataView.rs index 8efe0c6d..122a7dd2 100644 --- a/crates/js-sys/tests/wasm/DataView.rs +++ b/crates/js-sys/tests/wasm/DataView.rs @@ -50,4 +50,6 @@ fn dataview_inheritance() { assert!(v.is_instance_of::()); assert!(v.is_instance_of::()); + + let _: &Object = v.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Date.rs b/crates/js-sys/tests/wasm/Date.rs index c4026b47..d0496fa4 100644 --- a/crates/js-sys/tests/wasm/Date.rs +++ b/crates/js-sys/tests/wasm/Date.rs @@ -413,4 +413,5 @@ fn date_inheritance() { let date = Date::new(&"August 19, 1975 23:15:30".into()); assert!(date.is_instance_of::()); assert!(date.is_instance_of::()); + let _: &Object = date.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Error.rs b/crates/js-sys/tests/wasm/Error.rs index abe856f1..e05ed23c 100644 --- a/crates/js-sys/tests/wasm/Error.rs +++ b/crates/js-sys/tests/wasm/Error.rs @@ -42,4 +42,5 @@ fn error_inheritance() { let error = Error::new("test"); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Object = error.as_ref(); } diff --git a/crates/js-sys/tests/wasm/EvalError.rs b/crates/js-sys/tests/wasm/EvalError.rs index d1deb73a..e23a25b2 100644 --- a/crates/js-sys/tests/wasm/EvalError.rs +++ b/crates/js-sys/tests/wasm/EvalError.rs @@ -52,4 +52,6 @@ fn evalerror_inheritance() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Function.rs b/crates/js-sys/tests/wasm/Function.rs index c7fed283..86bfa919 100644 --- a/crates/js-sys/tests/wasm/Function.rs +++ b/crates/js-sys/tests/wasm/Function.rs @@ -66,4 +66,5 @@ fn to_string() { fn function_inheritance() { assert!(MAX.is_instance_of::()); assert!(MAX.is_instance_of::()); + let _: &Object = MAX.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Map.rs b/crates/js-sys/tests/wasm/Map.rs index f9ba7740..91282282 100644 --- a/crates/js-sys/tests/wasm/Map.rs +++ b/crates/js-sys/tests/wasm/Map.rs @@ -93,4 +93,5 @@ fn map_inheritance() { let map = Map::new(); assert!(map.is_instance_of::()); assert!(map.is_instance_of::()); + let _: &Object = map.as_ref(); } diff --git a/crates/js-sys/tests/wasm/Number.rs b/crates/js-sys/tests/wasm/Number.rs index 9d43f8a2..b3fae6b1 100644 --- a/crates/js-sys/tests/wasm/Number.rs +++ b/crates/js-sys/tests/wasm/Number.rs @@ -111,4 +111,5 @@ fn number_inheritance() { let n = Number::new(&JsValue::from(42)); assert!(n.is_instance_of::()); assert!(n.is_instance_of::()); + let _: &Object = n.as_ref(); } diff --git a/crates/js-sys/tests/wasm/RegExp.rs b/crates/js-sys/tests/wasm/RegExp.rs index a77d4892..eedbaafc 100644 --- a/crates/js-sys/tests/wasm/RegExp.rs +++ b/crates/js-sys/tests/wasm/RegExp.rs @@ -7,6 +7,7 @@ fn regexp_inheritance() { let re = RegExp::new(".", ""); assert!(re.is_instance_of::()); assert!(re.is_instance_of::()); + let _: &Object = re.as_ref(); } #[wasm_bindgen_test] diff --git a/crates/js-sys/tests/wasm/Set.rs b/crates/js-sys/tests/wasm/Set.rs index 419d66b8..f475c5a0 100644 --- a/crates/js-sys/tests/wasm/Set.rs +++ b/crates/js-sys/tests/wasm/Set.rs @@ -87,4 +87,5 @@ fn set_inheritance() { let set = Set::new(&JsValue::undefined()); assert!(set.is_instance_of::()); assert!(set.is_instance_of::()); + let _: &Object = set.as_ref(); } diff --git a/crates/js-sys/tests/wasm/WeakMap.rs b/crates/js-sys/tests/wasm/WeakMap.rs index 8cfe464c..9b3f0d78 100644 --- a/crates/js-sys/tests/wasm/WeakMap.rs +++ b/crates/js-sys/tests/wasm/WeakMap.rs @@ -57,4 +57,5 @@ fn weakmap_inheritance() { let map = WeakMap::new(); assert!(map.is_instance_of::()); assert!(map.is_instance_of::()); + let _: &Object = map.as_ref(); } diff --git a/crates/js-sys/tests/wasm/WeakSet.rs b/crates/js-sys/tests/wasm/WeakSet.rs index dc70ca8b..541bd448 100644 --- a/crates/js-sys/tests/wasm/WeakSet.rs +++ b/crates/js-sys/tests/wasm/WeakSet.rs @@ -47,4 +47,5 @@ fn weakset_inheritance() { let set = WeakSet::new(); assert!(set.is_instance_of::()); assert!(set.is_instance_of::()); + let _: &Object = set.as_ref(); } From bec3178e3c2046a9aa7fde72258811fd68030da6 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 17 Aug 2018 13:10:11 -0700 Subject: [PATCH 02/32] Make all errors extend Object Part of #670 --- crates/js-sys/src/lib.rs | 10 +++++----- crates/js-sys/tests/wasm/RangeError.rs | 2 ++ crates/js-sys/tests/wasm/ReferenceError.rs | 2 ++ crates/js-sys/tests/wasm/SyntaxError.rs | 2 ++ crates/js-sys/tests/wasm/TypeError.rs | 2 ++ crates/js-sys/tests/wasm/UriError.rs | 2 ++ 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 67cff622..55b5c8d6 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -2092,7 +2092,7 @@ extern { /// or range of allowed values. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError - #[wasm_bindgen(extends = Error)] + #[wasm_bindgen(extends = Error, extends = Object)] #[derive(Clone, Debug)] pub type RangeError; @@ -2111,7 +2111,7 @@ extern { /// variable is referenced. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError - #[wasm_bindgen(extends = Error)] + #[wasm_bindgen(extends = Error, extends = Object)] #[derive(Clone, Debug)] pub type ReferenceError; @@ -2505,7 +2505,7 @@ extern { /// parsing code. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError - #[wasm_bindgen(extends = Error)] + #[wasm_bindgen(extends = Error, extends = Object)] #[derive(Clone, Debug)] pub type SyntaxError; @@ -2525,7 +2525,7 @@ extern { /// expected type. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError - #[wasm_bindgen(extends = Error)] + #[wasm_bindgen(extends = Error, extends = Object)] #[derive(Clone, Debug)] pub type TypeError; @@ -2758,7 +2758,7 @@ extern { /// function was used in a wrong way. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/URIError - #[wasm_bindgen(extends = Error, js_name = URIError)] + #[wasm_bindgen(extends = Error, extends = Object, js_name = URIError)] #[derive(Clone, Debug)] pub type UriError; diff --git a/crates/js-sys/tests/wasm/RangeError.rs b/crates/js-sys/tests/wasm/RangeError.rs index 18c7d7d0..93b42b99 100644 --- a/crates/js-sys/tests/wasm/RangeError.rs +++ b/crates/js-sys/tests/wasm/RangeError.rs @@ -9,6 +9,8 @@ fn range_error() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); let base: &Error = error.as_ref(); assert_eq!(JsValue::from(base.message()), "out of range yo"); diff --git a/crates/js-sys/tests/wasm/ReferenceError.rs b/crates/js-sys/tests/wasm/ReferenceError.rs index 218ad52e..82d6e692 100644 --- a/crates/js-sys/tests/wasm/ReferenceError.rs +++ b/crates/js-sys/tests/wasm/ReferenceError.rs @@ -9,6 +9,8 @@ fn reference_error() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); let base: &Error = error.as_ref(); assert_eq!(JsValue::from(base.message()), "bad reference, fool"); diff --git a/crates/js-sys/tests/wasm/SyntaxError.rs b/crates/js-sys/tests/wasm/SyntaxError.rs index 23a211f0..136746af 100644 --- a/crates/js-sys/tests/wasm/SyntaxError.rs +++ b/crates/js-sys/tests/wasm/SyntaxError.rs @@ -9,6 +9,8 @@ fn syntax_error() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); let base: &Error = error.as_ref(); assert_eq!(JsValue::from(base.message()), "msg"); diff --git a/crates/js-sys/tests/wasm/TypeError.rs b/crates/js-sys/tests/wasm/TypeError.rs index ef7b09fb..e9a9957a 100644 --- a/crates/js-sys/tests/wasm/TypeError.rs +++ b/crates/js-sys/tests/wasm/TypeError.rs @@ -9,6 +9,8 @@ fn type_error() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); let base: &Error = error.as_ref(); assert_eq!(JsValue::from(base.message()), "msg"); diff --git a/crates/js-sys/tests/wasm/UriError.rs b/crates/js-sys/tests/wasm/UriError.rs index ddcafc49..df939e5d 100644 --- a/crates/js-sys/tests/wasm/UriError.rs +++ b/crates/js-sys/tests/wasm/UriError.rs @@ -9,6 +9,8 @@ fn uri_error() { assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); assert!(error.is_instance_of::()); + let _: &Error = error.as_ref(); + let _: &Object = error.as_ref(); let base: &Error = error.as_ref(); assert_eq!(JsValue::from(base.message()), "msg"); From 6dccb7f777c56ad9b209c78ec660b24f5f10c2c5 Mon Sep 17 00:00:00 2001 From: Matt Kraai Date: Fri, 17 Aug 2018 14:50:15 -0700 Subject: [PATCH 03/32] Remove blank line Part of #670 --- crates/js-sys/tests/wasm/DataView.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/js-sys/tests/wasm/DataView.rs b/crates/js-sys/tests/wasm/DataView.rs index 122a7dd2..84fdf0f6 100644 --- a/crates/js-sys/tests/wasm/DataView.rs +++ b/crates/js-sys/tests/wasm/DataView.rs @@ -1,7 +1,7 @@ +use js_sys::*; +use wasm_bindgen::JsCast; use wasm_bindgen::JsValue; use wasm_bindgen_test::*; -use wasm_bindgen::JsCast; -use js_sys::*; #[wasm_bindgen_test] fn test() { @@ -36,7 +36,9 @@ fn test() { v.set_int8(0, 42); // TODO: figure out how to do `bytes[2]` - bytes.subarray(2, 3).for_each(&mut |x, _, _| assert_eq!(x, 42)); + bytes + .subarray(2, 3) + .for_each(&mut |x, _, _| assert_eq!(x, 42)); } #[wasm_bindgen_test] @@ -50,6 +52,5 @@ fn dataview_inheritance() { assert!(v.is_instance_of::()); assert!(v.is_instance_of::()); - let _: &Object = v.as_ref(); } From 4a994da90442312222f1654b204f4e56636bc052 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Fri, 17 Aug 2018 22:54:59 -0400 Subject: [PATCH 04/32] Show how to use web-sys::console::log from the console_log example --- examples/console_log/Cargo.toml | 1 + examples/console_log/README.md | 6 ++++-- examples/console_log/src/lib.rs | 8 ++++++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/console_log/Cargo.toml b/examples/console_log/Cargo.toml index 25761c2d..aa558dc8 100644 --- a/examples/console_log/Cargo.toml +++ b/examples/console_log/Cargo.toml @@ -8,3 +8,4 @@ crate-type = ["cdylib"] [dependencies] wasm-bindgen = { path = "../.." } +web-sys = { path = "../../crates/web-sys" } \ No newline at end of file diff --git a/examples/console_log/README.md b/examples/console_log/README.md index 27a58418..dec3ea2e 100644 --- a/examples/console_log/README.md +++ b/examples/console_log/README.md @@ -2,8 +2,10 @@ [View this example online](https://webassembly.studio/?f=ppd7u8k9i9) -This directory is an example of using the `#[wasm_bindgen]` macro to import the -`console.log` function and call it + +This directory is an example of two ways to get access to the `console.log` function. +The first way uses the `#[wasm_bindgen]` macro to import the function and call it. +The second way uses the binding from the `web-sys` crate. You can build the example with: diff --git a/examples/console_log/src/lib.rs b/examples/console_log/src/lib.rs index 5b652e71..cd23275e 100644 --- a/examples/console_log/src/lib.rs +++ b/examples/console_log/src/lib.rs @@ -1,9 +1,14 @@ #![feature(use_extern_macros)] extern crate wasm_bindgen; +extern crate web_sys; use wasm_bindgen::prelude::*; +// You can use the console bindings from web-sys... +use web_sys::console; + +// ... or you can manually write the bindings yourself #[wasm_bindgen] extern "C" { #[wasm_bindgen(js_namespace = console)] @@ -19,4 +24,7 @@ pub fn run() { log("Hello from Rust!"); log_u32(42); log_many("Logging", "many values!"); + + console::log(JsValue::from("Another message from rust!")); + console::log(JsValue::from(56u32)); } From c543b5d1496549425850e0ca605383ab04b2dbd1 Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sat, 18 Aug 2018 09:11:07 -0500 Subject: [PATCH 05/32] Add extends attributes for js_sys:Generator --- crates/js-sys/src/lib.rs | 1 + crates/js-sys/tests/wasm/Generator.rs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 67cff622..91746028 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -885,6 +885,7 @@ impl Function { // Generator #[wasm_bindgen] extern { + #[wasm_bindgen(extends = Object)] #[derive(Clone, Debug)] pub type Generator; diff --git a/crates/js-sys/tests/wasm/Generator.rs b/crates/js-sys/tests/wasm/Generator.rs index 5fb738fc..3395ced2 100644 --- a/crates/js-sys/tests/wasm/Generator.rs +++ b/crates/js-sys/tests/wasm/Generator.rs @@ -1,5 +1,6 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_test::*; +use wasm_bindgen::JsCast; use js_sys::*; #[wasm_bindgen(module = "tests/wasm/Generator.js")] @@ -56,3 +57,10 @@ fn throw() { assert!(next.value().is_undefined()); assert!(next.done()); } + +#[wasm_bindgen_test] +fn generator_inheritance() { + let gen = dummy_generator(); + + assert!(gen.is_instance_of::()); +} From 302f7ba21d0480eb8c66e58c1d112fc25ebf8055 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sat, 18 Aug 2018 11:23:29 -0400 Subject: [PATCH 06/32] Fix missing WindowOrWorkerGlobalScope partial interface mixins. Without the "mixin" keyword, wasm_bindgen_webidl would report: Partial interface WindowOrWorkerGlobalScope missing non-partial interface Also, including the "mixin" keyword here is consistent with the official webidl spec (for example see https://fetch.spec.whatwg.org/#fetch-method) --- .../webidls/enabled/WindowOrWorkerGlobalScope.webidl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/web-sys/webidls/enabled/WindowOrWorkerGlobalScope.webidl b/crates/web-sys/webidls/enabled/WindowOrWorkerGlobalScope.webidl index b02a355f..9bc0711b 100644 --- a/crates/web-sys/webidls/enabled/WindowOrWorkerGlobalScope.webidl +++ b/crates/web-sys/webidls/enabled/WindowOrWorkerGlobalScope.webidl @@ -43,25 +43,25 @@ interface mixin WindowOrWorkerGlobalScope { }; // https://fetch.spec.whatwg.org/#fetch-method -partial interface WindowOrWorkerGlobalScope { +partial interface mixin WindowOrWorkerGlobalScope { [NewObject, NeedsCallerType] Promise fetch(RequestInfo input, optional RequestInit init); }; // https://w3c.github.io/webappsec-secure-contexts/#monkey-patching-global-object -partial interface WindowOrWorkerGlobalScope { +partial interface mixin WindowOrWorkerGlobalScope { readonly attribute boolean isSecureContext; }; // http://w3c.github.io/IndexedDB/#factory-interface -partial interface WindowOrWorkerGlobalScope { +partial interface mixin WindowOrWorkerGlobalScope { // readonly attribute IDBFactory indexedDB; [Throws] readonly attribute IDBFactory? indexedDB; }; // https://w3c.github.io/ServiceWorker/#self-caches -partial interface WindowOrWorkerGlobalScope { +partial interface mixin WindowOrWorkerGlobalScope { [Throws, Func="mozilla::dom::DOMPrefs::DOMCachesEnabled", SameObject] readonly attribute CacheStorage caches; }; From 0d3f7061954d4f3cfdf9e6517c128c38fd15465b Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sat, 18 Aug 2018 20:51:52 -0400 Subject: [PATCH 07/32] Add binding for String.prototype.localeCompare --- crates/js-sys/src/lib.rs | 8 ++++ crates/js-sys/tests/wasm/JsString.rs | 64 ++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 67cff622..73e77aa0 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -2996,6 +2996,14 @@ extern "C" { #[wasm_bindgen(method, js_class = "String", js_name = lastIndexOf)] pub fn last_index_of(this: &JsString, search_value: &str, from_index: i32) -> i32; + /// The localeCompare() method returns a number indicating whether + /// a reference string comes before or after or is the same as + /// the given string in sort order. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare + #[wasm_bindgen(method, js_class = "String", js_name = localeCompare)] + pub fn locale_compare(this: &JsString, compare_string: &str, locales: &Array, options: &Object) -> i32; + /// The normalize() method returns the Unicode Normalization Form /// of a given string (if the value isn't a string, it will be converted to one first). /// diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 66fc5771..ecdaa6ad 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -135,6 +135,70 @@ fn last_index_of() { assert_eq!(js.last_index_of("", 2), 2); } +#[wasm_bindgen_test] +fn locale_compare() { + let a = "résumé"; + let b = "RESUME"; + let js_a = JsString::from(a); + let js_b = JsString::from(b); + let locales = Array::new(); + let options = Object::new(); + + assert_eq!(js_a.locale_compare(a, &locales, &options), 0); + assert_eq!(js_b.locale_compare(b, &locales, &options), 0); + assert!(js_a.locale_compare(b, &locales, &options) > 0); + assert!(js_b.locale_compare(a, &locales, &options) < 0); + + locales.push(&"en".into()); + Reflect::set(options.as_ref(), &"sensitivity".into(), &"base".into()); + + assert_eq!(js_a.locale_compare(a, &locales, &options), 0); + assert_eq!(js_a.locale_compare(b, &locales, &options), 0); + assert_eq!(js_b.locale_compare(a, &locales, &options), 0); + assert_eq!(js_b.locale_compare(b, &locales, &options), 0); + + let a = "ä"; + let z = "z"; + let js_a = JsString::from(a); + let js_z = JsString::from(z); + let locales_de = Array::of1(&"de".into()); + let locales_sv = Array::of1(&"sv".into()); + let options = Object::new(); + + assert_eq!(js_a.locale_compare(a, &locales_de, &options), 0); + assert_eq!(js_z.locale_compare(z, &locales_de, &options), 0); + assert!(js_a.locale_compare(z, &locales_de, &options) < 0); + assert!(js_z.locale_compare(a, &locales_de, &options) > 0); + + assert_eq!(js_a.locale_compare(a, &locales_sv, &options), 0); + assert_eq!(js_z.locale_compare(z, &locales_sv, &options), 0); + assert!(js_a.locale_compare(z, &locales_sv, &options) < 0); + assert!(js_z.locale_compare(a, &locales_sv, &options) > 0); + + let two = "2"; + let ten = "10"; + let js_two = JsString::from(two); + let js_ten = JsString::from(ten); + let locales = Array::new(); + let options = Object::new(); + + assert_eq!(js_two.locale_compare(two, &locales, &options), 0); + assert_eq!(js_ten.locale_compare(ten, &locales, &options), 0); + assert!(js_two.locale_compare(ten, &locales, &options) > 0); + assert!(js_ten.locale_compare(two, &locales, &options) < 0); + + locales.push(&"en-u-kn-true".into()); + + assert!(js_two.locale_compare(ten, &locales, &options) < 0); + assert!(js_ten.locale_compare(two, &locales, &options) > 0); + + let locales = Array::new(); + Reflect::set(options.as_ref(), &"numeric".into(), &JsValue::TRUE); + + assert!(js_two.locale_compare(ten, &locales, &options) < 0); + assert!(js_ten.locale_compare(two, &locales, &options) > 0); +} + #[wasm_bindgen_test] fn normalize() { let js = JsString::from("\u{1E9B}\u{0323}"); From 00a0152adff8ef9e8627c6c3e66dbd5525583c29 Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sat, 18 Aug 2018 20:52:11 -0400 Subject: [PATCH 08/32] Rename local param to locale --- crates/js-sys/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 73e77aa0..aab68ce9 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3070,14 +3070,14 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase #[wasm_bindgen(method, js_class = "String", js_name = toLocaleLowerCase)] - pub fn to_locale_lower_case(this: &JsString, local: Option<&str>) -> JsString; + pub fn to_locale_lower_case(this: &JsString, locale: Option<&str>) -> JsString; /// The toLocaleUpperCase() method returns the calling string value converted to upper case, /// according to any locale-specific case mappings. /// /// https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase #[wasm_bindgen(method, js_class = "String", js_name = toLocaleUpperCase)] - pub fn to_locale_upper_case(this: &JsString, local: Option<&str>) -> JsString; + pub fn to_locale_upper_case(this: &JsString, locale: Option<&str>) -> JsString; /// The `toLowerCase()` method returns the calling string value /// converted to lower case. From 27d48ad267ad12bf8365caa40b940066d4426e86 Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Fri, 17 Aug 2018 20:46:44 -0400 Subject: [PATCH 09/32] Add bindings for String.from_code_point --- crates/js-sys/src/lib.rs | 34 ++++++++++++++++++++++++++++ crates/js-sys/tests/wasm/JsString.rs | 17 ++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 67cff622..855c4dc9 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -2973,6 +2973,40 @@ extern "C" { #[wasm_bindgen(static_method_of = JsString, js_class = "String", js_name = fromCharCode)] pub fn from_char_code5(a: u32, b: u32, c: u32, d: u32, e: u32) -> JsString; + + /// The static String.fromCodePoint() method returns a string created by + /// using the specified sequence of code points. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint + /// + /// # Exceptions + /// + /// A RangeError is thrown if an invalid Unicode code point is given + /// + /// # Notes + /// + /// There are a few bindings to `from_code_point` in `js-sys`: `from_code_point1`, `from_code_point2`, etc... + /// with different arities. + #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] + pub fn from_code_point1(a: u32) -> Result; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint + #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] + pub fn from_code_point2(a: u32, b: u32) -> Result; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint + #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] + pub fn from_code_point3(a: u32, b: u32, c: u32) -> Result; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint + #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] + pub fn from_code_point4(a: u32, b: u32, c: u32, d: u32) -> Result; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint + #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] + pub fn from_code_point5(a: u32, b: u32, c: u32, d: u32, e: u32) -> Result; + + /// The `includes()` method determines whether one string may be found /// within another string, returning true or false as appropriate. /// diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 66fc5771..74f3eac8 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -85,6 +85,23 @@ fn from_char_code() { assert_eq!(JsString::from_char_code4(codes[0], codes[1], codes[2], codes[3]), "½+¾="); } +#[wasm_bindgen_test] +fn from_code_point() { + let s = "☃★♲你"; + let codes : Vec = s.chars() + .map(|char| char as u32) + .collect(); + + assert_eq!(JsString::from_code_point1(codes[0]).unwrap(), "☃"); + assert_eq!(JsString::from_code_point2(codes[0], codes[1]).unwrap(), "☃★"); + assert_eq!(JsString::from_code_point3(codes[0], codes[1], codes[2]).unwrap(), "☃★♲"); + assert_eq!(JsString::from_code_point4(codes[0], codes[1], codes[2], codes[3]).unwrap(), "☃★♲你"); + + assert!(!JsString::from_code_point1(0x10FFFF).is_err()); + assert!(JsString::from_code_point1(0x110000).is_err()); + assert!(JsString::from_code_point1(u32::max_value()).is_err()); +} + #[wasm_bindgen_test] fn includes() { let str = JsString::from("Blue Whale"); From f0811d5ac0becd7cb325c59e8d8d849805a31e7a Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sun, 19 Aug 2018 10:03:56 -0500 Subject: [PATCH 10/32] Add extends to js-sys:Intl.Collater --- crates/js-sys/src/lib.rs | 2 +- crates/js-sys/tests/wasm/Intl.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 487fc095..8b4e2854 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3401,7 +3401,7 @@ pub mod Intl { /// that enable language sensitive string comparison. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator - #[wasm_bindgen(js_namespace = Intl)] + #[wasm_bindgen(extends = Object, js_namespace = Intl)] #[derive(Clone, Debug)] pub type Collator; diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index 6fc8add6..a22b75e4 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -35,6 +35,10 @@ fn collator() { let a = Intl::Collator::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); + + assert!(c.is_instance_of::()); + assert!(c.is_instance_of::()); + let _: &Object = c.as_ref(); } #[wasm_bindgen_test] From 780c7236f1de7196f6ab630e05afd6b499b6b087 Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sun, 19 Aug 2018 10:13:25 -0500 Subject: [PATCH 11/32] Add extends to js-sys:Intl.DateTimeFormat --- crates/js-sys/src/lib.rs | 2 +- crates/js-sys/tests/wasm/Intl.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 8b4e2854..89169596 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3445,7 +3445,7 @@ pub mod Intl { /// that enable language-sensitive date and time formatting. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat - #[wasm_bindgen(js_namespace = Intl)] + #[wasm_bindgen(extends = Object, js_namespace = Intl)] #[derive(Clone, Debug)] pub type DateTimeFormat; diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index a22b75e4..62f6102f 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -54,6 +54,10 @@ fn date_time_format() { let a = Intl::DateTimeFormat::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); + + assert!(c.is_instance_of::()); + assert!(c.is_instance_of::()); + let _: &Object = c.as_ref(); } #[wasm_bindgen_test] From ee131888da9eb62b8cd416641c1e1e14793b0ebe Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sun, 19 Aug 2018 10:19:03 -0500 Subject: [PATCH 12/32] Add extends to js-sys:Intl.NumberFormat --- crates/js-sys/src/lib.rs | 2 +- crates/js-sys/tests/wasm/Intl.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 89169596..e402b6ab 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3496,7 +3496,7 @@ pub mod Intl { /// that enable language sensitive number formatting. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat - #[wasm_bindgen(js_namespace = Intl)] + #[wasm_bindgen(extends = Object, js_namespace = Intl)] #[derive(Clone, Debug)] pub type NumberFormat; diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index 62f6102f..8abff50b 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -72,6 +72,10 @@ fn number_format() { let a = Intl::NumberFormat::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); + + assert!(n.is_instance_of::()); + assert!(n.is_instance_of::()); + let _: &Object = n.as_ref(); } #[wasm_bindgen_test] From 1762b3cba007fa5d2b4c389154d8ec7a97334a3d Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sun, 19 Aug 2018 11:03:55 -0500 Subject: [PATCH 13/32] Add extends to js-sys:Intl.PluralRules --- crates/js-sys/src/lib.rs | 2 +- crates/js-sys/tests/wasm/Intl.rs | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index e402b6ab..e429d413 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3546,7 +3546,7 @@ pub mod Intl { /// that enable plural sensitive formatting and plural language rules. /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/PluralRules - #[wasm_bindgen(js_namespace = Intl)] + #[wasm_bindgen(extends = Object, js_namespace = Intl)] #[derive(Clone, Debug)] pub type PluralRules; diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index 8abff50b..4fd43f5d 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -87,6 +87,10 @@ fn plural_rules() { assert!(r.resolved_options().is_instance_of::()); assert_eq!(r.select(1_f64), "one"); - let r = Intl::PluralRules::supported_locales_of(&locales, &opts); - assert!(r.is_instance_of::()); + let a = Intl::PluralRules::supported_locales_of(&locales, &opts); + assert!(a.is_instance_of::()); + + assert!(r.is_instance_of::()); + assert!(r.is_instance_of::()); + let _: &Object = r.as_ref(); } From b330bd1bf1065d826e86b219503afff6b74a84e3 Mon Sep 17 00:00:00 2001 From: Mason Stallmo Date: Sun, 19 Aug 2018 11:27:04 -0500 Subject: [PATCH 14/32] Refactor inheritance checks into their own tests --- crates/js-sys/tests/wasm/Intl.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/crates/js-sys/tests/wasm/Intl.rs b/crates/js-sys/tests/wasm/Intl.rs index 4fd43f5d..74c57ecd 100644 --- a/crates/js-sys/tests/wasm/Intl.rs +++ b/crates/js-sys/tests/wasm/Intl.rs @@ -35,6 +35,13 @@ fn collator() { let a = Intl::Collator::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); +} + +#[wasm_bindgen_test] +fn collator_inheritance() { + let locales = Array::of1(&JsValue::from("en-US")); + let opts = Object::new(); + let c = Intl::Collator::new(&locales, &opts); assert!(c.is_instance_of::()); assert!(c.is_instance_of::()); @@ -54,6 +61,13 @@ fn date_time_format() { let a = Intl::DateTimeFormat::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); +} + +#[wasm_bindgen_test] +fn date_time_format_inheritance() { + let locales = Array::of1(&JsValue::from("en-US")); + let opts = Object::new(); + let c = Intl::DateTimeFormat::new(&locales, &opts); assert!(c.is_instance_of::()); assert!(c.is_instance_of::()); @@ -72,6 +86,13 @@ fn number_format() { let a = Intl::NumberFormat::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); +} + +#[wasm_bindgen_test] +fn number_format_inheritance() { + let locales = Array::of1(&JsValue::from("en-US")); + let opts = Object::new(); + let n = Intl::NumberFormat::new(&locales, &opts); assert!(n.is_instance_of::()); assert!(n.is_instance_of::()); @@ -89,6 +110,13 @@ fn plural_rules() { let a = Intl::PluralRules::supported_locales_of(&locales, &opts); assert!(a.is_instance_of::()); +} + +#[wasm_bindgen_test] +fn plural_rules_inheritance() { + let locales = Array::of1(&JsValue::from("en-US")); + let opts = Object::new(); + let r = Intl::PluralRules::new(&locales, &opts); assert!(r.is_instance_of::()); assert!(r.is_instance_of::()); From 7b53b1c88ec828f52c2ed613716aac6e113d585c Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sat, 18 Aug 2018 21:55:59 -0400 Subject: [PATCH 15/32] Add binding for String.prototype.match --- crates/js-sys/src/lib.rs | 8 ++++++-- crates/js-sys/tests/wasm/JsString.rs | 25 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index e429d413..75d52cec 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -2974,7 +2974,6 @@ extern "C" { #[wasm_bindgen(static_method_of = JsString, js_class = "String", js_name = fromCharCode)] pub fn from_char_code5(a: u32, b: u32, c: u32, d: u32, e: u32) -> JsString; - /// The static String.fromCodePoint() method returns a string created by /// using the specified sequence of code points. /// @@ -3007,7 +3006,6 @@ extern "C" { #[wasm_bindgen(catch, static_method_of = JsString, js_class = "String", js_name = fromCodePoint)] pub fn from_code_point5(a: u32, b: u32, c: u32, d: u32, e: u32) -> Result; - /// The `includes()` method determines whether one string may be found /// within another string, returning true or false as appropriate. /// @@ -3039,6 +3037,12 @@ extern "C" { #[wasm_bindgen(method, js_class = "String", js_name = localeCompare)] pub fn locale_compare(this: &JsString, compare_string: &str, locales: &Array, options: &Object) -> i32; + /// The match() method retrieves the matches when matching a string against a regular expression. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match + #[wasm_bindgen(method, js_class = "String", js_name = match)] + pub fn match_(this: &JsString, pattern: &RegExp) -> Option; + /// The normalize() method returns the Unicode Normalization Form /// of a given string (if the value isn't a string, it will be converted to one first). /// diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index ca416cc9..a22fd653 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -216,6 +216,31 @@ fn locale_compare() { assert!(js_ten.locale_compare(two, &locales, &options) > 0); } +#[wasm_bindgen_test] +fn match_() { + let s = "The quick brown fox jumped over the lazy dog. It barked."; + let re = RegExp::new("[A-Z]", "g"); + let result = JsString::from(s).match_(&re); + let obj = result.unwrap(); + + assert_eq!(Reflect::get(obj.as_ref(), &"0".into()), "T"); + assert_eq!(Reflect::get(obj.as_ref(), &"1".into()), "I"); + + let result = JsString::from("foo").match_(&re); + assert!(result.is_none()); + + let s = "For more information, see Chapter 3.4.5.1"; + let re = RegExp::new("see (chapter \\d+(\\.\\d)*)", "i"); + let result = JsString::from(s).match_(&re); + let obj = result.unwrap(); + + assert_eq!(Reflect::get(obj.as_ref(), &"0".into()), "see Chapter 3.4.5.1"); + assert_eq!(Reflect::get(obj.as_ref(), &"1".into()), "Chapter 3.4.5.1"); + assert_eq!(Reflect::get(obj.as_ref(), &"2".into()), ".1"); + assert_eq!(Reflect::get(obj.as_ref(), &"index".into()), 22); + assert_eq!(Reflect::get(obj.as_ref(), &"input".into()), s); +} + #[wasm_bindgen_test] fn normalize() { let js = JsString::from("\u{1E9B}\u{0323}"); From 44877880bbf2ebc5062529becdb488c9c58db42b Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sun, 19 Aug 2018 14:42:22 -0400 Subject: [PATCH 16/32] Add bindings for String.prototype.replace --- crates/js-sys/src/lib.rs | 14 ++++++++++++++ crates/js-sys/tests/wasm/JsString.js | 8 +++++++- crates/js-sys/tests/wasm/JsString.rs | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 75d52cec..6cdc1fdd 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3075,6 +3075,20 @@ extern "C" { #[wasm_bindgen(method, js_class = "String")] pub fn repeat(this: &JsString, count: i32) -> JsString; + /// The replace() method returns a new string with some or all matches of a pattern + /// replaced by a replacement. The pattern can be a string or a RegExp, and + /// the replacement can be a string or a function to be called for each match. + /// + /// Note: The original string will remain unchanged. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace + #[wasm_bindgen(method, js_class = "String")] + pub fn replace(this: &JsString, pattern: &RegExp, replacement: &str) -> JsString; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace + #[wasm_bindgen(method, js_class = "String", js_name = replace)] + pub fn replace_function(this: &JsString, pattern: &RegExp, replacement: &Function) -> JsString; + /// The `slice()` method extracts a section of a string and returns it as a /// new string, without modifying the original string. /// diff --git a/crates/js-sys/tests/wasm/JsString.js b/crates/js-sys/tests/wasm/JsString.js index 04a64a9a..fbaec7ae 100644 --- a/crates/js-sys/tests/wasm/JsString.js +++ b/crates/js-sys/tests/wasm/JsString.js @@ -1 +1,7 @@ -exports.new_string_object = () => new String("hi"); \ No newline at end of file +exports.new_string_object = () => new String("hi"); + +exports.get_replacer_function = function() { + return function upperToHyphenLower(match, offset, string) { + return (offset > 0 ? '-' : '') + match.toLowerCase(); + }; +}; diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index a22fd653..47a3a8fe 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -7,6 +7,7 @@ use js_sys::*; #[wasm_bindgen(module = "tests/wasm/JsString.js")] extern { fn new_string_object() -> JsValue; + fn get_replacer_function() -> Function; } #[wasm_bindgen_test] @@ -284,6 +285,21 @@ fn repeat() { assert_eq!(JsString::from("test").repeat(3), "testtesttest"); } +#[wasm_bindgen_test] +fn replace() { + let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); + let re = RegExp::new("dog", "g"); + let result = js.replace(&re, "ferret"); + + assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?"); + + let js = JsString::from("borderTop"); + let re = RegExp::new("[A-Z]", "g"); + let result = js.replace_function(&re, &get_replacer_function()); + + assert_eq!(result, "border-top"); +} + #[wasm_bindgen_test] fn slice() { let characters = JsString::from("acxn18"); From 8698084a432f7e4882ce4d27eebb150ff01aaf1d Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sun, 19 Aug 2018 14:52:10 -0400 Subject: [PATCH 17/32] Add binding for String.prototype.search --- crates/js-sys/src/lib.rs | 7 +++++++ crates/js-sys/tests/wasm/JsString.rs | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 6cdc1fdd..6c491346 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3089,6 +3089,13 @@ extern "C" { #[wasm_bindgen(method, js_class = "String", js_name = replace)] pub fn replace_function(this: &JsString, pattern: &RegExp, replacement: &Function) -> JsString; + /// The search() method executes a search for a match between + /// a regular expression and this String object. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search + #[wasm_bindgen(method, js_class = "String")] + pub fn search(this: &JsString, pattern: &RegExp) -> 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/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 47a3a8fe..898ee767 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -300,6 +300,21 @@ fn replace() { assert_eq!(result, "border-top"); } +#[wasm_bindgen_test] +fn search() { + let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); + let re = RegExp::new("[^\\w\\s]", "g"); + + assert_eq!(js.search(&re), 44); + + let js = JsString::from("hey JudE"); + let re1 = RegExp::new("[A-Z]", "g"); + let re2 = RegExp::new("[.]", "g"); + + assert_eq!(js.search(&re1), 4); + assert_eq!(js.search(&re2), -1); +} + #[wasm_bindgen_test] fn slice() { let characters = JsString::from("acxn18"); From 4f294224f079cfae9d1388edbc07f1f62601f815 Mon Sep 17 00:00:00 2001 From: Danielle Pham Date: Sun, 19 Aug 2018 15:09:45 -0400 Subject: [PATCH 18/32] Add bindings for String.prototype.split --- crates/js-sys/src/lib.rs | 11 ++++++++++ crates/js-sys/tests/wasm/JsString.rs | 33 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 6c491346..6f36d8f8 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3103,6 +3103,17 @@ extern "C" { #[wasm_bindgen(method, js_class = "String")] pub fn slice(this: &JsString, start: u32, end: u32) -> JsString; + /// The split() method splits a String object into an array of strings by separating the string + /// into substrings, using a specified separator string to determine where to make each split. + /// + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split + #[wasm_bindgen(method, js_class = "String")] + pub fn split(this: &JsString, separator: &str) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split + #[wasm_bindgen(method, js_class = "String", js_name = split)] + pub fn split_limit(this: &JsString, separator: &str, limit: u32) -> Array; + /// The `startsWith()` method determines whether a string begins with the /// characters of a specified string, returning true or false as /// appropriate. diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 898ee767..5458e3e7 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -321,6 +321,39 @@ fn slice() { assert_eq!(characters.slice(1, 3), "cx"); } +#[wasm_bindgen_test] +fn split() { + let js = JsString::from("Oh brave new world"); + let result = js.split(" "); + + let mut v = Vec::with_capacity(result.length() as usize); + result.for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(v[0], "Oh"); + assert_eq!(v[1], "brave"); + assert_eq!(v[2], "new"); + assert_eq!(v[3], "world"); + + let js = JsString::from("Oct,Nov,Dec"); + let result = js.split(","); + + let mut v = Vec::with_capacity(result.length() as usize); + result.for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(v[0], "Oct"); + assert_eq!(v[1], "Nov"); + assert_eq!(v[2], "Dec"); + + let result = js.split_limit(",", 2); + + let mut v = Vec::with_capacity(result.length() as usize); + result.for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(result.length(), 2); + assert_eq!(v[0], "Oct"); + assert_eq!(v[1], "Nov"); +} + #[wasm_bindgen_test] fn starts_with() { let js = JsString::from("To be, or not to be, that is the question."); From d4297ad2d391aa93c685127616c46adfd1987f8a Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 19 Aug 2018 14:31:35 -0700 Subject: [PATCH 19/32] Remove `use_extern_macros` features This has now been stabilized! --- README.md | 2 - crates/futures/src/lib.rs | 3 - crates/futures/tests/tests.rs | 1 - crates/js-sys/src/lib.rs | 1 - crates/js-sys/tests/headless.rs | 1 - crates/js-sys/tests/wasm/main.rs | 1 - .../ui-tests/attribute-fails-to-parse.rs | 2 - .../ui-tests/attribute-fails-to-parse.stderr | 4 +- crates/macro/ui-tests/bad-signatures.rs | 2 - crates/macro/ui-tests/bad-signatures.stderr | 12 +-- crates/macro/ui-tests/invalid-attr.rs | 2 - crates/macro/ui-tests/invalid-attr.stderr | 12 +-- crates/macro/ui-tests/invalid-enums.rs | 2 - crates/macro/ui-tests/invalid-enums.stderr | 16 ++-- crates/macro/ui-tests/invalid-imports.rs | 2 - crates/macro/ui-tests/invalid-imports.stderr | 76 +++++++++---------- crates/macro/ui-tests/invalid-items.rs | 2 - crates/macro/ui-tests/invalid-items.stderr | 54 ++++++------- crates/macro/ui-tests/invalid-methods.rs | 2 - crates/macro/ui-tests/invalid-methods.stderr | 44 +++++------ crates/macro/ui-tests/non-public-function.rs | 2 - .../macro/ui-tests/non-public-function.stderr | 4 +- crates/test/README.md | 2 - crates/test/sample/src/lib.rs | 2 - crates/test/sample/tests/browser.rs | 2 - crates/test/sample/tests/node.rs | 2 - crates/test/src/lib.rs | 1 - crates/web-sys/tests/wasm/main.rs | 1 - crates/webidl-tests/main.rs | 2 - examples/add/src/lib.rs | 2 - examples/asm.js/src/lib.rs | 2 - examples/canvas/src/lib.rs | 2 - examples/char/src/lib.rs | 2 - examples/closures/src/lib.rs | 2 - examples/comments/src/lib.rs | 2 - examples/console_log/src/lib.rs | 2 - examples/dom/src/lib.rs | 2 - .../guide-supported-types-examples/src/lib.rs | 1 - examples/hello_world/src/lib.rs | 2 - examples/import_js/src/lib.rs | 2 - examples/julia_set/src/lib.rs | 2 - examples/math/src/lib.rs | 2 - examples/no_modules/src/lib.rs | 2 - examples/performance/src/lib.rs | 2 - examples/smorgasboard/src/lib.rs | 2 - examples/wasm-in-wasm/src/lib.rs | 2 - examples/webaudio/src/lib.rs | 4 +- guide/src/whirlwind-tour/basic-usage.md | 2 - .../src/whirlwind-tour/what-else-can-we-do.md | 2 - src/lib.rs | 2 +- tests/crates/a/src/lib.rs | 2 - tests/crates/b/src/lib.rs | 2 - tests/headless.rs | 1 - tests/no-std/test.rs | 1 - tests/non_wasm.rs | 2 - tests/std-crate-no-std-dep.rs | 1 - tests/wasm/main.rs | 1 - 57 files changed, 114 insertions(+), 198 deletions(-) diff --git a/README.md b/README.md index 5e827229..85861127 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,6 @@ Import JavaScript things into Rust and export Rust things to JavaScript. ```rust -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/futures/src/lib.rs b/crates/futures/src/lib.rs index 41bdd4e3..d8c672be 100644 --- a/crates/futures/src/lib.rs +++ b/crates/futures/src/lib.rs @@ -33,8 +33,6 @@ //! `Promise`. //! //! ```rust,no_run -//! #![feature(use_extern_macros)] -//! //! extern crate futures; //! extern crate js_sys; //! extern crate wasm_bindgen; @@ -104,7 +102,6 @@ //! ``` #![deny(missing_docs)] -#![feature(use_extern_macros)] extern crate futures; extern crate wasm_bindgen; diff --git a/crates/futures/tests/tests.rs b/crates/futures/tests/tests.rs index a6225737..089003d5 100755 --- a/crates/futures/tests/tests.rs +++ b/crates/futures/tests/tests.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] #![cfg(target_arch = "wasm32")] extern crate futures; diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 487fc095..7c4dd569 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -17,7 +17,6 @@ //! bindings. #![doc(html_root_url = "https://docs.rs/js-sys/0.2")] -#![feature(use_extern_macros)] extern crate wasm_bindgen; diff --git a/crates/js-sys/tests/headless.rs b/crates/js-sys/tests/headless.rs index 139c1358..1b45ea7b 100755 --- a/crates/js-sys/tests/headless.rs +++ b/crates/js-sys/tests/headless.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] #![cfg(target_arch = "wasm32")] extern crate wasm_bindgen_test; diff --git a/crates/js-sys/tests/wasm/main.rs b/crates/js-sys/tests/wasm/main.rs index 36271531..7cdcc54a 100755 --- a/crates/js-sys/tests/wasm/main.rs +++ b/crates/js-sys/tests/wasm/main.rs @@ -1,5 +1,4 @@ #![cfg(target_arch = "wasm32")] -#![feature(use_extern_macros)] #![allow(non_snake_case)] extern crate js_sys; diff --git a/crates/macro/ui-tests/attribute-fails-to-parse.rs b/crates/macro/ui-tests/attribute-fails-to-parse.rs index 514876fa..d58395e9 100644 --- a/crates/macro/ui-tests/attribute-fails-to-parse.rs +++ b/crates/macro/ui-tests/attribute-fails-to-parse.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/attribute-fails-to-parse.stderr b/crates/macro/ui-tests/attribute-fails-to-parse.stderr index dbe5f5d5..eb7960eb 100644 --- a/crates/macro/ui-tests/attribute-fails-to-parse.stderr +++ b/crates/macro/ui-tests/attribute-fails-to-parse.stderr @@ -1,7 +1,7 @@ error: error parsing #[wasm_bindgen] attribute options: failed to parse anything - --> $DIR/attribute-fails-to-parse.rs:7:16 + --> $DIR/attribute-fails-to-parse.rs:5:16 | -7 | #[wasm_bindgen(nonsense)] +5 | #[wasm_bindgen(nonsense)] | ^^^^^^^^ error: aborting due to previous error diff --git a/crates/macro/ui-tests/bad-signatures.rs b/crates/macro/ui-tests/bad-signatures.rs index 7e414149..561d909b 100644 --- a/crates/macro/ui-tests/bad-signatures.rs +++ b/crates/macro/ui-tests/bad-signatures.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/bad-signatures.stderr b/crates/macro/ui-tests/bad-signatures.stderr index 0a8466ab..b36e8947 100644 --- a/crates/macro/ui-tests/bad-signatures.stderr +++ b/crates/macro/ui-tests/bad-signatures.stderr @@ -1,19 +1,19 @@ error: cannot return a borrowed ref with #[wasm_bindgen] - --> $DIR/bad-signatures.rs:8:17 + --> $DIR/bad-signatures.rs:6:17 | -8 | pub fn foo() -> &u32 {} +6 | pub fn foo() -> &u32 {} | ^^^^ error: unsupported pattern in #[wasm_bindgen] imported function - --> $DIR/bad-signatures.rs:12:12 + --> $DIR/bad-signatures.rs:10:12 | -12 | fn foo(Foo(x): Foo); +10 | fn foo(Foo(x): Foo); | ^^^^^^ error: cannot return references in #[wasm_bindgen] imports yet - --> $DIR/bad-signatures.rs:14:17 + --> $DIR/bad-signatures.rs:12:17 | -14 | fn foo() -> &u32; +12 | fn foo() -> &u32; | ^^^^ error: aborting due to 3 previous errors diff --git a/crates/macro/ui-tests/invalid-attr.rs b/crates/macro/ui-tests/invalid-attr.rs index 74c95a97..9496c8a3 100644 --- a/crates/macro/ui-tests/invalid-attr.rs +++ b/crates/macro/ui-tests/invalid-attr.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/invalid-attr.stderr b/crates/macro/ui-tests/invalid-attr.stderr index a35479da..ee918ec5 100644 --- a/crates/macro/ui-tests/invalid-attr.stderr +++ b/crates/macro/ui-tests/invalid-attr.stderr @@ -1,19 +1,19 @@ error: error parsing #[wasm_bindgen] attribute options: failed to parse anything - --> $DIR/invalid-attr.rs:7:16 + --> $DIR/invalid-attr.rs:5:16 | -7 | #[wasm_bindgen(x)] +5 | #[wasm_bindgen(x)] | ^ error: error parsing #[wasm_bindgen] attribute options: failed to parse anything - --> $DIR/invalid-attr.rs:12:20 + --> $DIR/invalid-attr.rs:10:20 | -12 | #[wasm_bindgen(y)] +10 | #[wasm_bindgen(y)] | ^ error: malformed #[wasm_bindgen] attribute - --> $DIR/invalid-attr.rs:15:5 + --> $DIR/invalid-attr.rs:13:5 | -15 | #[wasm_bindgen { }] +13 | #[wasm_bindgen { }] | ^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/crates/macro/ui-tests/invalid-enums.rs b/crates/macro/ui-tests/invalid-enums.rs index 44c983c0..1be6bbd0 100644 --- a/crates/macro/ui-tests/invalid-enums.rs +++ b/crates/macro/ui-tests/invalid-enums.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/invalid-enums.stderr b/crates/macro/ui-tests/invalid-enums.stderr index 06da7570..96b117df 100644 --- a/crates/macro/ui-tests/invalid-enums.stderr +++ b/crates/macro/ui-tests/invalid-enums.stderr @@ -1,25 +1,25 @@ error: only public enums are allowed with #[wasm_bindgen] - --> $DIR/invalid-enums.rs:8:1 + --> $DIR/invalid-enums.rs:6:1 | -8 | enum A {} +6 | enum A {} | ^^^^^^^^^ error: only C-Style enums allowed with #[wasm_bindgen] - --> $DIR/invalid-enums.rs:12:6 + --> $DIR/invalid-enums.rs:10:6 | -12 | D(u32), +10 | D(u32), | ^^^^^ error: enums with #[wasm_bidngen] may only have number literal values - --> $DIR/invalid-enums.rs:17:9 + --> $DIR/invalid-enums.rs:15:9 | -17 | X = 1 + 3, +15 | X = 1 + 3, | ^^^^^ error: enums with #[wasm_bindgen] can only support numbers that can be represented as u32 - --> $DIR/invalid-enums.rs:22:9 + --> $DIR/invalid-enums.rs:20:9 | -22 | X = 4294967296, +20 | X = 4294967296, | ^^^^^^^^^^ error: aborting due to 4 previous errors diff --git a/crates/macro/ui-tests/invalid-imports.rs b/crates/macro/ui-tests/invalid-imports.rs index 9ed8d84a..969afb9e 100644 --- a/crates/macro/ui-tests/invalid-imports.rs +++ b/crates/macro/ui-tests/invalid-imports.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/invalid-imports.stderr b/crates/macro/ui-tests/invalid-imports.stderr index f2574c45..2dd15706 100644 --- a/crates/macro/ui-tests/invalid-imports.stderr +++ b/crates/macro/ui-tests/invalid-imports.stderr @@ -1,91 +1,91 @@ error: it is currently not sound to use lifetimes in function signatures - --> $DIR/invalid-imports.rs:11:16 - | -11 | fn f() -> &'static u32; - | ^^^^^^^ + --> $DIR/invalid-imports.rs:9:16 + | +9 | fn f() -> &'static u32; + | ^^^^^^^ error: imported methods must have at least one argument - --> $DIR/invalid-imports.rs:14:5 + --> $DIR/invalid-imports.rs:12:5 | -14 | fn f1(); +12 | fn f1(); | ^^^^^^^^ error: first argument of method must be a shared reference - --> $DIR/invalid-imports.rs:16:14 + --> $DIR/invalid-imports.rs:14:14 | -16 | fn f2(x: u32); +14 | fn f2(x: u32); | ^^^ error: first argument of method must be a path - --> $DIR/invalid-imports.rs:18:14 + --> $DIR/invalid-imports.rs:16:14 | -18 | fn f3(x: &&u32); +16 | fn f3(x: &&u32); | ^^^^^ error: multi-segment paths are not supported yet - --> $DIR/invalid-imports.rs:20:15 + --> $DIR/invalid-imports.rs:18:15 | -20 | fn f4(x: &foo::Bar); +18 | fn f4(x: &foo::Bar); | ^^^^^^^^ error: global paths are not supported yet + --> $DIR/invalid-imports.rs:20:15 + | +20 | fn f4(x: &::Bar); + | ^^^^^ + +error: paths with type parameters are not supported yet --> $DIR/invalid-imports.rs:22:15 | -22 | fn f4(x: &::Bar); - | ^^^^^ +22 | fn f4(x: &Bar); + | ^^^^^^ error: paths with type parameters are not supported yet --> $DIR/invalid-imports.rs:24:15 | -24 | fn f4(x: &Bar); - | ^^^^^^ - -error: paths with type parameters are not supported yet - --> $DIR/invalid-imports.rs:26:15 - | -26 | fn f4(x: &Fn(T)); +24 | fn f4(x: &Fn(T)); | ^^^^^ error: constructor returns must be bare types - --> $DIR/invalid-imports.rs:29:5 + --> $DIR/invalid-imports.rs:27:5 | -29 | fn f(); +27 | fn f(); | ^^^^^^^ error: global paths are not supported yet - --> $DIR/invalid-imports.rs:31:15 + --> $DIR/invalid-imports.rs:29:15 | -31 | fn f() -> ::Bar; +29 | fn f() -> ::Bar; | ^^^^^ error: return value of constructor must be a bare path - --> $DIR/invalid-imports.rs:33:5 + --> $DIR/invalid-imports.rs:31:5 | -33 | fn f() -> &Bar; +31 | fn f() -> &Bar; | ^^^^^^^^^^^^^^^ +error: must be Result<...> + --> $DIR/invalid-imports.rs:34:15 + | +34 | fn f() -> u32; + | ^^^ + error: must be Result<...> --> $DIR/invalid-imports.rs:36:15 | -36 | fn f() -> u32; - | ^^^ - -error: must be Result<...> - --> $DIR/invalid-imports.rs:38:15 - | -38 | fn f() -> &u32; +36 | fn f() -> &u32; | ^^^^ error: must have at least one generic parameter - --> $DIR/invalid-imports.rs:40:15 + --> $DIR/invalid-imports.rs:38:15 | -40 | fn f() -> Result<>; +38 | fn f() -> Result<>; | ^^^^^^^^ error: it is currently not sound to use lifetimes in function signatures - --> $DIR/invalid-imports.rs:42:22 + --> $DIR/invalid-imports.rs:40:22 | -42 | fn f() -> Result<'a>; +40 | fn f() -> Result<'a>; | ^^ error: aborting due to 15 previous errors diff --git a/crates/macro/ui-tests/invalid-items.rs b/crates/macro/ui-tests/invalid-items.rs index 851800d3..e1efac92 100644 --- a/crates/macro/ui-tests/invalid-items.rs +++ b/crates/macro/ui-tests/invalid-items.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/invalid-items.stderr b/crates/macro/ui-tests/invalid-items.stderr index 6040cf4d..d0fe8f32 100644 --- a/crates/macro/ui-tests/invalid-items.stderr +++ b/crates/macro/ui-tests/invalid-items.stderr @@ -1,67 +1,67 @@ error: can only #[wasm_bindgen] public functions - --> $DIR/invalid-items.rs:8:1 + --> $DIR/invalid-items.rs:6:1 | -8 | fn foo() {} +6 | fn foo() {} | ^^^^^^^^^^^ error: can only #[wasm_bindgen] safe functions - --> $DIR/invalid-items.rs:11:5 - | -11 | pub unsafe fn foo1() {} - | ^^^^^^ + --> $DIR/invalid-items.rs:9:5 + | +9 | pub unsafe fn foo1() {} + | ^^^^^^ error: can only #[wasm_bindgen] non-const functions - --> $DIR/invalid-items.rs:14:5 + --> $DIR/invalid-items.rs:12:5 | -14 | pub const fn foo2() {} +12 | pub const fn foo2() {} | ^^^^^ error: structs with #[wasm_bindgen] cannot have lifetime or type parameters currently - --> $DIR/invalid-items.rs:17:11 + --> $DIR/invalid-items.rs:15:11 | -17 | struct Foo(T); +15 | struct Foo(T); | ^^^ error: cannot import mutable globals yet - --> $DIR/invalid-items.rs:21:12 + --> $DIR/invalid-items.rs:19:12 | -21 | static mut FOO: u32; +19 | static mut FOO: u32; | ^^^ error: can't #[wasm_bindgen] variadic functions - --> $DIR/invalid-items.rs:23:25 + --> $DIR/invalid-items.rs:21:25 | -23 | pub fn foo3(x: i32, ...); +21 | pub fn foo3(x: i32, ...); | ^^^ error: only foreign mods with the `C` ABI are allowed - --> $DIR/invalid-items.rs:27:8 + --> $DIR/invalid-items.rs:25:8 | -27 | extern "system" { +25 | extern "system" { | ^^^^^^^^ +error: can't #[wasm_bindgen] functions with lifetime or type parameters + --> $DIR/invalid-items.rs:29:12 + | +29 | pub fn foo4() {} + | ^^^ + error: can't #[wasm_bindgen] functions with lifetime or type parameters --> $DIR/invalid-items.rs:31:12 | -31 | pub fn foo4() {} - | ^^^ +31 | pub fn foo5<'a>() {} + | ^^^^ error: can't #[wasm_bindgen] functions with lifetime or type parameters --> $DIR/invalid-items.rs:33:12 | -33 | pub fn foo5<'a>() {} - | ^^^^ - -error: can't #[wasm_bindgen] functions with lifetime or type parameters - --> $DIR/invalid-items.rs:35:12 - | -35 | pub fn foo6<'a, T>() {} +33 | pub fn foo6<'a, T>() {} | ^^^^^^^ error: #[wasm_bindgen] can only be applied to a function, struct, enum, impl, or extern block - --> $DIR/invalid-items.rs:38:1 + --> $DIR/invalid-items.rs:36:1 | -38 | trait X {} +36 | trait X {} | ^^^^^^^^^^ error: aborting due to 11 previous errors diff --git a/crates/macro/ui-tests/invalid-methods.rs b/crates/macro/ui-tests/invalid-methods.rs index 9fcf3f4b..ef7fae01 100644 --- a/crates/macro/ui-tests/invalid-methods.rs +++ b/crates/macro/ui-tests/invalid-methods.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/invalid-methods.stderr b/crates/macro/ui-tests/invalid-methods.stderr index 9ac1b887..7e16053e 100644 --- a/crates/macro/ui-tests/invalid-methods.stderr +++ b/crates/macro/ui-tests/invalid-methods.stderr @@ -1,61 +1,61 @@ error: #[wasm_bindgen] default impls are not supported - --> $DIR/invalid-methods.rs:11:1 - | -11 | default impl A { - | ^^^^^^^ + --> $DIR/invalid-methods.rs:9:1 + | +9 | default impl A { + | ^^^^^^^ error: #[wasm_bindgen] unsafe impls are not supported - --> $DIR/invalid-methods.rs:15:1 + --> $DIR/invalid-methods.rs:13:1 | -15 | unsafe impl A { +13 | unsafe impl A { | ^^^^^^ error: #[wasm_bindgen] trait impls are not supported - --> $DIR/invalid-methods.rs:19:6 + --> $DIR/invalid-methods.rs:17:6 | -19 | impl Clone for A { +17 | impl Clone for A { | ^^^^^ error: #[wasm_bindgen] generic impls aren't supported - --> $DIR/invalid-methods.rs:23:5 + --> $DIR/invalid-methods.rs:21:5 | -23 | impl A { +21 | impl A { | ^^^ error: unsupported self type in #[wasm_bindgen] impl - --> $DIR/invalid-methods.rs:27:6 + --> $DIR/invalid-methods.rs:25:6 | -27 | impl &'static A { +25 | impl &'static A { | ^^^^^^^^^^ error: const definitions aren't supported with #[wasm_bindgen] - --> $DIR/invalid-methods.rs:34:5 + --> $DIR/invalid-methods.rs:32:5 | -34 | const X: u32 = 3; +32 | const X: u32 = 3; | ^^^^^^^^^^^^^^^^^ error: type definitions in impls aren't supported with #[wasm_bindgen] - --> $DIR/invalid-methods.rs:35:5 + --> $DIR/invalid-methods.rs:33:5 | -35 | type Y = u32; +33 | type Y = u32; | ^^^^^^^^^^^^^ error: macros in impls aren't supported - --> $DIR/invalid-methods.rs:36:5 + --> $DIR/invalid-methods.rs:34:5 | -36 | x!(); +34 | x!(); | ^^^^^ error: can only #[wasm_bindgen] non-const functions - --> $DIR/invalid-methods.rs:41:9 + --> $DIR/invalid-methods.rs:39:9 | -41 | pub const fn foo() {} +39 | pub const fn foo() {} | ^^^^^ error: can only bindgen safe functions - --> $DIR/invalid-methods.rs:42:9 + --> $DIR/invalid-methods.rs:40:9 | -42 | pub unsafe fn foo() {} +40 | pub unsafe fn foo() {} | ^^^^^^ error: aborting due to 10 previous errors diff --git a/crates/macro/ui-tests/non-public-function.rs b/crates/macro/ui-tests/non-public-function.rs index 8f0b117d..b318ea78 100644 --- a/crates/macro/ui-tests/non-public-function.rs +++ b/crates/macro/ui-tests/non-public-function.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/crates/macro/ui-tests/non-public-function.stderr b/crates/macro/ui-tests/non-public-function.stderr index 510dc537..517ebe7c 100644 --- a/crates/macro/ui-tests/non-public-function.stderr +++ b/crates/macro/ui-tests/non-public-function.stderr @@ -1,7 +1,7 @@ error: can only #[wasm_bindgen] public functions - --> $DIR/non-public-function.rs:8:1 + --> $DIR/non-public-function.rs:6:1 | -8 | fn foo() {} +6 | fn foo() {} | ^^^^^^^^^^^ error: aborting due to previous error diff --git a/crates/test/README.md b/crates/test/README.md index 4ce08be6..ef5bd8e6 100644 --- a/crates/test/README.md +++ b/crates/test/README.md @@ -38,8 +38,6 @@ ton of documentation just yet, but a taste of how it works is: ```rust // in tests/wasm.rs - #![feature(use_extern_macros)] - extern crate wasm_bindgen_test; use wasm_bindgen_test::*; diff --git a/crates/test/sample/src/lib.rs b/crates/test/sample/src/lib.rs index b45cedf8..02b0a2e3 100644 --- a/crates/test/sample/src/lib.rs +++ b/crates/test/sample/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - #[macro_use] extern crate futures; extern crate js_sys; diff --git a/crates/test/sample/tests/browser.rs b/crates/test/sample/tests/browser.rs index 5d5b36f8..0f2bcd4c 100644 --- a/crates/test/sample/tests/browser.rs +++ b/crates/test/sample/tests/browser.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate futures; extern crate sample; extern crate wasm_bindgen; diff --git a/crates/test/sample/tests/node.rs b/crates/test/sample/tests/node.rs index 84d87170..e9cb596c 100644 --- a/crates/test/sample/tests/node.rs +++ b/crates/test/sample/tests/node.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate futures; extern crate sample; extern crate wasm_bindgen; diff --git a/crates/test/src/lib.rs b/crates/test/src/lib.rs index 99326b17..477e743c 100644 --- a/crates/test/src/lib.rs +++ b/crates/test/src/lib.rs @@ -2,7 +2,6 @@ //! //! More documentation can be found in the README for this crate! -#![feature(use_extern_macros)] #![deny(missing_docs)] extern crate console_error_panic_hook; diff --git a/crates/web-sys/tests/wasm/main.rs b/crates/web-sys/tests/wasm/main.rs index 69e4d6f0..2f21cde6 100644 --- a/crates/web-sys/tests/wasm/main.rs +++ b/crates/web-sys/tests/wasm/main.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] #![cfg(target_arch = "wasm32")] extern crate futures; diff --git a/crates/webidl-tests/main.rs b/crates/webidl-tests/main.rs index caedcb7b..9e743218 100644 --- a/crates/webidl-tests/main.rs +++ b/crates/webidl-tests/main.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate js_sys; extern crate wasm_bindgen; extern crate wasm_bindgen_test; diff --git a/examples/add/src/lib.rs b/examples/add/src/lib.rs index 77a63744..d8c7633a 100644 --- a/examples/add/src/lib.rs +++ b/examples/add/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/asm.js/src/lib.rs b/examples/asm.js/src/lib.rs index c6ee4f47..c2689b1b 100644 --- a/examples/asm.js/src/lib.rs +++ b/examples/asm.js/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/canvas/src/lib.rs b/examples/canvas/src/lib.rs index 05a67b19..f13e50ad 100755 --- a/examples/canvas/src/lib.rs +++ b/examples/canvas/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate js_sys; extern crate wasm_bindgen; extern crate web_sys; diff --git a/examples/char/src/lib.rs b/examples/char/src/lib.rs index 5682ae4c..ad7c1021 100644 --- a/examples/char/src/lib.rs +++ b/examples/char/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/closures/src/lib.rs b/examples/closures/src/lib.rs index 8b510f98..3aa0c30e 100755 --- a/examples/closures/src/lib.rs +++ b/examples/closures/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; extern crate js_sys; diff --git a/examples/comments/src/lib.rs b/examples/comments/src/lib.rs index cc416955..cc0a7e12 100644 --- a/examples/comments/src/lib.rs +++ b/examples/comments/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/console_log/src/lib.rs b/examples/console_log/src/lib.rs index cd23275e..7ae64334 100644 --- a/examples/console_log/src/lib.rs +++ b/examples/console_log/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; extern crate web_sys; diff --git a/examples/dom/src/lib.rs b/examples/dom/src/lib.rs index 43d98f76..98c4021e 100644 --- a/examples/dom/src/lib.rs +++ b/examples/dom/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/guide-supported-types-examples/src/lib.rs b/examples/guide-supported-types-examples/src/lib.rs index 9dbfdf48..13984c23 100755 --- a/examples/guide-supported-types-examples/src/lib.rs +++ b/examples/guide-supported-types-examples/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(use_extern_macros)] #![allow(unused_variables, dead_code)] extern crate wasm_bindgen; diff --git a/examples/hello_world/src/lib.rs b/examples/hello_world/src/lib.rs index 41486fa4..3a3634b9 100644 --- a/examples/hello_world/src/lib.rs +++ b/examples/hello_world/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/import_js/src/lib.rs b/examples/import_js/src/lib.rs index 5093db75..aab964d6 100644 --- a/examples/import_js/src/lib.rs +++ b/examples/import_js/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/julia_set/src/lib.rs b/examples/julia_set/src/lib.rs index 2f7a00a9..a92eea48 100644 --- a/examples/julia_set/src/lib.rs +++ b/examples/julia_set/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/math/src/lib.rs b/examples/math/src/lib.rs index 35194922..9f3449c3 100644 --- a/examples/math/src/lib.rs +++ b/examples/math/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/no_modules/src/lib.rs b/examples/no_modules/src/lib.rs index 41486fa4..3a3634b9 100644 --- a/examples/no_modules/src/lib.rs +++ b/examples/no_modules/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/performance/src/lib.rs b/examples/performance/src/lib.rs index 1598ed95..9a50eb6f 100644 --- a/examples/performance/src/lib.rs +++ b/examples/performance/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate humantime; extern crate wasm_bindgen; diff --git a/examples/smorgasboard/src/lib.rs b/examples/smorgasboard/src/lib.rs index 308f3390..a1f1755d 100644 --- a/examples/smorgasboard/src/lib.rs +++ b/examples/smorgasboard/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/wasm-in-wasm/src/lib.rs b/examples/wasm-in-wasm/src/lib.rs index b2539293..2757438c 100644 --- a/examples/wasm-in-wasm/src/lib.rs +++ b/examples/wasm-in-wasm/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/examples/webaudio/src/lib.rs b/examples/webaudio/src/lib.rs index bca2256d..b048c27e 100644 --- a/examples/webaudio/src/lib.rs +++ b/examples/webaudio/src/lib.rs @@ -1,4 +1,4 @@ -#![feature(use_extern_macros, nll)] +#![feature(nll)] extern crate wasm_bindgen; extern crate web_sys; @@ -144,4 +144,4 @@ impl FmOsc { } -} \ No newline at end of file +} diff --git a/guide/src/whirlwind-tour/basic-usage.md b/guide/src/whirlwind-tour/basic-usage.md index 8d8bb820..5a1f9fd8 100644 --- a/guide/src/whirlwind-tour/basic-usage.md +++ b/guide/src/whirlwind-tour/basic-usage.md @@ -39,8 +39,6 @@ wasm-bindgen = "0.2" Next up our actual code! We'll write this in `src/lib.rs`: ```rust,ignore -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/guide/src/whirlwind-tour/what-else-can-we-do.md b/guide/src/whirlwind-tour/what-else-can-we-do.md index 61b65318..80bc19b0 100644 --- a/guide/src/whirlwind-tour/what-else-can-we-do.md +++ b/guide/src/whirlwind-tour/what-else-can-we-do.md @@ -5,8 +5,6 @@ can also [explore this code online](https://webassembly.studio/?f=t61j18noqz): ```rust,ignore // src/lib.rs -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/src/lib.rs b/src/lib.rs index 6d0d33f1..90d6b5a2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,7 +5,7 @@ //! this crate and this crate also provides JS bindings through the `JsValue` //! interface. -#![feature(use_extern_macros, unsize)] +#![feature(unsize)] #![no_std] #![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")] diff --git a/tests/crates/a/src/lib.rs b/tests/crates/a/src/lib.rs index 04dde653..d39f7eee 100644 --- a/tests/crates/a/src/lib.rs +++ b/tests/crates/a/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/tests/crates/b/src/lib.rs b/tests/crates/b/src/lib.rs index 87f781da..c7876ed4 100644 --- a/tests/crates/b/src/lib.rs +++ b/tests/crates/b/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/tests/headless.rs b/tests/headless.rs index 70718911..6cb1449a 100644 --- a/tests/headless.rs +++ b/tests/headless.rs @@ -1,5 +1,4 @@ #![cfg(target_arch = "wasm32")] -#![feature(use_extern_macros)] extern crate wasm_bindgen_test; extern crate wasm_bindgen; diff --git a/tests/no-std/test.rs b/tests/no-std/test.rs index 4dc5c91e..a8e04ac8 100644 --- a/tests/no-std/test.rs +++ b/tests/no-std/test.rs @@ -4,7 +4,6 @@ //! This doesn't actually run any tests, it's mostly a compile-time verification //! that things work. -#![feature(use_extern_macros)] #![no_std] #![allow(dead_code)] diff --git a/tests/non_wasm.rs b/tests/non_wasm.rs index 7a8128f7..947dcf19 100644 --- a/tests/non_wasm.rs +++ b/tests/non_wasm.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; use wasm_bindgen::prelude::*; diff --git a/tests/std-crate-no-std-dep.rs b/tests/std-crate-no-std-dep.rs index 77a9a11e..e2b25037 100644 --- a/tests/std-crate-no-std-dep.rs +++ b/tests/std-crate-no-std-dep.rs @@ -2,7 +2,6 @@ //! `wasm-bindgen` is compiled itself with the `std` feature and everything //! works out just fine. -#![feature(use_extern_macros)] #![no_std] extern crate wasm_bindgen; diff --git a/tests/wasm/main.rs b/tests/wasm/main.rs index 6b783f93..95ceea15 100644 --- a/tests/wasm/main.rs +++ b/tests/wasm/main.rs @@ -1,5 +1,4 @@ #![cfg(target_arch = "wasm32")] -#![feature(use_extern_macros)] extern crate wasm_bindgen_test; extern crate wasm_bindgen; From 305ecb7910d7030d7e25594c8c8b2b0ef3eaf2f9 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 19 Aug 2018 14:42:25 -0700 Subject: [PATCH 20/32] Remove `nll` feature from `webaudio` example --- examples/webaudio/src/lib.rs | 56 ++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 24 deletions(-) diff --git a/examples/webaudio/src/lib.rs b/examples/webaudio/src/lib.rs index b048c27e..704f71e9 100644 --- a/examples/webaudio/src/lib.rs +++ b/examples/webaudio/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(nll)] - extern crate wasm_bindgen; extern crate web_sys; @@ -45,13 +43,20 @@ impl FmOsc { // TODO, how to throw from a constructor? let ctx = web_sys::AudioContext::new().unwrap(); - let base: &BaseAudioContext = ctx.as_ref(); + let primary; + let fm_osc; + let gain; + let fm_gain; - // create our web audio objects - let primary = base.create_oscillator().unwrap(); - let fm_osc = base.create_oscillator().unwrap(); - let gain = base.create_gain().unwrap(); - let fm_gain = base.create_gain().unwrap(); + { + let base: &BaseAudioContext = ctx.as_ref(); + + // create our web audio objects + primary = base.create_oscillator().unwrap(); + fm_osc = base.create_oscillator().unwrap(); + gain = base.create_gain().unwrap(); + fm_gain = base.create_gain().unwrap(); + } // some initial settings: primary.set_type(OscillatorType::Sine); @@ -63,27 +68,30 @@ impl FmOsc { // Create base class references: - let primary_node: &AudioNode = primary.as_ref(); - let gain_node: &AudioNode = gain.as_ref(); - let fm_osc_node: &AudioNode = fm_osc.as_ref(); - let fm_gain_node: &AudioNode = fm_gain.as_ref(); - let destination = base.destination(); - let destination_node: &AudioNode = destination.as_ref(); + { + let primary_node: &AudioNode = primary.as_ref(); + let gain_node: &AudioNode = gain.as_ref(); + let fm_osc_node: &AudioNode = fm_osc.as_ref(); + let fm_gain_node: &AudioNode = fm_gain.as_ref(); + let base: &BaseAudioContext = ctx.as_ref(); + let destination = base.destination(); + let destination_node: &AudioNode = destination.as_ref(); - // connect them up: + // connect them up: - // The primary oscillator is routed through the gain node, so that it can control the overall output volume - primary_node.connect_with_destination_and_output_and_input_using_destination(gain.as_ref()); - // Then connect the gain node to the AudioContext destination (aka your speakers) - gain_node.connect_with_destination_and_output_and_input_using_destination(destination_node); + // The primary oscillator is routed through the gain node, so that it can control the overall output volume + primary_node.connect_with_destination_and_output_and_input_using_destination(gain.as_ref()); + // Then connect the gain node to the AudioContext destination (aka your speakers) + gain_node.connect_with_destination_and_output_and_input_using_destination(destination_node); - // the FM oscillator is connected to its own gain node, so it can control the amount of modulation - fm_osc_node.connect_with_destination_and_output_and_input_using_destination(fm_gain.as_ref()); + // the FM oscillator is connected to its own gain node, so it can control the amount of modulation + fm_osc_node.connect_with_destination_and_output_and_input_using_destination(fm_gain.as_ref()); - // Connect the FM oscillator to the frequency parameter of the main oscillator, so that the - // FM node can modulate its frequency - fm_gain_node.connect_with_destination_and_output_using_destination(&primary.frequency()); + // Connect the FM oscillator to the frequency parameter of the main oscillator, so that the + // FM node can modulate its frequency + fm_gain_node.connect_with_destination_and_output_using_destination(&primary.frequency()); + } // start the oscillators! From 4c1bf937f297af22e0cb64b4fb0cf3278563ea25 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 19 Aug 2018 14:45:59 -0700 Subject: [PATCH 21/32] Move the `unsize` feature behind a `nightly` Cargo feature This should fully stabilize the `wasm-bindgen` crate, preparing us for stable Rust! --- .travis.yml | 1 + Cargo.toml | 1 + examples/closures/Cargo.toml | 2 +- src/closure.rs | 2 ++ src/lib.rs | 2 +- tests/wasm/closures.rs | 2 ++ 6 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bfd64e01..8144c973 100644 --- a/.travis.yml +++ b/.travis.yml @@ -56,6 +56,7 @@ matrix: - cargo test # Run the main body of the test suite - cargo test --target wasm32-unknown-unknown + - cargo test --target wasm32-unknown-unknown --features nightly # Rerun the test suite but disable `--debug` in generated JS - WASM_BINDGEN_NO_DEBUG=1 cargo test --target wasm32-unknown-unknown # Make sure our serde tests work diff --git a/Cargo.toml b/Cargo.toml index 330a4ce3..724964e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ default = ["spans", "std"] spans = ["wasm-bindgen-macro/spans"] std = [] serde-serialize = ["serde", "serde_json", "std"] +nightly = [] # This is only for debugging wasm-bindgen! No stability guarantees, so enable # this at your own peril! diff --git a/examples/closures/Cargo.toml b/examples/closures/Cargo.toml index ce6e6da6..e33f3ac8 100644 --- a/examples/closures/Cargo.toml +++ b/examples/closures/Cargo.toml @@ -7,5 +7,5 @@ authors = ["Alex Crichton "] crate-type = ["cdylib"] [dependencies] -wasm-bindgen = { path = "../.." } +wasm-bindgen = { path = "../..", features = ['nightly'] } js-sys = { path = "../../crates/js-sys" } diff --git a/src/closure.rs b/src/closure.rs index b2afd680..633d35b1 100644 --- a/src/closure.rs +++ b/src/closure.rs @@ -7,6 +7,7 @@ #![allow(const_err)] // FIXME(rust-lang/rust#52603) use std::cell::UnsafeCell; +#[cfg(feature = "nightly")] use std::marker::Unsize; use std::mem::{self, ManuallyDrop}; use std::prelude::v1::*; @@ -90,6 +91,7 @@ impl Closure /// /// This is unfortunately pretty restrictive for now but hopefully some of /// these restrictions can be lifted in the future! + #[cfg(feature = "nightly")] pub fn new(t: F) -> Closure where F: Unsize + 'static { diff --git a/src/lib.rs b/src/lib.rs index 90d6b5a2..7c9ce9f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,9 @@ //! this crate and this crate also provides JS bindings through the `JsValue` //! interface. -#![feature(unsize)] #![no_std] #![doc(html_root_url = "https://docs.rs/wasm-bindgen/0.2")] +#![cfg_attr(feature = "nightly", feature(unsize))] #[cfg(feature = "serde-serialize")] extern crate serde; diff --git a/tests/wasm/closures.rs b/tests/wasm/closures.rs index 84794725..0b896a7e 100644 --- a/tests/wasm/closures.rs +++ b/tests/wasm/closures.rs @@ -1,3 +1,5 @@ +#![cfg(feature = "nightly")] + use wasm_bindgen_test::*; use wasm_bindgen::prelude::*; use std::cell::Cell; From 9d7c0af08f485e793cbf201e44a37a632202c0e9 Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sat, 18 Aug 2018 17:20:42 -0400 Subject: [PATCH 22/32] Initial example for the Fetch API --- Cargo.toml | 1 + examples/fetch/.gitignore | 4 ++ examples/fetch/Cargo.toml | 16 ++++++ examples/fetch/build.bat | 2 + examples/fetch/build.sh | 10 ++++ examples/fetch/index.html | 10 ++++ examples/fetch/index.js | 11 +++++ examples/fetch/package.json | 9 ++++ examples/fetch/src/lib.rs | 85 ++++++++++++++++++++++++++++++++ examples/fetch/webpack.config.js | 10 ++++ 10 files changed, 158 insertions(+) create mode 100644 examples/fetch/.gitignore create mode 100644 examples/fetch/Cargo.toml create mode 100644 examples/fetch/build.bat create mode 100755 examples/fetch/build.sh create mode 100644 examples/fetch/index.html create mode 100644 examples/fetch/index.js create mode 100644 examples/fetch/package.json create mode 100644 examples/fetch/src/lib.rs create mode 100644 examples/fetch/webpack.config.js diff --git a/Cargo.toml b/Cargo.toml index 330a4ce3..3ff677f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ members = [ "examples/comments", "examples/console_log", "examples/dom", + "examples/fetch", "examples/guide-supported-types-examples", "examples/hello_world", "examples/import_js", diff --git a/examples/fetch/.gitignore b/examples/fetch/.gitignore new file mode 100644 index 00000000..cf66a572 --- /dev/null +++ b/examples/fetch/.gitignore @@ -0,0 +1,4 @@ +fetch.d.ts +fetch.js +fetch_bg.wasm +package-lock.json diff --git a/examples/fetch/Cargo.toml b/examples/fetch/Cargo.toml new file mode 100644 index 00000000..ef6df418 --- /dev/null +++ b/examples/fetch/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "fetch" +version = "0.1.0" +authors = ["Andrew Chin "] + +[lib] +crate-type = ["cdylib"] + +[dependencies] +futures = "0.1.20" +wasm-bindgen = { path = "../..", features = ["serde-serialize"] } +js-sys = { path = "../../crates/js-sys" } +web-sys = { path = "../../crates/web-sys" } +wasm-bindgen-futures = { path = "../../crates/futures" } +serde = "^1.0.59" +serde_derive = "^1.0.59" \ No newline at end of file diff --git a/examples/fetch/build.bat b/examples/fetch/build.bat new file mode 100644 index 00000000..590cd403 --- /dev/null +++ b/examples/fetch/build.bat @@ -0,0 +1,2 @@ +cargo +nightly build --target wasm32-unknown-unknown +cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml --bin wasm-bindgen -- ../../target/wasm32-unknown-unknown/debug/fetch.wasm --out-dir . diff --git a/examples/fetch/build.sh b/examples/fetch/build.sh new file mode 100755 index 00000000..585f428c --- /dev/null +++ b/examples/fetch/build.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +# For more coments about what's going on here, see the `hello_world` example + +set -ex + +cargo +nightly build --target wasm32-unknown-unknown +cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \ + --bin wasm-bindgen -- \ + ../../target/wasm32-unknown-unknown/debug/fetch.wasm --out-dir . diff --git a/examples/fetch/index.html b/examples/fetch/index.html new file mode 100644 index 00000000..3556e137 --- /dev/null +++ b/examples/fetch/index.html @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/examples/fetch/index.js b/examples/fetch/index.js new file mode 100644 index 00000000..5cea1ca2 --- /dev/null +++ b/examples/fetch/index.js @@ -0,0 +1,11 @@ +const rust = import('./fetch'); + + +rust.then(m => { + m.run().then((data) => { + console.log(data); + + console.log("The latest commit to the wasm-bindgen %s branch is:", data.name); + console.log("%s, authored by %s <%s>", data.commit.sha, data.commit.commit.author.name, data.commit.commit.author.email); + }) +}); diff --git a/examples/fetch/package.json b/examples/fetch/package.json new file mode 100644 index 00000000..07da0131 --- /dev/null +++ b/examples/fetch/package.json @@ -0,0 +1,9 @@ +{ + "scripts": { + "serve": "webpack-serve ./webpack.config.js" + }, + "devDependencies": { + "webpack": "^4.16.5", + "webpack-serve": "^2.0.2" + } +} diff --git a/examples/fetch/src/lib.rs b/examples/fetch/src/lib.rs new file mode 100644 index 00000000..8bf494ac --- /dev/null +++ b/examples/fetch/src/lib.rs @@ -0,0 +1,85 @@ +#![feature(use_extern_macros)] + +extern crate wasm_bindgen; +extern crate js_sys; +extern crate web_sys; +extern crate wasm_bindgen_futures; +extern crate futures; +#[macro_use] +extern crate serde_derive; + +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsCast; +use js_sys::Promise; +use web_sys::{Request, RequestInit, RequestMode, Response, Window}; +use wasm_bindgen_futures::JsFuture; +use futures::{future, Future}; +use wasm_bindgen_futures::future_to_promise; + +// A struct to hold some data from the github Branch API. +// Note how we don't have to define every member -- serde will ignore extra data when deserializing +#[derive(Debug, Serialize, Deserialize)] +pub struct Branch { + pub name: String, + pub commit: Commit, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Commit { + pub sha: String, + pub commit: CommitDetails, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CommitDetails { + pub author: Signature, + pub committer: Signature, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct Signature { + pub name: String, + pub email: String, +} + +#[wasm_bindgen] +extern "C" { + static window: Window; +} + +#[wasm_bindgen] +pub fn run() -> Promise { + let mut request_options = RequestInit::new(); + request_options.method("GET"); + request_options.mode(RequestMode::Cors); + + let req = Request::new_using_usv_str_and_request_init("https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", &request_options).unwrap(); + + // the RequestInit struct will eventually support setting headers, but that's missing right now + req.headers().set("Accept", "application/vnd.github.v3+json").unwrap(); + + let req_promise = window.fetch_using_request(&req); + + let to_return = JsFuture::from(req_promise).and_then(|resp_value| { + // resp_value is a Response object + assert!(resp_value.is_instance_of::()); + let resp: Response = resp_value.dyn_into().unwrap(); + + resp.json() + + + }).and_then(|json_value: Promise| { + // convert this other promise into a rust Future + JsFuture::from(json_value) + }).and_then(|json| { + // Use serde to parse this into a struct + let branch_info: Branch = json.into_serde().unwrap(); + + // Send the Branch struct back to javascript as an object + future::ok(JsValue::from_serde(&branch_info).unwrap()) + }); + + // Convert this rust future back into a javascript promise. + // Return it to javascript so that it can be driven to completion. + future_to_promise(to_return) +} diff --git a/examples/fetch/webpack.config.js b/examples/fetch/webpack.config.js new file mode 100644 index 00000000..dce27149 --- /dev/null +++ b/examples/fetch/webpack.config.js @@ -0,0 +1,10 @@ +const path = require('path'); + +module.exports = { + entry: './index.js', + output: { + path: path.resolve(__dirname, 'dist'), + filename: 'index.js', + }, + mode: 'development' +}; From 2c72eabea1d4046e9817457d4fddaae016fa717f Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 19 Aug 2018 10:59:14 -0400 Subject: [PATCH 23/32] Make the list of examples alphabetical, and add webaudio and fetch examples --- examples/README.md | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/examples/README.md b/examples/README.md index b58d29bc..05084ced 100644 --- a/examples/README.md +++ b/examples/README.md @@ -10,31 +10,33 @@ when using `build.sh`! The examples here are: -* `hello_world` - the "hello world" of `#[wasm_bindgen]`, aka throwing up a - dialog greeting you -* `console_log` - a showcase of `#[wasm_bindgen]` importing classes and how to - bind `console.log` -* `math` - like `console_log` except showing how to import Math-related - functions instead -* `dom` - an example of accessing the global `document` object and appending - HTML to it -* `smorgasboard` - a bunch of features all thrown into one, showing off the - various capabilities of the `#[wasm_bindgen]` macro and what you can do with - it from JS -* `performance` - how to import APIs like `performance.now()` and time various - operations in Rust -* `wasm-in-wasm` - how to interact with namespaced APIs like - `WebAssembly.Module` and shows off creation of a WebAssembly module from Rust -* `closures` - an example of how to invoke functions like `setInterval` or use - the `onclick` property in conjunction with closures. -* `no_modules` - an example of how to use the `--no-modules` flag to - the `wasm-bindgen` CLI tool * `add` - an example of generating a tiny wasm binary, one that only adds two numbers. * `asm.js` - an example of using the `wasm2asm` tool from [binaryen] to convert the generated WebAssembly to normal JS * `char` - an example of passing the rust `char` type to and from the js `string` type -* `import_js` - an example of importing local JS functionality into a crate +* `closures` - an example of how to invoke functions like `setInterval` or use + the `onclick` property in conjunction with closures. * `comments` - an example of how Rust comments are copied into js bindings +* `console_log` - a showcase of `#[wasm_bindgen]` importing classes and how to + bind `console.log` +* `dom` - an example of accessing the global `document` object and appending + HTML to it +* `fetch` -- how to use the Fetch API to make async http requests +* `hello_world` - the "hello world" of `#[wasm_bindgen]`, aka throwing up a + dialog greeting you +* `import_js` - an example of importing local JS functionality into a crate +* `math` - like `console_log` except showing how to import Math-related + functions instead +* `no_modules` - an example of how to use the `--no-modules` flag to + the `wasm-bindgen` CLI tool +* `performance` - how to import APIs like `performance.now()` and time various + operations in Rust +* `smorgasboard` - a bunch of features all thrown into one, showing off the + various capabilities of the `#[wasm_bindgen]` macro and what you can do with + it from JS +* `wasm-in-wasm` - how to interact with namespaced APIs like + `WebAssembly.Module` and shows off creation of a WebAssembly module from Rust +* `webaudio` - how to use the Web Audio APIs to generate sounds [binaryen]: https://github.com/WebAssembly/binaryen From a9a1e69f30314c605de7fd511498c31c44e77424 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Aug 2018 10:42:12 +0200 Subject: [PATCH 24/32] feat(js-sys) Implement `String.split` with regexp. --- crates/js-sys/src/lib.rs | 8 ++++++++ crates/js-sys/tests/wasm/JsString.rs | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 48e7cd30..34484add 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3113,6 +3113,14 @@ extern "C" { #[wasm_bindgen(method, js_class = "String", js_name = split)] pub fn split_limit(this: &JsString, separator: &str, limit: u32) -> Array; + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split + #[wasm_bindgen(method, js_class = "String", js_name = split)] + pub fn split_by_pattern(this: &JsString, pattern: &RegExp) -> Array; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split + #[wasm_bindgen(method, js_class = "String", js_name = split)] + pub fn split_by_pattern_limit(this: &JsString, pattern: &RegExp, limit: u32) -> Array; + /// The `startsWith()` method determines whether a string begins with the /// characters of a specified string, returning true or false as /// appropriate. diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 5458e3e7..33040966 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -352,6 +352,27 @@ fn split() { assert_eq!(result.length(), 2); assert_eq!(v[0], "Oct"); assert_eq!(v[1], "Nov"); + + let js = JsString::from("Oh brave new world"); + let re = RegExp::new("\\s", "g"); + let result = js.split_by_pattern(&re); + + let mut v = Vec::with_capacity(result.length() as usize); + result.for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(v[0], "Oh"); + assert_eq!(v[1], "brave"); + assert_eq!(v[2], "new"); + assert_eq!(v[3], "world"); + + let result = js.split_by_pattern_limit(&re, 2); + + let mut v = Vec::with_capacity(result.length() as usize); + result.for_each(&mut |x, _, _| v.push(x)); + + assert_eq!(result.length(), 2); + assert_eq!(v[0], "Oh"); + assert_eq!(v[1], "brave"); } #[wasm_bindgen_test] From 1e27b588e2ef52abec9a3e0763d2b84326986fa7 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 20 Aug 2018 11:01:56 +0200 Subject: [PATCH 25/32] =?UTF-8?q?feat(js-sys)=20Implement=20`String.replac?= =?UTF-8?q?e(&str,=20=E2=80=A6)`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/js-sys/src/lib.rs | 11 +++++++++-- crates/js-sys/tests/wasm/JsString.rs | 14 ++++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/crates/js-sys/src/lib.rs b/crates/js-sys/src/lib.rs index 48e7cd30..37bd4a55 100644 --- a/crates/js-sys/src/lib.rs +++ b/crates/js-sys/src/lib.rs @@ -3082,11 +3082,18 @@ extern "C" { /// /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace #[wasm_bindgen(method, js_class = "String")] - pub fn replace(this: &JsString, pattern: &RegExp, replacement: &str) -> JsString; + pub fn replace(this: &JsString, pattern: &str, replacement: &str) -> JsString; /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace #[wasm_bindgen(method, js_class = "String", js_name = replace)] - pub fn replace_function(this: &JsString, pattern: &RegExp, replacement: &Function) -> JsString; + pub fn replace_with_function(this: &JsString, pattern: &str, replacement: &Function) -> JsString; + + #[wasm_bindgen(method, js_class = "String", js_name = replace)] + pub fn replace_by_pattern(this: &JsString, pattern: &RegExp, replacement: &str) -> JsString; + + /// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace + #[wasm_bindgen(method, js_class = "String", js_name = replace)] + pub fn replace_by_pattern_with_function(this: &JsString, pattern: &RegExp, replacement: &Function) -> JsString; /// The search() method executes a search for a match between /// a regular expression and this String object. diff --git a/crates/js-sys/tests/wasm/JsString.rs b/crates/js-sys/tests/wasm/JsString.rs index 5458e3e7..30ab4771 100644 --- a/crates/js-sys/tests/wasm/JsString.rs +++ b/crates/js-sys/tests/wasm/JsString.rs @@ -287,15 +287,25 @@ fn repeat() { #[wasm_bindgen_test] fn replace() { + let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); + let result = js.replace("dog", "ferret"); + + assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the dog reacted, was it really lazy?"); + + let js = JsString::from("borderTop"); + let result = js.replace_with_function("T", &get_replacer_function()); + + assert_eq!(result, "border-top"); + let js = JsString::from("The quick brown fox jumped over the lazy dog. If the dog reacted, was it really lazy?"); let re = RegExp::new("dog", "g"); - let result = js.replace(&re, "ferret"); + let result = js.replace_by_pattern(&re, "ferret"); assert_eq!(result, "The quick brown fox jumped over the lazy ferret. If the ferret reacted, was it really lazy?"); let js = JsString::from("borderTop"); let re = RegExp::new("[A-Z]", "g"); - let result = js.replace_function(&re, &get_replacer_function()); + let result = js.replace_by_pattern_with_function(&re, &get_replacer_function()); assert_eq!(result, "border-top"); } From e4093eb178a07d6460bf4114ca098ca6601ac7af Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Mon, 20 Aug 2018 13:19:00 -0400 Subject: [PATCH 26/32] No more use_extern_macros feature! --- examples/fetch/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/fetch/src/lib.rs b/examples/fetch/src/lib.rs index 8bf494ac..1964917d 100644 --- a/examples/fetch/src/lib.rs +++ b/examples/fetch/src/lib.rs @@ -1,5 +1,3 @@ -#![feature(use_extern_macros)] - extern crate wasm_bindgen; extern crate js_sys; extern crate web_sys; From 92b7de3d3d8ef39c8805bbf4ac266f4d193a58c5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 16 Aug 2018 23:13:34 -0700 Subject: [PATCH 27/32] Skip args in overloaded method names if all same This commit updates how we name overloaded methods. Previously all argument names were concatenated, but after this commit it only concatenates argument names where at least one possibility has a different type. Otherwise if all possibilities have the same type name it in theory isn't adding too much more information! Additionally this commit also switches to using `_with_` consistently everywhere instead of `_with_` for constructors and `_using_` for methods. Closes #712 --- crates/web-sys/tests/wasm/console.rs | 4 ++-- crates/web-sys/tests/wasm/dom_point.rs | 4 ++-- crates/web-sys/tests/wasm/option_element.rs | 2 +- crates/web-sys/tests/wasm/table_element.rs | 2 +- crates/webidl-tests/simple.rs | 18 +++++++++--------- crates/webidl/src/util.rs | 8 ++++++-- examples/canvas/src/lib.rs | 18 +++++++++--------- examples/webaudio/src/lib.rs | 12 ++++++------ 8 files changed, 36 insertions(+), 32 deletions(-) diff --git a/crates/web-sys/tests/wasm/console.rs b/crates/web-sys/tests/wasm/console.rs index c2289293..b8363856 100644 --- a/crates/web-sys/tests/wasm/console.rs +++ b/crates/web-sys/tests/wasm/console.rs @@ -3,6 +3,6 @@ use web_sys::console; #[wasm_bindgen_test] fn test_console() { - console::time_using_label("test label"); - console::time_end_using_label("test label"); + console::time_with_label("test label"); + console::time_end_with_label("test label"); } diff --git a/crates/web-sys/tests/wasm/dom_point.rs b/crates/web-sys/tests/wasm/dom_point.rs index f1e87f3d..4ed22c37 100644 --- a/crates/web-sys/tests/wasm/dom_point.rs +++ b/crates/web-sys/tests/wasm/dom_point.rs @@ -4,7 +4,7 @@ use web_sys::{DomPoint, DomPointReadOnly}; #[wasm_bindgen_test] fn dom_point() { - let x = DomPoint::new_using_x_and_y_and_z_and_w(1.0, 2.0, 3.0, 4.0).unwrap(); + let x = DomPoint::new_with_x_and_y_and_z_and_w(1.0, 2.0, 3.0, 4.0).unwrap(); assert_eq!(x.x(), 1.0); x.set_x(1.5); assert_eq!(x.x(), 1.5); @@ -24,7 +24,7 @@ fn dom_point() { #[wasm_bindgen_test] fn dom_point_readonly() { - let x = DomPoint::new_using_x_and_y_and_z_and_w(1.0, 2.0, 3.0, 4.0).unwrap(); + let x = DomPoint::new_with_x_and_y_and_z_and_w(1.0, 2.0, 3.0, 4.0).unwrap(); let x = DomPointReadOnly::from(JsValue::from(x)); assert_eq!(x.x(), 1.0); assert_eq!(x.y(), 2.0); diff --git a/crates/web-sys/tests/wasm/option_element.rs b/crates/web-sys/tests/wasm/option_element.rs index e2e074e7..1cb2d262 100644 --- a/crates/web-sys/tests/wasm/option_element.rs +++ b/crates/web-sys/tests/wasm/option_element.rs @@ -3,7 +3,7 @@ use web_sys::HtmlOptionElement; #[wasm_bindgen_test] fn test_option_element() { - let option = HtmlOptionElement::new_using_text_and_value_and_default_selected_and_selected( + let option = HtmlOptionElement::new_with_text_and_value_and_default_selected_and_selected( "option_text", "option_value", false, diff --git a/crates/web-sys/tests/wasm/table_element.rs b/crates/web-sys/tests/wasm/table_element.rs index c83ae53e..0ed436cd 100644 --- a/crates/web-sys/tests/wasm/table_element.rs +++ b/crates/web-sys/tests/wasm/table_element.rs @@ -99,7 +99,7 @@ fn test_table_element() { ); table - .insert_row_using_index(0) + .insert_row_with_index(0) .expect("Failed to insert row at index 0"); assert!( table.rows().length() == 1, diff --git a/crates/webidl-tests/simple.rs b/crates/webidl-tests/simple.rs index b06d9dd4..f179894d 100644 --- a/crates/webidl-tests/simple.rs +++ b/crates/webidl-tests/simple.rs @@ -50,7 +50,7 @@ fn static_property() { } #[wasm_bindgen_test] -fn one_method_using_an_undefined_import_doesnt_break_all_other_methods() { +fn one_method_with_an_undefined_import_doesnt_break_all_other_methods() { let f = UndefinedMethod::new().unwrap(); assert!(f.ok_method()); } @@ -81,14 +81,14 @@ fn indexing() { #[wasm_bindgen_test] fn optional_and_union_arguments() { let f = OptionalAndUnionArguments::new().unwrap(); - assert_eq!(f.m_using_a("abc"), "string, abc, boolean, true, number, 123, number, 456"); - assert_eq!(f.m_using_a_and_b("abc", false), "string, abc, boolean, false, number, 123, number, 456"); - assert_eq!(f.m_using_dom_str_and_bool_and_i16("abc", false, 5), "string, abc, boolean, false, number, 5, number, 456"); - assert_eq!(f.m_using_dom_str_and_bool_and_dom_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456"); - assert_eq!(f.m_using_dom_str_and_bool_and_i16_and_opt_i64("abc", false, 5, Some(10)), "string, abc, boolean, false, number, 5, bigint, 10"); - assert_eq!(f.m_using_dom_str_and_bool_and_i16_and_opt_bool("abc", false, 5, Some(true)), "string, abc, boolean, false, number, 5, boolean, true"); - assert_eq!(f.m_using_dom_str_and_bool_and_dom_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10"); - assert_eq!(f.m_using_dom_str_and_bool_and_dom_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true"); + assert_eq!(f.m("abc"), "string, abc, boolean, true, number, 123, number, 456"); + assert_eq!(f.m_with_b("abc", false), "string, abc, boolean, false, number, 123, number, 456"); + assert_eq!(f.m_with_bool_and_i16("abc", false, 5), "string, abc, boolean, false, number, 5, number, 456"); + assert_eq!(f.m_with_bool_and_dom_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456"); + assert_eq!(f.m_with_bool_and_i16_and_opt_i64("abc", false, 5, Some(10)), "string, abc, boolean, false, number, 5, bigint, 10"); + assert_eq!(f.m_with_bool_and_i16_and_opt_bool("abc", false, 5, Some(true)), "string, abc, boolean, false, number, 5, boolean, true"); + assert_eq!(f.m_with_bool_and_dom_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10"); + assert_eq!(f.m_with_bool_and_dom_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true"); } #[wasm_bindgen_test] diff --git a/crates/webidl/src/util.rs b/crates/webidl/src/util.rs index aa80f93c..2276064d 100644 --- a/crates/webidl/src/util.rs +++ b/crates/webidl/src/util.rs @@ -273,9 +273,13 @@ impl<'src> FirstPassRecord<'src> { let rust_name = if possibilities.len() > 1 { let mut rust_name = rust_name.clone(); let mut first = true; - for ((argument_name, _, _), idl_type) in arguments.iter().zip(idl_types) { + let iter = arguments.iter().zip(idl_types).enumerate(); + for (i, ((argument_name, _, _), idl_type)) in iter { + if possibilities.iter().all(|p| p.get(i) == Some(idl_type)) { + continue + } if first { - rust_name.push_str("_using_"); + rust_name.push_str("_with_"); first = false; } else { rust_name.push_str("_and_"); diff --git a/examples/canvas/src/lib.rs b/examples/canvas/src/lib.rs index f13e50ad..722a10a9 100755 --- a/examples/canvas/src/lib.rs +++ b/examples/canvas/src/lib.rs @@ -20,7 +20,7 @@ pub fn draw() { .unwrap(); let context = canvas - .get_context_using_context_id("2d") + .get_context("2d") .unwrap() .unwrap() .dyn_into::() @@ -29,43 +29,43 @@ pub fn draw() { context.begin_path(); // Draw the outer circle. - context.arc_using_x_and_y_and_radius_and_start_angle_and_end_angle( + context.arc( 75.0, 75.0, 50.0, 0.0, f64::consts::PI * 2.0, - ); + ).unwrap(); // Draw the mouth. context.move_to(110.0, 75.0); - context.arc_using_x_and_y_and_radius_and_start_angle_and_end_angle( + context.arc( 75.0, 75.0, 35.0, 0.0, f64::consts::PI, - ); + ).unwrap(); // Draw the left eye. context.move_to(65.0, 65.0); - context.arc_using_x_and_y_and_radius_and_start_angle_and_end_angle( + context.arc( 60.0, 65.0, 5.0, 0.0, f64::consts::PI * 2.0, - ); + ).unwrap(); // Draw the right eye. context.move_to(95.0, 65.0); - context.arc_using_x_and_y_and_radius_and_start_angle_and_end_angle( + context.arc( 90.0, 65.0, 5.0, 0.0, f64::consts::PI * 2.0, - ); + ).unwrap(); context.stroke(); } diff --git a/examples/webaudio/src/lib.rs b/examples/webaudio/src/lib.rs index 704f71e9..3c86179c 100644 --- a/examples/webaudio/src/lib.rs +++ b/examples/webaudio/src/lib.rs @@ -81,22 +81,22 @@ impl FmOsc { // connect them up: // The primary oscillator is routed through the gain node, so that it can control the overall output volume - primary_node.connect_with_destination_and_output_and_input_using_destination(gain.as_ref()); + primary_node.connect_with_destination_and_output_and_input(gain.as_ref()).unwrap(); // Then connect the gain node to the AudioContext destination (aka your speakers) - gain_node.connect_with_destination_and_output_and_input_using_destination(destination_node); + gain_node.connect_with_destination_and_output_and_input(destination_node).unwrap(); // the FM oscillator is connected to its own gain node, so it can control the amount of modulation - fm_osc_node.connect_with_destination_and_output_and_input_using_destination(fm_gain.as_ref()); + fm_osc_node.connect_with_destination_and_output_and_input(fm_gain.as_ref()).unwrap(); // Connect the FM oscillator to the frequency parameter of the main oscillator, so that the // FM node can modulate its frequency - fm_gain_node.connect_with_destination_and_output_using_destination(&primary.frequency()); + fm_gain_node.connect_with_destination_and_output(&primary.frequency()).unwrap(); } // start the oscillators! - AsRef::::as_ref(&primary).start(); - AsRef::::as_ref(&fm_osc).start(); + AsRef::::as_ref(&primary).start().unwrap(); + AsRef::::as_ref(&fm_osc).start().unwrap(); FmOsc { ctx, From ddc42738cff1a5298059c7bc53201de4121c0d28 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 19 Aug 2018 10:24:23 -0700 Subject: [PATCH 28/32] Tweak some WebIDL type names in methods Instead of `dom_str`, `byte_str`, and `usv_str`, emit `str` for all of them. Similarly for `unrestricted_f64` just do `f64` instead. This reflects how we interpret the types already in terms of Rust types and although technically makes it possible to have name collisions in WebIDL they don't come up in practice. --- crates/webidl-tests/simple.rs | 6 +++--- crates/webidl/src/idl_type.rs | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/webidl-tests/simple.rs b/crates/webidl-tests/simple.rs index f179894d..edec1965 100644 --- a/crates/webidl-tests/simple.rs +++ b/crates/webidl-tests/simple.rs @@ -84,11 +84,11 @@ fn optional_and_union_arguments() { assert_eq!(f.m("abc"), "string, abc, boolean, true, number, 123, number, 456"); assert_eq!(f.m_with_b("abc", false), "string, abc, boolean, false, number, 123, number, 456"); assert_eq!(f.m_with_bool_and_i16("abc", false, 5), "string, abc, boolean, false, number, 5, number, 456"); - assert_eq!(f.m_with_bool_and_dom_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456"); + assert_eq!(f.m_with_bool_and_str("abc", false, "5"), "string, abc, boolean, false, string, 5, number, 456"); assert_eq!(f.m_with_bool_and_i16_and_opt_i64("abc", false, 5, Some(10)), "string, abc, boolean, false, number, 5, bigint, 10"); assert_eq!(f.m_with_bool_and_i16_and_opt_bool("abc", false, 5, Some(true)), "string, abc, boolean, false, number, 5, boolean, true"); - assert_eq!(f.m_with_bool_and_dom_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10"); - assert_eq!(f.m_with_bool_and_dom_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true"); + assert_eq!(f.m_with_bool_and_str_and_opt_i64("abc", false, "5", Some(10)), "string, abc, boolean, false, string, 5, bigint, 10"); + assert_eq!(f.m_with_bool_and_str_and_opt_bool("abc", false, "5", Some(true)), "string, abc, boolean, false, string, 5, boolean, true"); } #[wasm_bindgen_test] diff --git a/crates/webidl/src/idl_type.rs b/crates/webidl/src/idl_type.rs index c1dfa8b0..c5504fdf 100644 --- a/crates/webidl/src/idl_type.rs +++ b/crates/webidl/src/idl_type.rs @@ -348,13 +348,13 @@ impl<'a> IdlType<'a> { IdlType::UnsignedLong => dst.push_str("u32"), IdlType::LongLong => dst.push_str("i64"), IdlType::UnsignedLongLong => dst.push_str("u64"), - IdlType::Float => dst.push_str("f32"), - IdlType::UnrestrictedFloat => dst.push_str("unrestricted_f32"), - IdlType::Double => dst.push_str("f64"), - IdlType::UnrestrictedDouble => dst.push_str("unrestricted_f64"), - IdlType::DomString => dst.push_str("dom_str"), - IdlType::ByteString => dst.push_str("byte_str"), - IdlType::UsvString => dst.push_str("usv_str"), + IdlType::Float | + IdlType::UnrestrictedFloat => dst.push_str("f32"), + IdlType::Double | + IdlType::UnrestrictedDouble => dst.push_str("f64"), + IdlType::DomString | + IdlType::ByteString | + IdlType::UsvString => dst.push_str("str"), IdlType::Object => dst.push_str("object"), IdlType::Symbol => dst.push_str("symbol"), IdlType::Error => dst.push_str("error"), From 4195af68e774473ef1097d3229868d2e8de31582 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 20 Aug 2018 10:40:54 -0700 Subject: [PATCH 29/32] Fix the `constructor` and `catch` attributes combined This commit fixes annotations that include both the `constructor` and `catch` attributes on imported types, ensuring that we infer the right type being returned after extracting the first type parameter of the `Result`. Closes #735 --- crates/macro-support/src/parser.rs | 2 +- tests/wasm/import_class.js | 8 ++++++++ tests/wasm/import_class.rs | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index 18b198a6..a3de4d17 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -486,7 +486,7 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option)> for syn::ForeignItemFn ast::ImportFunctionKind::Method { class, ty, kind } } else if opts.constructor() { - let class = match wasm.ret { + let class = match js_ret { Some(ref ty) => ty, _ => bail_span!(self, "constructor returns must be bare types"), }; diff --git a/tests/wasm/import_class.js b/tests/wasm/import_class.js index 6154d9ce..fa60847c 100644 --- a/tests/wasm/import_class.js +++ b/tests/wasm/import_class.js @@ -123,3 +123,11 @@ exports.run_rust_option_tests = function() { assert.strictEqual(wasm.rust_return_none(), undefined); assert.strictEqual(wasm.rust_return_some() === undefined, false); }; + +exports.CatchConstructors = class { + constructor(x) { + if (x == 0) { + throw new Error('bad!'); + } + } +}; diff --git a/tests/wasm/import_class.rs b/tests/wasm/import_class.rs index 06083ea2..64c97d14 100644 --- a/tests/wasm/import_class.rs +++ b/tests/wasm/import_class.rs @@ -76,6 +76,10 @@ extern { fn return_undefined() -> Option; fn return_some() -> Option; fn run_rust_option_tests(); + + type CatchConstructors; + #[wasm_bindgen(constructor, catch)] + fn new(x: u32) -> Result; } #[wasm_bindgen] @@ -199,3 +203,9 @@ pub fn rust_return_none() -> Option { pub fn rust_return_some() -> Option { Some(Options::new()) } + +#[wasm_bindgen_test] +fn catch_constructors() { + assert!(CatchConstructors::new(0).is_err()); + assert!(CatchConstructors::new(1).is_ok()); +} From f8cf4ab7329fd77b561e32208a76591981b98bf5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 20 Aug 2018 10:52:54 -0700 Subject: [PATCH 30/32] Support importing same-name statics from two modules Closes #714 --- crates/macro-support/src/parser.rs | 15 +++++++-------- tests/wasm/duplicates.rs | 8 ++++++++ tests/wasm/duplicates_a.js | 1 + tests/wasm/duplicates_b.js | 1 + tests/wasm/duplicates_c.js | 1 + 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index 18b198a6..6f1bdba2 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -560,10 +560,12 @@ impl ConvertToAst for syn::ForeignItemType { } } -impl ConvertToAst for syn::ForeignItemStatic { +impl<'a> ConvertToAst<(BindgenAttrs, &'a Option)> for syn::ForeignItemStatic { type Target = ast::ImportKind; - fn convert(self, opts: BindgenAttrs) -> Result { + fn convert(self, (opts, module): (BindgenAttrs, &'a Option)) + -> Result + { if self.mutability.is_some() { bail_span!(self.mutability, "cannot import mutable globals yet") } @@ -571,11 +573,8 @@ impl ConvertToAst for syn::ForeignItemStatic { let js_name = opts.js_name().unwrap_or(&default_name); let shim = format!( "__wbg_static_accessor_{}_{}", - js_name - .chars() - .filter(|c| c.is_ascii_alphanumeric()) - .collect::(), - self.ident + self.ident, + ShortHash((&js_name, module, &self.ident)), ); Ok(ast::ImportKind::Static(ast::ImportStatic { ty: *self.ty, @@ -973,7 +972,7 @@ impl<'a> MacroParse<&'a BindgenAttrs> for syn::ForeignItem { let kind = match self { syn::ForeignItem::Fn(f) => f.convert((item_opts, &module))?, syn::ForeignItem::Type(t) => t.convert(item_opts)?, - syn::ForeignItem::Static(s) => s.convert(item_opts)?, + syn::ForeignItem::Static(s) => s.convert((item_opts, &module))?, _ => panic!("only foreign functions/types allowed for now"), }; diff --git a/tests/wasm/duplicates.rs b/tests/wasm/duplicates.rs index f35e6d37..60b17c82 100644 --- a/tests/wasm/duplicates.rs +++ b/tests/wasm/duplicates.rs @@ -6,6 +6,7 @@ pub mod same_function_different_locations_a { #[wasm_bindgen(module = "tests/wasm/duplicates_a.js")] extern { pub fn foo(); + pub static bar: JsValue; } } @@ -15,6 +16,7 @@ pub mod same_function_different_locations_b { #[wasm_bindgen(module = "tests/wasm/duplicates_a.js")] extern { pub fn foo(); + pub static bar: JsValue; } } @@ -22,6 +24,8 @@ pub mod same_function_different_locations_b { fn same_function_different_locations() { same_function_different_locations_a::foo(); same_function_different_locations_b::foo(); + assert_eq!(*same_function_different_locations_a::bar, 3); + assert_eq!(*same_function_different_locations_a::bar, 3); } pub mod same_function_different_modules_a { @@ -30,6 +34,7 @@ pub mod same_function_different_modules_a { #[wasm_bindgen(module = "tests/wasm/duplicates_b.js")] extern { pub fn foo() -> bool; + pub static bar: JsValue; } } @@ -39,6 +44,7 @@ pub mod same_function_different_modules_b { #[wasm_bindgen(module = "tests/wasm/duplicates_c.js")] extern { pub fn foo() -> bool; + pub static bar: JsValue; } } @@ -46,4 +52,6 @@ pub mod same_function_different_modules_b { fn same_function_different_modules() { assert!(same_function_different_modules_a::foo()); assert!(!same_function_different_modules_b::foo()); + assert_eq!(*same_function_different_modules_a::bar, 4); + assert_eq!(*same_function_different_modules_b::bar, 5); } diff --git a/tests/wasm/duplicates_a.js b/tests/wasm/duplicates_a.js index ee5ebb32..e52f346b 100644 --- a/tests/wasm/duplicates_a.js +++ b/tests/wasm/duplicates_a.js @@ -1 +1,2 @@ exports.foo = () => {}; +exports.bar = 3; diff --git a/tests/wasm/duplicates_b.js b/tests/wasm/duplicates_b.js index 00128ede..75263a24 100644 --- a/tests/wasm/duplicates_b.js +++ b/tests/wasm/duplicates_b.js @@ -1 +1,2 @@ exports.foo = () => true; +exports.bar = 4; diff --git a/tests/wasm/duplicates_c.js b/tests/wasm/duplicates_c.js index 90ca9240..601a99a5 100644 --- a/tests/wasm/duplicates_c.js +++ b/tests/wasm/duplicates_c.js @@ -1 +1,2 @@ exports.foo = () => false; +exports.bar = 5; From 61491eafbf6e958df97c3d296ae88a8e92667a50 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 15 Aug 2018 17:52:26 -0700 Subject: [PATCH 31/32] Add experimental support for `WeakRef` This commit adds experimental support for `WeakRef` to be used to automatically free wasm objects instead of having to always call the `free` function manually. Note that when enabled the `free` function for all exported objects is still generated, it's just optionally invoked by the application. Support isn't exposed through a CLI flag right now due to the early stages of the `WeakRef` proposal, but the env var `WASM_BINDGEN_WEAKREF` can be used to enable this generation. Upon doing so the output can then be edited slightly as well to work in the SpiderMonkey shell and it looks like this is working! Closes #704 --- crates/cli-support/src/js/mod.rs | 74 +++++++++++++++++++++++++++++--- crates/cli-support/src/lib.rs | 5 +++ 2 files changed, 73 insertions(+), 6 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 220f6e70..4e4b5ca6 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -490,6 +490,39 @@ impl<'a> Context<'a> { let mut dst = format!("class {} {{\n", name); let mut ts_dst = format!("export {}", dst); + let (mkweakref, freeref) = if self.config.weak_refs { + // When weak refs are enabled we use them to automatically free the + // contents of an exported rust class when it's gc'd. Note that a + // manual `free` function still exists for deterministic + // destruction. + // + // This is implemented by using a `WeakRefGroup` to run finalizers + // for all `WeakRef` objects that it creates. Upon construction of + // a new wasm object we use `makeRef` with "holdings" of a thunk to + // free the wasm instance. Once the `this` (the instance we're + // creating) is gc'd then the finalizer will run with the + // `WeakRef`, and we'll pull out the `holdings`, our pointer. + // + // Note, though, that if manual finalization happens we want to + // cancel the `WeakRef`-generated finalization, so we retain the + // `WeakRef` in a global map. This global map is then used to + // `drop()` the `WeakRef` (cancel finalization) whenever it is + // finalized. + self.expose_cleanup_groups(); + let mk = format!(" + const cleanup_ptr = this.ptr; + const ref = CLEANUPS.makeRef(this, () => free{}(cleanup_ptr)); + CLEANUPS_MAP.set(this.ptr, ref); + ", name); + let free = " + CLEANUPS_MAP.get(ptr).drop(); + CLEANUPS_MAP.delete(ptr); + "; + (mk, free) + } else { + (String::new(), "") + }; + if self.config.debug || class.constructor.is_some() { self.expose_constructor_token(); @@ -516,9 +549,11 @@ impl<'a> Context<'a> { // This invocation of new will call this constructor with a ConstructorToken let instance = {class}.{constructor}(...args); this.ptr = instance.ptr; + {mkweakref} ", class = name, - constructor = constructor + constructor = constructor, + mkweakref = mkweakref, )); } else { dst.push_str( @@ -537,9 +572,11 @@ impl<'a> Context<'a> { constructor(ptr) {{ this.ptr = ptr; + {} }} ", - name + name, + mkweakref, )); } @@ -599,16 +636,29 @@ impl<'a> Context<'a> { } } - dst.push_str(&format!( + self.global(&format!( " - free() {{ - const ptr = this.ptr; - this.ptr = 0; + function free{}(ptr) {{ + {} wasm.{}(ptr); }} ", + name, + freeref, shared::free_function(&name) )); + dst.push_str(&format!( + " + free() {{ + if (this.ptr === 0) + return; + const ptr = this.ptr; + this.ptr = 0; + free{}(this.ptr); + }} + ", + name, + )); ts_dst.push_str("free(): void;\n"); dst.push_str(&class.contents); ts_dst.push_str(&class.typescript); @@ -1594,6 +1644,18 @@ impl<'a> Context<'a> { "); } + fn expose_cleanup_groups(&mut self) { + if !self.exposed_globals.insert("cleanup_groups") { + return + } + self.global( + " + const CLEANUPS = new WeakRefGroup(x => x.holdings()); + const CLEANUPS_MAP = new Map(); + " + ); + } + fn gc(&mut self) -> Result<(), Error> { let module = mem::replace(self.module, Module::default()); let module = module.parse_names().unwrap_or_else(|p| p.1); diff --git a/crates/cli-support/src/lib.rs b/crates/cli-support/src/lib.rs index 5933a691..59f4eb85 100644 --- a/crates/cli-support/src/lib.rs +++ b/crates/cli-support/src/lib.rs @@ -10,6 +10,7 @@ extern crate failure; use std::any::Any; use std::collections::BTreeSet; +use std::env; use std::fmt; use std::fs; use std::mem; @@ -33,6 +34,9 @@ pub struct Bindgen { typescript: bool, demangle: bool, keep_debug: bool, + // Experimental support for `WeakRefGroup`, an upcoming ECMAScript feature. + // Currently only enable-able through an env var. + weak_refs: bool, } enum Input { @@ -55,6 +59,7 @@ impl Bindgen { typescript: false, demangle: true, keep_debug: false, + weak_refs: env::var("WASM_BINDGEN_WEAKREF").is_ok(), } } From 66d96aac11509ce6971f63a81563ef53bcc833df Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 20 Aug 2018 11:23:02 -0700 Subject: [PATCH 32/32] Fix merge conflicts with `fetch` example --- examples/fetch/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fetch/src/lib.rs b/examples/fetch/src/lib.rs index 1964917d..1b4854cb 100644 --- a/examples/fetch/src/lib.rs +++ b/examples/fetch/src/lib.rs @@ -51,12 +51,12 @@ pub fn run() -> Promise { request_options.method("GET"); request_options.mode(RequestMode::Cors); - let req = Request::new_using_usv_str_and_request_init("https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", &request_options).unwrap(); + let req = Request::new_with_str_and_request_init("https://api.github.com/repos/rustwasm/wasm-bindgen/branches/master", &request_options).unwrap(); // the RequestInit struct will eventually support setting headers, but that's missing right now req.headers().set("Accept", "application/vnd.github.v3+json").unwrap(); - let req_promise = window.fetch_using_request(&req); + let req_promise = window.fetch_with_request(&req); let to_return = JsFuture::from(req_promise).and_then(|resp_value| { // resp_value is a Response object