diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 81 |
1 files changed, 39 insertions, 42 deletions
diff --git a/lib/compress.js b/lib/compress.js index 0f9f0795..1be74033 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -477,14 +477,6 @@ merge(Compressor.prototype, { && !compressor.exposed(def) && !(def.init instanceof AST_LambdaExpression && def.init !== def.scope) && def.init; - if (def.fixed instanceof AST_LambdaDefinition && !all(def.references, function(ref) { - var scope = ref.scope.resolve(); - do { - if (def.scope === scope) return true; - } while (scope instanceof AST_LambdaExpression && (scope = scope.parent_scope.resolve())); - })) { - tw.defun_ids[def.id] = false; - } def.reassigned = 0; def.recursive_refs = 0; def.references = []; @@ -526,23 +518,25 @@ merge(Compressor.prototype, { var marker = tw.defun_ids[def.id]; if (!marker) return; var visited = tw.defun_visited[def.id]; - if (marker === tw.safe_ids) { - if (!visited) return def.fixed; - } else if (visited) { + if (marker === tw.safe_ids) return !visited && def.fixed; + if (visited) { def.init.enclosed.forEach(function(d) { if (def.init.variables.get(d.name) === d) return; if (!safe_to_read(tw, d)) d.fixed = false; }); - } else { - tw.defun_ids[def.id] = false; - } - } else { - if (!tw.in_loop) { - tw.defun_ids[def.id] = tw.safe_ids; - return def.fixed; + return; } - tw.defun_ids[def.id] = false; + } else if (!tw.in_loop) { + var scope = def.scope; + var s = tw.find_parent(AST_Scope); + do { + if (s === scope) { + tw.defun_ids[def.id] = tw.safe_ids; + return def.fixed; + } + } while (s instanceof AST_LambdaExpression && (s = s.parent_scope.resolve())); } + tw.defun_ids[def.id] = false; } function walk_defuns(tw, scope) { @@ -967,11 +961,11 @@ merge(Compressor.prototype, { }); }); def(AST_Call, function(tw, descend) { - tw.find_parent(AST_Scope).may_call_this(); - var exp = this.expression; + var node = this; + var exp = node.expression; if (exp instanceof AST_LambdaExpression) { - var iife = is_iife_single(this); - this.args.forEach(function(arg) { + var iife = is_iife_single(node); + node.args.forEach(function(arg) { arg.walk(tw); if (arg instanceof AST_Spread) iife = false; }); @@ -980,28 +974,28 @@ merge(Compressor.prototype, { if (iife) delete exp.reduce_vars; return true; } - if (exp instanceof AST_SymbolRef) { - var def = exp.definition(); - if (this.TYPE == "Call" && tw.in_boolean_context()) def.bool_fn++; - if (def.fixed instanceof AST_LambdaDefinition) { - var defun = mark_defun(tw, def); - if (defun) { - descend(); - defun.walk(tw); - return true; - } + var def = exp instanceof AST_SymbolRef && exp.definition(); + if (node.TYPE == "Call" && tw.in_boolean_context()) { + if (def) { + def.bool_fn++; + } else if (exp instanceof AST_Assign && exp.operator == "=" && exp.left instanceof AST_SymbolRef) { + exp.left.definition().bool_fn++; } - } else if (this.TYPE == "Call" - && exp instanceof AST_Assign - && exp.operator == "=" - && exp.left instanceof AST_SymbolRef - && tw.in_boolean_context()) { - exp.left.definition().bool_fn++; } - if (!this.optional) return; + if (def && def.fixed instanceof AST_LambdaDefinition) { + var defun = mark_defun(tw, def); + if (defun) { + descend(); + defun.walk(tw); + return true; + } + } else { + tw.find_parent(AST_Scope).may_call_this(); + } + if (!node.optional) return; exp.walk(tw); push(tw); - this.args.forEach(function(arg) { + node.args.forEach(function(arg) { arg.walk(tw); }); pop(tw); @@ -10911,7 +10905,10 @@ merge(Compressor.prototype, { single_use = false; } if (single_use) fixed.parent_scope = self.scope; - } else if (!fixed || !fixed.is_constant_expression() || fixed.drop_side_effect_free(compressor)) { + } else if (!fixed + || def.recursive_refs > 0 + || !fixed.is_constant_expression() + || fixed.drop_side_effect_free(compressor)) { single_use = false; } } |