swc_ecma_codegen/
class.rs

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