Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

View file

@ -0,0 +1,129 @@
use pmutil::ToTokensExt;
use quote::quote_spanned;
use swc_macros_common::prelude::*;
use syn::{
fold::Fold,
parse::{Parse, Parser},
spanned::Spanned,
token::Token,
*,
};
pub(crate) struct InjectSelf {
pub parser: Option<Ident>,
}
#[cfg(procmacro2_semver_exempt)]
fn get_joined_span(t: &dyn ToTokens) -> Span {
let tts: TokenStream = t.dump().into();
let (mut first, mut last) = (None, None);
for tt in tts {
match first {
None => first = Some(tt.span()),
_ => {}
}
last = Some(tt.span());
}
let cs = Span::call_site();
first.unwrap_or(cs).join(last.unwrap_or(cs)).unwrap_or(cs)
}
#[cfg(not(procmacro2_semver_exempt))]
fn get_joined_span(t: &dyn ToTokens) -> Span {
let tts: TokenStream = t.dump();
let mut first = None;
for tt in tts {
if first.is_none() {
first = Some(tt.span());
}
// last = Some(tt.span());
}
let cs = Span::call_site();
// first.unwrap_or(cs).join(last.unwrap_or(cs)).unwrap_or(cs)
first.unwrap_or(cs)
}
fn parse_args<T, P>(tokens: TokenStream) -> Punctuated<T, P>
where
T: Parse,
P: Parse + Token,
{
let parser = Punctuated::parse_separated_nonempty;
parser.parse2(tokens).expect("failed parse args")
}
impl Fold for InjectSelf {
fn fold_signature(&mut self, i: Signature) -> Signature {
self.parser = i.inputs.first().cloned().and_then(|arg| match arg {
FnArg::Receiver(Receiver {
self_token,
mutability: Some(..),
..
})
| FnArg::Receiver(Receiver { self_token, .. }) => {
Some(Ident::new("self", self_token.span()))
}
_ => None,
});
i
}
fn fold_macro(&mut self, i: Macro) -> Macro {
let parser = match self.parser {
Some(ref s) => s.clone(),
_ => {
// If we are not in parser, don't do anything.
return i;
}
};
let name = i.path.dump().to_string();
let span = get_joined_span(&i.path);
match &*name {
"smallvec" | "vec" | "unreachable" | "tok" | "op" | "js_word" => i,
"println" | "print" | "format" | "assert" | "assert_eq" | "assert_ne"
| "debug_assert" | "debug_assert_eq" | "debug_assert_ne" | "dbg" => {
let mut args: Punctuated<Expr, token::Comma> = parse_args(i.tokens);
args = args
.into_pairs()
.map(|el| el.map_item(|expr| self.fold_expr(expr)))
.collect();
Macro {
tokens: args.dump(),
..i
}
}
"trace" | "debug" | "info" | "warn" | "error" => i,
//TODO
"unimplemented" => i,
//TODO: Collect expect and give that list to unexpected
"keyword" | "emit" | "punct" | "semi" | "formatting_semi" | "space"
| "formatting_space" | "operator" | "opt" | "opt_leading_space" | "srcmap" => {
let tokens = if i.tokens.is_empty() {
quote_spanned!(span => #parser)
} else {
let args: Punctuated<Expr, token::Comma> = parse_args(i.tokens);
let args = args
.into_pairs()
.map(|el| el.map_item(|expr| self.fold_expr(expr)))
.flat_map(|arg| arg.dump());
quote_spanned!(span => #parser,)
.into_iter()
.chain(args)
.collect()
};
Macro { tokens, ..i }
}
_ => {
unimplemented!("Macro: {:#?}", i);
}
}
}
}

View file

@ -0,0 +1,87 @@
extern crate proc_macro;
use pmutil::{smart_quote, Quote, ToTokensExt};
use proc_macro::TokenStream;
use swc_macros_common::prelude::*;
use syn::{self, fold::Fold, *};
mod fold;
#[proc_macro_attribute]
pub fn emitter(_attr: TokenStream, item: TokenStream) -> TokenStream {
let item: ImplItemFn = syn::parse(item).expect("failed to parse input as an item");
let item = fold::InjectSelf { parser: None }.fold_impl_item_fn(item);
let item = expand(item);
print("emitter", item.dump())
}
fn expand(i: ImplItemFn) -> ImplItemFn {
let mtd_name = i.sig.ident.clone();
assert!(
format!("{}", i.sig.ident).starts_with("emit_"),
"#[emitter] methods should start with `emit_`"
);
let block = {
let node_type = {
i.sig
.inputs
.clone()
.into_iter()
.nth(1)
.and_then(|arg| match arg {
FnArg::Typed(ty) => Some(ty.ty),
_ => None,
})
.map(|ty| {
// &Ident -> Ident
match *ty {
Type::Reference(TypeReference { elem, .. }) => *elem,
_ => panic!(
"Type of node parameter should be reference but got {}",
ty.dump()
),
}
})
.expect(
"#[emitter] methods should have signature of
fn (&mut self, node: Node) -> Result;
",
)
};
Quote::new_call_site()
.quote_with(smart_quote!(
Vars {
block: &i.block,
NodeType: &node_type,
mtd_name,
},
{
{
impl crate::Node for NodeType {
fn emit_with<W, S: swc_common::SourceMapper>(&self, e: &mut crate::Emitter<'_, W, S>) -> Result
where
W: crate::text_writer::WriteJs,
S: swc_ecma_ast::SourceMapperExt
{
e.mtd_name(self)
}
}
block
// Emitter methods return Result<_, _>
// We inject this to avoid writing Ok(()) every time.
#[allow(unreachable_code)]
{
return Ok(());
}
}
}
))
.parse()
};
ImplItemFn { block, ..i }
}