swc_ecma_utils/
macros.rs

1/// Shortcut for `quote_ident!(span.apply_mark(Mark::fresh(Mark::root())), s)`
2#[macro_export]
3macro_rules! private_ident {
4    ($s:literal) => {
5        private_ident!($crate::swc_atoms::atom!($s))
6    };
7    ($s:expr) => {
8        private_ident!($crate::swc_common::DUMMY_SP, $s)
9    };
10    ($span:expr, $s:expr) => {{
11        let mark = $crate::swc_common::Mark::new();
12        let ctxt = $crate::swc_common::SyntaxContext::empty().apply_mark(mark);
13        $crate::swc_ecma_ast::Ident::new($s.into(), $span, ctxt)
14    }};
15}
16
17/// As we have multiple identifier types, the expected usage is
18/// `quote_ident!("foo").into()`.
19#[macro_export]
20macro_rules! quote_ident {
21    ($s:literal) => {{
22        quote_ident!($crate::swc_atoms::atom!($s))
23    }};
24    ($s:expr) => {{
25        let sym: $crate::swc_atoms::Atom = $s.into();
26        let id: $crate::swc_ecma_ast::IdentName = sym.into();
27
28        id
29    }};
30    ($ctxt:expr, $s:literal) => {{
31        quote_ident!($ctxt, $crate::swc_atoms::atom!($s))
32    }};
33    ($ctxt:expr, $s:expr) => {{
34        let sym: $crate::swc_atoms::Atom = $s.into();
35        let id: $crate::swc_ecma_ast::Ident =
36            $crate::swc_ecma_ast::Ident::new(sym, $crate::swc_common::DUMMY_SP, $ctxt);
37
38        id
39    }};
40
41    ($ctxt:expr, $span:expr, $s:expr) => {{
42        $crate::swc_ecma_ast::Ident::new($s.into(), $span, $ctxt)
43    }};
44}
45
46#[macro_export]
47macro_rules! quote_str {
48    ($s:literal) => {
49        quote_str!($crate::swc_atoms::atom!($s))
50    };
51    ($s:expr) => {
52        quote_str!($crate::swc_common::DUMMY_SP, $s)
53    };
54    ($span:expr, $s:expr) => {{
55        $crate::swc_ecma_ast::Str {
56            span: $span,
57            raw: None,
58            value: $s.into(),
59        }
60    }};
61}
62
63#[macro_export]
64macro_rules! quote_expr {
65    ($span:expr, null) => {{
66        use $crate::swc_ecma_ast::*;
67        Expr::Lit(Lit::Null(Null { span: $span }))
68    }};
69
70    ($span:expr, undefined) => {{
71        box Expr::Ident(Ident::new("undefined", $span))
72    }};
73}
74
75/// Creates a member expression.
76///
77/// # Usage
78/// ```rust,ignore
79/// member_expr!(span, Function.bind.apply);
80/// ```
81///
82/// Returns Box<[Expr](swc_ecma_ast::Expr)>.
83#[macro_export]
84macro_rules! member_expr {
85    ($ctxt:expr, $span:expr, $first:ident) => {{
86        use $crate::swc_ecma_ast::Expr;
87        Box::new(Expr::Ident($crate::quote_ident!($ctxt, $span, stringify!($first))))
88    }};
89
90    ($ctxt:expr, $span:expr, $first:ident . $($rest:tt)+) => {{
91        let obj = member_expr!($ctxt, $span, $first);
92
93        member_expr!(@EXT, $span, obj, $($rest)* )
94    }};
95
96    (@EXT, $span:expr, $obj:expr, $first:ident . $($rest:tt)* ) => {{
97        use $crate::swc_ecma_ast::MemberProp;
98        use $crate::swc_ecma_ast::IdentName;
99        let prop = MemberProp::Ident(IdentName::new(stringify!($first).into(), $span));
100
101        member_expr!(@EXT, $span, Box::new(Expr::Member(MemberExpr{
102            span: $crate::swc_common::DUMMY_SP,
103            obj: $obj,
104            prop,
105        })), $($rest)*)
106    }};
107
108    (@EXT, $span:expr, $obj:expr,  $first:ident) => {{
109        use $crate::swc_ecma_ast::*;
110        let prop = MemberProp::Ident(IdentName::new(stringify!($first).into(), $span));
111
112        MemberExpr{
113            span: $crate::swc_common::DUMMY_SP,
114            obj: $obj,
115            prop,
116        }
117    }};
118}
119
120#[cfg(test)]
121mod tests {
122    use swc_atoms::atom;
123    use swc_common::DUMMY_SP as span;
124    use swc_ecma_ast::*;
125
126    use crate::drop_span;
127
128    #[test]
129    fn quote_member_expr() {
130        let expr: Box<Expr> = drop_span(member_expr!(
131            Default::default(),
132            Default::default(),
133            Function.prototype.bind
134        ))
135        .into();
136
137        assert_eq!(
138            expr,
139            Box::new(Expr::Member(MemberExpr {
140                span,
141                obj: Box::new(Expr::Member(MemberExpr {
142                    span,
143                    obj: member_expr!(Default::default(), Default::default(), Function),
144                    prop: MemberProp::Ident(atom!("prototype").into()),
145                })),
146                prop: MemberProp::Ident(atom!("bind").into()),
147            }))
148        );
149    }
150}