Skip to content

Commit

Permalink
fix corner case in unused (#5867)
Browse files Browse the repository at this point in the history
fixes #5866
  • Loading branch information
alexlamsl authored Jun 26, 2024
1 parent ce8ef52 commit ed36c1e
Show file tree
Hide file tree
Showing 2 changed files with 253 additions and 2 deletions.
21 changes: 19 additions & 2 deletions lib/compress.js
Original file line number Diff line number Diff line change
Expand Up @@ -8129,6 +8129,7 @@ Compressor.prototype.compress = function(node) {
}

function trim_destructured(node, value, process, drop, root) {
var unwind = true;
var trimmer = new TreeTransformer(function(node) {
if (node instanceof AST_DefaultValue) {
if (!(compressor.option("default_values") && value && value.is_defined(compressor))) {
Expand All @@ -8146,21 +8147,27 @@ Compressor.prototype.compress = function(node) {
}
if (node instanceof AST_DestructuredArray) {
var save_drop = drop;
var save_unwind = unwind;
var save_value = value;
if (value instanceof AST_SymbolRef) {
drop = false;
value = value.fixed_value();
}
var native, values;
var last_side_effects, native, values;
if (value instanceof AST_Array) {
native = true;
values = value.elements;
if (save_unwind) for (last_side_effects = values.length; --last_side_effects >= 0;) {
if (values[last_side_effects].has_side_effects(compressor)) break;
}
} else {
native = value && value.is_string(compressor);
values = false;
last_side_effects = node.elements.length;
}
var elements = [], newValues = drop && [], pos = 0;
node.elements.forEach(function(element, index) {
if (save_unwind) unwind = index >= last_side_effects;
value = values && values[index];
if (value instanceof AST_Hole) {
value = null;
Expand Down Expand Up @@ -8203,6 +8210,7 @@ Compressor.prototype.compress = function(node) {
}
}
value = save_value;
unwind = save_unwind;
drop = save_drop;
if (values && newValues) {
fill_holes(value, newValues);
Expand All @@ -8218,6 +8226,7 @@ Compressor.prototype.compress = function(node) {
return null;
case 1:
if (!drop) break;
if (!unwind) break;
if (node === root) break;
var sym = elements[0];
if (sym.has_side_effects(compressor)) break;
Expand All @@ -8236,16 +8245,19 @@ Compressor.prototype.compress = function(node) {
}
if (node instanceof AST_DestructuredObject) {
var save_drop = drop;
var save_unwind = unwind;
var save_value = value;
if (value instanceof AST_SymbolRef) {
drop = false;
value = value.fixed_value();
}
var prop_keys, prop_map, values;
var last_side_effects, prop_keys, prop_map, values;
if (value instanceof AST_Object) {
last_side_effects = -1;
prop_keys = [];
prop_map = new Dictionary();
values = value.properties.map(function(prop, index) {
if (save_unwind && prop.has_side_effects(compressor)) last_side_effects = index;
prop = prop.clone();
if (prop instanceof AST_Spread) {
prop_map = false;
Expand All @@ -8261,6 +8273,8 @@ Compressor.prototype.compress = function(node) {
}
return prop;
});
} else {
last_side_effects = node.properties.length;
}
if (node.rest) {
value = false;
Expand All @@ -8283,6 +8297,7 @@ Compressor.prototype.compress = function(node) {
return key;
}).forEach(function(key, index) {
var prop = node.properties[index], trimmed;
if (save_unwind) unwind = index >= last_side_effects;
if (key instanceof AST_Node) {
drop = false;
value = false;
Expand Down Expand Up @@ -8323,6 +8338,7 @@ Compressor.prototype.compress = function(node) {
}
});
value = save_value;
unwind = save_unwind;
drop = save_drop;
if (drop_keys && prop_keys) {
value = value.clone();
Expand Down Expand Up @@ -8357,6 +8373,7 @@ Compressor.prototype.compress = function(node) {
return null;
case 1:
if (!drop) break;
if (!unwind) break;
if (node === root) break;
var prop = properties[0];
if (prop.key instanceof AST_Node) break;
Expand Down
234 changes: 234 additions & 0 deletions test/compress/destructured.js
Original file line number Diff line number Diff line change
Expand Up @@ -4007,3 +4007,237 @@ issue_5854_2: {
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_1: {
options = {
unused: true,
}
input: {
var a = {};
var { p: { q: b } } = {
p: a,
r: a.q = "PASS",
};
console.log(b);
}
expect: {
var a = {};
var { q: b } = {
p: a,
r: a.q = "PASS",
}.p;
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_2: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
({ p: { q: b } } = {
p: a,
r: a.q = "PASS",
});
console.log(b);
}
expect: {
var b, a = {};
({ q: b } = {
p: a,
r: a.q = "PASS",
}.p);
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_3: {
options = {
unused: true,
}
input: {
var a = {};
var [ { p: b } ] = [ a, a.p = "PASS" ];
console.log(b);
}
expect: {
var a = {};
var { p: b } = [ a, a.p = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_4: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
[ { p: b } ] = [ a, a.p = "PASS" ];
console.log(b);
}
expect: {
var b, a = {};
({ p: b } = [ a, a.p = "PASS" ][0]);
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_5: {
options = {
unused: true,
}
input: {
var a = [];
var [ [ b ] ] = [ a, a[0] = "PASS" ];
console.log(b);
}
expect: {
var a = [];
var [ b ] = [ a, a[0] = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_6: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = [], b;
[ [ b ] ] = [ a, a[0] = "PASS" ];
console.log(b);
}
expect: {
var b, a = [];
[ b ] = [ a, a[0] = "PASS" ][0];
console.log(b);
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_7: {
options = {
unused: true,
}
input: {
var a = {};
var [ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var a = {};
var [ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_8: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b, c;
[ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var b, c, a = {};
[ { p: b }, c ] = [ a, a.p = {} ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_9: {
options = {
unused: true,
}
input: {
var a = {};
var [ b, { p: c } ] = [ a.p = {}, a ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var a = {};
var [ b, c ] = [ a.p = {}, a.p ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_10: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b, c;
[ b, { p: c } ] = [ a.p = {}, a ];
console.log(b === c ? "PASS" : "FAIL");
}
expect: {
var b, c, a = {};
[ b, c ] = [ a.p = {}, a.p ];
console.log(b === c ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_11: {
options = {
unused: true,
}
input: {
var a = {};
var { p: { q: b } } = { p: a = { q: {} } };
console.log(a.q === b ? "PASS" : "FAIL");
}
expect: {
var a = {};
var b = { p: (a = { q: {} }).q }.p;
console.log(a.q === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

issue_5866_12: {
options = {
side_effects: true,
unused: true,
}
input: {
var a = {}, b;
({ p: { q: b } } = { p: a = { q: {} } });
console.log(a.q === b ? "PASS" : "FAIL");
}
expect: {
var b, a = {};
b = { p: (a = { q: {} }).q }.p;
console.log(a.q === b ? "PASS" : "FAIL");
}
expect_stdout: "PASS"
node_version: ">=6"
}

0 comments on commit ed36c1e

Please sign in to comment.