Skip to content

Commit 671f193

Browse files
committed
Fix optional arguments in TypeScript
1 parent cc89109 commit 671f193

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

crates/cli-support/src/js/js2rust.rs

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,22 @@ use crate::descriptor::{Descriptor, Function};
22
use crate::js::Context;
33
use failure::{bail, Error};
44

5+
pub struct JsArgument {
6+
pub optional: bool,
7+
pub name: String,
8+
pub type_: String,
9+
}
10+
11+
impl JsArgument {
12+
fn required(name: String, type_: String) -> Self {
13+
Self { optional: false, name, type_ }
14+
}
15+
16+
fn optional(name: String, type_: String) -> Self {
17+
Self { optional: true, name, type_ }
18+
}
19+
}
20+
521
/// Helper struct for manufacturing a shim in JS used to translate JS types to
622
/// Rust, aka pass from JS back into Rust
723
pub struct Js2Rust<'a, 'b: 'a> {
@@ -12,7 +28,7 @@ pub struct Js2Rust<'a, 'b: 'a> {
1228
rust_arguments: Vec<String>,
1329

1430
/// Arguments and their types to the JS shim.
15-
pub js_arguments: Vec<(String, String)>,
31+
pub js_arguments: Vec<JsArgument>,
1632

1733
/// Conversions that happen before we invoke the wasm function, such as
1834
/// converting a string to a ptr/length pair.
@@ -175,7 +191,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
175191

176192
if let Some(kind) = arg.vector_kind() {
177193
self.js_arguments
178-
.push((name.clone(), kind.js_ty().to_string()));
194+
.push(JsArgument::required(name.clone(), kind.js_ty().to_string()));
179195

180196
let func = self.cx.pass_to_wasm_function(kind)?;
181197
let val = if optional {
@@ -223,7 +239,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
223239
}
224240

225241
if arg.is_anyref() {
226-
self.js_arguments.push((name.clone(), "any".to_string()));
242+
self.js_arguments.push(JsArgument::required(name.clone(), "any".to_string()));
227243
if self.cx.config.anyref {
228244
if optional {
229245
self.cx.expose_add_to_anyref_table()?;
@@ -252,7 +268,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
252268

253269
if arg.is_wasm_native() {
254270
self.js_arguments
255-
.push((name.clone(), "number | undefined".to_string()));
271+
.push(JsArgument::optional(name.clone(), "number".to_string()));
256272

257273
if self.cx.config.debug {
258274
self.cx.expose_assert_num();
@@ -274,7 +290,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
274290

275291
if arg.is_abi_as_u32() {
276292
self.js_arguments
277-
.push((name.clone(), "number | undefined".to_string()));
293+
.push(JsArgument::optional(name.clone(), "number".to_string()));
278294

279295
if self.cx.config.debug {
280296
self.cx.expose_assert_num();
@@ -301,7 +317,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
301317
};
302318
self.cx.expose_uint32_memory();
303319
self.js_arguments
304-
.push((name.clone(), "BigInt | undefined".to_string()));
320+
.push(JsArgument::optional(name.clone(), "BigInt".to_string()));
305321
self.prelude(&format!(
306322
"
307323
{f}[0] = isLikeNone({name}) ? BigInt(0) : {name};
@@ -322,7 +338,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
322338
match *arg {
323339
Descriptor::Boolean => {
324340
self.js_arguments
325-
.push((name.clone(), "boolean | undefined".to_string()));
341+
.push(JsArgument::optional(name.clone(), "boolean".to_string()));
326342
if self.cx.config.debug {
327343
self.cx.expose_assert_bool();
328344
self.prelude(&format!(
@@ -339,21 +355,21 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
339355
}
340356
Descriptor::Char => {
341357
self.js_arguments
342-
.push((name.clone(), "string | undefined".to_string()));
358+
.push(JsArgument::optional(name.clone(), "string".to_string()));
343359
self.rust_arguments.push(format!(
344360
"isLikeNone({0}) ? 0xFFFFFF : {0}.codePointAt(0)",
345361
name
346362
));
347363
}
348364
Descriptor::Enum { hole } => {
349365
self.js_arguments
350-
.push((name.clone(), "number | undefined".to_string()));
366+
.push(JsArgument::optional(name.clone(), "number".to_string()));
351367
self.rust_arguments
352368
.push(format!("isLikeNone({0}) ? {1} : {0}", name, hole));
353369
}
354370
Descriptor::RustStruct(ref s) => {
355371
self.js_arguments
356-
.push((name.clone(), format!("{} | undefined", s)));
372+
.push(JsArgument::optional(name.clone(), s.to_string()));
357373
self.prelude(&format!("let ptr{} = 0;", i));
358374
self.prelude(&format!("if (!isLikeNone({0})) {{", name));
359375
self.assert_class(&name, s);
@@ -373,7 +389,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
373389
}
374390

375391
if let Some(s) = arg.rust_struct() {
376-
self.js_arguments.push((name.clone(), s.to_string()));
392+
self.js_arguments.push(JsArgument::required(name.clone(), s.to_string()));
377393
self.assert_class(&name, s);
378394
self.assert_not_moved(&name);
379395
if arg.is_by_ref() {
@@ -387,7 +403,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
387403
}
388404

389405
if arg.number().is_some() {
390-
self.js_arguments.push((name.clone(), "number".to_string()));
406+
self.js_arguments.push(JsArgument::required(name.clone(), "number".to_string()));
391407

392408
if self.cx.config.debug {
393409
self.cx.expose_assert_num();
@@ -405,7 +421,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
405421
self.cx.expose_uint64_cvt_shim()
406422
};
407423
self.cx.expose_uint32_memory();
408-
self.js_arguments.push((name.clone(), "BigInt".to_string()));
424+
self.js_arguments.push(JsArgument::required(name.clone(), "BigInt".to_string()));
409425
self.prelude(&format!(
410426
"
411427
{f}[0] = {name};
@@ -422,7 +438,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
422438
}
423439

424440
if arg.is_ref_anyref() {
425-
self.js_arguments.push((name.clone(), "any".to_string()));
441+
self.js_arguments.push(JsArgument::required(name.clone(), "any".to_string()));
426442
if self.cx.config.anyref {
427443
self.anyref_args.push((self.rust_arguments.len(), false));
428444
self.rust_arguments.push(name);
@@ -442,7 +458,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
442458
match *arg {
443459
Descriptor::Boolean => {
444460
self.js_arguments
445-
.push((name.clone(), "boolean".to_string()));
461+
.push(JsArgument::required(name.clone(), "boolean".to_string()));
446462
if self.cx.config.debug {
447463
self.cx.expose_assert_bool();
448464
self.prelude(&format!(
@@ -455,7 +471,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
455471
self.rust_arguments.push(format!("{}", name));
456472
}
457473
Descriptor::Char => {
458-
self.js_arguments.push((name.clone(), "string".to_string()));
474+
self.js_arguments.push(JsArgument::required(name.clone(), "string".to_string()));
459475
self.rust_arguments.push(format!("{}.codePointAt(0)", name))
460476
}
461477
_ => bail!(
@@ -737,7 +753,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
737753
let mut ret: String = self
738754
.js_arguments
739755
.iter()
740-
.map(|a| format!("@param {{{}}} {}\n", a.1, a.0))
756+
.map(|a| if a.optional {
757+
format!("@param {{{} | undefined}} {}\n", a.type_, a.name)
758+
} else {
759+
format!("@param {{{}}} {}\n", a.type_, a.name)
760+
})
741761
.collect();
742762
ret.push_str(&format!("@returns {{{}}}", self.ret_ty));
743763
ret
@@ -761,7 +781,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
761781
let js_args = self
762782
.js_arguments
763783
.iter()
764-
.map(|s| &s.0[..])
784+
.map(|s| &s.name[..])
765785
.collect::<Vec<_>>()
766786
.join(", ");
767787
let mut js = format!("{}({}) {{\n", prefix, js_args);
@@ -790,7 +810,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
790810
let ts_args = self
791811
.js_arguments
792812
.iter()
793-
.map(|s| format!("{}: {}", s.0, s.1))
813+
.map(|s| if s.optional {
814+
format!("{}?: {}", s.name, s.type_)
815+
} else {
816+
format!("{}: {}", s.name, s.type_)
817+
})
794818
.collect::<Vec<_>>()
795819
.join(", ");
796820
let mut ts = if prefix.is_empty() {

crates/cli-support/src/js/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2878,7 +2878,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
28782878
"\n {}{}: {};",
28792879
if field.readonly { "readonly " } else { "" },
28802880
field.name,
2881-
&cx.js_arguments[0].1
2881+
&cx.js_arguments[0].type_
28822882
));
28832883
cx.finish("", &format!("wasm.{}", wasm_setter), setter).0
28842884
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import * as wbg from '../pkg/typescript_tests';
22

3-
const opt_fn: (a: number | undefined) => number | undefined = wbg.opt_fn;
3+
const opt_fn: (a?: number) => number | undefined = wbg.opt_fn;

0 commit comments

Comments
 (0)