diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/ast.js | 12 | ||||
-rw-r--r-- | lib/compress.js | 49 | ||||
-rw-r--r-- | lib/output.js | 2 |
3 files changed, 62 insertions, 1 deletions
@@ -581,6 +581,18 @@ var AST_Seq = DEFNODE("Seq", "car cdr", { } return list; }, + to_array: function() { + var p = this, a = []; + while (p) { + a.push(p.car); + if (p.cdr && !(p.cdr instanceof AST_Seq)) { + a.push(p.cdr); + break; + } + p = p.cdr; + } + return a; + }, add: function(node) { var p = this; while (p) { diff --git a/lib/compress.js b/lib/compress.js index 3e5b524d..22fb330e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1380,6 +1380,10 @@ merge(Compressor.prototype, { }); OPT(AST_Seq, function(self, compressor){ + if (!compressor.option("side_effects")) + return self; + if (!self.car.has_side_effects()) + return self.cdr; if (compressor.option("cascade")) { if (self.car instanceof AST_Assign && !self.car.left.has_side_effects() @@ -1395,7 +1399,26 @@ merge(Compressor.prototype, { return self; }); + AST_Unary.DEFMETHOD("lift_sequences", function(compressor){ + if (compressor.option("sequences")) { + if (this.expression instanceof AST_Seq) { + var seq = this.expression; + var x = seq.to_array(); + this.expression = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + } + return this; + }); + + OPT(AST_UnaryPostfix, function(self, compressor){ + return self.lift_sequences(compressor); + }); + OPT(AST_UnaryPrefix, function(self, compressor){ + self = self.lift_sequences(compressor); var e = self.expression; if (compressor.option("booleans") && compressor.in_boolean_context()) { switch (self.operator) { @@ -1418,7 +1441,32 @@ merge(Compressor.prototype, { return self.evaluate(compressor)[0]; }); + AST_Binary.DEFMETHOD("lift_sequences", function(compressor){ + if (compressor.option("sequences")) { + if (this.left instanceof AST_Seq) { + var seq = this.left; + var x = seq.to_array(); + this.left = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + if (this.right instanceof AST_Seq + && !(this.operator == "||" || this.operator == "&&") + && !this.left.has_side_effects()) { + var seq = this.right; + var x = seq.to_array(); + this.right = x.pop(); + x.push(this); + seq = AST_Seq.from_array(x).transform(compressor); + return seq; + } + } + return this; + }); + OPT(AST_Binary, function(self, compressor){ + self = self.lift_sequences(compressor); if (compressor.option("comparisons")) switch (self.operator) { case "===": case "!==": @@ -1557,6 +1605,7 @@ merge(Compressor.prototype, { var ASSIGN_OPS = [ '+', '-', '/', '*', '%', '>>', '<<', '>>>', '|', '^', '&' ]; OPT(AST_Assign, function(self, compressor){ + self = self.lift_sequences(compressor); if (self.operator == "=" && self.left instanceof AST_SymbolRef && self.right instanceof AST_Binary diff --git a/lib/output.js b/lib/output.js index 8d2c4d39..4b515ecd 100644 --- a/lib/output.js +++ b/lib/output.js @@ -414,7 +414,7 @@ function OutputStream(options) { var p = output.parent(); return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) || p instanceof AST_Unary // !(foo, bar, baz) - || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 7 + || p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 || p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4 || p instanceof AST_Dot // (1, {foo:2}).foo ==> 2 || p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] |