Skip to content

Commit 2384af2

Browse files
committed
Fix optional arguments in TypeScript
1 parent d139228 commit 2384af2

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.
@@ -173,7 +189,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
173189

174190
if let Some(kind) = arg.vector_kind() {
175191
self.js_arguments
176-
.push((name.clone(), kind.js_ty().to_string()));
192+
.push(JsArgument::required(name.clone(), kind.js_ty().to_string()));
177193

178194
let func = self.cx.pass_to_wasm_function(kind)?;
179195
let val = if optional {
@@ -221,7 +237,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
221237
}
222238

223239
if arg.is_anyref() {
224-
self.js_arguments.push((name.clone(), "any".to_string()));
240+
self.js_arguments.push(JsArgument::required(name.clone(), "any".to_string()));
225241
if self.cx.config.anyref {
226242
if optional {
227243
self.cx.expose_add_to_anyref_table()?;
@@ -250,7 +266,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
250266

251267
if arg.is_wasm_native() {
252268
self.js_arguments
253-
.push((name.clone(), "number | undefined".to_string()));
269+
.push(JsArgument::optional(name.clone(), "number".to_string()));
254270

255271
if self.cx.config.debug {
256272
self.cx.expose_assert_num();
@@ -272,7 +288,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
272288

273289
if arg.is_abi_as_u32() {
274290
self.js_arguments
275-
.push((name.clone(), "number | undefined".to_string()));
291+
.push(JsArgument::optional(name.clone(), "number".to_string()));
276292

277293
if self.cx.config.debug {
278294
self.cx.expose_assert_num();
@@ -299,7 +315,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
299315
};
300316
self.cx.expose_uint32_memory();
301317
self.js_arguments
302-
.push((name.clone(), "BigInt | undefined".to_string()));
318+
.push(JsArgument::optional(name.clone(), "BigInt".to_string()));
303319
self.prelude(&format!(
304320
"
305321
{f}[0] = isLikeNone({name}) ? BigInt(0) : {name};
@@ -320,7 +336,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
320336
match *arg {
321337
Descriptor::Boolean => {
322338
self.js_arguments
323-
.push((name.clone(), "boolean | undefined".to_string()));
339+
.push(JsArgument::optional(name.clone(), "boolean".to_string()));
324340
if self.cx.config.debug {
325341
self.cx.expose_assert_bool();
326342
self.prelude(&format!(
@@ -337,21 +353,21 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
337353
}
338354
Descriptor::Char => {
339355
self.js_arguments
340-
.push((name.clone(), "string | undefined".to_string()));
356+
.push(JsArgument::optional(name.clone(), "string".to_string()));
341357
self.rust_arguments.push(format!(
342358
"isLikeNone({0}) ? 0xFFFFFF : {0}.codePointAt(0)",
343359
name
344360
));
345361
}
346362
Descriptor::Enum { hole } => {
347363
self.js_arguments
348-
.push((name.clone(), "number | undefined".to_string()));
364+
.push(JsArgument::optional(name.clone(), "number".to_string()));
349365
self.rust_arguments
350366
.push(format!("isLikeNone({0}) ? {1} : {0}", name, hole));
351367
}
352368
Descriptor::RustStruct(ref s) => {
353369
self.js_arguments
354-
.push((name.clone(), format!("{} | undefined", s)));
370+
.push(JsArgument::optional(name.clone(), s.to_string()));
355371
self.prelude(&format!("let ptr{} = 0;", i));
356372
self.prelude(&format!("if (!isLikeNone({0})) {{", name));
357373
self.assert_class(&name, s);
@@ -371,7 +387,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
371387
}
372388

373389
if let Some(s) = arg.rust_struct() {
374-
self.js_arguments.push((name.clone(), s.to_string()));
390+
self.js_arguments.push(JsArgument::required(name.clone(), s.to_string()));
375391
self.assert_class(&name, s);
376392
self.assert_not_moved(&name);
377393
if arg.is_by_ref() {
@@ -385,7 +401,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
385401
}
386402

387403
if arg.number().is_some() {
388-
self.js_arguments.push((name.clone(), "number".to_string()));
404+
self.js_arguments.push(JsArgument::required(name.clone(), "number".to_string()));
389405

390406
if self.cx.config.debug {
391407
self.cx.expose_assert_num();
@@ -403,7 +419,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
403419
self.cx.expose_uint64_cvt_shim()
404420
};
405421
self.cx.expose_uint32_memory();
406-
self.js_arguments.push((name.clone(), "BigInt".to_string()));
422+
self.js_arguments.push(JsArgument::required(name.clone(), "BigInt".to_string()));
407423
self.prelude(&format!(
408424
"
409425
{f}[0] = {name};
@@ -420,7 +436,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
420436
}
421437

422438
if arg.is_ref_anyref() {
423-
self.js_arguments.push((name.clone(), "any".to_string()));
439+
self.js_arguments.push(JsArgument::required(name.clone(), "any".to_string()));
424440
if self.cx.config.anyref {
425441
self.anyref_args.push((self.rust_arguments.len(), false));
426442
self.rust_arguments.push(name);
@@ -440,7 +456,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
440456
match *arg {
441457
Descriptor::Boolean => {
442458
self.js_arguments
443-
.push((name.clone(), "boolean".to_string()));
459+
.push(JsArgument::required(name.clone(), "boolean".to_string()));
444460
if self.cx.config.debug {
445461
self.cx.expose_assert_bool();
446462
self.prelude(&format!(
@@ -453,7 +469,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
453469
self.rust_arguments.push(format!("{}", name));
454470
}
455471
Descriptor::Char => {
456-
self.js_arguments.push((name.clone(), "string".to_string()));
472+
self.js_arguments.push(JsArgument::required(name.clone(), "string".to_string()));
457473
self.rust_arguments.push(format!("{}.codePointAt(0)", name))
458474
}
459475
_ => bail!(
@@ -735,7 +751,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
735751
let mut ret: String = self
736752
.js_arguments
737753
.iter()
738-
.map(|a| format!("@param {{{}}} {}\n", a.1, a.0))
754+
.map(|a| if a.optional {
755+
format!("@param {{{} | undefined}} {}\n", a.type_, a.name)
756+
} else {
757+
format!("@param {{{}}} {}\n", a.type_, a.name)
758+
})
739759
.collect();
740760
ret.push_str(&format!("@returns {{{}}}", self.ret_ty));
741761
ret
@@ -759,7 +779,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
759779
let js_args = self
760780
.js_arguments
761781
.iter()
762-
.map(|s| &s.0[..])
782+
.map(|s| &s.name[..])
763783
.collect::<Vec<_>>()
764784
.join(", ");
765785
let mut js = format!("{}({}) {{\n", prefix, js_args);
@@ -788,7 +808,11 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
788808
let ts_args = self
789809
.js_arguments
790810
.iter()
791-
.map(|s| format!("{}: {}", s.0, s.1))
811+
.map(|s| if s.optional {
812+
format!("{}?: {}", s.name, s.type_)
813+
} else {
814+
format!("{}: {}", s.name, s.type_)
815+
})
792816
.collect::<Vec<_>>()
793817
.join(", ");
794818
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
@@ -2963,7 +2963,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
29632963
"\n {}{}: {};",
29642964
if field.readonly { "readonly " } else { "" },
29652965
field.name,
2966-
&cx.js_arguments[0].1
2966+
&cx.js_arguments[0].type_
29672967
));
29682968
cx.finish("", &format!("wasm.{}", wasm_setter), setter).0
29692969
};
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)