1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/// Not a public API.
#[doc(hidden)]
pub extern crate swc_common;
/// Not a public API.
#[doc(hidden)]
pub extern crate swc_ecma_ast;
/// Not a public API.
#[doc(hidden)]
pub extern crate swc_ecma_quote_macros;

#[doc(hidden)]
pub use self::clone::ImplicitClone;

mod clone;

/// # Supported output types
///
///  - `Expr`
///  - `Pat`
///  - `AssignTarget`
///  - `Stmt`
///  - `ModuleItem`
///
///  - Option<T> where T is supported type
///  - Box<T> where T is supported type
///
/// For example, `Box<Expr>` and `Option<Box<Expr>>` are supported.
///
/// # Variable substitution
///
/// If an identifier starts with `$`, it is substituted with the value of the
/// parameter passed.
///
/// e.g.
///
/// ```rust
/// use swc_common::DUMMY_SP;
/// use swc_ecma_ast::Ident;
/// use swc_ecma_quote::quote;
///
/// // This will return ast for `const ref = 4;`
/// let _stmt = quote!("const $name = 4;" as Stmt, name = Ident::new("ref".into(), DUMMY_SP));
///
/// // Tip: Use private_ident!("ref") for real identifiers.
/// ```
///
/// ## Typed variables
///
/// As this macro generates static AST, it can't substitute variables if an
/// identifier is not allowed in such position. In other words, this macro only
/// supports substituting
///
///  - [swc_ecma_ast::Ident]
///  - [swc_ecma_ast::Expr]
///  - [swc_ecma_ast::Pat]
///  - [swc_ecma_ast::Str]
///
/// You can use it like
///
/// ```rust
/// use swc_common::DUMMY_SP;
/// use swc_ecma_ast::Ident;
/// use swc_ecma_quote::quote;
///
/// // This will return ast for `const ref = 4;`
/// let _stmt = quote!(
///                 "const $name = $val;" as Stmt,
///                 name = Ident::new("ref".into(), DUMMY_SP),
///                 val: Expr = 4.into(),
///             );
/// ```
///
/// # Examples
///
/// ## Quote a variable declaration
/// ```rust
/// use swc_common::DUMMY_SP;
/// use swc_ecma_ast::Ident;
/// use swc_ecma_quote::quote;
///
/// // This will return ast for `const ref = 4;`
/// let _stmt = quote!("const $name = 4;" as Stmt, name =
/// Ident::new("ref".into(), DUMMY_SP));
///
/// // Tip: Use private_ident!("ref") for real identifiers.
/// ```
///
/// ## Using `Str`
///
/// The grammar is `"$var_name"`.
///
/// ```rust
/// use swc_common::DUMMY_SP;
/// use swc_ecma_ast::Str;
/// use swc_ecma_quote::quote;
///
/// // This will return ast for `import thing from "foo";`
/// let _stmt = quote!(
///                 "import thing from \"$thing\";" as ModuleItem,
///                 thing: Str = "foo".into(),
///             );
/// ```
#[macro_export]
macro_rules! quote {
    ($($tt:tt)*) => {{
        $crate::swc_ecma_quote_macros::internal_quote!($($tt)*)
    }};
}

/// Creates a `Box<Expr>` from the source code.
///
/// This is an alias for [quote], but without `as Box<Expr>`.
#[macro_export]
macro_rules! quote_expr {
    ($src:tt) => {{
        $crate::quote!($src as Box<Expr>)
    }};

    ($src:tt, $($tt2:tt)*) => {{
        $crate::quote!($src as Box<Expr>, $($tt2)*)
    }};
}