mirror of
https://github.com/swc-project/swc.git
synced 2024-12-25 06:36:08 +03:00
feat(es/optimization): Accept top level mark from simplifiers (#4434)
This commit is contained in:
parent
d6c82b3b3a
commit
8048597c9e
@ -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"]
|
||||
|
@ -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
|
||||
);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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) => {
|
||||
|
@ -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));
|
||||
}
|
||||
_ => {}
|
||||
|
@ -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`");
|
||||
})?;
|
||||
|
@ -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"}
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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<Data>,
|
||||
|
||||
#[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<T>(&mut self, stmts: &mut Vec<T>)
|
||||
where
|
||||
T: StmtLike + ModuleItemLike + VisitMutWith<Self> + Send + Sync,
|
||||
Vec<T>: VisitMutWith<Self>,
|
||||
{
|
||||
#[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<T>(&mut self, stmts: &mut Vec<T>)
|
||||
where
|
||||
T: StmtLike + ModuleItemLike + VisitMutWith<Self> + Send + Sync,
|
||||
Vec<T>: VisitMutWith<Self>,
|
||||
{
|
||||
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);
|
||||
|
@ -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<VarDeclarator>,
|
||||
@ -1278,6 +1284,7 @@ impl VisitMut for SimplifyExpr {
|
||||
|
||||
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
|
||||
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<Stmt>) {
|
||||
let mut child = SimplifyExpr {
|
||||
top_level_ctxt: self.top_level_ctxt,
|
||||
config: self.config,
|
||||
changed: Default::default(),
|
||||
vars: Default::default(),
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
))
|
||||
}
|
||||
|
@ -1,24 +0,0 @@
|
||||
use std::ops::Deref;
|
||||
|
||||
#[cfg(feature = "concurrent")]
|
||||
pub(crate) type Readonly<T> = std::sync::Arc<T>;
|
||||
|
||||
#[cfg(not(feature = "concurrent"))]
|
||||
#[derive(Default)]
|
||||
pub(crate) struct Readonly<T>(T);
|
||||
|
||||
#[cfg(not(feature = "concurrent"))]
|
||||
impl<T> Deref for Readonly<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "concurrent"))]
|
||||
impl<T> From<T> for Readonly<T> {
|
||||
fn from(v: T) -> Self {
|
||||
Self(v)
|
||||
}
|
||||
}
|
@ -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,
|
||||
);
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user