fix corner case in collapse_vars (#4896)

fixes #4895
This commit is contained in:
Alex Lam S.L
2021-05-02 11:23:18 +01:00
committed by GitHub
parent fb03561799
commit 4114431eec
2 changed files with 33 additions and 6 deletions

View File

@@ -1886,8 +1886,7 @@ merge(Compressor.prototype, {
if (is_lhs(node, multi_replacer.parent())) return node; if (is_lhs(node, multi_replacer.parent())) return node;
var ref = rvalue.clone(); var ref = rvalue.clone();
value_def.references.push(ref); value_def.references.push(ref);
if (abort && candidate instanceof AST_Assign if (abort && candidate instanceof AST_Assign && remaining_refs(def) > 1) {
&& def.references.length - def.replaced - (assignments[def.name] || 0) > 1) {
return make_node(AST_Assign, candidate, { return make_node(AST_Assign, candidate, {
operator: "=", operator: "=",
left: node, left: node,
@@ -2281,7 +2280,9 @@ merge(Compressor.prototype, {
if (!(lhs instanceof AST_Destructured)) candidates.push(hit_stack.slice()); if (!(lhs instanceof AST_Destructured)) candidates.push(hit_stack.slice());
extract_candidates(lhs); extract_candidates(lhs);
extract_candidates(expr.right); extract_candidates(expr.right);
if (lhs instanceof AST_SymbolRef) assignments[lhs.name] = (assignments[lhs.name] || 0) + 1; if (lhs instanceof AST_SymbolRef && expr.operator == "=") {
assignments[lhs.name] = (assignments[lhs.name] || 0) + 1;
}
} else if (expr instanceof AST_Await) { } else if (expr instanceof AST_Await) {
extract_candidates(expr.expression, unused); extract_candidates(expr.expression, unused);
} else if (expr instanceof AST_Binary) { } else if (expr instanceof AST_Binary) {
@@ -2584,6 +2585,10 @@ merge(Compressor.prototype, {
return value_def = def; return value_def = def;
} }
function remaining_refs(def) {
return def.references.length - def.replaced - (assignments[def.name] || 0);
}
function get_lhs(expr) { function get_lhs(expr) {
if (expr instanceof AST_Assign) { if (expr instanceof AST_Assign) {
var lhs = expr.left; var lhs = expr.left;
@@ -2592,7 +2597,7 @@ merge(Compressor.prototype, {
var def = lhs.definition(); var def = lhs.definition();
if (scope.uses_arguments && is_funarg(def)) return lhs; if (scope.uses_arguments && is_funarg(def)) return lhs;
if (compressor.exposed(def)) return lhs; if (compressor.exposed(def)) return lhs;
remaining = def.references.length - def.replaced - (assignments[def.name] || 0); remaining = remaining_refs(def);
if (def.fixed && lhs.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { if (def.fixed && lhs.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) {
return ref.fixed === lhs.fixed; return ref.fixed === lhs.fixed;
}).length - 1); }).length - 1);
@@ -2608,7 +2613,7 @@ merge(Compressor.prototype, {
if (!member(lhs, def.orig)) return; if (!member(lhs, def.orig)) return;
if (scope.uses_arguments && is_funarg(def)) return; if (scope.uses_arguments && is_funarg(def)) return;
var declared = def.orig.length - def.eliminated - (declare_only[def.name] || 0); var declared = def.orig.length - def.eliminated - (declare_only[def.name] || 0);
remaining = def.references.length - def.replaced - (assignments[def.name] || 0); remaining = remaining_refs(def);
if (def.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) { if (def.fixed) remaining = Math.min(remaining, def.references.filter(function(ref) {
if (!ref.fixed) return true; if (!ref.fixed) return true;
if (!ref.fixed.assigns) return true; if (!ref.fixed.assigns) return true;

View File

@@ -8560,7 +8560,7 @@ issue_4047_1: {
expect: { expect: {
var b = 1; var b = 1;
var a; var a;
console.log((a = --b + ((a = 0) !== typeof A), +void ((a >>= 0) && console.log("PASS")))); console.log((a = --b + (0 !== typeof A), +void ((a >>= 0) && console.log("PASS"))));
} }
expect_stdout: [ expect_stdout: [
"PASS", "PASS",
@@ -9085,3 +9085,25 @@ issue_4891: {
"0", "0",
] ]
} }
issue_4895: {
options = {
collapse_vars: true,
toplevel: true,
}
input: {
var a, b;
(function f() {
a = 42;
})();
console.log((b = a) || b, b += 0);
}
expect: {
var a, b;
(function f() {
a = 42;
})();
console.log((b = a) || b, b += 0);
}
expect_stdout: "42 42"
}