-
-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathlib.rs
95 lines (80 loc) · 2.87 KB
/
lib.rs
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
#![allow(clippy::not_unsafe_ptr_arg_deref)]
use phf::phf_set;
use serde::Deserialize;
use swc_common::util::take::Take;
use swc_core::plugin::proxies::TransformPluginProgramMetadata;
use swc_ecma_ast::*;
use swc_ecma_utils::{prepend_stmts, StmtLike};
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
use swc_plugin_macro::plugin_transform;
static HOIST_METHODS: phf::Set<&str> = phf_set![
"mock",
"unmock",
"enableAutomock",
"disableAutomock",
"deepUnmock"
];
#[plugin_transform]
fn jest(mut program: Program, _: TransformPluginProgramMetadata) -> Program {
program.visit_mut_with(&mut Jest);
program
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct Config {}
struct Jest;
impl Jest {
fn visit_mut_stmt_like<T>(&mut self, orig: &mut Vec<T>)
where
T: StmtLike + VisitMutWith<Self>,
{
for item in &mut *orig {
item.visit_mut_with(self);
}
let items = orig.take();
let mut new = Vec::with_capacity(items.len());
let mut hoisted = Vec::with_capacity(8);
items.into_iter().for_each(|item| {
match item.try_into_stmt() {
Ok(stmt) => match &stmt {
Stmt::Expr(ExprStmt { expr, .. }) => match &**expr {
Expr::Call(CallExpr {
callee: Callee::Expr(callee),
..
}) => match &**callee {
Expr::Member(
callee @ MemberExpr {
prop: MemberProp::Ident(prop),
..
},
) => match &*callee.obj {
Expr::Ident(i) if i.sym == *"jest" => match prop {
_ if HOIST_METHODS.contains(&*prop.sym) => {
hoisted.push(T::from_stmt(stmt));
}
_ => new.push(T::from_stmt(stmt)),
},
_ => new.push(T::from_stmt(stmt)),
},
_ => new.push(T::from_stmt(stmt)),
},
_ => new.push(T::from_stmt(stmt)),
},
_ => new.push(T::from_stmt(stmt)),
},
Err(node) => new.push(node),
};
});
prepend_stmts(&mut new, hoisted.into_iter());
*orig = new;
}
}
impl VisitMut for Jest {
noop_visit_mut_type!();
fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
self.visit_mut_stmt_like(stmts)
}
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
self.visit_mut_stmt_like(items)
}
}