swc_ecma_codegen/
comments.rs1use swc_atoms::atom;
2use swc_common::comments::Comment;
3
4use super::*;
5
6macro_rules! write_comments {
7 ($e:expr, $prefix_space:expr, $cmts:expr) => {{
8 let cmts = match $cmts {
9 Some(v) => v,
10 None => return Ok(()),
11 };
12
13 for cmt in cmts.iter() {
14 match cmt.kind {
15 CommentKind::Line => {
16 if $prefix_space && !$e.cfg.minify {
17 $e.wr.write_comment(" ")?;
18 }
19
20 srcmap!($e, cmt, true);
21
22 $e.wr.write_comment("//")?;
23 $e.wr.write_comment(&cmt.text)?;
24
25 srcmap!($e, cmt, false);
26
27 $e.wr.write_line()?;
28 }
29 CommentKind::Block => {
30 if $prefix_space && !$e.cfg.minify {
31 $e.wr.write_comment(" ")?;
32 }
33
34 srcmap!($e, cmt, true);
35
36 $e.wr.write_comment("/*")?;
37 $e.wr.write_comment(&cmt.text)?;
38
39 {
40 let hi = cmt.span_hi();
41 if !hi.is_dummy() && hi.0 > 2 {
42 $e.wr.add_srcmap(hi - swc_common::BytePos(2))?;
43 }
44 }
45 $e.wr.write_comment("*/")?;
46
47 if !$e.cfg.minify {
48 $e.wr.write_space()?;
49 }
50 }
51 }
52 }
53
54 return Ok(());
55 }};
56}
57
58impl<W, S: SourceMapper> Emitter<'_, W, S>
59where
60 W: WriteJs,
61 S: SourceMapperExt,
62{
63 pub(super) fn emit_trailing_comments_of_pos(
64 &mut self,
65 pos: BytePos,
66 prefix_space: bool,
67 _is_hi: bool,
68 ) -> Result {
69 let cmts = self.take_trailing_comments_of_pos(pos);
70
71 write_comments!(self, prefix_space, &cmts)
72 }
73
74 pub(super) fn emit_trailing_comments_of_pos_with(
75 &mut self,
76 pos: BytePos,
77 prefix_space: bool,
78 callback: impl FnOnce(&mut Self) -> Result,
79 ) -> Result {
80 let cmts = self.take_trailing_comments_of_pos(pos);
81
82 callback(self)?;
83
84 write_comments!(self, prefix_space, &cmts)
85 }
86
87 fn take_trailing_comments_of_pos(&mut self, pos: BytePos) -> Option<Vec<Comment>> {
88 if pos.is_dummy() {
89 return None;
90 }
91
92 let comments = match self.comments {
93 Some(ref comments) => comments,
94 None => return None,
95 };
96
97 comments.take_trailing(pos)
98 }
99
100 pub(super) fn emit_leading_comments(&mut self, mut pos: BytePos, is_hi: bool) -> Result {
101 if pos.is_dummy() {
102 return Ok(());
103 }
104
105 if pos.is_pure() {
106 write_comments!(
107 self,
108 false,
109 Some(vec![Comment {
110 kind: CommentKind::Block,
111 span: DUMMY_SP,
112 text: atom!("#__PURE__"),
113 }])
114 );
115 }
116
117 let comments = match self.comments {
118 Some(ref comments) => comments,
119 None => return Ok(()),
120 };
121
122 if is_hi {
123 pos = pos - BytePos(1)
124 }
125
126 write_comments!(self, false, comments.take_leading(pos))
127 }
128
129 #[inline(always)]
130 pub(super) fn emit_leading_comments_of_span(&mut self, span: Span, is_hi: bool) -> Result {
131 let pos = if is_hi { span.hi } else { span.lo };
132 self.emit_leading_comments(pos, is_hi)
133 }
134}