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 @@
{"files":{"Cargo.toml":"aa0c7d94505b1c0a0571776b297129133e497449dcb7fcf7e9161b6008e1ee33","src/common.rs":"7298309281dbc24dc4ab007234b73ec65a3b089e04c6bed5f69029b70419e7de","src/fast.rs":"0e26d49c24ff2ed7c4d6837a542ab10e0883cbd29dd40128fc60acdede9b0c11","src/lib.rs":"b60dd0bb014894beab00351cdb25d42fe70ae989db32a682028f1efdacec57e7","src/parallel.rs":"b1ee1aee3d5802d14cd5b9179edf622d7b6923ed968c5edbc967724a6f448447"},"package":"8188eab297da773836ef5cf2af03ee5cca7a563e1be4b146f8141452c28cc690"}

View file

@ -0,0 +1,44 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
name = "swc_ecma_transforms_macros"
version = "0.5.3"
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
description = "Macros for swc_ecma_transforms."
documentation = "https://rustdoc.swc.rs/swc_ecma_transforms_macros/"
license = "Apache-2.0"
repository = "https://github.com/swc-project/swc.git"
[lib]
bench = false
proc-macro = true
[dependencies.pmutil]
version = "0.6.1"
[dependencies.proc-macro2]
version = "1"
[dependencies.quote]
version = "1"
[dependencies.swc_macros_common]
version = "0.3.8"
[dependencies.syn]
version = "2"
features = [
"fold",
"parsing",
"full",
]

View file

@ -0,0 +1,16 @@
/// Type of the visitor.
#[derive(Debug, Clone, Copy)]
pub enum Mode {
Fold,
VisitMut,
}
impl Mode {
pub fn prefix(self) -> &'static str {
match self {
Mode::Fold => "fold",
Mode::VisitMut => "visit_mut",
}
}
}

View file

@ -0,0 +1,155 @@
use pmutil::q;
use proc_macro2::TokenStream;
use swc_macros_common::call_site;
use syn::{FnArg, Ident, ImplItem, ImplItemFn, ItemImpl, Pat, Path, Stmt};
use crate::common::Mode;
pub fn expand(attr: TokenStream, item: ItemImpl) -> ItemImpl {
let expander = Expander {
handler: syn::parse2(attr).expect("Usage should be like #[fast_path(ArrowVisitor)]"),
mode: detect_mode(&item),
};
let items = expander.inject_default_methods(item.items);
ItemImpl {
items: items
.into_iter()
.map(|item| match item {
ImplItem::Fn(m) => ImplItem::Fn(expander.patch_method(m)),
_ => item,
})
.collect(),
..item
}
}
fn detect_mode(i: &ItemImpl) -> Mode {
if i.items.iter().any(|item| match item {
ImplItem::Fn(m) => m.sig.ident.to_string().starts_with("fold"),
_ => false,
}) {
return Mode::Fold;
}
Mode::VisitMut
}
struct Expander {
mode: Mode,
handler: Path,
}
impl Expander {
fn inject_default_methods(&self, mut items: Vec<ImplItem>) -> Vec<ImplItem> {
let list = &[
("stmt", q!({ swc_ecma_ast::Stmt })),
("stmts", q!({ Vec<swc_ecma_ast::Stmt> })),
("module_decl", q!({ swc_ecma_ast::ModuleDecl })),
("module_item", q!({ swc_ecma_ast::ModuleItem })),
("module_items", q!({ Vec<swc_ecma_ast::ModuleItem> })),
("expr", q!({ swc_ecma_ast::Expr })),
("exprs", q!({ Vec<Box<swc_ecma_ast::Expr>> })),
("decl", q!({ swc_ecma_ast::Decl })),
("pat", q!({ swc_ecma_ast::Pat })),
];
for (name, ty) in list {
let has = items.iter().any(|item| match item {
ImplItem::Fn(i) => i.sig.ident.to_string().ends_with(name),
_ => false,
});
if has {
continue;
}
let name = Ident::new(&format!("{}_{}", self.mode.prefix(), name), call_site());
let method = match self.mode {
Mode::Fold => q!(
Vars {
method: &name,
Type: ty,
},
{
fn method(&mut self, node: Type) -> Type {
node.fold_children_with(self)
}
}
),
Mode::VisitMut => q!(
Vars {
method: &name,
Type: ty,
},
{
fn method(&mut self, node: &mut Type) {
node.visit_mut_children_with(self)
}
}
),
};
items.push(method.parse());
}
items
}
/// Add fast path to a method
fn patch_method(&self, mut m: ImplItemFn) -> ImplItemFn {
let ty_arg = m
.sig
.inputs
.last()
.expect("method of Fold / VisitMut must accept two parameters");
let ty_arg = match ty_arg {
FnArg::Receiver(_) => unreachable!(),
FnArg::Typed(ty) => ty,
};
if m.sig.ident == "visit_mut_ident" || m.sig.ident == "fold_ident" {
return m;
}
if m.block.stmts.is_empty() {
return m;
}
let arg = match &*ty_arg.pat {
Pat::Ident(i) => &i.ident,
_ => unimplemented!(
"Fast-path injection for Fold / VisitMut where pattern is not an ident"
),
};
let fast_path = match self.mode {
Mode::Fold => q!(
Vars {
Checker: &self.handler,
arg
},
{
if !swc_ecma_transforms_base::perf::should_work::<Checker, _>(&arg) {
return arg;
}
}
)
.parse::<Stmt>(),
Mode::VisitMut => q!(
Vars {
Checker: &self.handler,
arg
},
{
if !swc_ecma_transforms_base::perf::should_work::<Checker, _>(&*arg) {
return;
}
}
)
.parse::<Stmt>(),
};
let mut stmts = vec![fast_path];
stmts.extend(m.block.stmts);
m.block.stmts = stmts;
m
}
}

View file

@ -0,0 +1,50 @@
#![deny(clippy::all)]
#![recursion_limit = "2048"]
use pmutil::ToTokensExt;
use proc_macro::TokenStream;
use swc_macros_common::print;
mod common;
mod fast;
mod parallel;
/// This macro adds fast-path to the `swc_ecma_visit::Fold` and
/// `swc_ecma_visit::Visit`.
///
/// Currently this macro modifies handler of `Expr`, `Stmt`, `ModuleItem`,
/// `Decl`, `Pat` and some vector types.
///
///
///
///
/// # Usage
///
/// `#[fast_path(ArrowVisitor)]`
///
/// where `ShouldWork` implements `swc_ecma_transforms::perf::Check`
#[proc_macro_attribute]
pub fn fast_path(attr: TokenStream, item: TokenStream) -> TokenStream {
let item = syn::parse(item).expect("failed to parse input as an item");
let expanded = fast::expand(attr.into(), item);
print("fast_path", expanded.dump())
}
///
/// # Input
///
/// Basically, input for each types are wrapped in the suffix of the visitor
/// method for the type.
///
/// ## `#[threashold]`
///
/// ```ignore,
/// #[parallel(module_items(threshold = "4"))]
/// impl VisitMut for Pass {}
/// ```
#[proc_macro_attribute]
pub fn parallel(attr: TokenStream, item: TokenStream) -> TokenStream {
let item = syn::parse(item).expect("failed to parse input as an item");
let expanded = parallel::expand(attr.into(), item);
print("parallel", expanded.dump())
}

View file

@ -0,0 +1,205 @@
#![allow(non_snake_case)]
use pmutil::q;
use proc_macro2::{Span, TokenStream};
use syn::{Expr, Ident, ImplItem, ImplItemFn, ItemImpl, Meta, Type};
use crate::common::Mode;
pub fn expand(attr: TokenStream, mut item: ItemImpl) -> ItemImpl {
let mode = {
let p = &item.trait_.as_ref().unwrap().1;
if p.is_ident("Fold") {
Mode::Fold
} else if p.is_ident("VisitMut") {
Mode::VisitMut
} else {
unimplemented!("Unknown visitor type: {:?}", p)
}
};
let meta = if attr.is_empty() {
None
} else {
Some(syn::parse2::<Meta>(attr).expect("failed to parse meta"))
};
let explode = meta
.as_ref()
.map(|v| v.path().is_ident("explode"))
.unwrap_or(false);
item.items.push(ImplItem::Fn(make_par_visit_method(
mode,
"module_items",
explode,
)));
item.items
.push(ImplItem::Fn(make_par_visit_method(mode, "stmts", explode)));
item
}
fn node_type(suffix: &str) -> Type {
match suffix {
"module_items" => q!((ModuleItem)).parse(),
"stmts" => q!((Stmt)).parse(),
_ => {
unimplemented!("Unknown suffix `{}`", suffix)
}
}
}
fn post_visit_hook(mode: Mode, suffix: &str) -> Option<Expr> {
match suffix {
"module_items" => Some(match mode {
Mode::Fold => q!(({
swc_ecma_transforms_base::perf::Parallel::after_module_items(self, &mut nodes);
}))
.parse(),
Mode::VisitMut => q!(({
swc_ecma_transforms_base::perf::Parallel::after_module_items(self, nodes);
}))
.parse(),
}),
"stmts" => Some(match mode {
Mode::Fold => q!(({
swc_ecma_transforms_base::perf::Parallel::after_stmts(self, &mut nodes);
}))
.parse(),
Mode::VisitMut => q!(({
swc_ecma_transforms_base::perf::Parallel::after_stmts(self, nodes);
}))
.parse(),
}),
_ => None,
}
}
fn explode_hook_method_name(explode: bool, suffix: &str) -> Option<Ident> {
if !explode {
return None;
}
match suffix {
"module_items" => Some(Ident::new("after_one_module_item", Span::call_site())),
"stmts" => Some(Ident::new("after_one_stmt", Span::call_site())),
_ => None,
}
}
fn make_par_visit_method(mode: Mode, suffix: &str, explode: bool) -> ImplItemFn {
let method_name = Ident::new(&format!("{}_{}", mode.prefix(), suffix), Span::call_site());
let hook = post_visit_hook(mode, suffix);
let explode_method_name = explode_hook_method_name(explode, suffix);
match (mode, explode_method_name) {
(Mode::Fold, Some(explode_method_name)) => q!(
Vars {
NodeType: node_type(suffix),
method_name,
hook,
explode_method_name,
},
{
fn method_name(&mut self, mut nodes: Vec<NodeType>) -> Vec<NodeType> {
use swc_common::errors::HANDLER;
use swc_ecma_transforms_base::perf::{ParExplode, Parallel};
use swc_ecma_visit::FoldWith;
let mut buf = Vec::with_capacity(nodes.len());
for node in nodes {
let mut visitor = Parallel::create(&*self);
let node = node.fold_with(&mut visitor);
ParExplode::explode_method_name(&mut visitor, &mut buf);
buf.push(node);
}
let mut nodes = buf;
{
hook;
}
nodes
}
}
)
.parse(),
(Mode::Fold, None) => q!(
Vars {
NodeType: node_type(suffix),
method_name,
hook,
},
{
fn method_name(&mut self, nodes: Vec<NodeType>) -> Vec<NodeType> {
use swc_common::errors::HANDLER;
use swc_ecma_transforms_base::perf::Parallel;
use swc_ecma_visit::FoldWith;
let mut nodes = nodes.fold_children_with(self);
{
hook;
}
nodes
}
}
)
.parse(),
(Mode::VisitMut, Some(explode_method_name)) => q!(
Vars {
NodeType: node_type(suffix),
method_name,
hook,
explode_method_name
},
{
fn method_name(&mut self, nodes: &mut Vec<NodeType>) {
use std::mem::take;
use swc_common::errors::HANDLER;
use swc_ecma_transforms_base::perf::{ParExplode, Parallel};
use swc_ecma_visit::VisitMutWith;
let mut buf = Vec::with_capacity(nodes.len());
for mut node in take(nodes) {
let mut visitor = Parallel::create(&*self);
node.visit_mut_with(&mut visitor);
ParExplode::explode_method_name(&mut visitor, &mut buf);
buf.push(node);
}
*nodes = buf;
{
hook;
}
}
}
)
.parse(),
(Mode::VisitMut, None) => q!(
Vars {
NodeType: node_type(suffix),
method_name,
hook,
},
{
fn method_name(&mut self, nodes: &mut Vec<NodeType>) {
use swc_common::errors::HANDLER;
use swc_ecma_transforms_base::perf::Parallel;
use swc_ecma_visit::VisitMutWith;
nodes.visit_mut_children_with(self);
{
hook;
}
}
}
)
.parse(),
}
}