diff options
-rw-r--r-- | lib/compress.js | 13 | ||||
-rw-r--r-- | test/compress/functions.js | 86 |
2 files changed, 96 insertions, 3 deletions
diff --git a/lib/compress.js b/lib/compress.js index 79614864..94b76670 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5828,14 +5828,17 @@ merge(Compressor.prototype, { && !(fn.name && fn instanceof AST_Function) && (value = can_flatten_body(stat)) && (exp === fn - || !recursive_ref(compressor, def = exp.definition) && fn.is_constant_expression(exp.scope)) + || !recursive_ref(compressor, def = exp.definition()) && fn.is_constant_expression(exp.scope)) && !fn.contains_this()) { if (can_substitute_directly()) { var args = self.args.slice(); args.push(value.clone(true).transform(new TreeTransformer(function(node) { if (node instanceof AST_SymbolRef) { var def = node.definition(); - if (fn.variables.get(node.name) !== def) return node; + if (fn.variables.get(node.name) !== def) { + if (exp !== fn) def.references.push(node); + return node; + } var index = resolve_index(def); var arg = args[index]; if (!arg) return make_node(AST_Undefined, self); @@ -5931,10 +5934,14 @@ merge(Compressor.prototype, { function can_substitute_directly() { if (compressor.option("inline") <= 1 && fn.argnames.length) return; - if (fn.variables.size() > fn.argnames.length + 1) return; + var var_count = fn.variables.size() - 1; + if (var_count > fn.argnames.length) return; + var var_names = []; if (!all(fn.argnames, function(argname) { + push_uniq(var_names, argname.name); return argname.definition().references.length < 2; })) return; + if (var_count > var_names.length) return; var abort = false; var begin; var in_order = []; diff --git a/test/compress/functions.js b/test/compress/functions.js index 4a192d59..c1522e2e 100644 --- a/test/compress/functions.js +++ b/test/compress/functions.js @@ -3928,3 +3928,89 @@ preserve_binding_2: { } expect_stdout: "PASS" } + +issue_3770: { + options = { + inline: true, + reduce_vars: true, + side_effects: true, + unused: true, + } + input: { + (function() { + function f(a, a) { + var b = function() { + return a || "PASS"; + }(); + console.log(b); + } + f("FAIL"); + })(); + } + expect: { + (function() { + b = a || "PASS", + console.log(b); + var a, b; + })(); + } + expect_stdout: "PASS" +} + +issue_3771: { + options = { + inline: true, + reduce_vars: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + try { + function f(a) { + var a = f(1234); + } + f(); + } catch (e) { + console.log("PASS"); + } + } + expect: { + try { + (function f(a) { + f(); + })(); + } catch (e) { + console.log("PASS"); + } + } + expect_stdout: "PASS" +} + +issue_3772: { + options = { + collapse_vars: true, + dead_code: true, + inline: true, + reduce_vars: true, + side_effects: true, + toplevel: true, + unused: true, + } + input: { + var a = "PASS"; + function f() { + return a; + } + var b = f(); + function g() { + console.log(f()); + } + g(); + } + expect: { + var a = "PASS"; + console.log(a); + } + expect_stdout: "PASS" +} |