From ebe658739c075fe78781d87ee9aa46533922476d Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 21 Jun 2022 20:11:27 +0200 Subject: [PATCH] fix(cli-support) Differentiate JS docs and TS docs when generating adapters. (#2956) A bug has been raised in https://github.com/rustwasm/wasm-bindgen/issues/2947, which is the consequence of a bug introduced in https://github.com/rustwasm/wasm-bindgen/pull/2909. This patch fixes it by differentiating JS docs and TS docs clearly. The `Context::push_setter` and `Context::push_getter` methods now receive a `js_docs` and a `ts_docs`, which prevent any confusions. --- crates/cli-support/src/js/mod.rs | 60 +++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index 707a4523328..8ca6a854a40 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -2564,31 +2564,33 @@ impl<'a> Context<'a> { false => None, }; + let js_docs = format_doc_comments(&export.comments, Some(js_doc)); + match &export.kind { AuxExportKind::Function(name) => { - let docs = format_doc_comments(&export.comments, Some(js_doc)); - if let Some(ts_sig) = ts_sig { - self.typescript.push_str(&docs); + self.typescript.push_str(&js_docs); self.typescript.push_str("export function "); self.typescript.push_str(&name); self.typescript.push_str(ts_sig); self.typescript.push_str(";\n"); } - self.export(&name, &format!("function{}", code), Some(&docs))?; + + self.export(&name, &format!("function{}", code), Some(&js_docs))?; self.globals.push_str("\n"); } AuxExportKind::Constructor(class) => { - let docs = format_doc_comments(&export.comments, Some(js_doc)); let exported = require_class(&mut self.exported_classes, class); + if exported.has_constructor { bail!("found duplicate constructor for class `{}`", class); } + exported.has_constructor = true; - exported.push(&docs, "constructor", "", &code, ts_sig); + exported.push(&js_docs, "constructor", "", &code, ts_sig); } AuxExportKind::Getter { class, field, .. } => { - let docs = format_doc_comments(&export.comments, None); + let ts_docs = format_doc_comments(&export.comments, None); let ret_ty = match export.generate_typescript { true => match &ts_ret_ty { Some(s) => Some(s.as_str()), @@ -2596,27 +2598,34 @@ impl<'a> Context<'a> { }, false => None, }; + let exported = require_class(&mut self.exported_classes, class); - exported.push_getter(&docs, field, &code, ret_ty); + exported.push_getter(&js_docs, &ts_docs, field, &code, ret_ty); } AuxExportKind::Setter { class, field, .. } => { - let docs = format_doc_comments(&export.comments, None); + let ts_docs = format_doc_comments(&export.comments, None); let arg_ty = match export.generate_typescript { true => Some(ts_arg_tys[0].as_str()), false => None, }; let exported = require_class(&mut self.exported_classes, class); - exported.push_setter(&docs, field, &code, arg_ty, might_be_optional_field); + + exported.push_setter( + &js_docs, + &ts_docs, + field, + &code, + arg_ty, + might_be_optional_field, + ); } AuxExportKind::StaticFunction { class, name } => { - let docs = format_doc_comments(&export.comments, Some(js_doc)); let exported = require_class(&mut self.exported_classes, class); - exported.push(&docs, name, "static ", &code, ts_sig); + exported.push(&js_docs, name, "static ", &code, ts_sig); } AuxExportKind::Method { class, name, .. } => { - let docs = format_doc_comments(&export.comments, Some(js_doc)); let exported = require_class(&mut self.exported_classes, class); - exported.push(&docs, name, "", &code, ts_sig); + exported.push(&js_docs, name, "", &code, ts_sig); } } } @@ -3836,11 +3845,20 @@ impl ExportedClass { /// Used for adding a getter to a class, mainly to ensure that TypeScript /// generation is handled specially. - fn push_getter(&mut self, docs: &str, field: &str, js: &str, ret_ty: Option<&str>) { - self.push_accessor(docs, field, js, "get "); + fn push_getter( + &mut self, + js_docs: &str, + ts_docs: &str, + field: &str, + js: &str, + ret_ty: Option<&str>, + ) { + self.push_accessor(js_docs, field, js, "get "); + if let Some(ret_ty) = ret_ty { - self.push_accessor_ts(docs, field, ret_ty, false); + self.push_accessor_ts(ts_docs, field, ret_ty, false); } + self.readable_properties.push(field.to_string()); } @@ -3848,15 +3866,17 @@ impl ExportedClass { /// generation is handled specially. fn push_setter( &mut self, - docs: &str, + js_docs: &str, + ts_docs: &str, field: &str, js: &str, ret_ty: Option<&str>, might_be_optional_field: bool, ) { - self.push_accessor(docs, field, js, "set "); + self.push_accessor(js_docs, field, js, "set "); + if let Some(ret_ty) = ret_ty { - let is_optional = self.push_accessor_ts(docs, field, ret_ty, true); + let is_optional = self.push_accessor_ts(ts_docs, field, ret_ty, true); *is_optional = might_be_optional_field; } }