From 220b227db4cb047d64b7614cd17915af374dac43 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 9 Oct 2024 17:31:49 +0200 Subject: [PATCH 1/6] Add JSDoc annotations to ensure enums type check even without `.d.ts` file --- crates/cli-support/src/js/mod.rs | 41 ++++++++++++++++++++--------- crates/cli/tests/reference/enums.js | 15 +++++++++++ 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 8a150de5816..422b3b7de5d 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -3771,11 +3771,11 @@ __wbg_set_wasm(wasm);" } fn generate_enum(&mut self, enum_: &AuxEnum) -> Result<(), Error> { - let docs = format_doc_comments(&enum_.comments, None); let mut variants = String::new(); if enum_.generate_typescript { - self.typescript.push_str(&docs); + self.typescript + .push_str(&format_doc_comments(&enum_.comments, None)); self.typescript .push_str(&format!("export enum {} {{", enum_.name)); } @@ -3802,6 +3802,18 @@ __wbg_set_wasm(wasm);" if enum_.generate_typescript { self.typescript.push_str("\n}\n"); } + + // add an `@enum {1|2|3}` to ensure that enums type-check even without .d.ts + let mut at_enum = "@enum {".to_string(); + for (i, (_, value, _)) in enum_.variants.iter().enumerate() { + if i != 0 { + at_enum.push('|'); + } + at_enum.push_str(&value.to_string()); + } + at_enum.push('}'); + let docs = format_doc_comments(&enum_.comments, Some(at_enum)); + self.export( &enum_.name, &format!("Object.freeze({{ {} }})", variants), @@ -3812,15 +3824,19 @@ __wbg_set_wasm(wasm);" } fn generate_string_enum(&mut self, string_enum: &AuxStringEnum) -> Result<(), Error> { - let docs = format_doc_comments(&string_enum.comments, None); - let variants: Vec<_> = string_enum .variant_values .iter() .map(|v| format!("\"{v}\"")) .collect(); + let type_expr = if variants.is_empty() { + "never".to_string() + } else { + variants.join(" | ") + }; if string_enum.generate_typescript { + let docs = format_doc_comments(&string_enum.comments, None); self.typescript.push_str(&docs); if string_enum.public { self.typescript.push_str("export "); @@ -3828,18 +3844,19 @@ __wbg_set_wasm(wasm);" self.typescript.push_str("type "); self.typescript.push_str(&string_enum.name); self.typescript.push_str(" = "); - - if variants.is_empty() { - self.typescript.push_str("never"); - } else { - self.typescript.push_str(&variants.join(" | ")); - } - + self.typescript.push_str(&type_expr); self.typescript.push_str(";\n"); } + // generate type definition in case there is no .d.ts file + let at = format!( + "@typedef {{{type_expr}}} {name}\n@type {{{name}[]}}", + name = string_enum.name + ); + let docs = format_doc_comments(&string_enum.comments, Some(at)); + self.global(&format!( - "const __wbindgen_enum_{name} = [{values}];\n", + "{docs}const __wbindgen_enum_{name} = [{values}];\n", name = string_enum.name, values = variants.join(", ") )); diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index a2ef36d4aaf..e3470a1bf1e 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -64,13 +64,28 @@ export function option_string_enum_echo(color) { /** * A color. + * @enum {0|1|2} */ export const Color = Object.freeze({ Green:0,"0":"Green",Yellow:1,"1":"Yellow",Red:2,"2":"Red", }); +/** + * The name of a color. + * @typedef {"green" | "yellow" | "red"} ColorName + * @type {ColorName[]} + */ const __wbindgen_enum_ColorName = ["green", "yellow", "red"]; +/** + * An unused string enum. + * @typedef {"foo" | "bar"} FooBar + * @type {FooBar[]} + */ const __wbindgen_enum_FooBar = ["foo", "bar"]; +/** + * @typedef {"foo" | "bar"} PrivateStringEnum + * @type {PrivateStringEnum[]} + */ const __wbindgen_enum_PrivateStringEnum = ["foo", "bar"]; export function __wbindgen_throw(arg0, arg1) { From 9360aa47ebba0ab1b8242320d0ff0b9076554eda Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 13 Oct 2024 23:16:03 +0200 Subject: [PATCH 2/6] Add space between numbers --- crates/cli-support/src/js/mod.rs | 4 ++-- crates/cli/tests/reference/enums.js | 33 +++++++++++++++------------ crates/cli/tests/reference/web-sys.js | 7 ++++++ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 9ec7aeeedf6..1f02db83d69 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -3824,11 +3824,11 @@ __wbg_set_wasm(wasm);" self.typescript.push_str("\n}\n"); } - // add an `@enum {1|2|3}` to ensure that enums type-check even without .d.ts + // add an `@enum {1 | 2 | 3}` to ensure that enums type-check even without .d.ts let mut at_enum = "@enum {".to_string(); for (i, (_, value, _)) in enum_.variants.iter().enumerate() { if i != 0 { - at_enum.push('|'); + at_enum.push_str(" | "); } at_enum.push_str(&value.to_string()); } diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index d18831245ab..b6fd048c97c 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -64,29 +64,32 @@ export function option_string_enum_echo(color) { /** * A color. - * @enum {0|1|2} + * @enum {0 | 1 | 2} */ -export const Color = Object.freeze({ Green:0,"0":"Green",Yellow:1,"1":"Yellow",Red:2,"2":"Red", }); - +export const Color = Object.freeze({ /** - * The name of a color. - * @typedef {"green" | "yellow" | "red"} ColorName - * @type {ColorName[]} + * Green as a leaf. */ -const __wbindgen_enum_ColorName = ["green", "yellow", "red"]; - +Green:0,"0":"Green", +/** + * Yellow as the sun. + */ +Yellow:1,"1":"Yellow", +/** + * Red as a rose. + */ +Red:2,"2":"Red", }); /** - * An unused string enum. - * @typedef {"foo" | "bar"} FooBar - * @type {FooBar[]} + * @enum {0 | 1 | 42 | 43} */ -const __wbindgen_enum_FooBar = ["foo", "bar"]; +export const ImplicitDiscriminant = Object.freeze({ A:0,"0":"A",B:1,"1":"B",C:42,"42":"C",D:43,"43":"D", }); /** - * @typedef {"foo" | "bar"} PrivateStringEnum - * @type {PrivateStringEnum[]} + * The name of a color. + * @typedef {"green" | "yellow" | "red"} ColorName + * @type {ColorName[]} */ -const __wbindgen_enum_PrivateStringEnum = ["foo", "bar"]; +const __wbindgen_enum_ColorName = ["green", "yellow", "red"]; export function __wbindgen_throw(arg0, arg1) { throw new Error(getStringFromWasm0(arg0, arg1)); diff --git a/crates/cli/tests/reference/web-sys.js b/crates/cli/tests/reference/web-sys.js index 12bc6777d2e..057774fe787 100644 --- a/crates/cli/tests/reference/web-sys.js +++ b/crates/cli/tests/reference/web-sys.js @@ -208,6 +208,13 @@ function handleError(f, args) { } } +/** + *The `MediaSourceEnum` enum. + * + **This API requires the following crate features to be activated: `MediaSourceEnum`* + * @typedef {"camera" | "screen" | "application" | "window" | "browser" | "microphone" | "audioCapture" | "other"} MediaSourceEnum + * @type {MediaSourceEnum[]} + */ const __wbindgen_enum_MediaSourceEnum = ["camera", "screen", "application", "window", "browser", "microphone", "audioCapture", "other"]; export function __wbg_new_1cabf49927794f50() { return handleError(function (arg0, arg1) { From 6a579a534e68301a234aa0c5e6286bb5d638117e Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 15 Oct 2024 13:18:14 +0200 Subject: [PATCH 3/6] Remove string enum comments --- crates/cli-support/src/js/mod.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 1377e901615..26bd104a534 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -3838,11 +3838,6 @@ __wbg_set_wasm(wasm);" .iter() .map(|v| format!("\"{v}\"")) .collect(); - let type_expr = if variants.is_empty() { - "never".to_string() - } else { - variants.join(" | ") - }; if string_enum.generate_typescript && self @@ -3850,6 +3845,11 @@ __wbg_set_wasm(wasm);" .contains(&TsReference::StringEnum(string_enum.name.clone())) { let docs = format_doc_comments(&string_enum.comments, None); + let type_expr = if variants.is_empty() { + "never".to_string() + } else { + variants.join(" | ") + }; self.typescript.push_str(&docs); self.typescript.push_str("type "); @@ -3861,16 +3861,8 @@ __wbg_set_wasm(wasm);" if self.used_string_enums.contains(&string_enum.name) { // only generate the internal string enum array if it's actually used - - // generate type definition in case there is no .d.ts file - let at = format!( - "@typedef {{{type_expr}}} {name}\n@type {{{name}[]}}", - name = string_enum.name - ); - let docs = format_doc_comments(&string_enum.comments, Some(at)); - self.global(&format!( - "{docs}const __wbindgen_enum_{name} = [{values}];\n", + "const __wbindgen_enum_{name} = [{values}];\n", name = string_enum.name, values = variants.join(", ") )); From 94c6f065711c72355a6447032db8cecd7641029a Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 15 Oct 2024 13:20:23 +0200 Subject: [PATCH 4/6] Updated refs --- crates/cli/tests/reference/enums.js | 5 ----- crates/cli/tests/reference/web-sys.js | 24 ------------------------ 2 files changed, 29 deletions(-) diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index b6fd048c97c..ab820abbc3f 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -84,11 +84,6 @@ Red:2,"2":"Red", }); */ export const ImplicitDiscriminant = Object.freeze({ A:0,"0":"A",B:1,"1":"B",C:42,"42":"C",D:43,"43":"D", }); -/** - * The name of a color. - * @typedef {"green" | "yellow" | "red"} ColorName - * @type {ColorName[]} - */ const __wbindgen_enum_ColorName = ["green", "yellow", "red"]; export function __wbindgen_throw(arg0, arg1) { diff --git a/crates/cli/tests/reference/web-sys.js b/crates/cli/tests/reference/web-sys.js index c12d4df6e1b..4ef9ffbab71 100644 --- a/crates/cli/tests/reference/web-sys.js +++ b/crates/cli/tests/reference/web-sys.js @@ -208,30 +208,6 @@ export function get_media_source() { return __wbindgen_enum_MediaSourceEnum[ret]; } -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} - -function handleError(f, args) { - try { - return f.apply(this, args); - } catch (e) { - wasm.__wbindgen_exn_store(addHeapObject(e)); - } -} - -/** - *The `MediaSourceEnum` enum. - * - **This API requires the following crate features to be activated: `MediaSourceEnum`* - * @typedef {"camera" | "screen" | "application" | "window" | "browser" | "microphone" | "audioCapture" | "other"} MediaSourceEnum - * @type {MediaSourceEnum[]} - */ const __wbindgen_enum_MediaSourceEnum = ["camera", "screen", "application", "window", "browser", "microphone", "audioCapture", "other"]; export function __wbg_new_1cabf49927794f50() { return handleError(function (arg0, arg1) { From ee8a2b266979fd4ce397b127ff7d0a58814250db Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 15 Oct 2024 22:16:37 +0200 Subject: [PATCH 5/6] Updated changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2593781fb3c..a0969ef806c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,9 @@ * Fixed potential `null` error when using `JsValue::as_debug_string()`. [#4192](https://github.com/rustwasm/wasm-bindgen/pull/4192) +* Fixed C-style enums causing TypeScript type errors without the generated `.d.ts` file. + [#4192](https://github.com/rustwasm/wasm-bindgen/pull/4192) + -------------------------------------------------------------------------------- ## [0.2.95](https://github.com/rustwasm/wasm-bindgen/compare/0.2.94...0.2.95) From b585490dbf8ee26bb2c8da94b1cab22b1283072a Mon Sep 17 00:00:00 2001 From: daxpedda Date: Wed, 16 Oct 2024 00:11:02 +0200 Subject: [PATCH 6/6] Adjust changelog entry --- CHANGELOG.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a0969ef806c..5bfc3cd40c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ ## Unreleased +### Added + +* Added JSDoc type annotations to C-style enums. + [#4192](https://github.com/rustwasm/wasm-bindgen/pull/4192) + ### Changed * String enums now generate private TypeScript types but only if used. @@ -28,9 +33,6 @@ * Fixed potential `null` error when using `JsValue::as_debug_string()`. [#4192](https://github.com/rustwasm/wasm-bindgen/pull/4192) -* Fixed C-style enums causing TypeScript type errors without the generated `.d.ts` file. - [#4192](https://github.com/rustwasm/wasm-bindgen/pull/4192) - -------------------------------------------------------------------------------- ## [0.2.95](https://github.com/rustwasm/wasm-bindgen/compare/0.2.94...0.2.95)