swc_macros_common/
lib.rs
1extern crate proc_macro;
4
5use proc_macro2::{Span, TokenStream};
6use quote::ToTokens;
7use syn::{punctuated::Pair, *};
8
9pub mod binder;
10pub mod derive;
11pub mod prelude;
12mod syn_ext;
13
14pub fn call_site() -> Span {
15 Span::call_site()
16}
17
18pub fn def_site() -> Span {
19 call_site()
20}
21
22pub fn print(attr: &'static str, tokens: proc_macro2::TokenStream) -> proc_macro::TokenStream {
24 use std::env;
25
26 match env::var("PRINT_GENERATED") {
27 Ok(ref s) if s == "1" || attr == s => {}
28 _ => return tokens.into(),
29 }
30
31 println!("\n\tOutput of #[{attr}]:\n\t {tokens}");
32 tokens.into()
33}
34
35pub fn is_attr_name(attr: &Attribute, name: &str) -> bool {
36 attr.path().is_ident(name)
37}
38
39pub fn doc_str(attr: &Attribute) -> Option<String> {
41 fn parse_tts(attr: &Attribute) -> String {
42 match &attr.meta {
43 Meta::NameValue(MetaNameValue {
44 value:
45 Expr::Lit(ExprLit {
46 lit: Lit::Str(s), ..
47 }),
48 ..
49 }) => s.value(),
50 _ => panic!("failed to parse {:?}", attr.meta),
51 }
52 }
53
54 if !is_attr_name(attr, "doc") {
55 return None;
56 }
57
58 Some(parse_tts(attr))
59}
60
61pub fn make_doc_attr(s: &str) -> Attribute {
63 let span = Span::call_site();
64
65 Attribute {
66 style: AttrStyle::Outer,
67 bracket_token: Default::default(),
68 pound_token: Token,
69 meta: Meta::NameValue(MetaNameValue {
70 path: Path {
71 leading_colon: None,
72 segments: vec![Pair::End(PathSegment {
73 ident: Ident::new("doc", span),
74 arguments: Default::default(),
75 })]
76 .into_iter()
77 .collect(),
78 },
79 eq_token: Token,
80 value: Expr::Lit(ExprLit {
81 attrs: Default::default(),
82 lit: Lit::Str(LitStr::new(s, span)),
83 }),
84 }),
85 }
86}
87
88pub fn access_field(obj: &dyn ToTokens, idx: usize, f: &Field) -> Expr {
89 Expr::Field(ExprField {
90 attrs: Default::default(),
91 base: syn::parse2(obj.to_token_stream())
92 .expect("swc_macros_common::access_field: failed to parse object"),
93 dot_token: Token),
94 member: match &f.ident {
95 Some(id) => Member::Named(id.clone()),
96 _ => Member::Unnamed(Index {
97 index: idx as _,
98 span: Span::call_site(),
99 }),
100 },
101 })
102}
103
104pub fn join_stmts(stmts: &[Stmt]) -> TokenStream {
105 let mut q = TokenStream::new();
106
107 for s in stmts {
108 s.to_tokens(&mut q);
109 }
110
111 q
112}
113
114#[macro_export]
116macro_rules! fail {
117 ($($args:tt)+) => {{
118 panic!("{}\n --> {}:{}:{}", format_args!($($args)*), file!(), line!(), column!());
119 }};
120}
121
122#[macro_export]
123macro_rules! unimplemented {
124 ($($args:tt)+) => {{
125 fail!("not yet implemented: {}", format_args!($($args)*));
126 }};
127}
128
129#[macro_export]
130macro_rules! unreachable {
131 () => {{
132 fail!("internal error: unreachable");
133 }};
134 ($($args:tt)+) => {{
135 fail!("internal error: unreachable\n{}", format_args!($($args)*));
136 }};
137}