1use swc_common::Spanned;
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::node_impl;
4
5#[cfg(swc_ast_unknown)]
6use crate::unknown_error;
7use crate::{util::StartsWithAlphaNum, ListFormat};
8
9#[node_impl]
10impl MacroNode for ModuleDecl {
11 fn emit(&mut self, emitter: &mut Macro) -> Result {
12 emitter.emit_leading_comments_of_span(self.span(), false)?;
13
14 match self {
15 ModuleDecl::Import(ref d) => emit!(d),
16 ModuleDecl::ExportDecl(ref d) => emit!(d),
17 ModuleDecl::ExportNamed(ref d) => emit!(d),
18 ModuleDecl::ExportDefaultDecl(ref d) => emit!(d),
19 ModuleDecl::ExportDefaultExpr(ref n) => emit!(n),
20 ModuleDecl::ExportAll(ref d) => emit!(d),
21 ModuleDecl::TsExportAssignment(ref n) => emit!(n),
22 ModuleDecl::TsImportEquals(ref n) => emit!(n),
23 ModuleDecl::TsNamespaceExport(ref n) => emit!(n),
24 #[cfg(swc_ast_unknown)]
25 _ => return Err(unknown_error()),
26 }
27
28 emitter.emit_trailing_comments_of_pos(self.span().hi, true, true)?;
29
30 if !emitter.cfg.minify {
31 emitter.wr.write_line()?;
32 }
33
34 Ok(())
35 }
36}
37
38#[node_impl]
39impl MacroNode for ExportDecl {
40 fn emit(&mut self, emitter: &mut Macro) -> Result {
41 srcmap!(emitter, self, true);
42
43 match &self.decl {
44 Decl::Class(decl) => {
45 for dec in &decl.class.decorators {
46 emit!(dec);
47 }
48
49 keyword!(emitter, "export");
50
51 space!(emitter);
52 emitter.emit_class_decl_inner(decl, true)?;
53 }
54 _ => {
55 keyword!(emitter, "export");
56
57 space!(emitter);
58 emit!(self.decl);
59 }
60 }
61
62 Ok(())
63 }
64}
65
66#[node_impl]
67impl MacroNode for ExportDefaultExpr {
68 fn emit(&mut self, emitter: &mut Macro) -> Result {
69 srcmap!(emitter, self, true);
70
71 keyword!(emitter, "export");
72
73 space!(emitter);
74 keyword!(emitter, "default");
75 {
76 let starts_with_alpha_num = self.expr.starts_with_alpha_num();
77 if starts_with_alpha_num {
78 space!(emitter);
79 } else {
80 formatting_space!(emitter);
81 }
82 emit!(self.expr);
83 }
84 semi!(emitter);
85
86 srcmap!(emitter, self, false);
87
88 Ok(())
89 }
90}
91
92#[node_impl]
93impl MacroNode for ExportDefaultDecl {
94 fn emit(&mut self, emitter: &mut Macro) -> Result {
95 emitter.emit_leading_comments_of_span(self.span(), false)?;
96
97 srcmap!(emitter, self, true);
98
99 keyword!(emitter, "export");
100
101 space!(emitter);
102 keyword!(emitter, "default");
103 space!(emitter);
104 match self.decl {
105 DefaultDecl::Class(ref n) => emit!(n),
106 DefaultDecl::Fn(ref n) => emit!(n),
107 DefaultDecl::TsInterfaceDecl(ref n) => emit!(n),
108 #[cfg(swc_ast_unknown)]
109 _ => return Err(unknown_error()),
110 }
111
112 Ok(())
113 }
114}
115
116#[node_impl]
117impl MacroNode for ImportDecl {
118 fn emit(&mut self, emitter: &mut Macro) -> Result {
119 emitter.emit_leading_comments_of_span(self.span(), false)?;
120
121 srcmap!(emitter, self, true);
122
123 keyword!(emitter, "import");
124
125 if self.type_only {
126 space!(emitter);
127 keyword!(emitter, "type");
128 }
129
130 match self.phase {
131 ImportPhase::Evaluation => {}
132 ImportPhase::Source => {
133 space!(emitter);
134 keyword!(emitter, "source");
135 }
136 ImportPhase::Defer => {
137 space!(emitter);
138 keyword!(emitter, "defer");
139 }
140 #[cfg(swc_ast_unknown)]
141 _ => return Err(unknown_error()),
142 }
143
144 let starts_with_ident = !self.specifiers.is_empty()
145 && match &self.specifiers[0] {
146 ImportSpecifier::Default(_) => true,
147 _ => false,
148 };
149 if starts_with_ident {
150 space!(emitter);
151 } else {
152 formatting_space!(emitter);
153 }
154
155 let mut specifiers = Vec::new();
156 let mut emitted_default = false;
157 let mut emitted_ns = false;
158 for specifier in &self.specifiers {
159 match specifier {
160 ImportSpecifier::Named(ref s) => {
161 specifiers.push(s);
162 }
163 ImportSpecifier::Default(ref s) => {
164 emit!(s.local);
165 emitted_default = true;
166 }
167 ImportSpecifier::Namespace(ref ns) => {
168 if emitted_default {
169 punct!(emitter, ",");
170 formatting_space!(emitter);
171 }
172
173 emitted_ns = true;
174
175 assert!(self.specifiers.len() <= 2);
176 punct!(emitter, "*");
177 formatting_space!(emitter);
178 keyword!(emitter, "as");
179 space!(emitter);
180 emit!(ns.local);
181 }
182 #[cfg(swc_ast_unknown)]
183 _ => return Err(unknown_error()),
184 }
185 }
186
187 if specifiers.is_empty() {
188 if emitted_ns || emitted_default {
189 space!(emitter);
190 keyword!(emitter, "from");
191 formatting_space!(emitter);
192 }
193 } else {
194 if emitted_default {
195 punct!(emitter, ",");
196 formatting_space!(emitter);
197 }
198
199 punct!(emitter, "{");
200 emitter.emit_list(
201 self.span(),
202 Some(&specifiers),
203 ListFormat::NamedImportsOrExportsElements,
204 )?;
205 punct!(emitter, "}");
206 formatting_space!(emitter);
207
208 keyword!(emitter, "from");
209 formatting_space!(emitter);
210 }
211
212 emit!(self.src);
213
214 if let Some(with) = &self.with {
215 formatting_space!(emitter);
216 if emitter.cfg.emit_assert_for_import_attributes {
217 keyword!(emitter, "assert");
218 } else {
219 keyword!(emitter, "with")
220 };
221 formatting_space!(emitter);
222 emit!(with);
223 }
224
225 semi!(emitter);
226
227 srcmap!(emitter, self, false);
228
229 Ok(())
230 }
231}
232
233#[node_impl]
234impl MacroNode for ImportNamedSpecifier {
235 fn emit(&mut self, emitter: &mut Macro) -> Result {
236 srcmap!(emitter, self, true);
237
238 if self.is_type_only {
239 keyword!(emitter, "type");
240 space!(emitter);
241 }
242
243 if let Some(ref imported) = self.imported {
244 emit!(imported);
245 space!(emitter);
246 keyword!(emitter, "as");
247 space!(emitter);
248 }
249
250 emit!(self.local);
251
252 srcmap!(emitter, self, false);
253
254 Ok(())
255 }
256}
257
258#[node_impl]
259impl MacroNode for ExportSpecifier {
260 fn emit(&mut self, emitter: &mut Macro) -> Result {
261 match self {
262 ExportSpecifier::Default(..) => {
263 unimplemented!("codegen of `export default from 'foo';`")
264 }
265 ExportSpecifier::Namespace(ref node) => emit!(node),
266 ExportSpecifier::Named(ref node) => emit!(node),
267 #[cfg(swc_ast_unknown)]
268 _ => return Err(unknown_error()),
269 }
270
271 Ok(())
272 }
273}
274
275#[node_impl]
276impl MacroNode for ExportNamespaceSpecifier {
277 fn emit(&mut self, emitter: &mut Macro) -> Result {
278 emitter.emit_leading_comments_of_span(self.span(), false)?;
279
280 srcmap!(emitter, self, true);
281
282 punct!(emitter, "*");
283 formatting_space!(emitter);
284 keyword!(emitter, "as");
285 space!(emitter);
286 emit!(self.name);
287
288 srcmap!(emitter, self, false);
289
290 Ok(())
291 }
292}
293
294#[node_impl]
295impl MacroNode for ExportNamedSpecifier {
296 fn emit(&mut self, emitter: &mut Macro) -> Result {
297 emitter.emit_leading_comments_of_span(self.span(), false)?;
298
299 srcmap!(emitter, self, true);
300
301 if self.is_type_only {
302 keyword!(emitter, "type");
303 space!(emitter);
304 }
305
306 if let Some(exported) = &self.exported {
307 emit!(self.orig);
308 space!(emitter);
309 keyword!(emitter, "as");
310 space!(emitter);
311 emit!(exported);
312 } else {
313 emit!(self.orig);
314 }
315 srcmap!(emitter, self, false);
316
317 Ok(())
318 }
319}
320
321#[node_impl]
322impl MacroNode for NamedExport {
323 fn emit(&mut self, emitter: &mut Macro) -> Result {
324 emitter.emit_leading_comments_of_span(self.span(), false)?;
325
326 srcmap!(emitter, self, true);
327
328 struct Specifiers<'a> {
329 has_namespace_spec: bool,
330 namespace_spec: Option<&'a ExportNamespaceSpecifier>,
331 has_named_specs: bool,
332 named_specs: Vec<&'a ExportSpecifier>,
333 }
334 let Specifiers {
335 has_namespace_spec,
336 namespace_spec,
337 has_named_specs,
338 named_specs,
339 } = self.specifiers.iter().fold(
340 Specifiers {
341 has_namespace_spec: false,
342 namespace_spec: None,
343 has_named_specs: false,
344 named_specs: Vec::new(),
345 },
346 |mut result, s| match s {
347 ExportSpecifier::Namespace(spec) => {
348 result.has_namespace_spec = true;
349 if result.namespace_spec.is_none() {
351 result.namespace_spec = Some(spec)
352 }
353 result
354 }
355 spec => {
356 result.has_named_specs = true;
357 result.named_specs.push(spec);
358 result
359 }
360 },
361 );
362
363 keyword!(emitter, "export");
364
365 if self.type_only {
366 space!(emitter);
367 keyword!(emitter, "type");
368 }
369 formatting_space!(emitter);
370
371 if let Some(spec) = namespace_spec {
372 emit!(spec);
373 if has_named_specs {
374 punct!(emitter, ",");
375 formatting_space!(emitter);
376 }
377 }
378 if has_named_specs || !has_namespace_spec {
379 punct!(emitter, "{");
380 emitter.emit_list(
381 self.span,
382 Some(&named_specs),
383 ListFormat::NamedImportsOrExportsElements,
384 )?;
385 punct!(emitter, "}");
386 }
387
388 if let Some(ref src) = self.src {
389 if has_named_specs || !has_namespace_spec {
390 formatting_space!(emitter);
391 } else if has_namespace_spec {
392 space!(emitter);
393 }
394 keyword!(emitter, "from");
395 formatting_space!(emitter);
396 emit!(src);
397
398 if let Some(with) = &self.with {
399 formatting_space!(emitter);
400 if emitter.cfg.emit_assert_for_import_attributes {
401 keyword!(emitter, "assert");
402 } else {
403 keyword!(emitter, "with")
404 };
405 formatting_space!(emitter);
406 emit!(with);
407 }
408 }
409 semi!(emitter);
410
411 srcmap!(emitter, self, false);
412
413 Ok(())
414 }
415}
416
417#[node_impl]
418impl MacroNode for ExportAll {
419 fn emit(&mut self, emitter: &mut Macro) -> Result {
420 emitter.emit_leading_comments_of_span(self.span(), false)?;
421
422 srcmap!(emitter, self, true);
423
424 keyword!(emitter, "export");
425
426 if self.type_only {
427 space!(emitter);
428 keyword!(emitter, "type");
429 space!(emitter);
430 } else {
431 formatting_space!(emitter);
432 }
433
434 punct!(emitter, "*");
435 formatting_space!(emitter);
436 keyword!(emitter, "from");
437 formatting_space!(emitter);
438 emit!(self.src);
439
440 if let Some(with) = &self.with {
441 formatting_space!(emitter);
442 if emitter.cfg.emit_assert_for_import_attributes {
443 keyword!(emitter, "assert");
444 } else {
445 keyword!(emitter, "with")
446 };
447 formatting_space!(emitter);
448 emit!(with);
449 }
450
451 semi!(emitter);
452
453 srcmap!(emitter, self, false);
454
455 Ok(())
456 }
457}