Fix output for arrays containing undefined values.
authorDavid Glasser <glasser@davidglasser.net>
Wed, 16 Jan 2013 19:59:19 +0000 (14:59 -0500)
committerMihai Bazon <mihai@bazon.net>
Thu, 17 Jan 2013 09:36:10 +0000 (11:36 +0200)
1b6bcca7 was a first attempt at this. That commit made Uglify stop replacing
holes with undefined, but instead it started replacing undefined with
holes. This is slightly problematic, because there is a difference between a
hole and an undefined value. More problematically, it changed [1,undefined] to
[1,] which generally doesn't even parse as a hole (just as a trailing comma), so
it didn't even preserve the length of the array!

Instead, parse holes as their own special AST node which prints invisibly.

lib/ast.js
lib/output.js
lib/parse.js
test/compress/arrays.js [new file with mode: 0644]

index c0b263e..62bdd8d 100644 (file)
@@ -863,6 +863,11 @@ var AST_Undefined = DEFNODE("Undefined", null, {
     value: (function(){}())
 }, AST_Atom);
 
+var AST_Hole = DEFNODE("Hole", null, {
+    $documentation: "A hole in an array",
+    value: (function(){}())
+}, AST_Atom);
+
 var AST_Infinity = DEFNODE("Infinity", null, {
     $documentation: "The `Infinity` value",
     value: 1/0
index 464a459..5da27e7 100644 (file)
@@ -984,8 +984,7 @@ function OutputStream(options) {
             if (len > 0) output.space();
             a.forEach(function(exp, i){
                 if (i) output.comma();
-                if (!(exp instanceof AST_Undefined))
-                    exp.print(output);
+                exp.print(output);
             });
             if (len > 0) output.space();
         });
@@ -1036,6 +1035,9 @@ function OutputStream(options) {
     DEFPRINT(AST_Undefined, function(self, output){
         output.print("void 0");
     });
+    DEFPRINT(AST_Hole, function(self, output){
+        output.print("");
+    });
     DEFPRINT(AST_Infinity, function(self, output){
         output.print("1/0");
     });
index 5b6820f..01fbb88 100644 (file)
@@ -1131,7 +1131,7 @@ function parse($TEXT, options) {
             if (first) first = false; else expect(",");
             if (allow_trailing_comma && is("punc", closing)) break;
             if (is("punc", ",") && allow_empty) {
-                a.push(new AST_Undefined({ start: S.token, end: S.token }));
+                a.push(new AST_Hole({ start: S.token, end: S.token }));
             } else {
                 a.push(expression(false));
             }
diff --git a/test/compress/arrays.js b/test/compress/arrays.js
new file mode 100644 (file)
index 0000000..10fe6eb
--- /dev/null
@@ -0,0 +1,12 @@
+holes_and_undefined: {
+    input: {
+        x = [1, 2, undefined];
+        y = [1, , 2, ];
+        z = [1, undefined, 3];
+    }
+    expect: {
+        x=[1,2,void 0];
+        y=[1,,2];
+        z=[1,void 0,3];
+    }
+}