mirror of
https://github.com/swc-project/swc.git
synced 2024-11-26 09:54:22 +03:00
feat(es/minifier): Implement more rules (#1717)
swc_ecma_minifier: - Implement `global-defs` pass. - Implement `properties` pass partially.
This commit is contained in:
parent
a1341dcdc6
commit
d20c1d3089
@ -5,6 +5,7 @@ documentation = "https://rustdoc.swc.rs/swc_babel_compat/"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_babel_compat"
|
||||
publish = false
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.1.0"
|
||||
|
||||
|
@ -31,7 +31,7 @@ typescript = ["swc_ecma_transforms/typescript"]
|
||||
swc_ecma_ast = {version = "0.45.0", path = "./ast"}
|
||||
swc_ecma_codegen = {version = "0.55.0", path = "./codegen", optional = true}
|
||||
swc_ecma_dep_graph = {version = "0.25.0", path = "./dep-graph", optional = true}
|
||||
swc_ecma_minifier = {version = "0.1.0-beta.0", path = "./minifier", optional = true}
|
||||
swc_ecma_minifier = {version = "0.2.0-beta.0", path = "./minifier", optional = true}
|
||||
swc_ecma_parser = {version = "0.57.0", path = "./parser", optional = true}
|
||||
swc_ecma_transforms = {version = "0.50.0", path = "./transforms", optional = true}
|
||||
swc_ecma_utils = {version = "0.36.0", path = "./utils", optional = true}
|
||||
|
@ -7,12 +7,13 @@ include = ["Cargo.toml", "src/**/*.rs", "src/lists/*.json"]
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecma_minifier"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.1.0-beta.0"
|
||||
version = "0.2.0-beta.0"
|
||||
|
||||
[dependencies]
|
||||
fxhash = "0.2.1"
|
||||
log = "0.4"
|
||||
once_cell = "1.5.2"
|
||||
pretty_assertions = {version = "0.6.1", optional = true}
|
||||
regex = "1.5.3"
|
||||
retain_mut = "0.1.2"
|
||||
serde = {version = "1.0.118", features = ["derive"]}
|
||||
@ -22,6 +23,7 @@ swc_atoms = {version = "0.2", path = "../../atoms"}
|
||||
swc_common = {version = "0.10.8", path = "../../common"}
|
||||
swc_ecma_ast = {version = "0.45.0", path = "../ast"}
|
||||
swc_ecma_codegen = {version = "0.55.0", path = "../codegen"}
|
||||
swc_ecma_parser = {version = "0.57.0", path = "../parser"}
|
||||
swc_ecma_transforms = {version = "0.50.0", path = "../transforms/", features = ["optimization"]}
|
||||
swc_ecma_transforms_base = {version = "0.15.0", path = "../transforms/base"}
|
||||
swc_ecma_utils = {version = "0.36.0", path = "../utils"}
|
||||
@ -30,6 +32,5 @@ swc_ecma_visit = {version = "0.31.0", path = "../visit"}
|
||||
[dev-dependencies]
|
||||
ansi_term = "0.12.1"
|
||||
pretty_assertions = "0.6.1"
|
||||
swc_ecma_parser = {version = "0.57.0", path = "../parser"}
|
||||
testing = {version = "0.10.2", path = "../../testing"}
|
||||
walkdir = "2.3.1"
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Note that this is append-only.
|
||||
set -eu
|
||||
|
||||
cargo test --test compress \
|
||||
cargo test --test compress --all-features \
|
||||
| grep 'js .\.\. ok$' \
|
||||
| sed -e 's!test fixture_terser__compress__!!' \
|
||||
| sed -e 's! ... ok!!' \
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -eu
|
||||
|
||||
cargo test --test compress $1 \
|
||||
cargo test --test compress --all-features $1 \
|
||||
| grep 'js .\.\. FAILED$' \
|
||||
| sed -e 's!test fixture_terser__compress__!!' \
|
||||
| sed -e 's! ... FAILED!!' \
|
||||
|
@ -16,7 +16,7 @@ if [ -z "$@" ]; then
|
||||
|
||||
export RUST_LOG=swc_ecma_minifier=trace
|
||||
|
||||
GOLDEN_ONLY=1 cargo test --test compress
|
||||
GOLDEN_ONLY=1 cargo test --test compress --all-features
|
||||
fi
|
||||
|
||||
cargo test --test compress $@
|
||||
cargo test --test compress --all-features $@
|
||||
|
@ -8,4 +8,8 @@ cat tests/golden.txt | awk NF | sort | uniq | awk '{$1=$1};1' | uniq | sort > te
|
||||
mv tests/golden_sorted.txt tests/golden.txt
|
||||
|
||||
cat tests/ignored.txt | awk NF | sort | uniq | awk '{$1=$1};1' | uniq | sort > tests/ignored_sorted.txt
|
||||
mv tests/ignored_sorted.txt tests/ignored.txt
|
||||
mv tests/ignored_sorted.txt tests/ignored.txt
|
||||
|
||||
# Don't mark ignored test as golden
|
||||
comm -23 tests/golden.txt tests/ignored.txt > tests/nodup.txt
|
||||
mv tests/nodup.txt tests/golden.txt
|
@ -5,6 +5,8 @@ use crate::compress::hoist_decls::decl_hoister;
|
||||
use crate::debug::dump;
|
||||
use crate::option::CompressOptions;
|
||||
use crate::util::Optional;
|
||||
#[cfg(feature = "pretty_assertions")]
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::fmt::Debug;
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::Optimizer;
|
||||
use crate::compress::optimize::Ctx;
|
||||
use std::mem::swap;
|
||||
use swc_common::Spanned;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_transforms_base::ext::MapWithMut;
|
||||
@ -160,7 +161,14 @@ impl Optimizer<'_> {
|
||||
/// ```
|
||||
pub(super) fn invoke_iife(&mut self, e: &mut Expr) {
|
||||
if self.options.inline == 0 {
|
||||
return;
|
||||
let skip = match e {
|
||||
Expr::Call(v) => !v.callee.span().is_dummy(),
|
||||
_ => true,
|
||||
};
|
||||
|
||||
if skip {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if self.ctx.inline_prevented {
|
||||
|
@ -47,6 +47,7 @@ mod inline;
|
||||
mod join_vars;
|
||||
mod loops;
|
||||
mod ops;
|
||||
mod properties;
|
||||
mod sequences;
|
||||
mod strings;
|
||||
mod switches;
|
||||
@ -485,6 +486,8 @@ impl Optimizer<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns [None] if expression is side-effect-free.
|
||||
/// If an expression has a side effect, only side effects are returned.
|
||||
fn ignore_return_value(&mut self, e: &mut Expr) -> Option<Expr> {
|
||||
match e {
|
||||
Expr::Ident(..) | Expr::This(_) | Expr::Invalid(_) | Expr::Lit(..) => {
|
||||
@ -1411,6 +1414,8 @@ impl VisitMut for Optimizer<'_> {
|
||||
|
||||
self.optimize_bools(e);
|
||||
|
||||
self.handle_property_access(e);
|
||||
|
||||
self.lift_seqs_of_cond_assign(e);
|
||||
|
||||
if self.options.negate_iife {
|
||||
@ -1444,6 +1449,21 @@ impl VisitMut for Optimizer<'_> {
|
||||
|| self.options.side_effects
|
||||
|| (self.options.sequences() && n.expr.is_seq())
|
||||
{
|
||||
// Preserve top-level negated iifes.
|
||||
match &*n.expr {
|
||||
Expr::Unary(unary) => match &*unary.arg {
|
||||
Expr::Call(CallExpr {
|
||||
callee: ExprOrSuper::Expr(callee),
|
||||
..
|
||||
}) => match &**callee {
|
||||
Expr::Fn(..) => return,
|
||||
_ => {}
|
||||
},
|
||||
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
let expr = self.ignore_return_value(&mut n.expr);
|
||||
n.expr = expr.map(Box::new).unwrap_or_else(|| undefined(DUMMY_SP));
|
||||
}
|
||||
@ -1562,6 +1582,8 @@ impl VisitMut for Optimizer<'_> {
|
||||
if n.computed {
|
||||
n.prop.visit_mut_with(self);
|
||||
}
|
||||
|
||||
self.handle_known_computed_member_expr(n);
|
||||
}
|
||||
|
||||
fn visit_mut_module_items(&mut self, stmts: &mut Vec<ModuleItem>) {
|
||||
|
131
ecmascript/minifier/src/compress/optimize/properties.rs
Normal file
131
ecmascript/minifier/src/compress/optimize/properties.rs
Normal file
@ -0,0 +1,131 @@
|
||||
use crate::compress::optimize::Optimizer;
|
||||
use crate::util::deeply_contains_this_expr;
|
||||
use swc_atoms::js_word;
|
||||
use swc_common::SyntaxContext;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::prop_name_eq;
|
||||
use swc_ecma_utils::ExprExt;
|
||||
|
||||
impl Optimizer<'_> {
|
||||
/// Converts `{ a: 1 }.a` into `1`.
|
||||
pub(super) fn handle_property_access(&mut self, e: &mut Expr) {
|
||||
if !self.options.props {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.ctx.is_update_arg {
|
||||
return;
|
||||
}
|
||||
|
||||
let me = match e {
|
||||
Expr::Member(m) => m,
|
||||
_ => return,
|
||||
};
|
||||
if me.computed {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = match &*me.prop {
|
||||
Expr::Ident(prop) => prop,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let obj = match &mut me.obj {
|
||||
ExprOrSuper::Expr(e) => &mut **e,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let obj = match obj {
|
||||
Expr::Object(o) => o,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
let duplicate_prop = obj
|
||||
.props
|
||||
.iter()
|
||||
.filter(|prop| match prop {
|
||||
PropOrSpread::Spread(_) => false,
|
||||
PropOrSpread::Prop(p) => match &**p {
|
||||
Prop::Shorthand(p) => p.sym == key.sym,
|
||||
Prop::KeyValue(p) => prop_name_eq(&p.key, &key.sym),
|
||||
Prop::Assign(p) => p.key.sym == key.sym,
|
||||
Prop::Getter(p) => prop_name_eq(&p.key, &key.sym),
|
||||
Prop::Setter(p) => prop_name_eq(&p.key, &key.sym),
|
||||
Prop::Method(p) => prop_name_eq(&p.key, &key.sym),
|
||||
},
|
||||
})
|
||||
.count()
|
||||
!= 1;
|
||||
if duplicate_prop {
|
||||
return;
|
||||
}
|
||||
|
||||
if obj.props.iter().any(|prop| match prop {
|
||||
PropOrSpread::Spread(_) => false,
|
||||
PropOrSpread::Prop(p) => match &**p {
|
||||
Prop::Shorthand(..) => false,
|
||||
Prop::KeyValue(p) => {
|
||||
p.key.is_computed()
|
||||
|| p.value.may_have_side_effects()
|
||||
|| deeply_contains_this_expr(&p.value)
|
||||
}
|
||||
Prop::Assign(p) => {
|
||||
p.value.may_have_side_effects() || deeply_contains_this_expr(&p.value)
|
||||
}
|
||||
Prop::Getter(p) => p.key.is_computed(),
|
||||
Prop::Setter(p) => p.key.is_computed(),
|
||||
Prop::Method(p) => p.key.is_computed(),
|
||||
},
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
|
||||
for prop in &obj.props {
|
||||
match prop {
|
||||
PropOrSpread::Spread(_) => {}
|
||||
PropOrSpread::Prop(p) => match &**p {
|
||||
Prop::Shorthand(_) => {}
|
||||
Prop::KeyValue(p) => {
|
||||
if prop_name_eq(&p.key, &key.sym) {
|
||||
log::trace!("properties: Inlining a key-value property `{}`", key.sym);
|
||||
self.changed = true;
|
||||
*e = *p.value.clone();
|
||||
return;
|
||||
}
|
||||
}
|
||||
Prop::Assign(_) => {}
|
||||
Prop::Getter(_) => {}
|
||||
Prop::Setter(_) => {}
|
||||
Prop::Method(_) => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn handle_known_computed_member_expr(&mut self, e: &mut MemberExpr) {
|
||||
if !self.options.props || !self.options.evaluate {
|
||||
return;
|
||||
}
|
||||
|
||||
if !e.computed {
|
||||
return;
|
||||
}
|
||||
|
||||
match &*e.prop {
|
||||
Expr::Lit(Lit::Str(s)) => {
|
||||
if s.value == js_word!("") || s.value.starts_with(|c: char| c.is_digit(10)) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.changed = true;
|
||||
|
||||
e.computed = false;
|
||||
e.prop = Box::new(Expr::Ident(Ident::new(
|
||||
s.value.clone(),
|
||||
s.span.with_ctxt(SyntaxContext::empty()),
|
||||
)));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
@ -6,9 +6,11 @@
|
||||
|
||||
use crate::compress::compressor;
|
||||
use crate::hygiene::unique_marker;
|
||||
use crate::option::ExtraOptions;
|
||||
use crate::option::MinifyOptions;
|
||||
use crate::pass::compute_char_freq::compute_char_freq;
|
||||
use crate::pass::expand_names::name_expander;
|
||||
use crate::pass::global_defs;
|
||||
use crate::pass::hygiene::hygiene_optimizer;
|
||||
use crate::pass::mangle_names::name_mangler;
|
||||
use crate::pass::mangle_props::mangle_properties;
|
||||
@ -34,7 +36,21 @@ pub fn optimize(
|
||||
comments: Option<&dyn Comments>,
|
||||
mut timings: Option<&mut Timings>,
|
||||
options: &MinifyOptions,
|
||||
extra: &ExtraOptions,
|
||||
) -> Module {
|
||||
if let Some(defs) = options.compress.as_ref().map(|c| &c.global_defs) {
|
||||
// Apply global defs.
|
||||
//
|
||||
// As terser treats `CONFIG['VALUE']` and `CONFIG.VALUE` differently, we don't
|
||||
// have to see if optimized code matches global definition and wecan run
|
||||
// this at startup.
|
||||
|
||||
if !defs.is_empty() {
|
||||
let defs = defs.iter().map(|(k, v)| (k.clone(), v.clone())).collect();
|
||||
m.visit_mut_with(&mut global_defs::globals_defs(defs, extra.top_level_mark));
|
||||
}
|
||||
}
|
||||
|
||||
m.visit_mut_with(&mut unique_marker());
|
||||
|
||||
if options.wrap {
|
||||
|
@ -3,10 +3,19 @@ use regex::Regex;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::Mark;
|
||||
use swc_ecma_ast::EsVersion;
|
||||
use swc_ecma_ast::Lit;
|
||||
use swc_ecma_ast::Expr;
|
||||
|
||||
pub mod terser;
|
||||
|
||||
/// This is not serializable.
|
||||
#[derive(Debug)]
|
||||
pub struct ExtraOptions {
|
||||
/// The [Mark] used for `resolver_with_mark`.
|
||||
pub top_level_mark: Mark,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[serde(deny_unknown_fields)]
|
||||
@ -128,9 +137,11 @@ pub struct CompressOptions {
|
||||
#[serde(alias = "expression")]
|
||||
pub expr: bool,
|
||||
|
||||
#[serde(default)]
|
||||
/// All expressions should have dummy span. Use [swc_ecma_utils::drop_span]
|
||||
/// to remove spans.
|
||||
#[serde(skip)]
|
||||
#[serde(alias = "global_defs")]
|
||||
pub global_defs: FxHashMap<JsWord, Lit>,
|
||||
pub global_defs: FxHashMap<Box<Expr>, Box<Expr>>,
|
||||
|
||||
#[serde(default)]
|
||||
#[serde(alias = "hoist_funs")]
|
||||
|
@ -6,8 +6,15 @@ use fxhash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use swc_atoms::JsWord;
|
||||
use swc_common::input::SourceFileInput;
|
||||
use swc_common::sync::Lrc;
|
||||
use swc_common::FileName;
|
||||
use swc_common::SourceMap;
|
||||
use swc_common::DUMMY_SP;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_parser::lexer::Lexer;
|
||||
use swc_ecma_parser::Parser;
|
||||
use swc_ecma_utils::drop_span;
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
@ -237,59 +244,77 @@ fn ecma_default() -> TerserEcmaVersion {
|
||||
TerserEcmaVersion::Num(5)
|
||||
}
|
||||
|
||||
impl From<TerserCompressorOptions> for CompressOptions {
|
||||
fn from(c: TerserCompressorOptions) -> Self {
|
||||
impl TerserCompressorOptions {
|
||||
pub fn into_config(self, cm: Lrc<SourceMap>) -> CompressOptions {
|
||||
CompressOptions {
|
||||
arguments: c.arguments,
|
||||
arrows: c.arrows.unwrap_or(c.defaults),
|
||||
bools: c.booleans.unwrap_or(c.defaults),
|
||||
bools_as_ints: c.booleans_as_integers,
|
||||
collapse_vars: c.collapse_vars.unwrap_or(c.defaults),
|
||||
comparisons: c.comparisons.unwrap_or(c.defaults),
|
||||
computed_props: c.computed_props,
|
||||
conditionals: c.conditionals,
|
||||
dead_code: c.dead_code,
|
||||
directives: c.directives,
|
||||
drop_console: c.drop_console,
|
||||
drop_debugger: c.drop_debugger.unwrap_or(c.defaults),
|
||||
ecma: c.ecma.into(),
|
||||
evaluate: c.evaluate.unwrap_or(c.defaults),
|
||||
expr: c.expression,
|
||||
global_defs: c
|
||||
arguments: self.arguments,
|
||||
arrows: self.arrows.unwrap_or(self.defaults),
|
||||
bools: self.booleans.unwrap_or(self.defaults),
|
||||
bools_as_ints: self.booleans_as_integers,
|
||||
collapse_vars: self.collapse_vars.unwrap_or(self.defaults),
|
||||
comparisons: self.comparisons.unwrap_or(self.defaults),
|
||||
computed_props: self.computed_props,
|
||||
conditionals: self.conditionals,
|
||||
dead_code: self.dead_code,
|
||||
directives: self.directives,
|
||||
drop_console: self.drop_console,
|
||||
drop_debugger: self.drop_debugger.unwrap_or(self.defaults),
|
||||
ecma: self.ecma.into(),
|
||||
evaluate: self.evaluate.unwrap_or(self.defaults),
|
||||
expr: self.expression,
|
||||
global_defs: self
|
||||
.global_defs
|
||||
.into_iter()
|
||||
.map(|(k, v)| {
|
||||
let parse = |input: String| {
|
||||
let fm = cm.new_source_file(FileName::Anon, input);
|
||||
|
||||
let lexer = Lexer::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
SourceFileInput::from(&*fm),
|
||||
None,
|
||||
);
|
||||
let mut parser = Parser::new_from(lexer);
|
||||
|
||||
parser.parse_expr().map(drop_span).unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to parse `global_defs.{}` of minifier options: {:?}",
|
||||
k, err
|
||||
)
|
||||
})
|
||||
};
|
||||
let key = parse(if k.starts_with('@') {
|
||||
k[1..].to_string()
|
||||
} else {
|
||||
k.to_string()
|
||||
});
|
||||
|
||||
(
|
||||
k,
|
||||
match v {
|
||||
Value::Null => Lit::Null(Null { span: DUMMY_SP }),
|
||||
Value::Bool(value) => Lit::Bool(Bool {
|
||||
span: DUMMY_SP,
|
||||
value,
|
||||
}),
|
||||
Value::Number(v) => Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: v.as_f64().unwrap(),
|
||||
}),
|
||||
Value::String(v) => Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: v.into(),
|
||||
has_escape: false,
|
||||
kind: Default::default(),
|
||||
}),
|
||||
Value::Object(_) | Value::Array(_) => {
|
||||
unreachable!()
|
||||
}
|
||||
key,
|
||||
if k.starts_with('@') {
|
||||
parse(
|
||||
v.as_str()
|
||||
.unwrap_or_else(|| {
|
||||
panic!(
|
||||
"Value of `global_defs.{}` must be a string literal: ",
|
||||
k
|
||||
)
|
||||
})
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
value_to_expr(v)
|
||||
},
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
hoist_fns: c.hoist_funs,
|
||||
hoist_props: c.hoist_props.unwrap_or(c.defaults),
|
||||
hoist_vars: c.hoist_vars,
|
||||
ie8: c.ie8,
|
||||
if_return: c.if_return.unwrap_or(c.defaults),
|
||||
inline: c
|
||||
hoist_fns: self.hoist_funs,
|
||||
hoist_props: self.hoist_props.unwrap_or(self.defaults),
|
||||
hoist_vars: self.hoist_vars,
|
||||
ie8: self.ie8,
|
||||
if_return: self.if_return.unwrap_or(self.defaults),
|
||||
inline: self
|
||||
.inline
|
||||
.map(|v| match v {
|
||||
TerserInlineOption::Bool(v) => {
|
||||
@ -301,19 +326,19 @@ impl From<TerserCompressorOptions> for CompressOptions {
|
||||
}
|
||||
TerserInlineOption::Num(n) => n,
|
||||
})
|
||||
.unwrap_or(if c.defaults { 3 } else { 0 }),
|
||||
join_vars: c.join_vars.unwrap_or(c.defaults),
|
||||
keep_classnames: c.keep_classnames,
|
||||
keep_fargs: c.keep_fargs.unwrap_or(c.defaults),
|
||||
keep_fnames: c.keep_fnames,
|
||||
keep_infinity: c.keep_infinity,
|
||||
loops: c.loops.unwrap_or(c.defaults),
|
||||
negate_iife: c.negate_iife.unwrap_or(c.defaults),
|
||||
passes: c.passes,
|
||||
props: c.properties.unwrap_or(c.defaults),
|
||||
reduce_fns: c.reduce_funcs,
|
||||
reduce_vars: c.reduce_vars,
|
||||
sequences: c
|
||||
.unwrap_or(if self.defaults { 3 } else { 0 }),
|
||||
join_vars: self.join_vars.unwrap_or(self.defaults),
|
||||
keep_classnames: self.keep_classnames,
|
||||
keep_fargs: self.keep_fargs.unwrap_or(self.defaults),
|
||||
keep_fnames: self.keep_fnames,
|
||||
keep_infinity: self.keep_infinity,
|
||||
loops: self.loops.unwrap_or(self.defaults),
|
||||
negate_iife: self.negate_iife.unwrap_or(self.defaults),
|
||||
passes: self.passes,
|
||||
props: self.properties.unwrap_or(self.defaults),
|
||||
reduce_fns: self.reduce_funcs,
|
||||
reduce_vars: self.reduce_vars,
|
||||
sequences: self
|
||||
.sequences
|
||||
.map(|v| match v {
|
||||
TerserSequenceOptions::Bool(v) => {
|
||||
@ -325,23 +350,23 @@ impl From<TerserCompressorOptions> for CompressOptions {
|
||||
}
|
||||
TerserSequenceOptions::Num(v) => v,
|
||||
})
|
||||
.unwrap_or(if c.defaults { 3 } else { 0 }),
|
||||
side_effects: c.side_effects.unwrap_or(c.defaults),
|
||||
switches: c.switches,
|
||||
top_retain: c.top_retain.map(From::from).unwrap_or_default(),
|
||||
top_level: c.toplevel.map(From::from),
|
||||
typeofs: c.typeofs.unwrap_or(c.defaults),
|
||||
unsafe_passes: c.unsafe_passes,
|
||||
unsafe_arrows: c.unsafe_arrows,
|
||||
unsafe_comps: c.unsafe_comps,
|
||||
unsafe_function: c.unsafe_function,
|
||||
unsafe_math: c.unsafe_math,
|
||||
unsafe_symbols: c.unsafe_symbols,
|
||||
unsafe_methods: c.unsafe_methods,
|
||||
unsafe_proto: c.unsafe_proto,
|
||||
unsafe_regexp: c.unsafe_regexp,
|
||||
unsafe_undefined: c.unsafe_undefined,
|
||||
unused: c.unused.unwrap_or(c.defaults),
|
||||
.unwrap_or(if self.defaults { 3 } else { 0 }),
|
||||
side_effects: self.side_effects.unwrap_or(self.defaults),
|
||||
switches: self.switches,
|
||||
top_retain: self.top_retain.map(From::from).unwrap_or_default(),
|
||||
top_level: self.toplevel.map(From::from),
|
||||
typeofs: self.typeofs.unwrap_or(self.defaults),
|
||||
unsafe_passes: self.unsafe_passes,
|
||||
unsafe_arrows: self.unsafe_arrows,
|
||||
unsafe_comps: self.unsafe_comps,
|
||||
unsafe_function: self.unsafe_function,
|
||||
unsafe_math: self.unsafe_math,
|
||||
unsafe_symbols: self.unsafe_symbols,
|
||||
unsafe_methods: self.unsafe_methods,
|
||||
unsafe_proto: self.unsafe_proto,
|
||||
unsafe_regexp: self.unsafe_regexp,
|
||||
unsafe_undefined: self.unsafe_undefined,
|
||||
unused: self.unused.unwrap_or(self.defaults),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -394,3 +419,59 @@ impl From<TerserTopRetainOption> for Vec<JsWord> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn value_to_expr(v: Value) -> Box<Expr> {
|
||||
match v {
|
||||
Value::Null => Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))),
|
||||
Value::Bool(value) => Box::new(Expr::Lit(Lit::Bool(Bool {
|
||||
span: DUMMY_SP,
|
||||
value,
|
||||
}))),
|
||||
Value::Number(v) => Box::new(Expr::Lit(Lit::Num(Number {
|
||||
span: DUMMY_SP,
|
||||
value: v.as_f64().unwrap(),
|
||||
}))),
|
||||
Value::String(v) => Box::new(Expr::Lit(Lit::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: v.into(),
|
||||
has_escape: false,
|
||||
kind: Default::default(),
|
||||
}))),
|
||||
|
||||
Value::Array(arr) => {
|
||||
let elems = arr
|
||||
.into_iter()
|
||||
.map(value_to_expr)
|
||||
.map(|expr| Some(ExprOrSpread { spread: None, expr }))
|
||||
.collect();
|
||||
Box::new(Expr::Array(ArrayLit {
|
||||
span: DUMMY_SP,
|
||||
elems,
|
||||
}))
|
||||
}
|
||||
|
||||
Value::Object(obj) => {
|
||||
let props = obj
|
||||
.into_iter()
|
||||
.map(|(k, v)| (k, value_to_expr(v)))
|
||||
.map(|(key, value)| KeyValueProp {
|
||||
key: PropName::Str(Str {
|
||||
span: DUMMY_SP,
|
||||
value: key.into(),
|
||||
has_escape: false,
|
||||
kind: Default::default(),
|
||||
}),
|
||||
value,
|
||||
})
|
||||
.map(Prop::KeyValue)
|
||||
.map(Box::new)
|
||||
.map(PropOrSpread::Prop)
|
||||
.collect();
|
||||
|
||||
Box::new(Expr::Object(ObjectLit {
|
||||
span: DUMMY_SP,
|
||||
props,
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
151
ecmascript/minifier/src/pass/global_defs.rs
Normal file
151
ecmascript/minifier/src/pass/global_defs.rs
Normal file
@ -0,0 +1,151 @@
|
||||
use fxhash::FxHashSet;
|
||||
use std::borrow::Cow;
|
||||
use swc_common::pass::CompilerPass;
|
||||
use swc_common::EqIgnoreSpan;
|
||||
use swc_common::Mark;
|
||||
use swc_common::SyntaxContext;
|
||||
use swc_ecma_ast::*;
|
||||
use swc_ecma_utils::ident::IdentLike;
|
||||
use swc_ecma_utils::Id;
|
||||
use swc_ecma_visit::noop_visit_mut_type;
|
||||
use swc_ecma_visit::noop_visit_type;
|
||||
use swc_ecma_visit::Visit;
|
||||
use swc_ecma_visit::VisitMut;
|
||||
use swc_ecma_visit::VisitMutWith;
|
||||
|
||||
pub fn globals_defs(defs: Vec<(Box<Expr>, Box<Expr>)>, top_level_mark: Mark) -> impl VisitMut {
|
||||
GlobalDefs {
|
||||
defs,
|
||||
top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct GlobalDefs {
|
||||
defs: Vec<(Box<Expr>, Box<Expr>)>,
|
||||
/// If syntax context of a identifier reference is not top-level, it means
|
||||
/// the reference points a binding (var / fn / class or whatever).
|
||||
top_level_ctxt: SyntaxContext,
|
||||
/// If a varaible is registered in this variable, it's not a global
|
||||
/// constant.
|
||||
///
|
||||
/// Non-top level bindings are filtered using `top_level_mark`.
|
||||
top_level_bindings: FxHashSet<Id>,
|
||||
in_lhs_of_assign: bool,
|
||||
}
|
||||
|
||||
impl CompilerPass for GlobalDefs {
|
||||
fn name() -> Cow<'static, str> {
|
||||
Cow::Borrowed("global-defs")
|
||||
}
|
||||
}
|
||||
|
||||
/// Finds top-level bindings.
|
||||
impl Visit for GlobalDefs {
|
||||
noop_visit_type!();
|
||||
}
|
||||
|
||||
/// We use [VisitMut] instead of [swc_ecma_visit::Fold] because it's faster.
|
||||
impl VisitMut for GlobalDefs {
|
||||
noop_visit_mut_type!();
|
||||
|
||||
fn visit_mut_assign_expr(&mut self, n: &mut AssignExpr) {
|
||||
let old = self.in_lhs_of_assign;
|
||||
self.in_lhs_of_assign = true;
|
||||
n.left.visit_mut_with(self);
|
||||
self.in_lhs_of_assign = false;
|
||||
n.right.visit_mut_with(self);
|
||||
self.in_lhs_of_assign = old;
|
||||
}
|
||||
|
||||
fn visit_mut_expr(&mut self, n: &mut Expr) {
|
||||
if self.in_lhs_of_assign {
|
||||
return;
|
||||
}
|
||||
|
||||
match n {
|
||||
Expr::Ident(i) => {
|
||||
if i.span.ctxt != self.top_level_ctxt
|
||||
|| self.top_level_bindings.contains(&i.to_id())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
Expr::Member(MemberExpr {
|
||||
obj: ExprOrSuper::Expr(obj),
|
||||
..
|
||||
}) => match &**obj {
|
||||
Expr::Ident(i) => {
|
||||
if i.span.ctxt != self.top_level_ctxt
|
||||
|| self.top_level_bindings.contains(&i.to_id())
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
||||
if let Some((_, new)) = self.defs.iter().find(|(pred, _)| should_replace(&pred, &n)) {
|
||||
*n = *new.clone();
|
||||
return;
|
||||
}
|
||||
|
||||
n.visit_mut_children_with(self);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_mut_update_expr(&mut self, e: &mut UpdateExpr) {
|
||||
match &mut *e.arg {
|
||||
Expr::Ident(..) => {}
|
||||
|
||||
Expr::Member(MemberExpr {
|
||||
computed: false, ..
|
||||
}) => {
|
||||
// TODO: Check for `obj`
|
||||
}
|
||||
|
||||
_ => {
|
||||
e.arg.visit_mut_with(self);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// This is used to detect optional chaining expressions like `a?.b.c` without
|
||||
/// allocation.
|
||||
fn should_replace(pred: &Expr, node: &Expr) -> bool {
|
||||
if pred.eq_ignore_span(node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
match (pred, node) {
|
||||
(pred, Expr::OptChain(node)) => {
|
||||
if should_replace(pred, &node.expr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
(Expr::Member(pred), Expr::Member(node)) => {
|
||||
if pred.computed || node.computed {
|
||||
return false;
|
||||
}
|
||||
|
||||
if !pred.prop.eq_ignore_span(&node.prop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
match (&pred.obj, &node.obj) {
|
||||
(ExprOrSuper::Expr(pred_obj), ExprOrSuper::Expr(node_obj)) => {
|
||||
return should_replace(pred_obj, node_obj)
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
pub mod compute_char_freq;
|
||||
pub mod expand_names;
|
||||
pub mod global_defs;
|
||||
pub mod hygiene;
|
||||
pub mod mangle_names;
|
||||
pub mod mangle_props;
|
||||
|
@ -245,3 +245,24 @@ where
|
||||
module.fold_with(&mut self.visitor)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DeepThisExprVisitor {
|
||||
found: bool,
|
||||
}
|
||||
|
||||
impl Visit for DeepThisExprVisitor {
|
||||
noop_visit_type!();
|
||||
|
||||
fn visit_this_expr(&mut self, _: &ThisExpr, _: &dyn Node) {
|
||||
self.found = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deeply_contains_this_expr<N>(body: &N) -> bool
|
||||
where
|
||||
N: VisitWith<DeepThisExprVisitor>,
|
||||
{
|
||||
let mut visitor = DeepThisExprVisitor { found: false };
|
||||
body.visit_with(&Invalid { span: DUMMY_SP } as _, &mut visitor);
|
||||
visitor.found
|
||||
}
|
||||
|
@ -14,12 +14,14 @@ use std::process::Command;
|
||||
use swc_common::comments::SingleThreadedComments;
|
||||
use swc_common::sync::Lrc;
|
||||
use swc_common::FileName;
|
||||
use swc_common::Mark;
|
||||
use swc_common::SourceMap;
|
||||
use swc_ecma_codegen::text_writer::JsWriter;
|
||||
use swc_ecma_codegen::Emitter;
|
||||
use swc_ecma_minifier::optimize;
|
||||
use swc_ecma_minifier::option::terser::TerserCompressorOptions;
|
||||
use swc_ecma_minifier::option::CompressOptions;
|
||||
use swc_ecma_minifier::option::ExtraOptions;
|
||||
use swc_ecma_minifier::option::MangleOptions;
|
||||
use swc_ecma_minifier::option::MinifyOptions;
|
||||
use swc_ecma_parser::lexer::input::SourceFileInput;
|
||||
@ -27,7 +29,7 @@ use swc_ecma_parser::lexer::Lexer;
|
||||
use swc_ecma_parser::Parser;
|
||||
use swc_ecma_transforms::fixer;
|
||||
use swc_ecma_transforms::hygiene;
|
||||
use swc_ecma_transforms::resolver;
|
||||
use swc_ecma_transforms::resolver_with_mark;
|
||||
use swc_ecma_visit::FoldWith;
|
||||
use testing::assert_eq;
|
||||
use testing::NormalizedOutput;
|
||||
@ -76,11 +78,11 @@ enum TestMangleOptions {
|
||||
Normal(MangleOptions),
|
||||
}
|
||||
|
||||
fn parse_compressor_config(s: &str) -> (bool, CompressOptions) {
|
||||
fn parse_compressor_config(cm: Lrc<SourceMap>, s: &str) -> (bool, CompressOptions) {
|
||||
let c: TerserCompressorOptions =
|
||||
serde_json::from_str(s).expect("failed to deserialize value into a compressor config");
|
||||
|
||||
(c.module, c.into())
|
||||
(c.module, c.into_config(cm))
|
||||
}
|
||||
|
||||
/// Tests ported from terser.
|
||||
@ -94,40 +96,44 @@ fn fixture(input: PathBuf) {
|
||||
let config = dir.join("config.json");
|
||||
let config = read_to_string(&config).expect("failed to read config.json");
|
||||
eprintln!("---- {} -----\n{}", Color::Green.paint("Config"), config);
|
||||
let (_module, config) = parse_compressor_config(&config);
|
||||
|
||||
let mangle = dir.join("mangle.json");
|
||||
let mangle = read_to_string(&mangle).ok();
|
||||
if let Some(mangle) = &mangle {
|
||||
eprintln!(
|
||||
"---- {} -----\n{}",
|
||||
Color::Green.paint("Mangle config"),
|
||||
mangle
|
||||
);
|
||||
}
|
||||
|
||||
let mangle: Option<TestMangleOptions> =
|
||||
mangle.map(|s| serde_json::from_str(&s).expect("failed to deserialize mangle.json"));
|
||||
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let (_module, config) = parse_compressor_config(cm.clone(), &config);
|
||||
|
||||
let mangle = dir.join("mangle.json");
|
||||
let mangle = read_to_string(&mangle).ok();
|
||||
if let Some(mangle) = &mangle {
|
||||
eprintln!(
|
||||
"---- {} -----\n{}",
|
||||
Color::Green.paint("Mangle config"),
|
||||
mangle
|
||||
);
|
||||
}
|
||||
|
||||
let mangle: Option<TestMangleOptions> =
|
||||
mangle.map(|s| serde_json::from_str(&s).expect("failed to deserialize mangle.json"));
|
||||
|
||||
let fm = cm.load_file(&input).expect("failed to load input.js");
|
||||
let comments = SingleThreadedComments::default();
|
||||
|
||||
eprintln!("---- {} -----\n{}", Color::Green.paint("Input"), fm.src);
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
|
||||
let lexer = Lexer::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
SourceFileInput::from(&*fm),
|
||||
Some(&comments),
|
||||
);
|
||||
|
||||
let mut parser = Parser::new_from(lexer);
|
||||
let program = parser
|
||||
.parse_module()
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver()));
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)));
|
||||
|
||||
// Ignore parser errors.
|
||||
//
|
||||
@ -155,6 +161,7 @@ fn fixture(input: PathBuf) {
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
)
|
||||
.fold_with(&mut hygiene())
|
||||
.fold_with(&mut fixer(None));
|
||||
|
@ -5,14 +5,7 @@ arguments/issue_687/input.js
|
||||
arguments/modified/input.js
|
||||
arguments/replace_index_keep_fargs_strict/input.js
|
||||
array_constructor/array_constructor/input.js
|
||||
array_constructor/array_constructor_unsafe/input.js
|
||||
arrays/constant_join/input.js
|
||||
arrays/constant_join_2/input.js
|
||||
arrays/constant_join_3/input.js
|
||||
arrays/for_loop/input.js
|
||||
arrays/holes_and_undefined/input.js
|
||||
arrays/index/input.js
|
||||
arrays/index_length/input.js
|
||||
arrays/length/input.js
|
||||
arrays/spread_with_array_at_end/input.js
|
||||
arrays/spread_with_logical_expression_at_end/input.js
|
||||
@ -37,10 +30,8 @@ arrow/issue_2271/input.js
|
||||
arrow/issue_3092a/input.js
|
||||
arrow/no_leading_parentheses/input.js
|
||||
arrow/object_parens/input.js
|
||||
ascii/ascii_only_false/input.js
|
||||
ascii/ascii_only_false_identifier_es2015/input.js
|
||||
ascii/ascii_only_false_identifier_es5/input.js
|
||||
ascii/ascii_only_true/input.js
|
||||
ascii/ascii_only_true_identifier_es2015/input.js
|
||||
ascii/ascii_only_true_identifier_es5/input.js
|
||||
asm/asm_function_expression/input.js
|
||||
@ -83,6 +74,7 @@ big_int/big_int_octal/input.js
|
||||
big_int/big_int_positive/input.js
|
||||
big_int/regression_big_int_hex_lower_with_e/input.js
|
||||
block_scope/do_not_hoist_let/input.js
|
||||
block_scope/do_not_remove_anon_blocks_if_they_have_decls/input.js
|
||||
block_scope/issue_241/input.js
|
||||
block_scope/issue_508/input.js
|
||||
block_scope/let_statement/input.js
|
||||
@ -104,17 +96,9 @@ classes/class_recursive_refs/input.js
|
||||
collapse_vars/anonymous_function/input.js
|
||||
collapse_vars/boolean_binary_1/input.js
|
||||
collapse_vars/boolean_binary_2/input.js
|
||||
collapse_vars/cascade_call/input.js
|
||||
collapse_vars/cascade_conditional/input.js
|
||||
collapse_vars/cascade_forin/input.js
|
||||
collapse_vars/cascade_if_1/input.js
|
||||
collapse_vars/cascade_if_2/input.js
|
||||
collapse_vars/cascade_return/input.js
|
||||
collapse_vars/cascade_statement/input.js
|
||||
collapse_vars/cascade_switch/input.js
|
||||
collapse_vars/chained_1/input.js
|
||||
collapse_vars/chained_2/input.js
|
||||
collapse_vars/chained_3/input.js
|
||||
collapse_vars/collapse_rhs_array/input.js
|
||||
collapse_vars/collapse_rhs_boolean_1/input.js
|
||||
collapse_vars/collapse_rhs_boolean_2/input.js
|
||||
@ -133,7 +117,7 @@ collapse_vars/collapse_rhs_this/input.js
|
||||
collapse_vars/collapse_rhs_undefined/input.js
|
||||
collapse_vars/collapse_rhs_var/input.js
|
||||
collapse_vars/collapse_rhs_vardef/input.js
|
||||
collapse_vars/collapse_vars_array/input.js
|
||||
collapse_vars/collapse_vars_properties/input.js
|
||||
collapse_vars/collapse_vars_try/input.js
|
||||
collapse_vars/collapse_vars_unary_2/input.js
|
||||
collapse_vars/cond_branch_switch/input.js
|
||||
@ -149,9 +133,8 @@ collapse_vars/issue_1537_destructuring_for_in/input.js
|
||||
collapse_vars/issue_1537_destructuring_for_of/input.js
|
||||
collapse_vars/issue_1537_for_of/input.js
|
||||
collapse_vars/issue_1605_1/input.js
|
||||
collapse_vars/issue_2203_1/input.js
|
||||
collapse_vars/issue_2203_3/input.js
|
||||
collapse_vars/issue_2313_1/input.js
|
||||
collapse_vars/issue_2313_2/input.js
|
||||
collapse_vars/issue_2319_2/input.js
|
||||
collapse_vars/issue_2364_6/input.js
|
||||
collapse_vars/issue_2364_7/input.js
|
||||
@ -162,7 +145,6 @@ collapse_vars/issue_2425_3/input.js
|
||||
collapse_vars/issue_2437_2/input.js
|
||||
collapse_vars/issue_2571_1/input.js
|
||||
collapse_vars/issue_2571_2/input.js
|
||||
collapse_vars/issue_27/input.js
|
||||
collapse_vars/issue_2858/input.js
|
||||
collapse_vars/issue_2873_1/input.js
|
||||
collapse_vars/issue_2873_2/input.js
|
||||
@ -205,16 +187,13 @@ conditionals/cond_3/input.js
|
||||
conditionals/cond_4/input.js
|
||||
conditionals/cond_5/input.js
|
||||
conditionals/cond_7/input.js
|
||||
conditionals/cond_7_1/input.js
|
||||
conditionals/cond_8/input.js
|
||||
conditionals/cond_8b/input.js
|
||||
conditionals/cond_8c/input.js
|
||||
conditionals/cond_9/input.js
|
||||
conditionals/condition_symbol_matches_consequent/input.js
|
||||
conditionals/delete_conditional_1/input.js
|
||||
conditionals/delete_conditional_2/input.js
|
||||
conditionals/equality_conditionals_false/input.js
|
||||
conditionals/equality_conditionals_true/input.js
|
||||
conditionals/hoist_decl/input.js
|
||||
conditionals/ifs_1/input.js
|
||||
conditionals/ifs_2/input.js
|
||||
@ -241,7 +220,6 @@ dead_code/issue_2666/input.js
|
||||
dead_code/issue_2701/input.js
|
||||
dead_code/issue_2929/input.js
|
||||
dead_code/throw_assignment/input.js
|
||||
dead_code/try_catch_finally/input.js
|
||||
debugger/drop_debugger/input.js
|
||||
debugger/keep_debugger/input.js
|
||||
defaults/defaults_false_evaluate_true/input.js
|
||||
@ -249,7 +227,6 @@ defaults/defaults_true/input.js
|
||||
defaults/defaults_true_conditionals_false/input.js
|
||||
destructuring/destructure_empty_array_1/input.js
|
||||
destructuring/destructure_empty_array_2/input.js
|
||||
destructuring/destructure_empty_array_3/input.js
|
||||
destructuring/destructuring_arrays/input.js
|
||||
destructuring/destructuring_arrays_holes/input.js
|
||||
destructuring/destructuring_assign_of_numeric_key/input.js
|
||||
@ -260,6 +237,8 @@ destructuring/destructuring_expressions/input.js
|
||||
destructuring/destructuring_letdef_in_loops/input.js
|
||||
destructuring/destructuring_objects/input.js
|
||||
destructuring/destructuring_objects_trailing_elision/input.js
|
||||
destructuring/destructuring_remove_unused_1/input.js
|
||||
destructuring/destructuring_remove_unused_2/input.js
|
||||
destructuring/destructuring_vardef_in_loops/input.js
|
||||
destructuring/empty_object_destructuring_1/input.js
|
||||
destructuring/empty_object_destructuring_2/input.js
|
||||
@ -269,9 +248,9 @@ destructuring/issue_2044_ecma_5/input.js
|
||||
destructuring/issue_2044_ecma_5_beautify/input.js
|
||||
destructuring/issue_2044_ecma_6/input.js
|
||||
destructuring/issue_2044_ecma_6_beautify/input.js
|
||||
destructuring/issue_2140/input.js
|
||||
destructuring/issue_3205_1/input.js
|
||||
destructuring/issue_t111_4/input.js
|
||||
destructuring/mangle_destructuring_decl_array/input.js
|
||||
destructuring/nested_destructuring_objects/input.js
|
||||
destructuring/object_destructuring_may_need_parentheses/input.js
|
||||
destructuring/reduce_vars/input.js
|
||||
@ -287,20 +266,17 @@ destructuring/unused_destructuring_getter_side_effect_1/input.js
|
||||
directives/class_directives_compression/input.js
|
||||
directives/simple_statement_is_not_a_directive/input.js
|
||||
drop_console/drop_console_1/input.js
|
||||
drop_unused/assign_binding/input.js
|
||||
drop_unused/assign_chain/input.js
|
||||
drop_unused/cascade_drop_assign/input.js
|
||||
drop_unused/const_assign/input.js
|
||||
drop_unused/double_assign_3/input.js
|
||||
drop_unused/drop_fnames/input.js
|
||||
drop_unused/drop_toplevel_all/input.js
|
||||
drop_unused/drop_toplevel_retain_array/input.js
|
||||
drop_unused/drop_value/input.js
|
||||
drop_unused/function_argument_modified_by_function_statement/input.js
|
||||
drop_unused/iife/input.js
|
||||
drop_unused/issue_1539/input.js
|
||||
drop_unused/issue_1709/input.js
|
||||
drop_unused/issue_2063/input.js
|
||||
drop_unused/issue_2136_1/input.js
|
||||
drop_unused/issue_3146_2/input.js
|
||||
drop_unused/issue_805_1/input.js
|
||||
drop_unused/issue_805_2/input.js
|
||||
@ -311,7 +287,6 @@ drop_unused/issue_t161_top_retain_12/input.js
|
||||
drop_unused/issue_t161_top_retain_13/input.js
|
||||
drop_unused/issue_t161_top_retain_14/input.js
|
||||
drop_unused/issue_t161_top_retain_2/input.js
|
||||
drop_unused/issue_t161_top_retain_3/input.js
|
||||
drop_unused/issue_t161_top_retain_5/input.js
|
||||
drop_unused/issue_t161_top_retain_6/input.js
|
||||
drop_unused/issue_t161_top_retain_7/input.js
|
||||
@ -332,11 +307,10 @@ drop_unused/unused_keep_setter_arg/input.js
|
||||
drop_unused/unused_nested_function/input.js
|
||||
drop_unused/unused_seq_elements/input.js
|
||||
drop_unused/unused_var_in_catch/input.js
|
||||
drop_unused/used_var_in_catch/input.js
|
||||
drop_unused/used_block_decls_in_catch/input.js
|
||||
drop_unused/vardef_value/input.js
|
||||
evaluate/Infinity_NaN_undefined_LHS/input.js
|
||||
evaluate/and/input.js
|
||||
evaluate/array_slice_index/input.js
|
||||
evaluate/call_args/input.js
|
||||
evaluate/call_args_drop_param/input.js
|
||||
evaluate/delete_binary_1/input.js
|
||||
@ -362,9 +336,9 @@ evaluate/pow_sequence_with_constants_and_parens/input.js
|
||||
evaluate/pow_sequence_with_parens/input.js
|
||||
evaluate/pow_sequence_with_parens_evaluated/input.js
|
||||
evaluate/pow_with_right_side_evaluating_to_unary/input.js
|
||||
evaluate/prop_function/input.js
|
||||
evaluate/string_case/input.js
|
||||
evaluate/unary_prefix/input.js
|
||||
evaluate/unsafe_array/input.js
|
||||
evaluate/unsafe_array_bad_index/input.js
|
||||
evaluate/unsafe_constant/input.js
|
||||
evaluate/unsafe_string/input.js
|
||||
@ -385,7 +359,6 @@ export/export_default_anonymous_function_not_call/input.js
|
||||
export/export_default_anonymous_generator/input.js
|
||||
export/export_default_arrow/input.js
|
||||
export/export_default_async_arrow_function/input.js
|
||||
export/export_default_seq/input.js
|
||||
export/issue_2038_1/input.js
|
||||
export/issue_2129/input.js
|
||||
export/issue_2131/input.js
|
||||
@ -419,23 +392,27 @@ functions/issue_2737_1/input.js
|
||||
functions/issue_2737_2/input.js
|
||||
functions/issue_3054/input.js
|
||||
functions/no_webkit/input.js
|
||||
functions/non_ascii_function_identifier_name/input.js
|
||||
functions/recursive_inline_1/input.js
|
||||
functions/webkit/input.js
|
||||
global_defs/conditional_chains/input.js
|
||||
global_defs/expanded/input.js
|
||||
global_defs/issue_1801/input.js
|
||||
global_defs/issue_1986/input.js
|
||||
global_defs/issue_2167/input.js
|
||||
global_defs/issue_3217/input.js
|
||||
global_defs/keyword/input.js
|
||||
global_defs/mixed/input.js
|
||||
global_defs/must_replace/input.js
|
||||
global_defs/object/input.js
|
||||
harmony/array_literal_with_spread_1/input.js
|
||||
harmony/array_literal_with_spread_2a/input.js
|
||||
harmony/array_literal_with_spread_2b/input.js
|
||||
harmony/array_literal_with_spread_3a/input.js
|
||||
harmony/array_literal_with_spread_3b/input.js
|
||||
harmony/array_literal_with_spread_4a/input.js
|
||||
harmony/array_literal_with_spread_4b/input.js
|
||||
harmony/array_spread_of_sequence/input.js
|
||||
harmony/arrow_function_parens/input.js
|
||||
harmony/arrow_function_parens_2/input.js
|
||||
harmony/class_expression_statement/input.js
|
||||
harmony/class_expression_statement_unused/input.js
|
||||
harmony/class_expression_statement_unused_toplevel/input.js
|
||||
harmony/class_extends/input.js
|
||||
harmony/class_extends_class/input.js
|
||||
harmony/class_extends_function/input.js
|
||||
harmony/class_extends_regex/input.js
|
||||
@ -457,7 +434,6 @@ harmony/export_default_object_expression/input.js
|
||||
harmony/export_module_statement/input.js
|
||||
harmony/export_statement/input.js
|
||||
harmony/export_statement_mangling/input.js
|
||||
harmony/fat_arrow_as_param/input.js
|
||||
harmony/format_methods/input.js
|
||||
harmony/import_all_statement/input.js
|
||||
harmony/import_meta/input.js
|
||||
@ -535,18 +511,15 @@ issue_1041/const_pragma/input.js
|
||||
issue_1041/not_const/input.js
|
||||
issue_1044/issue_1044/input.js
|
||||
issue_1105/Infinity_not_in_with_scope/input.js
|
||||
issue_1105/check_drop_unused_in_peer_function/input.js
|
||||
issue_1105/with_in_global_scope/input.js
|
||||
issue_12/keep_name_of_getter/input.js
|
||||
issue_12/setter_with_operator_keys/input.js
|
||||
issue_1212/issue_1212_debug_false/input.js
|
||||
issue_1212/issue_1212_debug_true/input.js
|
||||
issue_143/tranformation_sort_order_equal/input.js
|
||||
issue_143/tranformation_sort_order_greater_or_equal/input.js
|
||||
issue_143/tranformation_sort_order_lesser_or_equal/input.js
|
||||
issue_143/tranformation_sort_order_unequal/input.js
|
||||
issue_1466/same_variable_in_multiple_forIn_sequences_const/input.js
|
||||
issue_1466/same_variable_in_multiple_forIn_sequences_let/input.js
|
||||
issue_1466/same_variable_in_multiple_forOf_sequences_const/input.js
|
||||
issue_1466/same_variable_in_multiple_forOf_sequences_let/input.js
|
||||
issue_1588/runtime_error/input.js
|
||||
issue_1588/support_ie8/input.js
|
||||
issue_1656/f7/input.js
|
||||
@ -556,16 +529,8 @@ issue_1673/side_effects_finally/input.js
|
||||
issue_1673/side_effects_label/input.js
|
||||
issue_1673/side_effects_switch/input.js
|
||||
issue_1704/mangle_catch_ie8/input.js
|
||||
issue_1704/mangle_catch_redef_1/input.js
|
||||
issue_1704/mangle_catch_redef_1_ie8/input.js
|
||||
issue_1704/mangle_catch_redef_2/input.js
|
||||
issue_1704/mangle_catch_redef_2_ie8/input.js
|
||||
issue_1704/mangle_catch_redef_3_ie8_toplevel/input.js
|
||||
issue_1704/mangle_catch_redef_3_toplevel/input.js
|
||||
issue_1704/mangle_catch_var_ie8/input.js
|
||||
issue_1733/function_catch_catch/input.js
|
||||
issue_1733/function_catch_catch_ie8/input.js
|
||||
issue_1770/numeric_literal/input.js
|
||||
issue_1833/iife_for/input.js
|
||||
issue_1833/iife_for_in/input.js
|
||||
issue_1833/iife_while/input.js
|
||||
@ -586,7 +551,8 @@ issue_2001/export_func_3/input.js
|
||||
issue_2001/export_toplevel_1/input.js
|
||||
issue_2001/export_toplevel_2/input.js
|
||||
issue_208/do_not_update_lhs/input.js
|
||||
issue_229/template_strings/input.js
|
||||
issue_208/do_update_rhs/input.js
|
||||
issue_208/mixed/input.js
|
||||
issue_2652/insert_semicolon/input.js
|
||||
issue_2652/unary_postfix/input.js
|
||||
issue_267/issue_267/input.js
|
||||
@ -618,12 +584,7 @@ issue_640/issue_1254_negate_iife_true/input.js
|
||||
issue_640/negate_iife_3_off/input.js
|
||||
issue_640/negate_iife_5_off/input.js
|
||||
issue_751/negate_booleans_2/input.js
|
||||
issue_782/dont_remove_this_binding_sequence/input.js
|
||||
issue_782/remove_redundant_sequence_items/input.js
|
||||
issue_926/template_strings/input.js
|
||||
issue_973/this_binding_collapse_vars/input.js
|
||||
issue_973/this_binding_conditionals/input.js
|
||||
issue_973/this_binding_side_effects/input.js
|
||||
issue_t50/issue_t50/input.js
|
||||
issue_t50/issue_t50_const/input.js
|
||||
issue_t50/issue_t50_let/input.js
|
||||
@ -685,17 +646,14 @@ new/dot_parenthesis_2/input.js
|
||||
new/new_constructor_with_unary_arguments/input.js
|
||||
new/new_statement/input.js
|
||||
new/new_statements_2/input.js
|
||||
new/new_statements_3/input.js
|
||||
new/new_with_assignement_expression/input.js
|
||||
new/new_with_many_parameters/input.js
|
||||
new/new_with_rewritten_true_value/input.js
|
||||
new/new_with_unary_prefix/input.js
|
||||
node_version/eval_let_6/input.js
|
||||
nullish/nullish_coalescing_boolean_context/input.js
|
||||
nullish/nullish_coalescing_mandatory_parens/input.js
|
||||
nullish/nullish_coalescing_parens/input.js
|
||||
nullish/simplify_nullish_coalescing/input.js
|
||||
numbers/comparisons/input.js
|
||||
numbers/compress_numbers/input.js
|
||||
numbers/issue_1710/input.js
|
||||
numbers/keep_numbers/input.js
|
||||
@ -738,7 +696,6 @@ parameters/arrow_return/input.js
|
||||
parameters/default_values_in_destructurings/input.js
|
||||
parameters/destructuring_arguments_1/input.js
|
||||
parameters/destructuring_arguments_2/input.js
|
||||
parameters/destructuring_arguments_3/input.js
|
||||
parameters/regression_arrow_functions_and_hoist/input.js
|
||||
parameters/regression_assign_arrow_functions/input.js
|
||||
properties/accessor_1/input.js
|
||||
@ -750,11 +707,13 @@ properties/accessor_number/input.js
|
||||
properties/accessor_string/input.js
|
||||
properties/accessor_this/input.js
|
||||
properties/array_hole/input.js
|
||||
properties/evaluate_array_length/input.js
|
||||
properties/evaluate_string_length/input.js
|
||||
properties/first_256_chars_as_properties/input.js
|
||||
properties/first_256_hex_chars_as_properties/input.js
|
||||
properties/first_256_unicode_chars_as_properties/input.js
|
||||
properties/issue_2208_1/input.js
|
||||
properties/issue_2208_2/input.js
|
||||
properties/issue_2208_6/input.js
|
||||
properties/issue_2321/input.js
|
||||
properties/issue_2893_1/input.js
|
||||
properties/issue_2893_2/input.js
|
||||
@ -776,7 +735,6 @@ properties/mangle_define_property_arg/input.js
|
||||
properties/mangle_private_properties/input.js
|
||||
properties/mangle_properties_which_matches_pattern/input.js
|
||||
properties/native_prototype_lhs/input.js
|
||||
pure_funcs/array/input.js
|
||||
pure_funcs/assign/input.js
|
||||
pure_funcs/issue_3065_1/input.js
|
||||
pure_getters/chained/input.js
|
||||
@ -802,6 +760,7 @@ pure_getters/issue_2313_5/input.js
|
||||
pure_getters/issue_2313_7/input.js
|
||||
pure_getters/issue_2678/input.js
|
||||
pure_getters/issue_2938_1/input.js
|
||||
pure_getters/issue_2938_2/input.js
|
||||
pure_getters/set_immutable_2/input.js
|
||||
pure_getters/set_immutable_4/input.js
|
||||
reduce_vars/accessor_1/input.js
|
||||
@ -824,23 +783,17 @@ reduce_vars/conditional_nested_3/input.js
|
||||
reduce_vars/const_expr_1/input.js
|
||||
reduce_vars/const_expr_2/input.js
|
||||
reduce_vars/defun_assign/input.js
|
||||
reduce_vars/defun_catch_1/input.js
|
||||
reduce_vars/defun_catch_2/input.js
|
||||
reduce_vars/defun_catch_3/input.js
|
||||
reduce_vars/defun_catch_4/input.js
|
||||
reduce_vars/defun_catch_5/input.js
|
||||
reduce_vars/defun_catch_6/input.js
|
||||
reduce_vars/defun_reference/input.js
|
||||
reduce_vars/defun_single_use_loop/input.js
|
||||
reduce_vars/defun_var_1/input.js
|
||||
reduce_vars/defun_var_2/input.js
|
||||
reduce_vars/delay_def_lhs/input.js
|
||||
reduce_vars/do_while/input.js
|
||||
reduce_vars/double_reference/input.js
|
||||
reduce_vars/duplicate_lambda_defun_name_2/input.js
|
||||
reduce_vars/escape_await/input.js
|
||||
reduce_vars/escape_conditional/input.js
|
||||
reduce_vars/escape_local_conditional/input.js
|
||||
reduce_vars/escape_local_sequence/input.js
|
||||
reduce_vars/escape_local_throw/input.js
|
||||
reduce_vars/escape_throw/input.js
|
||||
reduce_vars/escape_yield/input.js
|
||||
@ -912,6 +865,7 @@ reduce_vars/multi_def_2/input.js
|
||||
reduce_vars/multi_def_3/input.js
|
||||
reduce_vars/obj_for_2/input.js
|
||||
reduce_vars/obj_var_1/input.js
|
||||
reduce_vars/obj_var_2/input.js
|
||||
reduce_vars/perf_5/input.js
|
||||
reduce_vars/pure_getters_1/input.js
|
||||
reduce_vars/recursive_inlining_5/input.js
|
||||
@ -935,17 +889,12 @@ reduce_vars/toplevel_on_loops_2/input.js
|
||||
reduce_vars/toplevel_on_loops_3/input.js
|
||||
reduce_vars/try_abort/input.js
|
||||
reduce_vars/unary_delete/input.js
|
||||
reduce_vars/unsafe_evaluate_array_1/input.js
|
||||
reduce_vars/unsafe_evaluate_array_2/input.js
|
||||
reduce_vars/unsafe_evaluate_array_3/input.js
|
||||
reduce_vars/unsafe_evaluate_array_4/input.js
|
||||
reduce_vars/unsafe_evaluate_array_5/input.js
|
||||
reduce_vars/unsafe_evaluate_object_3/input.js
|
||||
reduce_vars/unsafe_evaluate_side_effect_free_2/input.js
|
||||
reduce_vars/unsafe_evaluate_unknown/input.js
|
||||
reduce_vars/use_before_var/input.js
|
||||
reduce_vars/var_assign_1/input.js
|
||||
reduce_vars/var_assign_2/input.js
|
||||
reduce_vars/var_assign_3/input.js
|
||||
reduce_vars/var_assign_4/input.js
|
||||
reduce_vars/var_assign_5/input.js
|
||||
@ -956,45 +905,27 @@ regexp/regexp_1/input.js
|
||||
regexp/regexp_2/input.js
|
||||
regexp/regexp_simple/input.js
|
||||
regexp/regexp_slashes/input.js
|
||||
rename/function_catch_catch/input.js
|
||||
rename/function_catch_catch_ie8/input.js
|
||||
rename/function_iife_catch/input.js
|
||||
rename/issue_2120_2/input.js
|
||||
rename/mangle_catch_ie8/input.js
|
||||
rename/mangle_catch_redef_1/input.js
|
||||
rename/mangle_catch_redef_1_ie8/input.js
|
||||
rename/mangle_catch_redef_2/input.js
|
||||
rename/mangle_catch_redef_2_ie8/input.js
|
||||
rename/mangle_catch_var_ie8/input.js
|
||||
rename/mangle_catch_var_ie8_toplevel/input.js
|
||||
rename/mangle_catch_var_toplevel/input.js
|
||||
return_undefined/return_undefined/input.js
|
||||
return_undefined/return_void/input.js
|
||||
sandbox/console_log/input.js
|
||||
sequences/cascade_assignment_in_return/input.js
|
||||
sequences/delete_seq_1/input.js
|
||||
sequences/delete_seq_2/input.js
|
||||
sequences/delete_seq_3/input.js
|
||||
sequences/delete_seq_4/input.js
|
||||
sequences/delete_seq_5/input.js
|
||||
sequences/delete_seq_6/input.js
|
||||
sequences/forin/input.js
|
||||
sequences/func_def_1/input.js
|
||||
sequences/func_def_2/input.js
|
||||
sequences/func_def_3/input.js
|
||||
sequences/func_def_4/input.js
|
||||
sequences/func_def_5/input.js
|
||||
sequences/hoist_decl/input.js
|
||||
sequences/hoist_defun/input.js
|
||||
sequences/iife/input.js
|
||||
sequences/issue_1685/input.js
|
||||
sequences/issue_2062/input.js
|
||||
sequences/issue_2313/input.js
|
||||
sequences/lift_sequences_1/input.js
|
||||
sequences/lift_sequences_2/input.js
|
||||
sequences/lift_sequences_3/input.js
|
||||
sequences/lift_sequences_4/input.js
|
||||
sequences/lift_sequences_5/input.js
|
||||
sequences/lift_sequences_6/input.js
|
||||
sequences/limit_1/input.js
|
||||
sequences/limit_2/input.js
|
||||
@ -1005,10 +936,7 @@ sequences/make_sequences_4/input.js
|
||||
sequences/negate_iife_for/input.js
|
||||
sequences/reassign_const/input.js
|
||||
sequences/side_effects/input.js
|
||||
sequences/side_effects_cascade_1/input.js
|
||||
sequences/side_effects_cascade_2/input.js
|
||||
sequences/side_effects_cascade_3/input.js
|
||||
sequences/unsafe_undefined/input.js
|
||||
string_literal/issue_1929/input.js
|
||||
string_literal/octal_escape_sequence/input.js
|
||||
super/super_can_be_parsed/input.js
|
||||
@ -1044,68 +972,51 @@ switch/keep_case/input.js
|
||||
switch/keep_default/input.js
|
||||
template_string/allow_chained_templates/input.js
|
||||
template_string/allow_null_character/input.js
|
||||
template_string/array_join/input.js
|
||||
template_string/check_escaped_chars/input.js
|
||||
template_string/coerce_to_string/input.js
|
||||
template_string/do_not_optimize_tagged_template_1/input.js
|
||||
template_string/do_not_optimize_tagged_template_2/input.js
|
||||
template_string/equality/input.js
|
||||
template_string/es2018_revision_of_template_escapes_1/input.js
|
||||
template_string/escape_dollar_curly/input.js
|
||||
template_string/evaluate_nested_templates/input.js
|
||||
template_string/issue_1856/input.js
|
||||
template_string/issue_1856_ascii_only/input.js
|
||||
template_string/keep_raw_content_in_tagged_template/input.js
|
||||
template_string/regex_1/input.js
|
||||
template_string/regex_2/input.js
|
||||
template_string/respect_inline_script/input.js
|
||||
template_string/return_template_string_with_trailing_backslash/input.js
|
||||
template_string/semicolons/input.js
|
||||
template_string/sequence_1/input.js
|
||||
template_string/sequence_2/input.js
|
||||
template_string/side_effects/input.js
|
||||
template_string/simple_string/input.js
|
||||
template_string/tagged_call_with_invalid_escape/input.js
|
||||
template_string/tagged_call_with_invalid_escape_2/input.js
|
||||
template_string/tagged_template_function_inline_1/input.js
|
||||
template_string/tagged_template_function_inline_2/input.js
|
||||
template_string/tagged_template_function_inline_3/input.js
|
||||
template_string/tagged_template_function_inline_4/input.js
|
||||
template_string/tagged_template_function_inline_5/input.js
|
||||
template_string/tagged_template_parens/input.js
|
||||
template_string/tagged_template_valid_strict_legacy_octal/input.js
|
||||
template_string/tagged_template_with_comment/input.js
|
||||
template_string/tagged_template_with_ill_formed_unicode_escape/input.js
|
||||
template_string/tagged_template_with_invalid_escape/input.js
|
||||
template_string/template_concattenating_string/input.js
|
||||
template_string/template_ending_with_newline/input.js
|
||||
template_string/template_evaluate_undefined/input.js
|
||||
template_string/template_literal_plus/input.js
|
||||
template_string/template_literal_plus_grouping/input.js
|
||||
template_string/template_starting_with_newline/input.js
|
||||
template_string/template_string_evaluate_with_many_segments/input.js
|
||||
template_string/template_string_prefixes/input.js
|
||||
template_string/template_string_to_normal_string/input.js
|
||||
template_string/template_string_with_constant_expression/input.js
|
||||
template_string/template_string_with_many_segments/input.js
|
||||
template_string/template_string_with_predefined_constants/input.js
|
||||
template_string/template_strings/input.js
|
||||
template_string/template_strings_ascii_only/input.js
|
||||
template_string/template_strings_without_ascii_only/input.js
|
||||
template_string/template_with_newline/input.js
|
||||
transform/booleans_evaluate/input.js
|
||||
transform/booleans_global_defs/input.js
|
||||
transform/if_else_empty/input.js
|
||||
try_catch/catch_destructuring_with_sequence/input.js
|
||||
try_catch/issue_452/input.js
|
||||
try_catch/parameterless_catch/input.js
|
||||
try_catch/parent_scope_of_catch_block_is_not_the_try_block/input.js
|
||||
typeof/duplicate_defun_arg_name/input.js
|
||||
typeof/duplicate_lambda_arg_name/input.js
|
||||
typeof/issue_1668/input.js
|
||||
typeof/issue_2728_1/input.js
|
||||
typeof/issue_2728_2/input.js
|
||||
typeof/issue_2728_5/input.js
|
||||
typeof/issue_2728_6/input.js
|
||||
typeof/typeof_defun_1/input.js
|
||||
typeof/typeof_defun_2/input.js
|
||||
typeof/typeof_evaluation/input.js
|
||||
typeof/typeof_in_boolean_context/input.js
|
||||
|
@ -49,7 +49,6 @@ collapse_vars/cascade_switch/input.js
|
||||
collapse_vars/chained_1/input.js
|
||||
collapse_vars/chained_2/input.js
|
||||
collapse_vars/chained_3/input.js
|
||||
collapse_vars/collapse_rhs_lhs_2/input.js
|
||||
collapse_vars/collapse_vars_arguments/input.js
|
||||
collapse_vars/collapse_vars_array/input.js
|
||||
collapse_vars/collapse_vars_assignment/input.js
|
||||
@ -64,7 +63,6 @@ collapse_vars/collapse_vars_lvalues/input.js
|
||||
collapse_vars/collapse_vars_lvalues_drop_assign/input.js
|
||||
collapse_vars/collapse_vars_misc1/input.js
|
||||
collapse_vars/collapse_vars_object/input.js
|
||||
collapse_vars/collapse_vars_properties/input.js
|
||||
collapse_vars/collapse_vars_regexp/input.js
|
||||
collapse_vars/collapse_vars_repeated/input.js
|
||||
collapse_vars/collapse_vars_self_reference/input.js
|
||||
@ -217,7 +215,6 @@ destructuring/empty_object_destructuring_4/input.js
|
||||
destructuring/empty_object_destructuring_misc/input.js
|
||||
destructuring/export_function_containing_destructuring_decl/input.js
|
||||
destructuring/export_unreferenced_declarations_2/input.js
|
||||
destructuring/issue_2140/input.js
|
||||
destructuring/issue_3205_2/input.js
|
||||
destructuring/issue_3205_3/input.js
|
||||
destructuring/issue_3205_4/input.js
|
||||
@ -278,7 +275,6 @@ drop_unused/issue_1968/input.js
|
||||
drop_unused/issue_2063/input.js
|
||||
drop_unused/issue_2105_1/input.js
|
||||
drop_unused/issue_2105_2/input.js
|
||||
drop_unused/issue_2136_1/input.js
|
||||
drop_unused/issue_2136_2/input.js
|
||||
drop_unused/issue_2136_3/input.js
|
||||
drop_unused/issue_2163/input.js
|
||||
@ -327,7 +323,6 @@ evaluate/issue_2231_3/input.js
|
||||
evaluate/issue_2535_1/input.js
|
||||
evaluate/issue_2535_2/input.js
|
||||
evaluate/issue_2535_3/input.js
|
||||
evaluate/issue_2822/input.js
|
||||
evaluate/issue_2916_2/input.js
|
||||
evaluate/issue_2919/input.js
|
||||
evaluate/issue_2926_1/input.js
|
||||
@ -339,7 +334,6 @@ evaluate/null_conditional_chain_eval/input.js
|
||||
evaluate/positive_zero/input.js
|
||||
evaluate/pow_sequence_with_parens_exact/input.js
|
||||
evaluate/pow_with_number_constants/input.js
|
||||
evaluate/prop_function/input.js
|
||||
evaluate/prototype_function/input.js
|
||||
evaluate/self_comparison_1/input.js
|
||||
evaluate/self_comparison_2/input.js
|
||||
@ -462,18 +456,7 @@ functions/unsafe_call_3/input.js
|
||||
functions/unsafe_call_expansion_1/input.js
|
||||
functions/unsafe_call_expansion_2/input.js
|
||||
functions/use_before_init_in_loop/input.js
|
||||
global_defs/conditional_chains/input.js
|
||||
global_defs/expanded/input.js
|
||||
global_defs/issue_1801/input.js
|
||||
global_defs/issue_1986/input.js
|
||||
global_defs/issue_2167/input.js
|
||||
global_defs/issue_3217/input.js
|
||||
global_defs/keyword/input.js
|
||||
global_defs/mixed/input.js
|
||||
global_defs/must_replace/input.js
|
||||
global_defs/object/input.js
|
||||
harmony/array_literal_with_spread_2b/input.js
|
||||
harmony/array_literal_with_spread_3b/input.js
|
||||
harmony/array_literal_with_spread_4a/input.js
|
||||
harmony/array_literal_with_spread_4b/input.js
|
||||
harmony/array_spread_of_sequence/input.js
|
||||
@ -599,8 +582,6 @@ issue_1105/with_using_existing_variable_outside_scope/input.js
|
||||
issue_12/keep_name_of_setter/input.js
|
||||
issue_1202/mangle_keep_fnames_false/input.js
|
||||
issue_1202/mangle_keep_fnames_true/input.js
|
||||
issue_1212/issue_1212_debug_false/input.js
|
||||
issue_1212/issue_1212_debug_true/input.js
|
||||
issue_126/concatenate_rhs_strings/input.js
|
||||
issue_1261/pure_function_calls/input.js
|
||||
issue_1261/pure_function_calls_toplevel/input.js
|
||||
@ -682,8 +663,6 @@ issue_2001/export_mangle_6/input.js
|
||||
issue_203/compress_new_function/input.js
|
||||
issue_203/compress_new_function_with_destruct/input.js
|
||||
issue_203/compress_new_function_with_destruct_arrows/input.js
|
||||
issue_208/do_update_rhs/input.js
|
||||
issue_208/mixed/input.js
|
||||
issue_22/return_with_no_value_in_if_body/input.js
|
||||
issue_229/template_strings/input.js
|
||||
issue_269/issue_269_1/input.js
|
||||
@ -814,7 +793,6 @@ object/prop_func_to_concise_method_various/input.js
|
||||
object/shorthand_properties/input.js
|
||||
parameters/default_arguments/input.js
|
||||
parameters/destructuring_arguments_3/input.js
|
||||
properties/array_hole/input.js
|
||||
properties/computed_property/input.js
|
||||
properties/const_prop_assign_pure/input.js
|
||||
properties/const_prop_assign_strict/input.js
|
||||
@ -823,12 +801,9 @@ properties/dont_mangle_computed_property_2/input.js
|
||||
properties/dot_properties/input.js
|
||||
properties/dot_properties_es5/input.js
|
||||
properties/evaluate_array_length/input.js
|
||||
properties/evaluate_string_length/input.js
|
||||
properties/issue_2208_1/input.js
|
||||
properties/issue_2208_3/input.js
|
||||
properties/issue_2208_4/input.js
|
||||
properties/issue_2208_5/input.js
|
||||
properties/issue_2208_6/input.js
|
||||
properties/issue_2208_7/input.js
|
||||
properties/issue_2208_8/input.js
|
||||
properties/issue_2208_9/input.js
|
||||
@ -1010,7 +985,6 @@ reduce_vars/named_function_with_recursive_ref_reuse/input.js
|
||||
reduce_vars/obj_arg_1/input.js
|
||||
reduce_vars/obj_arg_2/input.js
|
||||
reduce_vars/obj_for_1/input.js
|
||||
reduce_vars/obj_var_2/input.js
|
||||
reduce_vars/passes/input.js
|
||||
reduce_vars/perf_1/input.js
|
||||
reduce_vars/perf_3/input.js
|
||||
@ -1037,7 +1011,6 @@ reduce_vars/unsafe_evaluate_modified/input.js
|
||||
reduce_vars/unsafe_evaluate_object_1/input.js
|
||||
reduce_vars/unsafe_evaluate_object_2/input.js
|
||||
reduce_vars/unsafe_evaluate_side_effect_free_1/input.js
|
||||
reduce_vars/unsafe_evaluate_side_effect_free_2/input.js
|
||||
reduce_vars/unused_modified/input.js
|
||||
reduce_vars/var_assign_1/input.js
|
||||
reduce_vars/var_assign_2/input.js
|
||||
@ -1090,12 +1063,10 @@ template_string/equality/input.js
|
||||
template_string/escape_dollar_curly/input.js
|
||||
template_string/evaluate_nested_templates/input.js
|
||||
template_string/regex_2/input.js
|
||||
template_string/sequence_1/input.js
|
||||
template_string/sequence_2/input.js
|
||||
template_string/side_effects/input.js
|
||||
template_string/simple_string/input.js
|
||||
template_string/special_chars_in_string/input.js
|
||||
template_string/tagged_template_function_inline_4/input.js
|
||||
template_string/tagged_template_function_inline_5/input.js
|
||||
template_string/tagged_template_parens/input.js
|
||||
template_string/template_concattenating_string/input.js
|
||||
@ -1103,7 +1074,6 @@ template_string/template_evaluate_undefined/input.js
|
||||
template_string/template_literal_plus/input.js
|
||||
template_string/template_literal_plus_grouping/input.js
|
||||
template_string/template_string_with_predefined_constants/input.js
|
||||
transform/booleans_global_defs/input.js
|
||||
transform/condition_evaluate/input.js
|
||||
transform/if_return/input.js
|
||||
transform/label_if_break/input.js
|
||||
@ -1111,7 +1081,6 @@ transform/while_if_break/input.js
|
||||
try_catch/broken_safari_catch_scope/input.js
|
||||
try_catch/broken_safari_catch_scope_caveat/input.js
|
||||
try_catch/catch_destructuring_with_sequence/input.js
|
||||
typeof/duplicate_lambda_arg_name/input.js
|
||||
typeof/issue_2728_3/input.js
|
||||
typeof/issue_2728_4/input.js
|
||||
typeof/typeof_defun_1/input.js
|
||||
|
@ -2,10 +2,12 @@ function f(CONFIG) {
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function g() {
|
||||
var CONFIG = { VALUE: 1 };
|
||||
var CONFIG = {
|
||||
VALUE: 1
|
||||
};
|
||||
return CONFIG.VALUE;
|
||||
}
|
||||
function h() {
|
||||
return 42;
|
||||
}
|
||||
if ([0][0]) console.debug("foo");
|
||||
if (0) console.debug("foo");
|
||||
|
@ -6,7 +6,7 @@ edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "swc_ecma_transforms_optimization"
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "0.20.0"
|
||||
version = "0.20.1"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
|
@ -190,6 +190,7 @@ impl SimplifyExpr {
|
||||
});
|
||||
}
|
||||
|
||||
self.changed = true;
|
||||
let idx = match op {
|
||||
KnownOp::Index(i) => i,
|
||||
_ => unreachable!(),
|
||||
|
168
package.json
168
package.json
@ -1,87 +1,87 @@
|
||||
{
|
||||
"name": "@swc/core",
|
||||
"version": "1.2.58",
|
||||
"description": "Super-fast alternative for babel",
|
||||
"homepage": "https://swc.rs",
|
||||
"main": "./index.js",
|
||||
"author": "강동윤 <kdy1997.dev@gmail.com>",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"swc",
|
||||
"spack",
|
||||
"babel",
|
||||
"typescript",
|
||||
"rust",
|
||||
"webpack",
|
||||
"tsc"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/swc-project/swc.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/swc-project/swc/issues"
|
||||
},
|
||||
"napi": {
|
||||
"name": "swc",
|
||||
"triples": {
|
||||
"defaults": true,
|
||||
"additional": [
|
||||
"x86_64-unknown-linux-musl",
|
||||
"i686-pc-windows-msvc",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"armv7-unknown-linux-gnueabihf",
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-linux-android"
|
||||
]
|
||||
"name": "@swc/core",
|
||||
"version": "1.2.59",
|
||||
"description": "Super-fast alternative for babel",
|
||||
"homepage": "https://swc.rs",
|
||||
"main": "./index.js",
|
||||
"author": "강동윤 <kdy1997.dev@gmail.com>",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"swc",
|
||||
"spack",
|
||||
"babel",
|
||||
"typescript",
|
||||
"rust",
|
||||
"webpack",
|
||||
"tsc"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/swc-project/swc.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/swc-project/swc/issues"
|
||||
},
|
||||
"napi": {
|
||||
"name": "swc",
|
||||
"triples": {
|
||||
"defaults": true,
|
||||
"additional": [
|
||||
"x86_64-unknown-linux-musl",
|
||||
"i686-pc-windows-msvc",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
"armv7-unknown-linux-gnueabihf",
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-linux-android"
|
||||
]
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@node-rs/helper": "^1.0.0"
|
||||
},
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"artifacts": "napi artifacts --dist scripts/npm",
|
||||
"prepublishOnly": "tsc -d && napi prepublish -p scripts/npm --tagstyle npm",
|
||||
"build": "tsc -d && napi build --platform --release --cargo-name node --cargo-flags=\"-p node\"",
|
||||
"build:dev": "tsc -d && napi build --platform --cargo-name node --cargo-flags=\"-p node\"",
|
||||
"test": "jest node-swc/__tests__",
|
||||
"version": "napi version -p scripts/npm"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.16",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.13.15",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
|
||||
"@babel/preset-env": "^7.13.15",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@babel/types": "^7.14.0",
|
||||
"@napi-rs/cli": "^1.0.4",
|
||||
"@swc/helpers": "^0.2.10",
|
||||
"@types/browserslist": "^4.15.0",
|
||||
"@types/jest": "^25.2.3",
|
||||
"@types/node": "^14.14.41",
|
||||
"axios": "^0.21.1",
|
||||
"babel-plugin-transform-node-env-inline": "^0.4.3",
|
||||
"browserslist": "^4.16.5",
|
||||
"jest": "^23.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"progress": "^2.0.3",
|
||||
"source-map": "^0.7.3",
|
||||
"source-map-support": "^0.5.19",
|
||||
"sourcemap-validator": "^1.1.1",
|
||||
"typescript": "^4.2.0-beta"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/swc"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org/",
|
||||
"access": "public"
|
||||
},
|
||||
"dependencies": {
|
||||
"@node-rs/helper": "^1.0.0"
|
||||
},
|
||||
"types": "./lib/index.d.ts",
|
||||
"scripts": {
|
||||
"artifacts": "napi artifacts --dist scripts/npm",
|
||||
"prepublishOnly": "tsc -d && napi prepublish -p scripts/npm --tagstyle npm",
|
||||
"build": "tsc -d && napi build --platform --release --cargo-name node --cargo-flags=\"-p node\"",
|
||||
"build:dev": "tsc -d && napi build --platform --cargo-name node --cargo-flags=\"-p node\"",
|
||||
"test": "jest node-swc/__tests__",
|
||||
"version": "napi version -p scripts/npm"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.13.16",
|
||||
"@babel/plugin-proposal-class-properties": "^7.13.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.13.15",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.13.8",
|
||||
"@babel/preset-env": "^7.13.15",
|
||||
"@babel/preset-react": "^7.13.13",
|
||||
"@babel/preset-typescript": "^7.13.0",
|
||||
"@babel/types": "^7.14.0",
|
||||
"@napi-rs/cli": "^1.0.4",
|
||||
"@swc/helpers": "^0.2.10",
|
||||
"@types/browserslist": "^4.15.0",
|
||||
"@types/jest": "^25.2.3",
|
||||
"@types/node": "^14.14.41",
|
||||
"axios": "^0.21.1",
|
||||
"babel-plugin-transform-node-env-inline": "^0.4.3",
|
||||
"browserslist": "^4.16.5",
|
||||
"jest": "^23.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"progress": "^2.0.3",
|
||||
"source-map": "^0.7.3",
|
||||
"source-map-support": "^0.5.19",
|
||||
"sourcemap-validator": "^1.1.1",
|
||||
"typescript": "^4.2.0-beta"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/swc"
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,9 @@ description = "wasm module for swc"
|
||||
edition = "2018"
|
||||
license = "Apache-2.0/MIT"
|
||||
name = "wasm"
|
||||
publish = false
|
||||
repository = "https://github.com/swc-project/swc.git"
|
||||
version = "1.2.58"
|
||||
version = "1.2.59"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
Loading…
Reference in New Issue
Block a user