enhance reduce_vars & unused (#4890)
This commit is contained in:
@@ -610,6 +610,11 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function is_immutable(value) {
|
function is_immutable(value) {
|
||||||
if (!value) return false;
|
if (!value) return false;
|
||||||
|
if (value instanceof AST_Assign) {
|
||||||
|
var op = value.operator;
|
||||||
|
return op == "=" ? is_immutable(value.right) : !lazy_op[op.slice(0, -1)];
|
||||||
|
}
|
||||||
|
if (value instanceof AST_Sequence) return is_immutable(value.tail_node());
|
||||||
return value.is_constant() || is_lambda(value) || value instanceof AST_ObjectIdentity;
|
return value.is_constant() || is_lambda(value) || value instanceof AST_ObjectIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -901,6 +906,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function walk_assign() {
|
function walk_assign() {
|
||||||
right.walk(tw);
|
right.walk(tw);
|
||||||
|
var modified = is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d));
|
||||||
scan_declaration(tw, compressor, left, function() {
|
scan_declaration(tw, compressor, left, function() {
|
||||||
return node.right;
|
return node.right;
|
||||||
}, function(sym, fixed, walk) {
|
}, function(sym, fixed, walk) {
|
||||||
@@ -911,10 +917,7 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
var d = sym.definition();
|
var d = sym.definition();
|
||||||
d.assignments++;
|
d.assignments++;
|
||||||
if (fixed
|
if (fixed && !modified && !sym.in_arg && safe_to_assign(tw, d)) {
|
||||||
&& !is_modified(compressor, tw, node, right, 0, is_immutable(right), recursive_ref(tw, d))
|
|
||||||
&& !sym.in_arg
|
|
||||||
&& safe_to_assign(tw, d)) {
|
|
||||||
push_ref(d, sym);
|
push_ref(d, sym);
|
||||||
mark(tw, d);
|
mark(tw, d);
|
||||||
if (d.single_use && left instanceof AST_Destructured) d.single_use = false;
|
if (d.single_use && left instanceof AST_Destructured) d.single_use = false;
|
||||||
@@ -6299,18 +6302,13 @@ merge(Compressor.prototype, {
|
|||||||
var drop_sym = is_var ? can_drop_symbol(def.name) : is_safe_lexical(sym);
|
var drop_sym = is_var ? can_drop_symbol(def.name) : is_safe_lexical(sym);
|
||||||
if (!drop_sym || !drop_vars || sym.id in in_use_ids) {
|
if (!drop_sym || !drop_vars || sym.id in in_use_ids) {
|
||||||
if (value && indexOf_assign(sym, def) < 0) {
|
if (value && indexOf_assign(sym, def) < 0) {
|
||||||
var write_only = value.write_only;
|
|
||||||
value = value.drop_side_effect_free(compressor);
|
value = value.drop_side_effect_free(compressor);
|
||||||
if (def.value !== value) {
|
|
||||||
if (value) {
|
if (value) {
|
||||||
AST_Node.warn("Side effects in last use of variable {name} [{file}:{line},{col}]", template(def.name));
|
AST_Node.warn("Side effects in last use of variable {name} [{file}:{line},{col}]", template(def.name));
|
||||||
side_effects.push(value);
|
side_effects.push(value);
|
||||||
}
|
}
|
||||||
value = null;
|
value = null;
|
||||||
trim_defns.push(def);
|
trim_defns.push(def);
|
||||||
} else if (value.write_only !== write_only) {
|
|
||||||
value.write_only = write_only;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
var old_def;
|
var old_def;
|
||||||
if (!value && !(node instanceof AST_Let)) {
|
if (!value && !(node instanceof AST_Let)) {
|
||||||
|
|||||||
@@ -6013,7 +6013,7 @@ issue_4823: {
|
|||||||
console.log(typeof function() {
|
console.log(typeof function() {
|
||||||
{
|
{
|
||||||
function f() {}
|
function f() {}
|
||||||
arguments = f();
|
f();
|
||||||
var arguments = function() {};
|
var arguments = function() {};
|
||||||
}
|
}
|
||||||
return f && arguments;
|
return f && arguments;
|
||||||
@@ -6040,3 +6040,171 @@ drop_unused_self_reference: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_1: {
|
||||||
|
options = {
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
a.p = a;
|
||||||
|
b = a = function() {};
|
||||||
|
b.q = b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_1_toplevel: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
a.p = a;
|
||||||
|
var b = a = function() {};
|
||||||
|
b.q = b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
b.p = a;
|
||||||
|
b = a = function() {};
|
||||||
|
a.q = b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_2_toplevel: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
b.p = a;
|
||||||
|
var b = a = function() {};
|
||||||
|
a.q = b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
a.p = b;
|
||||||
|
b = a = function() {};
|
||||||
|
b.q = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_3_toplevel: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
a.p = b;
|
||||||
|
var b = a = function() {};
|
||||||
|
b.q = a;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_4: {
|
||||||
|
options = {
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
b.p = b;
|
||||||
|
b = a = function() {};
|
||||||
|
a.q = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_4_toplevel: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
b.p = b;
|
||||||
|
var b = a = function() {};
|
||||||
|
a.q = a;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -2653,7 +2653,9 @@ issue_4019: {
|
|||||||
try {
|
try {
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
} catch (o) {}
|
} catch (o) {}
|
||||||
}, o = (console.log(o.length), ++o);
|
};
|
||||||
|
console.log(o.length),
|
||||||
|
++o;
|
||||||
}
|
}
|
||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user