Fix #269
authorRichard van Velzen <rvanvelzen1@gmail.com>
Thu, 24 Oct 2013 09:08:33 +0000 (11:08 +0200)
committerRichard van Velzen <rvanvelzen1@gmail.com>
Thu, 24 Oct 2013 09:08:33 +0000 (11:08 +0200)
Shorten most primitives where possible. Also optimize some edge cases.

lib/compress.js
test/compress/issue-269.js [new file with mode: 0644]

index 083b5d2..121e312 100644 (file)
@@ -1620,7 +1620,7 @@ merge(Compressor.prototype, {
                     if (self.args.length != 1) {
                         return make_node(AST_Array, self, {
                             elements: self.args
-                        });
+                        }).transform(compressor);
                     }
                     break;
                   case "Object":
@@ -1634,11 +1634,30 @@ merge(Compressor.prototype, {
                     if (self.args.length == 0) return make_node(AST_String, self, {
                         value: ""
                     });
-                    return make_node(AST_Binary, self, {
+                    if (self.args.length <= 1) return make_node(AST_Binary, self, {
                         left: self.args[0],
                         operator: "+",
                         right: make_node(AST_String, self, { value: "" })
+                    }).transform(compressor);
+                    break;
+                  case "Number":
+                    if (self.args.length == 0) return make_node(AST_Number, self, {
+                        value: 0
                     });
+                    if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
+                        expression: self.args[0],
+                        operator: "+"
+                    }).transform(compressor);
+                  case "Boolean":
+                    if (self.args.length == 0) return make_node(AST_False, self);
+                    if (self.args.length == 1) return make_node(AST_UnaryPrefix, self, {
+                        expression: make_node(AST_UnaryPrefix, null, {
+                            expression: self.args[0],
+                            operator: "!"
+                        }),
+                        operator: "!"
+                    }).transform(compressor);
+                    break;
                   case "Function":
                     if (all(self.args, function(x){ return x instanceof AST_String })) {
                         // quite a corner-case, but we can handle it:
@@ -1999,6 +2018,16 @@ merge(Compressor.prototype, {
             && self.right.getValue() === "" && self.left instanceof AST_Binary
             && self.left.operator == "+" && self.left.is_string(compressor)) {
             return self.left;
+        } else if (self.operator == "+" && self.right instanceof AST_String
+            && self.right.getValue() === "" && self.left instanceof AST_Binary
+            && self.left.operator == "+" && self.left.right instanceof AST_Number) {
+            return make_node(AST_Binary, self, {
+                left: self.left.left,
+                operator: "+",
+                right: make_node(AST_String, self.right, {
+                    value: String(self.left.right.value)
+                })
+            });
         }
         if (compressor.option("evaluate")) {
             if (self.operator == "+") {
diff --git a/test/compress/issue-269.js b/test/compress/issue-269.js
new file mode 100644 (file)
index 0000000..70e82d0
--- /dev/null
@@ -0,0 +1,68 @@
+issue_269_1: {
+       options = {unsafe: true};
+       input: {
+               f(
+                       String(x),
+                       Number(x),
+                       Boolean(x),
+
+                       String(),
+                       Number(),
+                       Boolean()
+               );
+       }
+       expect: {
+               f(
+                       x + '', +x, !!x,
+                       '', 0, false
+               );
+       }
+}
+
+issue_269_dangers: {
+       options = {unsafe: true};
+       input: {
+               f(
+                       String(x, x),
+                       Number(x, x),
+                       Boolean(x, x)
+               );
+       }
+       expect: {
+               f(String(x, x), Number(x, x), Boolean(x, x));
+       }
+}
+
+issue_269_in_scope: {
+       options = {unsafe: true};
+       input: {
+               var String, Number, Boolean;
+               f(
+                       String(x),
+                       Number(x, x),
+                       Boolean(x)
+               );
+       }
+       expect: {
+               var String, Number, Boolean;
+               f(String(x), Number(x, x), Boolean(x));
+       }
+}
+
+strings_concat: {
+       options = {unsafe: true};
+       input: {
+               f(
+                       String(x + 'str'),
+                       String('str' + x),
+                       String(x + 5)
+               );
+       }
+       expect: {
+               f(
+                       x + 'str',
+                       'str' + x,
+                       x + '5'
+               );
+       }
+}
\ No newline at end of file