1use swc_common::{SourceMapper, Spanned};
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::node_impl;
4
5#[cfg(swc_ast_unknown)]
6use crate::unknown_error;
7use crate::{
8 scope_helpers::{for_each_constructor_param_binding, for_each_param_binding},
9 text_writer::{BindingStorage, ScopeKind, WriteJs},
10 util::StartsWithAlphaNum,
11 Emitter, ExprPrecedence, ListFormat, Result, SourceMapperExt,
12};
13
14impl<W, S: SourceMapper> Emitter<'_, W, S>
15where
16 W: WriteJs,
17 S: SourceMapperExt,
18{
19 pub fn emit_class_trailing(&mut self, node: &Class) -> Result {
20 if let Some(super_class) = &node.super_class {
21 space!(self);
22 keyword!(self, "extends");
23
24 if self.expr_starts_with_alpha_num_after_codegen(super_class, ExprPrecedence::POSTFIX) {
25 space!(self);
26 } else {
27 formatting_space!(self)
28 }
29
30 self.emit_expr_with_precedence(super_class, ExprPrecedence::POSTFIX)?;
31 emit!(self, node.super_type_params);
32 }
33
34 if !node.implements.is_empty() {
35 space!(self);
36 keyword!(self, "implements");
37
38 space!(self);
39
40 self.emit_list(
41 node.span,
42 Some(&node.implements),
43 ListFormat::ClassHeritageClauses,
44 )?;
45 }
46
47 formatting_space!(self);
48
49 punct!(self, "{");
50
51 self.emit_list(node.span, Some(&node.body), ListFormat::ClassMembers)?;
52
53 srcmap!(self, node, false, true);
54 punct!(self, "}");
55
56 Ok(())
57 }
58}
59
60#[node_impl]
61impl MacroNode for ClassExpr {
62 fn emit(&mut self, emitter: &mut Macro) -> Result {
63 emitter.emit_leading_comments_of_span(self.span(), false)?;
64
65 srcmap!(emitter, self, true);
66
67 for dec in &self.class.decorators {
68 emit!(dec);
69 }
70
71 if self.class.is_abstract {
72 keyword!(emitter, "abstract");
73 space!(emitter);
74 }
75
76 keyword!(emitter, "class");
77
78 if let Some(ref i) = self.ident {
79 space!(emitter);
80 emit!(i);
81 emit!(self.class.type_params);
82 }
83
84 emitter.emit_class_trailing(&self.class)?;
85
86 Ok(())
87 }
88}
89
90#[node_impl]
91impl MacroNode for Class {
92 fn emit(&mut self, emitter: &mut Macro) -> Result {
93 if let Some(super_class) = &self.super_class {
94 space!(emitter);
95 keyword!(emitter, "extends");
96
97 if emitter
98 .expr_starts_with_alpha_num_after_codegen(super_class, ExprPrecedence::POSTFIX)
99 {
100 space!(emitter);
101 } else {
102 formatting_space!(emitter)
103 }
104
105 emitter.emit_expr_with_precedence(super_class, ExprPrecedence::POSTFIX)?;
106 emit!(self.super_type_params);
107 }
108
109 if !self.implements.is_empty() {
110 space!(emitter);
111 keyword!(emitter, "implements");
112
113 space!(emitter);
114
115 emitter.emit_list(
116 self.span,
117 Some(&self.implements),
118 ListFormat::ClassHeritageClauses,
119 )?;
120 }
121
122 formatting_space!(emitter);
123
124 punct!(emitter, "{");
125
126 emitter.emit_list(self.span, Some(&self.body), ListFormat::ClassMembers)?;
127
128 srcmap!(emitter, self, false, true);
129 punct!(emitter, "}");
130
131 Ok(())
132 }
133}
134
135#[node_impl]
136impl MacroNode for ClassMember {
137 fn emit(&mut self, emitter: &mut Macro) -> Result {
138 match self {
139 ClassMember::Constructor(ref n) => emit!(n),
140 ClassMember::ClassProp(ref n) => emit!(n),
141 ClassMember::Method(ref n) => emit!(n),
142 ClassMember::PrivateMethod(ref n) => emit!(n),
143 ClassMember::PrivateProp(ref n) => emit!(n),
144 ClassMember::TsIndexSignature(ref n) => emit!(n),
145 ClassMember::Empty(ref n) => emit!(n),
146 ClassMember::StaticBlock(ref n) => emit!(n),
147 ClassMember::AutoAccessor(ref n) => emit!(n),
148 #[cfg(swc_ast_unknown)]
149 _ => return Err(unknown_error()),
150 }
151
152 Ok(())
153 }
154}
155
156#[node_impl]
157impl MacroNode for AutoAccessor {
158 fn emit(&mut self, emitter: &mut Macro) -> Result {
159 emitter.emit_list(self.span, Some(&self.decorators), ListFormat::Decorators)?;
160
161 emitter.emit_accessibility(self.accessibility)?;
162
163 if self.is_static {
164 keyword!(emitter, "static");
165 space!(emitter);
166 }
167
168 if self.is_abstract {
169 keyword!(emitter, "abstract");
170 space!(emitter);
171 }
172
173 if self.is_override {
174 keyword!(emitter, "override");
175 space!(emitter);
176 }
177
178 keyword!(emitter, "accessor");
179 space!(emitter);
180
181 emit!(self.key);
182
183 if let Some(type_ann) = &self.type_ann {
184 if self.definite {
185 punct!(emitter, "!");
186 }
187 punct!(emitter, ":");
188 space!(emitter);
189 emit!(type_ann);
190 }
191
192 if let Some(init) = &self.value {
193 formatting_space!(emitter);
194 punct!(emitter, "=");
195 formatting_space!(emitter);
196 emit!(init);
197 }
198
199 semi!(emitter);
200
201 Ok(())
202 }
203}
204
205#[node_impl]
206impl MacroNode for Key {
207 fn emit(&mut self, emitter: &mut Macro) -> Result {
208 match self {
209 Key::Private(n) => emit!(n),
210 Key::Public(n) => emit!(n),
211 #[cfg(swc_ast_unknown)]
212 _ => return Err(unknown_error()),
213 }
214
215 Ok(())
216 }
217}
218
219#[node_impl]
220impl MacroNode for PrivateMethod {
221 fn emit(&mut self, emitter: &mut Macro) -> Result {
222 emitter.emit_leading_comments_of_span(self.span(), false)?;
223
224 srcmap!(emitter, self, true);
225 emitter.start_scope(
226 None,
227 ScopeKind::Function,
228 true,
229 false,
230 Some(self.function.span),
231 )?;
232 if emitter.scope_tracking_enabled() {
233 let mut names = vec![];
234 for_each_param_binding(&self.function.params, &mut |name| {
235 names.push(name.to_string())
236 });
237 for name in names {
238 emitter.add_scope_variable(&name, Some(&name), BindingStorage::Lexical)?;
239 }
240 }
241
242 if self.is_static {
243 keyword!(emitter, "static");
244 space!(emitter);
245 }
246 match self.kind {
247 MethodKind::Method => {
248 if self.function.is_async {
249 keyword!(emitter, "async");
250 space!(emitter);
251 }
252 if self.function.is_generator {
253 punct!(emitter, "*");
254 }
255
256 emit!(self.key);
257 }
258 MethodKind::Getter => {
259 keyword!(emitter, "get");
260 space!(emitter);
261
262 emit!(self.key);
263 }
264 MethodKind::Setter => {
265 keyword!(emitter, "set");
266 space!(emitter);
267
268 emit!(self.key);
269 }
270 #[cfg(swc_ast_unknown)]
271 _ => return Err(unknown_error()),
272 }
273
274 emitter.emit_fn_trailing(&self.function)?;
275 emitter.end_scope()?;
276
277 Ok(())
278 }
279}
280
281#[node_impl]
282impl MacroNode for ClassMethod {
283 fn emit(&mut self, emitter: &mut Macro) -> Result {
284 emitter.emit_leading_comments_of_span(self.span(), false)?;
285
286 emitter.emit_leading_comments_of_span(self.key.span(), false)?;
287
288 srcmap!(emitter, self, true);
289 emitter.start_scope(
290 None,
291 ScopeKind::Function,
292 true,
293 false,
294 Some(self.function.span),
295 )?;
296 if emitter.scope_tracking_enabled() {
297 let mut names = vec![];
298 for_each_param_binding(&self.function.params, &mut |name| {
299 names.push(name.to_string())
300 });
301 for name in names {
302 emitter.add_scope_variable(&name, Some(&name), BindingStorage::Lexical)?;
303 }
304 }
305
306 for d in &self.function.decorators {
307 emit!(d);
308 }
309
310 emitter.emit_accessibility(self.accessibility)?;
311
312 if self.is_static {
313 keyword!(emitter, "static");
314
315 let starts_with_alpha_num = match self.kind {
316 MethodKind::Method => {
317 if self.function.is_async {
318 true
319 } else if self.function.is_generator {
320 false
321 } else {
322 self.key.starts_with_alpha_num()
323 }
324 }
325 MethodKind::Getter => true,
326 MethodKind::Setter => true,
327 #[cfg(swc_ast_unknown)]
328 _ => return Err(unknown_error()),
329 };
330
331 if starts_with_alpha_num {
332 space!(emitter);
333 } else {
334 formatting_space!(emitter);
335 }
336 }
337
338 if self.is_abstract {
339 keyword!(emitter, "abstract");
340 space!(emitter)
341 }
342
343 if self.is_override {
344 keyword!(emitter, "override");
345 space!(emitter)
346 }
347
348 match self.kind {
349 MethodKind::Method => {
350 if self.function.is_async {
351 keyword!(emitter, "async");
352 space!(emitter);
353 }
354 if self.function.is_generator {
355 punct!(emitter, "*");
356 }
357
358 emit!(self.key);
359 }
360 MethodKind::Getter => {
361 keyword!(emitter, "get");
362
363 if self.key.starts_with_alpha_num() {
364 space!(emitter);
365 } else {
366 formatting_space!(emitter)
367 }
368
369 emit!(self.key);
370 }
371 MethodKind::Setter => {
372 keyword!(emitter, "set");
373
374 if self.key.starts_with_alpha_num() {
375 space!(emitter);
376 } else {
377 formatting_space!(emitter)
378 }
379
380 emit!(self.key);
381 }
382 #[cfg(swc_ast_unknown)]
383 _ => return Err(unknown_error()),
384 }
385
386 if self.is_optional {
387 punct!(emitter, "?");
388 }
389
390 if let Some(type_params) = &self.function.type_params {
391 emit!(type_params);
392 }
393
394 emitter.emit_fn_params(&self.function)?;
395
396 if let Some(ty) = &self.function.return_type {
397 punct!(emitter, ":");
398 formatting_space!(emitter);
399 emit!(ty);
400 }
401
402 if let Some(body) = &self.function.body {
403 formatting_space!(emitter);
404 emit!(body);
405 } else {
406 formatting_semi!(emitter)
407 }
408 emitter.end_scope()?;
409
410 Ok(())
411 }
412}
413
414#[node_impl]
415impl MacroNode for PrivateProp {
416 fn emit(&mut self, emitter: &mut Macro) -> Result {
417 emitter.emit_leading_comments_of_span(self.span(), false)?;
418
419 srcmap!(emitter, self, true);
420
421 emitter.emit_list(self.span, Some(&self.decorators), ListFormat::Decorators)?;
422
423 emitter.emit_accessibility(self.accessibility)?;
424
425 if self.is_static {
426 keyword!(emitter, "static");
427 space!(emitter);
428 }
429
430 if self.is_override {
431 keyword!(emitter, "override");
432 space!(emitter)
433 }
434
435 if self.readonly {
436 keyword!(emitter, "readonly");
437 space!(emitter);
438 }
439
440 emit!(self.key);
441
442 if self.is_optional {
443 punct!(emitter, "?");
444 }
445
446 if let Some(type_ann) = &self.type_ann {
447 if self.definite {
448 punct!(emitter, "!");
449 }
450 punct!(emitter, ":");
451 space!(emitter);
452 emit!(type_ann);
453 }
454
455 if let Some(value) = &self.value {
456 formatting_space!(emitter);
457 punct!(emitter, "=");
458 formatting_space!(emitter);
459
460 if value.is_seq() {
461 punct!(emitter, "(");
462 emit!(value);
463 punct!(emitter, ")");
464 } else {
465 emit!(value);
466 }
467 }
468
469 semi!(emitter);
470
471 srcmap!(emitter, self, false);
472
473 Ok(())
474 }
475}
476
477#[node_impl]
478impl MacroNode for ClassProp {
479 fn emit(&mut self, emitter: &mut Macro) -> Result {
480 emitter.emit_leading_comments_of_span(self.span(), false)?;
481 srcmap!(emitter, self, true);
482
483 for dec in &self.decorators {
484 emit!(dec)
485 }
486
487 if self.declare {
488 keyword!(emitter, "declare");
489 space!(emitter);
490 }
491
492 emitter.emit_accessibility(self.accessibility)?;
493
494 if self.is_static {
495 keyword!(emitter, "static");
496 space!(emitter);
497 }
498
499 if self.is_abstract {
500 keyword!(emitter, "abstract");
501 space!(emitter)
502 }
503
504 if self.is_override {
505 keyword!(emitter, "override");
506 space!(emitter)
507 }
508
509 if self.readonly {
510 keyword!(emitter, "readonly");
511 space!(emitter)
512 }
513
514 emit!(self.key);
515
516 if self.is_optional {
517 punct!(emitter, "?");
518 }
519
520 if let Some(ty) = &self.type_ann {
521 if self.definite {
522 punct!(emitter, "!");
523 }
524 punct!(emitter, ":");
525 space!(emitter);
526 emit!(ty);
527 }
528
529 if let Some(v) = &self.value {
530 formatting_space!(emitter);
531 punct!(emitter, "=");
532 formatting_space!(emitter);
533
534 if v.is_seq() {
535 punct!(emitter, "(");
536 emit!(v);
537 punct!(emitter, ")");
538 } else {
539 emit!(v);
540 }
541 }
542
543 semi!(emitter);
544
545 srcmap!(emitter, self, false);
546
547 Ok(())
548 }
549}
550
551#[node_impl]
552impl MacroNode for Constructor {
553 fn emit(&mut self, emitter: &mut Macro) -> Result {
554 emitter.emit_leading_comments_of_span(self.span(), false)?;
555
556 srcmap!(emitter, self, true);
557 emitter.start_scope(
558 Some("constructor"),
559 ScopeKind::Function,
560 true,
561 false,
562 Some(self.span()),
563 )?;
564 if emitter.scope_tracking_enabled() {
565 let mut names = vec![];
566 for_each_constructor_param_binding(&self.params, &mut |name| {
567 names.push(name.to_string())
568 });
569 for name in names {
570 emitter.add_scope_variable(&name, Some(&name), BindingStorage::Lexical)?;
571 }
572 }
573
574 emitter.emit_accessibility(self.accessibility)?;
575
576 keyword!(emitter, "constructor");
577 punct!(emitter, "(");
578 emitter.emit_list(self.span(), Some(&self.params), ListFormat::Parameters)?;
579 punct!(emitter, ")");
580
581 if let Some(body) = &self.body {
582 emit!(body);
583 } else {
584 formatting_semi!(emitter);
585 }
586 emitter.end_scope()?;
587
588 Ok(())
589 }
590}
591
592#[node_impl]
593impl MacroNode for StaticBlock {
594 fn emit(&mut self, emitter: &mut Macro) -> Result {
595 emitter.emit_leading_comments_of_span(self.span(), false)?;
596
597 srcmap!(emitter, self, true);
598
599 keyword!(emitter, "static");
600 emit!(self.body);
601
602 srcmap!(emitter, self, false);
603
604 Ok(())
605 }
606}
607
608impl<W, S: SourceMapper> Emitter<'_, W, S>
609where
610 W: WriteJs,
611 S: SourceMapperExt,
612{
613 pub fn emit_accessibility(&mut self, n: Option<Accessibility>) -> Result {
614 if let Some(a) = n {
615 match a {
616 Accessibility::Public => keyword!(self, "public"),
617 Accessibility::Protected => keyword!(self, "protected"),
618 Accessibility::Private => keyword!(self, "private"),
619 #[cfg(swc_ast_unknown)]
620 _ => return Err(unknown_error()),
621 }
622 space!(self);
623 }
624
625 Ok(())
626 }
627}