diff options
-rw-r--r-- | lib/compress.js | 488 |
1 files changed, 245 insertions, 243 deletions
diff --git a/lib/compress.js b/lib/compress.js index ec16dc2b..c44114b6 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -137,15 +137,6 @@ function Compressor(options, false_by_default) { return new ctor(props); }; - function SQUEEZE(nodetype, squeeze) { - nodetype.DEFMETHOD("squeeze", function(compressor){ - compressor.push_node(this); - var new_node = squeeze(this, compressor); - compressor.pop_node(); - return new_node !== undefined ? new_node : this; - }); - }; - function do_list(array, compressor) { return MAP(array, function(node){ return node.squeeze(compressor); @@ -760,11 +751,7 @@ function Compressor(options, false_by_default) { node.DEFMETHOD("aborts", func); }); - /* -----[ node squeezers ]----- */ - - SQUEEZE(AST_Directive, function(self, compressor){ - return self.optimize(compressor); - }); + /* -----[ optimizers ]----- */ AST_Directive.DEFMETHOD("optimize", function(compressor){ if (this.scope.has_directive(this.value) !== this.scope) { @@ -773,38 +760,16 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Debugger, function(self, compressor){ - return self.optimize(compressor); - }); - AST_Debugger.DEFMETHOD("optimize", function(compressor){ if (compressor.option("drop_debugger")) return make_node(AST_EmptyStatement, this); return this; }); - SQUEEZE(AST_LabeledStatement, function(self, compressor){ - self = self.clone(); - self.body = self.body.squeeze(compressor); - return self.optimize(compressor); - }); - AST_LabeledStatement.DEFMETHOD("optimize", function(){ return this.label.references.length == 0 ? this.body : this; }); - SQUEEZE(AST_Statement, function(self, compressor){ - self = self.clone(); - self.body = self.body.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_BlockStatement, function(self, compressor){ - self = self.clone(); - self.body = do_list(self.body, compressor); - return self.optimize(compressor); - }); - AST_BlockStatement.DEFMETHOD("optimize", function(compressor){ this.body = tighten_body(this.body, compressor); switch (this.body.length) { @@ -814,23 +779,11 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Block, function(self, compressor){ - self = self.clone(); - self.body = do_list(self.body, compressor); - return self.optimize(compressor); - }); - AST_Block.DEFMETHOD("optimize", function(compressor){ this.body = tighten_body(this.body, compressor); return this; }); - SQUEEZE(AST_Scope, function(self, compressor){ - self = self.clone().hoist_declarations(compressor); - self.body = do_list(self.body, compressor); - return self.optimize(compressor); - }); - AST_Scope.DEFMETHOD("optimize", function(compressor){ this.body = tighten_body(this.body, compressor); return this; @@ -1008,12 +961,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_SimpleStatement, function(self, compressor){ - self = self.clone(); - self.body = self.body.squeeze(compressor); - return self.optimize(compressor); - }); - AST_SimpleStatement.DEFMETHOD("optimize", function(compressor){ if (!this.body.has_side_effects()) { compressor.warn("Dropping side-effect-free statement [{file}:{line},{col}]", this.start); @@ -1022,17 +969,6 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_EmptyStatement, function(self, compressor){ - return self; - }); - - SQUEEZE(AST_DWLoop, function(self, compressor){ - self = self.clone(); - self.condition = self.condition.squeeze(compressor); - self.body = self.body.squeeze(compressor); - return self.optimize(compressor); - }); - AST_DWLoop.DEFMETHOD("optimize", function(compressor){ var self = this; var cond = self.condition.evaluate(compressor); @@ -1071,15 +1007,6 @@ function Compressor(options, false_by_default) { // return self; // }); - SQUEEZE(AST_For, function(self, compressor){ - self = self.clone(); - if (self.init) self.init = self.init.squeeze(compressor); - if (self.condition) self.condition = self.condition.squeeze(compressor); - if (self.step) self.step = self.step.squeeze(compressor); - self.body = self.body.squeeze(compressor); - return self.optimize(compressor); - }); - AST_For.DEFMETHOD("optimize", function(compressor){ var cond = this.condition; if (cond) { @@ -1107,42 +1034,6 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_ForIn, function(self, compressor){ - self = self.clone(); - self.init = self.init.squeeze(compressor); - self.object = self.object.squeeze(compressor); - self.body = self.body.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_With, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - self.body = self.body.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_Exit, function(self, compressor){ - self = self.clone(); - if (self.value) self.value = self.value.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_LoopControl, function(self, compressor){ - self = self.clone(); - if (self.label) self.label = self.label.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_If, function(self, compressor){ - self = self.clone(); - self.condition = self.condition.squeeze(compressor); - self.body = self.body.squeeze(compressor); - if (self.alternative) - self.alternative = self.alternative.squeeze(compressor); - return self.optimize(compressor); - }); - AST_If.DEFMETHOD("optimize", function(compressor){ var self = this; if (!compressor.option("conditionals")) return self; @@ -1267,13 +1158,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_Switch, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - self.body = self.body.squeeze(compressor); - return self.optimize(compressor); - }); - AST_Switch.DEFMETHOD("optimize", function(compressor){ var last_branch = this.body.body[this.body.body.length - 1]; if (last_branch) { @@ -1284,26 +1168,11 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Case, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - self.body = do_list(self.body, compressor); - return self.optimize(compressor); - }); - AST_Case.DEFMETHOD("optimize", function(compressor){ this.body = tighten_body(this.body, compressor); return this; }); - SQUEEZE(AST_Try, function(self, compressor){ - self = self.clone(); - self.body = do_list(self.body, compressor); - if (self.bcatch) self.bcatch = self.bcatch.squeeze(compressor); - if (self.bfinally) self.bfinally = self.bfinally.squeeze(compressor); - return self.optimize(compressor); - }); - AST_Try.DEFMETHOD("optimize", function(compressor){ this.body = tighten_body(this.body, compressor); return this; @@ -1340,32 +1209,12 @@ function Compressor(options, false_by_default) { })(assignments); }); - SQUEEZE(AST_Definitions, function(self, compressor){ - self = self.clone(); - self.definitions = do_list(self.definitions, compressor); - return self.optimize(compressor); - }); - AST_Definitions.DEFMETHOD("optimize", function(compressor){ if (this.definitions.length == 0) return make_node(AST_EmptyStatement, this); return this; }); - SQUEEZE(AST_VarDef, function(self, compressor){ - self = self.clone(); - if (self.value) self.value = self.value.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_Lambda, function(self, compressor){ - self = self.clone().hoist_declarations(compressor); - if (self.name) self.name = self.name.squeeze(compressor); - self.argnames = do_list(self.argnames, compressor); - self.body = do_list(self.body, compressor); - return self.optimize(compressor); - }); - AST_Function.DEFMETHOD("optimize", function(compressor){ var self = AST_Lambda.prototype.optimize.call(this, compressor); if (compressor.option("unused")) { @@ -1376,13 +1225,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_Call, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - self.args = do_list(self.args, compressor); - return self.optimize(compressor); - }); - AST_Call.DEFMETHOD("optimize", function(compressor){ if (compressor.option("unsafe")) { var exp = this.expression; @@ -1438,13 +1280,6 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Seq, function(self, compressor){ - self = self.clone(); - self.car = self.car.squeeze(compressor); - self.cdr = self.cdr.squeeze(compressor); - return self.optimize(compressor); - }); - AST_Seq.DEFMETHOD("optimize", function(compressor){ var self = this; if (compressor.option("cascade")) { @@ -1464,38 +1299,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_Dot, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_Sub, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - var prop = self.property = self.property.squeeze(compressor); - if (prop instanceof AST_String && compressor.option("properties")) { - prop = prop.getValue(); - if (is_identifier(prop)) { - self = new AST_Dot(self); - self.property = prop; - } - } - return self; - }); - - SQUEEZE(AST_Unary, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_UnaryPrefix, function(self, compressor){ - self = self.clone(); - self.expression = self.expression.squeeze(compressor); - return self.optimize(compressor); - }); - AST_UnaryPrefix.DEFMETHOD("optimize", function(compressor){ var self = this; var e = self.expression; @@ -1520,13 +1323,6 @@ function Compressor(options, false_by_default) { return self.evaluate(compressor)[0]; }); - SQUEEZE(AST_Binary, function(self, compressor){ - self = self.clone(); - self.left = self.left.squeeze(compressor); - self.right = self.right.squeeze(compressor); - return self.optimize(compressor); - }); - AST_Binary.DEFMETHOD("optimize", function(compressor){ if (compressor.option("comparations")) switch (this.operator) { case "===": @@ -1629,10 +1425,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_SymbolRef, function(self, compressor){ - return self.optimize(compressor); - }); - AST_SymbolRef.DEFMETHOD("optimize", function(compressor){ if (this.undeclared()) switch (this.name) { case "undefined": @@ -1643,10 +1435,6 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Undefined, function(self, compressor){ - return self.optimize(compressor); - }); - AST_Undefined.DEFMETHOD("optimize", function(compressor){ if (compressor.option("unsafe")) { var scope = compressor.find_parent(AST_Scope); @@ -1678,14 +1466,6 @@ function Compressor(options, false_by_default) { return this; }); - SQUEEZE(AST_Conditional, function(self, compressor){ - self = self.clone(); - self.condition = self.condition.squeeze(compressor); - self.consequent = self.consequent.squeeze(compressor); - self.alternative = self.alternative.squeeze(compressor); - return self.optimize(compressor); - }); - AST_Conditional.DEFMETHOD("optimize", function(compressor){ var self = this; if (!compressor.option("conditionals")) return self; @@ -1738,28 +1518,6 @@ function Compressor(options, false_by_default) { return self; }); - SQUEEZE(AST_Array, function(self, compressor){ - self = self.clone(); - self.elements = do_list(self.elements, compressor); - return self; - }); - - SQUEEZE(AST_Object, function(self, compressor){ - self = self.clone(); - self.properties = do_list(self.properties, compressor); - return self; - }); - - SQUEEZE(AST_ObjectProperty, function(self, compressor){ - self = self.clone(); - self.value = self.value.squeeze(compressor); - return self; - }); - - SQUEEZE(AST_Boolean, function(self, compressor){ - return self.optimize(compressor); - }); - AST_Boolean.DEFMETHOD("optimize", function(compressor){ if (compressor.option("booleans")) { var p = compressor.parent(); @@ -1786,4 +1544,248 @@ function Compressor(options, false_by_default) { return this; }); + /* -----[ node squeezers ]----- */ + + function SQUEEZE(nodetype, squeeze) { + nodetype.DEFMETHOD("squeeze", function(compressor){ + compressor.push_node(this); + var new_node = squeeze(this, compressor); + compressor.pop_node(); + return new_node !== undefined ? new_node : this; + }); + }; + + SQUEEZE(AST_Directive, function(self, compressor){ + return self.optimize(compressor); + }); + + SQUEEZE(AST_Debugger, function(self, compressor){ + return self.optimize(compressor); + }); + + SQUEEZE(AST_LabeledStatement, function(self, compressor){ + self = self.clone(); + self.body = self.body.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Statement, function(self, compressor){ + self = self.clone(); + self.body = self.body.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_BlockStatement, function(self, compressor){ + self = self.clone(); + self.body = do_list(self.body, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Block, function(self, compressor){ + self = self.clone(); + self.body = do_list(self.body, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Scope, function(self, compressor){ + self = self.clone().hoist_declarations(compressor); + self.body = do_list(self.body, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_SimpleStatement, function(self, compressor){ + self = self.clone(); + self.body = self.body.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_EmptyStatement, function(self, compressor){ + return self; + }); + + SQUEEZE(AST_DWLoop, function(self, compressor){ + self = self.clone(); + self.condition = self.condition.squeeze(compressor); + self.body = self.body.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_For, function(self, compressor){ + self = self.clone(); + if (self.init) self.init = self.init.squeeze(compressor); + if (self.condition) self.condition = self.condition.squeeze(compressor); + if (self.step) self.step = self.step.squeeze(compressor); + self.body = self.body.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_ForIn, function(self, compressor){ + self = self.clone(); + self.init = self.init.squeeze(compressor); + self.object = self.object.squeeze(compressor); + self.body = self.body.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_With, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + self.body = self.body.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_Exit, function(self, compressor){ + self = self.clone(); + if (self.value) self.value = self.value.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_LoopControl, function(self, compressor){ + self = self.clone(); + if (self.label) self.label = self.label.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_If, function(self, compressor){ + self = self.clone(); + self.condition = self.condition.squeeze(compressor); + self.body = self.body.squeeze(compressor); + if (self.alternative) + self.alternative = self.alternative.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Switch, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + self.body = self.body.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Case, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + self.body = do_list(self.body, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Try, function(self, compressor){ + self = self.clone(); + self.body = do_list(self.body, compressor); + if (self.bcatch) self.bcatch = self.bcatch.squeeze(compressor); + if (self.bfinally) self.bfinally = self.bfinally.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Definitions, function(self, compressor){ + self = self.clone(); + self.definitions = do_list(self.definitions, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_VarDef, function(self, compressor){ + self = self.clone(); + if (self.value) self.value = self.value.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_Lambda, function(self, compressor){ + self = self.clone().hoist_declarations(compressor); + if (self.name) self.name = self.name.squeeze(compressor); + self.argnames = do_list(self.argnames, compressor); + self.body = do_list(self.body, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Call, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + self.args = do_list(self.args, compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Seq, function(self, compressor){ + self = self.clone(); + self.car = self.car.squeeze(compressor); + self.cdr = self.cdr.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Dot, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_Sub, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + var prop = self.property = self.property.squeeze(compressor); + if (prop instanceof AST_String && compressor.option("properties")) { + prop = prop.getValue(); + if (is_identifier(prop)) { + self = new AST_Dot(self); + self.property = prop; + } + } + return self; + }); + + SQUEEZE(AST_Unary, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_UnaryPrefix, function(self, compressor){ + self = self.clone(); + self.expression = self.expression.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Binary, function(self, compressor){ + self = self.clone(); + self.left = self.left.squeeze(compressor); + self.right = self.right.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_SymbolRef, function(self, compressor){ + return self.optimize(compressor); + }); + + SQUEEZE(AST_Undefined, function(self, compressor){ + return self.optimize(compressor); + }); + + SQUEEZE(AST_Conditional, function(self, compressor){ + self = self.clone(); + self.condition = self.condition.squeeze(compressor); + self.consequent = self.consequent.squeeze(compressor); + self.alternative = self.alternative.squeeze(compressor); + return self.optimize(compressor); + }); + + SQUEEZE(AST_Array, function(self, compressor){ + self = self.clone(); + self.elements = do_list(self.elements, compressor); + return self; + }); + + SQUEEZE(AST_Object, function(self, compressor){ + self = self.clone(); + self.properties = do_list(self.properties, compressor); + return self; + }); + + SQUEEZE(AST_ObjectProperty, function(self, compressor){ + self = self.clone(); + self.value = self.value.squeeze(compressor); + return self; + }); + + SQUEEZE(AST_Boolean, function(self, compressor){ + return self.optimize(compressor); + }); + })(); |