fix corner case in reduce_vars (#4563)

fixes #4562
This commit is contained in:
Alex Lam S.L
2021-01-17 17:47:07 +00:00
committed by GitHub
parent 8d21516623
commit e616916de5
4 changed files with 41 additions and 18 deletions

View File

@@ -620,7 +620,7 @@ merge(Compressor.prototype, {
var save = fixed;
if (save) fixed = function() {
var value = save();
return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node.name;
return is_undefined(value) ? make_sequence(node, [ value, node.value ]) : node;
};
node.name.walk(scanner);
fixed = save;
@@ -646,7 +646,7 @@ merge(Compressor.prototype, {
var value = save();
return value instanceof AST_Array ? make_node(AST_Array, node, {
elements: value.elements.slice(node.elements.length),
}) : node.rest;
}) : node;
};
node.rest.walk(scanner);
}

View File

@@ -646,3 +646,20 @@ issue_4544_2: {
expect_stdout: "PASS"
node_version: ">=6"
}
issue_4562: {
options = {
evaluate: true,
reduce_vars: true,
rests: true,
unsafe: true,
}
input: {
console.log((([ ...[ a ] ]) => a)("foo"));
}
expect: {
console.log((([ a ]) => a)("foo"));
}
expect_stdout: "f"
node_version: ">=6"
}

View File

@@ -1,14 +1,12 @@
// (beautified)
try {
1 in 0;
} catch ({
message: message
}) {
} catch (message) {
console.log(message);
}
// output: Cannot use 'in' operator to search for '1' in 0
// output: TypeError: Cannot use 'in' operator to search for '1' in 0
//
// minify: Cannot use 'in' operator to search for '0' in 0
// minify: TypeError: Cannot use 'in' operator to search for '0' in 0
//
// options: {
// "mangle": false

View File

@@ -104,15 +104,14 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
// quick ignores
if (node instanceof U.AST_Accessor) return;
if (node instanceof U.AST_Destructured) return;
if (node instanceof U.AST_Directive) return;
if (!in_list && node instanceof U.AST_EmptyStatement) return;
if (node instanceof U.AST_Label) return;
if (node instanceof U.AST_LabelRef) return;
if (!in_list && node instanceof U.AST_SymbolDeclaration) return;
if (node instanceof U.AST_Toplevel) return;
var parent = tt.parent();
if (node instanceof U.AST_SymbolFunarg && parent instanceof U.AST_Accessor) return;
if (!in_list && parent.rest !== node && node instanceof U.AST_SymbolDeclaration) return;
// ensure that the _permute prop is a number.
// can not use `node.start._permute |= 0;` as it will erase fractional part.
@@ -124,6 +123,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
// ignore lvalues
if (parent instanceof U.AST_Assign && parent.left === node) return;
if (parent instanceof U.AST_DefaultValue && parent.name === node) return;
if (parent instanceof U.AST_DestructuredKeyVal && parent.value === node) return;
if (parent instanceof U.AST_Unary && parent.expression === node) switch (parent.operator) {
case "++":
@@ -229,6 +229,23 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
CHANGED = true;
return node.name;
}
else if (node instanceof U.AST_DestructuredArray) {
var expr = node.elements[0];
if (expr && !(expr instanceof U.AST_Hole)) {
node.start._permute++;
CHANGED = true;
return expr;
}
}
else if (node instanceof U.AST_DestructuredObject) {
// first property's value
var expr = node.properties[0];
if (expr) {
node.start._permute++;
CHANGED = true;
return expr.value;
}
}
else if (node instanceof U.AST_Defun) {
switch (((node.start._permute += step) * steps | 0) % 2) {
case 0:
@@ -443,15 +460,6 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
CHANGED = true;
return List.skip;
}
// skip element/property from (destructured) array/object
if (parent instanceof U.AST_Array
|| parent instanceof U.AST_Destructured
|| parent instanceof U.AST_Object) {
node.start._permute++;
CHANGED = true;
return List.skip;
}
} else if (parent.rest === node) {
node.start._permute++;
CHANGED = true;