fix corner case in reduce_vars & unused (#4465)

fixes #4464
This commit is contained in:
Alex Lam S.L
2020-12-26 08:52:16 +00:00
committed by GitHub
parent be1f5199f4
commit 94f3819dc6
3 changed files with 87 additions and 6 deletions

View File

@@ -363,6 +363,10 @@ merge(Compressor.prototype, {
return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg; return orig.length == 1 && orig[0] instanceof AST_SymbolFunarg;
} }
function is_funarg(def) {
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
}
function cross_scope(def, sym) { function cross_scope(def, sym) {
do { do {
if (def === sym) return false; if (def === sym) return false;
@@ -371,9 +375,9 @@ merge(Compressor.prototype, {
} }
function can_drop_symbol(ref, keep_lambda) { function can_drop_symbol(ref, keep_lambda) {
var orig = ref.definition().orig; var def = ref.definition();
if (ref.in_arg && (orig[0] instanceof AST_SymbolFunarg || orig[1] instanceof AST_SymbolFunarg)) return false; if (ref.in_arg && is_funarg(def)) return false;
return all(orig, function(sym) { return all(def.orig, function(sym) {
return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet
|| keep_lambda && sym instanceof AST_SymbolLambda); || keep_lambda && sym instanceof AST_SymbolLambda);
}); });
@@ -541,7 +545,8 @@ merge(Compressor.prototype, {
return compressor.option("unused") return compressor.option("unused")
&& !def.scope.pinned() && !def.scope.pinned()
&& def.single_use !== false && def.single_use !== false
&& def.references.length - def.recursive_refs == 1; && def.references.length - def.recursive_refs == 1
&& !(is_funarg(def) && def.scope.uses_arguments);
} }
function is_immutable(value) { function is_immutable(value) {
@@ -9331,7 +9336,7 @@ merge(Compressor.prototype, {
single_use = false; single_use = false;
} else if (fixed.name && fixed.name.definition() !== def) { } else if (fixed.name && fixed.name.definition() !== def) {
single_use = false; single_use = false;
} else if (fixed.parent_scope !== self.scope.resolve() || def.orig[0] instanceof AST_SymbolFunarg) { } else if (fixed.parent_scope !== self.scope.resolve() || is_funarg(def)) {
single_use = fixed.is_constant_expression(self.scope); single_use = fixed.is_constant_expression(self.scope);
if (single_use == "f") { if (single_use == "f") {
var scope = self.scope; var scope = self.scope;
@@ -9414,7 +9419,7 @@ merge(Compressor.prototype, {
if (fixed && (local || def.should_replace !== false)) { if (fixed && (local || def.should_replace !== false)) {
var init; var init;
if (fixed instanceof AST_This) { if (fixed instanceof AST_This) {
if (!(def.orig[0] instanceof AST_SymbolFunarg) && same_scope(def)) { if (!is_funarg(def) && same_scope(def)) {
init = fixed; init = fixed;
} }
} else { } else {

View File

@@ -3125,3 +3125,74 @@ issue_4413: {
} }
expect_stdout: "0" expect_stdout: "0"
} }
issue_4464_1: {
options = {
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var a = function() {};
return [ arguments, a ];
}
console.log(typeof f()[1]);
}
expect: {
function f(a) {
a = function() {};
return [ arguments, a ];
}
console.log(typeof f()[1]);
}
expect_stdout: "function"
}
issue_4464_2: {
options = {
reduce_vars: true,
unused: true,
}
input: {
function f(a) {
var a = function() {};
return [ arguments, a ];
}
console.log(typeof f(42)[0][0]);
}
expect: {
function f(a) {
a = function() {};
return [ arguments, a ];
}
console.log(typeof f(42)[0][0]);
}
expect_stdout: "function"
}
issue_4464_3: {
options = {
reduce_vars: true,
unused: true,
}
input: {
(function a(a) {
var a = function() {};
return [ arguments[0], a ];
})(42).forEach(function(b) {
console.log(typeof b);
});
}
expect: {
(function(a) {
a = function() {};
return [ arguments[0], a ];
})(42).forEach(function(b) {
console.log(typeof b);
});
}
expect_stdout: [
"function",
"function",
]
}

View File

@@ -352,6 +352,11 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
} }
} }
} }
else if (node instanceof U.AST_Spread) {
node.start._permute++;
CHANGED = true;
return node.expression;
}
else if (node instanceof U.AST_Switch) { else if (node instanceof U.AST_Switch) {
var expr = [ var expr = [
node.expression, // switch expression node.expression, // switch expression