mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
Improve performance and reduce binary size (#973)
spack: - Optimize resolver swc_bunder: - Parallize merging of reexports - Remove useless `clone`s swc_ecma_utils: - Migrate DropSpan to VisitMut swc_ecma_transforms: - Migrate simple transforms to VisitMut - Ignore types to reduce binary size - Hide actual types so that we can optimize it in future without breaking change swc_visit: - Apply transforms for vector in-place - Apply transforms for box in-place
This commit is contained in:
parent
7a13aabeb7
commit
3262052e33
@ -3,6 +3,7 @@
|
||||
rustflags = [
|
||||
"--cfg", "procmacro2_semver_exempt",
|
||||
"-Z", "thinlto=no",
|
||||
"-C", "target-feature=+sse2",
|
||||
]
|
||||
|
||||
rustdocflags = [
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_bundler"
|
||||
version = "0.2.3"
|
||||
version = "0.3.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -18,11 +18,11 @@ concurrent = ["swc_common/concurrent", "dashmap", "rayon"]
|
||||
swc_atoms = { version = "0.2", path = "../atoms" }
|
||||
swc_common = { version = "0.9", path = "../common" }
|
||||
swc_ecma_ast = { version = "0.28", path = "../ecmascript/ast" }
|
||||
swc_ecma_codegen = { version = "0.31", path = "../ecmascript/codegen" }
|
||||
swc_ecma_parser = { version = "0.33", path = "../ecmascript/parser" }
|
||||
swc_ecma_transforms = { version = "0.19", path = "../ecmascript/transforms" }
|
||||
swc_ecma_utils = { version = "0.17", path = "../ecmascript/utils" }
|
||||
swc_ecma_visit = { version = "0.13", path = "../ecmascript/visit" }
|
||||
swc_ecma_codegen = { version = "0.32.0", path = "../ecmascript/codegen" }
|
||||
swc_ecma_parser = { version = "0.34.0", path = "../ecmascript/parser" }
|
||||
swc_ecma_transforms = { version = "0.20.0", path = "../ecmascript/transforms" }
|
||||
swc_ecma_utils = { version = "0.18.0", path = "../ecmascript/utils" }
|
||||
swc_ecma_visit = { version = "0.14.0", path = "../ecmascript/visit" }
|
||||
anyhow = "1"
|
||||
crc = "1.8"
|
||||
radix_fmt = "1"
|
||||
|
@ -1,10 +1,10 @@
|
||||
use super::merge::{LocalMarker, Unexporter};
|
||||
use crate::{bundler::load::TransformedModule, Bundler, Load, ModuleId, Resolve};
|
||||
use hygiene::top_level_ident_folder;
|
||||
use std::iter::once;
|
||||
use swc_common::DUMMY_SP;
|
||||
use std::{borrow::Borrow, iter::once};
|
||||
use swc_common::{SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, FoldWith, Node, Visit, VisitMutWith, VisitWith};
|
||||
|
||||
mod hygiene;
|
||||
|
||||
@ -112,11 +112,11 @@ where
|
||||
for circular_module in circular_modules {
|
||||
for (src, specifiers) in entry.imports.specifiers.iter() {
|
||||
if circular_module.id == src.module_id {
|
||||
module = module.fold_with(&mut LocalMarker {
|
||||
module.visit_mut_with(&mut LocalMarker {
|
||||
mark: circular_module.mark(),
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
specifiers: &specifiers,
|
||||
excluded: vec![],
|
||||
is_export: false,
|
||||
excluded: Default::default(),
|
||||
});
|
||||
break;
|
||||
}
|
||||
@ -165,7 +165,7 @@ fn merge_respecting_order(mut entry: Vec<ModuleItem>, mut dep: Vec<ModuleItem>)
|
||||
}
|
||||
|
||||
// We checked the length of `dep`
|
||||
if let Some(pos) = dependency_index(&dep[0], &[item.clone()]) {
|
||||
if let Some(pos) = dependency_index(&dep[0], &[&item]) {
|
||||
log::trace!("Found reverse depndency (index[0]): {}", pos);
|
||||
|
||||
new.extend(entry.drain(..=pos));
|
||||
@ -192,25 +192,37 @@ fn merge_respecting_order(mut entry: Vec<ModuleItem>, mut dep: Vec<ModuleItem>)
|
||||
new
|
||||
}
|
||||
|
||||
fn dependency_index(item: &ModuleItem, deps: &[ModuleItem]) -> Option<usize> {
|
||||
/// Searches for top level declaration which provides requirements for `deps`.
|
||||
fn dependency_index<T>(item: &ModuleItem, deps: &[T]) -> Option<usize>
|
||||
where
|
||||
T: Borrow<ModuleItem>,
|
||||
{
|
||||
let mut v = DepFinder { deps, idx: None };
|
||||
item.visit_with(&Invalid { span: DUMMY_SP }, &mut v);
|
||||
v.idx
|
||||
}
|
||||
|
||||
struct DepFinder<'a> {
|
||||
deps: &'a [ModuleItem],
|
||||
struct DepFinder<'a, T>
|
||||
where
|
||||
T: Borrow<ModuleItem>,
|
||||
{
|
||||
deps: &'a [T],
|
||||
idx: Option<usize>,
|
||||
}
|
||||
|
||||
impl Visit for DepFinder<'_> {
|
||||
impl<T> Visit for DepFinder<'_, T>
|
||||
where
|
||||
T: Borrow<ModuleItem>,
|
||||
{
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_ident(&mut self, i: &Ident, _: &dyn Node) {
|
||||
if self.idx.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
for (idx, dep) in self.deps.iter().enumerate() {
|
||||
match dep {
|
||||
match dep.borrow() {
|
||||
ModuleItem::Stmt(Stmt::Decl(Decl::Class(decl))) => {
|
||||
log::trace!(
|
||||
"Decl (from dep) = {}{:?}, Ident = {}{:?}",
|
||||
@ -240,4 +252,11 @@ impl Visit for DepFinder<'_> {
|
||||
fn visit_class_member(&mut self, _: &ClassMember, _: &dyn Node) {}
|
||||
fn visit_function(&mut self, _: &Function, _: &dyn Node) {}
|
||||
fn visit_arrow_expr(&mut self, _: &ArrowExpr, _: &dyn Node) {}
|
||||
|
||||
/// We only search for top-level binding
|
||||
#[inline]
|
||||
fn visit_stmts(&mut self, _: &[Stmt], _: &dyn Node) {}
|
||||
/// We only search for top-level binding
|
||||
#[inline]
|
||||
fn visit_block_stmt(&mut self, _: &BlockStmt, _: &dyn Node) {}
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::id::Id;
|
||||
use std::collections::HashSet;
|
||||
use swc_common::{Mark, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn top_level_ident_folder(top_level_mark: Mark, module_mark: Mark) -> impl 'static + Fold {
|
||||
MergeFolder {
|
||||
@ -87,6 +87,8 @@ impl<'a> MergeFolder<'a> {
|
||||
}
|
||||
|
||||
impl Fold for MergeFolder<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class_decl(&mut self, c: ClassDecl) -> ClassDecl {
|
||||
ClassDecl {
|
||||
ident: self.fold_bindine_ident(c.ident),
|
||||
|
@ -5,7 +5,7 @@ use std::{borrow::Cow, sync::atomic::Ordering};
|
||||
use swc_common::{Mark, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::{ModuleItem, *};
|
||||
use swc_ecma_utils::{prepend, undefined, ExprFactory};
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitMut, VisitMutWith};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, FoldWith, VisitMut, VisitMutWith};
|
||||
|
||||
impl<L, R> Bundler<'_, L, R>
|
||||
where
|
||||
@ -49,10 +49,8 @@ where
|
||||
{
|
||||
info.helpers.require.store(true, Ordering::SeqCst);
|
||||
|
||||
let dep = dep
|
||||
.into_owned()
|
||||
.fold_with(&mut Unexporter)
|
||||
.fold_with(&mut ImportDropper);
|
||||
let mut dep = dep.into_owned().fold_with(&mut Unexporter);
|
||||
dep.visit_mut_with(&mut ImportDropper);
|
||||
|
||||
prepend(
|
||||
&mut entry.body,
|
||||
@ -150,6 +148,8 @@ struct RequireReplacer {
|
||||
}
|
||||
|
||||
impl VisitMut for RequireReplacer {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_item(&mut self, node: &mut ModuleItem) {
|
||||
node.visit_mut_children_with(self);
|
||||
|
||||
@ -173,6 +173,7 @@ impl VisitMut for RequireReplacer {
|
||||
}
|
||||
|
||||
let mut props = vec![];
|
||||
// TODO
|
||||
for spec in i.specifiers.clone() {
|
||||
match spec {
|
||||
ImportSpecifier::Named(s) => {
|
||||
@ -288,15 +289,15 @@ impl VisitMut for RequireReplacer {
|
||||
|
||||
struct ImportDropper;
|
||||
|
||||
impl Fold for ImportDropper {
|
||||
fn fold_module_item(&mut self, mut i: ModuleItem) -> ModuleItem {
|
||||
i = i.fold_children_with(self);
|
||||
impl VisitMut for ImportDropper {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_item(&mut self, i: &mut ModuleItem) {
|
||||
match i {
|
||||
ModuleItem::ModuleDecl(..) => {
|
||||
ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }))
|
||||
*i = ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }))
|
||||
}
|
||||
ModuleItem::Stmt(_) => i,
|
||||
ModuleItem::Stmt(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
use super::merge::{LocalMarker, Unexporter};
|
||||
use crate::{bundler::load::TransformedModule, Bundler, Load, ModuleId, Resolve};
|
||||
use crate::{bundler::load::TransformedModule, util, Bundler, Load, ModuleId, Resolve};
|
||||
use anyhow::{Context, Error};
|
||||
use std::mem::{replace, take};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::find_ids;
|
||||
use swc_ecma_visit::{FoldWith, VisitMut, VisitMutWith};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, FoldWith, VisitMut, VisitMutWith};
|
||||
|
||||
impl<L, R> Bundler<'_, L, R>
|
||||
where
|
||||
@ -15,10 +15,10 @@ where
|
||||
{
|
||||
pub(super) fn merge_reexports(
|
||||
&self,
|
||||
mut entry: Module,
|
||||
entry: &mut Module,
|
||||
info: &TransformedModule,
|
||||
targets: &mut Vec<ModuleId>,
|
||||
) -> Result<Module, Error> {
|
||||
) -> Result<(), Error> {
|
||||
entry.visit_mut_with(&mut DefaultRenamer);
|
||||
|
||||
for (src, specifiers) in &info.exports.reexports {
|
||||
@ -32,6 +32,32 @@ where
|
||||
targets.remove(pos);
|
||||
}
|
||||
|
||||
// print_hygiene("entry:init", &self.cm, &entry);
|
||||
// print_hygiene("dep:init", &self.cm, &dep);
|
||||
|
||||
let (_, dep) = util::join(
|
||||
|| {
|
||||
self.run(|| {
|
||||
entry.visit_mut_with(&mut LocalMarker {
|
||||
mark: imported.mark(),
|
||||
specifiers,
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
excluded: Default::default(),
|
||||
});
|
||||
// print_hygiene(&format!("entry:local-marker"), &self.cm, &entry);
|
||||
entry.visit_mut_with(&mut NamedExportOrigMarker {
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
target_ctxt: SyntaxContext::empty().apply_mark(info.mark()),
|
||||
});
|
||||
|
||||
entry.visit_mut_with(&mut ExportRenamer {
|
||||
from: SyntaxContext::empty().apply_mark(imported.mark()),
|
||||
to: SyntaxContext::empty().apply_mark(info.mark()),
|
||||
});
|
||||
})
|
||||
},
|
||||
|| -> Result<_, Error> {
|
||||
self.run(|| {
|
||||
let mut dep = self
|
||||
.merge_modules(src.module_id, false, targets)
|
||||
.with_context(|| {
|
||||
@ -43,23 +69,6 @@ where
|
||||
|
||||
dep = self.drop_unused(dep, Some(&specifiers));
|
||||
|
||||
// print_hygiene("entry:init", &self.cm, &entry);
|
||||
// print_hygiene("dep:init", &self.cm, &dep);
|
||||
|
||||
entry = entry.fold_with(&mut LocalMarker {
|
||||
mark: imported.mark(),
|
||||
specifiers,
|
||||
excluded: vec![],
|
||||
is_export: false,
|
||||
});
|
||||
// print_hygiene(&format!("entry:local-marker"), &self.cm, &entry);
|
||||
entry.visit_mut_with(&mut NamedExportOrigMarker {
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
target_ctxt: SyntaxContext::empty().apply_mark(info.mark()),
|
||||
});
|
||||
|
||||
// print_hygiene(&format!("entry:named-export-orig"), &self.cm, &entry);
|
||||
|
||||
dep.visit_mut_with(&mut UnexportAsVar {
|
||||
target_ctxt: SyntaxContext::empty().apply_mark(info.mark()),
|
||||
});
|
||||
@ -73,17 +82,18 @@ where
|
||||
|
||||
dep = dep.fold_with(&mut Unexporter);
|
||||
|
||||
entry.visit_mut_with(&mut ExportRenamer {
|
||||
from: SyntaxContext::empty().apply_mark(imported.mark()),
|
||||
to: SyntaxContext::empty().apply_mark(info.mark()),
|
||||
});
|
||||
Ok(dep)
|
||||
})
|
||||
},
|
||||
);
|
||||
let dep = dep?;
|
||||
|
||||
// print_hygiene("entry:before-injection", &self.cm, &entry);
|
||||
// print_hygiene("dep:before-injection", &self.cm, &dep);
|
||||
|
||||
// Replace import statement / require with module body
|
||||
let mut injector = ExportInjector {
|
||||
imported: dep.body.clone(),
|
||||
imported: dep.body,
|
||||
src: src.src.clone(),
|
||||
};
|
||||
entry.body.visit_mut_with(&mut injector);
|
||||
@ -100,7 +110,7 @@ where
|
||||
assert_eq!(injector.imported, vec![]);
|
||||
}
|
||||
|
||||
Ok(entry)
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -110,6 +120,8 @@ struct ExportInjector {
|
||||
}
|
||||
|
||||
impl VisitMut for ExportInjector {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_items(&mut self, orig: &mut Vec<ModuleItem>) {
|
||||
let items = take(orig);
|
||||
let mut buf = Vec::with_capacity(self.imported.len() + items.len());
|
||||
@ -154,6 +166,8 @@ struct ExportRenamer {
|
||||
}
|
||||
|
||||
impl VisitMut for ExportRenamer {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_named_export(&mut self, export: &mut NamedExport) {
|
||||
// if export.src.is_none() {
|
||||
// return;
|
||||
@ -196,6 +210,8 @@ struct UnexportAsVar {
|
||||
}
|
||||
|
||||
impl VisitMut for UnexportAsVar {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_item(&mut self, n: &mut ModuleItem) {
|
||||
n.visit_mut_children_with(self);
|
||||
|
||||
@ -277,6 +293,8 @@ pub(super) struct NamedExportOrigMarker {
|
||||
}
|
||||
|
||||
impl VisitMut for NamedExportOrigMarker {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_export_named_specifier(&mut self, s: &mut ExportNamedSpecifier) {
|
||||
if s.orig.span.ctxt == self.top_level_ctxt {
|
||||
s.orig.span = s.orig.span.with_ctxt(self.target_ctxt);
|
||||
@ -293,6 +311,8 @@ struct AliasExports {
|
||||
}
|
||||
|
||||
impl VisitMut for AliasExports {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_items(&mut self, items: &mut Vec<ModuleItem>) {
|
||||
for item in items.iter_mut() {
|
||||
item.visit_mut_with(self);
|
||||
@ -355,6 +375,8 @@ impl VisitMut for AliasExports {
|
||||
struct DefaultRenamer;
|
||||
|
||||
impl VisitMut for DefaultRenamer {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_export_named_specifier(&mut self, n: &mut ExportNamedSpecifier) {
|
||||
if n.orig.sym == js_word!("default") {
|
||||
n.orig.sym = "__default".into()
|
||||
|
@ -8,6 +8,7 @@ use crate::{
|
||||
use anyhow::{Context, Error};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashSet,
|
||||
mem::take,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
@ -15,7 +16,9 @@ use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{Mark, Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{find_ids, DestructuringFinder, StmtLike};
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitMut, VisitMutWith, VisitWith};
|
||||
use swc_ecma_visit::{
|
||||
noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitMutWith, VisitWith,
|
||||
};
|
||||
|
||||
impl<L, R> Bundler<'_, L, R>
|
||||
where
|
||||
@ -54,8 +57,7 @@ where
|
||||
|
||||
log::info!("Merge: ({}){} <= {:?}", info.id, info.fm.name, targets);
|
||||
|
||||
entry = self
|
||||
.merge_reexports(entry, &info, targets)
|
||||
self.merge_reexports(&mut entry, &info, targets)
|
||||
.context("failed to merge reepxorts")?;
|
||||
|
||||
for (src, specifiers) in &info.imports.specifiers {
|
||||
@ -71,11 +73,11 @@ where
|
||||
|
||||
if let Some(imported) = self.scope.get_module(src.module_id) {
|
||||
// Respan using imported module's syntax context.
|
||||
entry = entry.fold_with(&mut LocalMarker {
|
||||
entry.visit_mut_with(&mut LocalMarker {
|
||||
mark: imported.mark(),
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(self.top_level_mark),
|
||||
specifiers: &specifiers,
|
||||
excluded: vec![],
|
||||
is_export: false,
|
||||
excluded: Default::default(),
|
||||
});
|
||||
}
|
||||
|
||||
@ -177,11 +179,12 @@ where
|
||||
dep = dep.fold_with(&mut Unexporter);
|
||||
|
||||
if !specifiers.is_empty() {
|
||||
entry = entry.fold_with(&mut LocalMarker {
|
||||
entry.visit_mut_with(&mut LocalMarker {
|
||||
mark: imported.mark(),
|
||||
top_level_ctxt: SyntaxContext::empty()
|
||||
.apply_mark(self.top_level_mark),
|
||||
specifiers: &specifiers,
|
||||
excluded: vec![],
|
||||
is_export: false,
|
||||
excluded: Default::default(),
|
||||
});
|
||||
|
||||
// // Note: this does not handle `export default
|
||||
@ -196,7 +199,7 @@ where
|
||||
|
||||
// Replace import statement / require with module body
|
||||
let mut injector = Es6ModuleInjector {
|
||||
imported: dep.body.clone(),
|
||||
imported: take(&mut dep.body),
|
||||
src: src.src.clone(),
|
||||
};
|
||||
entry.body.visit_mut_with(&mut injector);
|
||||
@ -206,6 +209,7 @@ where
|
||||
if injector.imported.is_empty() {
|
||||
continue;
|
||||
}
|
||||
dep.body = take(&mut injector.imported);
|
||||
}
|
||||
|
||||
if self.config.require {
|
||||
@ -244,6 +248,8 @@ where
|
||||
pub(super) struct Unexporter;
|
||||
|
||||
impl Fold for Unexporter {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_item(&mut self, item: ModuleItem) -> ModuleItem {
|
||||
match item {
|
||||
ModuleItem::ModuleDecl(decl) => match decl {
|
||||
@ -342,6 +348,8 @@ impl ExportRenamer<'_> {
|
||||
}
|
||||
|
||||
impl Fold for ExportRenamer<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class(&mut self, node: Class) -> Class {
|
||||
node
|
||||
}
|
||||
@ -485,6 +493,8 @@ struct ActualMarker<'a> {
|
||||
}
|
||||
|
||||
impl Fold for ActualMarker<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, node: Expr) -> Expr {
|
||||
node
|
||||
}
|
||||
@ -515,29 +525,13 @@ impl Fold for ActualMarker<'_> {
|
||||
pub(super) struct LocalMarker<'a> {
|
||||
/// Mark applied to imported idents.
|
||||
pub mark: Mark,
|
||||
/// Syntax context of the top level items.
|
||||
pub top_level_ctxt: SyntaxContext,
|
||||
pub specifiers: &'a [Specifier],
|
||||
pub is_export: bool,
|
||||
pub excluded: Vec<Id>,
|
||||
pub excluded: HashSet<Id>,
|
||||
}
|
||||
|
||||
impl<'a> LocalMarker<'a> {
|
||||
/// Searches for i, and fold T.
|
||||
#[allow(dead_code)]
|
||||
fn recurse<I, F, Ret>(&mut self, excluded_idents: I, op: F) -> Ret
|
||||
where
|
||||
F: FnOnce(I, &mut Self) -> Ret,
|
||||
I: for<'any> VisitWith<DestructuringFinder<'any, Id>>,
|
||||
{
|
||||
let len = self.excluded.len();
|
||||
let ids = find_ids(&excluded_idents);
|
||||
|
||||
self.excluded.extend(ids);
|
||||
let ret = op(excluded_idents, self);
|
||||
self.excluded.drain(len..);
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
fn exclude<I>(&mut self, excluded_idents: &I) -> Excluder<'a, '_>
|
||||
where
|
||||
I: for<'any> VisitWith<DestructuringFinder<'any, Id>>,
|
||||
@ -567,101 +561,77 @@ impl<'a, 'b> DerefMut for Excluder<'a, 'b> {
|
||||
}
|
||||
}
|
||||
|
||||
impl Fold for LocalMarker<'_> {
|
||||
fn fold_catch_clause(&mut self, mut node: CatchClause) -> CatchClause {
|
||||
impl VisitMut for LocalMarker<'_> {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_catch_clause(&mut self, node: &mut CatchClause) {
|
||||
let mut f = self.exclude(&node.param);
|
||||
node.body = node.body.fold_with(&mut *f);
|
||||
node
|
||||
node.body.visit_mut_with(&mut *f);
|
||||
}
|
||||
|
||||
fn fold_class_decl(&mut self, mut node: ClassDecl) -> ClassDecl {
|
||||
self.excluded.push((&node.ident).into());
|
||||
node.class = node.class.fold_with(self);
|
||||
node
|
||||
fn visit_mut_class_decl(&mut self, node: &mut ClassDecl) {
|
||||
self.excluded.insert((&node.ident).into());
|
||||
node.class.visit_mut_with(self);
|
||||
}
|
||||
|
||||
fn fold_class_expr(&mut self, mut node: ClassExpr) -> ClassExpr {
|
||||
fn visit_mut_class_expr(&mut self, node: &mut ClassExpr) {
|
||||
let mut f = self.exclude(&node.ident);
|
||||
node.class = node.class.fold_with(&mut *f);
|
||||
node
|
||||
node.class.visit_mut_with(&mut *f);
|
||||
}
|
||||
|
||||
fn fold_constructor(&mut self, mut node: Constructor) -> Constructor {
|
||||
fn visit_mut_constructor(&mut self, node: &mut Constructor) {
|
||||
let mut f = self.exclude(&node.params);
|
||||
node.body = node.body.fold_with(&mut *f);
|
||||
node
|
||||
node.body.visit_mut_with(&mut *f);
|
||||
}
|
||||
|
||||
fn fold_fn_decl(&mut self, mut node: FnDecl) -> FnDecl {
|
||||
self.excluded.push((&node.ident).into());
|
||||
node.function = node.function.fold_with(self);
|
||||
node
|
||||
fn visit_mut_fn_decl(&mut self, node: &mut FnDecl) {
|
||||
self.excluded.insert((&node.ident).into());
|
||||
node.function.visit_mut_with(self);
|
||||
}
|
||||
|
||||
fn fold_fn_expr(&mut self, mut node: FnExpr) -> FnExpr {
|
||||
fn visit_mut_fn_expr(&mut self, node: &mut FnExpr) {
|
||||
let mut f = self.exclude(&node.ident);
|
||||
|
||||
node.function = node.function.fold_with(&mut *f);
|
||||
|
||||
node
|
||||
node.function.visit_mut_with(&mut *f);
|
||||
}
|
||||
|
||||
fn fold_function(&mut self, mut node: Function) -> Function {
|
||||
fn visit_mut_function(&mut self, node: &mut Function) {
|
||||
let mut f = self.exclude(&node.params);
|
||||
node.body = node.body.fold_with(&mut *f);
|
||||
node
|
||||
node.body.visit_mut_with(&mut *f);
|
||||
}
|
||||
|
||||
fn fold_ident(&mut self, mut node: Ident) -> Ident {
|
||||
if self.excluded.iter().any(|i| *i == node) {
|
||||
return node;
|
||||
fn visit_mut_ident(&mut self, mut node: &mut Ident) {
|
||||
if node.span.ctxt != self.top_level_ctxt {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.excluded.contains(&(&*node).into()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: sym() => correct span
|
||||
if self.is_export {
|
||||
if self.specifiers.iter().any(|id| match id {
|
||||
Specifier::Specific { local, alias } => match alias {
|
||||
Some(v) => *v == node,
|
||||
None => *local == node,
|
||||
},
|
||||
Specifier::Namespace { local } => *local == node,
|
||||
}) {
|
||||
node.span = node
|
||||
.span
|
||||
.with_ctxt(SyntaxContext::empty().apply_mark(self.mark));
|
||||
}
|
||||
} else {
|
||||
if self.specifiers.iter().any(|id| *id.local() == node) {
|
||||
if self.specifiers.iter().any(|id| *id.local() == *node) {
|
||||
node.span = node
|
||||
.span
|
||||
.with_ctxt(SyntaxContext::empty().apply_mark(self.mark));
|
||||
// dbg!(&node);
|
||||
}
|
||||
}
|
||||
|
||||
node
|
||||
fn visit_mut_labeled_stmt(&mut self, node: &mut LabeledStmt) {
|
||||
node.body.visit_mut_with(self);
|
||||
}
|
||||
|
||||
fn fold_labeled_stmt(&mut self, node: LabeledStmt) -> LabeledStmt {
|
||||
LabeledStmt {
|
||||
body: node.body.fold_with(self),
|
||||
..node
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_member_expr(&mut self, mut e: MemberExpr) -> MemberExpr {
|
||||
e.obj = e.obj.fold_with(self);
|
||||
fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
|
||||
e.obj.visit_mut_with(self);
|
||||
|
||||
if e.computed {
|
||||
e.prop = e.prop.fold_with(self);
|
||||
e.prop.visit_mut_with(self);
|
||||
}
|
||||
}
|
||||
|
||||
e
|
||||
}
|
||||
|
||||
fn fold_setter_prop(&mut self, mut node: SetterProp) -> SetterProp {
|
||||
fn visit_mut_setter_prop(&mut self, node: &mut SetterProp) {
|
||||
let mut f = self.exclude(&node.param);
|
||||
node.body = node.body.fold_with(&mut *f);
|
||||
node
|
||||
node.body.visit_mut_with(&mut *f);
|
||||
}
|
||||
}
|
||||
|
||||
@ -671,6 +641,8 @@ struct Es6ModuleInjector {
|
||||
}
|
||||
|
||||
impl VisitMut for Es6ModuleInjector {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_items(&mut self, orig: &mut Vec<ModuleItem>) {
|
||||
let items = take(orig);
|
||||
let mut buf = Vec::with_capacity(self.imported.len() + items.len());
|
||||
|
@ -8,7 +8,7 @@ use swc_atoms::js_word;
|
||||
use swc_common::{FileName, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::find_ids;
|
||||
use swc_ecma_visit::{VisitMut, VisitMutWith};
|
||||
use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
|
||||
|
||||
impl<L, R> Bundler<'_, L, R>
|
||||
where
|
||||
@ -92,6 +92,8 @@ where
|
||||
L: Load,
|
||||
R: Resolve,
|
||||
{
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module_item(&mut self, item: &mut ModuleItem) {
|
||||
match item {
|
||||
// TODO: Optimize pure constants
|
||||
|
@ -7,8 +7,7 @@ use std::{
|
||||
};
|
||||
use swc_common::{util::move_map::MoveMap, FileName};
|
||||
use swc_ecma_ast::{ImportDecl, Str};
|
||||
use swc_ecma_transforms::noop_fold_type;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
impl<L, R> Bundler<'_, L, R>
|
||||
where
|
||||
@ -121,12 +120,12 @@ where
|
||||
renamed: &'a HashMap<PathBuf, String>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Renamer<'_, '_>);
|
||||
|
||||
impl<R> Fold for Renamer<'_, R>
|
||||
where
|
||||
R: Resolve,
|
||||
{
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_import_decl(&mut self, import: ImportDecl) -> ImportDecl {
|
||||
let resolved = match self
|
||||
.resolver
|
||||
|
@ -3,8 +3,7 @@ use std::sync::atomic::{AtomicBool, Ordering::SeqCst};
|
||||
use swc_common::{FileName, FilePathMapping, SourceMap};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput};
|
||||
use swc_ecma_utils::{prepend_stmts, DropSpan};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use swc_ecma_utils::{drop_span, prepend_stmts};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub(super) struct Helpers {
|
||||
@ -35,9 +34,7 @@ macro_rules! define {
|
||||
);
|
||||
let stmts = Parser::new_from(lexer)
|
||||
.parse_module()
|
||||
.map(|script| script.body.fold_with(&mut DropSpan {
|
||||
preserve_ctxt:false,
|
||||
}))
|
||||
.map(|script| drop_span(script.body))
|
||||
.map_err(|_| {
|
||||
()
|
||||
})
|
||||
|
@ -11,7 +11,7 @@ use swc_common::{
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{find_ids, ident::IdentLike, Id};
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -143,6 +143,8 @@ where
|
||||
L: Load,
|
||||
R: Resolve,
|
||||
{
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_import_decl(&mut self, mut import: ImportDecl) -> ImportDecl {
|
||||
if !self.deglob_phase {
|
||||
// Ignore if it's a core module.
|
||||
|
@ -17,7 +17,7 @@ use swc_ecma_ast::{
|
||||
ModuleDecl, Str,
|
||||
};
|
||||
use swc_ecma_transforms::resolver_with_mark;
|
||||
use swc_ecma_visit::{FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, FoldWith, Node, Visit, VisitWith};
|
||||
/// Module after applying transformations.
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) struct TransformedModule {
|
||||
@ -375,6 +375,8 @@ struct Es6ModuleDetector {
|
||||
}
|
||||
|
||||
impl Visit for Es6ModuleDetector {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_call_expr(&mut self, e: &CallExpr, _: &dyn Node) {
|
||||
e.visit_children_with(self);
|
||||
|
||||
|
@ -7,7 +7,7 @@ use swc_common::{sync::Lrc, FileName, SourceFile, SourceMap, GLOBALS};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{lexer::Lexer, JscTarget, Parser, StringInput};
|
||||
use swc_ecma_utils::drop_span;
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use swc_ecma_visit::VisitMutWith;
|
||||
|
||||
pub(super) struct Tester<'a> {
|
||||
pub cm: Lrc<SourceMap>,
|
||||
@ -84,7 +84,10 @@ impl<'a> Tester<'a> {
|
||||
pub fn assert_eq(&self, m: &Module, expected: &str) {
|
||||
let expected = self.parse(expected);
|
||||
|
||||
let m = drop_span(m.clone().fold_with(&mut HygieneRemover));
|
||||
let mut m = m.clone();
|
||||
m.visit_mut_with(&mut HygieneRemover);
|
||||
|
||||
let m = drop_span(m);
|
||||
let expected = drop_span(expected);
|
||||
|
||||
assert_eq!(m, expected)
|
||||
|
@ -4,7 +4,7 @@ use std::io::{stdout, Write};
|
||||
use swc_common::{sync::Lrc, SourceMap};
|
||||
use swc_ecma_ast::{Ident, Module};
|
||||
use swc_ecma_codegen::{text_writer::JsWriter, Emitter};
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub(crate) fn print_hygiene(event: &str, cm: &Lrc<SourceMap>, t: &Module) {
|
||||
let module = t.clone().fold_with(&mut HygieneVisualizer);
|
||||
@ -27,6 +27,8 @@ pub(crate) fn print_hygiene(event: &str, cm: &Lrc<SourceMap>, t: &Module) {
|
||||
struct HygieneVisualizer;
|
||||
|
||||
impl Fold for HygieneVisualizer {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_ident(&mut self, node: Ident) -> Ident {
|
||||
Ident {
|
||||
sym: format!("{}{:?}", node.sym, node.span.ctxt()).into(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use std::hash::Hash;
|
||||
use swc_common::{Span, SyntaxContext};
|
||||
use swc_ecma_visit::Fold;
|
||||
use swc_ecma_visit::{noop_visit_mut_type, VisitMut};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct CloneMap<K, V>
|
||||
@ -62,9 +62,11 @@ where
|
||||
|
||||
pub(crate) struct HygieneRemover;
|
||||
|
||||
impl Fold for HygieneRemover {
|
||||
fn fold_span(&mut self, s: Span) -> Span {
|
||||
s.with_ctxt(SyntaxContext::empty())
|
||||
impl VisitMut for HygieneRemover {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_span(&mut self, s: &mut Span) {
|
||||
*s = s.with_ctxt(SyntaxContext::empty())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,2 @@
|
||||
/// Copied from `syntax::ptr::P`
|
||||
pub trait Map<T> {
|
||||
/// Transform the inner value, consuming `self` and producing a new `P<T>`.
|
||||
fn map<F>(self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T;
|
||||
}
|
||||
|
||||
impl<T> Map<T> for Box<T> {
|
||||
fn map<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: FnOnce(T) -> T,
|
||||
{
|
||||
*self = f(*self);
|
||||
self
|
||||
}
|
||||
}
|
||||
/// Moved
|
||||
pub use swc_visit::util::map::Map;
|
||||
|
@ -1,93 +1 @@
|
||||
use std::{iter, ptr};
|
||||
|
||||
pub trait MoveMap<T>: Sized {
|
||||
fn move_map<F>(self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
self.move_flat_map(|e| iter::once(f(e)))
|
||||
}
|
||||
|
||||
fn move_flat_map<F, I>(self, f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> I,
|
||||
I: IntoIterator<Item = T>;
|
||||
}
|
||||
|
||||
impl<T> MoveMap<T> for Vec<T> {
|
||||
/// This reduces binary size.
|
||||
fn move_map<F>(mut self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> T,
|
||||
{
|
||||
let mut read_i = 0;
|
||||
let mut write_i = 0;
|
||||
unsafe {
|
||||
let old_len = self.len();
|
||||
self.set_len(0); // make sure we just leak elements in case of panic
|
||||
|
||||
while read_i < old_len {
|
||||
// move the read_i'th item out of the vector and map it
|
||||
// to an iterator
|
||||
let e = ptr::read(self.get_unchecked(read_i));
|
||||
let e = f(e);
|
||||
read_i += 1;
|
||||
|
||||
assert!(write_i < read_i);
|
||||
ptr::write(self.get_unchecked_mut(write_i), e);
|
||||
write_i += 1;
|
||||
}
|
||||
|
||||
// write_i tracks the number of actually written new items.
|
||||
self.set_len(write_i);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
fn move_flat_map<F, I>(mut self, mut f: F) -> Self
|
||||
where
|
||||
F: FnMut(T) -> I,
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
let mut read_i = 0;
|
||||
let mut write_i = 0;
|
||||
unsafe {
|
||||
let mut old_len = self.len();
|
||||
self.set_len(0); // make sure we just leak elements in case of panic
|
||||
|
||||
while read_i < old_len {
|
||||
// move the read_i'th item out of the vector and map it
|
||||
// to an iterator
|
||||
let e = ptr::read(self.get_unchecked(read_i));
|
||||
let iter = f(e).into_iter();
|
||||
read_i += 1;
|
||||
|
||||
for e in iter {
|
||||
if write_i < read_i {
|
||||
ptr::write(self.get_unchecked_mut(write_i), e);
|
||||
write_i += 1;
|
||||
} else {
|
||||
// If this is reached we ran out of space
|
||||
// in the middle of the vector.
|
||||
// However, the vector is in a valid state here,
|
||||
// so we just do a somewhat inefficient insert.
|
||||
self.set_len(old_len);
|
||||
self.insert(write_i, e);
|
||||
|
||||
old_len = self.len();
|
||||
self.set_len(0);
|
||||
|
||||
read_i += 1;
|
||||
write_i += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write_i tracks the number of actually written new items.
|
||||
self.set_len(write_i);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
}
|
||||
pub use swc_visit::util::move_map::MoveMap;
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecmascript"
|
||||
version = "0.3.2"
|
||||
version = "0.4.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -17,10 +17,10 @@ visit = ["swc_ecma_visit"]
|
||||
|
||||
[dependencies]
|
||||
swc_ecma_ast = { version = "0.28.0", path ="./ast" }
|
||||
swc_ecma_codegen = { version = "0.31.0", path ="./codegen", optional = true }
|
||||
swc_ecma_parser = { version = "0.33.3", path ="./parser", optional = true }
|
||||
swc_ecma_utils = { version = "0.17.0", path ="./utils", optional = true }
|
||||
swc_ecma_transforms = { version = "0.19.5", path ="./transforms", optional = true }
|
||||
swc_ecma_visit = { version = "0.13.0", path ="./visit", optional = true }
|
||||
swc_ecma_codegen = { version = "0.32.0", path ="./codegen", optional = true }
|
||||
swc_ecma_parser = { version = "0.34.0", path ="./parser", optional = true }
|
||||
swc_ecma_utils = { version = "0.18.0", path ="./utils", optional = true }
|
||||
swc_ecma_transforms = { version = "0.20.0", path ="./transforms", optional = true }
|
||||
swc_ecma_visit = { version = "0.14.0", path ="./visit", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_codegen"
|
||||
version = "0.31.0"
|
||||
version = "0.32.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -20,5 +20,5 @@ num-bigint = { version = "0.2", features = ["serde"] }
|
||||
|
||||
[dev-dependencies]
|
||||
swc_common = { version = "0.9.0", path ="../../common", features = ["sourcemap"] }
|
||||
swc_ecma_parser = { version = "0.33.0", path ="../parser" }
|
||||
swc_ecma_parser = { version = "0.34.0", path ="../parser" }
|
||||
testing = { version = "0.9.0", path ="../../testing" }
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "jsdoc"
|
||||
version = "0.1.0"
|
||||
version = "0.2.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
@ -17,7 +17,7 @@ serde = { version = "1", features = ["derive"] }
|
||||
|
||||
[dev-dependencies]
|
||||
swc_ecma_ast = { version = "0.28.0", path = "../ast" }
|
||||
swc_ecma_parser = { version = "0.33.3", path = "../parser" }
|
||||
swc_ecma_parser = { version = "0.34.0", path = "../parser" }
|
||||
testing = { version = "0.9.0", path = "../../testing" }
|
||||
anyhow = "1"
|
||||
dashmap = "3"
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_parser"
|
||||
version = "0.33.3"
|
||||
version = "0.34.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -17,7 +17,7 @@ swc_atoms = { version = "0.2", path ="../../atoms" }
|
||||
swc_common = { version = "0.9.0", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.28.0", path ="../ast" }
|
||||
swc_ecma_parser_macros = { version = "0.4.1", path ="./macros" }
|
||||
swc_ecma_visit = { version = "0.13.0", path ="../visit" }
|
||||
swc_ecma_visit = { version = "0.14.0", path ="../visit" }
|
||||
enum_kind = { version = "0.2", path ="../../macros/enum_kind" }
|
||||
unicode-xid = "0.2"
|
||||
log = "0.4"
|
||||
|
101
ecmascript/parser/benches/compare.rs
Normal file
101
ecmascript/parser/benches/compare.rs
Normal file
@ -0,0 +1,101 @@
|
||||
#![feature(test)]
|
||||
|
||||
extern crate test;
|
||||
|
||||
use swc_common::{FileName, Span, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::Module;
|
||||
use swc_ecma_parser::{Parser, StringInput, Syntax};
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitMut, VisitMutWith};
|
||||
use test::Bencher;
|
||||
|
||||
static SOURCE: &str = include_str!("../../parser/benches/files/angular-1.2.5.js");
|
||||
|
||||
fn run<F>(b: &mut Bencher, mut op: F)
|
||||
where
|
||||
F: FnMut(Module) -> Module,
|
||||
{
|
||||
let _ = ::testing::run_test(false, |cm, _| {
|
||||
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
||||
|
||||
let mut parser = Parser::new(Syntax::default(), StringInput::from(&*fm), None);
|
||||
let module = parser.parse_module().map_err(|_| ()).unwrap();
|
||||
b.iter(|| {
|
||||
let module = module.clone();
|
||||
let module = op(module);
|
||||
test::black_box(module)
|
||||
});
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn base_clone(b: &mut Bencher) {
|
||||
run(b, |m| m);
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn visit_mut_span(b: &mut Bencher) {
|
||||
struct RespanVisitMut;
|
||||
|
||||
impl VisitMut for RespanVisitMut {
|
||||
fn visit_mut_span(&mut self, span: &mut Span) {
|
||||
*span = DUMMY_SP;
|
||||
}
|
||||
}
|
||||
|
||||
run(b, |mut m| {
|
||||
m.visit_mut_with(&mut RespanVisitMut);
|
||||
|
||||
m
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn visit_mut_span_panic(b: &mut Bencher) {
|
||||
struct RespanVisitMut;
|
||||
|
||||
impl VisitMut for RespanVisitMut {
|
||||
fn visit_mut_span(&mut self, span: &mut Span) {
|
||||
if span.ctxt != SyntaxContext::empty() {
|
||||
panic!()
|
||||
}
|
||||
|
||||
*span = DUMMY_SP;
|
||||
}
|
||||
}
|
||||
|
||||
run(b, |mut m| {
|
||||
m.visit_mut_with(&mut RespanVisitMut);
|
||||
|
||||
m
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn fold_span(b: &mut Bencher) {
|
||||
struct RespanFold;
|
||||
|
||||
impl Fold for RespanFold {
|
||||
fn fold_span(&mut self, _: Span) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
run(b, |m| m.fold_with(&mut RespanFold));
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn fold_span_pnic(b: &mut Bencher) {
|
||||
struct RespanFold;
|
||||
|
||||
impl Fold for RespanFold {
|
||||
fn fold_span(&mut self, s: Span) -> Span {
|
||||
if s.ctxt != SyntaxContext::empty() {
|
||||
panic!()
|
||||
}
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
run(b, |m| m.fold_with(&mut RespanFold));
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
use super::*;
|
||||
use swc_common::{Span, Spanned, DUMMY_SP};
|
||||
use swc_ecma_visit::{Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, Node, Visit, VisitWith};
|
||||
|
||||
impl<'a, I: Tokens> Parser<I> {
|
||||
pub(in crate::parser) fn verify_expr(&mut self, expr: Box<Expr>) -> PResult<Box<Expr>> {
|
||||
@ -21,6 +21,8 @@ pub(super) struct Verifier {
|
||||
}
|
||||
|
||||
impl Visit for Verifier {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_assign_prop(&mut self, p: &AssignProp, _: &dyn Node) {
|
||||
self.errors.push((p.span(), SyntaxError::AssignProperty));
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use fxhash::FxHashSet;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, Node, Visit, VisitWith};
|
||||
|
||||
mod builtin;
|
||||
mod data;
|
||||
@ -123,6 +123,8 @@ impl UsageVisitor {
|
||||
|
||||
/// Detects usage of types
|
||||
impl Visit for UsageVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_ident(&mut self, node: &Ident, _: &dyn Node) {
|
||||
node.visit_children_with(self);
|
||||
|
||||
|
@ -15,7 +15,7 @@ use fxhash::FxHashSet;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, Node, Visit, VisitWith};
|
||||
|
||||
pub(crate) struct UsageVisitor {
|
||||
shipped_proposals: bool,
|
||||
@ -145,6 +145,8 @@ impl UsageVisitor {
|
||||
}
|
||||
|
||||
impl Visit for UsageVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
/// `[a, b] = c`
|
||||
fn visit_array_pat(&mut self, p: &ArrayPat, _: &dyn Node) {
|
||||
p.visit_children_with(self);
|
||||
|
@ -81,14 +81,9 @@ pub fn preset_env(global_mark: Mark, c: Config) -> impl Fold {
|
||||
let pass = add!(pass, ExponentiationOperator, es2016::exponentation());
|
||||
|
||||
// ES2015
|
||||
let pass = add!(pass, BlockScopedFunctions, es2015::BlockScopedFns);
|
||||
let pass = add!(
|
||||
pass,
|
||||
TemplateLiterals,
|
||||
es2015::TemplateLiteral::default(),
|
||||
true
|
||||
);
|
||||
let pass = add!(pass, Classes, es2015::Classes::default());
|
||||
let pass = add!(pass, BlockScopedFunctions, es2015::block_scoped_functions());
|
||||
let pass = add!(pass, TemplateLiterals, es2015::template_literal(), true);
|
||||
let pass = add!(pass, Classes, es2015::classes());
|
||||
let pass = add!(
|
||||
pass,
|
||||
Spread,
|
||||
@ -98,10 +93,10 @@ pub fn preset_env(global_mark: Mark, c: Config) -> impl Fold {
|
||||
let pass = add!(pass, FunctionName, es2015::function_name());
|
||||
let pass = add!(pass, ArrowFunctions, es2015::arrow());
|
||||
let pass = add!(pass, DuplicateKeys, es2015::duplicate_keys());
|
||||
let pass = add!(pass, StickyRegex, es2015::StickyRegex);
|
||||
let pass = add!(pass, StickyRegex, es2015::sticky_regex());
|
||||
// TODO: InstanceOf,
|
||||
let pass = add!(pass, TypeOfSymbol, es2015::TypeOfSymbol);
|
||||
let pass = add!(pass, ShorthandProperties, es2015::Shorthand);
|
||||
let pass = add!(pass, TypeOfSymbol, es2015::typeof_symbol());
|
||||
let pass = add!(pass, ShorthandProperties, es2015::shorthand());
|
||||
let pass = add!(pass, Parameters, es2015::parameters());
|
||||
let pass = add!(
|
||||
pass,
|
||||
@ -138,15 +133,13 @@ pub fn preset_env(global_mark: Mark, c: Config) -> impl Fold {
|
||||
// NamedCapturingGroupsRegex,
|
||||
|
||||
// ES 3
|
||||
let pass = add!(pass, PropertyLiterals, es3::PropertyLiteral);
|
||||
let pass = add!(pass, MemberExpressionLiterals, es3::MemberExprLit);
|
||||
let pass = add!(pass, PropertyLiterals, es3::property_literals());
|
||||
let pass = add!(
|
||||
pass,
|
||||
ReservedWords,
|
||||
es3::ReservedWord {
|
||||
preserve_import: c.dynamic_import
|
||||
}
|
||||
MemberExpressionLiterals,
|
||||
es3::member_expression_literals()
|
||||
);
|
||||
let pass = add!(pass, ReservedWords, es3::reserved_words(c.dynamic_import));
|
||||
|
||||
if c.debug {
|
||||
println!("Targets: {:?}", targets);
|
||||
|
@ -1,6 +1,6 @@
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::Invalid;
|
||||
use swc_ecma_visit::{Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_visit_type, Visit, VisitWith};
|
||||
|
||||
pub(super) fn is_required<T: VisitWith<RegeneratorVisitor>>(node: &T) -> bool {
|
||||
let mut v = RegeneratorVisitor { found: false };
|
||||
@ -13,4 +13,6 @@ pub(super) struct RegeneratorVisitor {
|
||||
}
|
||||
|
||||
/// TODO
|
||||
impl Visit for RegeneratorVisitor {}
|
||||
impl Visit for RegeneratorVisitor {
|
||||
noop_visit_type!();
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ use swc_ecma_ast::*;
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_parser::{EsConfig, Parser, Syntax};
|
||||
use swc_ecma_preset_env::{preset_env, Config, FeatureOrModule, Mode, Targets, Version};
|
||||
use swc_ecma_transforms::util::DropSpan;
|
||||
use swc_ecma_transforms::util::drop_span;
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use test::{test_main, ShouldPanic, TestDesc, TestDescAndFn, TestFn, TestName, TestType};
|
||||
use testing::Tester;
|
||||
@ -304,11 +304,7 @@ fn exec(c: PresetConfig, dir: PathBuf) -> Result<(), Error> {
|
||||
let actual_src = print(&actual);
|
||||
let expected_src = print(&expected);
|
||||
|
||||
if actual.fold_with(&mut DropSpan {
|
||||
preserve_ctxt: false,
|
||||
}) == expected.fold_with(&mut DropSpan {
|
||||
preserve_ctxt: false,
|
||||
}) {
|
||||
if drop_span(actual) == drop_span(expected) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "swc_ecma_transforms"
|
||||
version = "0.19.8"
|
||||
version = "0.20.0"
|
||||
authors = ["강동윤 <kdy1997.dev@gmail.com>"]
|
||||
license = "Apache-2.0/MIT"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
@ -14,13 +14,13 @@ react = ["dashmap"]
|
||||
default = []
|
||||
|
||||
[dependencies]
|
||||
jsdoc = { version = "0.1.0", path ="../jsdoc" }
|
||||
jsdoc = { version = "0.2.0", path ="../jsdoc" }
|
||||
swc_atoms = { version = "0.2.0", path ="../../atoms" }
|
||||
swc_common = { version = "0.9.0", path ="../../common" }
|
||||
swc_ecma_ast = { version = "0.28.0", path ="../ast" }
|
||||
swc_ecma_utils = { version = "0.17.0", path ="../utils" }
|
||||
swc_ecma_parser = { version = "0.33.0", path ="../parser" }
|
||||
swc_ecma_visit = { version = "0.13.0", path ="../visit" }
|
||||
swc_ecma_utils = { version = "0.18.0", path ="../utils" }
|
||||
swc_ecma_parser = { version = "0.34.0", path ="../parser" }
|
||||
swc_ecma_visit = { version = "0.14.0", path ="../visit" }
|
||||
dashmap = { version = "3", optional = true }
|
||||
either = "1.5"
|
||||
fxhash = "0.2"
|
||||
@ -40,7 +40,7 @@ log = "0.4.8"
|
||||
|
||||
[dev-dependencies]
|
||||
testing = { version = "0.9.0", path ="../../testing" }
|
||||
swc_ecma_codegen = { version = "0.31.0", path ="../codegen" }
|
||||
swc_ecma_codegen = { version = "0.32.0", path ="../codegen" }
|
||||
tempfile = "3"
|
||||
pretty_assertions = "0.6"
|
||||
sourcemap = "6"
|
||||
|
@ -166,7 +166,7 @@ fn es2015_arrow(b: &mut Bencher) {
|
||||
|
||||
#[bench]
|
||||
fn es2015_block_scoped_fn(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::BlockScopedFns);
|
||||
tr!(b, || compat::es2015::block_scoped_functions());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@ -176,7 +176,7 @@ fn es2015_block_scoping(b: &mut Bencher) {
|
||||
|
||||
#[bench]
|
||||
fn es2015_classes(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::Classes::default());
|
||||
tr!(b, || compat::es2015::classes());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@ -211,12 +211,12 @@ fn es2015_for_of(b: &mut Bencher) {
|
||||
|
||||
#[bench]
|
||||
fn es2015_instanceof(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::InstanceOf);
|
||||
tr!(b, || compat::es2015::instance_of());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn es2015_shorthand_property(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::Shorthand);
|
||||
tr!(b, || compat::es2015::shorthand());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
@ -230,12 +230,12 @@ fn es2015_spread(b: &mut Bencher) {
|
||||
|
||||
#[bench]
|
||||
fn es2015_sticky_regex(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::StickyRegex);
|
||||
tr!(b, || compat::es2015::sticky_regex());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn es2015_typeof_symbol(b: &mut Bencher) {
|
||||
tr!(b, || compat::es2015::TypeOfSymbol);
|
||||
tr!(b, || compat::es2015::typeof_symbol());
|
||||
}
|
||||
|
||||
#[bench]
|
||||
|
@ -1,10 +1,10 @@
|
||||
pub use self::{
|
||||
arrow::arrow, block_scoped_fn::BlockScopedFns, block_scoping::block_scoping, classes::Classes,
|
||||
computed_props::computed_properties, destructuring::destructuring,
|
||||
arrow::arrow, block_scoped_fn::block_scoped_functions, block_scoping::block_scoping,
|
||||
classes::classes, computed_props::computed_properties, destructuring::destructuring,
|
||||
duplicate_keys::duplicate_keys, for_of::for_of, function_name::function_name,
|
||||
instanceof::InstanceOf, parameters::parameters, regenerator::regenerator,
|
||||
shorthand_property::Shorthand, spread::spread, sticky_regex::StickyRegex,
|
||||
template_literal::TemplateLiteral, typeof_symbol::TypeOfSymbol,
|
||||
instanceof::instance_of, parameters::parameters, regenerator::regenerator,
|
||||
shorthand_property::shorthand, spread::spread, sticky_regex::sticky_regex,
|
||||
template_literal::template_literal, typeof_symbol::typeof_symbol,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use swc_common::{chain, Mark};
|
||||
@ -32,19 +32,19 @@ fn exprs() -> impl Fold {
|
||||
chain!(
|
||||
arrow(),
|
||||
duplicate_keys(),
|
||||
StickyRegex,
|
||||
InstanceOf,
|
||||
TypeOfSymbol,
|
||||
Shorthand,
|
||||
sticky_regex(),
|
||||
instance_of(),
|
||||
typeof_symbol(),
|
||||
shorthand(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Compiles es2015 to es5.
|
||||
pub fn es2015(global_mark: Mark, c: Config) -> impl Fold {
|
||||
chain!(
|
||||
BlockScopedFns,
|
||||
TemplateLiteral::default(),
|
||||
Classes::default(),
|
||||
block_scoped_functions(),
|
||||
template_literal(),
|
||||
classes(),
|
||||
spread(c.spread),
|
||||
function_name(),
|
||||
exprs(),
|
||||
@ -145,7 +145,7 @@ export default function fn1() {
|
||||
|
||||
test!(
|
||||
::swc_ecma_parser::Syntax::default(),
|
||||
|_| chain!(BlockScopedFns, resolver(),),
|
||||
|_| chain!(block_scoped_functions(), resolver(),),
|
||||
issue_271,
|
||||
"
|
||||
function foo(scope) {
|
||||
|
@ -2,7 +2,7 @@ use crate::util::{contains_this_expr, ExprFactory};
|
||||
use swc_common::{Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::quote_ident;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// Compile ES2015 arrow functions to ES5
|
||||
///
|
||||
@ -58,9 +58,9 @@ pub fn arrow() -> impl Fold {
|
||||
|
||||
struct Arrow;
|
||||
|
||||
noop_fold_type!(Arrow);
|
||||
|
||||
impl Fold for Arrow {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
// fast path
|
||||
if !contains_arrow_expr(&e) {
|
||||
@ -141,6 +141,8 @@ struct ArrowVisitor {
|
||||
found: bool,
|
||||
}
|
||||
impl Visit for ArrowVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_arrow_expr(&mut self, _: &ArrowExpr, _: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
|
@ -1,14 +1,18 @@
|
||||
use crate::util::UsageFinder;
|
||||
use swc_common::{Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn block_scoped_functions() -> impl Fold {
|
||||
BlockScopedFns
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct BlockScopedFns;
|
||||
|
||||
noop_fold_type!(BlockScopedFns);
|
||||
struct BlockScopedFns;
|
||||
|
||||
impl Fold for BlockScopedFns {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_stmts(&mut self, items: Vec<Stmt>) -> Vec<Stmt> {
|
||||
let mut stmts = Vec::with_capacity(items.len());
|
||||
let mut extra_stmts = Vec::with_capacity(items.len());
|
||||
|
@ -6,7 +6,7 @@ use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{
|
||||
find_ids, ident::IdentLike, prepend, var::VarCollector, ExprFactory, Id, StmtLike,
|
||||
};
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
///
|
||||
///
|
||||
@ -50,8 +50,6 @@ struct BlockScoping {
|
||||
var_decl_kind: VarDeclKind,
|
||||
}
|
||||
|
||||
noop_fold_type!(BlockScoping);
|
||||
|
||||
impl BlockScoping {
|
||||
/// This methods remove [ScopeKind::Loop] and [ScopeKind::Fn], but not
|
||||
/// [ScopeKind::ForLetLoop]
|
||||
@ -341,6 +339,8 @@ impl BlockScoping {
|
||||
}
|
||||
|
||||
impl Fold for BlockScoping {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_arrow_expr(&mut self, f: ArrowExpr) -> ArrowExpr {
|
||||
ArrowExpr {
|
||||
params: f.params.fold_with(self),
|
||||
@ -592,9 +592,9 @@ struct InfectionFinder<'a> {
|
||||
found: bool,
|
||||
}
|
||||
|
||||
noop_visit_type!(InfectionFinder<'_>);
|
||||
|
||||
impl Visit for InfectionFinder<'_> {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_assign_expr(&mut self, node: &AssignExpr, _: &dyn Node) {
|
||||
let old = self.found;
|
||||
self.found = false;
|
||||
@ -656,10 +656,10 @@ struct FlowHelper {
|
||||
has_return: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(FlowHelper);
|
||||
|
||||
/// noop
|
||||
impl Fold for FlowHelper {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_arrow_expr(&mut self, f: ArrowExpr) -> ArrowExpr {
|
||||
f
|
||||
}
|
||||
@ -728,9 +728,9 @@ struct FunctionFinder {
|
||||
found: bool,
|
||||
}
|
||||
|
||||
noop_visit_type!(FunctionFinder);
|
||||
|
||||
impl Visit for FunctionFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_function(&mut self, _: &Function, _: &dyn Node) {
|
||||
self.found = true
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ use fxhash::FxBuildHasher;
|
||||
use std::iter;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
@ -24,6 +24,10 @@ pub(crate) mod native;
|
||||
mod prop_name;
|
||||
mod super_field;
|
||||
|
||||
pub fn classes() -> impl Fold {
|
||||
Classes::default()
|
||||
}
|
||||
|
||||
type IndexMap<K, V> = indexmap::IndexMap<K, V, FxBuildHasher>;
|
||||
|
||||
/// `@babel/plugin-transform-classes`
|
||||
@ -58,12 +62,10 @@ type IndexMap<K, V> = indexmap::IndexMap<K, V, FxBuildHasher>;
|
||||
/// }();
|
||||
/// ```
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct Classes {
|
||||
struct Classes {
|
||||
in_strict: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(Classes);
|
||||
|
||||
struct Data {
|
||||
key_prop: Box<Prop>,
|
||||
method: Option<Box<Expr>>,
|
||||
@ -167,6 +169,8 @@ impl Classes {
|
||||
}
|
||||
|
||||
impl Fold for Classes {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(items)
|
||||
}
|
||||
@ -181,6 +185,8 @@ impl Fold for Classes {
|
||||
found: bool,
|
||||
};
|
||||
impl Visit for Visitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_class(&mut self, _: &Class, _: &dyn Node) {
|
||||
self.found = true
|
||||
}
|
||||
@ -875,6 +881,8 @@ fn is_always_initialized(body: &[Stmt]) -> bool {
|
||||
}
|
||||
|
||||
impl Visit for SuperFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_expr_or_super(&mut self, node: &ExprOrSuper, _: &dyn Node) {
|
||||
match *node {
|
||||
ExprOrSuper::Super(..) => self.found = true,
|
||||
|
@ -5,7 +5,7 @@ use swc_atoms::JsWord;
|
||||
use swc_common::{Mark, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::quote_ident;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
pub(super) struct SuperCallFinder {
|
||||
mode: Option<SuperFoldingMode>,
|
||||
@ -13,8 +13,6 @@ pub(super) struct SuperCallFinder {
|
||||
in_complex: bool,
|
||||
}
|
||||
|
||||
noop_visit_type!(SuperCallFinder);
|
||||
|
||||
impl SuperCallFinder {
|
||||
///
|
||||
/// - `None`: if no `super()` is found or super() is last call
|
||||
@ -68,6 +66,8 @@ macro_rules! mark_as_complex {
|
||||
}
|
||||
|
||||
impl Visit for SuperCallFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
mark_as_complex!(visit_arrow_expr, ArrowExpr);
|
||||
mark_as_complex!(visit_if_stmt, IfStmt);
|
||||
mark_as_complex!(visit_prop_name, PropName);
|
||||
@ -176,6 +176,7 @@ pub(super) enum SuperFoldingMode {
|
||||
}
|
||||
|
||||
impl Fold for ConstructorFolder<'_> {
|
||||
noop_fold_type!();
|
||||
fold_only_key!();
|
||||
|
||||
ignore_return!(fold_function, Function);
|
||||
@ -400,6 +401,8 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: Constructor) -> (Constr
|
||||
}
|
||||
|
||||
impl Fold for Replacer {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class(&mut self, n: Class) -> Class {
|
||||
n
|
||||
}
|
||||
@ -485,6 +488,8 @@ pub(super) struct VarRenamer<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Fold for VarRenamer<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_pat(&mut self, pat: Pat) -> Pat {
|
||||
match pat {
|
||||
Pat::Ident(ident) => {
|
||||
|
@ -5,7 +5,7 @@ use swc_atoms::js_word;
|
||||
use swc_common::{Mark, Span, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::quote_ident;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// Process function body.
|
||||
///
|
||||
@ -40,8 +40,6 @@ pub(crate) struct SuperFieldAccessFolder<'a> {
|
||||
pub this_alias_mark: Option<Mark>,
|
||||
}
|
||||
|
||||
noop_fold_type!(SuperFieldAccessFolder<'_>);
|
||||
|
||||
struct SuperCalleeFolder<'a> {
|
||||
vars: &'a mut Vec<VarDeclarator>,
|
||||
class_name: &'a Ident,
|
||||
@ -59,8 +57,6 @@ struct SuperCalleeFolder<'a> {
|
||||
this_alias_mark: Option<Mark>,
|
||||
}
|
||||
|
||||
noop_fold_type!(SuperCalleeFolder<'_>);
|
||||
|
||||
macro_rules! mark_nested {
|
||||
($name:ident, $T:tt) => {
|
||||
fn $name(&mut self, n: $T) -> $T {
|
||||
@ -79,6 +75,8 @@ macro_rules! mark_nested {
|
||||
}
|
||||
|
||||
impl<'a> Fold for SuperCalleeFolder<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fold_only_key!();
|
||||
|
||||
fn fold_expr(&mut self, n: Expr) -> Expr {
|
||||
@ -410,6 +408,8 @@ impl<'a> SuperCalleeFolder<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Fold for SuperFieldAccessFolder<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
mark_nested!(fold_function, Function);
|
||||
mark_nested!(fold_class, Class);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::util::{ExprFactory, StmtLike};
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-computed-properties`
|
||||
///
|
||||
@ -40,8 +40,6 @@ pub fn computed_properties() -> impl Fold {
|
||||
|
||||
struct ComputedProps;
|
||||
|
||||
noop_fold_type!(ComputedProps);
|
||||
|
||||
#[derive(Default)]
|
||||
struct ObjectLitFolder {
|
||||
vars: Vec<VarDeclarator>,
|
||||
@ -49,6 +47,8 @@ struct ObjectLitFolder {
|
||||
}
|
||||
|
||||
impl Fold for ObjectLitFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let expr = validate!(expr);
|
||||
let expr = expr.fold_children_with(self);
|
||||
@ -276,6 +276,8 @@ struct ComplexVisitor {
|
||||
}
|
||||
|
||||
impl Visit for ComplexVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_prop_name(&mut self, pn: &PropName, _: &dyn Node) {
|
||||
match *pn {
|
||||
PropName::Computed(..) => self.found = true,
|
||||
@ -285,6 +287,8 @@ impl Visit for ComplexVisitor {
|
||||
}
|
||||
|
||||
impl Fold for ComputedProps {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -362,6 +366,8 @@ struct ShouldWork {
|
||||
}
|
||||
|
||||
impl Visit for ShouldWork {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_prop_name(&mut self, node: &PropName, _: &dyn Node) {
|
||||
match *node {
|
||||
PropName::Computed(_) => self.found = true,
|
||||
|
@ -6,7 +6,7 @@ use serde::Deserialize;
|
||||
use std::iter;
|
||||
use swc_common::{Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-destructuring`
|
||||
///
|
||||
@ -37,8 +37,6 @@ struct Destructuring {
|
||||
c: Config,
|
||||
}
|
||||
|
||||
noop_fold_type!(Destructuring);
|
||||
|
||||
#[derive(Debug, Default, Clone, Copy, Deserialize)]
|
||||
pub struct Config {
|
||||
#[serde(default)]
|
||||
@ -448,6 +446,8 @@ impl AssignFolder {
|
||||
}
|
||||
|
||||
impl Fold for Destructuring {
|
||||
noop_fold_type!();
|
||||
|
||||
impl_for_for_stmt!(fold_for_in_stmt, ForInStmt);
|
||||
impl_for_for_stmt!(fold_for_of_stmt, ForOfStmt);
|
||||
|
||||
@ -519,6 +519,8 @@ struct AssignFolder {
|
||||
}
|
||||
|
||||
impl Fold for AssignFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_export_decl(&mut self, decl: ExportDecl) -> ExportDecl {
|
||||
let old = self.exporting;
|
||||
self.exporting = true;
|
||||
@ -1101,6 +1103,8 @@ struct DestructuringVisitor {
|
||||
}
|
||||
|
||||
impl Visit for DestructuringVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_pat(&mut self, node: &Pat, _: &dyn Node) {
|
||||
node.visit_children_with(self);
|
||||
match *node {
|
||||
|
@ -2,7 +2,7 @@ use std::collections::HashSet;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::Spanned;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn duplicate_keys() -> impl Fold {
|
||||
DuplicateKeys
|
||||
@ -10,9 +10,9 @@ pub fn duplicate_keys() -> impl Fold {
|
||||
|
||||
struct DuplicateKeys;
|
||||
|
||||
noop_fold_type!(DuplicateKeys);
|
||||
|
||||
impl Fold for DuplicateKeys {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let expr = expr.fold_children_with(self);
|
||||
|
||||
@ -37,9 +37,9 @@ struct PropFolder {
|
||||
setter_props: HashSet<JsWord>,
|
||||
}
|
||||
|
||||
noop_fold_type!(PropFolder);
|
||||
|
||||
impl Fold for PropFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, node: Expr) -> Expr {
|
||||
node
|
||||
}
|
||||
@ -87,6 +87,8 @@ struct PropNameFolder<'a> {
|
||||
props: &'a mut HashSet<JsWord>,
|
||||
}
|
||||
impl<'a> Fold for PropNameFolder<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, node: Expr) -> Expr {
|
||||
node
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use serde::Deserialize;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-for-of`
|
||||
///
|
||||
@ -53,8 +53,6 @@ struct ForOf {
|
||||
c: Config,
|
||||
}
|
||||
|
||||
noop_fold_type!(ForOf);
|
||||
|
||||
/// Real folder.
|
||||
struct Actual {
|
||||
c: Config,
|
||||
@ -395,6 +393,8 @@ impl Actual {
|
||||
}
|
||||
|
||||
impl Fold for Actual {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_stmt(&mut self, stmt: Stmt) -> Stmt {
|
||||
match stmt {
|
||||
Stmt::Labeled(LabeledStmt { span, label, body }) => {
|
||||
@ -498,6 +498,8 @@ fn make_finally_block(
|
||||
}
|
||||
|
||||
impl Fold for ForOf {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -565,6 +567,8 @@ struct ForOfFinder {
|
||||
}
|
||||
|
||||
impl Visit for ForOfFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_for_of_stmt(&mut self, _: &ForOfStmt, _: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{ext::PatOrExprExt, util::UsageFinder};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// `@babel/plugin-transform-function-name`
|
||||
///
|
||||
@ -26,14 +26,10 @@ pub fn function_name() -> impl Fold {
|
||||
#[derive(Clone, Copy)]
|
||||
struct FnName;
|
||||
|
||||
noop_fold_type!(FnName);
|
||||
|
||||
struct Renamer {
|
||||
name: Option<Ident>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Renamer);
|
||||
|
||||
/// This function makes a new private identifier if required.
|
||||
fn prepare(i: Ident, force: bool) -> Ident {
|
||||
if i.is_reserved_for_es3() || i.sym == *"await" || i.sym == *"eval" {
|
||||
@ -48,6 +44,8 @@ fn prepare(i: Ident, force: bool) -> Ident {
|
||||
}
|
||||
|
||||
impl Fold for FnName {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_assign_expr(&mut self, expr: AssignExpr) -> AssignExpr {
|
||||
let mut expr = expr.fold_children_with(self);
|
||||
|
||||
@ -152,6 +150,8 @@ macro_rules! noop {
|
||||
}
|
||||
|
||||
impl Fold for Renamer {
|
||||
noop_fold_type!();
|
||||
|
||||
impl_for!(fold_fn_expr, FnExpr);
|
||||
impl_for!(fold_class_expr, ClassExpr);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::util::ExprFactory;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-instanceof`
|
||||
///
|
||||
@ -28,18 +28,22 @@ use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
///
|
||||
/// _instanceof(foo, Bar);
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct InstanceOf;
|
||||
|
||||
noop_fold_type!(InstanceOf);
|
||||
pub fn instance_of() -> impl Fold {
|
||||
InstanceOf
|
||||
}
|
||||
struct InstanceOf;
|
||||
|
||||
impl Fold for InstanceOf {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
fn should_work(node: &Expr) -> bool {
|
||||
struct Visitor {
|
||||
found: bool,
|
||||
}
|
||||
impl Visit for Visitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_bin_expr(&mut self, e: &BinExpr, _: &dyn Node) {
|
||||
if e.op == op!("instanceof") {
|
||||
self.found = true
|
||||
|
@ -2,18 +2,16 @@ use crate::util::{prepend_stmts, ExprFactory};
|
||||
use arrayvec::ArrayVec;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn parameters() -> Params {
|
||||
pub fn parameters() -> impl 'static + Fold {
|
||||
Params
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Params;
|
||||
struct Params;
|
||||
// prevent_recurse!(Params, Pat);
|
||||
|
||||
noop_fold_type!(Params);
|
||||
|
||||
impl Params {
|
||||
fn fold_fn_like(&mut self, ps: Vec<Param>, body: BlockStmt) -> (Vec<Param>, BlockStmt) {
|
||||
let body = validate!(body);
|
||||
@ -249,5 +247,7 @@ impl Params {
|
||||
}
|
||||
|
||||
impl Fold for Params {
|
||||
noop_fold_type!();
|
||||
|
||||
impl_fold_fn!();
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use swc_common::{
|
||||
BytePos, Span, Spanned, SyntaxContext, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(super) struct Loc {
|
||||
@ -1416,6 +1416,8 @@ macro_rules! leap {
|
||||
}
|
||||
|
||||
impl Visit for LeapFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
leap!(visit_yield_expr, YieldExpr);
|
||||
leap!(visit_break_stmt, BreakStmt);
|
||||
leap!(visit_continue_stmt, ContinueStmt);
|
||||
@ -1438,6 +1440,8 @@ struct UnmarkedInvalidHandler {
|
||||
}
|
||||
|
||||
impl Fold for UnmarkedInvalidHandler {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
|
||||
@ -1457,6 +1461,8 @@ struct InvalidToLit<'a> {
|
||||
map: &'a [Loc],
|
||||
}
|
||||
impl Fold for InvalidToLit<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
|
||||
@ -1486,9 +1492,9 @@ struct CatchParamHandler<'a> {
|
||||
param: Option<&'a Pat>,
|
||||
}
|
||||
|
||||
noop_fold_type!(CatchParamHandler<'_>);
|
||||
|
||||
impl Fold for CatchParamHandler<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, node: Expr) -> Expr {
|
||||
match self.param {
|
||||
None => return node,
|
||||
|
@ -3,7 +3,7 @@ use smallvec::SmallVec;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub(super) type Vars = SmallVec<[Ident; 32]>;
|
||||
|
||||
@ -26,8 +26,6 @@ pub(super) struct Hoister {
|
||||
pub arguments: Option<Ident>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Hoister);
|
||||
|
||||
impl Hoister {
|
||||
fn var_decl_to_expr(&mut self, var: VarDecl) -> Expr {
|
||||
let var = var.fold_children_with(self);
|
||||
@ -59,6 +57,8 @@ impl Hoister {
|
||||
}
|
||||
|
||||
impl Fold for Hoister {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
|
||||
|
@ -4,7 +4,7 @@ use std::mem::replace;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
mod case;
|
||||
mod hoist;
|
||||
@ -30,8 +30,6 @@ struct Regenerator {
|
||||
top_level_vars: Vec<VarDeclarator>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Regenerator);
|
||||
|
||||
fn rt(global_mark: Mark, rt: Ident) -> Stmt {
|
||||
Stmt::Decl(Decl::Var(VarDecl {
|
||||
span: DUMMY_SP,
|
||||
@ -86,6 +84,8 @@ impl Regenerator {
|
||||
}
|
||||
|
||||
impl Fold for Regenerator {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
if !Finder::find(&e) {
|
||||
return e;
|
||||
@ -485,6 +485,8 @@ struct FnSentVisitor {
|
||||
}
|
||||
|
||||
impl Fold for FnSentVisitor {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e: Expr = e.fold_children_with(self);
|
||||
|
||||
@ -516,6 +518,8 @@ impl Finder {
|
||||
}
|
||||
|
||||
impl Visit for Finder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_function(&mut self, node: &Function, _: &dyn Node) {
|
||||
if node.is_generator {
|
||||
self.found = true;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// Compile ES2015 shorthand properties to ES5
|
||||
///
|
||||
@ -35,12 +35,16 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// }
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct Shorthand;
|
||||
pub fn shorthand() -> impl 'static + Fold {
|
||||
Shorthand
|
||||
}
|
||||
|
||||
noop_fold_type!(Shorthand);
|
||||
#[derive(Clone, Copy)]
|
||||
struct Shorthand;
|
||||
|
||||
impl Fold for Shorthand {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_prop(&mut self, prop: Prop) -> Prop {
|
||||
let prop = prop.fold_children_with(self);
|
||||
|
||||
|
@ -7,7 +7,7 @@ use std::mem;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{util::move_map::MoveMap, Span, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn spread(c: Config) -> impl Fold {
|
||||
Spread { c }
|
||||
@ -25,17 +25,15 @@ struct Spread {
|
||||
c: Config,
|
||||
}
|
||||
|
||||
noop_fold_type!(Spread);
|
||||
|
||||
#[derive(Default)]
|
||||
struct ActualFolder {
|
||||
c: Config,
|
||||
vars: Vec<VarDeclarator>,
|
||||
}
|
||||
|
||||
noop_fold_type!(ActualFolder);
|
||||
|
||||
impl Fold for Spread {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -72,6 +70,8 @@ impl Spread {
|
||||
}
|
||||
|
||||
impl Fold for ActualFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = validate!(e.fold_children_with(self));
|
||||
|
||||
|
@ -2,7 +2,7 @@ use crate::util::ExprFactory;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// Compile ES2015 sticky regex to an ES5 RegExp constructor
|
||||
///
|
||||
@ -18,12 +18,16 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// ```js
|
||||
/// new RegExp("o+", "y")
|
||||
/// ```
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct StickyRegex;
|
||||
pub fn sticky_regex() -> impl 'static + Fold {
|
||||
StickyRegex
|
||||
}
|
||||
|
||||
noop_fold_type!(StickyRegex);
|
||||
#[derive(Clone, Copy)]
|
||||
struct StickyRegex;
|
||||
|
||||
impl Fold for StickyRegex {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
|
||||
|
@ -3,16 +3,20 @@ use std::{iter, mem};
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{BytePos, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct TemplateLiteral {
|
||||
pub fn template_literal() -> impl Fold {
|
||||
TemplateLiteral::default()
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct TemplateLiteral {
|
||||
added: Vec<Stmt>,
|
||||
}
|
||||
|
||||
noop_fold_type!(TemplateLiteral);
|
||||
|
||||
impl Fold for TemplateLiteral {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = validate!(e);
|
||||
|
||||
|
@ -2,31 +2,18 @@ use crate::util::ExprFactory;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
pub fn typeof_symbol() -> impl Fold {
|
||||
TypeOfSymbol
|
||||
}
|
||||
|
||||
/// `@babel/plugin-transform-typeof-symbol`
|
||||
///
|
||||
/// # Example
|
||||
/// ## In
|
||||
///
|
||||
/// ```js
|
||||
/// typeof Symbol() === "symbol";
|
||||
/// ```
|
||||
///
|
||||
/// ## Out
|
||||
/// ```js
|
||||
/// var _typeof = function (obj) {
|
||||
/// return obj && obj.constructor === Symbol ? "symbol" : typeof obj;
|
||||
/// };
|
||||
///
|
||||
/// _typeof(Symbol()) === "symbol";
|
||||
/// ```
|
||||
#[derive(Clone)]
|
||||
pub struct TypeOfSymbol;
|
||||
|
||||
noop_fold_type!(TypeOfSymbol);
|
||||
struct TypeOfSymbol;
|
||||
|
||||
impl Fold for TypeOfSymbol {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
// fast path
|
||||
if !should_work(&expr) {
|
||||
@ -87,6 +74,8 @@ fn should_work(node: &Expr) -> bool {
|
||||
found: bool,
|
||||
}
|
||||
impl Visit for Visitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_unary_expr(&mut self, e: &UnaryExpr, _: &dyn Node) {
|
||||
if e.op == op!("typeof") {
|
||||
self.found = true
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
};
|
||||
use swc_common::{Span, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-exponentiation-operator`
|
||||
///
|
||||
@ -28,19 +28,18 @@ use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
pub fn exponentation() -> impl Fold {
|
||||
Exponentation
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct Exponentation;
|
||||
|
||||
noop_fold_type!(Exponentation);
|
||||
|
||||
#[derive(Default)]
|
||||
struct AssignFolder {
|
||||
vars: Vec<VarDeclarator>,
|
||||
}
|
||||
|
||||
noop_fold_type!(AssignFolder);
|
||||
|
||||
impl Fold for AssignFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = e.fold_children_with(self);
|
||||
|
||||
@ -95,6 +94,8 @@ impl Fold for AssignFolder {
|
||||
}
|
||||
|
||||
impl Fold for Exponentation {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -167,6 +168,8 @@ struct ShouldFold {
|
||||
found: bool,
|
||||
}
|
||||
impl Visit for ShouldFold {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_bin_expr(&mut self, e: &BinExpr, _: &dyn Node) {
|
||||
if e.op == op!("**") {
|
||||
self.found = true;
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
use std::iter;
|
||||
use swc_common::{Mark, Span, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-transform-async-to-generator`
|
||||
///
|
||||
@ -34,15 +34,13 @@ pub fn async_to_generator() -> impl Fold {
|
||||
#[derive(Default, Clone)]
|
||||
struct AsyncToGenerator;
|
||||
|
||||
noop_fold_type!(AsyncToGenerator);
|
||||
|
||||
struct Actual {
|
||||
extra_stmts: Vec<Stmt>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Actual);
|
||||
|
||||
impl Fold for AsyncToGenerator {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -86,6 +84,8 @@ impl AsyncToGenerator {
|
||||
}
|
||||
|
||||
impl Fold for Actual {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class_method(&mut self, m: ClassMethod) -> ClassMethod {
|
||||
if m.function.body.is_none() {
|
||||
return m;
|
||||
@ -401,6 +401,8 @@ impl MethodFolder {
|
||||
}
|
||||
|
||||
impl Fold for MethodFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let expr = validate!(expr);
|
||||
// TODO(kdy): Cache (Reuse declaration for same property)
|
||||
@ -758,6 +760,8 @@ fn make_fn_ref(mut expr: FnExpr) -> Expr {
|
||||
}
|
||||
|
||||
impl Fold for AwaitToYield {
|
||||
noop_fold_type!();
|
||||
|
||||
noop!(fold_fn_decl, FnDecl);
|
||||
noop!(fold_fn_expr, FnExpr);
|
||||
noop!(fold_constructor, Constructor);
|
||||
@ -819,6 +823,8 @@ struct AsyncVisitor {
|
||||
}
|
||||
|
||||
impl Visit for AsyncVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_function(&mut self, f: &Function, _: &dyn Node) {
|
||||
if f.is_async {
|
||||
self.found = true;
|
||||
|
@ -4,7 +4,7 @@ use crate::util::{
|
||||
use std::{iter, mem};
|
||||
use swc_common::{chain, util::move_map::MoveMap, Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// `@babel/plugin-proposal-object-rest-spread`
|
||||
pub fn object_rest_spread() -> impl Fold {
|
||||
@ -13,8 +13,6 @@ pub fn object_rest_spread() -> impl Fold {
|
||||
|
||||
struct ObjectRest;
|
||||
|
||||
noop_fold_type!(ObjectRest);
|
||||
|
||||
#[allow(clippy::vec_box)]
|
||||
struct RestFolder {
|
||||
/// Injected before the original statement.
|
||||
@ -25,8 +23,6 @@ struct RestFolder {
|
||||
exprs: Vec<Box<Expr>>,
|
||||
}
|
||||
|
||||
noop_fold_type!(RestFolder);
|
||||
|
||||
macro_rules! impl_for_for_stmt {
|
||||
($name:ident, $T:tt) => {
|
||||
fn $name(&mut self, mut for_stmt: $T) -> $T {
|
||||
@ -143,6 +139,8 @@ macro_rules! impl_for_for_stmt {
|
||||
}
|
||||
|
||||
impl Fold for RestFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
impl_for_for_stmt!(fold_for_in_stmt, ForInStmt);
|
||||
impl_for_for_stmt!(fold_for_of_stmt, ForOfStmt);
|
||||
impl_fold_fn!();
|
||||
@ -381,6 +379,8 @@ struct RestVisitor {
|
||||
}
|
||||
|
||||
impl Visit for RestVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_object_pat_prop(&mut self, prop: &ObjectPatProp, _: &dyn Node) {
|
||||
match *prop {
|
||||
ObjectPatProp::Rest(..) => self.found = true,
|
||||
@ -399,6 +399,7 @@ where
|
||||
}
|
||||
|
||||
impl Fold for ObjectRest {
|
||||
noop_fold_type!();
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
@ -1016,6 +1017,8 @@ fn excluded_props(props: &[ObjectPatProp]) -> Vec<Option<ExprOrSpread>> {
|
||||
fn simplify_pat(pat: Pat) -> Pat {
|
||||
struct PatSimplifier;
|
||||
impl Fold for PatSimplifier {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_pat(&mut self, pat: Pat) -> Pat {
|
||||
let pat = pat.fold_children_with(self);
|
||||
|
||||
@ -1055,9 +1058,9 @@ fn simplify_pat(pat: Pat) -> Pat {
|
||||
|
||||
struct ObjectSpread;
|
||||
|
||||
noop_fold_type!(ObjectSpread);
|
||||
|
||||
impl Fold for ObjectSpread {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
// fast-path
|
||||
if !contains_spread(&expr) {
|
||||
@ -1132,6 +1135,8 @@ fn contains_spread(expr: &Expr) -> bool {
|
||||
}
|
||||
|
||||
impl Visit for Visitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_spread_element(&mut self, _: &SpreadElement, _: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
struct OptionalCatchBinding;
|
||||
|
||||
noop_fold_type!(OptionalCatchBinding);
|
||||
|
||||
pub fn optional_catch_binding() -> impl Fold {
|
||||
OptionalCatchBinding
|
||||
}
|
||||
|
||||
impl Fold for OptionalCatchBinding {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_catch_clause(&mut self, mut cc: CatchClause) -> CatchClause {
|
||||
cc = cc.fold_children_with(self);
|
||||
|
||||
|
@ -15,7 +15,7 @@ use std::{collections::HashSet, mem::take};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{util::move_map::MoveMap, Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith};
|
||||
|
||||
mod class_name_tdz;
|
||||
mod private_field;
|
||||
@ -51,6 +51,8 @@ struct ClassProperties {
|
||||
}
|
||||
|
||||
impl Fold for ClassProperties {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_ident(&mut self, i: Ident) -> Ident {
|
||||
Ident {
|
||||
optional: false,
|
||||
|
@ -1,15 +1,15 @@
|
||||
use crate::util::ExprFactory;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub(super) struct ClassNameTdzFolder<'a> {
|
||||
pub class_name: &'a Ident,
|
||||
}
|
||||
|
||||
noop_fold_type!(ClassNameTdzFolder<'_>);
|
||||
|
||||
impl<'a> Fold for ClassNameTdzFolder<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
match expr {
|
||||
Expr::Ident(i) => {
|
||||
|
@ -6,7 +6,7 @@ use std::{collections::HashSet, iter, mem};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{Mark, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub(super) struct FieldAccessFolder<'a> {
|
||||
pub mark: Mark,
|
||||
@ -16,8 +16,6 @@ pub(super) struct FieldAccessFolder<'a> {
|
||||
pub in_assign_pat: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(FieldAccessFolder<'_>);
|
||||
|
||||
macro_rules! take_vars {
|
||||
($name:ident, $T:tt) => {
|
||||
fn $name(&mut self, f: $T) -> $T {
|
||||
@ -47,6 +45,8 @@ macro_rules! take_vars {
|
||||
}
|
||||
|
||||
impl<'a> Fold for FieldAccessFolder<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
take_vars!(fold_function, Function);
|
||||
take_vars!(fold_constructor, Constructor);
|
||||
|
||||
|
@ -1,13 +1,13 @@
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub(super) struct ThisInStaticFolder {
|
||||
pub ident: Ident,
|
||||
}
|
||||
|
||||
noop_fold_type!(ThisInStaticFolder);
|
||||
|
||||
impl Fold for ThisInStaticFolder {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class(&mut self, n: Class) -> Class {
|
||||
n
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::Mark;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
/// Used to rename **binding** identifiers in constructor.
|
||||
pub(super) struct UsedNameRenamer<'a> {
|
||||
@ -9,9 +9,9 @@ pub(super) struct UsedNameRenamer<'a> {
|
||||
pub used_names: &'a [JsWord],
|
||||
}
|
||||
|
||||
noop_fold_type!(UsedNameRenamer<'_>);
|
||||
|
||||
impl<'a> Fold for UsedNameRenamer<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
match e {
|
||||
Expr::Ident(..) => e,
|
||||
@ -49,8 +49,6 @@ pub(super) struct UsedNameCollector<'a> {
|
||||
pub used_names: &'a mut Vec<JsWord>,
|
||||
}
|
||||
|
||||
noop_visit_type!(UsedNameCollector<'_>);
|
||||
|
||||
macro_rules! noop {
|
||||
($name:ident, $T:path) => {
|
||||
/// no-op
|
||||
@ -59,6 +57,8 @@ macro_rules! noop {
|
||||
}
|
||||
|
||||
impl<'a> Visit for UsedNameCollector<'a> {
|
||||
noop_visit_type!();
|
||||
|
||||
noop!(visit_arrow_expr, ArrowExpr);
|
||||
noop!(visit_function, Function);
|
||||
noop!(visit_setter_prop, SetterProp);
|
||||
|
@ -2,7 +2,7 @@ use crate::util::{alias_if_required, undefined, StmtLike};
|
||||
use std::mem::replace;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -43,6 +43,8 @@ impl NullishCoalescing {
|
||||
}
|
||||
|
||||
impl Fold for NullishCoalescing {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, n: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
self.fold_stmt_like(n)
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::util::{prepend, undefined, ExprFactory, StmtLike};
|
||||
use std::{fmt::Debug, iter::once, mem};
|
||||
use swc_common::{Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn optional_chaining() -> impl Fold {
|
||||
OptChaining::default()
|
||||
@ -13,9 +13,9 @@ struct OptChaining {
|
||||
vars: Vec<VarDeclarator>,
|
||||
}
|
||||
|
||||
noop_fold_type!(OptChaining);
|
||||
|
||||
impl Fold for OptChaining {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
let e = match e {
|
||||
Expr::OptChain(e) => Expr::Cond(validate!(self.unwrap(e))),
|
||||
|
@ -1,5 +1,6 @@
|
||||
pub use self::{
|
||||
member_expr_lits::MemberExprLit, prop_lits::PropertyLiteral, reserved_word::ReservedWord,
|
||||
member_expr_lits::member_expression_literals, prop_lits::property_literals,
|
||||
reserved_word::reserved_words,
|
||||
};
|
||||
use swc_common::chain;
|
||||
use swc_ecma_visit::Fold;
|
||||
@ -11,8 +12,8 @@ mod reserved_word;
|
||||
/// Make output es3-compatible.
|
||||
pub fn es3(preserve_import: bool) -> impl Fold {
|
||||
chain!(
|
||||
PropertyLiteral,
|
||||
MemberExprLit,
|
||||
ReservedWord { preserve_import }
|
||||
property_literals(),
|
||||
member_expression_literals(),
|
||||
reserved_words(preserve_import)
|
||||
)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::util::is_valid_ident;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// babel: `transform-member-expression-literals`
|
||||
///
|
||||
@ -19,12 +19,15 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// obj["const"] = "isKeyword";
|
||||
/// obj["var"] = "isKeyword";
|
||||
/// ```
|
||||
pub fn member_expression_literals() -> impl Fold {
|
||||
MemberExprLit
|
||||
}
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct MemberExprLit;
|
||||
|
||||
noop_fold_type!(MemberExprLit);
|
||||
struct MemberExprLit;
|
||||
|
||||
impl Fold for MemberExprLit {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_member_expr(&mut self, e: MemberExpr) -> MemberExpr {
|
||||
let mut e = validate!(e.fold_children_with(self));
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::util::is_valid_ident;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// babel: `transform-property-literals`
|
||||
///
|
||||
@ -29,12 +29,15 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// foo: 1
|
||||
/// };
|
||||
/// ```
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct PropertyLiteral;
|
||||
pub fn property_literals() -> impl Fold {
|
||||
PropertyLiteral
|
||||
}
|
||||
|
||||
noop_fold_type!(PropertyLiteral);
|
||||
struct PropertyLiteral;
|
||||
|
||||
impl Fold for PropertyLiteral {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_prop_name(&mut self, n: PropName) -> PropName {
|
||||
let n = validate!(n.fold_children_with(self));
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// babel: `@babel/plugin-transform-reserved-words`
|
||||
///
|
||||
@ -18,14 +18,16 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// var _abstract = 1;
|
||||
/// var x = _abstract + 1;
|
||||
/// ```
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct ReservedWord {
|
||||
pub fn reserved_words(preserve_import: bool) -> impl Fold {
|
||||
ReservedWord { preserve_import }
|
||||
}
|
||||
struct ReservedWord {
|
||||
pub preserve_import: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(ReservedWord);
|
||||
|
||||
impl Fold for ReservedWord {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_export_specifier(&mut self, n: ExportSpecifier) -> ExportSpecifier {
|
||||
n
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use swc_atoms::JsWord;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn reserved_words() -> impl 'static + Fold {
|
||||
EsReservedWord {}
|
||||
@ -8,9 +8,9 @@ pub fn reserved_words() -> impl 'static + Fold {
|
||||
|
||||
struct EsReservedWord {}
|
||||
|
||||
noop_fold_type!(EsReservedWord);
|
||||
|
||||
impl Fold for EsReservedWord {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_export_specifier(&mut self, n: ExportSpecifier) -> ExportSpecifier {
|
||||
n
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use swc_common::{sync::Lrc, util::move_map::MoveMap, FileName, SourceMap};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput};
|
||||
use swc_ecma_utils::HANDLER;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn const_modules(
|
||||
cm: Lrc<SourceMap>,
|
||||
@ -76,14 +76,14 @@ struct ConstModules {
|
||||
scope: Scope,
|
||||
}
|
||||
|
||||
noop_fold_type!(ConstModules);
|
||||
|
||||
#[derive(Default)]
|
||||
struct Scope {
|
||||
imported: HashMap<JsWord, Arc<Expr>>,
|
||||
}
|
||||
|
||||
impl Fold for ConstModules {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
items.move_flat_map(|item| match item {
|
||||
ModuleItem::ModuleDecl(ModuleDecl::Import(import)) => {
|
||||
|
@ -9,7 +9,7 @@ use swc_common::{
|
||||
Span, Spanned,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
pub fn fixer<'a>(comments: Option<&'a dyn Comments>) -> impl 'a + Fold {
|
||||
Fixer {
|
||||
@ -29,8 +29,6 @@ struct Fixer<'a> {
|
||||
span_map: FxHashMap<Span, Span>,
|
||||
}
|
||||
|
||||
noop_fold_type!(Fixer);
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum Context {
|
||||
@ -70,6 +68,8 @@ macro_rules! array {
|
||||
}
|
||||
|
||||
impl Fold for Fixer<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
array!(fold_array_lit, ArrayLit);
|
||||
// array!(ArrayPat);
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
use once_cell::sync::Lazy;
|
||||
use scoped_tls::scoped_thread_local;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use swc_common::{FileName, FilePathMapping, Mark, SourceMap, Span, DUMMY_SP};
|
||||
use swc_common::{FileName, FilePathMapping, Mark, SourceMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput};
|
||||
use swc_ecma_utils::{prepend_stmts, quote_ident, quote_str, DropSpan};
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{as_folder, noop_visit_mut_type, Fold, VisitMut, VisitMutWith};
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! enable_helper {
|
||||
@ -31,10 +31,11 @@ macro_rules! add_to {
|
||||
);
|
||||
let stmts = Parser::new_from(lexer)
|
||||
.parse_script()
|
||||
.map(|script| {
|
||||
script.body.fold_with(&mut DropSpan {
|
||||
.map(|mut script| {
|
||||
script.body.visit_mut_with(&mut DropSpan {
|
||||
preserve_ctxt: false,
|
||||
})
|
||||
});
|
||||
script.body
|
||||
})
|
||||
.map_err(|e| {
|
||||
unreachable!("Error occurred while parsing error: {:?}", e);
|
||||
@ -49,7 +50,10 @@ macro_rules! add_to {
|
||||
STMTS
|
||||
.iter()
|
||||
.cloned()
|
||||
.map(|stmt| stmt.fold_with(&mut Marker($mark)))
|
||||
.map(|mut stmt| {
|
||||
stmt.visit_mut_with(&mut Marker($mark));
|
||||
stmt
|
||||
})
|
||||
.map(ModuleItem::Stmt),
|
||||
)
|
||||
}
|
||||
@ -223,10 +227,11 @@ define_helpers!(Helpers {
|
||||
class_private_field_destructure: (),
|
||||
});
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InjectHelpers;
|
||||
pub fn inject_helpers() -> impl Fold {
|
||||
as_folder(InjectHelpers)
|
||||
}
|
||||
|
||||
noop_fold_type!(InjectHelpers);
|
||||
struct InjectHelpers;
|
||||
|
||||
impl InjectHelpers {
|
||||
fn mk_helpers(&self) -> Vec<ModuleItem> {
|
||||
@ -251,23 +256,23 @@ impl InjectHelpers {
|
||||
}
|
||||
}
|
||||
|
||||
impl Fold for InjectHelpers {
|
||||
fn fold_module(&mut self, module: Module) -> Module {
|
||||
let mut module = validate!(module);
|
||||
impl VisitMut for InjectHelpers {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_module(&mut self, module: &mut Module) {
|
||||
let helpers = self.mk_helpers();
|
||||
|
||||
prepend_stmts(&mut module.body, helpers.into_iter());
|
||||
module
|
||||
}
|
||||
}
|
||||
|
||||
struct Marker(Mark);
|
||||
|
||||
noop_fold_type!(Marker);
|
||||
impl VisitMut for Marker {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
impl Fold for Marker {
|
||||
fn fold_span(&mut self, sp: Span) -> Span {
|
||||
sp.apply_mark(self.0)
|
||||
fn visit_mut_ident(&mut self, i: &mut Ident) {
|
||||
i.span = i.span.apply_mark(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -275,6 +280,7 @@ impl Fold for Marker {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::pass::noop;
|
||||
use swc_ecma_visit::{as_folder, FoldWith};
|
||||
|
||||
#[test]
|
||||
fn external_helper() {
|
||||
@ -283,9 +289,9 @@ swcHelpers._throw()";
|
||||
crate::tests::Tester::run(|tester| {
|
||||
HELPERS.set(&Helpers::new(true), || {
|
||||
let expected = tester.apply_transform(
|
||||
DropSpan {
|
||||
as_folder(DropSpan {
|
||||
preserve_ctxt: false,
|
||||
},
|
||||
}),
|
||||
"output.js",
|
||||
Default::default(),
|
||||
"import * as swcHelpers1 from '@swc/helpers';
|
||||
@ -296,7 +302,7 @@ swcHelpers._throw();",
|
||||
|
||||
eprintln!("----- Actual -----");
|
||||
|
||||
let tr = InjectHelpers;
|
||||
let tr = as_folder(InjectHelpers);
|
||||
let actual = tester
|
||||
.apply_transform(tr, "input.js", Default::default(), input)?
|
||||
.fold_with(&mut crate::hygiene::hygiene())
|
||||
@ -329,7 +335,7 @@ swcHelpers._throw();",
|
||||
Default::default(),
|
||||
|_| {
|
||||
enable_helper!(throw);
|
||||
InjectHelpers
|
||||
as_folder(InjectHelpers)
|
||||
},
|
||||
"'use strict'",
|
||||
"'use strict'
|
||||
@ -347,7 +353,7 @@ function _throw(e) {
|
||||
Default::default(),
|
||||
|_| {
|
||||
enable_helper!(throw);
|
||||
InjectHelpers
|
||||
as_folder(InjectHelpers)
|
||||
},
|
||||
"let _throw = null",
|
||||
"function _throw(e) {
|
||||
|
@ -8,7 +8,7 @@ use std::{cell::RefCell, collections::HashMap};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{chain, Span, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{as_folder, noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut};
|
||||
|
||||
mod ops;
|
||||
#[cfg(test)]
|
||||
@ -21,8 +21,6 @@ struct Hygiene<'a> {
|
||||
ident_type: IdentType,
|
||||
}
|
||||
|
||||
noop_fold_type!(Hygiene<'_>);
|
||||
|
||||
type Contexts = SmallVec<[SyntaxContext; 32]>;
|
||||
|
||||
impl<'a> Hygiene<'a> {
|
||||
@ -141,23 +139,25 @@ impl<'a> Hygiene<'a> {
|
||||
}
|
||||
|
||||
pub fn hygiene() -> impl Fold + 'static {
|
||||
#[derive(Clone, Copy)]
|
||||
struct MarkClearer;
|
||||
impl Fold for MarkClearer {
|
||||
fn fold_span(&mut self, span: Span) -> Span {
|
||||
span.with_ctxt(SyntaxContext::empty())
|
||||
}
|
||||
}
|
||||
|
||||
chain!(
|
||||
Hygiene {
|
||||
current: Default::default(),
|
||||
ident_type: IdentType::Ref,
|
||||
},
|
||||
MarkClearer
|
||||
as_folder(MarkClearer)
|
||||
)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct MarkClearer;
|
||||
impl VisitMut for MarkClearer {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_span(&mut self, span: &mut Span) {
|
||||
*span = span.with_ctxt(SyntaxContext::empty());
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Hygiene<'a> {
|
||||
fn apply_ops<N>(&mut self, node: N) -> N
|
||||
where
|
||||
@ -485,6 +485,8 @@ macro_rules! track_ident {
|
||||
}
|
||||
|
||||
impl<'a> Fold for Hygiene<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
track_ident!();
|
||||
|
||||
fn fold_arrow_expr(&mut self, mut node: ArrowExpr) -> ArrowExpr {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{util::move_map::MoveMap, Spanned, SyntaxContext, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) enum ScopeOp {
|
||||
@ -13,9 +13,9 @@ pub(super) enum ScopeOp {
|
||||
|
||||
pub(super) struct Operator<'a>(pub &'a [ScopeOp]);
|
||||
|
||||
noop_fold_type!(Operator<'_>);
|
||||
|
||||
impl<'a> Fold for Operator<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
let mut stmts = Vec::with_capacity(items.len());
|
||||
|
||||
@ -287,6 +287,8 @@ struct VarFolder<'a, 'b> {
|
||||
}
|
||||
|
||||
impl Fold for VarFolder<'_, '_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, n: Expr) -> Expr {
|
||||
n
|
||||
}
|
||||
|
@ -201,155 +201,3 @@ macro_rules! validate {
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! noop_fold_type {
|
||||
($F:ty, $N:tt) => {
|
||||
// impl Fold<swc_ecma_ast::$N> for $F {
|
||||
// #[inline]
|
||||
// fn fold(&mut self, node: swc_ecma_ast::$N) -> swc_ecma_ast::$N {
|
||||
// node
|
||||
// }
|
||||
// }
|
||||
};
|
||||
($F:ty) => {
|
||||
noop_fold_type!($F, Accessibility);
|
||||
noop_fold_type!($F, TruePlusMinus);
|
||||
noop_fold_type!($F, TsArrayType);
|
||||
noop_fold_type!($F, TsCallSignatureDecl);
|
||||
noop_fold_type!($F, TsConditionalType);
|
||||
noop_fold_type!($F, TsConstructSignatureDecl);
|
||||
noop_fold_type!($F, TsConstructorType);
|
||||
noop_fold_type!($F, TsEntityName);
|
||||
noop_fold_type!($F, TsEnumDecl);
|
||||
noop_fold_type!($F, TsEnumMember);
|
||||
noop_fold_type!($F, TsEnumMemberId);
|
||||
noop_fold_type!($F, TsExternalModuleRef);
|
||||
noop_fold_type!($F, TsFnOrConstructorType);
|
||||
noop_fold_type!($F, TsFnParam);
|
||||
noop_fold_type!($F, TsFnType);
|
||||
noop_fold_type!($F, TsImportEqualsDecl);
|
||||
noop_fold_type!($F, TsImportType);
|
||||
noop_fold_type!($F, TsIndexSignature);
|
||||
noop_fold_type!($F, TsIndexedAccessType);
|
||||
noop_fold_type!($F, TsInferType);
|
||||
noop_fold_type!($F, TsInterfaceBody);
|
||||
noop_fold_type!($F, TsInterfaceDecl);
|
||||
noop_fold_type!($F, TsIntersectionType);
|
||||
noop_fold_type!($F, TsKeywordType);
|
||||
noop_fold_type!($F, TsKeywordTypeKind);
|
||||
noop_fold_type!($F, TsMappedType);
|
||||
noop_fold_type!($F, TsMethodSignature);
|
||||
noop_fold_type!($F, TsModuleBlock);
|
||||
noop_fold_type!($F, TsModuleDecl);
|
||||
noop_fold_type!($F, TsModuleName);
|
||||
noop_fold_type!($F, TsModuleRef);
|
||||
noop_fold_type!($F, TsNamespaceBody);
|
||||
noop_fold_type!($F, TsNamespaceDecl);
|
||||
noop_fold_type!($F, TsNamespaceExportDecl);
|
||||
noop_fold_type!($F, TsOptionalType);
|
||||
noop_fold_type!($F, TsParamProp);
|
||||
noop_fold_type!($F, TsParamPropParam);
|
||||
noop_fold_type!($F, TsParenthesizedType);
|
||||
noop_fold_type!($F, TsPropertySignature);
|
||||
noop_fold_type!($F, TsQualifiedName);
|
||||
noop_fold_type!($F, TsRestType);
|
||||
noop_fold_type!($F, TsSignatureDecl);
|
||||
noop_fold_type!($F, TsThisType);
|
||||
noop_fold_type!($F, TsThisTypeOrIdent);
|
||||
noop_fold_type!($F, TsTupleType);
|
||||
noop_fold_type!($F, TsType);
|
||||
noop_fold_type!($F, TsTypeAliasDecl);
|
||||
noop_fold_type!($F, TsTypeAnn);
|
||||
noop_fold_type!($F, TsTypeAssertion);
|
||||
noop_fold_type!($F, TsTypeCastExpr);
|
||||
noop_fold_type!($F, TsTypeElement);
|
||||
noop_fold_type!($F, TsTypeLit);
|
||||
noop_fold_type!($F, TsTypeOperator);
|
||||
noop_fold_type!($F, TsTypeOperatorOp);
|
||||
noop_fold_type!($F, TsTypeParam);
|
||||
noop_fold_type!($F, TsTypeParamDecl);
|
||||
noop_fold_type!($F, TsTypeParamInstantiation);
|
||||
noop_fold_type!($F, TsTypePredicate);
|
||||
noop_fold_type!($F, TsTypeQuery);
|
||||
noop_fold_type!($F, TsTypeQueryExpr);
|
||||
noop_fold_type!($F, TsTypeRef);
|
||||
noop_fold_type!($F, TsUnionOrIntersectionType);
|
||||
noop_fold_type!($F, TsUnionType);
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! noop_visit_type {
|
||||
($F:ty, $N:tt) => {
|
||||
// impl Visit<swc_ecma_ast::$N> for $F {
|
||||
// #[inline]
|
||||
// fn visit(&mut self, _: &swc_ecma_ast::$N) {}
|
||||
// }
|
||||
};
|
||||
($F:ty) => {
|
||||
noop_visit_type!($F, Accessibility);
|
||||
noop_visit_type!($F, TruePlusMinus);
|
||||
noop_visit_type!($F, TsArrayType);
|
||||
noop_visit_type!($F, TsCallSignatureDecl);
|
||||
noop_visit_type!($F, TsConditionalType);
|
||||
noop_visit_type!($F, TsConstructSignatureDecl);
|
||||
noop_visit_type!($F, TsConstructorType);
|
||||
noop_visit_type!($F, TsEntityName);
|
||||
noop_visit_type!($F, TsEnumDecl);
|
||||
noop_visit_type!($F, TsEnumMember);
|
||||
noop_visit_type!($F, TsEnumMemberId);
|
||||
noop_visit_type!($F, TsExternalModuleRef);
|
||||
noop_visit_type!($F, TsFnOrConstructorType);
|
||||
noop_visit_type!($F, TsFnParam);
|
||||
noop_visit_type!($F, TsFnType);
|
||||
noop_visit_type!($F, TsImportEqualsDecl);
|
||||
noop_visit_type!($F, TsImportType);
|
||||
noop_visit_type!($F, TsIndexSignature);
|
||||
noop_visit_type!($F, TsIndexedAccessType);
|
||||
noop_visit_type!($F, TsInferType);
|
||||
noop_visit_type!($F, TsInterfaceBody);
|
||||
noop_visit_type!($F, TsInterfaceDecl);
|
||||
noop_visit_type!($F, TsIntersectionType);
|
||||
noop_visit_type!($F, TsKeywordType);
|
||||
noop_visit_type!($F, TsKeywordTypeKind);
|
||||
noop_visit_type!($F, TsMappedType);
|
||||
noop_visit_type!($F, TsMethodSignature);
|
||||
noop_visit_type!($F, TsModuleBlock);
|
||||
noop_visit_type!($F, TsModuleDecl);
|
||||
noop_visit_type!($F, TsModuleName);
|
||||
noop_visit_type!($F, TsModuleRef);
|
||||
noop_visit_type!($F, TsNamespaceBody);
|
||||
noop_visit_type!($F, TsNamespaceDecl);
|
||||
noop_visit_type!($F, TsNamespaceExportDecl);
|
||||
noop_visit_type!($F, TsOptionalType);
|
||||
noop_visit_type!($F, TsParamProp);
|
||||
noop_visit_type!($F, TsParamPropParam);
|
||||
noop_visit_type!($F, TsParenthesizedType);
|
||||
noop_visit_type!($F, TsPropertySignature);
|
||||
noop_visit_type!($F, TsQualifiedName);
|
||||
noop_visit_type!($F, TsRestType);
|
||||
noop_visit_type!($F, TsSignatureDecl);
|
||||
noop_visit_type!($F, TsThisType);
|
||||
noop_visit_type!($F, TsThisTypeOrIdent);
|
||||
noop_visit_type!($F, TsTupleType);
|
||||
noop_visit_type!($F, TsType);
|
||||
noop_visit_type!($F, TsTypeAliasDecl);
|
||||
noop_visit_type!($F, TsTypeAnn);
|
||||
noop_visit_type!($F, TsTypeAssertion);
|
||||
noop_visit_type!($F, TsTypeCastExpr);
|
||||
noop_visit_type!($F, TsTypeElement);
|
||||
noop_visit_type!($F, TsTypeLit);
|
||||
noop_visit_type!($F, TsTypeOperator);
|
||||
noop_visit_type!($F, TsTypeOperatorOp);
|
||||
noop_visit_type!($F, TsTypeParam);
|
||||
noop_visit_type!($F, TsTypeParamDecl);
|
||||
noop_visit_type!($F, TsTypeParamInstantiation);
|
||||
noop_visit_type!($F, TsTypePredicate);
|
||||
noop_visit_type!($F, TsTypeQuery);
|
||||
noop_visit_type!($F, TsTypeQueryExpr);
|
||||
noop_visit_type!($F, TsTypeRef);
|
||||
noop_visit_type!($F, TsUnionOrIntersectionType);
|
||||
noop_visit_type!($F, TsUnionType);
|
||||
};
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ use std::iter;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{Mark, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith};
|
||||
|
||||
pub fn amd(config: Config) -> impl Fold {
|
||||
Amd {
|
||||
@ -27,8 +27,6 @@ struct Amd {
|
||||
exports: Exports,
|
||||
}
|
||||
|
||||
noop_fold_type!(Amd);
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields, rename_all = "camelCase")]
|
||||
pub struct Config {
|
||||
@ -40,6 +38,8 @@ pub struct Config {
|
||||
}
|
||||
|
||||
impl Fold for Amd {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let top_level = self.in_top_level;
|
||||
|
||||
|
@ -8,7 +8,7 @@ use fxhash::FxHashSet;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{Mark, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith};
|
||||
|
||||
pub fn common_js(root_mark: Mark, config: Config) -> impl Fold {
|
||||
CommonJs {
|
||||
@ -26,9 +26,9 @@ struct CommonJs {
|
||||
in_top_level: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(CommonJs);
|
||||
|
||||
impl Fold for CommonJs {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
let mut emitted_esmodule = false;
|
||||
let mut stmts = Vec::with_capacity(items.len() + 4);
|
||||
|
@ -2,7 +2,7 @@ use super::util::Scope;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, Node, Visit};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, Node, Visit};
|
||||
|
||||
pub fn import_analyzer() -> impl Fold {
|
||||
ImportAnalyzer {
|
||||
@ -15,10 +15,9 @@ struct ImportAnalyzer {
|
||||
scope: Scope,
|
||||
}
|
||||
|
||||
noop_fold_type!(ImportAnalyzer);
|
||||
noop_visit_type!(ImportAnalyzer);
|
||||
|
||||
impl Fold for ImportAnalyzer {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module(&mut self, module: Module) -> Module {
|
||||
self.visit_module(&module, &Invalid { span: DUMMY_SP } as _);
|
||||
|
||||
@ -35,6 +34,8 @@ impl Fold for ImportAnalyzer {
|
||||
}
|
||||
|
||||
impl Visit for ImportAnalyzer {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_export_all(&mut self, export: &ExportAll, _parent: &dyn Node) {
|
||||
*self
|
||||
.scope
|
||||
|
@ -9,7 +9,7 @@ use fxhash::FxHashSet;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::{sync::Lrc, Mark, SourceMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith};
|
||||
|
||||
mod config;
|
||||
|
||||
@ -34,9 +34,9 @@ struct Umd {
|
||||
exports: Exports,
|
||||
}
|
||||
|
||||
noop_fold_type!(Umd);
|
||||
|
||||
impl Fold for Umd {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let exports = self.exports.0.clone();
|
||||
let top_level = self.in_top_level;
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub use self::{inline_globals::InlineGlobals, json_parse::JsonParse, simplify::simplifier};
|
||||
pub use self::{inline_globals::inline_globals, json_parse::json_parse, simplify::simplifier};
|
||||
|
||||
mod inline_globals;
|
||||
mod json_parse;
|
||||
|
@ -1,17 +1,20 @@
|
||||
use std::collections::HashMap;
|
||||
use swc_atoms::{js_word, JsWord};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct InlineGlobals {
|
||||
pub envs: HashMap<JsWord, Expr>,
|
||||
pub globals: HashMap<JsWord, Expr>,
|
||||
pub fn inline_globals(envs: HashMap<JsWord, Expr>, globals: HashMap<JsWord, Expr>) -> impl Fold {
|
||||
InlineGlobals { envs, globals }
|
||||
}
|
||||
|
||||
noop_fold_type!(InlineGlobals);
|
||||
struct InlineGlobals {
|
||||
envs: HashMap<JsWord, Expr>,
|
||||
globals: HashMap<JsWord, Expr>,
|
||||
}
|
||||
|
||||
impl Fold for InlineGlobals {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let expr = match expr {
|
||||
Expr::Member(expr) => {
|
||||
@ -83,6 +86,7 @@ impl Fold for InlineGlobals {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use swc_ecma_utils::DropSpan;
|
||||
use swc_ecma_visit::as_folder;
|
||||
|
||||
fn mk_map(
|
||||
tester: &mut crate::tests::Tester<'_>,
|
||||
@ -100,9 +104,9 @@ mod tests {
|
||||
|
||||
let mut v = tester
|
||||
.apply_transform(
|
||||
DropSpan {
|
||||
as_folder(DropSpan {
|
||||
preserve_ctxt: false,
|
||||
},
|
||||
}),
|
||||
"global.js",
|
||||
::swc_ecma_parser::Syntax::default(),
|
||||
&v,
|
||||
|
@ -3,7 +3,7 @@ use serde_json::Value;
|
||||
use std::usize;
|
||||
use swc_common::{Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// Trnasform to optimize performance of literals.
|
||||
///
|
||||
@ -27,12 +27,13 @@ use swc_ecma_visit::{Fold, FoldWith};
|
||||
/// - Object literal is deeply nested (threshold: )
|
||||
///
|
||||
/// See https://github.com/swc-project/swc/issues/409
|
||||
#[derive(Debug)]
|
||||
pub struct JsonParse {
|
||||
pub min_cost: usize,
|
||||
pub fn json_parse(min_cost: usize) -> impl Fold {
|
||||
JsonParse { min_cost }
|
||||
}
|
||||
|
||||
noop_fold_type!(JsonParse);
|
||||
struct JsonParse {
|
||||
pub min_cost: usize,
|
||||
}
|
||||
|
||||
impl Default for JsonParse {
|
||||
fn default() -> Self {
|
||||
@ -41,6 +42,8 @@ impl Default for JsonParse {
|
||||
}
|
||||
|
||||
impl Fold for JsonParse {
|
||||
noop_fold_type!();
|
||||
|
||||
/// Handles parent expressions before child expressions.
|
||||
fn fold_expr(&mut self, e: Expr) -> Expr {
|
||||
if self.min_cost == usize::MAX {
|
||||
|
@ -10,7 +10,7 @@ use swc_common::{
|
||||
Spanned, DUMMY_SP,
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -44,9 +44,9 @@ struct Remover {
|
||||
normal_block: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(Remover);
|
||||
|
||||
impl Fold for Remover {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_array_pat(&mut self, p: ArrayPat) -> ArrayPat {
|
||||
let mut p: ArrayPat = p.fold_children_with(self);
|
||||
|
||||
@ -1465,6 +1465,8 @@ fn check_for_stopper(s: &[Stmt], only_conditional: bool) -> bool {
|
||||
}
|
||||
|
||||
impl Visit for Visitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_switch_case(&mut self, node: &SwitchCase, _: &dyn Node) {
|
||||
let old = self.in_cond;
|
||||
self.in_cond = true;
|
||||
|
@ -11,7 +11,9 @@ use swc_common::{
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{find_ids, ident::IdentLike, Id, StmtLike};
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{
|
||||
as_folder, noop_fold_type, noop_visit_mut_type, Fold, FoldWith, VisitMut, VisitWith,
|
||||
};
|
||||
|
||||
macro_rules! preserve {
|
||||
($name:ident, $T:ty) => {
|
||||
@ -62,7 +64,7 @@ pub fn dce<'a>(config: Config<'a>) -> impl RepeatedJsPass + 'a {
|
||||
marking_phase: false,
|
||||
decl_dropping_phase: false,
|
||||
},
|
||||
UsedMarkRemover { used_mark }
|
||||
as_folder(UsedMarkRemover { used_mark })
|
||||
)
|
||||
}
|
||||
|
||||
@ -70,8 +72,6 @@ struct UsedMarkRemover {
|
||||
used_mark: Mark,
|
||||
}
|
||||
|
||||
noop_fold_type!(UsedMarkRemover);
|
||||
|
||||
impl CompilerPass for UsedMarkRemover {
|
||||
fn name() -> Cow<'static, str> {
|
||||
Cow::Borrowed("dce-cleanup")
|
||||
@ -86,14 +86,14 @@ impl Repeated for UsedMarkRemover {
|
||||
fn reset(&mut self) {}
|
||||
}
|
||||
|
||||
impl Fold for UsedMarkRemover {
|
||||
fn fold_span(&mut self, s: Span) -> Span {
|
||||
let mut ctxt = s.ctxt().clone();
|
||||
if ctxt.remove_mark() == self.used_mark {
|
||||
return s.with_ctxt(ctxt);
|
||||
}
|
||||
impl VisitMut for UsedMarkRemover {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
s
|
||||
fn visit_mut_span(&mut self, s: &mut Span) {
|
||||
let mut ctxt = s.ctxt.clone(); // explicit clone
|
||||
if ctxt.remove_mark() == self.used_mark {
|
||||
s.ctxt = ctxt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,19 +134,14 @@ impl Repeated for Dce<'_> {
|
||||
}
|
||||
|
||||
impl Fold for Dce<'_> {
|
||||
preserve!(fold_ts_interface_decl, TsInterfaceDecl);
|
||||
preserve!(fold_ts_type_alias_decl, TsTypeAliasDecl);
|
||||
preserve!(fold_ts_enum_decl, TsEnumDecl);
|
||||
preserve!(fold_ts_module_decl, TsModuleDecl);
|
||||
noop_fold_type!();
|
||||
|
||||
preserve!(fold_debugger_stmt, DebuggerStmt);
|
||||
preserve!(fold_with_stmt, WithStmt);
|
||||
preserve!(fold_break_stmt, BreakStmt);
|
||||
preserve!(fold_continue_stmt, ContinueStmt);
|
||||
|
||||
preserve!(fold_ts_import_equals_decl, TsImportEqualsDecl);
|
||||
preserve!(fold_ts_export_assignment, TsExportAssignment);
|
||||
preserve!(fold_ts_namespace_export_decl, TsNamespaceExportDecl);
|
||||
|
||||
fn fold_block_stmt(&mut self, node: BlockStmt) -> BlockStmt {
|
||||
if self.is_marked(node.span) {
|
||||
@ -677,7 +672,7 @@ impl Dce<'_> {
|
||||
T: for<'any> VisitWith<SideEffectVisitor<'any>> + VisitWith<ImportDetector>,
|
||||
{
|
||||
if self.marking_phase {
|
||||
return items.move_map(|item| self.fold_in_marking_phase(item));
|
||||
return items.move_map(|item| item.fold_with(self));
|
||||
}
|
||||
|
||||
let old = self.changed;
|
||||
|
@ -10,9 +10,9 @@ pub(super) struct ImportDetector {
|
||||
found: bool,
|
||||
}
|
||||
|
||||
noop_visit_type!(ImportDetector);
|
||||
|
||||
impl Visit for ImportDetector {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_import_decl(&mut self, _: &ImportDecl, _: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
@ -58,8 +58,6 @@ impl SideEffectVisitor<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
noop_visit_type!(SideEffectVisitor<'_>);
|
||||
|
||||
pub(super) struct SideEffectVisitor<'a> {
|
||||
included: &'a mut FxHashSet<Id>,
|
||||
exports: Option<&'a [Id]>,
|
||||
@ -84,6 +82,8 @@ impl SideEffectVisitor<'_> {
|
||||
}
|
||||
|
||||
impl Visit for SideEffectVisitor<'_> {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_expr(&mut self, node: &Expr, _: &dyn Node) {
|
||||
log::debug!("Visit<Expr>");
|
||||
|
||||
|
@ -7,7 +7,7 @@ use swc_common::{
|
||||
};
|
||||
use swc_ecma_ast::{Ident, Lit, *};
|
||||
use swc_ecma_utils::ident::IdentLike;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -33,8 +33,6 @@ struct SimplifyExpr {
|
||||
changed: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(SimplifyExpr);
|
||||
|
||||
impl CompilerPass for SimplifyExpr {
|
||||
fn name() -> Cow<'static, str> {
|
||||
Cow::Borrowed("simplify-expr")
|
||||
@ -996,6 +994,8 @@ impl SimplifyExpr {
|
||||
}
|
||||
|
||||
impl Fold for SimplifyExpr {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
// fold children before doing something more.
|
||||
let expr = expr.fold_children_with(self);
|
||||
|
@ -7,7 +7,7 @@ use swc_common::{
|
||||
};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{contains_this_expr, find_ids, ident::IdentLike, undefined, Id};
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
mod scope;
|
||||
|
||||
@ -72,8 +72,6 @@ struct Inlining<'a> {
|
||||
pat_mode: PatFoldingMode,
|
||||
}
|
||||
|
||||
noop_fold_type!(Inlining<'_>);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
enum PatFoldingMode {
|
||||
Assign,
|
||||
@ -92,6 +90,8 @@ impl Inlining<'_> {
|
||||
}
|
||||
|
||||
impl Fold for Inlining<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_arrow_expr(&mut self, node: ArrowExpr) -> ArrowExpr {
|
||||
self.fold_with_child(ScopeKind::Fn { named: false }, node)
|
||||
}
|
||||
@ -814,6 +814,8 @@ struct IdentListVisitor<'a, 'b> {
|
||||
}
|
||||
|
||||
impl Visit for IdentListVisitor<'_, '_> {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_ident(&mut self, node: &Ident, _: &dyn Node) {
|
||||
self.scope.add_write(&node.to_id(), true);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ use serde::Deserialize;
|
||||
use std::iter;
|
||||
use swc_common::{Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, Node, Visit, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, Node, Visit, VisitWith};
|
||||
|
||||
mod legacy;
|
||||
mod usage;
|
||||
@ -78,9 +78,9 @@ struct Decorators {
|
||||
is_in_strict: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(Decorators);
|
||||
|
||||
impl Fold for Decorators {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_decl(&mut self, decl: Decl) -> Decl {
|
||||
let decl = decl.fold_children_with(self);
|
||||
|
||||
@ -633,6 +633,8 @@ struct DecoratorFinder {
|
||||
found: bool,
|
||||
}
|
||||
impl Visit for DecoratorFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_decorator(&mut self, _: &Decorator, _: &dyn Node) {
|
||||
self.found = true
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use smallvec::SmallVec;
|
||||
use std::mem::replace;
|
||||
use swc_common::{util::move_map::MoveMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith, VisitWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith, VisitWith};
|
||||
|
||||
mod metadata;
|
||||
|
||||
@ -29,9 +29,9 @@ pub(super) fn new(metadata: bool) -> Legacy {
|
||||
}
|
||||
}
|
||||
|
||||
noop_fold_type!(Legacy);
|
||||
|
||||
impl Fold for Legacy {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_decl(&mut self, decl: Decl) -> Decl {
|
||||
let decl: Decl = decl.fold_children_with(self);
|
||||
|
||||
@ -760,9 +760,9 @@ struct ClassFieldAccessConverter {
|
||||
alias: Ident,
|
||||
}
|
||||
|
||||
noop_fold_type!(ClassFieldAccessConverter);
|
||||
|
||||
impl Fold for ClassFieldAccessConverter {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_ident(&mut self, node: Ident) -> Ident {
|
||||
if node.sym == self.cls_name.sym && node.span.ctxt() == self.cls_name.span.ctxt() {
|
||||
return self.alias.clone();
|
||||
|
@ -1,12 +1,14 @@
|
||||
use swc_common::{util::move_map::MoveMap, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::{undefined, ExprFactory};
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
/// https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata/blob/master/src/parameter/parameterVisitor.ts
|
||||
pub(super) struct ParamMetadata;
|
||||
|
||||
impl Fold for ParamMetadata {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class(&mut self, mut cls: Class) -> Class {
|
||||
cls = cls.fold_children_with(self);
|
||||
let mut decorators = cls.decorators;
|
||||
@ -120,6 +122,8 @@ pub(super) struct Metadata<'a> {
|
||||
}
|
||||
|
||||
impl Fold for Metadata<'_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_class(&mut self, mut c: Class) -> Class {
|
||||
c = c.fold_children_with(self);
|
||||
|
||||
|
@ -14,6 +14,8 @@ pub(super) struct DecoratorFinder {
|
||||
}
|
||||
|
||||
impl Visit for DecoratorFinder {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_decorator(&mut self, _: &Decorator, _parent: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::util::IdentExt;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::Fold;
|
||||
use swc_ecma_visit::{noop_fold_type, Fold};
|
||||
|
||||
/// `@babel/plugin-proposal-export-default-from` and
|
||||
/// `@babel/plugin-proposal-export-namespace-from`
|
||||
@ -12,9 +12,9 @@ pub fn export() -> impl Fold {
|
||||
#[derive(Clone)]
|
||||
struct ExportDefaultFrom;
|
||||
|
||||
noop_fold_type!(ExportDefaultFrom);
|
||||
|
||||
impl Fold for ExportDefaultFrom {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_module_items(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
|
||||
// Imports
|
||||
let mut stmts = Vec::with_capacity(items.len() + 4);
|
||||
|
@ -3,7 +3,7 @@ use std::ops::DerefMut;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -17,9 +17,9 @@ pub fn display_name() -> impl Fold {
|
||||
|
||||
struct DisplayName;
|
||||
|
||||
noop_fold_type!(DisplayName);
|
||||
|
||||
impl Fold for DisplayName {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_assign_expr(&mut self, expr: AssignExpr) -> AssignExpr {
|
||||
let expr = expr.fold_children_with(self);
|
||||
|
||||
@ -123,6 +123,8 @@ struct Folder {
|
||||
}
|
||||
|
||||
impl Fold for Folder {
|
||||
noop_fold_type!();
|
||||
|
||||
/// Don't recurse into array.
|
||||
fn fold_array_lit(&mut self, node: ArrayLit) -> ArrayLit {
|
||||
node
|
||||
|
@ -8,7 +8,7 @@ use swc_atoms::{js_word, JsWord};
|
||||
use swc_common::{iter::IdentifyLast, sync::Lrc, FileName, SourceMap, Spanned, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::{Parser, StringInput, Syntax};
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -105,8 +105,6 @@ struct Jsx {
|
||||
throw_if_namespace: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(Jsx);
|
||||
|
||||
impl Jsx {
|
||||
fn jsx_frag_to_expr(&mut self, el: JSXFragment) -> Expr {
|
||||
let span = el.span();
|
||||
@ -255,6 +253,8 @@ impl Jsx {
|
||||
}
|
||||
|
||||
impl Fold for Jsx {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_expr(&mut self, expr: Expr) -> Expr {
|
||||
let mut expr = expr.fold_children_with(self);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
compat::{
|
||||
es2015::{arrow, Classes},
|
||||
es3::PropertyLiteral,
|
||||
es2015::{arrow, classes},
|
||||
es3::property_literals,
|
||||
},
|
||||
modules::common_js::common_js,
|
||||
react::display_name,
|
||||
@ -14,7 +14,7 @@ fn tr(t: &mut Tester, options: Options) -> impl Fold {
|
||||
chain!(
|
||||
jsx(t.cm.clone(), options),
|
||||
display_name(),
|
||||
Classes::default(),
|
||||
classes(),
|
||||
arrow(),
|
||||
)
|
||||
}
|
||||
@ -462,7 +462,7 @@ test!(
|
||||
jsx: true,
|
||||
..Default::default()
|
||||
}),
|
||||
|t| chain!(tr(t, Default::default()), PropertyLiteral),
|
||||
|t| chain!(tr(t, Default::default()), property_literals()),
|
||||
react_should_add_quotes_es3,
|
||||
r#"var es3 = <F aaa new const var default foo-bar/>;"#,
|
||||
r#"
|
||||
|
@ -1,6 +1,6 @@
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::Fold;
|
||||
use swc_ecma_visit::{noop_fold_type, Fold};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -15,9 +15,9 @@ struct JsxSelf {
|
||||
dev: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(JsxSelf);
|
||||
|
||||
impl Fold for JsxSelf {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_jsx_opening_element(&mut self, mut n: JSXOpeningElement) -> JSXOpeningElement {
|
||||
if !self.dev {
|
||||
return n;
|
||||
|
@ -1,6 +1,6 @@
|
||||
use swc_common::{sync::Lrc, FileName, SourceMap, DUMMY_SP};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::Fold;
|
||||
use swc_ecma_visit::{noop_fold_type, Fold};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -15,9 +15,9 @@ struct JsxSrc {
|
||||
dev: bool,
|
||||
}
|
||||
|
||||
noop_fold_type!(JsxSrc);
|
||||
|
||||
impl Fold for JsxSrc {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_jsx_opening_element(&mut self, mut e: JSXOpeningElement) -> JSXOpeningElement {
|
||||
if !self.dev || e.span == DUMMY_SP {
|
||||
return e;
|
||||
|
@ -3,19 +3,19 @@ use std::{cell::RefCell, collections::HashSet};
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::{Mark, SyntaxContext};
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{noop_fold_type, Fold, FoldWith};
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
const LOG: bool = false;
|
||||
|
||||
pub fn resolver() -> Resolver<'static> {
|
||||
pub fn resolver() -> impl 'static + Fold {
|
||||
resolver_with_mark(Mark::fresh(Mark::root()))
|
||||
}
|
||||
|
||||
/// `mark` should not be root.
|
||||
pub fn resolver_with_mark(top_level_mark: Mark) -> Resolver<'static> {
|
||||
pub fn resolver_with_mark(top_level_mark: Mark) -> impl 'static + Fold {
|
||||
assert_ne!(
|
||||
top_level_mark,
|
||||
Mark::root(),
|
||||
@ -59,7 +59,7 @@ impl<'a> Scope<'a> {
|
||||
/// ## Hoisting phase
|
||||
///
|
||||
/// ## Resolving phase
|
||||
pub struct Resolver<'a> {
|
||||
struct Resolver<'a> {
|
||||
hoist: bool,
|
||||
mark: Mark,
|
||||
current: Scope<'a>,
|
||||
@ -67,8 +67,6 @@ pub struct Resolver<'a> {
|
||||
ident_type: IdentType,
|
||||
}
|
||||
|
||||
noop_fold_type!(Resolver<'_>);
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
fn new(mark: Mark, current: Scope<'a>, cur_defining: Option<(JsWord, Mark)>) -> Self {
|
||||
Resolver {
|
||||
@ -200,6 +198,8 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Fold for Resolver<'a> {
|
||||
noop_fold_type!();
|
||||
|
||||
track_ident!();
|
||||
|
||||
fn fold_arrow_expr(&mut self, e: ArrowExpr) -> ArrowExpr {
|
||||
@ -592,6 +592,8 @@ struct Hoister<'a, 'b> {
|
||||
}
|
||||
|
||||
impl Fold for Hoister<'_, '_> {
|
||||
noop_fold_type!();
|
||||
|
||||
fn fold_fn_decl(&mut self, node: FnDecl) -> FnDecl {
|
||||
let ident = self.resolver.fold_binding_ident(node.ident);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::*;
|
||||
use crate::{
|
||||
compat::{
|
||||
es2015::{block_scoping, destructuring, Classes},
|
||||
es2015::{block_scoping, classes, destructuring},
|
||||
es2020::class_properties,
|
||||
},
|
||||
modules::common_js::common_js,
|
||||
@ -985,7 +985,7 @@ test!(
|
||||
syntax(),
|
||||
|_| chain!(
|
||||
tr(),
|
||||
Classes::default(),
|
||||
classes(),
|
||||
destructuring(Default::default()),
|
||||
common_js(Mark::fresh(Mark::root()), Default::default())
|
||||
),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::helpers::{InjectHelpers, HELPERS};
|
||||
use crate::helpers::{inject_helpers, HELPERS};
|
||||
use std::{
|
||||
fmt,
|
||||
fs::{create_dir_all, remove_dir_all, OpenOptions},
|
||||
@ -14,7 +14,7 @@ use swc_ecma_ast::{Pat, *};
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_parser::{error::Error, lexer::Lexer, Parser, StringInput, Syntax};
|
||||
use swc_ecma_utils::DropSpan;
|
||||
use swc_ecma_visit::{Fold, FoldWith};
|
||||
use swc_ecma_visit::{as_folder, Fold, FoldWith};
|
||||
use tempfile::tempdir_in;
|
||||
|
||||
pub(crate) struct Tester<'a> {
|
||||
@ -115,9 +115,9 @@ impl<'a> Tester<'a> {
|
||||
|
||||
let module = validate!(module)
|
||||
.fold_with(&mut tr)
|
||||
.fold_with(&mut DropSpan {
|
||||
.fold_with(&mut as_folder(DropSpan {
|
||||
preserve_ctxt: true,
|
||||
})
|
||||
}))
|
||||
.fold_with(&mut Normalizer);
|
||||
|
||||
Ok(module)
|
||||
@ -179,9 +179,9 @@ pub(crate) fn test_transform<F, P>(
|
||||
{
|
||||
crate::tests::Tester::run(|tester| {
|
||||
let expected = tester.apply_transform(
|
||||
::swc_ecma_utils::DropSpan {
|
||||
as_folder(::swc_ecma_utils::DropSpan {
|
||||
preserve_ctxt: true,
|
||||
},
|
||||
}),
|
||||
"output.js",
|
||||
syntax,
|
||||
expected,
|
||||
@ -304,7 +304,7 @@ where
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let module = module
|
||||
let mut module = module
|
||||
.fold_with(&mut crate::debug::validator::Validator { name: "actual-1" })
|
||||
.fold_with(&mut crate::hygiene::hygiene())
|
||||
.fold_with(&mut crate::debug::validator::Validator { name: "actual-2" })
|
||||
@ -312,7 +312,7 @@ where
|
||||
.fold_with(&mut crate::debug::validator::Validator { name: "actual-3" });
|
||||
|
||||
let src_without_helpers = tester.print(&module);
|
||||
let module = module.fold_with(&mut InjectHelpers {});
|
||||
module = module.fold_with(&mut inject_helpers());
|
||||
|
||||
let src = tester.print(&module);
|
||||
let root = Path::new(env!("CARGO_MANIFEST_DIR"))
|
||||
|
@ -609,7 +609,18 @@ impl Fold for Strip {
|
||||
}) => Expr::Member(MemberExpr {
|
||||
span,
|
||||
obj: obj.fold_with(self),
|
||||
prop: if computed { prop.fold_with(self) } else { prop },
|
||||
prop: if computed {
|
||||
prop.fold_with(self)
|
||||
} else {
|
||||
match *prop {
|
||||
Expr::Ident(i) => Box::new(Expr::Ident(Ident {
|
||||
optional: false,
|
||||
type_ann: None,
|
||||
..i
|
||||
})),
|
||||
_ => prop,
|
||||
}
|
||||
},
|
||||
computed,
|
||||
}),
|
||||
_ => expr.fold_children_with(self),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user