diff --git a/crates/backend/src/ast.rs b/crates/backend/src/ast.rs index 4a98f858cbf..9e2d0b173e2 100644 --- a/crates/backend/src/ast.rs +++ b/crates/backend/src/ast.rs @@ -307,6 +307,8 @@ pub struct Function { pub r#async: bool, /// Whether to generate a typescript definition for this function pub generate_typescript: bool, + /// Whether to generate jsdoc documentation for this function + pub generate_jsdoc: bool, /// Whether this is a function with a variadict parameter pub variadic: bool, } @@ -351,6 +353,8 @@ pub struct StructField { pub comments: Vec, /// Whether to generate a typescript definition for this field pub generate_typescript: bool, + /// Whether to generate jsdoc documentation for this field + pub generate_jsdoc: bool, /// The span of the `#[wasm_bindgen(getter_with_clone)]` attribute applied /// to this field, if any. /// diff --git a/crates/backend/src/encode.rs b/crates/backend/src/encode.rs index 254d0e88537..e89cae7c0ff 100644 --- a/crates/backend/src/encode.rs +++ b/crates/backend/src/encode.rs @@ -218,6 +218,7 @@ fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Functi asyncness: func.r#async, name: &func.name, generate_typescript: func.generate_typescript, + generate_jsdoc: func.generate_jsdoc, variadic: func.variadic, } } @@ -351,6 +352,7 @@ fn shared_struct_field<'a>(s: &'a ast::StructField, _intern: &'a Interner) -> St readonly: s.readonly, comments: s.comments.iter().map(|s| &**s).collect(), generate_typescript: s.generate_typescript, + generate_jsdoc: s.generate_jsdoc, } } diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 0723928ee9f..8c7e9d4e641 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -106,6 +106,7 @@ impl<'a, 'b> Builder<'a, 'b> { explicit_arg_names: &Option>, asyncness: bool, variadic: bool, + generate_jsdoc: bool, ) -> Result { if self .cx @@ -243,7 +244,11 @@ impl<'a, 'b> Builder<'a, 'b> { asyncness, variadic, ); - let js_doc = self.js_doc_comments(&function_args, &arg_tys, &ts_ret_ty, variadic); + let js_doc = if generate_jsdoc { + self.js_doc_comments(&function_args, &arg_tys, &ts_ret_ty, variadic) + } else { + String::new() + }; Ok(JsFunction { code, diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 1a1de40e909..9a126bf029f 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -2514,11 +2514,13 @@ impl<'a> Context<'a> { let mut arg_names = &None; let mut asyncness = false; let mut variadic = false; + let mut generate_jsdoc = false; match kind { Kind::Export(export) => { arg_names = &export.arg_names; asyncness = export.asyncness; variadic = export.variadic; + generate_jsdoc = export.generate_jsdoc; match &export.kind { AuxExportKind::Function(_) => {} AuxExportKind::Constructor(class) => builder.constructor(class), @@ -2546,7 +2548,14 @@ impl<'a> Context<'a> { catch, log_error, } = builder - .process(&adapter, instrs, arg_names, asyncness, variadic) + .process( + &adapter, + instrs, + arg_names, + asyncness, + variadic, + generate_jsdoc, + ) .with_context(|| match kind { Kind::Export(e) => format!("failed to generate bindings for `{}`", e.debug_name), Kind::Import(i) => { diff --git a/crates/cli-support/src/wit/mod.rs b/crates/cli-support/src/wit/mod.rs index 7986afb1c3a..ef78a15d2a7 100644 --- a/crates/cli-support/src/wit/mod.rs +++ b/crates/cli-support/src/wit/mod.rs @@ -528,6 +528,7 @@ impl<'a> Context<'a> { asyncness: export.function.asyncness, kind, generate_typescript: export.function.generate_typescript, + generate_jsdoc: export.function.generate_jsdoc, variadic: export.function.variadic, }, ); @@ -889,6 +890,7 @@ impl<'a> Context<'a> { kind: AuxExportedMethodKind::Getter, }, generate_typescript: field.generate_typescript, + generate_jsdoc: field.generate_jsdoc, variadic: false, }, ); @@ -920,6 +922,7 @@ impl<'a> Context<'a> { kind: AuxExportedMethodKind::Setter, }, generate_typescript: field.generate_typescript, + generate_jsdoc: field.generate_jsdoc, variadic: false, }, ); @@ -1148,6 +1151,7 @@ impl<'a> Context<'a> { asyncness: false, kind, generate_typescript: true, + generate_jsdoc: true, variadic: false, }; assert!(self.aux.export_map.insert(id, export).is_none()); diff --git a/crates/cli-support/src/wit/nonstandard.rs b/crates/cli-support/src/wit/nonstandard.rs index 46bcfedd8ff..d05761bfda0 100644 --- a/crates/cli-support/src/wit/nonstandard.rs +++ b/crates/cli-support/src/wit/nonstandard.rs @@ -79,6 +79,8 @@ pub struct AuxExport { pub kind: AuxExportKind, /// Whether typescript bindings should be generated for this export. pub generate_typescript: bool, + /// Whether jsdoc comments should be generated for this export. + pub generate_jsdoc: bool, /// Whether typescript bindings should be generated for this export. pub variadic: bool, } diff --git a/crates/cli/tests/reference/skip-jsdoc.d.ts b/crates/cli/tests/reference/skip-jsdoc.d.ts new file mode 100644 index 00000000000..dda14e231eb --- /dev/null +++ b/crates/cli/tests/reference/skip-jsdoc.d.ts @@ -0,0 +1,9 @@ +/* tslint:disable */ +/* eslint-disable */ +/** +* Manually documented function +* +* @param {number} arg - This is my arg. It is mine. +* @returns to whence I came +*/ +export function docme(arg: number): number; diff --git a/crates/cli/tests/reference/skip-jsdoc.js b/crates/cli/tests/reference/skip-jsdoc.js new file mode 100644 index 00000000000..a617a8f3098 --- /dev/null +++ b/crates/cli/tests/reference/skip-jsdoc.js @@ -0,0 +1,16 @@ +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} + +/** +* Manually documented function +* +* @param {number} arg - This is my arg. It is mine. +* @returns to whence I came +*/ +export function docme(arg) { + const ret = wasm.docme(arg); + return ret >>> 0; +} + diff --git a/crates/cli/tests/reference/skip-jsdoc.rs b/crates/cli/tests/reference/skip-jsdoc.rs new file mode 100644 index 00000000000..b4a131615c1 --- /dev/null +++ b/crates/cli/tests/reference/skip-jsdoc.rs @@ -0,0 +1,10 @@ +use wasm_bindgen::prelude::*; + +/// Manually documented function +/// +/// @param {number} arg - This is my arg. It is mine. +/// @returns to whence I came +#[wasm_bindgen(skip_jsdoc)] +pub fn docme(arg: u32) -> u32 { + arg + 1 +} diff --git a/crates/cli/tests/reference/skip-jsdoc.wat b/crates/cli/tests/reference/skip-jsdoc.wat new file mode 100644 index 00000000000..bac987a58bd --- /dev/null +++ b/crates/cli/tests/reference/skip-jsdoc.wat @@ -0,0 +1,6 @@ +(module + (type (;0;) (func (param i32) (result i32))) + (func $docme (type 0) (param i32) (result i32)) + (memory (;0;) 17) + (export "memory" (memory 0)) + (export "docme" (func $docme))) diff --git a/crates/macro-support/src/parser.rs b/crates/macro-support/src/parser.rs index a54d8e5934a..27310452f7e 100644 --- a/crates/macro-support/src/parser.rs +++ b/crates/macro-support/src/parser.rs @@ -80,6 +80,7 @@ macro_rules! attrgen { (variadic, Variadic(Span)), (typescript_custom_section, TypescriptCustomSection(Span)), (skip_typescript, SkipTypescript(Span)), + (skip_jsdoc, SkipJsDoc(Span)), (start, Start(Span)), (skip, Skip(Span)), (typescript_type, TypeScriptType(Span, String, Span)), @@ -445,6 +446,7 @@ impl<'a> ConvertToAst for &'a mut syn::ItemStruct { setter: Ident::new(&setter, Span::call_site()), comments, generate_typescript: attrs.skip_typescript().is_none(), + generate_jsdoc: attrs.skip_jsdoc().is_none(), getter_with_clone: attrs.getter_with_clone().or(getter_with_clone).copied(), }); attrs.check_used(); @@ -912,6 +914,7 @@ fn function_from_decl( r#unsafe: sig.unsafety.is_some(), r#async: sig.asyncness.is_some(), generate_typescript: opts.skip_typescript().is_none(), + generate_jsdoc: opts.skip_jsdoc().is_none(), variadic: opts.variadic().is_some(), }, method_self, diff --git a/crates/shared/src/lib.rs b/crates/shared/src/lib.rs index 408613be9f1..54647d32a5d 100644 --- a/crates/shared/src/lib.rs +++ b/crates/shared/src/lib.rs @@ -6,7 +6,7 @@ mod schema_hash_approval; // This gets changed whenever our schema changes. // At this time versions of wasm-bindgen and wasm-bindgen-cli are required to have the exact same // SCHEMA_VERSION in order to work together. -pub const SCHEMA_VERSION: &str = "0.2.84"; +pub const SCHEMA_VERSION: &str = "0.2.85"; #[macro_export] macro_rules! shared_api { @@ -123,6 +123,7 @@ macro_rules! shared_api { asyncness: bool, name: &'a str, generate_typescript: bool, + generate_jsdoc: bool, variadic: bool, } @@ -139,6 +140,7 @@ macro_rules! shared_api { readonly: bool, comments: Vec<&'a str>, generate_typescript: bool, + generate_jsdoc: bool, } struct LocalModule<'a> { diff --git a/crates/shared/src/schema_hash_approval.rs b/crates/shared/src/schema_hash_approval.rs index 0d4d0bb38f1..a410a360ac9 100644 --- a/crates/shared/src/schema_hash_approval.rs +++ b/crates/shared/src/schema_hash_approval.rs @@ -8,7 +8,7 @@ // If the schema in this library has changed then: // 1. Bump the version in `crates/shared/Cargo.toml` // 2. Change the `SCHEMA_VERSION` in this library to this new Cargo.toml version -const APPROVED_SCHEMA_FILE_HASH: &'static str = "584864585234329974"; +const APPROVED_SCHEMA_FILE_HASH: &'static str = "11107065389885651666"; #[test] fn schema_version() { diff --git a/guide/src/SUMMARY.md b/guide/src/SUMMARY.md index 2bd611cfe06..c6fcc31737a 100644 --- a/guide/src/SUMMARY.md +++ b/guide/src/SUMMARY.md @@ -83,6 +83,7 @@ - [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md) - [`readonly`](./reference/attributes/on-rust-exports/readonly.md) - [`skip`](./reference/attributes/on-rust-exports/skip.md) + - [`skip_jsdoc`](./reference/attributes/on-rust-exports/skip_jsdoc.md) - [`start`](./reference/attributes/on-rust-exports/start.md) - [`typescript_custom_section`](./reference/attributes/on-rust-exports/typescript_custom_section.md) - [`getter` and `setter`](./reference/attributes/on-rust-exports/getter-and-setter.md) diff --git a/guide/src/reference/attributes/on-rust-exports/skip_jsdoc.md b/guide/src/reference/attributes/on-rust-exports/skip_jsdoc.md new file mode 100644 index 00000000000..ddbdf6c55ee --- /dev/null +++ b/guide/src/reference/attributes/on-rust-exports/skip_jsdoc.md @@ -0,0 +1,42 @@ +# `skip_jsdoc` + +When attached to a function or a method, prevents `wasm-bindgen` from auto-generating JSDoc-style doc comments. +By default, `wasm-bindgen` adds `@param` and `@returns` annotations to doc comments in the generated +JS files. A `skip_jsdoc` annotation prevents this, allowing you to supply your own doc comments. + +The following rust uses `skip_jsdoc` to omit one of the auto-generated doc comments. + +```rust +use wasm_bindgen::prelude::*; + +/// Autogenerated docs. +#[wasm_bindgen] +pub fn foo(arg: u32) -> u32 { arg + 1 } + +/// Manually written docs. +/// +/// @param {number} arg - A descriptive description. +/// @returns {number} Something a bit bigger. +#[wasm_bindgen(skip_jsdoc)] +pub fn bar(arg: u32) -> u32 { arg + 2 } +``` + +The `wasm-bindgen`-generated JS interface of the above code will look something like this: + +```js +/** +* Autogenerated docs. +* +* @param {number} arg +* @returns {number} +*/ +export function foo(arg) { /* ... */ } + +/** +* Manually written docs. +* +* @param {number} arg - A descriptive description. +* @returns {number} Something a bit bigger. +*/ +export function bar(arg) { /* ... */ } +```