fix corner cases in reduce_vars & unused (#3955)

fixes #3953
fixes #3956
fixes #3957
This commit is contained in:
Alex Lam S.L
2020-06-05 11:51:21 +01:00
committed by GitHub
parent fbc9d8009b
commit eb481cee8c
4 changed files with 124 additions and 10 deletions

View File

@@ -495,6 +495,12 @@ merge(Compressor.prototype, {
});
}
function to_value(def, sym, fixed) {
if (fixed instanceof AST_Node) return fixed;
if (typeof fixed == "function") return fixed();
return make_node(AST_Undefined, sym);
}
function ref_once(compressor, def) {
return compressor.option("unused")
&& !def.scope.pinned()
@@ -576,8 +582,9 @@ merge(Compressor.prototype, {
var eq = node.operator == "=";
var value = eq ? node.right : node;
if (is_modified(compressor, tw, node, value, 0)) return;
var safe = eq || safe_to_read(tw, d);
node.right.walk(tw);
if ((eq || safe_to_read(tw, d)) && safe_to_assign(tw, d)) {
if (safe && safe_to_assign(tw, d)) {
push_ref(d, sym);
mark(tw, d);
if (eq) {
@@ -587,9 +594,8 @@ merge(Compressor.prototype, {
return node.right;
};
} else {
if (fixed == null) fixed = make_node(AST_Undefined, d.orig[0]);
sym.fixed = d.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed();
var value = to_value(d, sym, fixed);
return value && make_node(AST_Binary, node, {
operator: node.operator.slice(0, -1),
left: value,
@@ -597,7 +603,7 @@ merge(Compressor.prototype, {
});
};
}
sym.fixed.assigns = eq || !fixed.assigns ? [] : fixed.assigns.slice();
sym.fixed.assigns = eq || !fixed || !fixed.assigns ? [] : fixed.assigns.slice();
sym.fixed.assigns.push(node);
} else {
sym.walk(tw);
@@ -740,8 +746,8 @@ merge(Compressor.prototype, {
fn.argnames.forEach(function(arg, i) {
var d = arg.definition();
if (d.fixed === undefined && (!fn.uses_arguments || tw.has_directive("use strict"))) {
tw.loop_ids[d.id] = tw.in_loop;
mark(tw, d);
tw.loop_ids[d.id] = tw.in_loop;
var value = iife.args[i];
d.fixed = function() {
var j = fn.argnames.indexOf(arg);
@@ -870,9 +876,8 @@ merge(Compressor.prototype, {
if (safe_to_read(tw, d) && safe_to_assign(tw, d)) {
push_ref(d, exp);
mark(tw, d);
if (fixed == null) fixed = make_node(AST_Undefined, d.orig[0]);
d.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed();
var value = to_value(d, exp, fixed);
return value && make_node(AST_Binary, node, {
operator: node.operator.slice(0, -1),
left: make_node(AST_UnaryPrefix, node, {
@@ -884,19 +889,19 @@ merge(Compressor.prototype, {
})
});
};
d.fixed.assigns = fixed.assigns ? fixed.assigns.slice() : [];
d.fixed.assigns = fixed && fixed.assigns ? fixed.assigns.slice() : [];
d.fixed.assigns.push(node);
if (node instanceof AST_UnaryPrefix) {
exp.fixed = d.fixed;
} else {
exp.fixed = function() {
var value = fixed instanceof AST_Node ? fixed : fixed();
var value = to_value(d, exp, fixed);
return value && make_node(AST_UnaryPrefix, node, {
operator: "+",
expression: value
});
};
exp.fixed.assigns = fixed.assigns;
exp.fixed.assigns = fixed && fixed.assigns;
}
} else {
exp.walk(tw);
@@ -4429,6 +4434,7 @@ merge(Compressor.prototype, {
if (!drop_vars || sym.id in in_use_ids) {
if (def.value && indexOf_assign(sym, def) < 0) {
def.value = def.value.drop_side_effect_free(compressor);
if (def.value) def.value.tail_node().write_only = false;
}
var old_def, var_defs = var_defs_by_id.get(sym.id);
if (!def.value) {