fixes & improvements to [].join()

fixes
- [a].join() => "" + a
- ["a", , "b"].join() => "a,,b"
- ["a", null, "b"].join() => "a,,b"
- ["a", undefined, "b"].join() => "a,,b"

improvements
- ["a", "b"].join(null) => "anullb"
- ["a", "b"].join(undefined) => "a,b"
- [a + "b", c].join("") => a + "b" + c

closes #1453
This commit is contained in:
alexlamsl
2017-02-18 19:05:11 +08:00
parent 148047fbbf
commit 100307ab31
2 changed files with 92 additions and 23 deletions

View File

@@ -2290,39 +2290,57 @@ merge(Compressor.prototype, {
}).transform(compressor);
}
else if (exp instanceof AST_Dot && exp.expression instanceof AST_Array && exp.property == "join") EXIT: {
var separator = self.args.length == 0 ? "," : self.args[0].evaluate(compressor)[1];
if (separator == null) break EXIT; // not a constant
var elements = exp.expression.elements.reduce(function(a, el){
var separator;
if (self.args.length > 0) {
separator = self.args[0].evaluate(compressor);
if (separator.length < 2) break EXIT; // not a constant
separator = separator[1];
}
var elements = [];
var consts = [];
exp.expression.elements.forEach(function(el) {
el = el.evaluate(compressor);
if (a.length == 0 || el.length == 1) {
a.push(el);
if (el.length > 1) {
consts.push(el[1]);
} else {
var last = a[a.length - 1];
if (last.length == 2) {
// it's a constant
var val = "" + last[1] + separator + el[1];
a[a.length - 1] = [ make_node_from_constant(compressor, val, last[0]), val ];
} else {
a.push(el);
if (consts.length > 0) {
elements.push(make_node(AST_String, self, {
value: consts.join(separator)
}));
consts.length = 0;
}
elements.push(el[0]);
}
return a;
}, []);
});
if (consts.length > 0) {
elements.push(make_node(AST_String, self, {
value: consts.join(separator)
}));
}
if (elements.length == 0) return make_node(AST_String, self, { value: "" });
if (elements.length == 1) return elements[0][0];
if (elements.length == 1) {
if (elements[0].is_string(compressor)) {
return elements[0];
}
return make_node(AST_Binary, elements[0], {
operator : "+",
left : make_node(AST_String, self, { value: "" }),
right : elements[0]
});
}
if (separator == "") {
var first;
if (elements[0][0] instanceof AST_String
|| elements[1][0] instanceof AST_String) {
first = elements.shift()[0];
if (elements[0].is_string(compressor)
|| elements[1].is_string(compressor)) {
first = elements.shift();
} else {
first = make_node(AST_String, self, { value: "" });
}
return elements.reduce(function(prev, el){
return make_node(AST_Binary, el[0], {
return make_node(AST_Binary, el, {
operator : "+",
left : prev,
right : el[0],
right : el
});
}, first).transform(compressor);
}
@@ -2331,9 +2349,7 @@ merge(Compressor.prototype, {
var node = self.clone();
node.expression = node.expression.clone();
node.expression.expression = node.expression.expression.clone();
node.expression.expression.elements = elements.map(function(el){
return el[0];
});
node.expression.expression.elements = elements;
return best_of(self, node);
}
}