mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-15 05:51:23 +00:00
Add docs and remove typecheck from variadic attribute
This commit is contained in:
@ -2128,7 +2128,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
|||||||
import.shim,
|
import.shim,
|
||||||
if op.is_static { "" } else { ".call" }
|
if op.is_static { "" } else { ".call" }
|
||||||
))
|
))
|
||||||
>>>>>>> master
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_import_type(
|
fn generate_import_type(
|
||||||
|
@ -1101,60 +1101,6 @@ fn assert_not_variadic(attrs: &BindgenAttrs, span: &dyn ToTokens) -> Result<(),
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks the function signature to ensure it finishes with a slice
|
|
||||||
///
|
|
||||||
/// Example of a valid signature: `fn my_func(arg1: u64, res: &[u64])`.
|
|
||||||
fn assert_last_param_is_slice(decl: &syn::FnDecl) -> Result<(), Diagnostic> {
|
|
||||||
#[inline]
|
|
||||||
fn not_slice_error(tok: &dyn ToTokens) -> Diagnostic {
|
|
||||||
Diagnostic::span_error(tok, "for variadic extern functions, the last argument must be a \
|
|
||||||
slice or `::std::vec::Vec`, to hold the arguments of unknown length")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Is this path `::std::vec::Vec`.
|
|
||||||
///
|
|
||||||
/// I could add `Vec`, but this would break in wierd ways if the user does
|
|
||||||
/// `use SomethingElse as Vec;`.
|
|
||||||
#[inline]
|
|
||||||
fn path_is_vec(path: &syn::Path) -> bool {
|
|
||||||
#[inline]
|
|
||||||
fn is_path_segment(path: Option<&syn::PathSegment>,
|
|
||||||
name: Option<&str>,
|
|
||||||
plain: bool) -> bool {
|
|
||||||
match (path, name) {
|
|
||||||
(Some(ref path), Some(ref name)) =>
|
|
||||||
(path.arguments.is_empty() || ! plain) && path.ident == name,
|
|
||||||
(None, None) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut iter = (&path.segments).into_iter();
|
|
||||||
path.leading_colon.is_some()
|
|
||||||
&& is_path_segment(iter.next(), Some("std"), true)
|
|
||||||
&& is_path_segment(iter.next(), Some("vec"), true)
|
|
||||||
&& is_path_segment(iter.next(), Some("Vec"), false)
|
|
||||||
&& is_path_segment(iter.next(), None, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
let arg = decl.inputs.last().ok_or_else(|| not_slice_error(&decl.inputs))?;
|
|
||||||
if let syn::FnArg::Captured(ref arg_cap) = arg.value() {
|
|
||||||
// check for slice reference
|
|
||||||
if let syn::Type::Reference(ref ref_ty) = arg_cap.ty {
|
|
||||||
if let syn::Type::Slice(_) = *ref_ty.elem {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// check for `Vec`
|
|
||||||
if let syn::Type::Path(ref path) = arg_cap.ty {
|
|
||||||
if path_is_vec(&path.path) {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(not_slice_error(&arg))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If the path is a single ident, return it.
|
/// If the path is a single ident, return it.
|
||||||
fn extract_path_ident(path: &syn::Path) -> Result<Ident, Diagnostic> {
|
fn extract_path_ident(path: &syn::Path) -> Result<Ident, Diagnostic> {
|
||||||
if path.leading_colon.is_some() {
|
if path.leading_colon.is_some() {
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
|
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
|
||||||
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
||||||
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
||||||
|
- [variadic](./reference/attributes/on-js-imports/variadic.md)
|
||||||
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
||||||
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
||||||
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
||||||
|
38
guide/src/reference/attributes/on-js-imports/variadic.md
Normal file
38
guide/src/reference/attributes/on-js-imports/variadic.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Variadic Parameters
|
||||||
|
|
||||||
|
In javascript, both the types of function arguments, and the number of function arguments are
|
||||||
|
dynamic. For example
|
||||||
|
|
||||||
|
```js
|
||||||
|
function sum(...rest) {
|
||||||
|
let i;
|
||||||
|
// the old way
|
||||||
|
let old_way = 0;
|
||||||
|
for (i=0; i<arguments.length; i++) {
|
||||||
|
old_way += arguments[i];
|
||||||
|
}
|
||||||
|
// the new way
|
||||||
|
let new_way = 0;
|
||||||
|
for (i=0; i<rest.length; i++) {
|
||||||
|
new_way += rest[i];
|
||||||
|
}
|
||||||
|
// both give the same answer
|
||||||
|
assert(old_way === new_way);
|
||||||
|
return new_way;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This function doesn't translate directly into rust, since we don't currently support variadic
|
||||||
|
arguments on the wasm target. To bind to it, we use a slice as the last argument, and annotate the
|
||||||
|
function as variadic:
|
||||||
|
|
||||||
|
```rust
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern {
|
||||||
|
#[wasm_bindgen(variadic)]
|
||||||
|
fn sum(args: &[i32]) -> i32;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
when we call this function, the last argument will be expanded as the javascript expects.
|
||||||
|
|
@ -64,6 +64,10 @@ extern {
|
|||||||
fn new() -> Awesome;
|
fn new() -> Awesome;
|
||||||
#[wasm_bindgen(method)]
|
#[wasm_bindgen(method)]
|
||||||
fn get_internal(this: &Awesome) -> u32;
|
fn get_internal(this: &Awesome) -> u32;
|
||||||
|
// We can call javascript functions that have a dynamic number of arguments,
|
||||||
|
// e.g. rust `sum(&[1, 2, 3])` will be called like `sum(1, 2, 3)`
|
||||||
|
#[wasm_bindgen(variadic)]
|
||||||
|
fn sum(vals: &[u32]) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@ -143,5 +147,13 @@ export class Awesome {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function sum(...args) {
|
||||||
|
let answer = 0;
|
||||||
|
for(var i=0; i<args.length; i++) {
|
||||||
|
answer += args[i];
|
||||||
|
}
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
|
||||||
booted.then(main);
|
booted.then(main);
|
||||||
```
|
```
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
const wasm = require('wasm-bindgen-test.js');
|
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
|
|
||||||
// a function for testing numbers
|
// a function for testing numbers
|
||||||
|
@ -34,9 +34,9 @@ extern {
|
|||||||
//#[wasm_bindgen(variadic)]
|
//#[wasm_bindgen(variadic)]
|
||||||
//fn variadic_concat_string(first: String,
|
//fn variadic_concat_string(first: String,
|
||||||
// second: String,
|
// second: String,
|
||||||
// rest: ::std::vec::Vec<String>) -> String;
|
// rest: Vec<String>) -> String;
|
||||||
#[wasm_bindgen(variadic)]
|
#[wasm_bindgen(variadic)]
|
||||||
fn variadic_sum_rest_vec(first: u8, second: u8, rest: ::std::vec::Vec<u8>) -> u8;
|
fn variadic_sum_rest_vec(first: u8, second: u8, rest: Vec<u8>) -> u8;
|
||||||
//#[wasm_bindgen(variadic)]
|
//#[wasm_bindgen(variadic)]
|
||||||
//fn variadic_compare_pairs(first: JsValue, second: JsValue, rest: &[JsValue]);
|
//fn variadic_compare_pairs(first: JsValue, second: JsValue, rest: &[JsValue]);
|
||||||
//TODO imported type
|
//TODO imported type
|
||||||
|
Reference in New Issue
Block a user