var separator = self.args[0];
// [].join() ---> ""
// [].join(x) ---> (x, "")
- if (exp.expression.elements.length == 0) return separator ? make_sequence(self, [
- separator,
- make_node(AST_String, self, { value: "" }),
- ]).optimize(compressor) : make_node(AST_String, self, { value: "" });
+ if (exp.expression.elements.length == 0 && !(separator instanceof AST_Spread)) {
+ return separator ? make_sequence(self, [
+ separator,
+ make_node(AST_String, self, { value: "" }),
+ ]).optimize(compressor) : make_node(AST_String, self, { value: "" });
+ }
if (separator) {
separator = separator.evaluate(compressor);
if (separator instanceof AST_Node) break EXIT; // not a constant
}
var elements = [];
var consts = [];
- exp.expression.elements.forEach(function(el) {
+ for (var i = 0; i < exp.expression.elements.length; i++) {
+ var el = exp.expression.elements[i];
var value = el.evaluate(compressor);
if (value !== el) {
consts.push(value);
+ } else if (el instanceof AST_Spread) {
+ break EXIT;
} else {
if (consts.length > 0) {
elements.push(make_node(AST_String, self, {
}
elements.push(el);
}
- });
+ }
if (consts.length > 0) elements.push(make_node(AST_String, self, {
value: consts.join(separator),
}));
node_version: ">=8"
}
+unsafe_join_1: {
+ options = {
+ unsafe: true,
+ }
+ input: {
+ console.log([ ..."foo" ].join());
+ }
+ expect: {
+ console.log([ ..."foo" ].join());
+ }
+ expect_stdout: "f,o,o"
+ node_version: ">=6"
+}
+
+unsafe_join_2: {
+ options = {
+ evaluate: true,
+ unsafe: true,
+ }
+ input: {
+ console.log([ "foo", ..."bar" ].join(""));
+ }
+ expect: {
+ console.log([ "foo", ..."bar" ].join(""));
+ }
+ expect_stdout: "foobar"
+ node_version: ">=6"
+}
+
+unsafe_join_3: {
+ options = {
+ unsafe: true,
+ }
+ input: {
+ try {
+ [].join(...console);
+ } catch (e) {
+ console.log("PASS");
+ }
+ }
+ expect: {
+ try {
+ [].join(...console);
+ } catch (e) {
+ console.log("PASS");
+ }
+ }
+ expect_stdout: "PASS"
+ node_version: ">=6"
+}
+
issue_4329: {
options = {
objects: true,