diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/lib/compress.js b/lib/compress.js index 696e2056..8bbbc3f6 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -245,7 +245,8 @@ merge(Compressor.prototype, { if (node instanceof AST_SymbolRef) { var d = node.definition(); d.references.push(node); - if (!d.fixed || isModified(node, 0) || !is_safe(d)) { + if (!d.fixed || !is_safe(d) + || is_modified(node, 0, d.fixed instanceof AST_Lambda)) { d.fixed = false; } } @@ -261,6 +262,21 @@ merge(Compressor.prototype, { d.fixed = false; } } + if (node instanceof AST_Defun) { + var d = node.name.definition(); + if (!toplevel && d.global || is_safe(d)) { + d.fixed = false; + } else { + d.fixed = node; + mark_as_safe(d); + } + var save_ids = safe_ids; + safe_ids = []; + push(); + descend(); + safe_ids = save_ids; + return true; + } var iife; if (node instanceof AST_Function && (iife = tw.parent()) instanceof AST_Call @@ -344,13 +360,13 @@ merge(Compressor.prototype, { def.should_replace = undefined; } - function isModified(node, level) { + function is_modified(node, level, func) { var parent = tw.parent(level); if (isLHS(node, parent) - || parent instanceof AST_Call && parent.expression === node) { + || !func && parent instanceof AST_Call && parent.expression === node) { return true; } else if (parent instanceof AST_PropAccess && parent.expression === node) { - return isModified(parent, level + 1); + return !func && is_modified(parent, level + 1); } } }); @@ -1307,14 +1323,7 @@ merge(Compressor.prototype, { def(AST_Statement, function(){ throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start)); }); - // XXX: AST_Accessor and AST_Function both inherit from AST_Scope, - // which itself inherits from AST_Statement; however, they aren't - // really statements. This could bite in other places too. :-( - // Wish JS had multiple inheritance. - def(AST_Accessor, function(){ - throw def; - }); - def(AST_Function, function(){ + def(AST_Lambda, function(){ throw def; }); function ev(node, compressor) { @@ -2590,6 +2599,24 @@ merge(Compressor.prototype, { OPT(AST_Call, function(self, compressor){ var exp = self.expression; + if (compressor.option("reduce_vars") + && exp instanceof AST_SymbolRef) { + var def = exp.definition(); + if (def.fixed instanceof AST_Defun) { + def.fixed = make_node(AST_Function, def.fixed, def.fixed).clone(true); + } + if (def.fixed instanceof AST_Function) { + exp = def.fixed; + if (compressor.option("unused") + && def.references.length == 1 + && compressor.find_parent(AST_Scope) === def.scope) { + if (!compressor.option("keep_fnames")) { + exp.name = null; + } + self.expression = exp; + } + } + } if (compressor.option("unused") && exp instanceof AST_Function && !exp.uses_arguments |