mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-13 04:51:23 +00:00
Add skip_typescript attribute to prevent .d.ts emit (#2016)
* Add skip_typescript attribute to prevent .d.ts emit * Add guide page for typescript attribute
This commit is contained in:
@ -111,7 +111,7 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
export_name: &str,
|
||||
contents: &str,
|
||||
comments: Option<String>,
|
||||
comments: Option<&str>,
|
||||
) -> Result<(), Error> {
|
||||
let definition_name = generate_identifier(export_name, &mut self.defined_identifiers);
|
||||
if contents.starts_with("class") && definition_name != export_name {
|
||||
@ -119,9 +119,8 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
let contents = contents.trim();
|
||||
if let Some(ref c) = comments {
|
||||
if let Some(c) = comments {
|
||||
self.globals.push_str(c);
|
||||
self.typescript.push_str(c);
|
||||
}
|
||||
let global = match self.config.mode {
|
||||
OutputMode::Node {
|
||||
@ -804,7 +803,7 @@ impl<'a> Context<'a> {
|
||||
dst.push_str("}\n");
|
||||
ts_dst.push_str("}\n");
|
||||
|
||||
self.export(&name, &dst, Some(class.comments.clone()))?;
|
||||
self.export(&name, &dst, Some(&class.comments))?;
|
||||
self.typescript.push_str(&ts_dst);
|
||||
|
||||
Ok(())
|
||||
@ -2153,15 +2152,23 @@ impl<'a> Context<'a> {
|
||||
// on what's being exported.
|
||||
match kind {
|
||||
Kind::Export(export) => {
|
||||
let ts_sig = match export.generate_typescript {
|
||||
true => Some(ts_sig.as_str()),
|
||||
false => None,
|
||||
};
|
||||
|
||||
let docs = format_doc_comments(&export.comments, Some(js_doc));
|
||||
match &export.kind {
|
||||
AuxExportKind::Function(name) => {
|
||||
self.export(&name, &format!("function{}", code), Some(docs))?;
|
||||
if let Some(ts_sig) = ts_sig {
|
||||
self.typescript.push_str(&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.globals.push_str("\n");
|
||||
self.typescript.push_str("export function ");
|
||||
self.typescript.push_str(&name);
|
||||
self.typescript.push_str(&ts_sig);
|
||||
self.typescript.push_str(";\n");
|
||||
}
|
||||
AuxExportKind::Constructor(class) => {
|
||||
let exported = require_class(&mut self.exported_classes, class);
|
||||
@ -2169,25 +2176,34 @@ impl<'a> Context<'a> {
|
||||
bail!("found duplicate constructor for class `{}`", class);
|
||||
}
|
||||
exported.has_constructor = true;
|
||||
exported.push(&docs, "constructor", "", &code, &ts_sig);
|
||||
exported.push(&docs, "constructor", "", &code, ts_sig);
|
||||
}
|
||||
AuxExportKind::Getter { class, field } => {
|
||||
let ret_ty = ts_ret_ty.unwrap();
|
||||
let ret_ty = match export.generate_typescript {
|
||||
true => match &ts_ret_ty {
|
||||
Some(s) => Some(s.as_str()),
|
||||
_ => None,
|
||||
},
|
||||
false => None,
|
||||
};
|
||||
let exported = require_class(&mut self.exported_classes, class);
|
||||
exported.push_getter(&docs, field, &code, &ret_ty);
|
||||
exported.push_getter(&docs, field, &code, ret_ty);
|
||||
}
|
||||
AuxExportKind::Setter { class, field } => {
|
||||
let arg_ty = ts_arg_tys[0].clone();
|
||||
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(&docs, field, &code, arg_ty, might_be_optional_field);
|
||||
}
|
||||
AuxExportKind::StaticFunction { class, name } => {
|
||||
let exported = require_class(&mut self.exported_classes, class);
|
||||
exported.push(&docs, name, "static ", &code, &ts_sig);
|
||||
exported.push(&docs, name, "static ", &code, ts_sig);
|
||||
}
|
||||
AuxExportKind::Method { class, name, .. } => {
|
||||
let exported = require_class(&mut self.exported_classes, class);
|
||||
exported.push(&docs, name, "", &code, &ts_sig);
|
||||
exported.push(&docs, name, "", &code, ts_sig);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2865,19 +2881,27 @@ impl<'a> Context<'a> {
|
||||
}
|
||||
|
||||
fn generate_enum(&mut self, enum_: &AuxEnum) -> Result<(), Error> {
|
||||
let docs = format_doc_comments(&enum_.comments, None);
|
||||
let mut variants = String::new();
|
||||
|
||||
self.typescript
|
||||
.push_str(&format!("export enum {} {{", enum_.name));
|
||||
if enum_.generate_typescript {
|
||||
self.typescript.push_str(&docs);
|
||||
self.typescript
|
||||
.push_str(&format!("export enum {} {{", enum_.name));
|
||||
}
|
||||
for (name, value) in enum_.variants.iter() {
|
||||
variants.push_str(&format!("{}:{},", name, value));
|
||||
self.typescript.push_str(&format!("\n {},", name));
|
||||
if enum_.generate_typescript {
|
||||
self.typescript.push_str(&format!("\n {},", name));
|
||||
}
|
||||
}
|
||||
if enum_.generate_typescript {
|
||||
self.typescript.push_str("\n}\n");
|
||||
}
|
||||
self.typescript.push_str("\n}\n");
|
||||
self.export(
|
||||
&enum_.name,
|
||||
&format!("Object.freeze({{ {} }})", variants),
|
||||
Some(format_doc_comments(&enum_.comments, None)),
|
||||
Some(&docs),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
@ -3163,24 +3187,36 @@ fn require_class<'a>(
|
||||
}
|
||||
|
||||
impl ExportedClass {
|
||||
fn push(&mut self, docs: &str, function_name: &str, function_prefix: &str, js: &str, ts: &str) {
|
||||
fn push(
|
||||
&mut self,
|
||||
docs: &str,
|
||||
function_name: &str,
|
||||
function_prefix: &str,
|
||||
js: &str,
|
||||
ts: Option<&str>,
|
||||
) {
|
||||
self.contents.push_str(docs);
|
||||
self.contents.push_str(function_prefix);
|
||||
self.contents.push_str(function_name);
|
||||
self.contents.push_str(js);
|
||||
self.contents.push_str("\n");
|
||||
self.typescript.push_str(docs);
|
||||
self.typescript.push_str(" ");
|
||||
self.typescript.push_str(function_prefix);
|
||||
self.typescript.push_str(function_name);
|
||||
self.typescript.push_str(ts);
|
||||
self.typescript.push_str(";\n");
|
||||
if let Some(ts) = ts {
|
||||
self.typescript.push_str(docs);
|
||||
self.typescript.push_str(" ");
|
||||
self.typescript.push_str(function_prefix);
|
||||
self.typescript.push_str(function_name);
|
||||
self.typescript.push_str(ts);
|
||||
self.typescript.push_str(";\n");
|
||||
}
|
||||
}
|
||||
|
||||
/// 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: &str) {
|
||||
self.push_accessor(docs, field, js, "get ", ret_ty);
|
||||
fn push_getter(&mut self, docs: &str, field: &str, js: &str, ret_ty: Option<&str>) {
|
||||
self.push_accessor(docs, field, js, "get ");
|
||||
if let Some(ret_ty) = ret_ty {
|
||||
self.push_accessor_ts(field, ret_ty);
|
||||
}
|
||||
self.readable_properties.push(field.to_string());
|
||||
}
|
||||
|
||||
@ -3191,28 +3227,18 @@ impl ExportedClass {
|
||||
docs: &str,
|
||||
field: &str,
|
||||
js: &str,
|
||||
ret_ty: &str,
|
||||
ret_ty: Option<&str>,
|
||||
might_be_optional_field: bool,
|
||||
) {
|
||||
let (has_setter, is_optional) = self.push_accessor(docs, field, js, "set ", ret_ty);
|
||||
*has_setter = true;
|
||||
*is_optional = might_be_optional_field;
|
||||
self.push_accessor(docs, field, js, "set ");
|
||||
if let Some(ret_ty) = ret_ty {
|
||||
let (has_setter, is_optional) = self.push_accessor_ts(field, ret_ty);
|
||||
*has_setter = true;
|
||||
*is_optional = might_be_optional_field;
|
||||
}
|
||||
}
|
||||
|
||||
fn push_accessor(
|
||||
&mut self,
|
||||
docs: &str,
|
||||
field: &str,
|
||||
js: &str,
|
||||
prefix: &str,
|
||||
ret_ty: &str,
|
||||
) -> (&mut bool, &mut bool) {
|
||||
self.contents.push_str(docs);
|
||||
self.contents.push_str(prefix);
|
||||
self.contents.push_str(field);
|
||||
self.contents.push_str(js);
|
||||
self.contents.push_str("\n");
|
||||
|
||||
fn push_accessor_ts(&mut self, field: &str, ret_ty: &str) -> (&mut bool, &mut bool) {
|
||||
let (ty, has_setter, is_optional) = self
|
||||
.typescript_fields
|
||||
.entry(field.to_string())
|
||||
@ -3221,6 +3247,14 @@ impl ExportedClass {
|
||||
*ty = ret_ty.to_string();
|
||||
(has_setter, is_optional)
|
||||
}
|
||||
|
||||
fn push_accessor(&mut self, docs: &str, field: &str, js: &str, prefix: &str) {
|
||||
self.contents.push_str(docs);
|
||||
self.contents.push_str(prefix);
|
||||
self.contents.push_str(field);
|
||||
self.contents.push_str(js);
|
||||
self.contents.push_str("\n");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -454,6 +454,7 @@ impl<'a> Context<'a> {
|
||||
comments: concatenate_comments(&export.comments),
|
||||
arg_names: Some(export.function.arg_names),
|
||||
kind,
|
||||
generate_typescript: export.function.generate_typescript,
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
@ -767,6 +768,7 @@ impl<'a> Context<'a> {
|
||||
.iter()
|
||||
.map(|v| (v.name.to_string(), v.value))
|
||||
.collect(),
|
||||
generate_typescript: enum_.generate_typescript,
|
||||
};
|
||||
self.aux.enums.push(aux);
|
||||
Ok(())
|
||||
@ -799,6 +801,7 @@ impl<'a> Context<'a> {
|
||||
class: struct_.name.to_string(),
|
||||
field: field.name.to_string(),
|
||||
},
|
||||
generate_typescript: field.generate_typescript,
|
||||
},
|
||||
);
|
||||
|
||||
@ -824,6 +827,7 @@ impl<'a> Context<'a> {
|
||||
class: struct_.name.to_string(),
|
||||
field: field.name.to_string(),
|
||||
},
|
||||
generate_typescript: field.generate_typescript,
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -831,6 +835,7 @@ impl<'a> Context<'a> {
|
||||
name: struct_.name.to_string(),
|
||||
comments: concatenate_comments(&struct_.comments),
|
||||
is_inspectable: struct_.is_inspectable,
|
||||
generate_typescript: struct_.generate_typescript,
|
||||
};
|
||||
self.aux.structs.push(aux);
|
||||
|
||||
@ -1048,6 +1053,7 @@ impl<'a> Context<'a> {
|
||||
comments: String::new(),
|
||||
arg_names: None,
|
||||
kind,
|
||||
generate_typescript: true,
|
||||
};
|
||||
assert!(self.aux.export_map.insert(id, export).is_none());
|
||||
}
|
||||
|
@ -73,6 +73,8 @@ pub struct AuxExport {
|
||||
pub arg_names: Option<Vec<String>>,
|
||||
/// What kind of function this is and where it shows up
|
||||
pub kind: AuxExportKind,
|
||||
/// Whether typescript bindings should be generated for this export.
|
||||
pub generate_typescript: bool,
|
||||
}
|
||||
|
||||
/// All possible kinds of exports from a wasm module.
|
||||
@ -131,7 +133,10 @@ pub struct AuxEnum {
|
||||
/// The copied Rust comments to forward to JS
|
||||
pub comments: String,
|
||||
/// A list of variants with their name and value
|
||||
/// and whether typescript bindings should be generated for each variant
|
||||
pub variants: Vec<(String, u32)>,
|
||||
/// Whether typescript bindings should be generated for this enum.
|
||||
pub generate_typescript: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -142,6 +147,8 @@ pub struct AuxStruct {
|
||||
pub comments: String,
|
||||
/// Whether to generate helper methods for inspecting the class
|
||||
pub is_inspectable: bool,
|
||||
/// Whether typescript bindings should be generated for this struct.
|
||||
pub generate_typescript: bool,
|
||||
}
|
||||
|
||||
/// All possible types of imports that can be imported by a wasm module.
|
||||
|
Reference in New Issue
Block a user