mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-01 15:11:22 +00:00
Merge remote-tracking branch 'upstream/master'
# Conflicts: # crates/webidl/src/first_pass.rs # crates/webidl/src/lib.rs # crates/webidl/src/util.rs
This commit is contained in:
commit
ef3f086102
@ -52,6 +52,9 @@ matrix:
|
||||
script:
|
||||
- cargo test --release
|
||||
- cargo test --target wasm32-unknown-unknown
|
||||
- WASM_BINDGEN_NO_DEBUG=1 cargo test --target wasm32-unknown-unknown
|
||||
- cargo test --target wasm32-unknown-unknown --features serde-serialize
|
||||
- cargo test --target wasm32-unknown-unknown -p no-std
|
||||
# Check JS output from all tests against eslint
|
||||
- npm run run-lint-generated-tests
|
||||
# Check Examples against eslint
|
||||
|
@ -33,6 +33,9 @@ serde_json = { version = "1.0", optional = true }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = { path = 'crates/test', version = '=0.2.15' }
|
||||
serde_derive = "1.0"
|
||||
wasm-bindgen-test-crate-a = { path = 'tests/crates/a' }
|
||||
wasm-bindgen-test-crate-b = { path = 'tests/crates/b' }
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||
wasm-bindgen-test-project-builder = { path = "crates/test-project-builder", version = '=0.2.15' }
|
||||
@ -63,6 +66,7 @@ members = [
|
||||
"examples/performance",
|
||||
"examples/smorgasboard",
|
||||
"examples/wasm-in-wasm",
|
||||
"tests/no-std",
|
||||
]
|
||||
|
||||
[patch.crates-io]
|
||||
|
@ -56,7 +56,6 @@ pub enum MethodSelf {
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
pub struct Import {
|
||||
pub module: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub js_namespace: Option<Ident>,
|
||||
pub kind: ImportKind,
|
||||
}
|
||||
@ -119,7 +118,7 @@ pub struct ImportStatic {
|
||||
pub ty: syn::Type,
|
||||
pub shim: Ident,
|
||||
pub rust_name: Ident,
|
||||
pub js_name: Ident,
|
||||
pub js_name: String,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
@ -146,7 +145,7 @@ pub struct ImportEnum {
|
||||
|
||||
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
|
||||
pub struct Function {
|
||||
pub name: Ident,
|
||||
pub name: String,
|
||||
pub arguments: Vec<syn::ArgCaptured>,
|
||||
pub ret: Option<syn::Type>,
|
||||
pub rust_attrs: Vec<syn::Attribute>,
|
||||
@ -304,33 +303,8 @@ impl Variant {
|
||||
|
||||
impl Import {
|
||||
fn shared(&self) -> Result<shared::Import, Diagnostic> {
|
||||
match (&self.module, &self.version) {
|
||||
(&Some(ref m), None) if m.starts_with("./") => {}
|
||||
(&Some(ref m), &Some(_)) if m.starts_with("./") => {
|
||||
panic!(
|
||||
"when a module path starts with `./` that indicates \
|
||||
that a local file is being imported so the `version` \
|
||||
key cannot also be specified"
|
||||
);
|
||||
}
|
||||
(&Some(_), &Some(_)) => {}
|
||||
(&Some(_), &None) => panic!(
|
||||
"when the `module` directive doesn't start with `./` \
|
||||
then it's interpreted as an NPM package which requires \
|
||||
a `version` to be specified as well, try using \
|
||||
#[wasm_bindgen(module = \"...\", version = \"...\")]"
|
||||
),
|
||||
(&None, &Some(_)) => {
|
||||
panic!(
|
||||
"the #[wasm_bindgen(version = \"...\")] attribute can only \
|
||||
be used when `module = \"...\"` is also specified"
|
||||
);
|
||||
}
|
||||
(&None, &None) => {}
|
||||
}
|
||||
Ok(shared::Import {
|
||||
module: self.module.clone(),
|
||||
version: self.version.clone(),
|
||||
js_namespace: self.js_namespace.as_ref().map(|s| s.to_string()),
|
||||
kind: self.kind.shared(),
|
||||
})
|
||||
|
@ -94,7 +94,6 @@ pub fn ident_ty(ident: Ident) -> syn::Type {
|
||||
pub fn wrap_import_function(function: ast::ImportFunction) -> ast::Import {
|
||||
ast::Import {
|
||||
module: None,
|
||||
version: None,
|
||||
js_namespace: None,
|
||||
kind: ast::ImportKind::Function(function),
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ base64 = "0.9"
|
||||
failure = "0.1.2"
|
||||
parity-wasm = "0.31"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
serde_json = "1.0"
|
||||
tempfile = "3.0"
|
||||
wasm-bindgen-shared = { path = "../shared", version = '=0.2.15' }
|
||||
|
@ -5,7 +5,6 @@ use std::mem;
|
||||
use failure::{Error, ResultExt};
|
||||
use parity_wasm;
|
||||
use parity_wasm::elements::*;
|
||||
use serde_json;
|
||||
use shared;
|
||||
use wasm_gc;
|
||||
|
||||
@ -43,7 +42,6 @@ pub struct Context<'a> {
|
||||
pub exported_classes: HashMap<String, ExportedClass>,
|
||||
pub function_table_needed: bool,
|
||||
pub run_descriptor: &'a Fn(&str) -> Option<Vec<u32>>,
|
||||
pub module_versions: Vec<(String, String)>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -458,7 +456,6 @@ impl<'a> Context<'a> {
|
||||
|
||||
self.export_table();
|
||||
self.gc()?;
|
||||
self.add_wasm_pack_section();
|
||||
|
||||
while js.contains("\n\n\n") {
|
||||
js = js.replace("\n\n\n", "\n\n");
|
||||
@ -1629,28 +1626,6 @@ impl<'a> Context<'a> {
|
||||
self.globals.push_str("\n");
|
||||
}
|
||||
|
||||
fn add_wasm_pack_section(&mut self) {
|
||||
if self.module_versions.len() == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct WasmPackSchema<'a> {
|
||||
version: &'a str,
|
||||
modules: &'a [(String, String)],
|
||||
}
|
||||
|
||||
let contents = serde_json::to_string(&WasmPackSchema {
|
||||
version: "0.0.1",
|
||||
modules: &self.module_versions,
|
||||
}).unwrap();
|
||||
|
||||
let mut section = CustomSection::default();
|
||||
*section.name_mut() = "__wasm_pack_unstable".to_string();
|
||||
*section.payload_mut() = contents.into_bytes();
|
||||
self.module.sections_mut().push(Section::Custom(section));
|
||||
}
|
||||
|
||||
fn use_node_require(&self) -> bool {
|
||||
self.config.nodejs && !self.config.nodejs_experimental_modules
|
||||
}
|
||||
@ -1766,7 +1741,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
}
|
||||
|
||||
fn generate_import(&mut self, import: &shared::Import) -> Result<(), Error> {
|
||||
self.validate_import_module(import)?;
|
||||
match import.kind {
|
||||
shared::ImportKind::Function(ref f) => {
|
||||
self.generate_import_function(import, f).with_context(|_| {
|
||||
@ -1787,41 +1761,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_import_module(&mut self, import: &shared::Import) -> Result<(), Error> {
|
||||
let version = match import.version {
|
||||
Some(ref s) => s,
|
||||
None => return Ok(()),
|
||||
};
|
||||
let module = match import.module {
|
||||
Some(ref s) => s,
|
||||
None => return Ok(()),
|
||||
};
|
||||
if module.starts_with("./") {
|
||||
return Ok(());
|
||||
}
|
||||
let pkg = if module.starts_with("@") {
|
||||
// Translate `@foo/bar/baz` to `@foo/bar` and `@foo/bar` to itself
|
||||
let first_slash = match module.find('/') {
|
||||
Some(i) => i,
|
||||
None => bail!(
|
||||
"packages starting with `@` must be of the form \
|
||||
`@foo/bar`, but found: `{}`",
|
||||
module
|
||||
),
|
||||
};
|
||||
match module[first_slash + 1..].find('/') {
|
||||
Some(i) => &module[..i],
|
||||
None => module,
|
||||
}
|
||||
} else {
|
||||
module.split('/').next().unwrap()
|
||||
};
|
||||
self.cx
|
||||
.module_versions
|
||||
.push((pkg.to_string(), version.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn generate_import_static(
|
||||
&mut self,
|
||||
info: &shared::Import,
|
||||
|
@ -2,8 +2,6 @@
|
||||
|
||||
extern crate parity_wasm;
|
||||
extern crate wasm_bindgen_shared as shared;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
extern crate serde_json;
|
||||
extern crate wasm_gc;
|
||||
extern crate wasmi;
|
||||
@ -203,7 +201,6 @@ impl Bindgen {
|
||||
config: &self,
|
||||
module: &mut module,
|
||||
function_table_needed: false,
|
||||
module_versions: Default::default(),
|
||||
run_descriptor: &|name| {
|
||||
let mut v = MyExternals(Vec::new());
|
||||
match instance.invoke_export(name, &[], &mut v) {
|
||||
|
@ -123,11 +123,12 @@ fn rmain() -> Result<(), Error> {
|
||||
node = !custom.payload().contains(&0x01);
|
||||
}
|
||||
let headless = env::var("NO_HEADLESS").is_err();
|
||||
let debug = env::var("WASM_BINDGEN_NO_DEBUG").is_err();
|
||||
|
||||
// Make the generated bindings available for the tests to execute against.
|
||||
shell.status("Executing bindgen...");
|
||||
let mut b = Bindgen::new();
|
||||
b.debug(true)
|
||||
b.debug(debug)
|
||||
.nodejs(node)
|
||||
.input_module(module, wasm, |w| parity_wasm::serialize(w).unwrap())
|
||||
.keep_debug(false)
|
||||
|
@ -361,6 +361,16 @@ extern "C" {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(length: u32) -> ArrayBuffer;
|
||||
|
||||
/// The byteLength property of an object which is an instance of type ArrayBuffer
|
||||
/// it's an accessor property whose set accessor function is undefined,
|
||||
/// meaning that you can only read this property.
|
||||
/// The value is established when the array is constructed and cannot be changed.
|
||||
/// This property returns 0 if this ArrayBuffer has been detached.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength
|
||||
#[wasm_bindgen(method, getter, js_name = byteLength)]
|
||||
pub fn byte_length(this: &ArrayBuffer) -> u32;
|
||||
|
||||
/// The `isView()` method returns true if arg is one of the `ArrayBuffer`
|
||||
/// views, such as typed array objects or a DataView; false otherwise.
|
||||
///
|
||||
@ -2168,6 +2178,30 @@ extern {
|
||||
#[wasm_bindgen(method, getter)]
|
||||
pub fn multiline(this: &RegExp) -> bool;
|
||||
|
||||
/// The non-standard $1, $2, $3, $4, $5, $6, $7, $8, $9 properties
|
||||
/// are static and read-only properties of regular expressions
|
||||
/// that contain parenthesized substring matches.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/n
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$1")]
|
||||
pub fn n1() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$2")]
|
||||
pub fn n2() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$3")]
|
||||
pub fn n3() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$4")]
|
||||
pub fn n4() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$5")]
|
||||
pub fn n5() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$6")]
|
||||
pub fn n6() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$7")]
|
||||
pub fn n7() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$8")]
|
||||
pub fn n8() -> JsString;
|
||||
#[wasm_bindgen(static_method_of = RegExp, getter, js_name = "$9")]
|
||||
pub fn n9() -> JsString;
|
||||
|
||||
/// The RegExp constructor creates a regular expression object for matching text with a pattern.
|
||||
///
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
|
||||
|
@ -9,6 +9,12 @@ fn new() {
|
||||
assert!(y.is_object());
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn byte_length() {
|
||||
let buf = ArrayBuffer::new(42);
|
||||
assert_eq!(buf.byte_length(), 42);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn is_view() {
|
||||
let x = Uint8Array::new(&JsValue::from(42));
|
||||
|
@ -29,7 +29,7 @@ fn apply() {
|
||||
assert_eq!(Array::from(&arr).length(), 1);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Function.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Function.js")]
|
||||
extern {
|
||||
fn get_function_to_bind() -> Function;
|
||||
fn get_value_to_bind_to() -> JsValue;
|
||||
|
@ -2,7 +2,7 @@ use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
use js_sys::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Generator.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Generator.js")]
|
||||
extern {
|
||||
fn one_two_generator() -> Generator;
|
||||
fn dummy_generator() -> Generator;
|
||||
|
@ -10,7 +10,7 @@ extern {
|
||||
fn set_foo(this: &Foo42, val: JsValue);
|
||||
}
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Object.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Object.js")]
|
||||
extern {
|
||||
fn map_with_symbol_key() -> Object;
|
||||
fn symbol_key() -> JsValue;
|
||||
|
@ -2,7 +2,7 @@ use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
use js_sys::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Proxy.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Proxy.js")]
|
||||
extern {
|
||||
fn proxy_target() -> JsValue;
|
||||
fn proxy_handler() -> Object;
|
||||
|
@ -2,7 +2,7 @@ use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
use js_sys::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Reflect.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Reflect.js")]
|
||||
extern {
|
||||
fn get_char_at() -> Function;
|
||||
|
||||
|
@ -3,7 +3,6 @@ use js_sys::*;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn exec() {
|
||||
|
||||
let re = RegExp::new("quick\\s(brown).+?(jumps)", "ig");
|
||||
let result = re.exec("The Quick Brown Fox Jumps Over The Lazy Dog");
|
||||
|
||||
@ -76,6 +75,21 @@ fn multiline() {
|
||||
assert!(re.multiline());
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn n1_to_n9() {
|
||||
let re = RegExp::new(r"(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)\s(\w+)", "");
|
||||
re.test("The Quick Brown Fox Jumps Over The Lazy Dog");
|
||||
assert_eq!(RegExp::n1(), "The");
|
||||
assert_eq!(RegExp::n2(), "Quick");
|
||||
assert_eq!(RegExp::n3(), "Brown");
|
||||
assert_eq!(RegExp::n4(), "Fox");
|
||||
assert_eq!(RegExp::n5(), "Jumps");
|
||||
assert_eq!(RegExp::n6(), "Over");
|
||||
assert_eq!(RegExp::n7(), "The");
|
||||
assert_eq!(RegExp::n8(), "Lazy");
|
||||
assert_eq!(RegExp::n9(), "Dog");
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn new() {
|
||||
let re = RegExp::new("foo", "");
|
||||
|
@ -2,7 +2,7 @@ use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
use js_sys::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/Symbol.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/Symbol.js")]
|
||||
extern {
|
||||
fn test_has_instance(sym: &Symbol);
|
||||
fn test_is_concat_spreadable(sym: &Symbol);
|
||||
|
@ -53,17 +53,6 @@ impl BindgenAttrs {
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Get the first version attribute
|
||||
fn version(&self) -> Option<&str> {
|
||||
self.attrs
|
||||
.iter()
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::Version(s) => Some(&s[..]),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
}
|
||||
|
||||
/// Whether the catch attribute is present
|
||||
fn catch(&self) -> bool {
|
||||
self.attrs.iter().any(|a| match a {
|
||||
@ -173,11 +162,11 @@ impl BindgenAttrs {
|
||||
}
|
||||
|
||||
/// Get the first js_name attribute
|
||||
fn js_name(&self) -> Option<&Ident> {
|
||||
fn js_name(&self) -> Option<&str> {
|
||||
self.attrs
|
||||
.iter()
|
||||
.filter_map(|a| match a {
|
||||
BindgenAttr::JsName(s) => Some(s),
|
||||
BindgenAttr::JsName(s) => Some(&s[..]),
|
||||
_ => None,
|
||||
})
|
||||
.next()
|
||||
@ -219,7 +208,6 @@ pub enum BindgenAttr {
|
||||
StaticMethodOf(Ident),
|
||||
JsNamespace(Ident),
|
||||
Module(String),
|
||||
Version(String),
|
||||
Getter(Option<Ident>),
|
||||
Setter(Option<Ident>),
|
||||
SpecialGetter,
|
||||
@ -227,7 +215,7 @@ pub enum BindgenAttr {
|
||||
SpecialDeleter,
|
||||
Structural,
|
||||
Readonly,
|
||||
JsName(Ident),
|
||||
JsName(String),
|
||||
JsClass(String),
|
||||
}
|
||||
|
||||
@ -290,18 +278,15 @@ impl syn::synom::Synom for BindgenAttr {
|
||||
(s.value())
|
||||
)=> { BindgenAttr::Module }
|
||||
|
|
||||
do_parse!(
|
||||
call!(term, "version") >>
|
||||
punct!(=) >>
|
||||
s: syn!(syn::LitStr) >>
|
||||
(s.value())
|
||||
)=> { BindgenAttr::Version }
|
||||
|
|
||||
do_parse!(
|
||||
call!(term, "js_name") >>
|
||||
punct!(=) >>
|
||||
ns: call!(term2ident) >>
|
||||
(ns)
|
||||
name: alt!(
|
||||
syn!(syn::LitStr) => { |s| s.value() }
|
||||
|
|
||||
call!(term2ident) => { |s| s.to_string() }
|
||||
) >>
|
||||
(name)
|
||||
)=> { BindgenAttr::JsName }
|
||||
|
|
||||
do_parse!(
|
||||
@ -398,9 +383,10 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
fn convert(self, (opts, module): (BindgenAttrs, &'a Option<String>))
|
||||
-> Result<Self::Target, Diagnostic>
|
||||
{
|
||||
let js_name = opts.js_name().unwrap_or(&self.ident).clone();
|
||||
let default_name = self.ident.to_string();
|
||||
let js_name = opts.js_name().unwrap_or(&default_name);
|
||||
let wasm = function_from_decl(
|
||||
&js_name,
|
||||
js_name,
|
||||
self.decl.clone(),
|
||||
self.attrs.clone(),
|
||||
self.vis.clone(),
|
||||
@ -517,7 +503,9 @@ impl<'a> ConvertToAst<(BindgenAttrs, &'a Option<String>)> for syn::ForeignItemFn
|
||||
ast::ImportFunctionKind::Method { ref class, .. } => (1, &class[..]),
|
||||
};
|
||||
let data = (ns, &self.ident, module);
|
||||
format!("__wbg_{}_{}", js_name, ShortHash(data))
|
||||
format!("__wbg_{}_{}",
|
||||
js_name.chars().filter(|c| c.is_ascii_alphanumeric()).collect::<String>(),
|
||||
ShortHash(data))
|
||||
};
|
||||
Ok(ast::ImportKind::Function(ast::ImportFunction {
|
||||
function: wasm,
|
||||
@ -552,13 +540,16 @@ impl ConvertToAst<BindgenAttrs> for syn::ForeignItemStatic {
|
||||
if self.mutability.is_some() {
|
||||
bail_span!(self.mutability, "cannot import mutable globals yet")
|
||||
}
|
||||
let js_name = opts.js_name().unwrap_or(&self.ident);
|
||||
let shim = format!("__wbg_static_accessor_{}_{}", js_name, self.ident);
|
||||
let default_name = self.ident.to_string();
|
||||
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::<String>(),
|
||||
self.ident);
|
||||
Ok(ast::ImportKind::Static(ast::ImportStatic {
|
||||
ty: *self.ty,
|
||||
vis: self.vis,
|
||||
rust_name: self.ident.clone(),
|
||||
js_name: js_name.clone(),
|
||||
js_name: js_name.to_string(),
|
||||
shim: Ident::new(&shim, Span::call_site()),
|
||||
}))
|
||||
}
|
||||
@ -579,14 +570,15 @@ impl ConvertToAst<BindgenAttrs> for syn::ItemFn {
|
||||
bail_span!(self.unsafety, "can only #[wasm_bindgen] safe functions");
|
||||
}
|
||||
|
||||
let name = attrs.js_name().unwrap_or(&self.ident);
|
||||
let default_name = self.ident.to_string();
|
||||
let name = attrs.js_name().unwrap_or(&default_name);
|
||||
Ok(function_from_decl(name, self.decl, self.attrs, self.vis, false, None)?.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a function (and gets the self type if appropriate) for our AST from a syn function.
|
||||
fn function_from_decl(
|
||||
name: &Ident,
|
||||
name: &str,
|
||||
decl: Box<syn::FnDecl>,
|
||||
attrs: Vec<syn::Attribute>,
|
||||
vis: syn::Visibility,
|
||||
@ -661,7 +653,7 @@ fn function_from_decl(
|
||||
|
||||
Ok((
|
||||
ast::Function {
|
||||
name: name.clone(),
|
||||
name: name.to_string(),
|
||||
arguments,
|
||||
ret,
|
||||
rust_vis: vis,
|
||||
@ -824,7 +816,7 @@ impl<'a, 'b> MacroParse<()> for (&'a Ident, &'b mut syn::ImplItem) {
|
||||
};
|
||||
|
||||
let (function, method_self) = function_from_decl(
|
||||
opts.js_name().unwrap_or(&method.sig.ident),
|
||||
opts.js_name().unwrap_or(&method.sig.ident.to_string()),
|
||||
Box::new(method.sig.decl.clone()),
|
||||
method.attrs.clone(),
|
||||
method.vis.clone(),
|
||||
@ -940,10 +932,6 @@ impl<'a> MacroParse<&'a BindgenAttrs> for syn::ForeignItem {
|
||||
BindgenAttrs::find(attrs)?
|
||||
};
|
||||
let module = item_opts.module().or(opts.module()).map(|s| s.to_string());
|
||||
let version = item_opts
|
||||
.version()
|
||||
.or(opts.version())
|
||||
.map(|s| s.to_string());
|
||||
let js_namespace = item_opts.js_namespace().or(opts.js_namespace()).cloned();
|
||||
let kind = match self {
|
||||
syn::ForeignItem::Fn(f) => f.convert((item_opts, &module))?,
|
||||
@ -954,7 +942,6 @@ impl<'a> MacroParse<&'a BindgenAttrs> for syn::ForeignItem {
|
||||
|
||||
program.imports.push(ast::Import {
|
||||
module,
|
||||
version,
|
||||
js_namespace,
|
||||
kind,
|
||||
});
|
||||
|
@ -24,7 +24,6 @@ pub struct Program {
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Import {
|
||||
pub module: Option<String>,
|
||||
pub version: Option<String>,
|
||||
pub js_namespace: Option<String>,
|
||||
pub kind: ImportKind,
|
||||
}
|
||||
|
@ -32,9 +32,16 @@ pub fn wasm_bindgen_test(
|
||||
|
||||
let mut body = TokenStream::from(body).into_iter();
|
||||
|
||||
// Assume the input item is of the form `fn #ident ...`, and extract
|
||||
// `#ident`
|
||||
let fn_tok = body.next();
|
||||
// Skip over other attributes to `fn #ident ...`, and extract `#ident`
|
||||
let mut leading_tokens = Vec::new();
|
||||
while let Some(token) = body.next() {
|
||||
leading_tokens.push(token.clone());
|
||||
if let TokenTree::Ident(token) = token {
|
||||
if token == "fn" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
let ident = match body.next() {
|
||||
Some(TokenTree::Ident(token)) => token,
|
||||
_ => panic!("expected a function name"),
|
||||
@ -64,7 +71,7 @@ pub fn wasm_bindgen_test(
|
||||
}
|
||||
}).into_iter());
|
||||
|
||||
tokens.extend(fn_tok);
|
||||
tokens.extend(leading_tokens);
|
||||
tokens.push(ident.into());
|
||||
tokens.extend(body);
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
extern crate env_logger;
|
||||
#[macro_use]
|
||||
extern crate failure;
|
||||
extern crate wasm_bindgen_webidl;
|
||||
extern crate sourcefile;
|
||||
@ -8,9 +9,8 @@ use sourcefile::SourceFile;
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::io::Write;
|
||||
use std::path;
|
||||
use std::process;
|
||||
use std::process::{self, Command};
|
||||
|
||||
fn main() {
|
||||
if let Err(e) = try_main() {
|
||||
@ -32,12 +32,14 @@ fn try_main() -> Result<(), failure::Error> {
|
||||
let mut source = SourceFile::default();
|
||||
for entry in entries {
|
||||
let entry = entry.context("getting webidls/enabled/*.webidl entry")?;
|
||||
if entry.path().extension() == Some(OsStr::new("webidl")) {
|
||||
println!("cargo:rerun-if-changed={}", entry.path().display());
|
||||
source = source.add_file(entry.path())
|
||||
.with_context(|_| format!("reading contents of file \"{}\"",
|
||||
entry.path().display()))?;
|
||||
let path = entry.path();
|
||||
if path.extension() != Some(OsStr::new("webidl")) {
|
||||
continue
|
||||
}
|
||||
println!("cargo:rerun-if-changed={}", path.display());
|
||||
source = source.add_file(&path)
|
||||
.with_context(|_| format!("reading contents of file \"{}\"",
|
||||
path.display()))?;
|
||||
}
|
||||
|
||||
let bindings = match wasm_bindgen_webidl::compile(&source.contents) {
|
||||
@ -60,17 +62,19 @@ fn try_main() -> Result<(), failure::Error> {
|
||||
|
||||
let out_dir = env::var("OUT_DIR").context("reading OUT_DIR environment variable")?;
|
||||
let out_file_path = path::Path::new(&out_dir).join("bindings.rs");
|
||||
let mut out_file = fs::File::create(&out_file_path)
|
||||
.context("creating output bindings file")?;
|
||||
out_file
|
||||
.write_all(bindings.as_bytes())
|
||||
fs::write(&out_file_path, bindings)
|
||||
.context("writing bindings to output file")?;
|
||||
|
||||
// run rustfmt on the generated file - really handy for debugging
|
||||
//if ! process::Command::new("rustfmt").arg(&out_file_path).status()
|
||||
// .context("running rustfmt")?.success() {
|
||||
// return Err(format_err!("rustfmt failed to format {}", out_file_path.display()));
|
||||
//}
|
||||
if env::var("WEBIDL_RUSTFMT_BINDINGS").is_ok() {
|
||||
let status = Command::new("rustfmt")
|
||||
.arg(&out_file_path)
|
||||
.status()
|
||||
.context("running rustfmt")?;
|
||||
if !status.success() {
|
||||
bail!("rustfmt failed: {}", status)
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ fn main() {
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen(module = "{}", version = "*")]
|
||||
#[wasm_bindgen(module = "{}")]
|
||||
extern {{
|
||||
fn not_actually_a_function{1}();
|
||||
}}
|
||||
|
@ -20,4 +20,4 @@ proc-macro2 = "0.4.8"
|
||||
quote = '0.6'
|
||||
syn = { version = '0.14', features = ['full'] }
|
||||
wasm-bindgen-backend = { version = "=0.2.15", path = "../backend" }
|
||||
webidl = "0.7.0"
|
||||
weedle = "0.6"
|
||||
|
@ -7,69 +7,61 @@
|
||||
//! Only `interface`s, `dictionary`s, `enum`s and `mixin`s can
|
||||
//! be partial.
|
||||
|
||||
use std::{
|
||||
collections::{BTreeMap, BTreeSet}, mem,
|
||||
};
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
|
||||
use webidl;
|
||||
use weedle::argument::Argument;
|
||||
use weedle::attribute::ExtendedAttribute;
|
||||
use weedle::interface::StringifierOrStatic;
|
||||
use weedle::mixin::MixinMembers;
|
||||
use weedle;
|
||||
|
||||
use super::Result;
|
||||
use util;
|
||||
|
||||
/// Collection of constructs that may use partial.
|
||||
#[derive(Default)]
|
||||
pub(crate) struct FirstPassRecord<'a> {
|
||||
pub(crate) interfaces: BTreeMap<String, InterfaceData>,
|
||||
pub(crate) dictionaries: BTreeSet<String>,
|
||||
pub(crate) enums: BTreeSet<String>,
|
||||
pub(crate) struct FirstPassRecord<'src> {
|
||||
pub(crate) interfaces: BTreeMap<&'src str, InterfaceData<'src>>,
|
||||
pub(crate) dictionaries: BTreeSet<&'src str>,
|
||||
pub(crate) enums: BTreeSet<&'src str>,
|
||||
/// The mixins, mapping their name to the webidl ast node for the mixin.
|
||||
pub(crate) mixins: BTreeMap<String, MixinData<'a>>,
|
||||
pub(crate) typedefs: BTreeMap<String, webidl::ast::Type>,
|
||||
pub(crate) mixins: BTreeMap<&'src str, Vec<&'src MixinMembers<'src>>>,
|
||||
pub(crate) typedefs: BTreeMap<&'src str, &'src weedle::types::Type<'src>>,
|
||||
}
|
||||
|
||||
/// We need to collect interface data during the first pass, to be used later.
|
||||
#[derive(Default)]
|
||||
pub(crate) struct InterfaceData {
|
||||
pub(crate) struct InterfaceData<'src> {
|
||||
/// Whether only partial interfaces were encountered
|
||||
pub(crate) partial: bool,
|
||||
pub(crate) operations: BTreeMap<OperationId, OperationData>,
|
||||
pub(crate) global: bool,
|
||||
pub(crate) operations: BTreeMap<OperationId<'src>, OperationData<'src>>,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub(crate) enum OperationId {
|
||||
pub(crate) enum OperationId<'src> {
|
||||
Constructor,
|
||||
Operation(Option<String>),
|
||||
Operation(Option<&'src str>),
|
||||
SpecialGetter,
|
||||
SpecialSetter,
|
||||
SpecialDeleter,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct OperationData {
|
||||
pub(crate) struct OperationData<'src> {
|
||||
pub(crate) overloaded: bool,
|
||||
/// Map from argument names to whether they are the same for multiple overloads
|
||||
pub(crate) argument_names_same: BTreeMap<Vec<String>, bool>,
|
||||
}
|
||||
|
||||
/// We need to collect mixin data during the first pass, to be used later.
|
||||
#[derive(Default)]
|
||||
pub(crate) struct MixinData<'a> {
|
||||
/// The non partial mixin, if present. If there is more than one, we are
|
||||
/// parsing is a malformed WebIDL file, but the parser will recover by
|
||||
/// using the last parsed mixin.
|
||||
pub(crate) non_partial: Option<&'a webidl::ast::NonPartialMixin>,
|
||||
/// 0 or more partial mixins.
|
||||
pub(crate) partials: Vec<&'a webidl::ast::PartialMixin>,
|
||||
pub(crate) argument_names_same: BTreeMap<Vec<&'src str>, bool>,
|
||||
}
|
||||
|
||||
/// Implemented on an AST node to populate the `FirstPassRecord` struct.
|
||||
pub(crate) trait FirstPass<Ctx> {
|
||||
pub(crate) trait FirstPass<'src, Ctx> {
|
||||
/// Populate `record` with any constructs in `self`.
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, ctx: Ctx) -> Result<()>;
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, ctx: Ctx) -> Result<()>;
|
||||
}
|
||||
|
||||
impl FirstPass<()> for [webidl::ast::Definition] {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
impl<'src> FirstPass<'src, ()> for [weedle::Definition<'src>] {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
for def in self {
|
||||
def.first_pass(record, ())?;
|
||||
}
|
||||
@ -78,15 +70,17 @@ impl FirstPass<()> for [webidl::ast::Definition] {
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Definition {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
use webidl::ast::Definition::*;
|
||||
impl<'src> FirstPass<'src, ()> for weedle::Definition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
use weedle::Definition::*;
|
||||
|
||||
match self {
|
||||
Dictionary(dictionary) => dictionary.first_pass(record, ()),
|
||||
Enum(enum_) => enum_.first_pass(record, ()),
|
||||
Interface(interface) => interface.first_pass(record, ()),
|
||||
Mixin(mixin) => mixin.first_pass(record, ()),
|
||||
PartialInterface(interface) => interface.first_pass(record, ()),
|
||||
InterfaceMixin(mixin) => mixin.first_pass(record, ()),
|
||||
PartialInterfaceMixin(mixin) => mixin.first_pass(record, ()),
|
||||
Typedef(typedef) => typedef.first_pass(record, ()),
|
||||
_ => {
|
||||
// Other definitions aren't currently used in the first pass
|
||||
@ -96,46 +90,38 @@ impl FirstPass<()> for webidl::ast::Definition {
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Dictionary {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
use webidl::ast::Dictionary::*;
|
||||
|
||||
match self {
|
||||
NonPartial(dictionary) => dictionary.first_pass(record, ()),
|
||||
_ => {
|
||||
// Other dictionaries aren't currently used in the first pass
|
||||
Ok(())
|
||||
}
|
||||
impl<'src> FirstPass<'src, ()> for weedle::DictionaryDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if !record.dictionaries.insert(self.identifier.0) {
|
||||
warn!("encountered multiple dictionary declarations of {}", self.identifier.0);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::NonPartialDictionary {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
if record.dictionaries.insert(self.name.clone()) {
|
||||
warn!("Encountered multiple declarations of {}", self.name);
|
||||
impl<'src> FirstPass<'src, ()> for weedle::EnumDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if !record.enums.insert(self.identifier.0) {
|
||||
warn!("Encountered multiple enum declarations of {}", self.identifier.0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Enum {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
if record.enums.insert(self.name.clone()) {
|
||||
warn!("Encountered multiple declarations of {}", self.name);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn first_pass_operation<'a>(
|
||||
record: &mut FirstPassRecord<'a>,
|
||||
self_name: &str,
|
||||
id: OperationId,
|
||||
arguments: &[webidl::ast::Argument],
|
||||
fn first_pass_operation<'src>(
|
||||
record: &mut FirstPassRecord<'src>,
|
||||
self_name: &'src str,
|
||||
id: OperationId<'src>,
|
||||
arguments: &[Argument<'src>],
|
||||
) -> Result<()> {
|
||||
let mut names = Vec::with_capacity(arguments.len());
|
||||
for argument in arguments {
|
||||
match argument {
|
||||
Argument::Single(arg) => names.push(arg.identifier.0),
|
||||
Argument::Variadic(_) => return Ok(()),
|
||||
}
|
||||
}
|
||||
record
|
||||
.interfaces
|
||||
.get_mut(self_name)
|
||||
@ -143,77 +129,48 @@ fn first_pass_operation<'a>(
|
||||
.operations
|
||||
.entry(id)
|
||||
.and_modify(|operation_data| operation_data.overloaded = true)
|
||||
.or_insert_with(||
|
||||
OperationData {
|
||||
overloaded: false,
|
||||
argument_names_same: Default::default(),
|
||||
}
|
||||
)
|
||||
.or_insert_with(Default::default)
|
||||
.argument_names_same
|
||||
.entry(arguments.iter().map(|argument| argument.name.clone()).collect())
|
||||
.entry(names)
|
||||
.and_modify(|same_argument_names| *same_argument_names = true)
|
||||
.or_insert(false);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Interface {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
use webidl::ast::Interface::*;
|
||||
|
||||
match self {
|
||||
Partial(interface) => interface.first_pass(record, ()),
|
||||
NonPartial(interface) => interface.first_pass(record, ()),
|
||||
// TODO
|
||||
Callback(..) => {
|
||||
warn!("Unsupported WebIDL interface: {:?}", self);
|
||||
Ok(())
|
||||
}
|
||||
impl<'src> FirstPass<'src, ()> for weedle::InterfaceDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
{
|
||||
let interface = record
|
||||
.interfaces
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(Default::default);
|
||||
interface.partial = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::NonPartialInterface {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
record
|
||||
.interfaces
|
||||
.entry(self.name.clone())
|
||||
.and_modify(|interface_data| {
|
||||
if interface_data.partial {
|
||||
interface_data.partial = false;
|
||||
} else {
|
||||
warn!("Encountered multiple declarations of {}", self.name);
|
||||
}
|
||||
})
|
||||
.or_insert_with(||
|
||||
InterfaceData {
|
||||
partial: false,
|
||||
operations: Default::default(),
|
||||
global: false,
|
||||
},
|
||||
);
|
||||
|
||||
if ::util::is_chrome_only(&self.extended_attributes) {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
for extended_attribute in &self.extended_attributes {
|
||||
extended_attribute.first_pass(record, &self.name)?;
|
||||
if let Some(attrs) = &self.attributes {
|
||||
for attr in &attrs.body.list {
|
||||
attr.first_pass(record, self.identifier.0)?;
|
||||
}
|
||||
}
|
||||
|
||||
for member in &self.members {
|
||||
member.first_pass(record, &self.name)?;
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::PartialInterface {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
record
|
||||
.interfaces
|
||||
.entry(self.name.clone())
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(||
|
||||
InterfaceData {
|
||||
partial: true,
|
||||
@ -222,191 +179,129 @@ impl FirstPass<()> for webidl::ast::PartialInterface {
|
||||
},
|
||||
);
|
||||
|
||||
if ::util::is_chrome_only(&self.extended_attributes) {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
for member in &self.members {
|
||||
member.first_pass(record, &self.name)?;
|
||||
for member in &self.members.body {
|
||||
member.first_pass(record, self.identifier.0)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::ExtendedAttribute {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
impl<'src> FirstPass<'src, &'src str> for ExtendedAttribute<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
match self {
|
||||
webidl::ast::ExtendedAttribute::ArgumentList(
|
||||
webidl::ast::ArgumentListExtendedAttribute { arguments, name },
|
||||
)
|
||||
if name == "Constructor" =>
|
||||
{
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&arguments,
|
||||
)
|
||||
}
|
||||
webidl::ast::ExtendedAttribute::NoArguments(webidl::ast::Other::Identifier(name))
|
||||
if name == "Constructor" =>
|
||||
{
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&[],
|
||||
)
|
||||
}
|
||||
webidl::ast::ExtendedAttribute::NamedArgumentList(
|
||||
webidl::ast::NamedArgumentListExtendedAttribute {
|
||||
lhs_name,
|
||||
rhs_arguments,
|
||||
..
|
||||
},
|
||||
)
|
||||
if lhs_name == "NamedConstructor" =>
|
||||
{
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&rhs_arguments,
|
||||
)
|
||||
},
|
||||
webidl::ast::ExtendedAttribute::Identifier(
|
||||
webidl::ast::IdentifierExtendedAttribute { lhs, .. }
|
||||
)
|
||||
| webidl::ast::ExtendedAttribute::IdentifierList(
|
||||
webidl::ast::IdentifierListExtendedAttribute { lhs, .. }
|
||||
)
|
||||
if lhs == "Global" =>
|
||||
{
|
||||
record.interfaces.get_mut(self_name).unwrap().global = true;
|
||||
Ok(())
|
||||
}
|
||||
ExtendedAttribute::ArgList(list) if list.identifier.0 == "Constructor" => {
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&list.args.body.list,
|
||||
)
|
||||
}
|
||||
ExtendedAttribute::NoArgs(name) if (name.0).0 == "Constructor" => {
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&[],
|
||||
)
|
||||
}
|
||||
ExtendedAttribute::NamedArgList(list)
|
||||
if list.lhs_identifier.0 == "NamedConstructor" =>
|
||||
{
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Constructor,
|
||||
&list.args.body.list,
|
||||
)
|
||||
}
|
||||
ExtendedAttribute::Ident(id) if id.lhs_identifier.0 == "Global" => {
|
||||
record.interfaces.get_mut(self_name).unwrap().global = true;
|
||||
Ok(())
|
||||
}
|
||||
ExtendedAttribute::IdentList(id) if id.identifier.0 == "Global" => {
|
||||
record.interfaces.get_mut(self_name).unwrap().global = true;
|
||||
Ok(())
|
||||
}
|
||||
_ => Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::InterfaceMember {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::interface::InterfaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
match self {
|
||||
webidl::ast::InterfaceMember::Operation(op) => op.first_pass(record, self_name),
|
||||
weedle::interface::InterfaceMember::Operation(op) => {
|
||||
op.first_pass(record, self_name)
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::Operation {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
match self {
|
||||
webidl::ast::Operation::Regular(op) => op.first_pass(record, self_name),
|
||||
webidl::ast::Operation::Static(op) => op.first_pass(record, self_name),
|
||||
webidl::ast::Operation::Special(op) => op.first_pass(record, self_name),
|
||||
// TODO
|
||||
webidl::ast::Operation::Stringifier(_) => {
|
||||
warn!("Unsupported WebIDL operation: {:?}", self);
|
||||
Ok(())
|
||||
}
|
||||
impl<'src> FirstPass<'src, &'src str> for weedle::interface::OperationInterfaceMember<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, self_name: &'src str) -> Result<()> {
|
||||
if !self.specials.is_empty() && self.specials.len() != 1 {
|
||||
warn!("Unsupported webidl operation {:?}", self);
|
||||
return Ok(())
|
||||
}
|
||||
if let Some(StringifierOrStatic::Stringifier(_)) = self.modifier {
|
||||
warn!("Unsupported webidl operation {:?}", self);
|
||||
return Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::RegularOperation {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Operation(self.name.clone()),
|
||||
&self.arguments,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::StaticOperation {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
OperationId::Operation(self.name.clone()),
|
||||
&self.arguments,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> FirstPass<&'b str> for webidl::ast::SpecialOperation {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, self_name: &'b str) -> Result<()> {
|
||||
first_pass_operation(
|
||||
record,
|
||||
self_name,
|
||||
match self.name {
|
||||
None => match self.special_keywords.iter().next() {
|
||||
Some(webidl::ast::Special::Getter) => OperationId::SpecialGetter,
|
||||
Some(webidl::ast::Special::Setter) => OperationId::SpecialSetter,
|
||||
Some(webidl::ast::Special::Deleter) => OperationId::SpecialDeleter,
|
||||
Some(webidl::ast::Special::LegacyCaller) => return Ok(()),
|
||||
None => {
|
||||
panic!("unsupported special operation: {:?} of {}", self, self_name);
|
||||
}
|
||||
match self.identifier.map(|s| s.0) {
|
||||
None => match self.specials.get(0) {
|
||||
None => OperationId::Operation(None),
|
||||
Some(weedle::interface::Special::Getter(weedle::term::Getter)) => OperationId::SpecialGetter,
|
||||
Some(weedle::interface::Special::Setter(weedle::term::Setter)) => OperationId::SpecialSetter,
|
||||
Some(weedle::interface::Special::Deleter(weedle::term::Deleter)) => OperationId::SpecialDeleter,
|
||||
Some(weedle::interface::Special::LegacyCaller(weedle::term::LegacyCaller)) => return Ok(()),
|
||||
},
|
||||
Some(ref name) => OperationId::Operation(Some(name.clone())),
|
||||
},
|
||||
&self.arguments,
|
||||
&self.args.body.list,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Mixin {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
use webidl::ast::Mixin::*;
|
||||
|
||||
match self {
|
||||
NonPartial(mixin) => mixin.first_pass(record, ()),
|
||||
Partial(mixin) => mixin.first_pass(record, ()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::NonPartialMixin {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
let entry = record
|
||||
impl<'src> FirstPass<'src, ()> for weedle::InterfaceMixinDefinition<'src>{
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
record
|
||||
.mixins
|
||||
.entry(self.name.clone())
|
||||
.or_insert_with(Default::default);
|
||||
if mem::replace(&mut entry.non_partial, Some(self)).is_some() {
|
||||
warn!(
|
||||
"Encounterd multiple declarations of {}, using last encountered",
|
||||
self.name
|
||||
);
|
||||
}
|
||||
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(Default::default)
|
||||
.push(&self.members.body);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::PartialMixin {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
let entry = record
|
||||
impl<'src> FirstPass<'src, ()> for weedle::PartialInterfaceMixinDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
record
|
||||
.mixins
|
||||
.entry(self.name.clone())
|
||||
.or_insert_with(Default::default);
|
||||
entry.partials.push(self);
|
||||
|
||||
.entry(self.identifier.0)
|
||||
.or_insert_with(Default::default)
|
||||
.push(&self.members.body);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FirstPass<()> for webidl::ast::Typedef {
|
||||
fn first_pass<'a>(&'a self, record: &mut FirstPassRecord<'a>, (): ()) -> Result<()> {
|
||||
if ::util::is_chrome_only(&self.extended_attributes) {
|
||||
impl<'src> FirstPass<'src, ()> for weedle::TypedefDefinition<'src> {
|
||||
fn first_pass(&'src self, record: &mut FirstPassRecord<'src>, (): ()) -> Result<()> {
|
||||
if util::is_chrome_only(&self.attributes) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if record.typedefs.insert(self.name.clone(), *self.type_.clone()).is_some() {
|
||||
warn!("Encountered multiple declarations of {}", self.name);
|
||||
if record.typedefs.insert(self.identifier.0, &self.type_.type_).is_some() {
|
||||
warn!("Encountered multiple declarations of {}", self.identifier.0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,37 +5,6 @@ controlling precisely how imports are imported and what they map to in JS. This
|
||||
section is intended to hopefully be an exhaustive reference of the
|
||||
possibilities!
|
||||
|
||||
* `module` and `version` - we've seen `module` so far indicating where we can
|
||||
import items from but `version` is also allowed:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(module = "moment", version = "^2.0.0")]
|
||||
extern {
|
||||
type Moment;
|
||||
fn moment() -> Moment;
|
||||
#[wasm_bindgen(method)]
|
||||
fn format(this: &Moment) -> String;
|
||||
}
|
||||
```
|
||||
|
||||
The `module` key is used to configure the module that each item is imported
|
||||
from. The `version` key does not affect the generated wasm itself but rather
|
||||
it's an informative directive for tools like [wasm-pack]. Tools like wasm-pack
|
||||
will generate a `package.json` for you and the `version` listed here, when
|
||||
`module` is also an NPM package, will correspond to what to write down in
|
||||
`package.json`.
|
||||
|
||||
In other words the usage of `module` as the name of an NPM package and
|
||||
`version` as the version requirement allows you to, inline in Rust, depend on
|
||||
the NPM ecosystem and import functionality from those packages. When bundled
|
||||
with a tool like [wasm-pack] everything will automatically get wired up with
|
||||
bundlers and you should be good to go!
|
||||
|
||||
Note that the `version` is *required* if `module` doesn't start with `./`. If
|
||||
`module` starts with `./` then it is an error to provide a version.
|
||||
|
||||
[wasm-pack]: https://github.com/rustwasm/wasm-pack
|
||||
|
||||
* `catch` - this attribute allows catching a JS exception. This can be attached
|
||||
to any imported function and the function must return a `Result` where the
|
||||
`Err` payload is a `JsValue`, like so:
|
||||
|
73
package-lock.json
generated
73
package-lock.json
generated
@ -106,9 +106,9 @@
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.5.tgz",
|
||||
"integrity": "sha512-6Qnb1gXbp3g1JX9QVJj3A6ORzc9XCyhokxUKaoonHgNXcQhmk8adhotxfkeK8El9TnFeUuH72yI6jQ5nDJKS6w==",
|
||||
"version": "10.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.5.6.tgz",
|
||||
"integrity": "sha512-c5Z1j1ysgo4878ptz6gxLcgMfJ6Wf908R3l5KAGabr0XJ72ZFmOCgsaodPpNYTfp4iOrSwgTDvR/BxbFfB4zPQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@webassemblyjs/ast": {
|
||||
@ -1759,9 +1759,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.2.0.tgz",
|
||||
"integrity": "sha512-zlggW1qp7/TBjwLfouRoY7eWXrXwJZFqCdIxxh0/LVB/QuuKuIMkzyUZEcDo6LBadsry5JcEMxIqd3H/66CXVg==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-5.3.0.tgz",
|
||||
"integrity": "sha512-N/tCqlMKkyNvAvLu+zI9AqDasnSLt00K+Hu8kdsERliC9jYEc8ck12XtjvOXrBKu8fK6RrBcN9bat6Xk++9jAg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.0",
|
||||
@ -1795,7 +1795,7 @@
|
||||
"path-is-inside": "^1.0.2",
|
||||
"pluralize": "^7.0.0",
|
||||
"progress": "^2.0.0",
|
||||
"regexpp": "^1.1.0",
|
||||
"regexpp": "^2.0.0",
|
||||
"require-uncached": "^1.0.3",
|
||||
"semver": "^5.5.0",
|
||||
"string.prototype.matchall": "^2.0.0",
|
||||
@ -2379,7 +2379,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -2400,12 +2401,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -2420,17 +2423,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -2547,7 +2553,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -2559,6 +2566,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -2573,6 +2581,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -2580,12 +2589,14 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@ -2604,6 +2615,7 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -2684,7 +2696,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -2696,6 +2709,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -2781,7 +2795,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -2817,6 +2832,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -2836,6 +2852,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -2879,12 +2896,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -3225,9 +3244,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.2.tgz",
|
||||
"integrity": "sha512-uoxnT7PYpyEnsja+yX+7v49B7LXxmzDJ2JALqHH3oEGzpM2U1IGcbfnOr8Dt57z3B/UWs7/iAgPFbmye8m4I0g==",
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.3.tgz",
|
||||
"integrity": "sha512-Z/vAH2GGIEATQnBVXMclE2IGV6i0GyVngKThcGZ5kHgHMxLo9Ow2+XHRq1aEKEej5vOF1TPJNbvX6J/anT0M7A==",
|
||||
"dev": true
|
||||
},
|
||||
"immediate": {
|
||||
@ -5020,9 +5039,9 @@
|
||||
}
|
||||
},
|
||||
"regexpp": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
|
||||
"integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==",
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.0.tgz",
|
||||
"integrity": "sha512-g2FAVtR8Uh8GO1Nv5wpxW7VFVwHcCEr4wyA8/MHiRkO8uHoR5ntAA8Uq3P1vvMTX/BeQiRVSpDGLd+Wn5HNOTA==",
|
||||
"dev": true
|
||||
},
|
||||
"remove-trailing-separator": {
|
||||
@ -6379,9 +6398,9 @@
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.16.4",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.4.tgz",
|
||||
"integrity": "sha512-RqUfwp4qMqv3oFwBQQOoK69C2tdu2FHJEqPABPqgjGDvOIOLqkTOhmmdJjpiRabzNAAH1ahmkA3z4xowlHN+VA==",
|
||||
"version": "4.16.5",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.16.5.tgz",
|
||||
"integrity": "sha512-i5cHYHonzSc1zBuwB5MSzW4v9cScZFbprkHK8ZgzPDCRkQXGGpYzPmJhbus5bOrZ0tXTcQp+xyImRSvKb0b+Kw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@webassemblyjs/ast": "1.5.13",
|
||||
|
@ -8,14 +8,14 @@
|
||||
"run-lint-generated-tests": "eslint ./target/generated-tests/*/out*js"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^10.5.5",
|
||||
"@types/node": "^10.5.6",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"eslint": "^5.2.0",
|
||||
"eslint": "^5.3.0",
|
||||
"geckodriver": "^1.12.1",
|
||||
"selenium-webdriver": "^4.0.0-alpha.1",
|
||||
"ts-loader": "^4.4.2",
|
||||
"typescript": "^3.0.1",
|
||||
"webpack": "^4.16.4",
|
||||
"webpack": "^4.16.5",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.5"
|
||||
}
|
||||
|
@ -1,209 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn dependencies_work() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
extern crate dependency;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn return_dep_ty(x: f64) -> dependency::Foo {
|
||||
dependency::Foo(x)
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn takes_own_dep_ty(foo: dependency::Foo) -> f64 {
|
||||
foo.0
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn takes_ref_dep_ty(foo: &dependency::Foo) -> f64 {
|
||||
foo.0
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn takes_mut_dep_ty(foo: &mut dependency::Foo, x: f64) {
|
||||
foo.0 = x;
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.add_local_dependency("dependency", "vendor/dependency")
|
||||
.file(
|
||||
"vendor/dependency/Cargo.toml",
|
||||
&format!(
|
||||
r#"
|
||||
[package]
|
||||
name = "dependency"
|
||||
version = "0.0.1"
|
||||
authors = []
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
"#,
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"vendor/dependency/src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo(pub f64);
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
pub fn new(x: f64) -> Foo { Foo(x) }
|
||||
pub fn get(&self) -> f64 { self.0 }
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
const foo = wasm.return_dep_ty(42);
|
||||
assert.strictEqual(foo.get(), 42);
|
||||
|
||||
const x = wasm.takes_ref_dep_ty(foo);
|
||||
assert.strictEqual(x, 42);
|
||||
|
||||
const y = 1337;
|
||||
wasm.takes_mut_dep_ty(foo, y);
|
||||
assert.strictEqual(foo.get(), y);
|
||||
|
||||
const z = wasm.takes_own_dep_ty(foo);
|
||||
assert.strictEqual(z, y);
|
||||
assert.strictEqual(foo.ptr, 0);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn same_api_two_crates() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
extern crate a;
|
||||
extern crate b;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "./foo")]
|
||||
extern {
|
||||
fn assert_next_undefined();
|
||||
fn assert_next_ten();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
assert_next_undefined();
|
||||
a::test();
|
||||
assert_next_ten();
|
||||
b::test();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
import { strictEqual } from "assert";
|
||||
|
||||
let next = null;
|
||||
|
||||
export function assert_next_undefined() {
|
||||
next = undefined;
|
||||
}
|
||||
|
||||
export function assert_next_ten() {
|
||||
next = 10;
|
||||
}
|
||||
|
||||
export function foo(a) {
|
||||
console.log(a, next);
|
||||
strictEqual(a, next);
|
||||
next = null;
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.add_local_dependency("a", "a")
|
||||
.file(
|
||||
"a/Cargo.toml",
|
||||
&format!(r#"
|
||||
[package]
|
||||
name = 'a'
|
||||
version = '0.0.0'
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
"#,
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"a/src/lib.rs",
|
||||
"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = \"./foo\")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
foo();
|
||||
}
|
||||
",
|
||||
)
|
||||
.add_local_dependency("b", "b")
|
||||
.file(
|
||||
"b/Cargo.toml",
|
||||
&format!(r#"
|
||||
[package]
|
||||
name = 'b'
|
||||
version = '0.0.0'
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = {{ path = '{}' }}
|
||||
"#,
|
||||
env!("CARGO_MANIFEST_DIR")
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"b/src/lib.rs",
|
||||
"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = \"./foo\")]
|
||||
extern {
|
||||
fn foo(x: u32);
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
foo(10);
|
||||
}
|
||||
",
|
||||
)
|
||||
.test();
|
||||
}
|
@ -1,88 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn unused_imports_not_generated() {
|
||||
let mut project = project();
|
||||
|
||||
project
|
||||
.debug(false)
|
||||
.file("src/lib.rs", r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
pub fn foo();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn run() {
|
||||
}
|
||||
"#)
|
||||
.file("test.js", r#"
|
||||
import { run } from "./out";
|
||||
|
||||
export function test() {
|
||||
run();
|
||||
}
|
||||
"#)
|
||||
.test();
|
||||
|
||||
let contents = project.read_js();
|
||||
assert!(contents.contains("run"), "didn't find `run` in {}", contents);
|
||||
assert!(!contents.contains("foo"), "found `foo` in {}", contents);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn versions() {
|
||||
project()
|
||||
.debug(false)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "webpack", version = "^0.2.0")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn run() {
|
||||
foo();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as fs from 'fs';
|
||||
import * as assert from 'assert';
|
||||
|
||||
export function test() {
|
||||
const bytes = fs.readFileSync('out_bg.wasm');
|
||||
const m = new WebAssembly.Module(bytes);
|
||||
const name = '__wasm_pack_unstable';
|
||||
const sections = WebAssembly.Module.customSections(m, name);
|
||||
assert.strictEqual(sections.length, 1);
|
||||
const b = new Uint8Array(sections[0]);
|
||||
const buf = new Buffer(b);
|
||||
const map = JSON.parse(buf.toString());
|
||||
assert.deepStrictEqual(map, {
|
||||
version: '0.0.1',
|
||||
modules: [
|
||||
['webpack', '^0.2.0']
|
||||
]
|
||||
});
|
||||
};
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn serde() {
|
||||
project()
|
||||
.serde(true)
|
||||
.depend("serde = '1.0'")
|
||||
.depend("serde_derive = '1.0'")
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Foo {
|
||||
a: u32,
|
||||
b: String,
|
||||
c: Option<Bar>,
|
||||
d: Bar,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Bar {
|
||||
a: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen(module = "./test")]
|
||||
extern {
|
||||
fn verify(a: JsValue) -> JsValue;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn run() {
|
||||
let js = JsValue::from_serde("foo").unwrap();
|
||||
assert_eq!(js.as_string(), Some("foo".to_string()));
|
||||
|
||||
let ret = verify(JsValue::from_serde(&Foo {
|
||||
a: 0,
|
||||
b: "foo".to_string(),
|
||||
c: None,
|
||||
d: Bar { a: 1 },
|
||||
}).unwrap());
|
||||
|
||||
let foo = ret.into_serde::<Foo>().unwrap();
|
||||
assert_eq!(foo.a, 2);
|
||||
assert_eq!(foo.b, "bar");
|
||||
assert!(foo.c.is_some());
|
||||
assert_eq!(foo.c.as_ref().unwrap().a, 3);
|
||||
assert_eq!(foo.d.a, 4);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn parse(j: &JsValue) {
|
||||
let s = j.into_serde::<String>().unwrap();
|
||||
assert_eq!(s, "bar");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import { run, parse } from "./out";
|
||||
import * as assert from "assert";
|
||||
|
||||
export function verify(a) {
|
||||
assert.deepStrictEqual(a, {
|
||||
a: 0,
|
||||
b: 'foo',
|
||||
c: null,
|
||||
d: { a: 1 }
|
||||
});
|
||||
|
||||
return {
|
||||
a: 2,
|
||||
b: 'bar',
|
||||
c: { a: 3 },
|
||||
d: { a: 4 },
|
||||
}
|
||||
}
|
||||
|
||||
export function test() {
|
||||
run();
|
||||
parse('bar');
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -2,14 +2,7 @@
|
||||
|
||||
extern crate wasm_bindgen_test_project_builder as project_builder;
|
||||
|
||||
use project_builder::{project, run};
|
||||
use project_builder::project;
|
||||
|
||||
mod comments;
|
||||
mod dependencies;
|
||||
mod js_objects;
|
||||
mod imports;
|
||||
mod node;
|
||||
mod non_debug;
|
||||
mod non_wasm;
|
||||
mod simple;
|
||||
mod typescript;
|
||||
|
@ -1,161 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
project()
|
||||
.debug(false)
|
||||
.nodejs_experimental_modules(false)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "./test")]
|
||||
extern {
|
||||
static FOO: JsValue;
|
||||
fn hit();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn run() {
|
||||
hit();
|
||||
assert_eq!(FOO.as_f64(), Some(1.0));
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
contents: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
pub fn new() -> Foo {
|
||||
Foo::with_contents(0)
|
||||
}
|
||||
pub fn with_contents(a: u32) -> Foo {
|
||||
Foo { contents: a }
|
||||
}
|
||||
pub fn add(&mut self, amt: u32) -> u32 {
|
||||
self.contents += amt;
|
||||
self.contents
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub enum Color {
|
||||
Green,
|
||||
Yellow,
|
||||
Red,
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn cycle(color: Color) -> Color {
|
||||
match color {
|
||||
Color::Green => Color::Yellow,
|
||||
Color::Yellow => Color::Red,
|
||||
Color::Red => Color::Green,
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn math(a: f32, b: f64) -> f64 {
|
||||
b.acos() +
|
||||
b.asin() +
|
||||
b.atan() +
|
||||
b.atan2(b) +
|
||||
b.cbrt() +
|
||||
b.cosh() +
|
||||
b.exp_m1() +
|
||||
b.ln_1p() +
|
||||
b.sinh() +
|
||||
b.tan() +
|
||||
b.tanh() +
|
||||
b.hypot(b) +
|
||||
b.cos() +
|
||||
b.exp() +
|
||||
b.exp2() +
|
||||
b.mul_add(b, b) +
|
||||
b.ln() +
|
||||
b.log(b) +
|
||||
b.log10() +
|
||||
b.log2() +
|
||||
b.powi(8) +
|
||||
b.powf(b) +
|
||||
b.round() +
|
||||
b.sin() +
|
||||
b.abs() +
|
||||
b.signum() +
|
||||
b.floor() +
|
||||
b.ceil() +
|
||||
b.trunc() +
|
||||
b.sqrt() +
|
||||
(b % (a as f64)) +
|
||||
((a.cos() +
|
||||
a.exp() +
|
||||
a.exp2() +
|
||||
a.mul_add(a, a) +
|
||||
a.ln() +
|
||||
a.log(a) +
|
||||
a.log10() +
|
||||
a.log2() +
|
||||
a.powi(8) +
|
||||
a.powf(a) +
|
||||
a.round() +
|
||||
a.sin() +
|
||||
a.abs() +
|
||||
a.signum() +
|
||||
a.floor() +
|
||||
a.ceil() +
|
||||
a.trunc() +
|
||||
a.sqrt() +
|
||||
(a % (b as f32))) as f64) +
|
||||
(b + 2.0f64.powf(a as f64))
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
const assert = require('assert');
|
||||
|
||||
var called = false;
|
||||
|
||||
module.exports.hit = function() {
|
||||
called = true;
|
||||
};
|
||||
|
||||
module.exports.FOO = 1.0;
|
||||
|
||||
const { math, run, Foo, Color, cycle } = require('./out');
|
||||
|
||||
module.exports.test = function() {
|
||||
run();
|
||||
assert.strictEqual(called, true);
|
||||
|
||||
var r = Foo.new();
|
||||
assert.strictEqual(r.add(0), 0);
|
||||
assert.strictEqual(r.add(1), 1);
|
||||
assert.strictEqual(r.add(2), 3);
|
||||
r.free();
|
||||
|
||||
var r2 = Foo.with_contents(10);
|
||||
assert.strictEqual(r2.add(0), 10);
|
||||
assert.strictEqual(r2.add(1), 11);
|
||||
assert.strictEqual(r2.add(2), 13);
|
||||
r2.free();
|
||||
|
||||
assert.strictEqual(Color.Green, 0);
|
||||
assert.strictEqual(Color.Yellow, 1);
|
||||
assert.strictEqual(Color.Red, 2);
|
||||
assert.strictEqual(Object.keys(Color).length, 3);
|
||||
assert.strictEqual(cycle(Color.Green), Color.Yellow);
|
||||
|
||||
math(1.0, 2.0);
|
||||
};
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
project()
|
||||
.debug(false)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn new() -> A {
|
||||
A {}
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn clone(a: &JsValue) -> JsValue {
|
||||
drop(a.clone());
|
||||
a.clone()
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
let sym = Symbol('a');
|
||||
assert.strictEqual(wasm.clone(sym), sym);
|
||||
let a = wasm.A.new();
|
||||
a.free();
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
use super::{project, run};
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
fn works() {
|
||||
let mut p = project();
|
||||
let name = p.crate_name();
|
||||
p.rlib(true)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {
|
||||
x: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn new() -> A {
|
||||
A { x: 3 }
|
||||
}
|
||||
|
||||
pub fn foo(&self) {
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(x: bool) {
|
||||
A::new().foo();
|
||||
|
||||
if x {
|
||||
bar("test");
|
||||
baz(JsValue::from(3));
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn some_import();
|
||||
static A: JsValue;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn bar(_: &str) -> JsValue {
|
||||
some_import();
|
||||
A.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn baz(_: JsValue) {
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"tests/foo.rs",
|
||||
&format!(
|
||||
"
|
||||
extern crate {} as mytest;
|
||||
|
||||
#[test]
|
||||
fn foo() {{
|
||||
mytest::foo(false);
|
||||
mytest::A::new().foo();
|
||||
}}
|
||||
",
|
||||
name
|
||||
),
|
||||
)
|
||||
.file(
|
||||
"benches/foo.rs",
|
||||
&format!(
|
||||
"
|
||||
#![feature(test)]
|
||||
extern crate test;
|
||||
extern crate {} as mytest;
|
||||
|
||||
#[bench]
|
||||
fn foo(b: &mut test::Bencher) {{
|
||||
b.iter(|| mytest::foo(false));
|
||||
}}
|
||||
",
|
||||
name
|
||||
),
|
||||
);
|
||||
let (root, target_dir) = p.build();
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("test")
|
||||
.arg("--test")
|
||||
.arg("foo")
|
||||
.arg("--bench")
|
||||
.arg("foo")
|
||||
.current_dir(&root)
|
||||
.env("CARGO_TARGET_DIR", &target_dir);
|
||||
run(&mut cmd, "cargo");
|
||||
}
|
@ -1,564 +0,0 @@
|
||||
use super::project;
|
||||
|
||||
#[test]
|
||||
fn add() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn add(a: u32, b: u32) -> u32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn add3(a: u32) -> u32 {
|
||||
a + 3
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn get2(_b: bool) -> u32 {
|
||||
2
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn return_and_take_bool(a: bool, b: bool) -> bool {
|
||||
a && b
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 {
|
||||
unsafe {
|
||||
(*a) = (*b) as u32;
|
||||
return a
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.strictEqual(wasm.add(1, 2), 3);
|
||||
assert.strictEqual(wasm.add(2, 3), 5);
|
||||
assert.strictEqual(wasm.add3(2), 5);
|
||||
assert.strictEqual(wasm.get2(true), 2);
|
||||
assert.strictEqual(wasm.return_and_take_bool(true, false), false);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn add_headless() {
|
||||
project()
|
||||
.headless(true)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn add(a: u32, b: u32) -> u32 {
|
||||
a + b
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
console.log("start `add_headless` test");
|
||||
assert.strictEqual(wasm.add(1, 2), 3);
|
||||
console.log("end `add_headless` test");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn string_arguments() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn assert_foo_and_bar(a: &str, b: &str) {
|
||||
assert_eq!(a, "foo2");
|
||||
assert_eq!(b, "bar");
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn assert_foo(a: &str) {
|
||||
assert_eq!(a, "foo");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
wasm.assert_foo("foo");
|
||||
wasm.assert_foo_and_bar("foo2", "bar");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn return_a_string() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn clone(a: &str) -> String {
|
||||
a.to_string()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn concat(a: &str, b: &str, c: i8) -> String {
|
||||
format!("{} {} {}", a, b, c)
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.strictEqual(wasm.clone("foo"), "foo");
|
||||
assert.strictEqual(wasm.clone("another"), "another");
|
||||
assert.strictEqual(wasm.concat("a", "b", 3), "a b 3");
|
||||
assert.strictEqual(wasm.concat("c", "d", -2), "c d -2");
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exceptions() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn bar(_a: &str) {}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.throws(() => wasm.foo('a'), /expected a number argument/);
|
||||
assert.throws(() => wasm.bar(3), /expected a string argument/);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn other_imports() {
|
||||
// project()
|
||||
// .file("src/lib.rs", r#"
|
||||
// #![feature(use_extern_macros)]
|
||||
//
|
||||
// extern crate wasm_bindgen;
|
||||
//
|
||||
// use wasm_bindgen::prelude::*;
|
||||
//
|
||||
// extern {
|
||||
// fn another_import(a: u32);
|
||||
// }
|
||||
//
|
||||
// wasm_bindgen! {
|
||||
// pub fn foo(a: u32) {
|
||||
// unsafe { another_import(a); }
|
||||
// }
|
||||
// }
|
||||
// "#)
|
||||
// .file("test.js", r#"
|
||||
// import * as assert from "assert";
|
||||
// import * as wasm from "./out";
|
||||
//
|
||||
// let ARG: number | null = null;
|
||||
//
|
||||
// export function test() {
|
||||
// wasm.foo(2);
|
||||
// assert.strictEqual(ARG, 2);
|
||||
// }
|
||||
// "#)
|
||||
// .test();
|
||||
// }
|
||||
|
||||
#[test]
|
||||
fn other_exports() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#[no_mangle]
|
||||
pub extern fn foo(_a: u32) {
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as wasm from "./out_bg";
|
||||
|
||||
export function test() {
|
||||
wasm.foo(2);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_std() {
|
||||
project()
|
||||
.no_std(true)
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
extern crate std as _some_other_name;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "./foo")]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method)]
|
||||
fn init(this: &Js);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as wasm from "./out_bg";
|
||||
|
||||
export function test() {
|
||||
// mostly just testing the project compiles here
|
||||
wasm.foo(1);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
export class Js {
|
||||
init() {
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_std_class() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
#![no_std]
|
||||
#![allow(dead_code)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
extern crate std as _some_other_name;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method, structural)]
|
||||
fn init(this: &Js);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn foo(&self) {}
|
||||
pub fn bar(&mut self) {}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as wasm from "./out_bg";
|
||||
|
||||
export function test() {
|
||||
// mostly just testing the project compiles here
|
||||
wasm.foo(1);
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn jsvalue_typeof() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_object(val: &JsValue) -> bool {
|
||||
val.is_object()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_function(val: &JsValue) -> bool {
|
||||
val.is_function()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_string(val: &JsValue) -> bool {
|
||||
val.is_string()
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"test.js",
|
||||
r#"
|
||||
import * as assert from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function test() {
|
||||
assert.ok(wasm.is_object({}));
|
||||
assert.ok(!wasm.is_object(42));
|
||||
assert.ok(wasm.is_function(function() {}));
|
||||
assert.ok(!wasm.is_function(42));
|
||||
assert.ok(wasm.is_string("2b or !2b"));
|
||||
assert.ok(!wasm.is_string(42));
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn binding_to_unimplemented_apis_doesnt_break_everything() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
#[derive(Clone)]
|
||||
type Array;
|
||||
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Array;
|
||||
|
||||
#[wasm_bindgen(method, catch)]
|
||||
fn standardized_method_this_js_runtime_doesnt_implement_yet(this: &Array)
|
||||
-> Result<(), JsValue>;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
let array = Array::new();
|
||||
let res = array.standardized_method_this_js_runtime_doesnt_implement_yet();
|
||||
assert!(res.is_err());
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.test();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn optional_slices() {
|
||||
project()
|
||||
.file(
|
||||
"src/lib.rs",
|
||||
r#"
|
||||
#![feature(use_extern_macros, wasm_custom_section)]
|
||||
extern crate wasm_bindgen;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "./foo")]
|
||||
extern {
|
||||
fn optional_str_none(a: Option<&str>);
|
||||
fn optional_str_some(a: Option<&str>);
|
||||
fn optional_slice_none(a: Option<&[u8]>);
|
||||
fn optional_slice_some(a: Option<&[u8]>);
|
||||
|
||||
fn optional_string_none(a: Option<String>);
|
||||
fn optional_string_some(a: Option<String>);
|
||||
fn optional_string_some_empty(a: Option<String>);
|
||||
|
||||
fn return_string_none() -> Option<String>;
|
||||
fn return_string_some() -> Option<String>;
|
||||
|
||||
fn run_rust_tests();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn test() {
|
||||
optional_str_none(None);
|
||||
optional_str_some(Some("x"));
|
||||
optional_slice_none(None);
|
||||
optional_slice_some(Some(&[1, 2, 3]));
|
||||
optional_string_none(None);
|
||||
optional_string_some_empty(Some(String::new()));
|
||||
optional_string_some(Some("abcd".to_string()));
|
||||
|
||||
assert_eq!(return_string_none(), None);
|
||||
assert_eq!(return_string_some(), Some("foo".to_string()));
|
||||
run_rust_tests();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn take_optional_str_none(x: Option<String>) {
|
||||
assert!(x.is_none())
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn take_optional_str_some(x: Option<String>) {
|
||||
assert_eq!(x, Some(String::from("hello")));
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn return_optional_str_none() -> Option<String> {
|
||||
None
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn return_optional_str_some() -> Option<String> {
|
||||
Some("world".to_string())
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.file(
|
||||
"foo.js",
|
||||
r#"
|
||||
import { strictEqual } from "assert";
|
||||
import * as wasm from "./out";
|
||||
|
||||
export function optional_str_none(x) {
|
||||
strictEqual(x, undefined);
|
||||
}
|
||||
|
||||
export function optional_str_some(x) {
|
||||
strictEqual(x, 'x');
|
||||
}
|
||||
|
||||
export function optional_slice_none(x) {
|
||||
strictEqual(x, undefined);
|
||||
}
|
||||
|
||||
export function optional_slice_some(x) {
|
||||
strictEqual(x.length, 3);
|
||||
strictEqual(x[0], 1);
|
||||
strictEqual(x[1], 2);
|
||||
strictEqual(x[2], 3);
|
||||
}
|
||||
|
||||
export function optional_string_none(x) {
|
||||
strictEqual(x, undefined);
|
||||
}
|
||||
|
||||
export function optional_string_some(x) {
|
||||
strictEqual(x, 'abcd');
|
||||
}
|
||||
|
||||
export function optional_string_some_empty(x) {
|
||||
strictEqual(x, '');
|
||||
}
|
||||
|
||||
export function return_string_none() {}
|
||||
export function return_string_some() {
|
||||
return 'foo';
|
||||
}
|
||||
|
||||
export function run_rust_tests() {
|
||||
wasm.take_optional_str_none();
|
||||
wasm.take_optional_str_none(null);
|
||||
wasm.take_optional_str_none(undefined);
|
||||
wasm.take_optional_str_some('hello');
|
||||
strictEqual(wasm.return_optional_str_none(), undefined);
|
||||
strictEqual(wasm.return_optional_str_some(), 'world');
|
||||
}
|
||||
"#
|
||||
)
|
||||
.test();
|
||||
}
|
9
tests/crates/a/Cargo.toml
Normal file
9
tests/crates/a/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "wasm-bindgen-test-crate-a"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Authors"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "internal test crate for wasm-bindgen"
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = { path = '../../..', version = '0.2' }
|
14
tests/crates/a/src/lib.rs
Normal file
14
tests/crates/a/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicate_deps.js")]
|
||||
extern {
|
||||
fn foo();
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
foo();
|
||||
}
|
9
tests/crates/b/Cargo.toml
Normal file
9
tests/crates/b/Cargo.toml
Normal file
@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "wasm-bindgen-test-crate-b"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Authors"]
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "internal test crate for wasm-bindgen"
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = { path = '../../..', version = '0.2' }
|
14
tests/crates/b/src/lib.rs
Normal file
14
tests/crates/b/src/lib.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicate_deps.js")]
|
||||
extern {
|
||||
fn foo(x: u32);
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
foo(10);
|
||||
}
|
10
tests/no-std/Cargo.toml
Normal file
10
tests/no-std/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "no-std"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
|
||||
[lib]
|
||||
path = "test.rs"
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = { path = '../..', default-features = false }
|
0
tests/no-std/lib.rs
Normal file
0
tests/no-std/lib.rs
Normal file
28
tests/no-std/test.rs
Normal file
28
tests/no-std/test.rs
Normal file
@ -0,0 +1,28 @@
|
||||
//! This is a test that we compile `wasm-bindgen` itself in `no_std` mode and we
|
||||
//! can export/import various items.
|
||||
//!
|
||||
//! 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)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
extern crate std as _some_other_name;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(_a: u32) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method, structural)]
|
||||
fn init(this: &Js);
|
||||
}
|
53
tests/non_wasm.rs
Normal file
53
tests/non_wasm.rs
Normal file
@ -0,0 +1,53 @@
|
||||
#![feature(use_extern_macros)]
|
||||
|
||||
extern crate wasm_bindgen;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {
|
||||
x: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn new() -> A {
|
||||
A { x: 3 }
|
||||
}
|
||||
|
||||
pub fn foo(&self) {
|
||||
drop(self.x);
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(x: bool) {
|
||||
A::new().foo();
|
||||
|
||||
if x {
|
||||
bar("test");
|
||||
baz(JsValue::from(3));
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn some_import();
|
||||
static A: JsValue;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn bar(_: &str) -> JsValue {
|
||||
some_import();
|
||||
A.clone()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn baz(_: JsValue) {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_foo() {
|
||||
foo(false);
|
||||
A::new().foo();
|
||||
}
|
30
tests/std-crate-no-std-dep.rs
Normal file
30
tests/std-crate-no-std-dep.rs
Normal file
@ -0,0 +1,30 @@
|
||||
//! This is a test that we can define items in a `#![no_std]` crate when
|
||||
//! `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;
|
||||
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
fn test(a: &str);
|
||||
|
||||
type Js;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Js;
|
||||
#[wasm_bindgen(method, structural)]
|
||||
fn init(this: &Js);
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct A {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl A {
|
||||
pub fn foo(&self) {}
|
||||
pub fn bar(&mut self) {}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/api.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/api.js")]
|
||||
extern {
|
||||
fn js_works();
|
||||
fn js_eq_works();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/char.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/char.js")]
|
||||
extern {
|
||||
fn js_identity(c: char) -> char;
|
||||
fn js_works();
|
||||
|
@ -31,6 +31,10 @@ exports.js_strings = () => {
|
||||
};
|
||||
|
||||
exports.js_exceptions = () => {
|
||||
// this test only works when `--debug` is passed to `wasm-bindgen` (or the
|
||||
// equivalent thereof)
|
||||
if (require('process').env.WASM_BINDGEN_NO_DEBUG)
|
||||
return;
|
||||
assert.throws(() => new wasm.ClassesExceptions1(), /cannot invoke `new` directly/);
|
||||
let a = wasm.ClassesExceptions1.new();
|
||||
a.free();
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/classes.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/classes.js")]
|
||||
extern {
|
||||
fn js_simple();
|
||||
fn js_strings();
|
||||
|
@ -3,7 +3,7 @@ use wasm_bindgen::prelude::*;
|
||||
use std::cell::Cell;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/closures.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/closures.js")]
|
||||
extern {
|
||||
fn works_call(a: &Fn());
|
||||
fn works_thread(a: &Fn(u32) -> u32) -> u32;
|
||||
|
17
tests/wasm/duplicate_deps.js
Normal file
17
tests/wasm/duplicate_deps.js
Normal file
@ -0,0 +1,17 @@
|
||||
const assert = require('assert');
|
||||
|
||||
let next = null;
|
||||
|
||||
exports.assert_next_undefined = function() {
|
||||
next = undefined;
|
||||
};
|
||||
|
||||
exports.assert_next_ten = function() {
|
||||
next = 10;
|
||||
};
|
||||
|
||||
exports.foo = function(a) {
|
||||
console.log(a, next);
|
||||
assert.strictEqual(a, next);
|
||||
next = null;
|
||||
};
|
18
tests/wasm/duplicate_deps.rs
Normal file
18
tests/wasm/duplicate_deps.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen_test_crate_a as a;
|
||||
use wasm_bindgen_test_crate_b as b;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicate_deps.js")]
|
||||
extern {
|
||||
fn assert_next_undefined();
|
||||
fn assert_next_ten();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn works() {
|
||||
assert_next_undefined();
|
||||
a::test();
|
||||
assert_next_ten();
|
||||
b::test();
|
||||
}
|
@ -3,7 +3,7 @@ use wasm_bindgen_test::*;
|
||||
pub mod same_function_different_locations_a {
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_a.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_a.js")]
|
||||
extern {
|
||||
pub fn foo();
|
||||
}
|
||||
@ -12,7 +12,7 @@ pub mod same_function_different_locations_a {
|
||||
pub mod same_function_different_locations_b {
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_a.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_a.js")]
|
||||
extern {
|
||||
pub fn foo();
|
||||
}
|
||||
@ -27,7 +27,7 @@ fn same_function_different_locations() {
|
||||
pub mod same_function_different_modules_a {
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_b.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_b.js")]
|
||||
extern {
|
||||
pub fn foo() -> bool;
|
||||
}
|
||||
@ -36,7 +36,7 @@ pub mod same_function_different_modules_a {
|
||||
pub mod same_function_different_modules_b {
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_c.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/duplicates_c.js")]
|
||||
extern {
|
||||
pub fn foo() -> bool;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use self::inner::ColorWithCustomValues;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/enums.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/enums.js")]
|
||||
extern {
|
||||
fn js_c_style_enum();
|
||||
fn js_c_style_enum_with_custom_values();
|
||||
|
@ -5,7 +5,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/import_class.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/import_class.js")]
|
||||
extern {
|
||||
fn math_log(f: f64) -> f64;
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
const assert = require('assert');
|
||||
const wasm = require('wasm-bindgen-test');
|
||||
const fs = require('fs');
|
||||
|
||||
let ARG = null;
|
||||
let ANOTHER_ARG = null;
|
||||
@ -90,3 +91,12 @@ exports.touch_custom_type = function() {
|
||||
exports.interpret_2_as_custom_type = function() {
|
||||
assert.throws(wasm.interpret_2_as_custom_type, /expected value of type CustomType/);
|
||||
};
|
||||
|
||||
exports.baz$ = function() {};
|
||||
exports.$foo = 1.0;
|
||||
|
||||
exports.assert_dead_import_not_generated = function() {
|
||||
const filename = require.resolve("wasm-bindgen-test");
|
||||
const bindings = fs.readFileSync(filename);
|
||||
assert.ok(!bindings.includes("unused_import"));
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/imports.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/imports.js")]
|
||||
extern {
|
||||
fn test_simple();
|
||||
|
||||
@ -42,6 +42,14 @@ extern {
|
||||
fn custom_type_return_2() -> CustomType;
|
||||
#[wasm_bindgen(js_name = interpret_2_as_custom_type)]
|
||||
fn js_interpret_2_as_custom_type();
|
||||
|
||||
#[wasm_bindgen(js_name = "baz$")]
|
||||
fn renamed_with_dollar_sign();
|
||||
#[wasm_bindgen(js_name = "$foo")]
|
||||
static RENAMED: JsValue;
|
||||
|
||||
fn unused_import();
|
||||
fn assert_dead_import_not_generated();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@ -153,3 +161,18 @@ impl CustomType {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn rename_with_string() {
|
||||
renamed_with_dollar_sign();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn rename_static_with_string() {
|
||||
assert_eq!(RENAMED.as_f64(), Some(1.0));
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn dead_imports_not_generated() {
|
||||
assert_dead_import_not_generated();
|
||||
}
|
||||
|
@ -82,3 +82,19 @@ exports.js_returning_vector = () => {
|
||||
exports.js_another_vector_return = () => {
|
||||
assert.deepStrictEqual(wasm.another_vector_return_get_array(), [1, 2, 3, 4, 5, 6]);
|
||||
};
|
||||
|
||||
exports.verify_serde = function(a) {
|
||||
assert.deepStrictEqual(a, {
|
||||
a: 0,
|
||||
b: 'foo',
|
||||
c: null,
|
||||
d: { a: 1 }
|
||||
});
|
||||
|
||||
return {
|
||||
a: 2,
|
||||
b: 'bar',
|
||||
c: { a: 3 },
|
||||
d: { a: 4 },
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/js_objects.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/js_objects.js")]
|
||||
extern {
|
||||
fn simple_foo(s: &JsValue);
|
||||
fn js_simple();
|
||||
@ -26,6 +26,7 @@ extern {
|
||||
fn js_returning_vector();
|
||||
|
||||
fn js_another_vector_return();
|
||||
fn verify_serde(val: JsValue) -> JsValue;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
@ -105,3 +106,40 @@ pub fn another_vector_return_get_array() -> Vec<JsValue> {
|
||||
fn another_vector_return() {
|
||||
js_another_vector_return();
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde-serialize")]
|
||||
#[wasm_bindgen_test]
|
||||
fn serde() {
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Foo {
|
||||
a: u32,
|
||||
b: String,
|
||||
c: Option<Bar>,
|
||||
d: Bar,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Bar {
|
||||
a: u32,
|
||||
}
|
||||
|
||||
|
||||
let js = JsValue::from_serde("foo").unwrap();
|
||||
assert_eq!(js.as_string(), Some("foo".to_string()));
|
||||
|
||||
let ret = verify_serde(JsValue::from_serde(&Foo {
|
||||
a: 0,
|
||||
b: "foo".to_string(),
|
||||
c: None,
|
||||
d: Bar { a: 1 },
|
||||
}).unwrap());
|
||||
|
||||
let foo = ret.into_serde::<Foo>().unwrap();
|
||||
assert_eq!(foo.a, 2);
|
||||
assert_eq!(foo.b, "bar");
|
||||
assert!(foo.c.is_some());
|
||||
assert_eq!(foo.c.as_ref().unwrap().a, 3);
|
||||
assert_eq!(foo.d.a, 4);
|
||||
|
||||
assert_eq!(JsValue::from("bar").into_serde::<String>().unwrap(), "bar");
|
||||
}
|
||||
|
@ -3,19 +3,28 @@
|
||||
|
||||
extern crate wasm_bindgen_test;
|
||||
extern crate wasm_bindgen;
|
||||
extern crate wasm_bindgen_test_crate_a;
|
||||
extern crate wasm_bindgen_test_crate_b;
|
||||
|
||||
#[cfg(feature = "serde-serialize")]
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
||||
pub mod api;
|
||||
pub mod char;
|
||||
pub mod classes;
|
||||
pub mod closures;
|
||||
pub mod duplicate_deps;
|
||||
pub mod duplicates;
|
||||
pub mod enums;
|
||||
pub mod imports;
|
||||
pub mod import_class;
|
||||
pub mod imports;
|
||||
pub mod js_objects;
|
||||
pub mod math;
|
||||
pub mod node;
|
||||
pub mod option;
|
||||
pub mod optional_primitives;
|
||||
pub mod simple;
|
||||
pub mod slice;
|
||||
pub mod structural;
|
||||
pub mod u64;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/math.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/math.js")]
|
||||
extern {
|
||||
fn js_auto_bind_math();
|
||||
}
|
||||
@ -64,4 +64,4 @@ pub fn math(a: f32, b: f64) -> f64 {
|
||||
#[wasm_bindgen_test]
|
||||
fn auto_bind_math() {
|
||||
js_auto_bind_math();
|
||||
}
|
||||
}
|
||||
|
34
tests/wasm/node.js
Normal file
34
tests/wasm/node.js
Normal file
@ -0,0 +1,34 @@
|
||||
const assert = require('assert');
|
||||
const wasm = require('wasm-bindgen-test');
|
||||
|
||||
var called = false;
|
||||
|
||||
exports.hit = function() {
|
||||
called = true;
|
||||
};
|
||||
|
||||
exports.FOO = 1.0;
|
||||
|
||||
exports.test_works = function() {
|
||||
assert.strictEqual(called, true);
|
||||
|
||||
var r = wasm.Foo.new();
|
||||
assert.strictEqual(r.add(0), 0);
|
||||
assert.strictEqual(r.add(1), 1);
|
||||
assert.strictEqual(r.add(2), 3);
|
||||
r.free();
|
||||
|
||||
var r2 = wasm.Foo.with_contents(10);
|
||||
assert.strictEqual(r2.add(0), 10);
|
||||
assert.strictEqual(r2.add(1), 11);
|
||||
assert.strictEqual(r2.add(2), 13);
|
||||
r2.free();
|
||||
|
||||
assert.strictEqual(wasm.Color.Green, 0);
|
||||
assert.strictEqual(wasm.Color.Yellow, 1);
|
||||
assert.strictEqual(wasm.Color.Red, 2);
|
||||
assert.strictEqual(Object.keys(wasm.Color).length, 3);
|
||||
assert.strictEqual(wasm.cycle(wasm.Color.Green), wasm.Color.Yellow);
|
||||
|
||||
wasm.node_math(1.0, 2.0);
|
||||
};
|
105
tests/wasm/node.rs
Normal file
105
tests/wasm/node.rs
Normal file
@ -0,0 +1,105 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/node.js")]
|
||||
extern {
|
||||
fn test_works();
|
||||
static FOO: JsValue;
|
||||
fn hit();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn works() {
|
||||
hit();
|
||||
assert_eq!(FOO.as_f64(), Some(1.0));
|
||||
test_works();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
contents: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
pub fn new() -> Foo {
|
||||
Foo::with_contents(0)
|
||||
}
|
||||
pub fn with_contents(a: u32) -> Foo {
|
||||
Foo { contents: a }
|
||||
}
|
||||
pub fn add(&mut self, amt: u32) -> u32 {
|
||||
self.contents += amt;
|
||||
self.contents
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub enum Color {
|
||||
Green,
|
||||
Yellow,
|
||||
Red,
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn cycle(color: Color) -> Color {
|
||||
match color {
|
||||
Color::Green => Color::Yellow,
|
||||
Color::Yellow => Color::Red,
|
||||
Color::Red => Color::Green,
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn node_math(a: f32, b: f64) -> f64 {
|
||||
b.acos() +
|
||||
b.asin() +
|
||||
b.atan() +
|
||||
b.atan2(b) +
|
||||
b.cbrt() +
|
||||
b.cosh() +
|
||||
b.exp_m1() +
|
||||
b.ln_1p() +
|
||||
b.sinh() +
|
||||
b.tan() +
|
||||
b.tanh() +
|
||||
b.hypot(b) +
|
||||
b.cos() +
|
||||
b.exp() +
|
||||
b.exp2() +
|
||||
b.mul_add(b, b) +
|
||||
b.ln() +
|
||||
b.log(b) +
|
||||
b.log10() +
|
||||
b.log2() +
|
||||
b.powi(8) +
|
||||
b.powf(b) +
|
||||
b.round() +
|
||||
b.sin() +
|
||||
b.abs() +
|
||||
b.signum() +
|
||||
b.floor() +
|
||||
b.ceil() +
|
||||
b.trunc() +
|
||||
b.sqrt() +
|
||||
(b % (a as f64)) +
|
||||
((a.cos() +
|
||||
a.exp() +
|
||||
a.exp2() +
|
||||
a.mul_add(a, a) +
|
||||
a.ln() +
|
||||
a.log(a) +
|
||||
a.log10() +
|
||||
a.log2() +
|
||||
a.powi(8) +
|
||||
a.powf(a) +
|
||||
a.round() +
|
||||
a.sin() +
|
||||
a.abs() +
|
||||
a.signum() +
|
||||
a.floor() +
|
||||
a.ceil() +
|
||||
a.trunc() +
|
||||
a.sqrt() +
|
||||
(a % (b as f32))) as f64) +
|
||||
(b + 2.0f64.powf(a as f64))
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/option.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/option.js")]
|
||||
extern {
|
||||
pub type MyType;
|
||||
#[wasm_bindgen(constructor)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/optional_primitives.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/optional_primitives.js")]
|
||||
extern {
|
||||
fn optional_i32_js_identity(a: Option<i32>) -> Option<i32>;
|
||||
fn optional_u32_js_identity(a: Option<u32>) -> Option<u32>;
|
||||
|
89
tests/wasm/simple.js
Normal file
89
tests/wasm/simple.js
Normal file
@ -0,0 +1,89 @@
|
||||
const assert = require('assert');
|
||||
const wasm = require('wasm-bindgen-test');
|
||||
|
||||
exports.test_add = function() {
|
||||
assert.strictEqual(wasm.simple_add(1, 2), 3);
|
||||
assert.strictEqual(wasm.simple_add(2, 3), 5);
|
||||
assert.strictEqual(wasm.simple_add3(2), 5);
|
||||
assert.strictEqual(wasm.simple_get2(true), 2);
|
||||
assert.strictEqual(wasm.simple_return_and_take_bool(true, false), false);
|
||||
};
|
||||
|
||||
exports.test_string_arguments = function() {
|
||||
wasm.simple_assert_foo("foo");
|
||||
wasm.simple_assert_foo_and_bar("foo2", "bar");
|
||||
};
|
||||
|
||||
exports.test_return_a_string = function() {
|
||||
assert.strictEqual(wasm.simple_clone("foo"), "foo");
|
||||
assert.strictEqual(wasm.simple_clone("another"), "another");
|
||||
assert.strictEqual(wasm.simple_concat("a", "b", 3), "a b 3");
|
||||
assert.strictEqual(wasm.simple_concat("c", "d", -2), "c d -2");
|
||||
};
|
||||
|
||||
exports.test_wrong_types = function() {
|
||||
// this test only works when `--debug` is passed to `wasm-bindgen` (or the
|
||||
// equivalent thereof)
|
||||
if (require('process').env.WASM_BINDGEN_NO_DEBUG)
|
||||
return;
|
||||
assert.throws(() => wasm.simple_int('a'), /expected a number argument/);
|
||||
assert.throws(() => wasm.simple_str(3), /expected a string argument/);
|
||||
};
|
||||
|
||||
exports.test_other_exports_still_available = function() {
|
||||
require('wasm-bindgen-test_bg').foo(3);
|
||||
};
|
||||
|
||||
exports.test_jsvalue_typeof = function() {
|
||||
assert.ok(wasm.is_object({}));
|
||||
assert.ok(!wasm.is_object(42));
|
||||
assert.ok(wasm.is_function(function() {}));
|
||||
assert.ok(!wasm.is_function(42));
|
||||
assert.ok(wasm.is_string("2b or !2b"));
|
||||
assert.ok(!wasm.is_string(42));
|
||||
};
|
||||
|
||||
exports.optional_str_none = function(x) {
|
||||
assert.strictEqual(x, undefined);
|
||||
};
|
||||
|
||||
exports.optional_str_some = function(x) {
|
||||
assert.strictEqual(x, 'x');
|
||||
};
|
||||
|
||||
exports.optional_slice_none = function(x) {
|
||||
assert.strictEqual(x, undefined);
|
||||
};
|
||||
|
||||
exports.optional_slice_some = function(x) {
|
||||
assert.strictEqual(x.length, 3);
|
||||
assert.strictEqual(x[0], 1);
|
||||
assert.strictEqual(x[1], 2);
|
||||
assert.strictEqual(x[2], 3);
|
||||
}
|
||||
|
||||
exports.optional_string_none = function(x) {
|
||||
assert.strictEqual(x, undefined);
|
||||
};
|
||||
|
||||
exports.optional_string_some = function(x) {
|
||||
assert.strictEqual(x, 'abcd');
|
||||
};
|
||||
|
||||
exports.optional_string_some_empty = function(x) {
|
||||
assert.strictEqual(x, '');
|
||||
};
|
||||
|
||||
exports.return_string_none = function() {};
|
||||
exports.return_string_some = function() {
|
||||
return 'foo';
|
||||
};
|
||||
|
||||
exports.test_rust_optional = function() {
|
||||
wasm.take_optional_str_none();
|
||||
wasm.take_optional_str_none(null);
|
||||
wasm.take_optional_str_none(undefined);
|
||||
wasm.take_optional_str_some('hello');
|
||||
assert.strictEqual(wasm.return_optional_str_none(), undefined);
|
||||
assert.strictEqual(wasm.return_optional_str_some(), 'world');
|
||||
};
|
180
tests/wasm/simple.rs
Normal file
180
tests/wasm/simple.rs
Normal file
@ -0,0 +1,180 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/simple.js")]
|
||||
extern {
|
||||
fn test_add();
|
||||
fn test_string_arguments();
|
||||
fn test_return_a_string();
|
||||
fn test_wrong_types();
|
||||
fn test_other_exports_still_available();
|
||||
fn test_jsvalue_typeof();
|
||||
|
||||
fn optional_str_none(a: Option<&str>);
|
||||
fn optional_str_some(a: Option<&str>);
|
||||
fn optional_slice_none(a: Option<&[u8]>);
|
||||
fn optional_slice_some(a: Option<&[u8]>);
|
||||
fn optional_string_none(a: Option<String>);
|
||||
fn optional_string_some(a: Option<String>);
|
||||
fn optional_string_some_empty(a: Option<String>);
|
||||
fn return_string_none() -> Option<String>;
|
||||
fn return_string_some() -> Option<String>;
|
||||
fn test_rust_optional();
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn add() {
|
||||
test_add();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_add(a: u32, b: u32) -> u32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_add3(a: u32) -> u32 {
|
||||
a + 3
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_get2(_b: bool) -> u32 {
|
||||
2
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_return_and_take_bool(a: bool, b: bool) -> bool {
|
||||
a && b
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_raw_pointers_work(a: *mut u32, b: *const u8) -> *const u32 {
|
||||
unsafe {
|
||||
(*a) = (*b) as u32;
|
||||
return a
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn string_arguments() {
|
||||
test_string_arguments();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_assert_foo_and_bar(a: &str, b: &str) {
|
||||
assert_eq!(a, "foo2");
|
||||
assert_eq!(b, "bar");
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_assert_foo(a: &str) {
|
||||
assert_eq!(a, "foo");
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn return_a_string() {
|
||||
test_return_a_string();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_clone(a: &str) -> String {
|
||||
a.to_string()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_concat(a: &str, b: &str, c: i8) -> String {
|
||||
format!("{} {} {}", a, b, c)
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn wrong_types() {
|
||||
test_wrong_types();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_int(_a: u32) {}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn simple_str(_a: &str) {}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn other_exports() {
|
||||
test_other_exports_still_available();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn foo(_a: u32) {
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn jsvalue_typeof() {
|
||||
test_jsvalue_typeof();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_object(val: &JsValue) -> bool {
|
||||
val.is_object()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_function(val: &JsValue) -> bool {
|
||||
val.is_function()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn is_string(val: &JsValue) -> bool {
|
||||
val.is_string()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern {
|
||||
#[derive(Clone)]
|
||||
type Array;
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Array;
|
||||
#[wasm_bindgen(method, catch)]
|
||||
fn standardized_method_this_js_runtime_doesnt_implement_yet(this: &Array)
|
||||
-> Result<(), JsValue>;
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn binding_to_unimplemented_apis_doesnt_break_everything() {
|
||||
let array = Array::new();
|
||||
let res = array.standardized_method_this_js_runtime_doesnt_implement_yet();
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn optional_slices() {
|
||||
optional_str_none(None);
|
||||
optional_str_some(Some("x"));
|
||||
optional_slice_none(None);
|
||||
optional_slice_some(Some(&[1, 2, 3]));
|
||||
optional_string_none(None);
|
||||
optional_string_some_empty(Some(String::new()));
|
||||
optional_string_some(Some("abcd".to_string()));
|
||||
|
||||
assert_eq!(return_string_none(), None);
|
||||
assert_eq!(return_string_some(), Some("foo".to_string()));
|
||||
test_rust_optional();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn take_optional_str_none(x: Option<String>) {
|
||||
assert!(x.is_none())
|
||||
|
||||
}
|
||||
#[wasm_bindgen]
|
||||
pub fn take_optional_str_some(x: Option<String>) {
|
||||
assert_eq!(x, Some(String::from("hello")));
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn return_optional_str_none() -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn return_optional_str_some() -> Option<String> {
|
||||
Some("world".to_string())
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js")]
|
||||
extern {
|
||||
fn js_export();
|
||||
|
||||
@ -44,7 +44,7 @@ fn export() {
|
||||
|
||||
macro_rules! import_macro {
|
||||
($(($rust:ident, $js:ident, $i:ident))*) => ($(
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js")]
|
||||
extern {
|
||||
fn $js(a: &[$i]) -> Vec<$i>;
|
||||
}
|
||||
@ -105,7 +105,7 @@ fn pass_array() {
|
||||
macro_rules! import_mut_macro {
|
||||
($(($rust:ident, $js:ident, $i:ident))*) => (
|
||||
$(
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/slice.js")]
|
||||
extern {
|
||||
fn $js(a: &mut [$i]);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/structural.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/structural.js")]
|
||||
extern {
|
||||
fn js_works();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/u64.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/u64.js")]
|
||||
extern {
|
||||
fn i64_js_identity(a: i64) -> i64;
|
||||
fn u64_js_identity(a: u64) -> u64;
|
||||
|
@ -1,7 +1,7 @@
|
||||
use wasm_bindgen_test::*;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/validate_prt.js", version = "*")]
|
||||
#[wasm_bindgen(module = "tests/wasm/validate_prt.js")]
|
||||
extern {
|
||||
fn js_works();
|
||||
}
|
||||
|
40
yarn.lock
40
yarn.lock
@ -78,9 +78,9 @@
|
||||
lodash "^4.2.0"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@types/node@^10.5.5":
|
||||
version "10.5.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.5.tgz#8e84d24e896cd77b0d4f73df274027e3149ec2ba"
|
||||
"@types/node@^10.5.6":
|
||||
version "10.5.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.6.tgz#1640f021dd0eaf12e731e54198c12ad2e020dc8e"
|
||||
|
||||
"@webassemblyjs/ast@1.5.13":
|
||||
version "1.5.13"
|
||||
@ -245,9 +245,9 @@ acorn@^5.0.0, acorn@^5.0.3, acorn@^5.6.0, acorn@^5.6.2:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8"
|
||||
|
||||
adm-zip@0.4.7:
|
||||
version "0.4.7"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.7.tgz#8606c2cbf1c426ce8c8ec00174447fd49b6eafc1"
|
||||
adm-zip@0.4.11:
|
||||
version "0.4.11"
|
||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.11.tgz#2aa54c84c4b01a9d0fb89bb11982a51f13e3d62a"
|
||||
|
||||
ajv-keywords@^3.0.0, ajv-keywords@^3.1.0:
|
||||
version "3.2.0"
|
||||
@ -1267,9 +1267,9 @@ eslint-visitor-keys@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d"
|
||||
|
||||
eslint@^5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.2.0.tgz#3901ae249195d473e633c4acbc370068b1c964dc"
|
||||
eslint@^5.3.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.3.0.tgz#53695aca5213968aacdf970ccb231e42a2b285f8"
|
||||
dependencies:
|
||||
ajv "^6.5.0"
|
||||
babel-code-frame "^6.26.0"
|
||||
@ -1302,7 +1302,7 @@ eslint@^5.2.0:
|
||||
path-is-inside "^1.0.2"
|
||||
pluralize "^7.0.0"
|
||||
progress "^2.0.0"
|
||||
regexpp "^1.1.0"
|
||||
regexpp "^2.0.0"
|
||||
require-uncached "^1.0.3"
|
||||
semver "^5.5.0"
|
||||
string.prototype.matchall "^2.0.0"
|
||||
@ -1651,11 +1651,11 @@ gauge@~2.7.3:
|
||||
strip-ansi "^3.0.1"
|
||||
wide-align "^1.1.0"
|
||||
|
||||
geckodriver@^1.12.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.12.0.tgz#997a1efeca90543192fbcf1eae70d7cb2196330e"
|
||||
geckodriver@^1.12.1:
|
||||
version "1.12.1"
|
||||
resolved "https://registry.yarnpkg.com/geckodriver/-/geckodriver-1.12.1.tgz#f3b2ecd5224f383462f07841f4fdcf5007d1b42d"
|
||||
dependencies:
|
||||
adm-zip "0.4.7"
|
||||
adm-zip "0.4.11"
|
||||
bluebird "3.4.6"
|
||||
got "5.6.0"
|
||||
tar "4.0.2"
|
||||
@ -3271,9 +3271,9 @@ regexp.prototype.flags@^1.2.0:
|
||||
dependencies:
|
||||
define-properties "^1.1.2"
|
||||
|
||||
regexpp@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-1.1.0.tgz#0e3516dd0b7904f413d2d4193dce4618c3a689ab"
|
||||
regexpp@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.0.tgz#b2a7534a85ca1b033bcf5ce9ff8e56d4e0755365"
|
||||
|
||||
remove-trailing-separator@^1.0.1:
|
||||
version "1.1.0"
|
||||
@ -4185,9 +4185,9 @@ webpack-sources@^1.0.1, webpack-sources@^1.1.0:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.6.1"
|
||||
|
||||
webpack@^4.16.4:
|
||||
version "4.16.4"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.4.tgz#6b020f76483bc66339164c296d89978aa100d37a"
|
||||
webpack@^4.16.5:
|
||||
version "4.16.5"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.5.tgz#29fb39462823d7eb8aefcab8b45f7f241db0d092"
|
||||
dependencies:
|
||||
"@webassemblyjs/ast" "1.5.13"
|
||||
"@webassemblyjs/helper-module-context" "1.5.13"
|
||||
|
Loading…
x
Reference in New Issue
Block a user