Better fix for #343
authorMihai Bazon <mihai@bazon.net>
Wed, 6 Nov 2013 08:47:36 +0000 (10:47 +0200)
committerMihai Bazon <mihai@bazon.net>
Wed, 6 Nov 2013 08:48:48 +0000 (10:48 +0200)
We can in fact lift sequences, but only if the operation is assignment and
the left-hand side has no side effects nor property access -- that should
guarantee that whatever we place before it cannot affect the sense of the
assignment.

Dropped contrived test case (too hard to support it now), added a more
meaningful one.

lib/compress.js
test/compress/sequences.js

index 59caa15..f44277c 100644 (file)
@@ -1865,6 +1865,14 @@ merge(Compressor.prototype, {
         return self.evaluate(compressor)[0];
     });
 
+    function has_side_effects_or_prop_access(node, compressor) {
+        var save_pure_getters = compressor.option("pure_getters");
+        compressor.options.pure_getters = false;
+        var ret = node.has_side_effects(compressor);
+        compressor.options.pure_getters = save_pure_getters;
+        return ret;
+    }
+
     AST_Binary.DEFMETHOD("lift_sequences", function(compressor){
         if (compressor.option("sequences")) {
             if (this.left instanceof AST_Seq) {
@@ -1875,6 +1883,16 @@ merge(Compressor.prototype, {
                 seq = AST_Seq.from_array(x).transform(compressor);
                 return seq;
             }
+            if (this.right instanceof AST_Seq
+                && this instanceof AST_Assign
+                && !has_side_effects_or_prop_access(this.left, compressor)) {
+                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;
     });
index 6f63ace..4669571 100644 (file)
@@ -101,10 +101,12 @@ lift_sequences_1: {
 lift_sequences_2: {
     options = { sequences: true, evaluate: true };
     input: {
-        q = 1 + (foo(), bar(), 5) + 7 * (5 / (3 - (a(), (QW=ER), c(), 2))) - (x(), y(), 5);
+        foo.x = (foo = {}, 10);
+        bar = (bar = {}, 10);
     }
     expect: {
-        foo(), bar(), a(), QW = ER, c(), x(), y(), q = 36
+        foo.x = (foo = {}, 10),
+        bar = {}, bar = 10;
     }
 }