mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-15 04:23:12 +03:00
Preserve argument names
This commit is contained in:
parent
90c3196b7b
commit
70f5373348
@ -165,7 +165,22 @@ fn shared_export<'a>(export: &'a ast::Export, intern: &'a Interner) -> Export<'a
|
||||
}
|
||||
|
||||
fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Function<'a> {
|
||||
Function { name: &func.name }
|
||||
let arg_names = func
|
||||
.arguments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, arg)| {
|
||||
if let syn::Pat::Ident(ref x) = arg.pat {
|
||||
x.ident.to_string()
|
||||
} else {
|
||||
format!("arg{}", idx)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
Function {
|
||||
name: &func.name,
|
||||
arg_names,
|
||||
}
|
||||
}
|
||||
|
||||
fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> {
|
||||
@ -364,6 +379,12 @@ impl<'a> Encode for &'a str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Encode for String {
|
||||
fn encode(&self, dst: &mut Encoder) {
|
||||
self.as_bytes().encode(dst);
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Encode> Encode for Vec<T> {
|
||||
fn encode(&self, dst: &mut Encoder) {
|
||||
self.len().encode(dst);
|
||||
|
@ -46,6 +46,15 @@ impl<'src> Decode<'src> for &'src str {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src> Decode<'src> for String {
|
||||
fn decode(data: &mut &'src [u8]) -> String {
|
||||
let n = u32::decode(data);
|
||||
let (a, b) = data.split_at(n as usize);
|
||||
*data = b;
|
||||
String::from_utf8(a.to_vec()).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'src, T: Decode<'src>> Decode<'src> for Vec<T> {
|
||||
fn decode(data: &mut &'src [u8]) -> Self {
|
||||
let n = u32::decode(data);
|
||||
|
@ -193,7 +193,7 @@ impl ClosureDescriptors {
|
||||
builder.rust_argument("this.a").rust_argument("b");
|
||||
}
|
||||
builder.finally("if (this.cnt-- == 1) d(this.a, b);");
|
||||
builder.process(&closure.function)?.finish(
|
||||
builder.process(&closure.function, None)?.finish(
|
||||
"function",
|
||||
"f",
|
||||
ExportedShim::TableElement(&mut shim),
|
||||
|
@ -75,9 +75,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
|
||||
/// Generates all bindings necessary for the signature in `Function`,
|
||||
/// creating necessary argument conversions and return value processing.
|
||||
pub fn process(&mut self, function: &Function) -> Result<&mut Self, Error> {
|
||||
for arg in function.arguments.iter() {
|
||||
self.argument(arg)?;
|
||||
pub fn process<'c, I>(
|
||||
&mut self,
|
||||
function: &Function,
|
||||
opt_arg_names: I,
|
||||
) -> Result<&mut Self, Error>
|
||||
where
|
||||
I: Into<Option<&'c Vec<String>>>,
|
||||
{
|
||||
if let Some(arg_names) = opt_arg_names.into() {
|
||||
for (arg, arg_name) in function.arguments.iter().zip(arg_names) {
|
||||
self.argument(arg, arg_name.clone())?;
|
||||
}
|
||||
} else {
|
||||
for arg in function.arguments.iter() {
|
||||
self.argument(arg, None)?;
|
||||
}
|
||||
}
|
||||
self.ret(&function.ret)?;
|
||||
Ok(self)
|
||||
@ -138,15 +151,22 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
self
|
||||
}
|
||||
|
||||
fn abi_arg(&mut self) -> String {
|
||||
let s = format!("arg{}", self.arg_idx);
|
||||
fn abi_arg(&mut self, opt_arg_name: Option<String>) -> String {
|
||||
let ret = if let Some(x) = opt_arg_name {
|
||||
x
|
||||
} else {
|
||||
format!("arg{}", self.arg_idx)
|
||||
};
|
||||
self.arg_idx += 1;
|
||||
s
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn argument(&mut self, arg: &Descriptor) -> Result<&mut Self, Error> {
|
||||
pub fn argument<I>(&mut self, arg: &Descriptor, opt_arg_name: I) -> Result<&mut Self, Error>
|
||||
where
|
||||
I: Into<Option<String>>,
|
||||
{
|
||||
let i = self.arg_idx;
|
||||
let name = self.abi_arg();
|
||||
let name = self.abi_arg(opt_arg_name.into());
|
||||
|
||||
let (arg, optional) = match arg {
|
||||
Descriptor::Option(t) => (&**t, true),
|
||||
|
@ -2498,7 +2498,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
}
|
||||
|
||||
let (js, ts, js_doc) = Js2Rust::new(&export.function.name, self.cx)
|
||||
.process(descriptor.unwrap_function())?
|
||||
.process(descriptor.unwrap_function(), &export.function.arg_names)?
|
||||
.finish(
|
||||
"function",
|
||||
&format!("wasm.{}", export.function.name),
|
||||
@ -2554,7 +2554,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
} else {
|
||||
None
|
||||
})
|
||||
.process(descriptor.unwrap_function())?
|
||||
.process(descriptor.unwrap_function(), &export.function.arg_names)?
|
||||
.finish(
|
||||
"",
|
||||
&format!("wasm.{}", wasm_name),
|
||||
@ -2772,7 +2772,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
let setter = ExportedShim::Named(&wasm_setter);
|
||||
let mut cx = Js2Rust::new(&field.name, self.cx);
|
||||
cx.method(true, false)
|
||||
.argument(&descriptor)?
|
||||
.argument(&descriptor, None)?
|
||||
.ret(&Descriptor::Unit)?;
|
||||
ts_dst.push_str(&format!(
|
||||
"\n {}{}: {};",
|
||||
|
@ -285,7 +285,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
} else {
|
||||
builder.rust_argument("this.a");
|
||||
}
|
||||
builder.rust_argument("this.b").process(f)?.finish(
|
||||
builder.rust_argument("this.b").process(f, None)?.finish(
|
||||
"function",
|
||||
"this.f",
|
||||
ExportedShim::TableElement(&mut shim),
|
||||
|
@ -106,6 +106,7 @@ macro_rules! shared_api {
|
||||
}
|
||||
|
||||
struct Function<'a> {
|
||||
arg_names: Vec<String>,
|
||||
name: &'a str,
|
||||
}
|
||||
|
||||
|
16
tests/wasm/arg_names.js
Normal file
16
tests/wasm/arg_names.js
Normal file
@ -0,0 +1,16 @@
|
||||
const wasm = require('wasm-bindgen-test.js');
|
||||
const assert = require('assert');
|
||||
|
||||
const ARGUMENT_NAMES = /([^\s,]+)/g;
|
||||
const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
||||
|
||||
// https://stackoverflow.com/q/1007981/210304
|
||||
function getArgNames(func) {
|
||||
let fnStr = func.toString().replace(STRIP_COMMENTS, '');
|
||||
let result = fnStr.slice(fnStr.indexOf('(')+1, fnStr.indexOf(')')).match(ARGUMENT_NAMES);
|
||||
return result === null ? [] : result;
|
||||
}
|
||||
|
||||
exports.js_arg_names = () => {
|
||||
assert.deepEqual(getArgNames(wasm.fn_with_many_args), ['_a', '_b', '_c', '_d']);
|
||||
};
|
15
tests/wasm/arg_names.rs
Normal file
15
tests/wasm/arg_names.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen(module = "tests/wasm/arg_names.js")]
|
||||
extern "C" {
|
||||
fn js_arg_names();
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn fn_with_many_args(_a: i32, _b: i32, _c: i32, _d: i32) {}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn rust_arg_names() {
|
||||
js_arg_names();
|
||||
}
|
@ -13,6 +13,7 @@ extern crate serde_derive;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
pub mod api;
|
||||
pub mod arg_names;
|
||||
pub mod char;
|
||||
pub mod classes;
|
||||
pub mod closures;
|
||||
|
Loading…
Reference in New Issue
Block a user