diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 39 | ||||
-rw-r--r-- | lib/scope.js | 4 |
2 files changed, 32 insertions, 11 deletions
diff --git a/lib/compress.js b/lib/compress.js index bb355423..d890caf7 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -319,6 +319,7 @@ merge(Compressor.prototype, { } else { def.fixed = false; } + def.recursive_refs = 0; def.references = []; def.should_replace = undefined; def.single_use = undefined; @@ -369,7 +370,7 @@ merge(Compressor.prototype, { return compressor.option("unused") && !def.scope.uses_eval && !def.scope.uses_with - && def.references.length == 1 + && def.references.length - def.recursive_refs == 1 && tw.loop_ids[def.id] === tw.in_loop; } @@ -621,7 +622,9 @@ merge(Compressor.prototype, { d.fixed = false; } else if (d.fixed) { value = this.fixed_value(); - if (value && ref_once(tw, compressor, d)) { + if (value instanceof AST_Lambda && recursive_ref(tw, d)) { + d.recursive_refs++; + } else if (value && ref_once(tw, compressor, d)) { d.single_use = value instanceof AST_Lambda || d.scope === this.scope && value.is_constant_expression(); } else { @@ -4670,17 +4673,18 @@ merge(Compressor.prototype, { if (fixed instanceof AST_Defun) { d.fixed = fixed = make_node(AST_Function, fixed, fixed); } - if (d.single_use && fixed instanceof AST_Function) { + var single_use = d.single_use; + if (single_use && fixed instanceof AST_Function) { if (d.scope !== self.scope && (!compressor.option("reduce_funcs") || d.escaped == 1 || fixed.inlined)) { - d.single_use = false; + single_use = false; } else if (recursive_ref(compressor, d)) { - d.single_use = false; + single_use = false; } else if (d.scope !== self.scope || d.orig[0] instanceof AST_SymbolFunarg) { - d.single_use = fixed.is_constant_expression(self.scope); - if (d.single_use == "f") { + single_use = fixed.is_constant_expression(self.scope); + if (single_use == "f") { var scope = self.scope; do { if (scope instanceof AST_Defun || scope instanceof AST_Function) { @@ -4690,9 +4694,24 @@ merge(Compressor.prototype, { } } } - if (d.single_use && fixed) { - var value = fixed.optimize(compressor); - return value === fixed ? fixed.clone(true) : value; + if (single_use && fixed) { + var value; + if (d.recursive_refs > 0 && fixed.name instanceof AST_SymbolDefun) { + value = fixed.clone(true); + var defun_def = value.name.definition(); + value.name = make_node(AST_SymbolLambda, value.name, value.name); + value.name.scope = value; + var lambda_def = value.def_function(value.name); + value.walk(new TreeWalker(function(node) { + if (node instanceof AST_SymbolRef && node.definition() === defun_def) { + node.thedef = lambda_def; + } + })); + } else { + value = fixed.optimize(compressor); + if (value === fixed) value = fixed.clone(true); + } + return value; } if (fixed && d.should_replace === undefined) { var init; diff --git a/lib/scope.js b/lib/scope.js index bbfa037c..bceec289 100644 --- a/lib/scope.js +++ b/lib/scope.js @@ -307,7 +307,9 @@ AST_Scope.DEFMETHOD("find_variable", function(name){ }); AST_Scope.DEFMETHOD("def_function", function(symbol){ - this.functions.set(symbol.name, this.def_variable(symbol)); + var def = this.def_variable(symbol); + this.functions.set(symbol.name, def); + return def; }); AST_Scope.DEFMETHOD("def_variable", function(symbol){ |