Compare commits

...

48 Commits

Author SHA1 Message Date
Alex Lam S.L
fe19ab7c57 v3.7.2 2019-12-08 15:36:18 +00:00
Alex Lam S.L
9074f05129 fix corner case in collapse_vars (#3629)
fixes #3628
2019-12-05 05:08:37 +08:00
Alex Lam S.L
04fbb1f949 avoid collision with HTML comments (#3625)
fixes #3624
2019-12-05 02:43:25 +08:00
Alex Lam S.L
bf7e4ca1a3 fix corner case in collapse_vars (#3627)
fixes #3626
2019-12-05 00:59:57 +08:00
Alex Lam S.L
d68ddc31f9 fix corner case in reduce_vars (#3623)
fixes #3622
2019-12-04 20:24:55 +08:00
Alex Lam S.L
500e31e03b enhance collapse_vars (#3621) 2019-12-02 15:25:38 +08:00
Alex Lam S.L
bef856addb fix corner case in keep_fargs (#3620)
fixes #3619
2019-12-02 12:28:17 +08:00
Alex Lam S.L
9a6faf365b fix corner cases in keep_fargs & unused (#3618) 2019-12-02 06:43:54 +08:00
Alex Lam S.L
e915832a36 enhance unused (#3617) 2019-12-01 18:10:37 +08:00
Alex Lam S.L
0593892d6e enhance collapse_vars (#3616) 2019-12-01 02:31:04 +08:00
Alex Lam S.L
b866a23671 v3.7.1 2019-11-30 06:02:09 +08:00
Alex Lam S.L
1283d73853 fix corner case in parsing directives (#3615) 2019-11-29 18:57:29 +08:00
Alex Lam S.L
1b61a81b5d enhance collapse_vars (#3613) 2019-11-29 17:45:49 +08:00
Alex Lam S.L
5a88c30d65 enhance assignments (#3612) 2019-11-28 07:40:34 +08:00
Alex Lam S.L
168ae747ad enhance collapse_vars (#3611) 2019-11-28 03:57:10 +08:00
Alex Lam S.L
d4b7010678 fix corner case in unsafe_regexp (#3609) 2019-11-27 17:35:21 +08:00
Alex Lam S.L
e27493f3c2 fix corner case in inline (#3608) 2019-11-27 14:54:36 +08:00
Alex Lam S.L
292d1de363 use stable Node.js version for fuzzing (#3605) 2019-11-26 02:11:11 +08:00
Alex Lam S.L
6768e6578f inline functions with directives more effectively (#3604) 2019-11-26 01:51:04 +08:00
Alex Lam S.L
48a0f6fe41 enhance unsafe_math (#3603) 2019-11-25 21:14:13 +08:00
Alex Lam S.L
81caadb709 enhance collapse_vars (#3602) 2019-11-20 12:54:49 +08:00
Alex Lam S.L
d959e0b86f fix corner case in if_return (#3601)
fixes #3600
2019-11-19 15:45:20 +08:00
Alex Lam S.L
67278e76c8 fix corner case in unused (#3599)
fixes #3598
2019-11-19 04:26:41 +08:00
Alex Lam S.L
c289ba1139 fix corner case in collapse_vars (#3597)
fixes #3596
2019-11-19 02:30:52 +08:00
Alex Lam S.L
02cc4a0d03 v3.7.0 2019-11-18 20:21:07 +08:00
Alex Lam S.L
4e06e1ca34 fix corner case in inline (#3595) 2019-11-18 15:04:55 +08:00
Alex Lam S.L
644f65feca fix corner case in unsafe_math (#3594)
fixes #3593
2019-11-18 13:44:13 +08:00
Alex Lam S.L
8504a4ea0e fix corner case in reduce_funcs (#3592) 2019-11-17 11:19:42 +08:00
Alex Lam S.L
10c1a78772 fix corner case in collapse_vars (#3591) 2019-11-17 05:24:02 +08:00
Alex Lam S.L
a6a0319f1c compress empty for-in loops (#3590) 2019-11-17 02:36:42 +08:00
Alex Lam S.L
d1b2ecec27 refine precision limits on unsafe_math (#3589) 2019-11-17 01:16:42 +08:00
Alex Lam S.L
552be61c4d introduce eager evaluation (#3587) 2019-11-16 06:10:47 +08:00
Alex Lam S.L
dcfc4aca5b minor clean-ups (#3588) 2019-11-16 00:40:22 +08:00
Alex Lam S.L
4027f87717 migrate to GitHub Actions (#3586) 2019-11-14 10:48:32 +08:00
Alex Lam S.L
910799ca99 fix corner case in switches (#3585) 2019-11-14 02:29:55 +08:00
Alex Lam S.L
4bd36dc8da enhance unused (#3584) 2019-11-13 21:44:44 +08:00
Alex Lam S.L
ab15c40770 enhance switches (#3583) 2019-11-13 20:03:48 +08:00
Alex Lam S.L
fe65ce9658 fix corner case in collapse_vars (#3582)
fixes #3581
2019-11-13 16:45:16 +08:00
Alex Lam S.L
d6fd18d0b0 enhance evaluate & inline (#3580) 2019-11-13 04:17:09 +08:00
Alex Lam S.L
0d17c5b0fa v3.6.9 2019-11-12 22:50:52 +08:00
Alex Lam S.L
5b20bad4b3 fix corner case in dead_code (#3579)
fixes #3578
2019-11-12 05:16:14 +08:00
Alex Lam S.L
765a06340f enable cache on GitHub Actions (#3570) 2019-11-10 09:06:48 +08:00
Alex Lam S.L
5045e140b1 fix corner case in conditionals (#3577)
fixes #3576
2019-11-09 00:53:15 +08:00
Alex Lam S.L
10648c9af6 enhance dead_code (#3575) 2019-11-08 13:45:28 +08:00
Alex Lam S.L
87e67ec299 fix corner case in collapse_vars (#3574)
fixes #3573
2019-11-07 20:38:03 +08:00
Alex Lam S.L
61a0dad9fe v3.6.8 2019-11-06 13:52:58 +08:00
Alex Lam S.L
3e2c51a4da enhance collapse_vars (#3572) 2019-11-05 18:15:28 +08:00
Alex Lam S.L
0e29ad5eb9 fix corner case in evaluate (#3569) 2019-11-04 13:13:48 +08:00
32 changed files with 3439 additions and 698 deletions

View File

@@ -14,13 +14,17 @@ jobs:
TYPE: ${{ matrix.script }}
steps:
- uses: actions/checkout@v1
- shell: bash
- uses: actions/cache@v1
with:
path: tmp
key: tmp ${{ matrix.script }}
- name: Perform tests
shell: bash
run: |
git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh
nvs --version
nvs add node/$NODE
nvs use node/$NODE
git clone --branch v1.5.3 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh --version
nvs add $NODE
nvs use $NODE
node --version
npm --version --no-update-notifier
npm install --no-audit --no-optional --no-save --no-update-notifier

View File

@@ -12,13 +12,13 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v1
- shell: bash
- name: Perform fuzzing
shell: bash
run: |
git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh
nvs --version
nvs add node
nvs use node
git clone --branch v1.5.3 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
. ~/.nvs/nvs.sh --version
nvs add 10
nvs use 10
node --version
npm --version --no-update-notifier
npm install --no-audit --no-optional --no-save --no-update-notifier

View File

@@ -1,46 +0,0 @@
cache:
directories: tmp
language: shell
matrix:
fast_finish: true
env:
- NODE=0.10 TYPE=compress
- NODE=0.10 TYPE=mocha
- NODE=0.10 TYPE=release/benchmark
- NODE=0.10 TYPE=release/jetstream
- NODE=0.12 TYPE=compress
- NODE=0.12 TYPE=mocha
- NODE=0.12 TYPE=release/benchmark
- NODE=0.12 TYPE=release/jetstream
- NODE=4 TYPE=compress
- NODE=4 TYPE=mocha
- NODE=4 TYPE=release/benchmark
- NODE=4 TYPE=release/jetstream
- NODE=6 TYPE=compress
- NODE=6 TYPE=mocha
- NODE=6 TYPE=release/benchmark
- NODE=6 TYPE=release/jetstream
- NODE=8 TYPE=compress
- NODE=8 TYPE=mocha
- NODE=8 TYPE=release/benchmark
- NODE=8 TYPE=release/jetstream
- NODE=10 TYPE=compress
- NODE=10 TYPE=mocha
- NODE=10 TYPE=release/benchmark
- NODE=10 TYPE=release/jetstream
- NODE=latest TYPE=compress
- NODE=latest TYPE=mocha
- NODE=latest TYPE=release/benchmark
- NODE=latest TYPE=release/jetstream
before_install:
- git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
- . ~/.nvs/nvs.sh
- nvs --version
install:
- nvs add node/$NODE
- nvs use node/$NODE
- node --version
- npm --version --no-update-notifier
- npm install --no-audit --no-optional --no-save --no-update-notifier
script:
- node test/$TYPE

View File

@@ -631,7 +631,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
- `evaluate` (default: `true`) -- attempt to evaluate constant expressions
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
representation. Pass `"eager"` to always replace function calls whenever
possible, or a positive integer to specify an upper bound for each individual
evaluation in number of characters.
- `expression` (default: `false`) -- Pass `true` to preserve completion values
from terminal statements without `return`, e.g. in bookmarklets.

View File

@@ -1,74 +1,5 @@
build: off
cache:
- tmp
matrix:
fast_finish: true
environment:
matrix:
- NODE: 0.10
TYPE: compress
- NODE: 0.10
TYPE: mocha
- NODE: 0.10
TYPE: release/benchmark
- NODE: 0.10
TYPE: release/jetstream
- NODE: 0.12
TYPE: compress
- NODE: 0.12
TYPE: mocha
- NODE: 0.12
TYPE: release/benchmark
- NODE: 0.12
TYPE: release/jetstream
- NODE: 4
TYPE: compress
- NODE: 4
TYPE: mocha
- NODE: 4
TYPE: release/benchmark
- NODE: 4
TYPE: release/jetstream
- NODE: 6
TYPE: compress
- NODE: 6
TYPE: mocha
- NODE: 6
TYPE: release/benchmark
- NODE: 6
TYPE: release/jetstream
- NODE: 8
TYPE: compress
- NODE: 8
TYPE: mocha
- NODE: 8
TYPE: release/benchmark
- NODE: 8
TYPE: release/jetstream
- NODE: 10
TYPE: compress
- NODE: 10
TYPE: mocha
- NODE: 10
TYPE: release/benchmark
- NODE: 10
TYPE: release/jetstream
- NODE: latest
TYPE: compress
- NODE: latest
TYPE: mocha
- NODE: latest
TYPE: release/benchmark
- NODE: latest
TYPE: release/jetstream
install:
- git clone --branch v1.5.2 --depth 1 https://github.com/jasongin/nvs.git %LOCALAPPDATA%\nvs
- set PATH=%LOCALAPPDATA%\nvs;%PATH%
- nvs --version
- nvs add node/%NODE%
- nvs use node/%NODE%
- node --version
- npm --version --no-update-notifier
- npm install --no-audit --no-optional --no-save --no-update-notifier
test_script:
- node test/%TYPE%
- echo No longer in use

File diff suppressed because it is too large Load Diff

View File

@@ -252,7 +252,7 @@ function minify(files, options) {
properties: 1e-3 * (timings.output - timings.properties),
output: 1e-3 * (timings.end - timings.output),
total: 1e-3 * (timings.end - timings.start)
}
};
}
if (warnings.length) {
result.warnings = warnings;

View File

@@ -269,7 +269,7 @@ function OutputStream(options) {
}
}
newline_insert = -1;
var prev = last.charAt(last.length - 1);
var prev = last.slice(-1);
if (might_need_semicolon) {
might_need_semicolon = false;
@@ -298,16 +298,16 @@ function OutputStream(options) {
}
if (might_need_space) {
if ((is_identifier_char(prev)
&& (is_identifier_char(ch) || ch == "\\"))
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|| (ch == "/" && ch == prev)
|| ((ch == "+" || ch == "-") && ch == last))
{
|| ((ch == "+" || ch == "-") && ch == last)
|| str == "--" && last == "!"
|| last == "--" && ch == ">") {
OUTPUT += " ";
current_col++;
current_pos++;
}
might_need_space = false;
if (prev != "<" || str != "!") might_need_space = false;
}
if (mapping_token) {
@@ -322,7 +322,7 @@ function OutputStream(options) {
}
OUTPUT += str;
has_parens = str[str.length - 1] == "(";
has_parens = str.slice(-1) == "(";
current_pos += str.length;
var a = str.split(/\r?\n/), n = a.length - 1;
current_line += n;
@@ -711,16 +711,23 @@ function OutputStream(options) {
PARENS(AST_Sequence, function(output) {
var p = output.parent();
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST_Unary // !(foo, bar, baz)
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
* ==> 20 (side effect, set a := 10 and b := 20) */
;
// (foo, bar)() or foo(1, (2, 3), 4)
return p instanceof AST_Call
// !(foo, bar, baz)
|| p instanceof AST_Unary
// 1 + (2, 3) + 4 ==> 8
|| p instanceof AST_Binary
// var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST_VarDef
// (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST_PropAccess && p.expression === this
// [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST_Array
// { foo: (1, 2) }.foo ==> 2
|| p instanceof AST_ObjectProperty
// (false, true) ? (a = 10, b = 20) : (c = 30)
// ==> 20 (side effect, set a := 10 and b := 20)
|| p instanceof AST_Conditional;
});
PARENS(AST_Binary, function(output) {
@@ -1247,29 +1254,10 @@ function OutputStream(options) {
output.print(self.operator);
});
DEFPRINT(AST_Binary, function(self, output) {
var op = self.operator;
self.left.print(output);
if (op[0] == ">" /* ">>" ">>>" ">" ">=" */
&& self.left instanceof AST_UnaryPostfix
&& self.left.operator == "--") {
// space is mandatory to avoid outputting -->
output.print(" ");
} else {
// the space is optional depending on "beautify"
output.space();
}
output.print(op);
if ((op == "<" || op == "<<")
&& self.right instanceof AST_UnaryPrefix
&& self.right.operator == "!"
&& self.right.expression instanceof AST_UnaryPrefix
&& self.right.expression.operator == "--") {
// space is mandatory to avoid outputting <!--
output.print(" ");
} else {
// the space is optional depending on "beautify"
output.space();
}
output.space();
output.print(self.operator);
output.space();
self.right.print(output);
});
DEFPRINT(AST_Conditional, function(self, output) {

View File

@@ -787,20 +787,18 @@ function parse($TEXT, options) {
handle_regexp();
switch (S.token.type) {
case "string":
if (S.in_directives) {
var token = peek();
if (S.token.raw.indexOf("\\") == -1
&& (is_token(token, "punc", ";")
|| is_token(token, "punc", "}")
|| has_newline_before(token)
|| is_token(token, "eof"))) {
S.input.add_directive(S.token.value);
var dir = S.in_directives;
var body = expression(true);
if (dir) {
var token = body.start;
if (body instanceof AST_String && token.raw.indexOf("\\") == -1) {
S.input.add_directive(token.value);
} else {
S.in_directives = false;
S.in_directives = dir = false;
}
}
var dir = S.in_directives, stat = simple_statement();
return dir ? new AST_Directive(stat.body) : stat;
semicolon();
return dir ? new AST_Directive(body) : new AST_SimpleStatement({ body: body });
case "num":
case "regexp":
case "operator":
@@ -965,8 +963,10 @@ function parse($TEXT, options) {
return new AST_LabeledStatement({ body: stat, label: label });
}
function simple_statement(tmp) {
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
function simple_statement() {
var body = expression(true);
semicolon();
return new AST_SimpleStatement({ body: body });
}
function break_cont(type) {

View File

@@ -3,7 +3,7 @@
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
"license": "BSD-2-Clause",
"version": "3.6.7",
"version": "3.7.2",
"engines": {
"node": ">=0.8.0"
},

View File

@@ -290,26 +290,60 @@ increment_decrement_2: {
expect_stdout: "42"
}
issue_3375: {
issue_3375_1: {
options = {
assignments: true,
reduce_vars: true,
}
input: {
console.log(typeof function(b) {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b += 1;
--b;
return a;
}("object"));
}
expect: {
console.log(typeof function(b) {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b += 1;
--b;
return a;
}("object"));
}
expect_stdout: "string"
expect_stdout: "string object1"
}
issue_3375_2: {
options = {
assignments: true,
reduce_vars: true,
}
input: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = b -= 1;
--b;
return a;
}("object"));
}
expect: {
function p(o) {
console.log(typeof o, o);
}
p(function(b) {
var a = --b;
--b;
return a;
}("object"));
}
expect_stdout: "number NaN"
}
issue_3427: {

File diff suppressed because it is too large Load Diff

View File

@@ -1489,3 +1489,29 @@ angularjs_chain: {
}
}
}
issue_3576: {
options = {
conditionals: true,
evaluate: true,
pure_getters: "strict",
reduce_vars: true,
}
input: {
var c = "FAIL";
(function(a) {
(a = -1) ? (a && (a.a = 0)) : (a && (a.a = 0));
a && a[c = "PASS"]++;
})();
console.log(c);
}
expect: {
var c = "FAIL";
(function(a) {
a = -1, a, a.a = 0;
a, a[c = "PASS"]++;
})();
console.log(c);
}
expect_stdout: "PASS"
}

View File

@@ -892,9 +892,7 @@ issue_2860_1: {
}());
}
expect: {
console.log(function(a) {
return 1 ^ a;
}());
console.log(1);
}
expect_stdout: "1"
}
@@ -1064,3 +1062,68 @@ issue_3552: {
}
expect_stdout: "PASS"
}
unreachable_assign: {
options = {
dead_code: true,
}
input: {
console.log(A = "P" + (A = "A" + (B = "S" + (A = B = "S"))), A, B);
}
expect: {
console.log(A = "P" + "A" + (B = "S" + "S"), A, B);
}
expect_stdout: "PASS PASS SS"
}
catch_return_assign: {
options = {
dead_code: true,
}
input: {
console.log(function() {
try {
throw "FAIL";
} catch (e) {
return e = "PASS";
}
}());
}
expect: {
console.log(function() {
try {
throw "FAIL";
} catch (e) {
return "PASS";
}
}());
}
expect_stdout: "PASS"
}
issue_3578: {
options = {
dead_code: true,
}
input: {
var a = "FAIL", b, c;
try {
b = c.p = b = 0;
} catch (e) {
b += 42;
b && (a = "PASS");
}
console.log(a);
}
expect: {
var a = "FAIL", b, c;
try {
b = c.p = b = 0;
} catch (e) {
b += 42;
b && (a = "PASS");
}
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -0,0 +1,95 @@
simple_statement_is_not_a_directive: {
input: {
"use strict"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
(function() {
"directive"
""
"use strict"
"hello world"
.split(" ")
.forEach(function(s) {
console.log(s);
});
console.log(!this); // is strict mode?
})();
}
expect: {
"use strict".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
(function() {
"directive";
"";
"use strict";
"hello world".split(" ").forEach(function(s) {
console.log(s);
});
console.log(!this);
})();
}
expect_stdout: [
"use",
"strict",
"false",
"hello",
"world",
"true",
]
}
drop_lone_use_strict: {
options = {
directives: true,
side_effects: true,
}
input: {
function f1() {
"use strict";
}
function f2() {
"use strict";
function f3() {
"use strict";
}
}
(function f4() {
"use strict";
})();
}
expect: {
function f1() {
}
function f2() {
"use strict";
function f3() {
}
}
}
}
issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}

View File

@@ -1019,14 +1019,21 @@ delete_assign_1: {
console.log(delete (a = 0 / 0));
}
expect: {
console.log((void 0, !0));
console.log((void 0, !0));
console.log((1 / 0, !0));
console.log((1 / 0, !0));
console.log((NaN, !0));
console.log((NaN, !0));
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
}
expect_stdout: true
expect_stdout: [
"true",
"true",
"true",
"true",
"true",
"true",
]
}
delete_assign_2: {
@@ -1047,14 +1054,21 @@ delete_assign_2: {
console.log(delete (a = 0 / 0));
}
expect: {
console.log((void 0, !0));
console.log((void 0, !0));
console.log((Infinity, !0));
console.log((1 / 0, !0));
console.log((NaN, !0));
console.log((NaN, !0));
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
console.log(!0);
}
expect_stdout: true
expect_stdout: [
"true",
"true",
"true",
"true",
"true",
"true",
]
}
drop_var: {
@@ -1635,7 +1649,7 @@ double_assign_2: {
}
expect: {
for (var i = 0; i < 2; i++)
void 0, a = {}, console.log(a);
a = {}, console.log(a);
var a;
}
}
@@ -1716,7 +1730,7 @@ issue_2768: {
}
expect: {
var a = "FAIL";
var c = (d = a, 0, void (d && (a = "PASS")));
var c = (d = a, void (d && (a = "PASS")));
var d;
console.log(a, typeof c);
}
@@ -2221,3 +2235,34 @@ function_assign: {
}
expect_stdout: "PASS"
}
issue_3598: {
options = {
collapse_vars: true,
reduce_vars: true,
unused: true,
}
input: {
var a = "FAIL";
try {
(function() {
var b = void 0;
a = "PASS";
c.p = 0;
var c = b[!1];
})();
} catch (e) {}
console.log(a);
}
expect: {
var a = "FAIL";
try {
(function() {
a = "PASS";
var c = (void (c.p = 0))[!1];
})();
} catch (e) {}
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -1876,3 +1876,288 @@ issue_3558: {
}
expect_stdout: "1 0"
}
issue_3568: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unsafe: true,
}
input: {
var a = 0;
function f(b) {
return b && b.p;
}
console.log(f(++a + f()));
}
expect: {
var a = 0;
function f(b) {
return b && b.p;
}
console.log(NaN);
}
expect_stdout: "NaN"
}
conditional_function: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
function f(a) {
return a && "undefined" != typeof A ? A : 42;
}
console.log(f(0), f(1));
}
expect: {
function f(a) {
return a && "undefined" != typeof A ? A : 42;
}
console.log(42, f(1));
}
expect_stdout: "42 42"
}
best_of_evaluate: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function d(x, y) {
return x / y;
}
console.log(0 / 3, 1 / 64, 4 / 7, 7 / 7);
console.log(d(0, 3), d(1, 64), d(4, 7), d(7, 7));
}
expect: {
function d(x, y) {
return x / y;
}
console.log(0, 1 / 64, 4 / 7, 1);
console.log(0, .015625, d(4, 7), 1);
}
expect_stdout: [
"0 0.015625 0.5714285714285714 1",
"0 0.015625 0.5714285714285714 1",
]
}
eager_evaluate: {
options = {
evaluate: "eager",
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function d(x, y) {
return x / y;
}
console.log(0 / 3, 1 / 64, 4 / 7, 7 / 7);
console.log(d(0, 3), d(1, 64), d(4, 7), d(7, 7));
}
expect: {
console.log(0, .015625, .5714285714285714, 1);
console.log(0, .015625, .5714285714285714, 1);
}
expect_stdout: [
"0 0.015625 0.5714285714285714 1",
"0 0.015625 0.5714285714285714 1",
]
}
threshold_evaluate_default: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function b(x) {
return x + x + x;
}
console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK"))));
}
expect: {
function b(x) {
return x + x + x;
}
console.log("111", 6, b(b(b("ABCDEFGHIJK"))));
}
expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"
}
threshold_evaluate_30: {
options = {
evaluate: 30,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function b(x) {
return x + x + x;
}
console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK"))));
}
expect: {
function b(x) {
return x + x + x;
}
console.log("111", 6, b(b("ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK")));
}
expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"
}
threshold_evaluate_100: {
options = {
evaluate: 100,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function b(x) {
return x + x + x;
}
console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK"))));
}
expect: {
function b(x) {
return x + x + x;
}
console.log("111", 6, b("ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"));
}
expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"
}
threshold_evaluate_999: {
options = {
evaluate: 999,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function b(x) {
return x + x + x;
}
console.log(b("1"), b(2), b(b(b("ABCDEFGHIJK"))));
}
expect: {
console.log("111", 6, "ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK");
}
expect_stdout: "111 6 ABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJKABCDEFGHIJK"
}
collapse_vars_regexp: {
options = {
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: true,
loops: false,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
unsafe_regexp: true,
unused: true,
}
input: {
function f1() {
var k = 9;
var rx = /[A-Z]+/;
return [rx, k];
}
function f2() {
var rx = /ab*/g;
return function(s) {
return rx.exec(s);
};
}
function f3() {
var rx = /ab*/g;
return function() {
return rx;
};
}
(function() {
var result;
var s = "acdabcdeabbb";
var rx = /ab*/g;
while (result = rx.exec(s))
console.log(result[0]);
})();
(function() {
var result;
var s = "acdabcdeabbb";
var rx = f2();
while (result = rx(s))
console.log(result[0]);
})();
(function() {
var result;
var s = "acdabcdeabbb";
var rx = f3();
while (result = rx().exec(s))
console.log(result[0]);
})();
}
expect: {
function f1() {
return [/[A-Z]+/, 9];
}
function f2() {
var rx = /ab*/g;
return function(s) {
return rx.exec(s);
};
}
function f3() {
var rx = /ab*/g;
return function() {
return rx;
};
}
(function() {
var result, rx = /ab*/g;
while (result = rx.exec("acdabcdeabbb"))
console.log(result[0]);
})();
(function() {
var result, rx = f2();
while (result = rx("acdabcdeabbb"))
console.log(result[0]);
})();
(function() {
var result, rx = f3();
while (result = rx().exec("acdabcdeabbb"))
console.log(result[0]);
})();
}
expect_stdout: [
"a",
"ab",
"abbb",
"a",
"ab",
"abbb",
"a",
"ab",
"abbb",
]
}

View File

@@ -2004,57 +2004,6 @@ deduplicate_parenthesis: {
expect_exact: "({}).a=b;({}.a=b)();(function(){}).a=b;(function(){}.a=b)();"
}
drop_lone_use_strict: {
options = {
directives: true,
side_effects: true,
}
input: {
function f1() {
"use strict";
}
function f2() {
"use strict";
function f3() {
"use strict";
}
}
(function f4() {
"use strict";
})();
}
expect: {
function f1() {
}
function f2() {
"use strict";
function f3() {
}
}
}
}
issue_3166: {
options = {
directives: true,
}
input: {
"foo";
"use strict";
function f() {
"use strict";
"bar";
"use asm";
}
}
expect: {
"use strict";
function f() {
"use asm";
}
}
}
issue_3016_1: {
options = {
inline: true,
@@ -2265,7 +2214,8 @@ issue_3054: {
return { a: !0 };
}
console.log(function(b) {
return { a: !(b = !1) };
b = !1;
return f();
}().a, f.call().a);
}
expect_stdout: "true true"
@@ -2345,7 +2295,7 @@ issue_3274: {
}
expect: {
(function() {
for (var c; void 0, (c = 1..p) != c;)
for (var c; (c = 1..p) != c;)
console.log("FAIL");
console.log("PASS");
})();
@@ -2415,7 +2365,7 @@ issue_3297_2: {
doProcessOne({
param1: param1,
param2: param2,
}, function () {
}, function() {
processBulk(bulk);
});
};
@@ -2496,7 +2446,7 @@ issue_3297_3: {
doProcessOne({
param1: param1,
param2: param2,
}, function () {
}, function() {
processBulk(bulk);
});
};
@@ -2513,18 +2463,21 @@ issue_3297_3: {
}).processBulk([1, 2, 3]);
}
expect: {
function function1(u) {
function function1(c) {
return {
processBulk: function n(r) {
var o, t = u();
r && 0 < r.length && (o = {
param1: r.shift(),
processBulk: function n(o) {
var r, t, u = c();
o && 0 < o.length && (r = {
param1: o.shift(),
param2: {
subparam1: t
subparam1: u
}
},
console.log(JSON.stringify(o)),
n(r));
t = function() {
n(o);
},
console.log(JSON.stringify(r)),
t());
}
};
}
@@ -3096,23 +3049,20 @@ issue_3400_1: {
});
}
expect: {
void console.log(function() {
function g() {
function h(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}
function e() {
return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
void console.log(function g() {
function h(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}
return g;
}()()[0].p);
function e() {
return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
}()[0].p);
}
expect_stdout: [
"undefined",
@@ -3153,12 +3103,10 @@ issue_3400_2: {
expect: {
void console.log(function g() {
return [ 42 ].map(function(v) {
return function(u) {
var o = {
p: u
};
return console.log(o[g]), o;
}(v);
return o = {
p: v
}, console.log(o[g]), o;
var o;
});
}()[0].p);
}
@@ -3400,3 +3348,360 @@ issue_3562: {
}
expect_stdout: "PASS"
}
hoisted_inline: {
options = {
inline: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f() {
console.log("PASS");
}
function g() {
for (var console in [ 0 ])
h();
}
function h() {
f();
}
g();
}
expect: {
function f() {
console.log("PASS");
}
(function() {
for (var console in [ 0 ])
void f();
})();
}
expect_stdout: "PASS"
}
hoisted_single_use: {
options = {
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function f(a) {
for (var r in a) g(r);
}
function g(a) {
console.log(a);
}
function h(a) {
var g = a.bar;
g();
g();
i(a);
}
function i(b) {
f(b);
}
h({
bar: function() {
console.log("foo");
}
});
}
expect: {
function f(a) {
for (var r in a) g(r);
}
function g(a) {
console.log(a);
}
(function(a) {
var g = a.bar;
g();
g();
(function(b) {
f(b);
})(a);
})({
bar: function() {
console.log("foo");
}
});
}
expect_stdout: [
"foo",
"foo",
"bar",
]
}
pr_3592_1: {
options = {
inline: true,
reduce_funcs: false,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function problem(w) {
return g.indexOf(w);
}
function unused(x) {
return problem(x);
}
function B(problem) {
return g[problem];
}
function A(y) {
return problem(y);
}
function main(z) {
return B(A(z));
}
var g = [ "PASS" ];
console.log(main("PASS"));
}
expect: {
function problem(w) {
return g.indexOf(w);
}
function B(problem) {
return g[problem];
}
var g = [ "PASS" ];
console.log((z = "PASS", B((y = z, problem(y)))));
var z, y;
}
expect_stdout: "PASS"
}
pr_3592_2: {
options = {
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function problem(w) {
return g.indexOf(w);
}
function unused(x) {
return problem(x);
}
function B(problem) {
return g[problem];
}
function A(y) {
return problem(y);
}
function main(z) {
return B(A(z));
}
var g = [ "PASS" ];
console.log(main("PASS"));
}
expect: {
function problem(w) {
return g.indexOf(w);
}
var g = [ "PASS" ];
console.log((z = "PASS", function(problem) {
return g[problem];
}((y = z, problem(y)))));
var z, y;
}
expect_stdout: "PASS"
}
inline_use_strict: {
options = {
evaluate: true,
inline: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
console.log(function() {
"use strict";
return function() {
"use strict";
var a = "foo";
a += "bar";
return a;
};
}()());
}
expect: {
console.log("foobar");
}
expect_stdout: "foobar"
}
pr_3595_1: {
options = {
collapse_vars: false,
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
function unused(arg) {
return problem(arg);
}
function a(arg) {
return problem(arg);
}
function b(problem) {
return g[problem];
}
function c(arg) {
return b(a(arg));
}
console.log(c("PASS"));
}
expect: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
console.log((arg = "PASS", function(problem) {
return g[problem];
}(function(arg) {
return problem(arg);
}(arg))));
var arg;
}
expect_stdout: "PASS"
}
pr_3595_2: {
options = {
collapse_vars: true,
inline: true,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
function unused(arg) {
return problem(arg);
}
function a(arg) {
return problem(arg);
}
function b(problem) {
return g[problem];
}
function c(arg) {
return b(a(arg));
}
console.log(c("PASS"));
}
expect: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
console.log(function(problem) {
return g[problem];
}(function(arg) {
return problem(arg);
}("PASS")));
}
expect_stdout: "PASS"
}
pr_3595_3: {
options = {
collapse_vars: true,
inline: true,
passes: 2,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
function unused(arg) {
return problem(arg);
}
function a(arg) {
return problem(arg);
}
function b(problem) {
return g[problem];
}
function c(arg) {
return b(a(arg));
}
console.log(c("PASS"));
}
expect: {
var g = [ "PASS" ];
console.log(function(problem) {
return g[problem];
}(function(arg) {
return g.indexOf(arg);
}("PASS")));
}
expect_stdout: "PASS"
}
pr_3595_4: {
options = {
collapse_vars: true,
inline: true,
passes: 3,
reduce_funcs: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var g = [ "PASS" ];
function problem(arg) {
return g.indexOf(arg);
}
function unused(arg) {
return problem(arg);
}
function a(arg) {
return problem(arg);
}
function b(problem) {
return g[problem];
}
function c(arg) {
return b(a(arg));
}
console.log(c("PASS"));
}
expect: {
var g = [ "PASS" ];
console.log((problem = g.indexOf("PASS"), g[problem]));
var problem;
}
expect_stdout: "PASS"
}

View File

@@ -1,55 +1,107 @@
html_comment_in_expression: {
input: {
function f(a, b, x, y) { return a < !--b && x-- > y; }
(function(a, b) {
console.log(a < !--b && a-- > b, a, b);
})(1, 2);
}
expect_exact: "function f(a,b,x,y){return a< !--b&&x-- >y}";
expect_exact: "(function(a,b){console.log(a<! --b&&a-- >b,a,b)})(1,2);"
expect_stdout: "false 1 1"
}
html_comment_in_less_than: {
input: {
function f(a, b) { return a < !--b; }
(function(a, b, c) {
console.log(
a < !--b,
a < !--b + c,
a + b < !--c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "function f(a,b){return a< !--b}";
expect_exact: "(function(a,b,c){console.log(a<! --b,a<! --b+c,a+b<! --c,a,b,c)})(1,2,3);"
expect_stdout: "false true false 1 0 2"
}
html_comment_in_left_shift: {
input: {
function f(a, b) { return a << !--b; }
(function(a, b, c) {
console.log(
a << !--b,
a << !--b + c,
a + b << !--c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "function f(a,b){return a<< !--b}";
}
html_comment_in_right_shift: {
input: {
function f(a, b) { return a-- >> b; }
}
expect_exact: "function f(a,b){return a-- >>b}";
}
html_comment_in_zero_fill_right_shift: {
input: {
function f(a, b) { return a-- >>> b; }
}
expect_exact: "function f(a,b){return a-- >>>b}";
expect_exact: "(function(a,b,c){console.log(a<<! --b,a<<! --b+c,a+b<<! --c,a,b,c)})(1,2,3);"
expect_stdout: "1 16 1 1 0 2"
}
html_comment_in_greater_than: {
input: {
function f(a, b) { return a-- > b; }
(function(a, b, c) {
console.log(
a-- > b,
a-- > b + c,
a + b-- > c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "function f(a,b){return a-- >b}";
expect_exact: "(function(a,b,c){console.log(a-- >b,a-- >b+c,a+b-- >c,a,b,c)})(1,2,3);"
expect_stdout: "false false false -1 1 3"
}
html_comment_in_greater_than_or_equal: {
input: {
function f(a, b) { return a-- >= b; }
(function(a, b, c) {
console.log(
a-- >= b,
a-- >= b + c,
a + b-- >= c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "function f(a,b){return a-- >=b}";
expect_exact: "(function(a,b,c){console.log(a-- >=b,a-- >=b+c,a+b-- >=c,a,b,c)})(1,2,3);"
expect_stdout: "false false false -1 1 3"
}
html_comment_in_right_shift: {
input: {
(function(a, b, c) {
console.log(
a-- >> b,
a-- >> b + c,
a + b-- >> c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "(function(a,b,c){console.log(a-- >>b,a-- >>b+c,a+b-- >>c,a,b,c)})(1,2,3);"
expect_stdout: "0 0 0 -1 1 3"
}
html_comment_in_zero_fill_right_shift: {
input: {
(function(a, b, c) {
console.log(
a-- >>> b,
a-- >>> b + c,
a + b-- >>> c,
a, b, c
);
})(1, 2, 3);
}
expect_exact: "(function(a,b,c){console.log(a-- >>>b,a-- >>>b+c,a+b-- >>>c,a,b,c)})(1,2,3);"
expect_stdout: "0 0 0 -1 1 3"
}
html_comment_in_string_literal: {
input: {
function f() { return "<!--HTML-->comment in<!--string literal-->"; }
console.log("<!--HTML-->comment in<!--string literal-->".length);
}
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
expect_exact: 'console.log("\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e".length);'
expect_stdout: "42"
}

View File

@@ -544,3 +544,32 @@ if_body_return_3: {
"PASS",
]
}
issue_3600: {
options = {
if_return: true,
inline: true,
side_effects: true,
unused: true,
}
input: {
var c = 0;
(function() {
if ([ ][c++]); else return;
return void function() {
var b = --b, a = c = 42;
return c;
}();
})();
console.log(c);
}
expect: {
var c = 0;
(function() {
if ([][c++]) b = --b, c = 42;
var b;
})();
console.log(c);
}
expect_stdout: "1"
}

View File

@@ -52,3 +52,30 @@ chained_evaluation_2: {
})();
}
}
chained_evaluation_3: {
options = {
collapse_vars: true,
evaluate: 10,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
(function() {
var a = "long piece of string";
(function() {
var b = a, c;
c = f(b);
c.bar = b;
})();
})();
}
expect: {
(function() {
(function() {
f("long piece of string").bar = "long piece of string";
})();
})();
}
}

View File

@@ -873,13 +873,13 @@ iife_func_side_effects: {
function z() {
console.log("z");
}
(function(a, b) {
(function(b) {
return function() {
console.log("FAIL");
} + b();
})(x(), function() {
})((x(), function() {
return y();
}, z());
}), z());
}
expect_stdout: [
"x",
@@ -1155,3 +1155,303 @@ issue_3423_2: {
}
expect_stdout: "1"
}
collapse_vars_repeated: {
options = {
booleans: true,
collapse_vars: true,
comparisons: true,
conditionals: true,
dead_code: true,
evaluate: true,
hoist_funs: true,
if_return: true,
join_vars: true,
keep_fargs: "strict",
loops: true,
properties: true,
reduce_funcs: true,
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
function f1() {
var dummy = 3, a = 5, unused = 2, a = 1, a = 3;
return -a;
}
function f2(x) {
var a = 3, a = x;
return a;
}
(function(x) {
var a = "GOOD" + x, e = "BAD", k = "!", e = a;
console.log(e + k);
})("!"),
(function(x) {
var a = "GOOD" + x, e = "BAD" + x, k = "!", e = a;
console.log(e + k);
})("!");
}
expect: {
function f1() {
return -3;
}
function f2(x) {
return x;
}
(function() {
console.log("GOOD!!");
})(),
(function() {
console.log("GOOD!!");
})();
}
expect_stdout: true
}
chained_3: {
options = {
collapse_vars: true,
keep_fargs: "strict",
unused: true,
}
input: {
console.log(function(a, b) {
var c = a, c = b;
b++;
return c;
}(1, 2));
}
expect: {
console.log(function(b) {
var c = 1;
c = b;
b++;
return c;
}(2));
}
expect_stdout: "2"
}
replace_all_var_scope: {
rename = true
options = {
collapse_vars: true,
keep_fargs: "strict",
unused: true,
}
mangle = {}
input: {
var a = 100, b = 10;
(function(r, a) {
switch (~a) {
case (b += a):
case a++:
}
})(--b, a);
console.log(a, b);
}
expect: {
var a = 100, b = 10;
(function(c) {
switch (~a) {
case (b += a):
case c++:
}
})((--b, a));
console.log(a, b);
}
expect_stdout: "100 109"
}
issue_1583: {
options = {
keep_fargs: "strict",
passes: 2,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
function m(t) {
(function(e) {
t = e();
})(function() {
return (function(a) {
return a;
})(function(a) {});
});
}
}
expect: {
function m(t) {
(function() {
(function() {
return (function() {
return function(a) {};
})();
})();
})();
}
}
}
issues_3267_1: {
options = {
collapse_vars: true,
conditionals: true,
dead_code: true,
evaluate: true,
inline: true,
keep_fargs: "strict",
reduce_vars: true,
sequences: true,
side_effects: true,
unused: true,
}
input: {
(function(x) {
x();
})(function() {
(function(i) {
if (i)
return console.log("PASS");
throw "FAIL";
})(Object());
});
}
expect: {
!function() {
if (Object())
return console.log("PASS");
throw "FAIL";
}();
}
expect_stdout: "PASS"
}
trailing_argument_side_effects: {
options = {
keep_fargs: "strict",
unused: true,
}
input: {
function f() {
return "FAIL";
}
console.log(function(a, b) {
return b || "PASS";
}(f()));
}
expect: {
function f() {
return "FAIL";
}
console.log(function(b) {
return b || "PASS";
}(void f()));
}
expect_stdout: "PASS"
}
recursive_iife_1: {
options = {
keep_fargs: "strict",
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(a, b) {
return b || f("FAIL", "PASS");
}());
}
expect: {
console.log(function f(a, b) {
return b || f("FAIL", "PASS");
}());
}
expect_stdout: "PASS"
}
recursive_iife_2: {
options = {
keep_fargs: "strict",
reduce_vars: true,
unused: true,
}
input: {
console.log(function f(a, b) {
return b || f("FAIL", "PASS");
}(null, 0));
}
expect: {
console.log(function f(a, b) {
return b || f("FAIL", "PASS");
}(0, 0));
}
expect_stdout: "PASS"
}
recursive_iife_3: {
options = {
keep_fargs: false,
reduce_vars: true,
unused: true,
}
input: {
var a = 1, c = "PASS";
(function() {
function f(b, d, e) {
a-- && f(null, 42, 0);
e && (c = "FAIL");
d && d.p;
}
var a_1 = f();
})();
console.log(c);
}
expect: {
var a = 1, c = "PASS";
(function() {
(function f(b, d, e) {
a-- && f(null, 42, 0);
e && (c = "FAIL");
d && d.p;
})();
})();
console.log(c);
}
expect_stdout: "PASS"
}
issue_3619: {
options = {
keep_fargs: false,
unused: true,
}
input: {
var a = 1, b = "FAIL";
(function f(c, d) {
function g() {
d && (b = "PASS", 0 <= --a && g());
0 <= --a && f(0, "function");
}
g();
})();
console.log(b);
}
expect: {
var a = 1, b = "FAIL";
(function f(c, d) {
function g() {
d && (b = "PASS", 0 <= --a && g());
0 <= --a && f(0, "function");
}
g();
})();
console.log(b);
}
expect_stdout: "PASS"
}

View File

@@ -689,3 +689,67 @@ step: {
}
expect_stdout: "42"
}
empty_for_in: {
options = {
loops: true,
toplevel: true,
unused: true,
}
input: {
for (var a in [ 1, 2, 3 ]) {
var b = a + 1;
}
}
expect: {}
expect_warnings: [
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
]
}
empty_for_in_used: {
options = {
loops: true,
toplevel: true,
unused: true,
}
input: {
for (var a in [ 1, 2, 3 ]) {
var b = a + 1;
}
console.log(a);
}
expect: {
for (var a in [ 1, 2, 3 ]);
console.log(a);
}
expect_stdout: "2"
expect_warnings: [
"WARN: Dropping unused variable b [test/compress/loops.js:2,16]",
]
}
empty_for_in_side_effects: {
options = {
loops: true,
toplevel: true,
unused: true,
}
input: {
for (var a in {
foo: console.log("PASS")
}) {
var b = a + "bar";
}
}
expect: {
console.log("PASS");
}
expect_stdout: "PASS"
expect_warnings: [
"WARN: Dropping unused variable b [test/compress/loops.js:4,16]",
"INFO: Dropping unused loop variable a [test/compress/loops.js:1,17]",
"WARN: Side effects in object of for-in loop [test/compress/loops.js:1,17]",
]
}

View File

@@ -870,7 +870,7 @@ issue_3547_3: {
a + "21",
a + "2" - 1,
a - 1,
a - "2" - 1,
a - 3,
].forEach(function(n) {
console.log(typeof n, n);
});
@@ -904,7 +904,7 @@ issue_3547_4: {
[
"3" + a + 1,
"3" + a - 1,
"3" - a + 1,
4 - a,
2 - a,
].forEach(function(n) {
console.log(typeof n, n);
@@ -917,3 +917,65 @@ issue_3547_4: {
"number 0",
]
}
unsafe_math_rounding: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log(4 / -3 + 1 === 1 / -3);
}
expect: {
console.log(false);
}
expect_stdout: "false"
}
issue_3593: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
console.log((0 === this) - 1 - "1");
}
expect: {
console.log((0 === this) - 2);
}
expect_stdout: "-2"
}
unsafe_math_swap_constant: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = 1, b = 2;
console.log(
a++ + b-- + 3,
a++ + b + 3,
a + b-- + 3,
a + b + 3,
a++ - b-- + 3,
a++ - b + 3,
a - b-- + 3,
a - b + 3
);
}
expect: {
var a = 1, b = 2;
console.log(
3 + a++ + b--,
a++ + b + 3,
a + b-- + 3,
a + b + 3,
3 + a++ - b--,
3 + a++ - b,
a - b-- + 3,
a - b + 3
);
}
expect_stdout: "6 6 7 6 6 8 9 10"
}

View File

@@ -1427,13 +1427,13 @@ defun_inline_3: {
defun_call: {
options = {
inline: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
}
input: {
function f() {
console.log(function f() {
return g() + h(1) - h(g(), 2, 3);
function g() {
return 4;
@@ -1441,21 +1441,17 @@ defun_call: {
function h(a) {
return a;
}
}
}());
}
expect: {
function f() {
return 4 + h(1) - h(4);
function h(a) {
return a;
}
}
console.log(1);
}
expect_stdout: "1"
}
defun_redefine: {
options = {
inline: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -1480,7 +1476,7 @@ defun_redefine: {
(function() {
return 3;
});
return 3 + 2;
return 5;
}
console.log(f());
}
@@ -1517,7 +1513,7 @@ func_inline: {
func_modified: {
options = {
inline: true,
evaluate: true,
reduce_funcs: true,
reduce_vars: true,
unused: true,
@@ -1550,7 +1546,7 @@ func_modified: {
(function() {
return 4;
});
return 1 + 2 + 4;
return 7;
}
console.log(f());
}
@@ -5516,9 +5512,7 @@ issue_2860_1: {
}());
}
expect: {
console.log(function(a) {
return 1 ^ a;
}());
console.log(1);
}
expect_stdout: "1"
}
@@ -6780,3 +6774,30 @@ issue_3509: {
}
expect_stdout: "PASS"
}
issue_3622: {
options = {
evaluate: true,
inline: true,
keep_fargs: "strict",
reduce_vars: true,
sequences: true,
toplevel: true,
unused: true,
}
input: {
var c = "FAIL";
!function(b, a) {
a && (c = "PASS");
}(42, this);
console.log(c);
}
expect: {
var c = "FAIL";
var a;
a = this,
!void (a && (c = "PASS")),
console.log(c);
}
expect_stdout: "PASS"
}

View File

@@ -261,13 +261,13 @@ drop_default_1: {
}
input: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
default:
}
}
expect: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
}
}
}
@@ -279,14 +279,14 @@ drop_default_2: {
}
input: {
switch (foo) {
case 'bar': baz(); break;
case "bar": baz(); break;
default:
break;
}
}
expect: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
}
}
}
@@ -298,7 +298,7 @@ keep_default: {
}
input: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
default:
something();
break;
@@ -306,7 +306,7 @@ keep_default: {
}
expect: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
default:
something();
}
@@ -347,25 +347,103 @@ issue_1663: {
expect_stdout: true
}
drop_case: {
drop_case_1: {
options = {
dead_code: true,
switches: true,
}
input: {
switch (foo) {
case 'bar': baz(); break;
case 'moo':
case "bar": baz(); break;
case "moo":
break;
}
}
expect: {
switch (foo) {
case 'bar': baz();
case "bar": baz();
}
}
}
drop_case_2: {
options = {
dead_code: true,
switches: true,
}
input: {
switch (foo) {
case "bar":
bar();
break;
default:
case "moo":
moo();
break;
}
}
expect: {
switch (foo) {
case "bar":
bar();
break;
default:
moo();
}
}
}
drop_case_3: {
options = {
dead_code: true,
switches: true,
}
input: {
var c = "PASS";
switch ({}.p) {
default:
case void 0:
break;
case c = "FAIL":
}
console.log(c);
}
expect: {
var c = "PASS";
switch ({}.p) {
default:
case void 0:
break;
case c = "FAIL":
}
console.log(c);
}
expect_stdout: "PASS"
}
drop_case_4: {
options = {
dead_code: true,
switches: true,
}
input: {
switch (0) {
case [ a, typeof b ]:
default:
var a;
}
console.log("PASS");
}
expect: {
switch (0) {
case [ a, typeof b ]:
var a;
}
console.log("PASS");
}
expect_stdout: "PASS"
}
keep_case: {
options = {
dead_code: true,
@@ -373,14 +451,14 @@ keep_case: {
}
input: {
switch (foo) {
case 'bar': baz(); break;
case "bar": baz(); break;
case moo:
break;
}
}
expect: {
switch (foo) {
case 'bar': baz(); break;
case "bar": baz(); break;
case moo:
}
}
@@ -539,7 +617,7 @@ issue_1679: {
f();
console.log(a, b);
}
expect_stdout: true
expect_stdout: "99 8"
}
issue_1680_1: {
@@ -864,3 +942,89 @@ issue_1750: {
}
expect_stdout: "0 2"
}
drop_switch_1: {
options = {
dead_code: true,
switches: true,
}
input: {
switch (foo) {
default:
break;
case "bar":
break;
}
}
expect: {
foo;
}
}
drop_switch_2: {
options = {
dead_code: true,
switches: true,
}
input: {
switch (foo) {
default:
case "bar":
baz();
}
}
expect: {
foo;
baz();
}
}
drop_switch_3: {
options = {
dead_code: true,
switches: true,
}
input: {
console.log(function() {
switch (0) {
default:
return "PASS";
case 1:
}
}());
}
expect: {
console.log(function() {
switch (0) {
default:
return "PASS";
case 1:
}
}());
}
expect_stdout: "PASS"
}
drop_switch_4: {
options = {
dead_code: true,
switches: true,
}
input: {
var a = "FAIL";
switch (0) {
default:
case a:
var b = a = "PASS";
break;
}
console.log(a);
}
expect: {
var a = "FAIL";
0;
var b = a = "PASS";
console.log(a);
}
expect_stdout: "PASS"
}

View File

@@ -166,9 +166,7 @@ duplicate_lambda_arg_name: {
}());
}
expect: {
console.log(function long_name(long_name) {
return typeof long_name;
}());
console.log("undefined");
}
expect_stdout: "undefined"
}

View File

@@ -12,7 +12,9 @@ describe("bin/uglifyjs", function() {
it("Should produce a functional build when using --self", function(done) {
this.timeout(30000);
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
exec(command, function(err, stdout) {
exec(command, {
maxBuffer: 1048576
}, function(err, stdout) {
if (err) throw err;
eval(stdout);
assert.strictEqual(typeof WrappedUglifyJS, "object");

View File

@@ -54,8 +54,8 @@ describe("Directives", function() {
[
[
'"use strict"\n',
[ "use strict"],
[ "use asm"]
[ "use strict" ],
[ "use asm" ]
],
[
'"use\\\nstrict";',
@@ -80,8 +80,8 @@ describe("Directives", function() {
[
// no ; or newline
'"use strict"',
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
[ "use strict" ],
[ "use\nstrict", "use \nstrict", "use asm" ]
],
[
';"use strict"',
@@ -116,8 +116,8 @@ describe("Directives", function() {
],
[
'var foo = function() {"use strict"', // no ; or newline
[],
[ "use strict", "use\nstrict", "use \nstrict", "use asm" ]
[ "use strict" ],
[ "use\nstrict", "use \nstrict", "use asm" ]
],
[
'var foo = function() {;"use strict"',

View File

@@ -2,10 +2,18 @@ var assert = require("assert");
var UglifyJS = require("../node");
describe("Number literals", function() {
it("Should allow legacy octal literals in non-strict mode", function() {
[
"'use strict'\n.slice()\n00",
'"use strict"\n.slice()\nvar foo = 00',
].forEach(function(input) {
UglifyJS.parse(input);
});
});
it("Should not allow legacy octal literals in strict mode", function() {
var inputs = [
'"use strict";00;',
'"use strict"; var foo = 00;'
'"use strict"; var foo = 00;',
];
var test = function(input) {
return function() {

View File

@@ -10,7 +10,9 @@ describe("spidermonkey export/import sanity test", function() {
var command = uglifyjs + " --self -cm --wrap SpiderUglify -o spidermonkey | " +
uglifyjs + " -p spidermonkey -cm";
exec(command, function(err, stdout) {
exec(command, {
maxBuffer: 1048576
}, function(err, stdout) {
if (err) throw err;
eval(stdout);

View File

@@ -1,44 +0,0 @@
"use strict";
var child_process = require("child_process");
var https = require("https");
var url = require("url");
var period = 45 * 60 * 1000;
var wait = 2 * 60 * 1000;
if (process.argv.length > 2) {
var token = process.argv[2];
var branch = process.argv[3] || "v" + require("../../package.json").version;
var repository = encodeURIComponent(process.argv[4] || "mishoo/UglifyJS2");
var concurrency = process.argv[5] || 1;
var platform = process.argv[6] || "latest";
(function request() {
setTimeout(request, (period + wait) / concurrency);
var options = url.parse("https://api.travis-ci.org/repo/" + repository + "/requests");
options.method = "POST";
options.headers = {
"Content-Type": "application/json",
"Travis-API-Version": 3,
"Authorization": "token " + token
};
https.request(options, function(res) {
console.log("HTTP", res.statusCode);
console.log(JSON.stringify(res.headers, null, 2));
console.log();
res.setEncoding("utf8");
res.on("data", console.log);
}).on("error", console.error).end(JSON.stringify({
request: {
message: "ufuzz testing",
branch: branch,
config: {
cache: false,
env: "NODE=" + platform,
script: "node test/ufuzz/job " + period
}
}
}));
})();
} else {
console.log("Usage: test/ufuzz/travis.js <token> [branch] [repository] [concurrency] [platform]");
}