Merge branch 'master' into harmony-v3.3.5

This commit is contained in:
alexlamsl
2018-01-07 20:35:53 +08:00
30 changed files with 2063 additions and 290 deletions

View File

@@ -1203,3 +1203,24 @@ issue_2560: {
"2",
]
}
hoist_decl: {
options = {
conditionals: true,
join_vars: true,
sequences: true,
}
input: {
if (x()) {
var a;
y();
} else {
z();
var b;
}
}
expect: {
var a, b;
x() ? y() : z();
}
}

View File

@@ -1100,3 +1100,31 @@ issue_2692: {
}
expect_stdout: "function"
}
issue_2701: {
options = {
dead_code: true,
inline: false,
}
input: {
function f(a) {
return a = function() {
return function() {
return a;
};
}();
}
console.log(typeof f()());
}
expect: {
function f(a) {
return a = function() {
return function() {
return a;
};
}();
}
console.log(typeof f()());
}
expect_stdout: "function"
}

View File

@@ -1895,3 +1895,125 @@ issue_2665: {
}
expect_stdout: "-1"
}
double_assign_1: {
options = {
passes: 2,
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
var a = {};
var a = [];
return a;
}
function f2() {
var a = {};
a = [];
return a;
}
function f3() {
a = {};
var a = [];
return a;
}
function f4(a) {
a = {};
a = [];
return a;
}
function f5(a) {
var a = {};
a = [];
return a;
}
function f6(a) {
a = {};
var a = [];
return a;
}
console.log(f1(), f2(), f3(), f4(), f5(), f6());
}
expect: {
function f1() {
return [];
}
function f2() {
var a;
a = [];
return a;
}
function f3() {
return [];
}
function f4(a) {
a = [];
return a;
}
function f5(a) {
a = [];
return a;
}
function f6(a) {
a = [];
return a;
}
console.log(f1(), f2(), f3(), f4(), f5(), f6());
}
expect_stdout: true
}
double_assign_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
for (var i = 0; i < 2; i++)
a = void 0, a = {}, console.log(a);
var a;
}
expect: {
for (var i = 0; i < 2; i++)
void 0, a = {}, console.log(a);
var a;
}
}
double_assign_3: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
for (var i = 0; i < 2; i++)
a = void 0, a = { a: a }, console.log(a);
var a;
}
expect: {
for (var i = 0; i < 2; i++)
a = void 0, a = { a: a }, console.log(a);
var a;
}
}
cascade_drop_assign: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var a, b = a = "PASS";
console.log(b);
}
expect: {
var b = "PASS";
console.log(b);
}
expect_stdout: "PASS"
}

View File

@@ -800,12 +800,12 @@ issue_2601_1: {
expect: {
var a = "FAIL";
(function() {
var b;
b = "foo",
function(b) {
b && b();
}(),
b && (a = "PASS");
var b;
})(),
console.log(a);
}
@@ -1318,7 +1318,7 @@ issue_2630_1: {
expect: {
var c = 0;
(function() {
while (c++, void (c = 1 + c));
while (void (c = 1 + ++c));
})(),
console.log(c);
}
@@ -1332,6 +1332,7 @@ issue_2630_2: {
passes: 2,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
@@ -1349,7 +1350,7 @@ issue_2630_2: {
expect: {
var c = 0;
!function() {
while (c += 1, void (c = 1 + c));
while (void (c = 1 + (c += 1)));
}(), console.log(c);
}
expect_stdout: "2"
@@ -1449,7 +1450,7 @@ issue_2630_5: {
!function() {
do {
c *= 10;
} while (c += 3, (c = 2 + c) < 100);
} while ((c = 2 + (c += 3)) < 100);
}();
console.log(c);
}
@@ -1771,3 +1772,347 @@ issue_2663_3: {
"reset",
]
}
duplicate_argnames: {
options = {
inline: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = "PASS";
function f(b, b, b) {
b && (a = "FAIL");
}
f(0, console);
console.log(a);
}
expect: {
var a = "PASS";
console, b && (a = "FAIL");
var b;
console.log(a);
}
expect_stdout: "PASS"
}
loop_init_arg: {
options = {
inline: true,
side_effects: true,
toplevel: true,
}
input: {
var a = "PASS";
for (var k in "12") (function (b) {
(b >>= 1) && (a = "FAIL"), b = 2;
})();
console.log(a);
}
expect: {
var a = "PASS";
for (var k in "12")
b = void 0, (b >>= 1) && (a = "FAIL"), b = 2;
var b;
console.log(a);
}
expect_stdout: "PASS"
}
inline_false: {
options = {
inline: false,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect_stdout: [
"1",
"2",
"3",
]
}
inline_0: {
options = {
inline: 0,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect_stdout: [
"1",
"2",
"3",
]
}
inline_1: {
options = {
inline: 1,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
console.log(1);
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect_stdout: [
"1",
"2",
"3",
]
}
inline_2: {
options = {
inline: 2,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
console.log(1);
a = 2, console.log(a);
var a;
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect_stdout: [
"1",
"2",
"3",
]
}
inline_3: {
options = {
inline: 3,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
console.log(1);
a = 2, console.log(a);
var a;
b = 3, c = b, console.log(c);
var b, c;
}
expect_stdout: [
"1",
"2",
"3",
]
}
inline_true: {
options = {
inline: true,
side_effects: true,
toplevel: true,
}
input: {
(function() {
console.log(1);
})();
(function(a) {
console.log(a);
})(2);
(function(b) {
var c = b;
console.log(c);
})(3);
}
expect: {
console.log(1);
a = 2, console.log(a);
var a;
b = 3, c = b, console.log(c);
var b, c;
}
expect_stdout: [
"1",
"2",
"3",
]
}
use_before_init_in_loop: {
options = {
inline: true,
side_effects: true,
toplevel: true,
}
input: {
var a = "PASS";
for (var b = 2; --b >= 0;) (function() {
var c = function() {
return 1;
}(c && (a = "FAIL"));
})();
console.log(a);
}
expect: {
var a = "PASS";
for (var b = 2; --b >= 0;)
c = void 0, c = (c && (a = "FAIL"), 1);
var c;
console.log(a);
}
expect_stdout: "PASS"
}
duplicate_arg_var: {
options = {
inline: true,
toplevel: true,
}
input: {
console.log(function(b) {
return b;
var b;
}("PASS"));
}
expect: {
console.log((b = "PASS", b));
var b;
}
expect_stdout: "PASS"
}
issue_2737_1: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function(a) {
while (a());
})(function f() {
console.log(typeof f);
});
}
expect: {
(function(a) {
while (a());
})(function f() {
console.log(typeof f);
});
}
expect_stdout: "function"
}
issue_2737_2: {
options = {
inline: true,
reduce_vars: true,
unused: true,
}
input: {
(function(bar) {
for (;bar(); ) break;
})(function qux() {
return console.log("PASS"), qux;
});
}
expect: {
(function(bar) {
for (;bar(); ) break;
})(function qux() {
return console.log("PASS"), qux;
});
}
expect_stdout: "PASS"
}

View File

@@ -384,3 +384,73 @@ issue_1317_strict: {
expect_stdout: "1"
node_version: ">=4"
}
if_var_return: {
options = {
conditionals: true,
if_return: true,
join_vars: true,
sequences: true,
}
input: {
function f() {
var a;
return;
var b;
}
function g() {
var a;
if (u()) {
var b;
return v();
var c;
}
var d;
if (w()) {
var e;
return x();
var f;
} else {
var g;
y();
var h;
}
var i;
z();
var j;
}
}
expect: {
function f() {
var a, b;
}
function g() {
var a, b, c, d, e, f, g, h, i, j;
return u() ? v() : w() ? x() : (y(), z(), void 0);
}
}
}
if_if_return_return: {
options = {
conditionals: true,
if_return: true,
}
input: {
function f(a, b) {
if (a) {
if (b)
return b;
return;
}
g();
}
}
expect: {
function f(a, b) {
if (a)
return b || void 0;
g();
}
}
}

View File

@@ -64,3 +64,27 @@ strings_concat: {
);
}
}
regexp: {
options = {
evaluate: true,
unsafe: true,
}
input: {
RegExp("foo");
RegExp("bar", "ig");
RegExp(foo);
RegExp("bar", ig);
RegExp("should", "fail");
}
expect: {
/foo/;
/bar/ig;
RegExp(foo);
RegExp("bar", ig);
RegExp("should", "fail");
}
expect_warnings: [
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
]
}

View File

@@ -0,0 +1,32 @@
warn: {
options = {
evaluate: true,
inline: true,
passes: 2,
properties: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
return g();
}
function g() {
return g["call" + "er"].arguments;
}
// 3
console.log(f(1, 2, 3).length);
}
expect: {
// TypeError: Cannot read property 'arguments' of null
console.log(function g() {
return g.caller.arguments;
}().length);
}
expect_warnings: [
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:17,19]",
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:17,19]",
]
}

View File

@@ -569,12 +569,18 @@ native_prototype: {
}
input: {
Array.prototype.splice.apply(a, [1, 2, b, c]);
Function.prototype.call.apply(console.log, console, [ "foo" ]);
Number.prototype.toFixed.call(Math.PI, 2);
Object.prototype.hasOwnProperty.call(d, "foo");
RegExp.prototype.test.call(/foo/, "bar");
String.prototype.indexOf.call(e, "bar");
}
expect: {
[].splice.apply(a, [1, 2, b, c]);
(function() {}).call.apply(console.log, console, [ "foo" ]);
0..toFixed.call(Math.PI, 2);
({}).hasOwnProperty.call(d, "foo");
/t/.test.call(/foo/, "bar");
"".indexOf.call(e, "bar");
}
}

View File

@@ -414,3 +414,124 @@ issue_2638: {
"/* */(a()||b())(c(),d());",
]
}
issue_2705_1: {
options = {
side_effects: true,
}
beautify = {
comments: "all",
}
input: {
/*@__PURE__*/ new a();
/*@__PURE__*/ (new b());
new (/*@__PURE__*/ c)();
(/*@__PURE__*/ new d());
}
expect_exact: [
"new/* */c;",
]
}
issue_2705_2: {
options = {
side_effects: true,
}
beautify = {
comments: "all",
}
input: {
/*@__PURE__*/ new a(1)(2)(3);
/*@__PURE__*/ new (b(1))(2)(3);
/*@__PURE__*/ new (c(1)(2))(3);
/*@__PURE__*/ new (d(1)(2)(3));
new (/*@__PURE__*/ e)(1)(2)(3);
(/*@__PURE__*/ new f(1))(2)(3);
(/*@__PURE__*/ new g(1)(2))(3);
(/*@__PURE__*/ new h(1)(2)(3));
}
expect_exact: [
"new/* */e(1)(2)(3);",
"/* */new f(1)(2)(3);",
"/* */new g(1)(2)(3);",
]
}
issue_2705_3: {
options = {
side_effects: true,
}
beautify = {
comments: "all",
}
input: {
/*@__PURE__*/ new a.x(1).y(2).z(3);
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
/*@__PURE__*/ new (g.x(1).y(2).z(3));
new (/*@__PURE__*/ h).x(1).y(2).z(3);
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
(/*@__PURE__*/ new n.x(1).y(2).z(3));
}
expect_exact: [
"new/* */h.x(1).y(2).z(3);",
"/* */new/* */i.x(1).y(2).z(3);",
"/* */new j.x(1).y(2).z(3);",
"/* */new k.x(1).y(2).z(3);",
"/* */new l.x(1).y(2).z(3);",
"/* */new m.x(1).y(2).z(3);",
]
}
issue_2705_4: {
options = {
side_effects: true,
}
input: {
(/*@__PURE__*/ new x(), y());
(w(), /*@__PURE__*/ new x(), y());
}
expect: {
y();
w(), y();
}
}
issue_2705_5: {
options = {
side_effects: true,
}
input: {
[ /*@__PURE__*/ new x() ];
[ /*@__PURE__*/ new x(), y() ];
[ w(), /*@__PURE__*/ new x(), y() ];
}
expect: {
y();
w(), y();
}
}
issue_2705_6: {
options = {
side_effects: true,
}
beautify = {
comments: "all",
}
input: {
/*@__PURE__*/new (g() || h())(x(), y());
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
}
expect_exact: [
"/* */x(),y();",
"/* */new(/* */a()||b())(c(),d());",
]
}

View File

@@ -348,6 +348,57 @@ set_immutable_4: {
expect_stdout: true
}
set_immutable_5: {
options = {
collapse_vars: true,
conditionals: true,
evaluate: true,
pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
"use strict";
var a = 1;
a.foo += "";
if (a.foo) console.log("FAIL");
else console.log("PASS");
}
expect: {
"use strict";
1..foo += "";
1..foo ? console.log("FAIL") : console.log("PASS");
}
expect_stdout: true
}
set_immutable_6: {
options = {
collapse_vars: true,
conditionals: true,
evaluate: true,
pure_getters: "strict",
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unused: true,
}
input: {
var a = 1;
a.foo += "";
if (a.foo) console.log("FAIL");
else console.log("PASS");
}
expect: {
1..foo ? console.log("FAIL") : console.log("PASS");
}
expect_stdout: true
}
set_mutable_1: {
options = {
collapse_vars: true,

View File

@@ -299,7 +299,7 @@ unsafe_evaluate_modified: {
console.log(function(){ var o={p:1}; o.p++; console.log(o.p); return o.p; }());
console.log(function(){ var o={p:2}; --o.p; console.log(o.p); return o.p; }());
console.log(function(){ var o={p:3}; o.p += ""; console.log(o.p); return o.p; }());
console.log(function(){ var o={p:4}; o = {}; console.log(o.p); return o.p; }());
console.log(function(){ var o; o = {}; console.log(o.p); return o.p; }());
console.log(function(){ var o={p:5}; o.p = -9; console.log(o.p); return o.p; }());
function inc() { this.p++; }
console.log(function(){ var o={p:6}; inc.call(o); console.log(o.p); return o.p; }());
@@ -2312,8 +2312,7 @@ delay_def: {
}
expect: {
function f() {
return a;
var a;
return;
}
function g() {
return a;
@@ -2324,6 +2323,28 @@ delay_def: {
expect_stdout: true
}
delay_def_lhs: {
options = {
evaluate: true,
reduce_vars: true,
}
input: {
console.log(function() {
long_name++;
return long_name;
var long_name;
}());
}
expect: {
console.log(function() {
long_name++;
return long_name;
var long_name;
}());
}
expect_stdout: "NaN"
}
booleans: {
options = {
booleans: true,
@@ -5477,3 +5498,306 @@ issue_2670: {
expect_stdout: "PASS"
node_version: ">=6"
}
var_if: {
options = {
evaluate: true,
reduce_vars: true,
unused: true,
}
input: {
function f() {
if (x()) {
var a;
if (!g) a = true;
if (a) g();
}
}
}
expect: {
function f() {
if (x()) {
var a;
if (!g) a = true;
if (a) g();
}
}
}
}
defun_assign: {
options = {
reduce_vars: true,
toplevel: true,
}
input: {
console.log(typeof a);
a = 42;
console.log(typeof a);
function a() {}
console.log(typeof a);
}
expect: {
console.log(typeof a);
a = 42;
console.log(typeof a);
function a() {}
console.log(typeof a);
}
expect_stdout: [
"function",
"number",
"number",
]
}
defun_var_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
var a = 42, b;
function a() {}
function b() {}
console.log(typeof a, typeof b);
}
expect: {
var a = 42;
function a() {}
console.log(typeof a, "function");
}
expect_stdout: "number function"
}
defun_var_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
function a() {}
function b() {}
var a = 42, b;
console.log(typeof a, typeof b);
}
expect: {
function a() {}
var a = 42;
console.log(typeof a, "function");
}
expect_stdout: "number function"
}
defun_var_3: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
function a() {}
function b() {}
console.log(typeof a, typeof b);
var a = 42, b;
}
expect: {
function a() {}
console.log(typeof a, "function");
var a = 42;
}
expect_stdout: "function function"
}
defun_catch_1: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function a() {}
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_2: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
function a() {}
throw 42;
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_3: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
function a() {}
} catch (a) {
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
defun_catch_4: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
function a() {}
console.log(a);
}
}
expect: {
try {
throw 42;
} catch (a) {
function a() {}
console.log(a);
}
}
expect_stdout: true
}
defun_catch_5: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
console.log(a);
function a() {}
}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
function a() {}
}
}
expect_stdout: true
}
defun_catch_6: {
options = {
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
try {
throw 42;
} catch (a) {
console.log(a);
}
function a() {}
}
expect: {
try {
throw 42;
} catch (a) {
console.log(a);
}
}
expect_stdout: "42"
}
duplicate_lambda_defun_name_1: {
options = {
reduce_vars: true,
}
input: {
console.log(function f(a) {
function f() {}
return f.length;
}());
}
expect: {
console.log(function f(a) {
function f() {}
return f.length;
}());
}
expect_stdout: "0"
}
duplicate_lambda_defun_name_2: {
options = {
passes: 2,
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(a) {
function f() {}
return f.length;
}());
}
expect: {
console.log(function(a) {
return function() {}.length;
}());
}
expect_stdout: "0"
}

View File

@@ -820,3 +820,66 @@ cascade_assignment_in_return: {
}
}
}
hoist_defun: {
options = {
join_vars: true,
sequences: true,
}
input: {
x();
function f() {}
y();
}
expect: {
function f() {}
x(), y();
}
}
hoist_decl: {
options = {
join_vars: true,
sequences: true,
}
input: {
var a;
w();
var b = x();
y();
for (var c; 0;) z();
var d;
}
expect: {
var a;
w();
var b = x(), c, d;
for (y(); 0;) z();
}
}
for_init_var: {
options = {
join_vars: true,
unused: false,
}
input: {
var a = "PASS";
(function() {
var b = 42;
for (var c = 5; c > 0;) c--;
a = "FAIL";
var a;
})();
console.log(a);
}
expect: {
var a = "PASS";
(function() {
for (var b = 42, c = 5, a; c > 0;) c--;
a = "FAIL";
})();
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -100,7 +100,7 @@ typeof_defun_1: {
g = 42;
console.log("YES");
"function" == typeof g && g();
h();
"function" == typeof h && h();
}
expect_stdout: [
"YES",
@@ -138,3 +138,166 @@ typeof_defun_2: {
"2",
]
}
duplicate_defun_arg_name: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
function long_name(long_name) {
return typeof long_name;
}
console.log(typeof long_name, long_name());
}
expect: {
function long_name(long_name) {
return typeof long_name;
}
console.log(typeof long_name, long_name());
}
expect_stdout: "function undefined"
}
duplicate_lambda_arg_name: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
console.log(function long_name(long_name) {
return typeof long_name;
}());
}
expect: {
console.log(function long_name(long_name) {
return typeof long_name;
}());
}
expect_stdout: "undefined"
}
issue_2728_1: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
(function arguments() {
console.log(typeof arguments);
})();
}
expect: {
(function arguments() {
console.log(typeof arguments);
})();
}
expect_stdout: "object"
}
issue_2728_2: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
function arguments() {
return typeof arguments;
}
console.log(typeof arguments, arguments());
}
expect: {
function arguments() {
return typeof arguments;
}
console.log(typeof arguments, arguments());
}
expect_stdout: "function object"
}
issue_2728_3: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
(function() {
function arguments() {
}
console.log(typeof arguments);
})();
}
expect: {
(function() {
function arguments() {
}
console.log("function");
})();
}
expect_stdout: "function"
}
issue_2728_4: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
typeofs: true,
}
input: {
function arguments() {
}
console.log(typeof arguments);
}
expect: {
function arguments() {
}
console.log("function");
}
expect_stdout: "function"
}
issue_2728_5: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
(function arguments(arguments) {
console.log(typeof arguments);
})();
}
expect: {
(function arguments(arguments) {
console.log(typeof arguments);
})();
}
expect_stdout: "undefined"
}
issue_2728_6: {
options = {
evaluate: true,
reduce_vars: true,
typeofs: true,
}
input: {
function arguments(arguments) {
return typeof arguments;
}
console.log(typeof arguments, arguments());
}
expect: {
function arguments(arguments) {
return typeof arguments;
}
console.log(typeof arguments, arguments());
}
expect_stdout: "function undefined"
}

View File

@@ -1,4 +1,4 @@
var a = bar(1+2);
var b = baz(3+9);
print('q' + 'u' + 'x', a, b);
var x = bar(1+2);
var y = baz(3+9);
print('q' + 'u' + 'x', x, y);
foo(5+6);

View File

@@ -5,11 +5,7 @@
var site = "http://browserbench.org/JetStream";
if (typeof phantom == "undefined") {
// workaround for tty output truncation upon process.exit()
[process.stdout, process.stderr].forEach(function(stream){
if (stream._handle && stream._handle.setBlocking)
stream._handle.setBlocking(true);
});
require("../tools/exit");
var args = process.argv.slice(2);
var debug = args.indexOf("--debug");
if (debug >= 0) {

View File

@@ -220,4 +220,24 @@ describe("Comment", function() {
if (result.error) throw result.error;
assert.strictEqual(result.code, "/*a*/ /*b*/(function(){/*c*/}/*d*/ /*e*/)();");
});
it("Should output line comments after statements", function() {
var result = uglify.minify([
"x()//foo",
"{y()//bar",
"}",
].join("\n"), {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"x();//foo",
"{y();//bar",
"}",
].join("\n"));
});
});

View File

@@ -42,8 +42,15 @@ describe("minify", function() {
original += code;
compressed += result.code;
});
assert.strictEqual(JSON.stringify(cache).slice(0, 20), '{"cname":5,"props":{');
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
assert.strictEqual(JSON.stringify(cache).slice(0, 10), '{"props":{');
assert.strictEqual(compressed, [
"function n(n){return 3*n}",
"function r(n){return n/2}",
"var o=console.log.bind(console);",
'function c(n){o("Foo:",2*n)}',
"var a=n(3),b=r(12);",
'o("qux",a,b),c(11);',
].join(""));
assert.strictEqual(run_code(compressed), run_code(original));
});
@@ -68,12 +75,48 @@ describe("minify", function() {
original += code;
compressed += result.code;
});
assert.strictEqual(JSON.stringify(cache).slice(0, 28), '{"vars":{"cname":5,"props":{');
assert.strictEqual(compressed, 'function n(n){return 3*n}function r(n){return n/2}var c=console.log.bind(console);function l(o){c("Foo:",2*o)}var f=n(3),i=r(12);c("qux",f,i),l(11);');
assert.strictEqual(JSON.stringify(cache).slice(0, 18), '{"vars":{"props":{');
assert.strictEqual(compressed, [
"function n(n){return 3*n}",
"function r(n){return n/2}",
"var o=console.log.bind(console);",
'function c(n){o("Foo:",2*n)}',
"var a=n(3),b=r(12);",
'o("qux",a,b),c(11);',
].join(""));
assert.strictEqual(run_code(compressed), run_code(original));
});
it("should not parse invalid use of reserved words", function() {
it("Should avoid mangled names in cache", function() {
var cache = {};
var original = "";
var compressed = "";
[
'"xxxyy";var i={s:1};',
'"xxyyy";var j={t:2,u:3},k=4;',
'console.log(i.s,j.t,j.u,k);',
].forEach(function(code) {
var result = Uglify.minify(code, {
compress: false,
mangle: {
properties: true,
toplevel: true
},
nameCache: cache
});
if (result.error) throw result.error;
original += code;
compressed += result.code;
});
assert.strictEqual(compressed, [
'"xxxyy";var x={x:1};',
'"xxyyy";var y={y:2,a:3},a=4;',
'console.log(x.x,y.y,y.a,a);',
].join(""));
assert.strictEqual(run_code(compressed), run_code(original));
});
it("Should not parse invalid use of reserved words", function() {
assert.strictEqual(Uglify.minify("function enum(){}").error, undefined);
assert.strictEqual(Uglify.minify("function static(){}").error, undefined);
assert.strictEqual(Uglify.minify("function super(){}").error.message, "Unexpected token: name (super)");

View File

@@ -10,6 +10,7 @@ var semver = require("semver");
var tests_dir = path.dirname(module.filename);
var failures = 0;
var failed_files = {};
var minify_options = require("./ufuzz.json").map(JSON.stringify);
run_compress_tests();
if (failures) {
@@ -100,6 +101,15 @@ function run_compress_tests() {
quote_style: 3,
keep_quoted_props: true
});
try {
U.parse(input_code);
} catch (ex) {
log("!!! Cannot parse input\n---INPUT---\n{input}\n--PARSE ERROR--\n{error}\n\n", {
input: input_formatted,
error: ex,
});
return false;
}
var options = U.defaults(test.options, {
warnings: false
});
@@ -139,78 +149,77 @@ function run_compress_tests() {
output: output,
expected: expect
});
failures++;
failed_files[file] = 1;
return false;
}
else {
// expect == output
try {
var reparsed_ast = U.parse(output);
} catch (ex) {
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
// expect == output
try {
U.parse(output);
} catch (ex) {
log("!!! Test matched expected result but cannot parse output\n---INPUT---\n{input}\n---OUTPUT---\n{output}\n--REPARSE ERROR--\n{error}\n\n", {
input: input_formatted,
output: output,
error: ex,
});
return false;
}
if (test.expect_warnings) {
U.AST_Node.warn_function = original_warn_function;
var expected_warnings = make_code(test.expect_warnings, {
beautify: false,
quote_style: 2, // force double quote to match JSON
});
warnings_emitted = warnings_emitted.map(function(input) {
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
});
var actual_warnings = JSON.stringify(warnings_emitted);
if (expected_warnings != actual_warnings) {
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
input: input_formatted,
output: output,
error: ex.toString(),
expected_warnings: expected_warnings,
actual_warnings: actual_warnings,
});
failures++;
failed_files[file] = 1;
}
if (test.expect_warnings) {
U.AST_Node.warn_function = original_warn_function;
var expected_warnings = make_code(test.expect_warnings, {
beautify: false,
quote_style: 2, // force double quote to match JSON
});
warnings_emitted = warnings_emitted.map(function(input) {
return input.split(process.cwd() + path.sep).join("").split(path.sep).join("/");
});
var actual_warnings = JSON.stringify(warnings_emitted);
if (expected_warnings != actual_warnings) {
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED WARNINGS---\n{expected_warnings}\n---ACTUAL WARNINGS---\n{actual_warnings}\n\n", {
input: input_formatted,
expected_warnings: expected_warnings,
actual_warnings: actual_warnings,
});
failures++;
failed_files[file] = 1;
}
}
if (test.expect_stdout
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
var stdout = sandbox.run_code(input_code);
if (test.expect_stdout === true) {
test.expect_stdout = stdout;
}
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
actual: stdout,
});
failures++;
failed_files[file] = 1;
} else {
stdout = sandbox.run_code(output);
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
actual: stdout,
});
failures++;
failed_files[file] = 1;
}
}
return false;
}
}
if (test.expect_stdout
&& (!test.node_version || semver.satisfies(process.version, test.node_version))) {
var stdout = sandbox.run_code(input_code);
if (test.expect_stdout === true) {
test.expect_stdout = stdout;
}
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
log("!!! Invalid input or expected stdout\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
actual: stdout,
});
return false;
}
stdout = sandbox.run_code(output);
if (!sandbox.same_stdout(test.expect_stdout, stdout)) {
log("!!! failed\n---INPUT---\n{input}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
expected_type: typeof test.expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: test.expect_stdout,
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
actual: stdout,
});
return false;
}
if (!reminify(test.options, input_code, input_formatted, test.expect_stdout)) {
return false;
}
}
return true;
}
var tests = parse_test(path.resolve(dir, file));
for (var i in tests) if (tests.hasOwnProperty(i)) {
test_case(tests[i]);
if (!test_case(tests[i])) {
failures++;
failed_files[file] = 1;
}
}
}
files.forEach(function(file){
@@ -346,3 +355,46 @@ function evaluate(code) {
code = make_code(code, { beautify: true });
return new Function("return(" + code + ")")();
}
// Try to reminify original input with standard options
// to see if it matches expect_stdout.
function reminify(orig_options, input_code, input_formatted, expect_stdout) {
for (var i = 0; i < minify_options.length; i++) {
var options = JSON.parse(minify_options[i]);
if (options.compress) [
"keep_fargs",
"keep_fnames",
].forEach(function(name) {
if (name in orig_options) {
options.compress[name] = orig_options[name];
}
});
var options_formatted = JSON.stringify(options, null, 4);
var result = U.minify(input_code, options);
if (result.error) {
log("!!! failed input reminify\n---INPUT---\n{input}\n--ERROR---\n{error}\n\n", {
input: input_formatted,
error: result.error,
});
return false;
} else {
var stdout = sandbox.run_code(result.code);
if (typeof expect_stdout != "string" && typeof stdout != "string" && expect_stdout.name == stdout.name) {
stdout = expect_stdout;
}
if (!sandbox.same_stdout(expect_stdout, stdout)) {
log("!!! failed running reminified input\n---INPUT---\n{input}\n---OPTIONS---\n{options}\n---OUTPUT---\n{output}\n---EXPECTED {expected_type}---\n{expected}\n---ACTUAL {actual_type}---\n{actual}\n\n", {
input: input_formatted,
options: options_formatted,
output: result.code,
expected_type: typeof expect_stdout == "string" ? "STDOUT" : "ERROR",
expected: expect_stdout,
actual_type: typeof stdout == "string" ? "STDOUT" : "ERROR",
actual: stdout,
});
return false;
}
}
}
return true;
}

View File

@@ -6,11 +6,7 @@
// bin/uglifyjs s.js -c && bin/uglifyjs s.js -c passes=3 && bin/uglifyjs s.js -c passes=3 -m
// cat s.js | node && node s.js && bin/uglifyjs s.js -c | node && bin/uglifyjs s.js -c passes=3 | node && bin/uglifyjs s.js -c passes=3 -m | node
// workaround for tty output truncation upon process.exit()
[process.stdout, process.stderr].forEach(function(stream){
if (stream._handle && stream._handle.setBlocking)
stream._handle.setBlocking(true);
});
require("../tools/exit");
var UglifyJS = require("..");
var randomBytes = require("crypto").randomBytes;
@@ -127,6 +123,9 @@ for (var i = 2; i < process.argv.length; ++i) {
}
var VALUES = [
'"a"',
'"b"',
'"c"',
'""',
'true',
'false',