Skip to content

Commit 7b55f3c

Browse files
committed
Add typescript attribute to prevent .d.ts emit
1 parent fb51d90 commit 7b55f3c

File tree

8 files changed

+131
-51
lines changed

8 files changed

+131
-51
lines changed

crates/backend/src/ast.rs

+4
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ pub struct Function {
222222
pub rust_attrs: Vec<syn::Attribute>,
223223
pub rust_vis: syn::Visibility,
224224
pub r#async: bool,
225+
pub generate_typescript: bool,
225226
}
226227

227228
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@@ -232,6 +233,7 @@ pub struct Struct {
232233
pub fields: Vec<StructField>,
233234
pub comments: Vec<String>,
234235
pub is_inspectable: bool,
236+
pub generate_typescript: bool,
235237
}
236238

237239
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@@ -245,6 +247,7 @@ pub struct StructField {
245247
pub setter: Ident,
246248
pub comments: Vec<String>,
247249
pub unstable_api: bool,
250+
pub generate_typescript: bool,
248251
}
249252

250253
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]
@@ -255,6 +258,7 @@ pub struct Enum {
255258
pub comments: Vec<String>,
256259
pub hole: u32,
257260
pub unstable_api: bool,
261+
pub generate_typescript: bool,
258262
}
259263

260264
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]

crates/backend/src/encode.rs

+4
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ fn shared_function<'a>(func: &'a ast::Function, _intern: &'a Interner) -> Functi
207207
Function {
208208
arg_names,
209209
name: &func.name,
210+
generate_typescript: func.generate_typescript,
210211
}
211212
}
212213

@@ -219,6 +220,7 @@ fn shared_enum<'a>(e: &'a ast::Enum, intern: &'a Interner) -> Enum<'a> {
219220
.map(|v| shared_variant(v, intern))
220221
.collect(),
221222
comments: e.comments.iter().map(|s| &**s).collect(),
223+
generate_typescript: e.generate_typescript,
222224
}
223225
}
224226

@@ -308,6 +310,7 @@ fn shared_struct<'a>(s: &'a ast::Struct, intern: &'a Interner) -> Struct<'a> {
308310
.collect(),
309311
comments: s.comments.iter().map(|s| &**s).collect(),
310312
is_inspectable: s.is_inspectable,
313+
generate_typescript: s.generate_typescript,
311314
}
312315
}
313316

@@ -319,6 +322,7 @@ fn shared_struct_field<'a>(s: &'a ast::StructField, intern: &'a Interner) -> Str
319322
},
320323
readonly: s.readonly,
321324
comments: s.comments.iter().map(|s| &**s).collect(),
325+
generate_typescript: s.generate_typescript,
322326
}
323327
}
324328

crates/cli-support/src/js/mod.rs

+81-44
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,16 @@ impl<'a> Context<'a> {
111111
&mut self,
112112
export_name: &str,
113113
contents: &str,
114-
comments: Option<String>,
114+
comments: Option<&str>,
115115
) -> Result<(), Error> {
116116
let definition_name = generate_identifier(export_name, &mut self.defined_identifiers);
117117
if contents.starts_with("class") && definition_name != export_name {
118118
bail!("cannot shadow already defined class `{}`", export_name);
119119
}
120120

121121
let contents = contents.trim();
122-
if let Some(ref c) = comments {
122+
if let Some(c) = comments {
123123
self.globals.push_str(c);
124-
self.typescript.push_str(c);
125124
}
126125
let global = match self.config.mode {
127126
OutputMode::Node {
@@ -721,7 +720,7 @@ impl<'a> Context<'a> {
721720
dst.push_str("}\n");
722721
ts_dst.push_str("}\n");
723722

724-
self.export(&name, &dst, Some(class.comments.clone()))?;
723+
self.export(&name, &dst, Some(&class.comments))?;
725724
self.typescript.push_str(&ts_dst);
726725

727726
Ok(())
@@ -2067,41 +2066,58 @@ impl<'a> Context<'a> {
20672066
// on what's being exported.
20682067
match kind {
20692068
Kind::Export(export) => {
2069+
let ts_sig = match export.generate_typescript {
2070+
true => Some(ts_sig.as_str()),
2071+
false => None
2072+
};
2073+
20702074
let docs = format_doc_comments(&export.comments, Some(js_doc));
20712075
match &export.kind {
20722076
AuxExportKind::Function(name) => {
2073-
self.export(&name, &format!("function{}", code), Some(docs))?;
2077+
if let Some(ts_sig) = ts_sig {
2078+
self.typescript.push_str(&docs);
2079+
self.typescript.push_str("export function ");
2080+
self.typescript.push_str(&name);
2081+
self.typescript.push_str(ts_sig);
2082+
self.typescript.push_str(";\n");
2083+
}
2084+
self.export(&name, &format!("function{}", code), Some(&docs))?;
20742085
self.globals.push_str("\n");
2075-
self.typescript.push_str("export function ");
2076-
self.typescript.push_str(&name);
2077-
self.typescript.push_str(&ts_sig);
2078-
self.typescript.push_str(";\n");
20792086
}
20802087
AuxExportKind::Constructor(class) => {
20812088
let exported = require_class(&mut self.exported_classes, class);
20822089
if exported.has_constructor {
20832090
bail!("found duplicate constructor for class `{}`", class);
20842091
}
20852092
exported.has_constructor = true;
2086-
exported.push(&docs, "constructor", "", &code, &ts_sig);
2093+
exported.push(&docs, "constructor", "", &code, ts_sig);
20872094
}
20882095
AuxExportKind::Getter { class, field } => {
2089-
let ret_ty = ts_ret_ty.unwrap();
2096+
let ret_ty = match export.generate_typescript {
2097+
true => match &ts_ret_ty {
2098+
Some(s) => Some(s.as_str()),
2099+
_ => None,
2100+
},
2101+
false => None
2102+
};
20902103
let exported = require_class(&mut self.exported_classes, class);
2091-
exported.push_getter(&docs, field, &code, &ret_ty);
2104+
exported.push_getter(&docs, field, &code, ret_ty);
20922105
}
20932106
AuxExportKind::Setter { class, field } => {
2094-
let arg_ty = ts_arg_tys[0].clone();
2107+
let arg_ty = match export.generate_typescript {
2108+
true => Some(ts_arg_tys[0].as_str()),
2109+
false => None
2110+
};
20952111
let exported = require_class(&mut self.exported_classes, class);
2096-
exported.push_setter(&docs, field, &code, &arg_ty, might_be_optional_field);
2112+
exported.push_setter(&docs, field, &code, arg_ty, might_be_optional_field);
20972113
}
20982114
AuxExportKind::StaticFunction { class, name } => {
20992115
let exported = require_class(&mut self.exported_classes, class);
2100-
exported.push(&docs, name, "static ", &code, &ts_sig);
2116+
exported.push(&docs, name, "static ", &code, ts_sig);
21012117
}
21022118
AuxExportKind::Method { class, name, .. } => {
21032119
let exported = require_class(&mut self.exported_classes, class);
2104-
exported.push(&docs, name, "", &code, &ts_sig);
2120+
exported.push(&docs, name, "", &code, ts_sig);
21052121
}
21062122
}
21072123
}
@@ -2780,19 +2796,27 @@ impl<'a> Context<'a> {
27802796
}
27812797

27822798
fn generate_enum(&mut self, enum_: &AuxEnum) -> Result<(), Error> {
2799+
let docs = format_doc_comments(&enum_.comments, None);
27832800
let mut variants = String::new();
27842801

2785-
self.typescript
2786-
.push_str(&format!("export enum {} {{", enum_.name));
2802+
if enum_.generate_typescript {
2803+
self.typescript.push_str(&docs);
2804+
self.typescript
2805+
.push_str(&format!("export enum {} {{", enum_.name));
2806+
}
27872807
for (name, value) in enum_.variants.iter() {
27882808
variants.push_str(&format!("{}:{},", name, value));
2789-
self.typescript.push_str(&format!("\n {},", name));
2809+
if enum_.generate_typescript {
2810+
self.typescript.push_str(&format!("\n {},", name));
2811+
}
2812+
}
2813+
if enum_.generate_typescript {
2814+
self.typescript.push_str("\n}\n");
27902815
}
2791-
self.typescript.push_str("\n}\n");
27922816
self.export(
27932817
&enum_.name,
27942818
&format!("Object.freeze({{ {} }})", variants),
2795-
Some(format_doc_comments(&enum_.comments, None)),
2819+
Some(&docs),
27962820
)?;
27972821

27982822
Ok(())
@@ -3078,24 +3102,29 @@ fn require_class<'a>(
30783102
}
30793103

30803104
impl ExportedClass {
3081-
fn push(&mut self, docs: &str, function_name: &str, function_prefix: &str, js: &str, ts: &str) {
3105+
fn push(&mut self, docs: &str, function_name: &str, function_prefix: &str, js: &str, ts: Option<&str>) {
30823106
self.contents.push_str(docs);
30833107
self.contents.push_str(function_prefix);
30843108
self.contents.push_str(function_name);
30853109
self.contents.push_str(js);
30863110
self.contents.push_str("\n");
3087-
self.typescript.push_str(docs);
3088-
self.typescript.push_str(" ");
3089-
self.typescript.push_str(function_prefix);
3090-
self.typescript.push_str(function_name);
3091-
self.typescript.push_str(ts);
3092-
self.typescript.push_str(";\n");
3111+
if let Some(ts) = ts {
3112+
self.typescript.push_str(docs);
3113+
self.typescript.push_str(" ");
3114+
self.typescript.push_str(function_prefix);
3115+
self.typescript.push_str(function_name);
3116+
self.typescript.push_str(ts);
3117+
self.typescript.push_str(";\n");
3118+
}
30933119
}
30943120

30953121
/// Used for adding a getter to a class, mainly to ensure that TypeScript
30963122
/// generation is handled specially.
3097-
fn push_getter(&mut self, docs: &str, field: &str, js: &str, ret_ty: &str) {
3098-
self.push_accessor(docs, field, js, "get ", ret_ty);
3123+
fn push_getter(&mut self, docs: &str, field: &str, js: &str, ret_ty: Option<&str>) {
3124+
self.push_accessor(docs, field, js, "get ");
3125+
if let Some(ret_ty) = ret_ty {
3126+
self.push_accessor_ts(field, ret_ty);
3127+
}
30993128
self.readable_properties.push(field.to_string());
31003129
}
31013130

@@ -3106,28 +3135,22 @@ impl ExportedClass {
31063135
docs: &str,
31073136
field: &str,
31083137
js: &str,
3109-
ret_ty: &str,
3138+
ret_ty: Option<&str>,
31103139
might_be_optional_field: bool,
31113140
) {
3112-
let (has_setter, is_optional) = self.push_accessor(docs, field, js, "set ", ret_ty);
3113-
*has_setter = true;
3114-
*is_optional = might_be_optional_field;
3141+
self.push_accessor(docs, field, js, "set ");
3142+
if let Some(ret_ty) = ret_ty {
3143+
let (has_setter, is_optional) = self.push_accessor_ts(field, ret_ty);
3144+
*has_setter = true;
3145+
*is_optional = might_be_optional_field;
3146+
}
31153147
}
31163148

3117-
fn push_accessor(
3149+
fn push_accessor_ts(
31183150
&mut self,
3119-
docs: &str,
31203151
field: &str,
3121-
js: &str,
3122-
prefix: &str,
31233152
ret_ty: &str,
31243153
) -> (&mut bool, &mut bool) {
3125-
self.contents.push_str(docs);
3126-
self.contents.push_str(prefix);
3127-
self.contents.push_str(field);
3128-
self.contents.push_str(js);
3129-
self.contents.push_str("\n");
3130-
31313154
let (ty, has_setter, is_optional) = self
31323155
.typescript_fields
31333156
.entry(field.to_string())
@@ -3136,6 +3159,20 @@ impl ExportedClass {
31363159
*ty = ret_ty.to_string();
31373160
(has_setter, is_optional)
31383161
}
3162+
3163+
fn push_accessor(
3164+
&mut self,
3165+
docs: &str,
3166+
field: &str,
3167+
js: &str,
3168+
prefix: &str,
3169+
) {
3170+
self.contents.push_str(docs);
3171+
self.contents.push_str(prefix);
3172+
self.contents.push_str(field);
3173+
self.contents.push_str(js);
3174+
self.contents.push_str("\n");
3175+
}
31393176
}
31403177

31413178
#[test]

crates/cli-support/src/wit/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ impl<'a> Context<'a> {
456456
comments: concatenate_comments(&export.comments),
457457
arg_names: Some(export.function.arg_names),
458458
kind,
459+
generate_typescript: export.function.generate_typescript,
459460
},
460461
);
461462
Ok(())
@@ -769,6 +770,7 @@ impl<'a> Context<'a> {
769770
.iter()
770771
.map(|v| (v.name.to_string(), v.value))
771772
.collect(),
773+
generate_typescript: enum_.generate_typescript,
772774
};
773775
self.aux.enums.push(aux);
774776
Ok(())
@@ -801,6 +803,7 @@ impl<'a> Context<'a> {
801803
class: struct_.name.to_string(),
802804
field: field.name.to_string(),
803805
},
806+
generate_typescript: struct_.generate_typescript,
804807
},
805808
);
806809

@@ -826,13 +829,15 @@ impl<'a> Context<'a> {
826829
class: struct_.name.to_string(),
827830
field: field.name.to_string(),
828831
},
832+
generate_typescript: field.generate_typescript,
829833
},
830834
);
831835
}
832836
let aux = AuxStruct {
833837
name: struct_.name.to_string(),
834838
comments: concatenate_comments(&struct_.comments),
835839
is_inspectable: struct_.is_inspectable,
840+
generate_typescript: struct_.generate_typescript,
836841
};
837842
self.aux.structs.push(aux);
838843

@@ -1050,6 +1055,7 @@ impl<'a> Context<'a> {
10501055
comments: String::new(),
10511056
arg_names: None,
10521057
kind,
1058+
generate_typescript: true,
10531059
};
10541060
assert!(self.aux.export_map.insert(id, export).is_none());
10551061
}

crates/cli-support/src/wit/nonstandard.rs

+7
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ pub struct AuxExport {
7373
pub arg_names: Option<Vec<String>>,
7474
/// What kind of function this is and where it shows up
7575
pub kind: AuxExportKind,
76+
/// Whether typescript bindings should be generated for this export.
77+
pub generate_typescript: bool,
7678
}
7779

7880
/// All possible kinds of exports from a wasm module.
@@ -131,7 +133,10 @@ pub struct AuxEnum {
131133
/// The copied Rust comments to forward to JS
132134
pub comments: String,
133135
/// A list of variants with their name and value
136+
/// and whether typescript bindings should be generated for each variant
134137
pub variants: Vec<(String, u32)>,
138+
/// Whether typescript bindings should be generated for this enum.
139+
pub generate_typescript: bool,
135140
}
136141

137142
#[derive(Debug)]
@@ -142,6 +147,8 @@ pub struct AuxStruct {
142147
pub comments: String,
143148
/// Whether to generate helper methods for inspecting the class
144149
pub is_inspectable: bool,
150+
/// Whether typescript bindings should be generated for this struct.
151+
pub generate_typescript: bool,
145152
}
146153

147154
/// All possible types of imports that can be imported by a wasm module.

0 commit comments

Comments
 (0)