[...].join() - handle null and better compress [...].join("str")
* null, undefined, and holes in arrays are interpreted as an empty
string by Array.prototype.join. This commit fixes various issues when
compressing them, or values that can be null or undefined.
* Compress [foo+"str","123"+bar].join("-") -> foo+"str-123"+bar
This commit is contained in:
parent
afdaeba37d
commit
48d2f430ff
|
|
@ -1690,7 +1690,7 @@ merge(Compressor.prototype, {
|
|||
var last = a[a.length - 1];
|
||||
if (last.length == 2) {
|
||||
// it's a constant
|
||||
var val = "" + last[1] + separator + el[1];
|
||||
var val = "" + (last[1] == null ? "" : last[1] ) + separator + (el[1] == null ? "" : el[1]);
|
||||
a[a.length - 1] = [ make_node_from_constant(compressor, val, last[0]), val ];
|
||||
} else {
|
||||
a.push(el);
|
||||
|
|
@ -1699,23 +1699,55 @@ merge(Compressor.prototype, {
|
|||
return a;
|
||||
}, []);
|
||||
if (elements.length == 0) return make_node(AST_String, self, { value: "" });
|
||||
if (elements.length == 1) return elements[0][0];
|
||||
if (separator == "") {
|
||||
var first;
|
||||
if (elements[0][0] instanceof AST_String
|
||||
|| elements[1][0] instanceof AST_String) {
|
||||
first = elements.shift()[0];
|
||||
if (elements.length == 1) {
|
||||
if (elements[0][0].is_string()) {
|
||||
return elements[0][0];
|
||||
} else if (elements[0][0] instanceof AST_Constant) {
|
||||
return make_node(AST_String, self, {
|
||||
value: [elements[0][0].evaluate(compressor)[1]].join()
|
||||
});
|
||||
} else {
|
||||
first = make_node(AST_String, self, { value: "" });
|
||||
break EXIT;
|
||||
}
|
||||
return elements.reduce(function(prev, el){
|
||||
return make_node(AST_Binary, el[0], {
|
||||
}
|
||||
|
||||
// If all components are either strings or constants we can
|
||||
// concatenate them with +
|
||||
var all_string_or_constant = elements.every(function(el){
|
||||
return el[0] instanceof AST_Constant || el[0].is_string(compressor);
|
||||
});
|
||||
if (all_string_or_constant) {
|
||||
if (separator == "") {
|
||||
if (!elements[0][0].is_string(compressor)
|
||||
&& !elements[1][0].is_string(compressor)) {
|
||||
elements = elements.unshift([make_node(AST_String, self, { value: "" })]);
|
||||
}
|
||||
return elements.map(function(el){ return el[0] }).reduce(function(prev, el){
|
||||
if (el instanceof AST_Constant && el.getValue() == null) {
|
||||
return prev;
|
||||
}
|
||||
return make_node(AST_Binary, el, {
|
||||
operator : "+",
|
||||
left : prev,
|
||||
right : el[0],
|
||||
right : el
|
||||
});
|
||||
}, first).transform(compressor);
|
||||
}).transform(compressor);
|
||||
} else {
|
||||
var ast_separator = make_node_from_constant(compressor, ""+separator, self.args[0]);
|
||||
return elements.map(function(el){ return el[0] }).reduce(function(prev, el){
|
||||
return make_node(AST_Binary, el, {
|
||||
operator : "+",
|
||||
left : make_node(AST_Binary, prev, {
|
||||
operator : "+",
|
||||
left : prev,
|
||||
right : ast_separator
|
||||
}),
|
||||
right : el
|
||||
});
|
||||
}).transform(compressor);
|
||||
}
|
||||
}
|
||||
|
||||
// need this awkward cloning to not affect original element
|
||||
// best_of will decide which one to get through.
|
||||
var node = self.clone();
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ constant_join: {
|
|||
var a1 = [ "foo", "bar", "baz" ].join();
|
||||
var b = [ "foo", 1, 2, 3, "bar" ].join("");
|
||||
var c = [ boo(), "foo", 1, 2, 3, "bar", bar() ].join("");
|
||||
var c1 = [ boo(), bar(), "foo", 1, 2, 3, "bar", bar() ].join("");
|
||||
var c2 = [ 1, 2, "foo", "bar", baz() ].join("");
|
||||
var c1 = [ boo() + bar() + "boo", "foo", 1, 2, 3, "bar", bar() + "foo" ].join("");
|
||||
var c2 = [ 1, 2, null, , undefined, "foo", "bar", baz() ].join();
|
||||
var d = [ "foo", 1 + 2 + "bar", "baz" ].join("-");
|
||||
var e = [].join(foo + bar);
|
||||
var f = [].join("");
|
||||
|
|
@ -34,9 +34,9 @@ constant_join: {
|
|||
var a = "foobarbaz";
|
||||
var a1 = "foo,bar,baz";
|
||||
var b = "foo123bar";
|
||||
var c = boo() + "foo123bar" + bar();
|
||||
var c1 = "" + boo() + bar() + "foo123bar" + bar();
|
||||
var c2 = "12foobar" + baz();
|
||||
var c = [ boo(), "foo123bar", bar() ].join("");
|
||||
var c1 = boo() + bar() + "boofoo123bar" + (bar() + "foo");
|
||||
var c2 = ["1,2,,,,foo,bar", baz()].join();
|
||||
var d = "foo-3bar-baz";
|
||||
var e = [].join(foo + bar);
|
||||
var f = "";
|
||||
|
|
@ -62,7 +62,7 @@ constant_join_2: {
|
|||
var f = [ "str", "str" + variable, "foo", "bar", "moo" + foo ].join("");
|
||||
}
|
||||
expect: {
|
||||
var a = "foobar" + boo() + "bazxy";
|
||||
var a = [ "foobar", boo(), "bazxy" ].join("");
|
||||
var b = [ "foo-bar", boo(), "baz-x-y" ].join("-");
|
||||
var c = [ "foo", "bar", boo(), "baz", "x", "y" ].join("really-long-separator");
|
||||
var d = [ "foo-bar", boo(), "foo+1+2+3+bar-baz-x-y" ].join("-");
|
||||
|
|
@ -72,3 +72,30 @@ constant_join_2: {
|
|||
var f = "strstr" + variable + "foobarmoo" + foo;
|
||||
}
|
||||
}
|
||||
|
||||
constant_join_3: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
input: {
|
||||
var a = [ null ].join();
|
||||
var b = [ , ].join();
|
||||
var c = [ foo ].join();
|
||||
var d = [ foo, null, undefined, boo ].join("-");
|
||||
var e = [ foo, boo ].join("");
|
||||
var f = [ null, "foo", null, foo + "boo" ].join("");
|
||||
var g = [ null, "foo", null, foo + "boo" ].join("-");
|
||||
var h = [ "foo" + bar, null, baz + "boo" ].join("");
|
||||
}
|
||||
expect: {
|
||||
var a = "";
|
||||
var b = "";
|
||||
var c = [ foo ].join();
|
||||
var d = [ foo, "-", boo].join("-");
|
||||
var e = [ foo, boo ].join("");
|
||||
var f = "foo" + (foo + "boo");
|
||||
var g = "-foo--" + (foo + "boo");
|
||||
var h = "foo" + bar + (baz + "boo");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user