diff options
-rw-r--r-- | lib/compress.js | 17 | ||||
-rw-r--r-- | test/compress/drop-unused.js | 71 | ||||
-rw-r--r-- | test/reduce.js | 5 |
3 files changed, 87 insertions, 6 deletions
diff --git a/lib/compress.js b/lib/compress.js index ae66d140..97b6149b 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -363,6 +363,10 @@ merge(Compressor.prototype, { 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) { do { if (def === sym) return false; @@ -371,9 +375,9 @@ merge(Compressor.prototype, { } function can_drop_symbol(ref, keep_lambda) { - var orig = ref.definition().orig; - if (ref.in_arg && (orig[0] instanceof AST_SymbolFunarg || orig[1] instanceof AST_SymbolFunarg)) return false; - return all(orig, function(sym) { + var def = ref.definition(); + if (ref.in_arg && is_funarg(def)) return false; + return all(def.orig, function(sym) { return !(sym instanceof AST_SymbolConst || sym instanceof AST_SymbolLet || keep_lambda && sym instanceof AST_SymbolLambda); }); @@ -541,7 +545,8 @@ merge(Compressor.prototype, { return compressor.option("unused") && !def.scope.pinned() && 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) { @@ -9331,7 +9336,7 @@ merge(Compressor.prototype, { single_use = false; } else if (fixed.name && fixed.name.definition() !== def) { 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); if (single_use == "f") { var scope = self.scope; @@ -9414,7 +9419,7 @@ merge(Compressor.prototype, { if (fixed && (local || def.should_replace !== false)) { var init; if (fixed instanceof AST_This) { - if (!(def.orig[0] instanceof AST_SymbolFunarg) && same_scope(def)) { + if (!is_funarg(def) && same_scope(def)) { init = fixed; } } else { diff --git a/test/compress/drop-unused.js b/test/compress/drop-unused.js index 3feb0183..ae1a6e5b 100644 --- a/test/compress/drop-unused.js +++ b/test/compress/drop-unused.js @@ -3125,3 +3125,74 @@ issue_4413: { } 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", + ] +} diff --git a/test/reduce.js b/test/reduce.js index f6b54141..48030b0f 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -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) { var expr = [ node.expression, // switch expression |