Reduce binary size (#663)

This pr add two helper macros to prevent folding type unnecessarily.
This reduces the binary size by 3MB on linux.
This commit is contained in:
강동윤 2020-02-13 21:55:54 +09:00 committed by GitHub
parent 1b6b916dc9
commit f344caa4fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 288 additions and 0 deletions

View File

@ -60,6 +60,8 @@ pub fn arrow() -> impl Pass {
struct Arrow;
noop_fold_type!(Arrow);
impl Fold<Expr> for Arrow {
fn fold(&mut self, e: Expr) -> Expr {
// fast path

View File

@ -5,6 +5,8 @@ use swc_ecma_ast::*;
#[derive(Clone, Copy)]
pub struct BlockScopedFns;
noop_fold_type!(BlockScopedFns);
impl Fold<Vec<Stmt>> for BlockScopedFns {
fn fold(&mut self, items: Vec<Stmt>) -> Vec<Stmt> {
let mut stmts = Vec::with_capacity(items.len());

View File

@ -45,6 +45,8 @@ struct BlockScoping {
vars: Vec<VarDeclarator>,
}
noop_fold_type!(BlockScoping);
impl BlockScoping {
/// This methods remove [ScopeKind::Loop] and [ScopeKind::Fn], but not
/// [ScopeKind::ForLetLoop]

View File

@ -61,6 +61,8 @@ pub struct Classes {
in_strict: bool,
}
noop_fold_type!(Classes);
struct Data {
key_prop: Box<Prop>,
method: Option<Box<Expr>>,

View File

@ -12,6 +12,8 @@ pub(super) struct SuperCallFinder {
in_complex: bool,
}
noop_visit_type!(SuperCallFinder);
impl SuperCallFinder {
///
/// - `None`: if no `super()` is found or super() is last call

View File

@ -39,6 +39,8 @@ 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,
@ -56,6 +58,8 @@ struct SuperCalleeFolder<'a> {
this_alias_mark: Option<Mark>,
}
noop_fold_type!(SuperCalleeFolder<'_>);
macro_rules! mark_nested {
($T:tt) => {
impl<'a> Fold<$T> for SuperFieldAccessFolder<'a> {

View File

@ -42,6 +42,8 @@ pub fn computed_properties() -> impl Pass {
struct ComputedProps;
noop_fold_type!(ComputedProps);
#[derive(Default)]
struct ObjectLitFolder {
vars: Vec<VarDeclarator>,

View File

@ -39,6 +39,8 @@ struct Destructuring {
c: Config,
}
noop_fold_type!(Destructuring);
#[derive(Debug, Default, Clone, Copy, Deserialize)]
pub struct Config {
#[serde(default)]

View File

@ -10,6 +10,8 @@ pub fn duplicate_keys() -> impl Pass {
struct DuplicateKeys;
noop_fold_type!(DuplicateKeys);
impl Fold<Expr> for DuplicateKeys {
fn fold(&mut self, expr: Expr) -> Expr {
let expr = expr.fold_children(self);
@ -35,6 +37,8 @@ struct PropFolder {
setter_props: HashSet<JsWord>,
}
noop_fold_type!(PropFolder);
impl Fold<Expr> for PropFolder {
fn fold(&mut self, node: Expr) -> Expr {
node

View File

@ -55,6 +55,8 @@ struct ForOf {
c: Config,
}
noop_fold_type!(ForOf);
/// Real folder.
struct Actual {
c: Config,

View File

@ -26,10 +26,14 @@ pub fn function_name() -> impl Pass {
#[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" {

View File

@ -30,6 +30,8 @@ use swc_ecma_ast::*;
#[derive(Clone)]
pub struct InstanceOf;
noop_fold_type!(InstanceOf);
impl Fold<Expr> for InstanceOf {
fn fold(&mut self, expr: Expr) -> Expr {
fn should_work(node: &Expr) -> bool {

View File

@ -11,6 +11,8 @@ pub fn parameters() -> Params {
pub struct Params;
// prevent_recurse!(Params, Pat);
noop_fold_type!(Params);
impl Params {
fn fold_fn_like(&mut self, ps: Vec<Pat>, body: BlockStmt) -> (Vec<Pat>, BlockStmt) {
let body = validate!(body);

View File

@ -25,6 +25,8 @@ 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(self);

View File

@ -26,6 +26,8 @@ struct Regenerator {
top_level_vars: Vec<VarDeclarator>,
}
noop_fold_type!(Regenerator);
fn rt(rt: Ident) -> Stmt {
Stmt::Decl(Decl::Var(VarDecl {
span: DUMMY_SP,

View File

@ -38,6 +38,8 @@ use swc_ecma_ast::*;
#[derive(Default, Clone, Copy)]
pub struct Shorthand;
noop_fold_type!(Shorthand);
impl Fold<Prop> for Shorthand {
fn fold(&mut self, prop: Prop) -> Prop {
let prop = prop.fold_children(self);

View File

@ -24,12 +24,16 @@ struct Spread {
c: Config,
}
noop_fold_type!(Spread);
#[derive(Default)]
struct ActualFolder {
c: Config,
vars: Vec<VarDeclarator>,
}
noop_fold_type!(ActualFolder);
impl<T> Fold<Vec<T>> for Spread
where
T: StmtLike + FoldWith<ActualFolder> + FoldWith<Self>,

View File

@ -20,6 +20,8 @@ use swc_ecma_ast::*;
#[derive(Clone, Copy)]
pub struct StickyRegex;
noop_fold_type!(StickyRegex);
impl Fold<Expr> for StickyRegex {
fn fold(&mut self, e: Expr) -> Expr {
let e = e.fold_children(self);

View File

@ -9,6 +9,8 @@ pub struct TemplateLiteral {
added: Vec<Stmt>,
}
noop_fold_type!(TemplateLiteral);
impl Fold<Module> for TemplateLiteral {
fn fold(&mut self, m: Module) -> Module {
let mut body = m.body.fold_children(self);

View File

@ -23,6 +23,8 @@ use swc_ecma_ast::*;
#[derive(Clone)]
pub struct TypeOfSymbol;
noop_fold_type!(TypeOfSymbol);
impl Fold<Expr> for TypeOfSymbol {
fn fold(&mut self, expr: Expr) -> Expr {
// fast path

View File

@ -30,11 +30,15 @@ pub fn exponentation() -> impl Pass {
#[derive(Clone, Copy)]
struct Exponentation;
noop_fold_type!(Exponentation);
#[derive(Default)]
struct AssignFolder {
vars: Vec<VarDeclarator>,
}
noop_fold_type!(AssignFolder);
impl Fold<Expr> for AssignFolder {
fn fold(&mut self, e: Expr) -> Expr {
let e = e.fold_children(self);

View File

@ -33,10 +33,15 @@ pub fn async_to_generator() -> impl Pass {
#[derive(Default, Clone)]
struct AsyncToGenerator;
noop_fold_type!(AsyncToGenerator);
struct Actual {
extra_stmts: Vec<Stmt>,
}
noop_fold_type!(Actual);
impl<T> Fold<Vec<T>> for AsyncToGenerator
where
T: StmtLike + VisitWith<AsyncVisitor> + FoldWith<Actual>,

View File

@ -17,6 +17,8 @@ pub fn object_rest_spread() -> impl Pass {
struct ObjectRest;
noop_fold_type!(ObjectRest);
#[allow(clippy::vec_box)]
struct RestFolder {
/// Injected before the original statement.
@ -27,6 +29,8 @@ struct RestFolder {
exprs: Vec<Box<Expr>>,
}
noop_fold_type!(RestFolder);
macro_rules! impl_for_for_stmt {
($T:tt) => {
impl Fold<$T> for RestFolder {
@ -1012,6 +1016,8 @@ fn simplify_pat(pat: Pat) -> Pat {
struct ObjectSpread;
noop_fold_type!(ObjectSpread);
impl Fold<Expr> for ObjectSpread {
fn fold(&mut self, expr: Expr) -> Expr {
// fast-path

View File

@ -4,6 +4,8 @@ use swc_ecma_ast::*;
struct OptionalCatchBinding;
noop_fold_type!(OptionalCatchBinding);
pub fn optional_catch_binding() -> impl Pass {
OptionalCatchBinding
}

View File

@ -22,6 +22,8 @@ use swc_ecma_ast::*;
#[derive(Default, Clone, Copy)]
pub struct MemberExprLit;
noop_fold_type!(MemberExprLit);
impl Fold<Module> for MemberExprLit {
fn fold(&mut self, node: Module) -> Module {
validate!(node.fold_children(self))

View File

@ -32,6 +32,8 @@ use swc_ecma_ast::*;
#[derive(Default, Clone, Copy)]
pub struct PropertyLiteral;
noop_fold_type!(PropertyLiteral);
impl Fold<Module> for PropertyLiteral {
fn fold(&mut self, node: Module) -> Module {
validate!(node.fold_children(self))

View File

@ -23,6 +23,8 @@ pub struct ReservedWord {
pub preserve_import: bool,
}
noop_fold_type!(ReservedWord);
impl Fold<Ident> for ReservedWord {
fn fold(&mut self, i: Ident) -> Ident {
fold_ident(self.preserve_import, i)

View File

@ -75,6 +75,8 @@ struct ConstModules {
scope: Scope,
}
noop_fold_type!(ConstModules);
#[derive(Default)]
struct Scope {
imported: HashMap<JsWord, Arc<Expr>>,

View File

@ -26,6 +26,8 @@ struct Fixer {
span_map: FxHashMap<Span, Span>,
}
noop_fold_type!(Fixer);
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum Context {

View File

@ -224,6 +224,9 @@ define_helpers!(Helpers {
#[derive(Clone)]
pub struct InjectHelpers;
noop_fold_type!(InjectHelpers);
impl InjectHelpers {
fn mk_helpers(&self) -> Vec<ModuleItem> {
let (mark, external) = HELPERS.with(|helper| (helper.mark(), helper.external()));
@ -257,6 +260,9 @@ impl Fold<Module> for InjectHelpers {
}
struct Marker(Mark);
noop_fold_type!(Marker);
impl Fold<Span> for Marker {
fn fold(&mut self, sp: Span) -> Span {
sp.apply_mark(self.0)

View File

@ -22,6 +22,8 @@ struct Hygiene<'a> {
ident_type: IdentType,
}
noop_fold_type!(Hygiene<'_>);
type Contexts = SmallVec<[SyntaxContext; 32]>;
impl<'a> Hygiene<'a> {

View File

@ -12,6 +12,8 @@ pub(super) enum ScopeOp {
pub(super) struct Operator<'a>(pub &'a [ScopeOp]);
noop_fold_type!(Operator<'_>);
impl<'a> Fold<Vec<ModuleItem>> for Operator<'a> {
fn fold(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut stmts = Vec::with_capacity(items.len());

View File

@ -210,3 +210,153 @@ macro_rules! validate {
}
}};
}
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_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);
};
}

View File

@ -29,6 +29,8 @@ struct Amd {
exports: Exports,
}
noop_fold_type!(Amd);
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
pub struct Config {

View File

@ -26,6 +26,8 @@ struct CommonJs {
in_top_level: bool,
}
noop_fold_type!(CommonJs);
impl Fold<Vec<ModuleItem>> for CommonJs {
fn fold(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
let mut emitted_esmodule = false;

View File

@ -15,6 +15,9 @@ struct ImportAnalyzer {
scope: Scope,
}
noop_fold_type!(ImportAnalyzer);
noop_visit_type!(ImportAnalyzer);
impl Fold<Module> for ImportAnalyzer {
fn fold(&mut self, module: Module) -> Module {
module.visit_with(self);

View File

@ -35,6 +35,8 @@ struct Umd {
exports: Exports,
}
noop_fold_type!(Umd);
impl Fold<Module> for Umd {
fn fold(&mut self, module: Module) -> Module {
self.in_top_level = true;

View File

@ -9,6 +9,8 @@ pub struct InlineGlobals {
pub globals: HashMap<JsWord, Expr>,
}
noop_fold_type!(InlineGlobals);
impl Fold<Expr> for InlineGlobals {
fn fold(&mut self, expr: Expr) -> Expr {
let expr = match expr {

View File

@ -31,6 +31,8 @@ pub struct JsonParse {
pub min_cost: usize,
}
noop_fold_type!(JsonParse);
impl Default for JsonParse {
fn default() -> Self {
JsonParse { min_cost: 1024 }

View File

@ -44,6 +44,8 @@ struct Remover {
normal_block: bool,
}
noop_fold_type!(Remover);
impl<T: StmtLike> Fold<Vec<T>> for Remover
where
Self: Fold<T>,

View File

@ -73,6 +73,8 @@ struct UsedMarkRemover {
used_mark: Mark,
}
noop_fold_type!(UsedMarkRemover);
impl CompilerPass for UsedMarkRemover {
fn name() -> Cow<'static, str> {
Cow::Borrowed("dce-cleanup")

View File

@ -34,6 +34,8 @@ impl SideEffectVisitor<'_> {
}
}
noop_visit_type!(SideEffectVisitor<'_>);
pub(super) struct SideEffectVisitor<'a> {
included: &'a mut FxHashSet<Id>,
exports: Option<&'a [Id]>,

View File

@ -22,6 +22,8 @@ struct SimplifyExpr {
changed: bool,
}
noop_fold_type!(SimplifyExpr);
impl CompilerPass for SimplifyExpr {
fn name() -> Cow<'static, str> {
Cow::Borrowed("simplify-expr")

View File

@ -71,6 +71,8 @@ struct Inlining<'a> {
pat_mode: PatFoldingMode,
}
noop_fold_type!(Inlining<'_>);
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum PatFoldingMode {
Assign,

View File

@ -6,6 +6,8 @@ pub(super) struct ClassNameTdzFolder<'a> {
pub class_name: &'a Ident,
}
noop_fold_type!(ClassNameTdzFolder<'_>);
impl<'a> Fold<Expr> for ClassNameTdzFolder<'a> {
fn fold(&mut self, expr: Expr) -> Expr {
match expr {

View File

@ -13,6 +13,8 @@ pub(super) struct FieldAccessFolder<'a> {
pub in_assign_pat: bool,
}
noop_fold_type!(FieldAccessFolder<'_>);
impl<'a> Fold<Expr> for FieldAccessFolder<'a> {
fn fold(&mut self, e: Expr) -> Expr {
match e {

View File

@ -5,6 +5,8 @@ pub(super) struct ThisInStaticFolder {
pub ident: Ident,
}
noop_fold_type!(ThisInStaticFolder);
impl Fold<Expr> for ThisInStaticFolder {
fn fold(&mut self, e: Expr) -> Expr {
let e = e.fold_children(self);

View File

@ -7,6 +7,8 @@ pub(super) struct UsedNameRenamer<'a> {
pub used_names: &'a [JsWord],
}
noop_fold_type!(UsedNameRenamer<'_>);
impl<'a> Fold<Ident> for UsedNameRenamer<'a> {
fn fold(&mut self, ident: Ident) -> Ident {
if self.used_names.contains(&ident.sym) {
@ -23,6 +25,8 @@ pub(super) struct UsedNameCollector<'a> {
pub used_names: &'a mut Vec<JsWord>,
}
noop_visit_type!(UsedNameCollector<'_>);
impl<'a> Visit<Expr> for UsedNameCollector<'a> {
fn visit(&mut self, expr: &Expr) {
match *expr {

View File

@ -75,6 +75,8 @@ struct Decorators {
is_in_strict: bool,
}
noop_fold_type!(Decorators);
impl Fold<Vec<ModuleItem>> for Decorators {
fn fold(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
if !self::usage::has_decorator(&items) {

View File

@ -15,6 +15,8 @@ pub(super) struct Legacy {
exports: Vec<ExportSpecifier>,
}
noop_fold_type!(Legacy);
impl Fold<Module> for Legacy {
fn fold(&mut self, m: Module) -> Module {
let mut m = m.fold_children(self);

View File

@ -12,6 +12,8 @@ pub(super) struct DecoratorFinder {
found: bool,
}
noop_visit_type!(DecoratorFinder);
impl Visit<Decorator> for DecoratorFinder {
fn visit(&mut self, _: &Decorator) {
self.found = true;

View File

@ -11,6 +11,8 @@ pub fn export() -> impl Pass {
#[derive(Clone)]
struct ExportDefaultFrom;
noop_fold_type!(ExportDefaultFrom);
impl Fold<Vec<ModuleItem>> for ExportDefaultFrom {
fn fold(&mut self, items: Vec<ModuleItem>) -> Vec<ModuleItem> {
// Imports

View File

@ -15,6 +15,8 @@ struct OptChaining {
vars: Vec<VarDeclarator>,
}
noop_fold_type!(OptChaining);
impl<T> Fold<Vec<T>> for OptChaining
where
T: Debug + StmtLike + FoldWith<Self>,

View File

@ -15,6 +15,8 @@ pub fn display_name() -> impl Pass {
struct DisplayName;
noop_fold_type!(DisplayName);
impl Fold<VarDeclarator> for DisplayName {
fn fold(&mut self, decl: VarDeclarator) -> VarDeclarator {
match decl.name {

View File

@ -114,6 +114,8 @@ 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();

View File

@ -15,6 +15,8 @@ struct JsxSelf {
dev: bool,
}
noop_fold_type!(JsxSelf);
impl Fold<JSXOpeningElement> for JsxSelf {
fn fold(&mut self, mut n: JSXOpeningElement) -> JSXOpeningElement {
if !self.dev {

View File

@ -16,6 +16,8 @@ struct JsxSrc {
dev: bool,
}
noop_fold_type!(JsxSrc);
impl Fold<JSXOpeningElement> for JsxSrc {
fn fold(&mut self, mut e: JSXOpeningElement) -> JSXOpeningElement {
if !self.dev || e.span == DUMMY_SP {

View File

@ -64,6 +64,8 @@ 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 {