parent
d40631fd44
commit
7fa1dea9d0
|
|
@ -652,6 +652,7 @@ merge(Compressor.prototype, {
|
||||||
d.escaped.push(parent);
|
d.escaped.push(parent);
|
||||||
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
if (depth > 1 && !(value && value.is_constant_expression(scope))) depth = 1;
|
||||||
if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth;
|
if (!d.escaped.depth || d.escaped.depth > depth) d.escaped.depth = depth;
|
||||||
|
if (d.scope !== scope) d.escaped.cross_scope = true;
|
||||||
return;
|
return;
|
||||||
} else if (value_in_use(node, parent)) {
|
} else if (value_in_use(node, parent)) {
|
||||||
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
mark_escaped(tw, d, scope, parent, parent, level + 1, depth);
|
||||||
|
|
@ -1973,6 +1974,7 @@ merge(Compressor.prototype, {
|
||||||
var read_toplevel = false;
|
var read_toplevel = false;
|
||||||
var modify_toplevel = false;
|
var modify_toplevel = false;
|
||||||
// Locate symbols which may execute code outside of scanning range
|
// Locate symbols which may execute code outside of scanning range
|
||||||
|
var well_defined = true;
|
||||||
var lvalues = get_lvalues(candidate);
|
var lvalues = get_lvalues(candidate);
|
||||||
var lhs_local = is_lhs_local(lhs);
|
var lhs_local = is_lhs_local(lhs);
|
||||||
var rvalue = get_rvalue(candidate);
|
var rvalue = get_rvalue(candidate);
|
||||||
|
|
@ -2173,11 +2175,18 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent);
|
if (node instanceof AST_ObjectIdentity) return symbol_in_lvalues(node, parent);
|
||||||
if (node instanceof AST_PropAccess) {
|
if (node instanceof AST_PropAccess) {
|
||||||
|
if (side_effects) return true;
|
||||||
var exp = node.expression;
|
var exp = node.expression;
|
||||||
return side_effects
|
if (exp instanceof AST_SymbolRef && is_arguments(exp.definition())) return true;
|
||||||
|| exp instanceof AST_SymbolRef && is_arguments(exp.definition())
|
if (compressor.option("unsafe")) {
|
||||||
|| !value_def && (in_try || !lhs_local)
|
if (is_undeclared_ref(exp) && global_names[exp.name]) return false;
|
||||||
&& !node.optional && exp.may_throw_on_access(compressor);
|
if (is_static_fn(exp)) return false;
|
||||||
|
}
|
||||||
|
if (!well_defined) return true;
|
||||||
|
if (value_def) return false;
|
||||||
|
if (!in_try && lhs_local) return false;
|
||||||
|
if (node.optional) return false;
|
||||||
|
return exp.may_throw_on_access(compressor);
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Spread) return true;
|
if (node instanceof AST_Spread) return true;
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
|
|
@ -2537,8 +2546,7 @@ merge(Compressor.prototype, {
|
||||||
}
|
}
|
||||||
if (parent instanceof AST_PropAccess) {
|
if (parent instanceof AST_PropAccess) {
|
||||||
var exp = parent.expression;
|
var exp = parent.expression;
|
||||||
if (exp === node) return find_stop_value(parent, level + 1);
|
return exp === node ? find_stop_value(parent, level + 1) : node;
|
||||||
return find_stop_expr(exp, find_stop_value, node, parent, level);
|
|
||||||
}
|
}
|
||||||
if (parent instanceof AST_Sequence) {
|
if (parent instanceof AST_Sequence) {
|
||||||
return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1);
|
return (parent.tail_node() === node ? find_stop_value : find_stop_unused)(parent, level + 1);
|
||||||
|
|
@ -2770,13 +2778,23 @@ merge(Compressor.prototype, {
|
||||||
|
|
||||||
function get_lvalues(expr) {
|
function get_lvalues(expr) {
|
||||||
var lvalues = new Dictionary();
|
var lvalues = new Dictionary();
|
||||||
if (expr instanceof AST_VarDef) lvalues.add(expr.name.name, lhs);
|
if (expr instanceof AST_VarDef) {
|
||||||
|
if (!expr.name.definition().fixed) well_defined = false;
|
||||||
|
lvalues.add(expr.name.name, lhs);
|
||||||
|
}
|
||||||
var find_arguments = scope.uses_arguments && !compressor.has_directive("use strict");
|
var find_arguments = scope.uses_arguments && !compressor.has_directive("use strict");
|
||||||
var scan_toplevel = scope instanceof AST_Toplevel;
|
var scan_toplevel = scope instanceof AST_Toplevel;
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
var value;
|
var value;
|
||||||
if (node instanceof AST_SymbolRef) {
|
if (node instanceof AST_SymbolRef) {
|
||||||
value = node.fixed_value() || node;
|
value = node.fixed_value();
|
||||||
|
if (!value) {
|
||||||
|
value = node;
|
||||||
|
var def = node.definition();
|
||||||
|
if (!def.undeclared && (def.assignments || !def.escaped || def.escaped.cross_scope)) {
|
||||||
|
well_defined = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (node instanceof AST_ObjectIdentity) {
|
} else if (node instanceof AST_ObjectIdentity) {
|
||||||
value = node;
|
value = node;
|
||||||
}
|
}
|
||||||
|
|
@ -2784,6 +2802,7 @@ merge(Compressor.prototype, {
|
||||||
if (find_arguments && node instanceof AST_Sub) {
|
if (find_arguments && node instanceof AST_Sub) {
|
||||||
scope.each_argname(function(argname) {
|
scope.each_argname(function(argname) {
|
||||||
if (!compressor.option("reduce_vars") || argname.definition().assignments) {
|
if (!compressor.option("reduce_vars") || argname.definition().assignments) {
|
||||||
|
if (!argname.definition().fixed) well_defined = false;
|
||||||
lvalues.add(argname.name, true);
|
lvalues.add(argname.name, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -4290,6 +4309,14 @@ merge(Compressor.prototype, {
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function is_static_fn(node) {
|
||||||
|
if (!(node instanceof AST_Dot)) return false;
|
||||||
|
var expr = node.expression;
|
||||||
|
if (!is_undeclared_ref(expr)) return false;
|
||||||
|
var static_fn = static_fns[expr.name];
|
||||||
|
return static_fn && (static_fn[node.property] || expr.name == "Math" && node.property == "random");
|
||||||
|
}
|
||||||
|
|
||||||
// Accomodate when compress option evaluate=false
|
// Accomodate when compress option evaluate=false
|
||||||
// as well as the common constant expressions !0 and -1
|
// as well as the common constant expressions !0 and -1
|
||||||
(function(def) {
|
(function(def) {
|
||||||
|
|
@ -4912,11 +4939,7 @@ merge(Compressor.prototype, {
|
||||||
if (global_pure_fns[expr.name]) return true;
|
if (global_pure_fns[expr.name]) return true;
|
||||||
if (this instanceof AST_New && global_pure_constructors[expr.name]) return true;
|
if (this instanceof AST_New && global_pure_constructors[expr.name]) return true;
|
||||||
}
|
}
|
||||||
if (expr instanceof AST_Dot && is_undeclared_ref(expr.expression)) {
|
if (is_static_fn(expr)) return true;
|
||||||
var static_fn = static_fns[expr.expression.name];
|
|
||||||
return static_fn && (static_fn[expr.property]
|
|
||||||
|| expr.expression.name == "Math" && expr.property == "random");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return compressor.option("annotations") && this.pure || !compressor.pure_funcs(this);
|
return compressor.option("annotations") && this.pure || !compressor.pure_funcs(this);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,7 @@ issue_3858: {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
|
||||||
|
|
@ -421,6 +421,7 @@ collapse_value: {
|
||||||
arrows: true,
|
arrows: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
|
||||||
|
|
@ -632,6 +632,7 @@ collapse_non_strict: {
|
||||||
collapse_rhs: {
|
collapse_rhs: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
|
||||||
|
|
@ -2264,6 +2264,7 @@ var_defs: {
|
||||||
properties: true,
|
properties: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -2486,6 +2487,7 @@ issue_1858: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -2907,6 +2909,7 @@ compound_assignment_2: {
|
||||||
issue_2187_1: {
|
issue_2187_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -4271,6 +4274,7 @@ issue_2436_14: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -4761,6 +4765,7 @@ unsafe_builtin: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|
@ -6965,6 +6970,7 @@ sequence_in_iife_2: {
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -6976,7 +6982,7 @@ sequence_in_iife_2: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "foo", b = 42;
|
var a = "foo", b = 42;
|
||||||
console.log(a, b = a);
|
console.log(b = a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: "foo foo"
|
expect_stdout: "foo foo"
|
||||||
}
|
}
|
||||||
|
|
@ -6988,6 +6994,7 @@ sequence_in_iife_3: {
|
||||||
passes: 2,
|
passes: 2,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -7092,6 +7099,7 @@ setter_side_effect: {
|
||||||
substitution_assign: {
|
substitution_assign: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(a, b) {
|
function f1(a, b) {
|
||||||
|
|
@ -7112,8 +7120,7 @@ substitution_assign: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1(a, b) {
|
function f1(a, b) {
|
||||||
f1 = a;
|
console.log(f1 = a, a);
|
||||||
console.log(a, a);
|
|
||||||
}
|
}
|
||||||
function f2(a, b) {
|
function f2(a, b) {
|
||||||
a = 1 + (b = a);
|
a = 1 + (b = a);
|
||||||
|
|
@ -7917,6 +7924,7 @@ issue_3744: {
|
||||||
assign_value_def: {
|
assign_value_def: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -7957,6 +7965,7 @@ join_vars_value_def: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -7996,6 +8005,7 @@ join_vars_value_def: {
|
||||||
var_value_def: {
|
var_value_def: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -8033,6 +8043,7 @@ var_value_def: {
|
||||||
mangleable_var: {
|
mangleable_var: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -8067,6 +8078,7 @@ mangleable_var: {
|
||||||
mangleable_assignment_1: {
|
mangleable_assignment_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -8098,6 +8110,7 @@ mangleable_assignment_1: {
|
||||||
mangleable_assignment_2: {
|
mangleable_assignment_2: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
@ -8939,6 +8952,8 @@ dot_non_local: {
|
||||||
issue_4806: {
|
issue_4806: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, o = {
|
var a, o = {
|
||||||
|
|
@ -8962,6 +8977,7 @@ issue_4806: {
|
||||||
issue_4852: {
|
issue_4852: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = "PASS";
|
var a = "PASS";
|
||||||
|
|
@ -9195,7 +9211,7 @@ issue_4918: {
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_4920: {
|
issue_4920_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
|
@ -9221,6 +9237,64 @@ issue_4920: {
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4920_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a = "PASS", b;
|
||||||
|
o[b = a];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a = "PASS", b;
|
||||||
|
o[b = a];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4920_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
var o = {
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a = "PASS", b;
|
||||||
|
o[b = a];
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
var o = {
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a = "PASS", b;
|
||||||
|
o[b = a];
|
||||||
|
log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4935: {
|
issue_4935: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
|
@ -9279,3 +9353,62 @@ inline_throw: {
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4977_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a = "PASS";
|
||||||
|
console.log(o.p, a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
a = "PASS";
|
||||||
|
console.log(o.p, a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4977_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, o = {
|
||||||
|
get p() {
|
||||||
|
return a = "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (console) {
|
||||||
|
var a = "FAIL";
|
||||||
|
console.log(o.p, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, o = {
|
||||||
|
get p() {
|
||||||
|
return a = "PASS";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (console) {
|
||||||
|
var a = "FAIL";
|
||||||
|
console.log(o.p, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ issue_1858: {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|
|
||||||
|
|
@ -727,7 +727,8 @@ side_effects_cascade_1: {
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a, b) {
|
function f(a, b) {
|
||||||
b.a = a = (a -= 42) < 0 ? 0 : a;
|
(a -= 42) < 0 && (a = 0),
|
||||||
|
b.a = a;
|
||||||
}
|
}
|
||||||
var m = {}, n = {};
|
var m = {}, n = {};
|
||||||
f(13, m),
|
f(13, m),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user