swc_ecma_quote_macros/
lib.rs

1extern crate proc_macro;
2
3use std::iter::once;
4
5use quote::ToTokens;
6use syn::{Block, ExprBlock};
7
8use crate::{
9    ast::ToCode,
10    ctxt::{prepare_vars, Ctx},
11    input::QuoteInput,
12    ret_type::parse_input_type,
13};
14
15mod ast;
16mod builder;
17mod ctxt;
18mod input;
19mod ret_type;
20
21/// Don't invoke this macro directly, use the `quote!` macro from
22/// `swc_ecma_quote` instead.
23#[proc_macro]
24pub fn internal_quote(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
25    let QuoteInput {
26        src,
27        as_token: _,
28        output_type,
29        vars,
30    } = syn::parse::<QuoteInput>(input).expect("failed to parse input to quote!()");
31
32    let ret_type =
33        parse_input_type(&src.value(), &output_type).expect("failed to parse input type");
34
35    let vars = vars.map(|v| v.1);
36
37    let (stmts, vars) = if let Some(vars) = vars {
38        prepare_vars(&ret_type, vars)
39    } else {
40        Default::default()
41    };
42
43    let cx = Ctx { vars };
44
45    let expr_for_ast_creation = ret_type.to_code(&cx);
46
47    syn::Expr::Block(ExprBlock {
48        attrs: Default::default(),
49        label: Default::default(),
50        block: Block {
51            brace_token: Default::default(),
52            stmts: stmts
53                .into_iter()
54                .chain(once(syn::Stmt::Expr(expr_for_ast_creation, None)))
55                .collect(),
56        },
57    })
58    .to_token_stream()
59    .into()
60}