don't change order in binary expressions if both operands have side effects
authorMihai Bazon <mihai@bazon.net>
Tue, 13 Nov 2012 12:32:07 +0000 (14:32 +0200)
committerMihai Bazon <mihai@bazon.net>
Tue, 13 Nov 2012 12:32:07 +0000 (14:32 +0200)
lib/compress.js

index a4a53f5..dcd376c 100644 (file)
@@ -554,12 +554,24 @@ merge(Compressor.prototype, {
         def(AST_UnaryPrefix, function(){
             return this.operator == "typeof";
         });
-        def(AST_Binary, function(){
+        def(AST_Binary, function(compressor){
             return this.operator == "+" &&
-                (this.left.is_string() || this.right.is_string());
+                (this.left.is_string(compressor) || this.right.is_string(compressor));
         });
-        def(AST_Assign, function(){
-            return this.operator == "=" && this.right.is_string();
+        def(AST_Assign, function(compressor){
+            return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
+        });
+        def(AST_Seq, function(compressor){
+            return this.cdr.is_string(compressor);
+        });
+        def(AST_Conditional, function(compressor){
+            return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
+        });
+        def(AST_Call, function(compressor){
+            return compressor.option("unsafe")
+                && this.expression instanceof AST_SymbolRef
+                && this.expression.name == "String"
+                && this.expression.undeclared();
         });
     })(function(node, func){
         node.DEFMETHOD("is_string", func);
@@ -1549,10 +1561,12 @@ merge(Compressor.prototype, {
 
     OPT(AST_Binary, function(self, compressor){
         function reverse(op) {
-            if (op) self.operator = op;
-            var tmp = self.left;
-            self.left = self.right;
-            self.right = tmp;
+            if (!(self.left.has_side_effects() && self.right.has_side_effects())) {
+                if (op) self.operator = op;
+                var tmp = self.left;
+                self.left = self.right;
+                self.right = tmp;
+            }
         };
         if (commutativeOperators(self.operator)) {
             if (self.right instanceof AST_Constant
@@ -1564,7 +1578,7 @@ merge(Compressor.prototype, {
         if (compressor.option("comparisons")) switch (self.operator) {
           case "===":
           case "!==":
-            if ((self.left.is_string() && self.right.is_string()) ||
+            if ((self.left.is_string(compressor) && self.right.is_string(compressor)) ||
                 (self.left.is_boolean() && self.right.is_boolean())) {
                 self.operator = self.operator.substr(0, 2);
             }