Skip to main content

swc_ecma_codegen/
macros.rs

1#![allow(unused)]
2
3macro_rules! opt_leading_space {
4    ($emitter:expr, $e:expr) => {
5        if let Some(ref e) = $e {
6            formatting_space!($emitter);
7            emit!($emitter, e);
8        }
9    };
10}
11
12macro_rules! opt {
13    ($emitter:expr, $e:expr) => {{
14        if let Some(ref expr) = $e {
15            emit!($emitter, expr);
16        }
17    }};
18    ($emitter:expr, $e:expr,) => {{
19        opt!($emitter, $e)
20    }};
21}
22
23macro_rules! emit {
24    ($emitter:expr, $e:expr) => {{
25        crate::Node::emit_with(&$e, $emitter)?;
26    }};
27}
28
29macro_rules! keyword {
30    ($emitter:expr, $span:expr, $s:expr) => {
31        $emitter.wr.write_keyword(Some($span), $s)?
32    };
33    ($emitter:expr, $s:expr) => {
34        $emitter.wr.write_keyword(None, $s)?
35    };
36}
37
38/// Returns true if the punctuation character requires committing a pending
39/// semicolon before it (to avoid ASI issues).
40#[inline(always)]
41pub const fn punct_requires_semi_commit(s: &'static str) -> bool {
42    let bytes = s.as_bytes();
43    if bytes.len() == 1 {
44        let c = bytes[0];
45        matches!(
46            c,
47            b'"' | b'\''
48                | b'['
49                | b'!'
50                | b'/'
51                | b'{'
52                | b'('
53                | b'~'
54                | b'-'
55                | b'+'
56                | b'#'
57                | b'`'
58                | b'*'
59        )
60    } else {
61        false
62    }
63}
64
65macro_rules! punct {
66    ($emitter:expr, $sp:expr, ";") => {
67        $emitter.wr.write_semi(Some($sp))?;
68    };
69    ($emitter:expr, $sp:expr, $s:expr) => {
70        $emitter
71            .wr
72            .write_punct(Some($sp), $s, crate::macros::punct_requires_semi_commit($s))?;
73    };
74
75    ($emitter:expr, ";") => {
76        $emitter.wr.write_semi(None)?
77    };
78    ($emitter:expr, $s:expr) => {
79        $emitter
80            .wr
81            .write_punct(None, $s, crate::macros::punct_requires_semi_commit($s))?
82    };
83}
84
85macro_rules! operator {
86    ($emitter:expr, $sp:expr, $s:expr) => {
87        $emitter.wr.write_operator(Some($sp), $s)?;
88    };
89
90    ($emitter:expr, $s:expr) => {
91        $emitter.wr.write_operator(None, $s)?;
92    };
93}
94
95macro_rules! space {
96    ($emitter:expr) => {
97        $emitter.wr.write_space()?
98    };
99    ($emitter:expr,) => {
100        space!($emitter)
101    };
102}
103
104macro_rules! formatting_space {
105    ($emitter:expr) => {
106        if !$emitter.cfg.minify {
107            $emitter.wr.write_space()?;
108        }
109    };
110    ($emitter:expr,) => {
111        formatting_space!($emitter)
112    };
113}
114
115/// This macro *may* emit a semicolon, if it's required in this context.
116macro_rules! formatting_semi {
117    ($emitter:expr) => {
118        punct!($emitter, ";")
119    };
120    ($emitter:expr, ) => {
121        punct!($emitter, ";")
122    };
123}
124
125/// This macro *always* emits a semicolon, as it's required by the structure we
126/// emit.
127macro_rules! semi {
128    ($emitter:expr, $sp:expr) => {
129        $emitter.wr.write_semi(Some($sp))?;
130    };
131    ($emitter:expr) => {
132        $emitter.wr.write_semi(None)?;
133    };
134}
135
136///
137/// - `srcmap!(true)` for start (span.lo)
138/// - `srcmap!(false)` for end (span.hi)
139macro_rules! srcmap {
140    ($emitter:expr, $n:expr, true) => {{
141        let lo = $n.span_lo();
142        if !lo.is_dummy() {
143            $emitter.wr.add_srcmap(lo)?;
144        }
145    }};
146    ($emitter:expr, $n:expr, false) => {
147        srcmap!($emitter, $n, false, false)
148    };
149    ($emitter:expr, $n:expr, false, $subtract:expr) => {
150        let hi = $n.span_hi();
151        if !hi.is_dummy() {
152            if $subtract {
153                // hi is exclusive
154                $emitter.wr.add_srcmap(hi - swc_common::BytePos(1))?;
155            } else {
156                // TODO(kdy1): Remove this branch.
157                $emitter.wr.add_srcmap(hi)?;
158            }
159        }
160    };
161}
162
163macro_rules! emit_node_inner {
164    ($emitter:expr, true, $n:expr) => {
165        crate::Node::emit_with(&$n, $emitter)?
166    };
167}