Skip to content

Commit 720b9fe

Browse files
Make API for exporting JS content more explicit (#4333)
1 parent 6e09815 commit 720b9fe

File tree

1 file changed

+49
-27
lines changed
  • crates/cli-support/src/js

1 file changed

+49
-27
lines changed

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

+49-27
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,18 @@ struct FieldAccessor {
120120
is_optional: bool,
121121
}
122122

123+
/// Different JS constructs that can be exported.
124+
enum ExportJs<'a> {
125+
/// A class of the form `class Name {...}`.
126+
Class(&'a str),
127+
/// An anonymous function expression of the form `function(...) {...}`.
128+
///
129+
/// Note that the function name is not included in the string.
130+
Function(&'a str),
131+
/// An arbitrary JS expression.
132+
Expression(&'a str),
133+
}
134+
123135
const INITIAL_HEAP_VALUES: &[&str] = &["undefined", "null", "true", "false"];
124136
// Must be kept in sync with `src/lib.rs` of the `wasm-bindgen` crate
125137
const INITIAL_HEAP_OFFSET: usize = 128;
@@ -163,38 +175,46 @@ impl<'a> Context<'a> {
163175
fn export(
164176
&mut self,
165177
export_name: &str,
166-
contents: &str,
178+
export: ExportJs,
167179
comments: Option<&str>,
168180
) -> Result<(), Error> {
169181
let definition_name = self.generate_identifier(export_name);
170-
if contents.starts_with("class") && definition_name != export_name {
182+
if matches!(export, ExportJs::Class(_)) && definition_name != export_name {
171183
bail!("cannot shadow already defined class `{}`", export_name);
172184
}
173185

174-
let contents = contents.trim();
186+
// write out comments
175187
if let Some(c) = comments {
176188
self.globals.push_str(c);
177189
}
190+
178191
let global = match self.config.mode {
179-
OutputMode::Node { module: false } => {
180-
if contents.starts_with("class") {
181-
format!("{}\nmodule.exports.{1} = {1};\n", contents, export_name)
182-
} else {
183-
format!("module.exports.{} = {};\n", export_name, contents)
192+
OutputMode::Node { module: false } => match export {
193+
ExportJs::Class(class) => {
194+
format!("{}\nmodule.exports.{1} = {1};\n", class, export_name)
184195
}
185-
}
186-
OutputMode::NoModules { .. } => {
187-
if contents.starts_with("class") {
188-
format!("{}\n__exports.{1} = {1};\n", contents, export_name)
189-
} else {
190-
format!("__exports.{} = {};\n", export_name, contents)
196+
ExportJs::Function(expr) | ExportJs::Expression(expr) => {
197+
format!("module.exports.{} = {};\n", export_name, expr)
191198
}
192-
}
199+
},
200+
OutputMode::NoModules { .. } => match export {
201+
ExportJs::Class(class) => {
202+
format!("{}\n__exports.{1} = {1};\n", class, export_name)
203+
}
204+
ExportJs::Function(expr) | ExportJs::Expression(expr) => {
205+
format!("__exports.{} = {};\n", export_name, expr)
206+
}
207+
},
193208
OutputMode::Bundler { .. }
194209
| OutputMode::Node { module: true }
195210
| OutputMode::Web
196-
| OutputMode::Deno => {
197-
if let Some(body) = contents.strip_prefix("function") {
211+
| OutputMode::Deno => match export {
212+
ExportJs::Class(class) => {
213+
assert_eq!(export_name, definition_name);
214+
format!("export {}\n", class)
215+
}
216+
ExportJs::Function(function) => {
217+
let body = function.strip_prefix("function").unwrap();
198218
if export_name == definition_name {
199219
format!("export function {}{}\n", export_name, body)
200220
} else {
@@ -203,14 +223,12 @@ impl<'a> Context<'a> {
203223
definition_name, body, definition_name, export_name,
204224
)
205225
}
206-
} else if contents.starts_with("class") {
207-
assert_eq!(export_name, definition_name);
208-
format!("export {}\n", contents)
209-
} else {
226+
}
227+
ExportJs::Expression(expr) => {
210228
assert_eq!(export_name, definition_name);
211-
format!("export const {} = {};\n", export_name, contents)
229+
format!("export const {} = {};\n", export_name, expr)
212230
}
213-
}
231+
},
214232
};
215233
self.global(&global);
216234
Ok(())
@@ -1169,10 +1187,10 @@ __wbg_set_wasm(wasm);"
11691187

11701188
self.write_class_field_types(class, &mut ts_dst);
11711189

1172-
dst.push_str("}\n");
1190+
dst.push('}');
11731191
ts_dst.push_str("}\n");
11741192

1175-
self.export(name, &dst, Some(&class.comments))?;
1193+
self.export(name, ExportJs::Class(&dst), Some(&class.comments))?;
11761194

11771195
if class.generate_typescript {
11781196
self.typescript.push_str(&class.comments);
@@ -2872,7 +2890,11 @@ __wbg_set_wasm(wasm);"
28722890
self.typescript.push_str(";\n");
28732891
}
28742892

2875-
self.export(name, &format!("function{}", code), Some(&js_docs))?;
2893+
self.export(
2894+
name,
2895+
ExportJs::Function(&format!("function{}", code)),
2896+
Some(&js_docs),
2897+
)?;
28762898
self.globals.push('\n');
28772899
}
28782900
AuxExportKind::Constructor(class) => {
@@ -3995,7 +4017,7 @@ __wbg_set_wasm(wasm);"
39954017

39964018
self.export(
39974019
&enum_.name,
3998-
&format!("Object.freeze({{\n{}}})", variants),
4020+
ExportJs::Expression(&format!("Object.freeze({{\n{}}})", variants)),
39994021
Some(&docs),
40004022
)?;
40014023

0 commit comments

Comments
 (0)