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