support const (#4190)
This commit is contained in:
@@ -76,9 +76,8 @@ asm_mixed: {
|
||||
start = start | 0;
|
||||
end = end | 0;
|
||||
var sum = 0.0, p = 0, q = 0;
|
||||
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0) {
|
||||
for (p = start << 3, q = end << 3; (p | 0) < (q | 0); p = p + 8 | 0)
|
||||
sum = sum + +log(values[p >> 3]);
|
||||
}
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
@@ -91,7 +90,8 @@ asm_mixed: {
|
||||
function no_asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
function logSum(start, end) {
|
||||
start |= 0, end |= 0;
|
||||
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0) sum += +log(values[p >> 3]);
|
||||
for (var sum = 0, p = 0, q = 0, p = start << 3, q = end << 3; (0 | p) < (0 | q); p = p + 8 | 0)
|
||||
sum += +log(values[p >> 3]);
|
||||
return +sum;
|
||||
}
|
||||
function geometricMean(start, end) {
|
||||
|
||||
@@ -346,9 +346,8 @@ collapse_vars_if: {
|
||||
return "x" != "Bar" + x / 4 ? g9 : g5;
|
||||
}
|
||||
function f3(x) {
|
||||
if (x) {
|
||||
if (x)
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
@@ -4192,9 +4191,8 @@ issue_2436_11: {
|
||||
if (isCollection(arg1)) {
|
||||
var size = arg1, max = arg2, min = 0, res = _randomDataForMatrix(size.valueOf(), min, max, _randomInt);
|
||||
return size && true === size.isMatrix ? matrix(res) : res;
|
||||
} else {
|
||||
} else
|
||||
return _randomInt(min = arg1, max = arg2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4310,9 +4308,8 @@ issue_2497: {
|
||||
function sample() {
|
||||
if (true)
|
||||
for (var i = 0; i < 1; ++i)
|
||||
for (var k = 0; k < 1; ++k) {
|
||||
for (var k = 0; k < 1; ++k)
|
||||
value = (value = 1) ? value + 1 : 0;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < 1; ++i)
|
||||
for (k = 0; k < 1; ++k)
|
||||
|
||||
@@ -55,14 +55,15 @@ ifs_3_should_warn: {
|
||||
}
|
||||
input: {
|
||||
var x, y;
|
||||
if (x && !(x + "1") && y) { // 1
|
||||
// 1
|
||||
if (x && !(x + "1") && y) {
|
||||
var qq;
|
||||
foo();
|
||||
} else {
|
||||
bar();
|
||||
}
|
||||
|
||||
if (x || !!(x + "1") || y) { // 2
|
||||
// 2
|
||||
if (x || !!(x + "1") || y) {
|
||||
foo();
|
||||
} else {
|
||||
var jj;
|
||||
@@ -71,9 +72,27 @@ ifs_3_should_warn: {
|
||||
}
|
||||
expect: {
|
||||
var x, y;
|
||||
var qq; bar(); // 1
|
||||
var jj; foo(); // 2
|
||||
// 1
|
||||
var qq; bar();
|
||||
// 2
|
||||
foo(); var jj;
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: + in boolean context always true [test/compress/conditionals.js:3,18]",
|
||||
"WARN: Boolean && always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Condition left of && always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Condition always false [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/conditionals.js:3,34]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/conditionals.js:4,12]",
|
||||
"WARN: + in boolean context always true [test/compress/conditionals.js:10,19]",
|
||||
"WARN: Boolean || always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Condition left of || always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Condition always true [test/compress/conditionals.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/conditionals.js:12,15]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/conditionals.js:13,12]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:3,12]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/conditionals.js:10,12]",
|
||||
]
|
||||
}
|
||||
|
||||
ifs_4: {
|
||||
|
||||
667
test/compress/const.js
Normal file
667
test/compress/const.js
Normal file
@@ -0,0 +1,667 @@
|
||||
mangle_catch_1: {
|
||||
mangle = {}
|
||||
input: {
|
||||
try {
|
||||
throw "eeeee";
|
||||
} catch (c) {
|
||||
const e = typeof d;
|
||||
}
|
||||
console.log(typeof a, typeof b);
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw "eeeee";
|
||||
} catch (e) {
|
||||
const o = typeof d;
|
||||
}
|
||||
console.log(typeof a, typeof b);
|
||||
}
|
||||
expect_stdout: "undefined undefined"
|
||||
}
|
||||
|
||||
mangle_catch_2: {
|
||||
mangle = {}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
try {} catch (e) {
|
||||
const f = 0;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function o() {
|
||||
try {} catch (c) {
|
||||
const o = 0;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
retain_block: {
|
||||
options = {}
|
||||
input: {
|
||||
{
|
||||
const a = "FAIL";
|
||||
}
|
||||
var a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = "FAIL";
|
||||
}
|
||||
var a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
if_dead_branch: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
if (0) {
|
||||
const a = 0;
|
||||
}
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
0;
|
||||
{
|
||||
const a = void 0;
|
||||
}
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
const a = console;
|
||||
console.log(typeof a);
|
||||
var b = typeof a;
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
const a = console;
|
||||
console.log(typeof a);
|
||||
var b = typeof a;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
"object",
|
||||
]
|
||||
}
|
||||
|
||||
merge_vars_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(function() {
|
||||
var b = function f() {
|
||||
const c = a && f;
|
||||
c.var += 0;
|
||||
}();
|
||||
console.log(b);
|
||||
})(1 && --a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
1 && --a,
|
||||
b = function f() {
|
||||
const c = a && f;
|
||||
c.var += 0;
|
||||
}(),
|
||||
void console.log(b);
|
||||
var b;
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
merge_vars_3: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = 0;
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
}
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = 0;
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
}
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_merge_vars: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
const a = console;
|
||||
console.log(typeof a);
|
||||
var b = typeof a;
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
b = typeof b;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
"object",
|
||||
]
|
||||
}
|
||||
|
||||
use_before_init_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
a = "foo";
|
||||
const a = "bar";
|
||||
}
|
||||
expect: {
|
||||
a = "foo";
|
||||
const a = "bar";
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
use_before_init_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
a = "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = "bar";
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
a = "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = "bar";
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
use_before_init_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
a;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = 42;
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
a;
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = 42;
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
use_before_init_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
console.log(a);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = "FAIL";
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
console.log(a);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
const a = "FAIL";
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
collapse_block: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
reduce_block_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
reduce_block_1_toplevel: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
reduce_block_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_block_2_toplevel: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = typeof console;
|
||||
console.log(a);
|
||||
}
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
hoist_props_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const o = {
|
||||
p: "PASS",
|
||||
};
|
||||
console.log(o.p);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const o = {
|
||||
p: "PASS",
|
||||
};
|
||||
console.log(o.p);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
hoist_props_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const o = {
|
||||
p: "PASS",
|
||||
};
|
||||
console.log(o.p);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o_p = "PASS";
|
||||
console.log(o_p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
loop_block_1: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
const o = console;
|
||||
console.log(typeof o.log);
|
||||
} while (!console);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
const o = console;
|
||||
console.log(typeof o.log);
|
||||
} while (!console);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
loop_block_2: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
const o = {};
|
||||
(function() {
|
||||
console.log(typeof this, o.p++);
|
||||
})();
|
||||
} while (!console);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
const o = {};
|
||||
(function() {
|
||||
console.log(typeof this, o.p++);
|
||||
})();
|
||||
} while (!console);
|
||||
}
|
||||
expect_stdout: "object NaN"
|
||||
}
|
||||
|
||||
do_continue: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
do {
|
||||
{
|
||||
const a = 0;
|
||||
continue;
|
||||
}
|
||||
} while ([ A ]);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
do {
|
||||
const a = 0;
|
||||
continue;
|
||||
} while ([ A ]);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
catch_ie8_1: {
|
||||
options = {
|
||||
ie8: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {} catch (a) {}
|
||||
console.log(function a() {
|
||||
const a = 0;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
try {} catch (a) {}
|
||||
console.log(function a() {
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
catch_ie8_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
try {} catch (a) {
|
||||
const b = 0;
|
||||
}
|
||||
try {} catch (b) {}
|
||||
console.log(function() {
|
||||
return this;
|
||||
}().b);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return this;
|
||||
}().b);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
dead_block_after_return: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
return;
|
||||
{
|
||||
const a = 0;
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
console.log(a);
|
||||
return;
|
||||
{
|
||||
const a = void 0;
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
const_to_var_scope_adjustment: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var k in [ 42 ])
|
||||
console.log(function f() {
|
||||
if (k) {
|
||||
const a = 0;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
for (var k in [ 42 ])
|
||||
console.log(void (k && 0));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
if (console) {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
var b;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} while (b);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
var b;
|
||||
}
|
||||
}
|
||||
} while (b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
do_if_continue_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
if (console) {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
A = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
} while (A);
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
A = 0;
|
||||
}
|
||||
}
|
||||
} while (A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_unused: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
const b = a, c = b;
|
||||
0 && c.p++;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
const b = a;
|
||||
b;
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
@@ -59,6 +59,11 @@ dead_code_2_should_warn: {
|
||||
f();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/dead-code.js:8,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/dead-code.js:10,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/dead-code.js:10,16]",
|
||||
]
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
@@ -89,11 +94,23 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
function bar() {}
|
||||
// nothing for the while
|
||||
// as for the for, it should keep:
|
||||
var moo;
|
||||
var x = 10, y;
|
||||
var moo;
|
||||
bar();
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: + in boolean context always true [test/compress/dead-code.js:1,33]",
|
||||
"WARN: Boolean || always true [test/compress/dead-code.js:1,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/dead-code.js:1,45]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/dead-code.js:3,12]",
|
||||
"WARN: Boolean expression always true [test/compress/dead-code.js:6,47]",
|
||||
"WARN: Boolean && always false [test/compress/dead-code.js:6,28]",
|
||||
"WARN: Dropping unreachable code [test/compress/dead-code.js:6,63]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/dead-code.js:9,12]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/dead-code.js:1,15]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/dead-code.js:6,28]",
|
||||
]
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
|
||||
@@ -90,13 +90,13 @@ non_hoisted_function_after_return_2a: {
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 36",
|
||||
"INFO: pass 0: last_count: Infinity, count: 35",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
|
||||
"INFO: pass 1: last_count: 36, count: 18",
|
||||
"INFO: pass 1: last_count: 35, count: 18",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -248,13 +248,13 @@ non_hoisted_function_after_return_2a_strict: {
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,21]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 47",
|
||||
"INFO: pass 0: last_count: Infinity, count: 46",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
"INFO: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
|
||||
"INFO: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
|
||||
"INFO: pass 1: last_count: 47, count: 29",
|
||||
"INFO: pass 1: last_count: 46, count: 29",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -547,8 +547,8 @@ dead_code_condition: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var c;
|
||||
var a = 0, b = 5;
|
||||
var c;
|
||||
a += 1, 0,
|
||||
console.log(a);
|
||||
}
|
||||
@@ -1197,3 +1197,28 @@ issue_4182_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
do_continue: {
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
do {
|
||||
continue;
|
||||
} while ([ A ]);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
do {
|
||||
continue;
|
||||
} while ([ A ]);
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -848,9 +848,8 @@ collapse_vars_1_true: {
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
for (;;)
|
||||
if (a.g() || b.p) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return;
|
||||
}
|
||||
// preserve for (var xxx; ...)
|
||||
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Var) return node;
|
||||
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node;
|
||||
// preserve for (xxx in ...)
|
||||
if (parent instanceof U.AST_ForIn && parent.init === node) return node;
|
||||
|
||||
@@ -145,7 +145,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
return permute < 2 ? expr : wrap_with_console_log(expr);
|
||||
}
|
||||
else if (node instanceof U.AST_BlockStatement) {
|
||||
if (in_list) {
|
||||
if (in_list && node.body.filter(function(node) {
|
||||
return node instanceof U.AST_Const;
|
||||
}).length == 0) {
|
||||
node.start._permute++;
|
||||
CHANGED = true;
|
||||
return List.splice(node.body);
|
||||
@@ -410,7 +412,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
||||
start: {},
|
||||
});
|
||||
}
|
||||
else if (node instanceof U.AST_Var) {
|
||||
else if (node instanceof U.AST_Definitions) {
|
||||
// remove empty var statement
|
||||
if (node.definitions.length == 0) return in_list ? List.skip : new U.AST_EmptyStatement({
|
||||
start: {},
|
||||
|
||||
@@ -275,6 +275,7 @@ var CANNOT_RETURN = true;
|
||||
var NO_DEFUN = false;
|
||||
var DEFUN_OK = true;
|
||||
var DONT_STORE = true;
|
||||
var NO_CONST = true;
|
||||
|
||||
var VAR_NAMES = [
|
||||
"a",
|
||||
@@ -312,6 +313,7 @@ var TYPEOF_OUTCOMES = [
|
||||
"crap",
|
||||
];
|
||||
|
||||
var block_vars = [];
|
||||
var unique_vars = [];
|
||||
var loops = 0;
|
||||
var funcs = 0;
|
||||
@@ -374,33 +376,66 @@ function filterDirective(s) {
|
||||
return s;
|
||||
}
|
||||
|
||||
function createBlockVariables(recurmax, stmtDepth, canThrow, fn) {
|
||||
var block_len = block_vars.length;
|
||||
var var_len = VAR_NAMES.length;
|
||||
var consts = [];
|
||||
unique_vars.push("a", "b", "c", "undefined", "NaN", "Infinity");
|
||||
while (!rng(block_vars.length > block_len ? 10 : 100)) {
|
||||
var name = createVarName(MANDATORY, DONT_STORE);
|
||||
consts.push(name);
|
||||
block_vars.push(name);
|
||||
}
|
||||
unique_vars.length -= 6;
|
||||
fn(function() {
|
||||
var s = [];
|
||||
if (consts.length) {
|
||||
var save = VAR_NAMES;
|
||||
VAR_NAMES = VAR_NAMES.filter(function(name) {
|
||||
return consts.indexOf(name) < 0;
|
||||
});
|
||||
var len = VAR_NAMES.length;
|
||||
s.push("const " + consts.map(function(name) {
|
||||
var value = createExpression(recurmax, NO_COMMA, stmtDepth, canThrow);
|
||||
VAR_NAMES.push(name);
|
||||
return name + " = " + value;
|
||||
}).join(", ") + ";");
|
||||
VAR_NAMES = save.concat(VAR_NAMES.slice(len));
|
||||
}
|
||||
return s.join("\n");
|
||||
});
|
||||
block_vars.length = block_len;
|
||||
if (consts.length) VAR_NAMES.splice(var_len, consts.length);
|
||||
}
|
||||
|
||||
function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
if (--recurmax < 0) { return ";"; }
|
||||
if (!STMT_COUNT_FROM_GLOBAL) stmtDepth = 0;
|
||||
var namesLenBefore = VAR_NAMES.length;
|
||||
var s = [];
|
||||
var name;
|
||||
if (allowDefun || rng(5) > 0) {
|
||||
name = "f" + funcs++;
|
||||
} else {
|
||||
unique_vars.push("a", "b", "c");
|
||||
name = createVarName(MANDATORY, !allowDefun);
|
||||
unique_vars.length -= 3;
|
||||
}
|
||||
var s = [
|
||||
"function " + name + "(" + createParams() + "){",
|
||||
strictMode()
|
||||
];
|
||||
if (rng(5) === 0) {
|
||||
// functions with functions. lower the recursion to prevent a mess.
|
||||
s.push(createFunctions(rng(5) + 1, Math.ceil(recurmax * 0.7), DEFUN_OK, canThrow, stmtDepth));
|
||||
} else {
|
||||
// functions with statements
|
||||
s.push(createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
}
|
||||
s.push("}", "");
|
||||
s = filterDirective(s).join("\n");
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
var namesLenBefore = VAR_NAMES.length;
|
||||
if (allowDefun || rng(5) > 0) {
|
||||
name = "f" + funcs++;
|
||||
} else {
|
||||
unique_vars.push("a", "b", "c");
|
||||
name = createVarName(MANDATORY, !allowDefun);
|
||||
unique_vars.length -= 3;
|
||||
}
|
||||
s.push("function " + name + "(" + createParams() + "){", strictMode());
|
||||
s.push(defns());
|
||||
if (rng(5) === 0) {
|
||||
// functions with functions. lower the recursion to prevent a mess.
|
||||
s.push(createFunctions(rng(5) + 1, Math.ceil(recurmax * 0.7), DEFUN_OK, canThrow, stmtDepth));
|
||||
} else {
|
||||
// functions with statements
|
||||
s.push(_createStatements(3, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth));
|
||||
}
|
||||
s.push("}", "");
|
||||
s = filterDirective(s).join("\n");
|
||||
|
||||
VAR_NAMES.length = namesLenBefore;
|
||||
VAR_NAMES.length = namesLenBefore;
|
||||
});
|
||||
|
||||
if (!allowDefun) {
|
||||
// avoid "function statements" (decl inside statements)
|
||||
@@ -414,7 +449,7 @@ function createFunction(recurmax, allowDefun, canThrow, stmtDepth) {
|
||||
return s + ";";
|
||||
}
|
||||
|
||||
function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||
function _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||
if (--recurmax < 0) { return ";"; }
|
||||
var s = "";
|
||||
while (--n > 0) {
|
||||
@@ -423,6 +458,15 @@ function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotRe
|
||||
return s;
|
||||
}
|
||||
|
||||
function createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) {
|
||||
var s = "";
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
s += defns() + "\n";
|
||||
s += _createStatements(n, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
||||
});
|
||||
return s;
|
||||
}
|
||||
|
||||
function enableLoopControl(flag, defaultValue) {
|
||||
return Array.isArray(flag) && flag.indexOf("") < 0 ? flag.concat("") : flag || defaultValue;
|
||||
}
|
||||
@@ -496,7 +540,7 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
var label = createLabel(canBreak, canContinue);
|
||||
canBreak = label.break || enableLoopControl(canBreak, CAN_BREAK);
|
||||
canContinue = label.continue || enableLoopControl(canContinue, CAN_CONTINUE);
|
||||
var key = rng(10) ? "key" + loop : getVarName();
|
||||
var key = rng(10) ? "key" + loop : getVarName(NO_CONST);
|
||||
return [
|
||||
"{var expr" + loop + " = " + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "; ",
|
||||
label.target + " for (",
|
||||
@@ -571,13 +615,18 @@ function createStatement(recurmax, canThrow, canBreak, canContinue, cannotReturn
|
||||
// the catch var should only be accessible in the catch clause...
|
||||
// we have to do go through some trouble here to prevent leaking it
|
||||
var nameLenBefore = VAR_NAMES.length;
|
||||
var catchName = createVarName(MANDATORY);
|
||||
var freshCatchName = VAR_NAMES.length !== nameLenBefore;
|
||||
if (!catch_redef) unique_vars.push(catchName);
|
||||
s += " catch (" + catchName + ") { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
||||
// remove catch name
|
||||
if (!catch_redef) unique_vars.pop();
|
||||
if (freshCatchName) VAR_NAMES.splice(nameLenBefore, 1);
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
var catchName = createVarName(MANDATORY);
|
||||
var freshCatchName = VAR_NAMES.length !== nameLenBefore;
|
||||
if (!catch_redef) unique_vars.push(catchName);
|
||||
s += " catch (" + catchName + ") { ";
|
||||
s += defns() + "\n";
|
||||
s += _createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth);
|
||||
s += " }";
|
||||
// remove catch name
|
||||
if (!catch_redef) unique_vars.pop();
|
||||
if (freshCatchName) VAR_NAMES.splice(nameLenBefore, 1);
|
||||
});
|
||||
}
|
||||
if (n !== 0) s += " finally { " + createStatements(3, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth) + " }";
|
||||
return s;
|
||||
@@ -597,7 +646,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
||||
if (hadDefault || rng(5) > 0) {
|
||||
s.push(
|
||||
"case " + createExpression(recurmax, NO_COMMA, stmtDepth, canThrow) + ":",
|
||||
createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
_createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
rng(10) > 0 ? " break;" : "/* fall-through */",
|
||||
""
|
||||
);
|
||||
@@ -605,7 +654,7 @@ function createSwitchParts(recurmax, n, canThrow, canBreak, canContinue, cannotR
|
||||
hadDefault = true;
|
||||
s.push(
|
||||
"default:",
|
||||
createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
_createStatements(rng(3) + 1, recurmax, canThrow, canBreak, canContinue, cannotReturn, stmtDepth),
|
||||
""
|
||||
);
|
||||
}
|
||||
@@ -653,7 +702,7 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
case p++:
|
||||
return getVarName();
|
||||
case p++:
|
||||
return getVarName() + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||
return getVarName(NO_CONST) + createAssignment() + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||
case p++:
|
||||
return createExpression(recurmax, COMMA_OK, stmtDepth, canThrow);
|
||||
case p++:
|
||||
@@ -699,19 +748,22 @@ function _createExpression(recurmax, noComma, stmtDepth, canThrow) {
|
||||
);
|
||||
break;
|
||||
default:
|
||||
var instantiate = rng(4) ? "new " : "";
|
||||
s.push(
|
||||
instantiate + "function " + name + "(){",
|
||||
strictMode()
|
||||
);
|
||||
if (instantiate) for (var i = rng(4); --i >= 0;) {
|
||||
if (rng(2)) s.push("this." + getDotKey(true) + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";");
|
||||
else s.push("this[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]" + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";");
|
||||
}
|
||||
s.push(
|
||||
createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
rng(2) == 0 ? "}" : "}()"
|
||||
);
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
var instantiate = rng(4) ? "new " : "";
|
||||
s.push(
|
||||
instantiate + "function " + name + "(){",
|
||||
strictMode(),
|
||||
defns()
|
||||
);
|
||||
if (instantiate) for (var i = rng(4); --i >= 0;) {
|
||||
if (rng(2)) s.push("this." + getDotKey(true) + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";");
|
||||
else s.push("this[" + createExpression(recurmax, COMMA_OK, stmtDepth, canThrow) + "]" + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ";");
|
||||
}
|
||||
s.push(
|
||||
_createStatements(rng(5) + 1, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
rng(2) == 0 ? "}" : "}()"
|
||||
);
|
||||
});
|
||||
break;
|
||||
}
|
||||
VAR_NAMES.length = nameLenBefore;
|
||||
@@ -861,13 +913,16 @@ function createAccessor(recurmax, stmtDepth, canThrow) {
|
||||
do {
|
||||
prop2 = getDotKey();
|
||||
} while (prop1 == prop2);
|
||||
s = [
|
||||
"set " + prop1 + "(" + createVarName(MANDATORY) + "){",
|
||||
strictMode(),
|
||||
createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
"this." + prop2 + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";",
|
||||
"},"
|
||||
];
|
||||
createBlockVariables(recurmax, stmtDepth, canThrow, function(defns) {
|
||||
s = [
|
||||
"set " + prop1 + "(" + createVarName(MANDATORY) + "){",
|
||||
strictMode(),
|
||||
defns(),
|
||||
_createStatements(2, recurmax, canThrow, CANNOT_BREAK, CANNOT_CONTINUE, CAN_RETURN, stmtDepth),
|
||||
"this." + prop2 + createAssignment() + _createBinaryExpr(recurmax, COMMA_OK, stmtDepth, canThrow) + ";",
|
||||
"},"
|
||||
];
|
||||
});
|
||||
}
|
||||
VAR_NAMES.length = namesLenBefore;
|
||||
return filterDirective(s).join("\n");
|
||||
@@ -906,7 +961,7 @@ function _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) {
|
||||
case 1:
|
||||
return "(" + createUnarySafePrefix() + "(" + _createSimpleBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + "))";
|
||||
case 2:
|
||||
assignee = getVarName();
|
||||
assignee = getVarName(NO_CONST);
|
||||
return "(" + assignee + createAssignment() + _createBinaryExpr(recurmax, noComma, stmtDepth, canThrow) + ")";
|
||||
case 3:
|
||||
assignee = getVarName();
|
||||
@@ -968,9 +1023,10 @@ function createUnaryPostfix() {
|
||||
return UNARY_POSTFIX[rng(UNARY_POSTFIX.length)];
|
||||
}
|
||||
|
||||
function getVarName() {
|
||||
function getVarName(noConst) {
|
||||
// try to get a generated name reachable from current scope. default to just `a`
|
||||
return VAR_NAMES[INITIAL_NAMES_LEN + rng(VAR_NAMES.length - INITIAL_NAMES_LEN)] || "a";
|
||||
var name = VAR_NAMES[INITIAL_NAMES_LEN + rng(VAR_NAMES.length - INITIAL_NAMES_LEN)];
|
||||
return !name || noConst && block_vars.indexOf(name) >= 0 ? "a" : name;
|
||||
}
|
||||
|
||||
function createVarName(maybe, dontStore) {
|
||||
@@ -980,7 +1036,7 @@ function createVarName(maybe, dontStore) {
|
||||
do {
|
||||
name = VAR_NAMES[rng(VAR_NAMES.length)];
|
||||
if (suffix) name += "_" + suffix;
|
||||
} while (unique_vars.indexOf(name) >= 0);
|
||||
} while (unique_vars.indexOf(name) >= 0 || block_vars.indexOf(name) >= 0);
|
||||
if (suffix && !dontStore) VAR_NAMES.push(name);
|
||||
return name;
|
||||
}
|
||||
@@ -1258,10 +1314,6 @@ function patch_try_catch(orig, toplevel) {
|
||||
}
|
||||
}
|
||||
|
||||
var fallback_options = [ JSON.stringify({
|
||||
compress: false,
|
||||
mangle: false
|
||||
}) ];
|
||||
var minify_options = require("./options.json").map(JSON.stringify);
|
||||
var original_code, original_result, errored;
|
||||
var uglify_code, uglify_result, ok;
|
||||
@@ -1269,10 +1321,19 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
process.stdout.write(round + " of " + num_iterations + "\r");
|
||||
|
||||
original_code = createTopLevelCode();
|
||||
var orig_result = [ sandbox.run_code(original_code) ];
|
||||
var orig_result = [ sandbox.run_code(original_code), sandbox.run_code(original_code, true) ];
|
||||
errored = typeof orig_result[0] != "string";
|
||||
if (!errored) orig_result.push(sandbox.run_code(original_code, true));
|
||||
(errored ? fallback_options : minify_options).forEach(function(options) {
|
||||
if (errored) {
|
||||
println("//=============================================================");
|
||||
println("// original code");
|
||||
try_beautify(original_code, false, orig_result[0], println);
|
||||
println();
|
||||
println();
|
||||
println("original result:");
|
||||
println(orig_result[0]);
|
||||
println();
|
||||
}
|
||||
minify_options.forEach(function(options) {
|
||||
var o = JSON.parse(options);
|
||||
var toplevel = sandbox.has_toplevel(o);
|
||||
o.validate = true;
|
||||
@@ -1294,6 +1355,8 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
ok = sandbox.same_stdout(fuzzy_result, uglify_result);
|
||||
}
|
||||
}
|
||||
// ignore difference in error message caused by Temporal Dead Zone
|
||||
if (!ok && errored) ok = uglify_result.name == "ReferenceError" && original_result.name == "ReferenceError";
|
||||
// ignore difference in error message caused by `in`
|
||||
// ignore difference in depth of termination caused by infinite recursion
|
||||
if (!ok) {
|
||||
@@ -1308,16 +1371,6 @@ for (var round = 1; round <= num_iterations; round++) {
|
||||
ok = errored && uglify_code.name == original_result.name;
|
||||
}
|
||||
if (verbose || (verbose_interval && !(round % INTERVAL_COUNT)) || !ok) log(options);
|
||||
else if (errored) {
|
||||
println("//=============================================================");
|
||||
println("// original code");
|
||||
try_beautify(original_code, toplevel, original_result, println);
|
||||
println();
|
||||
println();
|
||||
println("original result:");
|
||||
println(original_result);
|
||||
println();
|
||||
}
|
||||
if (!ok && isFinite(num_iterations)) {
|
||||
println();
|
||||
process.exit(1);
|
||||
|
||||
Reference in New Issue
Block a user