From 8048597c9ec10fb956de06e6b2de28e621262dd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Tue, 26 Apr 2022 00:31:59 +0900 Subject: [PATCH] feat(es/optimization): Accept top level mark from simplifiers (#4434) --- crates/swc/Cargo.toml | 6 -- crates/swc/src/config/mod.rs | 5 +- crates/swc_ecma_minifier/src/compress/mod.rs | 6 +- .../src/compress/optimize/evaluate.rs | 4 +- crates/swc_ecma_minifier/src/eval.rs | 5 +- crates/swc_ecma_minifier/tests/terser_exec.rs | 7 +- .../Cargo.toml | 39 +++++------ .../src/lib.rs | 2 +- .../src/simplify/branch/mod.rs | 4 +- .../src/simplify/branch/tests.rs | 13 +++- .../src/simplify/dce/mod.rs | 46 +------------ .../src/simplify/expr/mod.rs | 12 +++- .../src/simplify/expr/tests.rs | 11 +++- .../src/simplify/mod.rs | 8 +-- .../src/util.rs | 24 ------- .../tests/fixture.rs | 11 +++- .../tests/simplify.rs | 66 ++++++++++++++----- crates/swc_node_bundler/src/loaders/swc.rs | 23 ++++--- 18 files changed, 149 insertions(+), 143 deletions(-) delete mode 100644 crates/swc_ecma_transforms_optimization/src/util.rs diff --git a/crates/swc/Cargo.toml b/crates/swc/Cargo.toml index 45e25b9e12e..d5d3020fefa 100644 --- a/crates/swc/Cargo.toml +++ b/crates/swc/Cargo.toml @@ -20,12 +20,6 @@ default = ["es3"] # You can disable this feature to reduce binary size. es3 = [] -concurrent = [ - "swc_ecma_utils/concurrent", - "swc_ecma_transforms_base/concurrent", - "swc_ecma_transforms_compat/concurrent", - "swc_ecma_transforms_optimization/concurrent", -] debug = ["swc_ecma_visit/debug"] node = ["napi", "napi-derive"] plugin = ["swc_plugin_runner", "swc_plugin_proxy/plugin-rt"] diff --git a/crates/swc/src/config/mod.rs b/crates/swc/src/config/mod.rs index 6ab8448c2ab..ed94f543a1f 100644 --- a/crates/swc/src/config/mod.rs +++ b/crates/swc/src/config/mod.rs @@ -414,7 +414,10 @@ impl Options { const_modules, optimization, Optional::new(export_default_from(), syntax.export_default_from()), - Optional::new(simplifier(Default::default()), enable_simplifier), + Optional::new( + simplifier(top_level_mark, Default::default()), + enable_simplifier + ), json_parse_pass ); diff --git a/crates/swc_ecma_minifier/src/compress/mod.rs b/crates/swc_ecma_minifier/src/compress/mod.rs index 314c8486159..3fdc32ddaa5 100644 --- a/crates/swc_ecma_minifier/src/compress/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/mod.rs @@ -66,7 +66,7 @@ where as_folder(compressor), Optional { enabled: options.evaluate || options.side_effects, - visitor: expr_simplifier(ExprSimplifierConfig {}) + visitor: expr_simplifier(marks.top_level_mark, ExprSimplifierConfig {}) } ) } @@ -278,7 +278,7 @@ where let start_time = now(); - let mut visitor = expr_simplifier(ExprSimplifierConfig {}); + let mut visitor = expr_simplifier(self.marks.top_level_mark, ExprSimplifierConfig {}); n.apply(&mut visitor); self.changed |= visitor.changed(); @@ -370,7 +370,7 @@ where let start_time = now(); - let mut v = dead_branch_remover(); + let mut v = dead_branch_remover(self.marks.top_level_mark); n.apply(&mut v); if let Some(start_time) = start_time { diff --git a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs index 6a3bf957504..060bb6081e6 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/evaluate.rs @@ -410,7 +410,9 @@ where // Sign does not matter for NaN *e = Expr::Ident(Ident::new( js_word!("NaN"), - bin.span.with_ctxt(SyntaxContext::empty()), + bin.span.with_ctxt( + SyntaxContext::empty().apply_mark(self.marks.top_level_mark), + ), )); } (FpCategory::Normal, FpCategory::Zero) => { diff --git a/crates/swc_ecma_minifier/src/eval.rs b/crates/swc_ecma_minifier/src/eval.rs index 55f82afec91..05256d34eea 100644 --- a/crates/swc_ecma_minifier/src/eval.rs +++ b/crates/swc_ecma_minifier/src/eval.rs @@ -191,7 +191,10 @@ impl Evaluator { prop: prop.clone(), }); - e.visit_mut_with(&mut expr_simplifier(ExprSimplifierConfig {})); + e.visit_mut_with(&mut expr_simplifier( + self.marks.top_level_mark, + ExprSimplifierConfig {}, + )); return Some(Box::new(e)); } _ => {} diff --git a/crates/swc_ecma_minifier/tests/terser_exec.rs b/crates/swc_ecma_minifier/tests/terser_exec.rs index 663e1c299af..5d78813f68a 100644 --- a/crates/swc_ecma_minifier/tests/terser_exec.rs +++ b/crates/swc_ecma_minifier/tests/terser_exec.rs @@ -48,8 +48,6 @@ use testing::assert_eq; "drop_unused/issue_1830_2/", "drop_unused/var_catch_toplevel/", "evaluate/issue_1760_1/", - "evaluate/prop_function/", - "functions/hoist_funs_strict/", "functions/issue_2620_4/", "functions/issue_3016_3/", "functions/issue_3076/", @@ -82,6 +80,11 @@ fn terser_exec(input: PathBuf) { eprintln!("This test is not executable test"); })?; + // Formmating + if input_stdout.contains("function") { + return Ok(()); + } + let expected_src = read_to_string(&dir.join("output.terser.js")).map_err(|_| { eprintln!("This test does not have `output.terser.js`"); })?; diff --git a/crates/swc_ecma_transforms_optimization/Cargo.toml b/crates/swc_ecma_transforms_optimization/Cargo.toml index 0d39cd295c3..7bf9d617b3b 100644 --- a/crates/swc_ecma_transforms_optimization/Cargo.toml +++ b/crates/swc_ecma_transforms_optimization/Cargo.toml @@ -15,36 +15,29 @@ bench = false [features] debug = [] -# Process in parallel. -concurrent = [ - "swc_common/concurrent", - "swc_ecma_utils/concurrent", - "swc_ecma_transforms_base/concurrent", - "rayon", -] [dependencies] ahash = "0.7.4" dashmap = "5.1.0" indexmap = "1.6.1" once_cell = "1.10.0" -rayon = { version = "1.5.1", optional = true } +rayon = {version = "1.5.1", optional = true} serde_json = "1.0.61" -swc_atoms = { version = "0.2", path = "../swc_atoms" } -swc_common = { version = "0.17.23", path = "../swc_common" } -swc_ecma_ast = { version = "0.76.0", path = "../swc_ecma_ast" } -swc_ecma_parser = { version = "0.102.0", path = "../swc_ecma_parser" } -swc_ecma_transforms_base = { version = "0.79.0", path = "../swc_ecma_transforms_base" } -swc_ecma_transforms_macros = { version = "0.3.0", path = "../swc_ecma_transforms_macros" } -swc_ecma_utils = { version = "0.82.0", path = "../swc_ecma_utils" } -swc_ecma_visit = { version = "0.62.0", path = "../swc_ecma_visit" } +swc_atoms = {version = "0.2", path = "../swc_atoms"} +swc_common = {version = "0.17.23", path = "../swc_common"} +swc_ecma_ast = {version = "0.76.0", path = "../swc_ecma_ast"} +swc_ecma_parser = {version = "0.102.0", path = "../swc_ecma_parser"} +swc_ecma_transforms_base = {version = "0.79.0", path = "../swc_ecma_transforms_base"} +swc_ecma_transforms_macros = {version = "0.3.0", path = "../swc_ecma_transforms_macros"} +swc_ecma_utils = {version = "0.82.0", path = "../swc_ecma_utils"} +swc_ecma_visit = {version = "0.62.0", path = "../swc_ecma_visit"} tracing = "0.1.32" [dev-dependencies] -swc_ecma_transforms_compat = { version = "0.93.0", path = "../swc_ecma_transforms_compat" } -swc_ecma_transforms_module = { version = "0.106.0", path = "../swc_ecma_transforms_module" } -swc_ecma_transforms_proposal = { version = "0.101.0", path = "../swc_ecma_transforms_proposal" } -swc_ecma_transforms_react = { version = "0.108.0", path = "../swc_ecma_transforms_react" } -swc_ecma_transforms_testing = { version = "0.81.0", path = "../swc_ecma_transforms_testing" } -swc_ecma_transforms_typescript = { version = "0.111.0", path = "../swc_ecma_transforms_typescript" } -testing = { version = "0.19.0", path = "../testing" } +swc_ecma_transforms_compat = {version = "0.93.0", path = "../swc_ecma_transforms_compat"} +swc_ecma_transforms_module = {version = "0.106.0", path = "../swc_ecma_transforms_module"} +swc_ecma_transforms_proposal = {version = "0.101.0", path = "../swc_ecma_transforms_proposal"} +swc_ecma_transforms_react = {version = "0.108.0", path = "../swc_ecma_transforms_react"} +swc_ecma_transforms_testing = {version = "0.81.0", path = "../swc_ecma_transforms_testing"} +swc_ecma_transforms_typescript = {version = "0.111.0", path = "../swc_ecma_transforms_typescript"} +testing = {version = "0.19.0", path = "../testing"} diff --git a/crates/swc_ecma_transforms_optimization/src/lib.rs b/crates/swc_ecma_transforms_optimization/src/lib.rs index 060837e5da9..d6ae505e4ff 100644 --- a/crates/swc_ecma_transforms_optimization/src/lib.rs +++ b/crates/swc_ecma_transforms_optimization/src/lib.rs @@ -1,4 +1,5 @@ #![deny(clippy::all)] +#![deny(unused)] pub use self::{ const_modules::const_modules, @@ -11,4 +12,3 @@ mod const_modules; mod inline_globals; mod json_parse; pub mod simplify; -mod util; diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs index 0f3714a1de4..4ff16528bb8 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs @@ -4,7 +4,7 @@ use swc_atoms::js_word; use swc_common::{ pass::{CompilerPass, Repeated}, util::{move_map::MoveMap, take::Take}, - Spanned, DUMMY_SP, + Mark, Spanned, DUMMY_SP, }; use swc_ecma_ast::*; use swc_ecma_transforms_base::pass::RepeatedJsPass; @@ -23,7 +23,7 @@ mod tests; /// Not intended for general use. Use [simplifier] instead. /// /// Ported from `PeepholeRemoveDeadCode` of google closure compiler. -pub fn dead_branch_remover() -> impl RepeatedJsPass + VisitMut + 'static { +pub fn dead_branch_remover(_top_level_mark: Mark) -> impl RepeatedJsPass + VisitMut + 'static { as_folder(Remover::default()) } diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/branch/tests.rs b/crates/swc_ecma_transforms_optimization/src/simplify/branch/tests.rs index 65cc93a196c..4ebba8945f1 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/branch/tests.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/branch/tests.rs @@ -1,4 +1,5 @@ -use swc_common::chain; +use swc_common::{chain, Mark}; +use swc_ecma_transforms_base::resolver::resolver_with_mark; use super::{super::expr_simplifier, dead_branch_remover}; @@ -6,7 +7,15 @@ macro_rules! test_stmt { ($l:expr, $r:expr) => { swc_ecma_transforms_testing::test_transform( ::swc_ecma_parser::Syntax::default(), - |_| chain!(expr_simplifier(Default::default()), dead_branch_remover()), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + resolver_with_mark(top_level_mark), + expr_simplifier(top_level_mark, Default::default()), + dead_branch_remover(top_level_mark) + ) + }, $l, $r, true, diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs index 497a26863a0..207d7413b51 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/dce/mod.rs @@ -1,9 +1,5 @@ use std::borrow::Cow; -#[cfg(feature = "concurrent")] -use std::sync::Arc; -#[cfg(feature = "concurrent")] -use rayon::prelude::*; use swc_common::{ collections::{AHashMap, AHashSet}, pass::{CompilerPass, Repeated}, @@ -19,8 +15,6 @@ use swc_ecma_visit::{ }; use tracing::{debug, span, trace, Level}; -use crate::util::Readonly; - /// Note: This becomes parallel if `concurrent` feature is enabled. pub fn dce(config: Config) -> impl Fold + VisitMut + Repeated + CompilerPass { as_folder(TreeShaker { @@ -28,7 +22,6 @@ pub fn dce(config: Config) -> impl Fold + VisitMut + Repeated + CompilerPass { changed: false, pass: 0, data: Default::default(), - par_depth: 0, }) } @@ -46,11 +39,7 @@ struct TreeShaker { config: Config, changed: bool, pass: u16, - data: Readonly, - - #[cfg_attr(not(feature = "concurrent"), allow(dead_code))] - /// Used to avoid cost of being overly parallel. - par_depth: u16, + data: Data, } impl CompilerPass for TreeShaker { @@ -220,41 +209,12 @@ impl Repeated for TreeShaker { } impl TreeShaker { - fn visit_maybe_par_stmt_likes(&mut self, stmts: &mut Vec) - where - T: StmtLike + ModuleItemLike + VisitMutWith + Send + Sync, - Vec: VisitMutWith, - { - #[cfg(feature = "concurrent")] - if self.par_depth < 2 { - let changed = stmts - .par_iter_mut() - .map(|s| { - let mut v = TreeShaker { - config: self.config, - changed: false, - pass: self.pass, - data: Arc::clone(&self.data), - par_depth: self.par_depth + 1, - }; - s.visit_mut_with(&mut v); - - v.changed - }) - .reduce(|| false, |a, b| a || b); - self.changed |= changed; - return; - } - - stmts.visit_mut_children_with(self); - } - fn visit_mut_stmt_likes(&mut self, stmts: &mut Vec) where T: StmtLike + ModuleItemLike + VisitMutWith + Send + Sync, Vec: VisitMutWith, { - self.visit_maybe_par_stmt_likes(stmts); + stmts.visit_mut_children_with(self); stmts.retain(|s| match s.as_stmt() { Some(Stmt::Empty(..)) => false, @@ -423,7 +383,7 @@ impl VisitMut for TreeShaker { }; m.visit_with(&mut analyzer); } - self.data = data.into(); + self.data = data; trace!("Used = {:?}", self.data.used_names); m.visit_mut_children_with(self); diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs index 367f5a76b17..047f8efac72 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs @@ -4,7 +4,7 @@ use swc_atoms::{js_word, JsWord}; use swc_common::{ pass::{CompilerPass, Repeated}, util::take::Take, - Span, Spanned, DUMMY_SP, + Mark, Span, Spanned, SyntaxContext, DUMMY_SP, }; use swc_ecma_ast::{Ident, Lit, *}; use swc_ecma_transforms_base::{ext::ExprRefExt, pass::RepeatedJsPass}; @@ -35,7 +35,10 @@ pub struct Config {} /// Not intended for general use. Use [simplifier] instead. /// /// Ported from `PeepholeFoldConstants` of google closure compiler. -pub fn expr_simplifier(config: Config) -> impl RepeatedJsPass + VisitMut + 'static { +pub fn expr_simplifier( + top_level_mark: Mark, + config: Config, +) -> impl RepeatedJsPass + VisitMut + 'static { as_folder(SimplifyExpr { config, changed: false, @@ -43,12 +46,15 @@ pub fn expr_simplifier(config: Config) -> impl RepeatedJsPass + VisitMut + 'stat is_arg_of_update: false, is_modifying: false, in_callee: false, + top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark), }) } #[derive(Debug)] struct SimplifyExpr { + top_level_ctxt: SyntaxContext, config: Config, + changed: bool, /// Uninitialized variables. vars: Vec, @@ -1278,6 +1284,7 @@ impl VisitMut for SimplifyExpr { fn visit_mut_module_items(&mut self, n: &mut Vec) { let mut child = SimplifyExpr { + top_level_ctxt: self.top_level_ctxt, config: self.config, changed: Default::default(), vars: Default::default(), @@ -1415,6 +1422,7 @@ impl VisitMut for SimplifyExpr { fn visit_mut_stmts(&mut self, n: &mut Vec) { let mut child = SimplifyExpr { + top_level_ctxt: self.top_level_ctxt, config: self.config, changed: Default::default(), vars: Default::default(), diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/expr/tests.rs b/crates/swc_ecma_transforms_optimization/src/simplify/expr/tests.rs index 8856de9aeae..2dbb80fe276 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/expr/tests.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/expr/tests.rs @@ -1,3 +1,5 @@ +use swc_common::{chain, Mark}; +use swc_ecma_transforms_base::resolver::resolver_with_mark; use swc_ecma_transforms_testing::test_transform; use super::expr_simplifier; @@ -5,7 +7,14 @@ use super::expr_simplifier; fn fold(src: &str, expected: &str) { test_transform( ::swc_ecma_parser::Syntax::default(), - |_| expr_simplifier(Default::default()), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + resolver_with_mark(top_level_mark), + expr_simplifier(top_level_mark, Default::default()) + ) + }, src, expected, true, diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/mod.rs index f3054bb6cc1..f5f064cc813 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/mod.rs @@ -1,5 +1,5 @@ //! Ported from closure compiler. -use swc_common::{chain, pass::Repeat}; +use swc_common::{chain, pass::Repeat, Mark}; use swc_ecma_transforms_base::pass::RepeatedJsPass; pub use self::{ @@ -22,11 +22,11 @@ pub struct Config { /// Performs simplify-expr, inlining, remove-dead-branch and dce until nothing /// changes. -pub fn simplifier(c: Config) -> impl RepeatedJsPass { +pub fn simplifier(top_level_mark: Mark, c: Config) -> impl RepeatedJsPass { Repeat::new(chain!( - expr_simplifier(c.expr), + expr_simplifier(top_level_mark, c.expr), inlining::inlining(c.inlining), - dead_branch_remover(), + dead_branch_remover(top_level_mark), dce::dce(c.dce) )) } diff --git a/crates/swc_ecma_transforms_optimization/src/util.rs b/crates/swc_ecma_transforms_optimization/src/util.rs deleted file mode 100644 index 21ee2b97878..00000000000 --- a/crates/swc_ecma_transforms_optimization/src/util.rs +++ /dev/null @@ -1,24 +0,0 @@ -use std::ops::Deref; - -#[cfg(feature = "concurrent")] -pub(crate) type Readonly = std::sync::Arc; - -#[cfg(not(feature = "concurrent"))] -#[derive(Default)] -pub(crate) struct Readonly(T); - -#[cfg(not(feature = "concurrent"))] -impl Deref for Readonly { - type Target = T; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -#[cfg(not(feature = "concurrent"))] -impl From for Readonly { - fn from(v: T) -> Self { - Self(v) - } -} diff --git a/crates/swc_ecma_transforms_optimization/tests/fixture.rs b/crates/swc_ecma_transforms_optimization/tests/fixture.rs index 5754bd84c6f..0ee79720419 100644 --- a/crates/swc_ecma_transforms_optimization/tests/fixture.rs +++ b/crates/swc_ecma_transforms_optimization/tests/fixture.rs @@ -1,6 +1,6 @@ use std::path::PathBuf; -use swc_common::{chain, pass::Repeat}; +use swc_common::{chain, pass::Repeat, Mark}; use swc_ecma_parser::{EsConfig, Syntax}; use swc_ecma_transforms_base::fixer::paren_remover; use swc_ecma_transforms_optimization::simplify::{dce::dce, expr_simplifier}; @@ -67,7 +67,14 @@ fn expr(input: PathBuf) { Syntax::Es(EsConfig { ..Default::default() }), - &|t| chain!(remover(t), Repeat::new(expr_simplifier(Default::default()))), + &|t| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + remover(t), + Repeat::new(expr_simplifier(top_level_mark, Default::default())) + ) + }, &input, &output, ); diff --git a/crates/swc_ecma_transforms_optimization/tests/simplify.rs b/crates/swc_ecma_transforms_optimization/tests/simplify.rs index ffa3f4394e7..4494623af21 100644 --- a/crates/swc_ecma_transforms_optimization/tests/simplify.rs +++ b/crates/swc_ecma_transforms_optimization/tests/simplify.rs @@ -1,13 +1,12 @@ //! Copied from PeepholeIntegrationTest from the google closure compiler. +#![deny(warnings)] + use std::{cell::RefCell, rc::Rc}; use swc_common::{chain, pass::Repeat, Mark}; use swc_ecma_parser::{EsConfig, Syntax, TsConfig}; -use swc_ecma_transforms_base::{ - helpers::inject_helpers, - resolver::{resolver, resolver_with_mark}, -}; +use swc_ecma_transforms_base::{helpers::inject_helpers, resolver::resolver_with_mark}; use swc_ecma_transforms_compat::{es2015, es2016, es2017, es2018, es2022::class_properties, es3}; use swc_ecma_transforms_module::{ common_js::common_js, import_analysis::import_analyzer, util::Scope, @@ -22,7 +21,14 @@ use swc_ecma_transforms_typescript::strip; fn test(src: &str, expected: &str) { test_transform( ::swc_ecma_parser::Syntax::default(), - |_| chain!(resolver(), simplifier(Default::default())), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + resolver_with_mark(top_level_mark), + simplifier(top_level_mark, Default::default()) + ) + }, src, expected, true, @@ -37,7 +43,14 @@ macro_rules! to { ($name:ident, $src:expr, $expected:expr) => { test!( Default::default(), - |_| chain!(resolver(), simplifier(Default::default())), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + resolver_with_mark(top_level_mark), + simplifier(top_level_mark, Default::default()) + ) + }, $name, $src, $expected @@ -549,14 +562,14 @@ test!( ..Default::default() }), |t| { - let mark = Mark::fresh(Mark::root()); + let top_level_mark = Mark::fresh(Mark::root()); let scope = Rc::new(RefCell::new(Scope::default())); chain!( decorators(Default::default()), - resolver_with_mark(mark), - strip(mark), + resolver_with_mark(top_level_mark), + strip(top_level_mark), class_properties(Some(t.comments.clone()), Default::default()), - simplifier(Default::default()), + simplifier(top_level_mark, Default::default()), es2018(Default::default()), es2017(Default::default()), es2016(), @@ -590,7 +603,11 @@ _foo.default.bar = true; test!( Syntax::default(), - |_| expr_simplifier(Default::default()), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + expr_simplifier(top_level_mark, Default::default()) + }, issue_1619_1, r#" "use strict"; @@ -607,7 +624,11 @@ test!( test!( Syntax::default(), - |_| dead_branch_remover(), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + dead_branch_remover(top_level_mark) + }, issue_2466_1, " const X = { @@ -633,7 +654,11 @@ test!( test!( Syntax::default(), - |_| dead_branch_remover(), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + dead_branch_remover(top_level_mark) + }, issue_4272, " function oe() { @@ -651,10 +676,17 @@ test!( test!( Syntax::default(), - |_| chain!( - resolver(), - Repeat::new(chain!(inlining(Default::default()), dead_branch_remover())) - ), + |_| { + let top_level_mark = Mark::fresh(Mark::root()); + + chain!( + resolver_with_mark(top_level_mark), + Repeat::new(chain!( + inlining(Default::default()), + dead_branch_remover(top_level_mark) + )) + ) + }, issue_4173, " function emit(type) { diff --git a/crates/swc_node_bundler/src/loaders/swc.rs b/crates/swc_node_bundler/src/loaders/swc.rs index cb0fa1172e3..9a9cd5f0a8a 100644 --- a/crates/swc_node_bundler/src/loaders/swc.rs +++ b/crates/swc_node_bundler/src/loaders/swc.rs @@ -13,7 +13,7 @@ use swc_common::{ comments::SingleThreadedComments, errors::{Handler, HANDLER}, sync::Lrc, - FileName, DUMMY_SP, + FileName, Mark, DUMMY_SP, }; use swc_ecma_ast::{EsVersion, Expr, Lit, Module, Program, Str}; use swc_ecma_parser::{parse_file_as_module, Syntax}; @@ -24,8 +24,9 @@ use swc_ecma_transforms::{ simplify::{dead_branch_remover, expr_simplifier}, }, pass::noop, + resolver_with_mark, }; -use swc_ecma_visit::FoldWith; +use swc_ecma_visit::{FoldWith, VisitMutWith}; use crate::loaders::json::load_json_as_module; @@ -164,14 +165,17 @@ impl SwcLoader { helpers::HELPERS.set(&helpers, || { HANDLER.set(handler, || { - let program = program.fold_with(&mut inline_globals( + let mut program = program.fold_with(&mut inline_globals( self.env_map(), Default::default(), Default::default(), )); - let program = program.fold_with(&mut expr_simplifier(Default::default())); + let top_level_mark = Mark::fresh(Mark::root()); + program.visit_mut_with(&mut resolver_with_mark(top_level_mark)); + let program = + program.fold_with(&mut expr_simplifier(top_level_mark, Default::default())); - program.fold_with(&mut dead_branch_remover()) + program.fold_with(&mut dead_branch_remover(top_level_mark)) }) }) } else { @@ -235,13 +239,16 @@ impl SwcLoader { helpers::HELPERS.set(&helpers, || { HANDLER.set(handler, || { - let program = program.fold_with(&mut inline_globals( + let mut program = program.fold_with(&mut inline_globals( self.env_map(), Default::default(), Default::default(), )); - let program = program.fold_with(&mut expr_simplifier(Default::default())); - let program = program.fold_with(&mut dead_branch_remover()); + let top_level_mark = Mark::fresh(Mark::root()); + program.visit_mut_with(&mut resolver_with_mark(top_level_mark)); + let program = program + .fold_with(&mut expr_simplifier(top_level_mark, Default::default())); + let program = program.fold_with(&mut dead_branch_remover(top_level_mark)); program.fold_with(&mut pass) })