Compare commits

...

39 Commits

Author SHA1 Message Date
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
Alex Lam S.L
0f2687ecfc v3.6.7 2019-11-02 13:32:05 +08:00
Alex Lam S.L
1c0defdc03 enhance unsafe evaluate (#3564) 2019-11-02 03:34:32 +08:00
Alex Lam S.L
dcbf2236c7 more tests for #3562 (#3565) 2019-11-02 03:34:20 +08:00
Alex Lam S.L
24bb288832 fix corner case in collapse_vars (#3563)
fixes #3562
2019-11-01 22:38:19 +08:00
Alex Lam S.L
6ad8e1081f v3.6.6 2019-11-01 13:40:03 +08:00
Alex Lam S.L
815eff1f7c enhance if_return (#3560) 2019-11-01 02:08:31 +08:00
Alex Lam S.L
1e9b576ee9 fix corner case in evaluate (#3559)
fixes #3558
2019-11-01 00:01:25 +08:00
Alex Lam S.L
3797458365 enhance conditionals (#3557) 2019-10-31 09:33:46 +08:00
Alex Lam S.L
1858c2018c enhance typeofs (#3556) 2019-10-31 08:00:04 +08:00
Alex Lam S.L
ec7f071272 fix corner case in dead_code (#3553)
fixes #3552
2019-10-30 14:21:22 +08:00
Alex Lam S.L
f1eb03f2c0 enhance dead_code (#3551) 2019-10-30 06:34:54 +08:00
Alex Lam S.L
0f4cfa877a fix corner case in comments (#3550) 2019-10-30 03:49:39 +08:00
Alex Lam S.L
1d5c2becbd enhance evaluate (#3549) 2019-10-29 19:51:55 +08:00
Alex Lam S.L
22a09ea7c5 fix corner case in unsafe_math (#3548)
fixes #3547
2019-10-29 17:06:57 +08:00
Alex Lam S.L
bad664c632 compress object literals (#3546) 2019-10-29 16:53:48 +08:00
27 changed files with 2336 additions and 540 deletions

View File

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

View File

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

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

@@ -478,42 +478,42 @@ if (result.error) throw result.error;
## Minify options ## Minify options
- `warnings` (default `false`) — pass `true` to return compressor warnings
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
- `parse` (default `{}`) — pass an object if you wish to specify some
additional [parse options](#parse-options).
- `compress` (default `{}`) — pass `false` to skip compressing entirely. - `compress` (default `{}`) — pass `false` to skip compressing entirely.
Pass an object to specify custom [compress options](#compress-options). Pass an object to specify custom [compress options](#compress-options).
- `ie8` (default `false`) -- set to `true` to support IE8.
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
of function names. Useful for code relying on `Function.prototype.name`.
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass - `mangle` (default `true`) — pass `false` to skip mangling names, or pass
an object to specify [mangle options](#mangle-options) (see below). an object to specify [mangle options](#mangle-options) (see below).
- `mangle.properties` (default `false`) — a subcategory of the mangle option. - `mangle.properties` (default `false`) — a subcategory of the mangle option.
Pass an object to specify custom [mangle property options](#mangle-properties-options). Pass an object to specify custom [mangle property options](#mangle-properties-options).
- `output` (default `null`) pass an object if you wish to specify - `nameCache` (default `null`) -- pass an empty object `{}` or a previously
additional [output options](#output-options). The defaults are optimized
for best compression.
- `sourceMap` (default `false`) - pass an object if you wish to specify
[source map options](#source-map-options).
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
variable and function name mangling and to drop unused variables and functions.
- `nameCache` (default `null`) - pass an empty object `{}` or a previously
used `nameCache` object if you wish to cache mangled variable and used `nameCache` object if you wish to cache mangled variable and
property names across multiple invocations of `minify()`. Note: this is property names across multiple invocations of `minify()`. Note: this is
a read/write property. `minify()` will read the name cache state of this a read/write property. `minify()` will read the name cache state of this
object and update it during minification so that it may be object and update it during minification so that it may be
reused or externally persisted by the user. reused or externally persisted by the user.
- `ie8` (default `false`) - set to `true` to support IE8. - `output` (default `null`) — pass an object if you wish to specify
additional [output options](#output-options). The defaults are optimized
for best compression.
- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling - `parse` (default `{}`) pass an object if you wish to specify some
of function names. Useful for code relying on `Function.prototype.name`. additional [parse options](#parse-options).
- `sourceMap` (default `false`) -- pass an object if you wish to specify
[source map options](#source-map-options).
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
variable and function name mangling and to drop unused variables and functions.
- `warnings` (default `false`) — pass `true` to return compressor warnings
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
## Minify options structure ## Minify options structure
@@ -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 - `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 - `expression` (default: `false`) -- Pass `true` to preserve completion values
from terminal statements without `return`, e.g. in bookmarklets. from terminal statements without `return`, e.g. in bookmarklets.
@@ -682,6 +685,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
where the return value is discarded, to avoid the parens that the where the return value is discarded, to avoid the parens that the
code generator would insert. code generator would insert.
- `objects` (default: `true`) -- compact duplicate keys in object literals.
- `passes` (default: `1`) -- The maximum number of times to run compress. - `passes` (default: `1`) -- The maximum number of times to run compress.
In some cases more than one pass leads to further compressed code. Keep in In some cases more than one pass leads to further compressed code. Keep in
mind more passes will take more time. mind more passes will take more time.

View File

@@ -1,74 +1,5 @@
build: off build: off
cache:
- tmp
matrix: matrix:
fast_finish: true 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: 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), properties: 1e-3 * (timings.output - timings.properties),
output: 1e-3 * (timings.end - timings.output), output: 1e-3 * (timings.end - timings.output),
total: 1e-3 * (timings.end - timings.start) total: 1e-3 * (timings.end - timings.start)
} };
} }
if (warnings.length) { if (warnings.length) {
result.warnings = warnings; result.warnings = warnings;

View File

@@ -1253,6 +1253,7 @@ function parse($TEXT, options) {
var ex = expression(true); var ex = expression(true);
var len = start.comments_before.length; var len = start.comments_before.length;
[].unshift.apply(ex.start.comments_before, start.comments_before); [].unshift.apply(ex.start.comments_before, start.comments_before);
start.comments_before.length = 0;
start.comments_before = ex.start.comments_before; start.comments_before = ex.start.comments_before;
start.comments_before_length = len; start.comments_before_length = len;
if (len == 0 && start.comments_before.length > 0) { if (len == 0 && start.comments_before.length > 0) {
@@ -1268,6 +1269,7 @@ function parse($TEXT, options) {
var end = prev(); var end = prev();
end.comments_before = ex.end.comments_before; end.comments_before = ex.end.comments_before;
[].push.apply(ex.end.comments_after, end.comments_after); [].push.apply(ex.end.comments_after, end.comments_after);
end.comments_after.length = 0;
end.comments_after = ex.end.comments_after; end.comments_after = ex.end.comments_after;
ex.end = end; ex.end = end;
if (ex instanceof AST_Call) mark_pure(ex); if (ex instanceof AST_Call) mark_pure(ex);

View File

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

View File

@@ -1458,7 +1458,7 @@ collapse_vars_constants: {
function f3(x) { function f3(x) {
var b = x.prop; var b = x.prop;
sideeffect1(); sideeffect1();
return b + (function() { return -9; })(); return b + -9;
} }
} }
} }
@@ -5748,7 +5748,7 @@ issue_3215_1: {
}()); }());
} }
expect: { expect: {
console.log("number"); console.log(typeof 42);
} }
expect_stdout: "number" expect_stdout: "number"
} }
@@ -6238,7 +6238,7 @@ issue_3439_2: {
expect_stdout: "number" expect_stdout: "number"
} }
cond_sequence_return: { cond_sequence_return_1: {
options = { options = {
collapse_vars: true, collapse_vars: true,
} }
@@ -6259,6 +6259,27 @@ cond_sequence_return: {
expect_stdout: "2" expect_stdout: "2"
} }
cond_sequence_return_2: {
options = {
collapse_vars: true,
}
input: {
console.log(function(n) {
var c = 0;
for (var k in [0, 1])
if (c += 1, k == n) return c;
}(1));
}
expect: {
console.log(function(n) {
var c = 0;
for (var k in [0, 1])
if (c += 1, k == n) return c;
}(1));
}
expect_stdout: "2"
}
issue_3520: { issue_3520: {
options = { options = {
collapse_vars: true, collapse_vars: true,
@@ -6348,3 +6369,183 @@ issue_3526_2: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_3562: {
options = {
collapse_vars: true,
conditionals: true,
sequences: true,
}
input: {
function f(a) {
console.log("PASS", a);
}
function g(b) {
console.log("FAIL", b);
}
var h;
var c;
if (console) {
h = f;
c = "PASS";
} else {
h = g;
c = "FAIL";
}
h(c);
}
expect: {
function f(a) {
console.log("PASS", a);
}
function g(b) {
console.log("FAIL", b);
}
var h;
var c;
c = console ? (h = f, "PASS") : (h = g, "FAIL"),
h(c);
}
expect_stdout: "PASS PASS"
}
dot_throw_assign_sequence: {
options = {
collapse_vars: true,
}
input: {
var a = "FAIL";
try {
var b;
b[0] = (a = "PASS", 0);
a = 1 + a;
} catch (c) {
}
console.log(a);
}
expect: {
var a = "FAIL";
try {
var b;
b[0] = (a = "PASS", 0);
a = 1 + a;
} catch (c) {
}
console.log(a);
}
expect_stdout: "PASS"
}
call_assign_order: {
options = {
collapse_vars: true,
}
input: {
var a, b = 1, c = 0, log = console.log;
(function() {
a = b = "PASS";
})((b = "FAIL", c++));
log(a, b);
}
expect: {
var a, b = 1, c = 0, log = console.log;
(function() {
a = b = "PASS";
})((b = "FAIL", c++));
log(a, b);
}
expect_stdout: "PASS PASS"
}
issue_3573: {
options = {
collapse_vars: true,
}
input: {
var c = 0;
(function(b) {
while (--b) {
b = NaN;
switch (0 / this < 0) {
case c++, false:
case c++, NaN:
}
}
})(3);
console.log(c);
}
expect: {
var c = 0;
(function(b) {
while (--b) {
b = NaN;
switch (0 / this < 0) {
case c++, false:
case c++, NaN:
}
}
})(3);
console.log(c);
}
expect_stdout: "1"
}
issue_3581_1: {
options = {
collapse_vars: true,
}
input: {
var a = "PASS", b = "FAIL";
try {
b = "PASS";
if (a) throw 0;
b = 1 + b;
a = "FAIL";
} catch (e) {}
console.log(a, b);
}
expect: {
var a = "PASS", b = "FAIL";
try {
b = "PASS";
if (a) throw 0;
b = 1 + b;
a = "FAIL";
} catch (e) {}
console.log(a, b);
}
expect_stdout: "PASS PASS"
}
issue_3581_2: {
options = {
collapse_vars: true,
}
input: {
(function() {
var a = "PASS", b = "FAIL";
try {
b = "PASS";
if (a) return;
b = 1 + b;
a = "FAIL";
} finally {
console.log(a, b);
}
})();
}
expect: {
(function() {
var a = "PASS", b = "FAIL";
try {
b = "PASS";
if (a) return;
b = 1 + b;
a = "FAIL";
} finally {
console.log(a, b);
}
})();
}
expect_stdout: "PASS PASS"
}

View File

@@ -161,6 +161,24 @@ ifs_6: {
} }
} }
ifs_7: {
options = {
conditionals: true,
}
input: {
if (A); else;
if (A) while (B); else;
if (A); else while (C);
if (A) while (B); else while (C);
}
expect: {
A;
if (A) while (B);
if (!A) while (C);
if (A) while (B); else while (C);
}
}
cond_1: { cond_1: {
options = { options = {
conditionals: true, conditionals: true,
@@ -1471,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: { expect: {
console.log(function(a) { console.log(1);
return 1 ^ a;
}());
} }
expect_stdout: "1" expect_stdout: "1"
} }
@@ -1013,3 +1011,119 @@ issue_3406: {
} }
expect_stdout: "true" expect_stdout: "true"
} }
function_assign: {
options = {
dead_code: true,
}
input: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = function(b) {
return b;
}.p = a;
return h;
}().p);
}
expect: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect_stdout: "PASS"
}
issue_3552: {
options = {
dead_code: true,
pure_getters: "strict",
}
input: {
var a = "PASS";
(function() {
(1..p += 42) && (a = "FAIL");
})();
console.log(a);
}
expect: {
var a = "PASS";
(function() {
(1..p += 42) && (a = "FAIL");
})();
console.log(a);
}
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

@@ -1019,14 +1019,21 @@ delete_assign_1: {
console.log(delete (a = 0 / 0)); console.log(delete (a = 0 / 0));
} }
expect: { expect: {
console.log((void 0, !0)); console.log(!0);
console.log((void 0, !0)); console.log(!0);
console.log((1 / 0, !0)); console.log(!0);
console.log((1 / 0, !0)); console.log(!0);
console.log((NaN, !0)); console.log(!0);
console.log((NaN, !0)); console.log(!0);
} }
expect_stdout: true expect_stdout: [
"true",
"true",
"true",
"true",
"true",
"true",
]
} }
delete_assign_2: { delete_assign_2: {
@@ -1047,14 +1054,21 @@ delete_assign_2: {
console.log(delete (a = 0 / 0)); console.log(delete (a = 0 / 0));
} }
expect: { expect: {
console.log((void 0, !0)); console.log(!0);
console.log((void 0, !0)); console.log(!0);
console.log((Infinity, !0)); console.log(!0);
console.log((1 / 0, !0)); console.log(!0);
console.log((NaN, !0)); console.log(!0);
console.log((NaN, !0)); console.log(!0);
} }
expect_stdout: true expect_stdout: [
"true",
"true",
"true",
"true",
"true",
"true",
]
} }
drop_var: { drop_var: {
@@ -1635,7 +1649,7 @@ double_assign_2: {
} }
expect: { expect: {
for (var i = 0; i < 2; i++) for (var i = 0; i < 2; i++)
void 0, a = {}, console.log(a); a = {}, console.log(a);
var a; var a;
} }
} }
@@ -1716,7 +1730,7 @@ issue_2768: {
} }
expect: { expect: {
var a = "FAIL"; var a = "FAIL";
var c = (d = a, 0, void (d && (a = "PASS"))); var c = (d = a, void (d && (a = "PASS")));
var d; var d;
console.log(a, typeof c); console.log(a, typeof c);
} }
@@ -2187,3 +2201,37 @@ issue_3515_3: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
function_assign: {
options = {
pure_getters: "strict",
reduce_vars: true,
side_effects: true,
unused: true,
}
input: {
console.log(function() {
var a = "PASS";
function g(b) {
return b;
}
g.p = a;
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect: {
console.log(function() {
var a = "PASS";
function h(c) {
return c;
}
h.p = a;
return h;
}().p);
}
expect_stdout: "PASS"
}

View File

@@ -237,22 +237,39 @@ unsafe_constant: {
unsafe: true, unsafe: true,
} }
input: { input: {
console.log( console.log(true.a, false.a);
true.a, console.log(true.valueOf(), false.valueOf());
false.a, try {
null.a, console.log(null.a);
undefined.a } catch (e) {
); console.log("PASS");
}
try {
console.log(undefined.a);
} catch (e) {
console.log("PASS");
}
} }
expect: { expect: {
console.log( console.log(void 0, void 0);
void 0, console.log(true, false);
false.a, try {
null.a, console.log(null.a);
(void 0).a } catch (e) {
); console.log("PASS");
}
try {
console.log((void 0).a);
} catch (e) {
console.log("PASS");
}
} }
expect_stdout: true expect_stdout: [
"undefined undefined",
"true false",
"PASS",
"PASS",
]
} }
unsafe_object: { unsafe_object: {
@@ -1757,3 +1774,286 @@ issue_3387_2: {
} }
expect_stdout: "NaN" expect_stdout: "NaN"
} }
simple_function_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function sum(a, b) {
return a + b;
}
console.log(sum(1, 2) * sum(3, 4));
}
expect: {
console.log(21);
}
expect_stdout: "21"
}
simple_function_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var sum = function(a, b) {
return a + b;
}
console.log(sum(1, 2) * sum(3, 4));
}
expect: {
console.log(21);
}
expect_stdout: "21"
}
recursive_function_1: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
function factorial(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect: {
console.log(function factorial(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}(5));
}
expect_stdout: "120"
}
recursive_function_2: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
unused: true,
}
input: {
var factorial = function(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect: {
var factorial = function(a) {
return a > 0 ? a * factorial(a - 1) : 1;
}
console.log(factorial(5));
}
expect_stdout: "120"
}
issue_3558: {
options = {
evaluate: true,
reduce_vars: true,
toplevel: true,
}
input: {
function f(a) {
return 1 + --a;
}
console.log(f(true), f(false));
}
expect: {
function f(a) {
return 1 + --a;
}
console.log(1, 0);
}
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"
}

View File

@@ -2265,7 +2265,8 @@ issue_3054: {
return { a: !0 }; return { a: !0 };
} }
console.log(function(b) { console.log(function(b) {
return { a: !(b = !1) }; b = !1;
return f();
}().a, f.call().a); }().a, f.call().a);
} }
expect_stdout: "true true" expect_stdout: "true true"
@@ -2345,7 +2346,7 @@ issue_3274: {
} }
expect: { expect: {
(function() { (function() {
for (var c; void 0, (c = 1..p) != c;) for (var c; (c = 1..p) != c;)
console.log("FAIL"); console.log("FAIL");
console.log("PASS"); console.log("PASS");
})(); })();
@@ -2415,7 +2416,7 @@ issue_3297_2: {
doProcessOne({ doProcessOne({
param1: param1, param1: param1,
param2: param2, param2: param2,
}, function () { }, function() {
processBulk(bulk); processBulk(bulk);
}); });
}; };
@@ -2496,7 +2497,7 @@ issue_3297_3: {
doProcessOne({ doProcessOne({
param1: param1, param1: param1,
param2: param2, param2: param2,
}, function () { }, function() {
processBulk(bulk); processBulk(bulk);
}); });
}; };
@@ -2513,18 +2514,21 @@ issue_3297_3: {
}).processBulk([1, 2, 3]); }).processBulk([1, 2, 3]);
} }
expect: { expect: {
function function1(u) { function function1(c) {
return { return {
processBulk: function n(r) { processBulk: function n(o) {
var o, t = u(); var r, t, u = c();
r && 0 < r.length && (o = { o && 0 < o.length && (r = {
param1: r.shift(), param1: o.shift(),
param2: { param2: {
subparam1: t subparam1: u
} }
}, },
console.log(JSON.stringify(o)), t = function() {
n(r)); n(o);
},
console.log(JSON.stringify(r)),
t());
} }
}; };
} }
@@ -3096,23 +3100,20 @@ issue_3400_1: {
}); });
} }
expect: { expect: {
void console.log(function() { void console.log(function g() {
function g() { function h(u) {
function h(u) { var o = {
var o = { p: u
p: u };
}; return console.log(o[g]), o;
return console.log(o[g]), o;
}
function e() {
return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
} }
return g; function e() {
}()()[0].p); return [ 42 ].map(function(v) {
return h(v);
});
}
return e();
}()[0].p);
} }
expect_stdout: [ expect_stdout: [
"undefined", "undefined",
@@ -3153,12 +3154,10 @@ issue_3400_2: {
expect: { expect: {
void console.log(function g() { void console.log(function g() {
return [ 42 ].map(function(v) { return [ 42 ].map(function(v) {
return function(u) { return o = {
var o = { p: v
p: u }, console.log(o[g]), o;
}; var o;
return console.log(o[g]), o;
}(v);
}); });
}()[0].p); }()[0].p);
} }
@@ -3370,3 +3369,202 @@ issue_3512: {
} }
expect_stdout: "PASS" expect_stdout: "PASS"
} }
issue_3562: {
options = {
collapse_vars: true,
reduce_vars: true,
}
input: {
var a = "PASS";
function f(b) {
f = function() {
console.log(b);
};
return "FAIL";
}
a = f(a);
f(a);
}
expect: {
var a = "PASS";
function f(b) {
f = function() {
console.log(b);
};
return "FAIL";
}
a = f(a);
f(a);
}
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"
}

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

@@ -689,3 +689,67 @@ step: {
} }
expect_stdout: "42" 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

@@ -781,3 +781,167 @@ issue_3539: {
} }
expect_stdout: "NaN -Infinity Infinity" expect_stdout: "NaN -Infinity Infinity"
} }
issue_3547_1: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
[
1/0 + "1" + 0,
1/0 + "1" - 0,
1/0 - "1" + 0,
1/0 - "1" - 0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
[
1/0 + "10",
NaN,
1/0,
1/0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string Infinity10",
"number NaN",
"number Infinity",
"number Infinity",
]
}
issue_3547_2: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
[
"1" + 1/0 + 0,
"1" + 1/0 - 0,
"1" - 1/0 + 0,
"1" - 1/0 - 0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
[
"1" + 1/0 + 0,
NaN,
-1/0,
-1/0,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 1Infinity0",
"number NaN",
"number -Infinity",
"number -Infinity",
]
}
issue_3547_3: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "3";
[
a + "2" + 1,
a + "2" - 1,
a - "2" + 1,
a - "2" - 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "3";
[
a + "21",
a + "2" - 1,
a - 1,
a - 3,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 321",
"number 31",
"number 2",
"number 0",
]
}
issue_3547_4: {
options = {
evaluate: true,
unsafe_math: true,
}
input: {
var a = "2";
[
"3" + a + 1,
"3" + a - 1,
"3" - a + 1,
"3" - a - 1,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect: {
var a = "2";
[
"3" + a + 1,
"3" + a - 1,
4 - a,
2 - a,
].forEach(function(n) {
console.log(typeof n, n);
});
}
expect_stdout: [
"string 321",
"number 31",
"number 2",
"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"
}

223
test/compress/objects.js Normal file
View File

@@ -0,0 +1,223 @@
duplicate_key: {
options = {
objects: true,
side_effects: true,
}
input: {
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
var o = {
a: 3,
b: 2,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: [
"a 3",
"b 2",
]
}
duplicate_key_strict: {
options = {
objects: true,
side_effects: true,
}
input: {
"use strict";
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
"use strict";
var o = {
a: 1,
b: 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: true
}
duplicate_key_side_effect: {
options = {
objects: true,
side_effects: true,
}
input: {
var o = {
a: 1,
b: o = 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect: {
var o = {
a: 1,
b: o = 2,
a: 3,
};
for (var k in o)
console.log(k, o[k]);
}
expect_stdout: [
"a 3",
"b 2",
]
}
duplicate_key_with_accessor: {
options = {
objects: true,
side_effects: true,
}
input: {
[
{
a: 0,
b: 1,
a: 2,
set b(v) {},
},
{
a: 3,
b: 4,
get a() {
return 5;
},
a: 6,
b: 7,
a: 8,
b: 9,
},
].forEach(function(o) {
for (var k in o)
console.log(k, o[k]);
});
}
expect: {
[
{
a: 2,
b: 1,
set b(v) {},
},
{
a: 3,
b: 4,
get a() {
return 5;
},
a: 8,
b: 9,
},
].forEach(function(o) {
for (var k in o)
console.log(k, o[k]);
});
}
expect_stdout: true
}
unsafe_object_repeated: {
options = {
evaluate: true,
objects: true,
reduce_funcs: true,
reduce_vars: true,
side_effects: true,
toplevel: true,
unsafe: true,
}
input: {
var o = { a: { b: 1 }, a: 1 };
console.log(
o + 1,
o.a + 1,
o.b + 1,
o.a.b + 1
);
}
expect: {
var o = { a: 1 };
console.log(
o + 1,
2,
o.b + 1,
NaN
);
}
expect_stdout: true
}
numeric_literal: {
options = {
objects: true,
side_effects: true,
}
mangle = {
properties: true,
}
beautify = {
beautify: true,
}
input: {
var obj = {
0: 0,
"-0": 1,
42: 2,
"42": 3,
0x25: 4,
"0x25": 5,
1E42: 6,
"1E42": 7,
"1e+42": 8,
};
console.log(obj[-0], obj[-""], obj["-0"]);
console.log(obj[42], obj["42"]);
console.log(obj[0x25], obj["0x25"], obj[37], obj["37"]);
console.log(obj[1E42], obj["1E42"], obj["1e+42"]);
}
expect_exact: [
'var obj = {',
' 0: 0,',
' "-0": 1,',
' 42: 3,',
' 37: 4,',
' o: 5,',
' 1e42: 8,',
' b: 7',
'};',
'',
'console.log(obj[-0], obj[-""], obj["-0"]);',
'',
'console.log(obj[42], obj["42"]);',
'',
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
'',
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
]
expect_stdout: [
"0 0 1",
"3 3",
"4 5 4 4",
"8 7 8",
]
}

View File

@@ -1427,13 +1427,13 @@ defun_inline_3: {
defun_call: { defun_call: {
options = { options = {
inline: true, evaluate: true,
reduce_funcs: true, reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
} }
input: { input: {
function f() { console.log(function f() {
return g() + h(1) - h(g(), 2, 3); return g() + h(1) - h(g(), 2, 3);
function g() { function g() {
return 4; return 4;
@@ -1441,21 +1441,17 @@ defun_call: {
function h(a) { function h(a) {
return a; return a;
} }
} }());
} }
expect: { expect: {
function f() { console.log(1);
return 4 + h(1) - h(4);
function h(a) {
return a;
}
}
} }
expect_stdout: "1"
} }
defun_redefine: { defun_redefine: {
options = { options = {
inline: true, evaluate: true,
reduce_funcs: true, reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
@@ -1480,7 +1476,7 @@ defun_redefine: {
(function() { (function() {
return 3; return 3;
}); });
return 3 + 2; return 5;
} }
console.log(f()); console.log(f());
} }
@@ -1517,7 +1513,7 @@ func_inline: {
func_modified: { func_modified: {
options = { options = {
inline: true, evaluate: true,
reduce_funcs: true, reduce_funcs: true,
reduce_vars: true, reduce_vars: true,
unused: true, unused: true,
@@ -1550,7 +1546,7 @@ func_modified: {
(function() { (function() {
return 4; return 4;
}); });
return 1 + 2 + 4; return 7;
} }
console.log(f()); console.log(f());
} }
@@ -5516,9 +5512,7 @@ issue_2860_1: {
}()); }());
} }
expect: { expect: {
console.log(function(a) { console.log(1);
return 1 ^ a;
}());
} }
expect_stdout: "1" expect_stdout: "1"
} }

View File

@@ -36,6 +36,20 @@ regexp_2: {
expect_stdout: '["PASS","pass"]' expect_stdout: '["PASS","pass"]'
} }
regexp_properties: {
options = {
evaluate: true,
unsafe: true,
}
input: {
console.log(/abc/g.source, /abc/g.global, /abc/g.ignoreCase, /abc/g.lastIndex, /abc/g.multiline);
}
expect: {
console.log("abc", true, false, /abc/g.lastIndex, false);
}
expect_stdout: "abc true false 0 false"
}
issue_3434_1: { issue_3434_1: {
options = { options = {
evaluate: true, evaluate: true,

View File

@@ -261,13 +261,13 @@ drop_default_1: {
} }
input: { input: {
switch (foo) { switch (foo) {
case 'bar': baz(); case "bar": baz();
default: default:
} }
} }
expect: { expect: {
switch (foo) { switch (foo) {
case 'bar': baz(); case "bar": baz();
} }
} }
} }
@@ -279,14 +279,14 @@ drop_default_2: {
} }
input: { input: {
switch (foo) { switch (foo) {
case 'bar': baz(); break; case "bar": baz(); break;
default: default:
break; break;
} }
} }
expect: { expect: {
switch (foo) { switch (foo) {
case 'bar': baz(); case "bar": baz();
} }
} }
} }
@@ -298,7 +298,7 @@ keep_default: {
} }
input: { input: {
switch (foo) { switch (foo) {
case 'bar': baz(); case "bar": baz();
default: default:
something(); something();
break; break;
@@ -306,7 +306,7 @@ keep_default: {
} }
expect: { expect: {
switch (foo) { switch (foo) {
case 'bar': baz(); case "bar": baz();
default: default:
something(); something();
} }
@@ -347,25 +347,103 @@ issue_1663: {
expect_stdout: true expect_stdout: true
} }
drop_case: { drop_case_1: {
options = { options = {
dead_code: true, dead_code: true,
switches: true, switches: true,
} }
input: { input: {
switch (foo) { switch (foo) {
case 'bar': baz(); break; case "bar": baz(); break;
case 'moo': case "moo":
break; break;
} }
} }
expect: { expect: {
switch (foo) { 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: { keep_case: {
options = { options = {
dead_code: true, dead_code: true,
@@ -373,14 +451,14 @@ keep_case: {
} }
input: { input: {
switch (foo) { switch (foo) {
case 'bar': baz(); break; case "bar": baz(); break;
case moo: case moo:
break; break;
} }
} }
expect: { expect: {
switch (foo) { switch (foo) {
case 'bar': baz(); break; case "bar": baz(); break;
case moo: case moo:
} }
} }
@@ -539,7 +617,7 @@ issue_1679: {
f(); f();
console.log(a, b); console.log(a, b);
} }
expect_stdout: true expect_stdout: "99 8"
} }
issue_1680_1: { issue_1680_1: {
@@ -864,3 +942,89 @@ issue_1750: {
} }
expect_stdout: "0 2" 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: { expect: {
console.log(function long_name(long_name) { console.log("undefined");
return typeof long_name;
}());
} }
expect_stdout: "undefined" expect_stdout: "undefined"
} }
@@ -295,3 +293,145 @@ issue_2728_6: {
} }
expect_stdout: "function undefined" expect_stdout: "function undefined"
} }
typeof_defined_1: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"undefined" == typeof A && A;
"undefined" != typeof A && A;
"undefined" == typeof A || A;
"undefined" != typeof A || A;
}
expect: {
"undefined" == typeof A && A;
"undefined" != typeof A || A;
}
}
typeof_defined_2: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"function" == typeof A && A;
"function" != typeof A && A;
"function" == typeof A || A;
"function" != typeof A || A;
}
expect: {
"function" != typeof A && A;
"function" == typeof A || A;
}
}
typeof_defined_3: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"undefined" == typeof A && "undefined" == typeof B && (A, B);
"undefined" == typeof A && "undefined" != typeof B && (A, B);
"undefined" != typeof A && "undefined" == typeof B && (A, B);
"undefined" != typeof A && "undefined" != typeof B && (A, B);
"undefined" == typeof A && "undefined" == typeof B || (A, B);
"undefined" == typeof A && "undefined" != typeof B || (A, B);
"undefined" != typeof A && "undefined" == typeof B || (A, B);
"undefined" != typeof A && "undefined" != typeof B || (A, B);
"undefined" == typeof A || "undefined" == typeof B && (A, B);
"undefined" == typeof A || "undefined" != typeof B && (A, B);
"undefined" != typeof A || "undefined" == typeof B && (A, B);
"undefined" != typeof A || "undefined" != typeof B && (A, B);
"undefined" == typeof A || "undefined" == typeof B || (A, B);
"undefined" == typeof A || "undefined" != typeof B || (A, B);
"undefined" != typeof A || "undefined" == typeof B || (A, B);
"undefined" != typeof A || "undefined" != typeof B || (A, B);
}
expect: {
"undefined" == typeof A && "undefined" == typeof B && (A, B);
"undefined" == typeof A && "undefined" != typeof B && A;
"undefined" != typeof A && "undefined" == typeof B && B;
"undefined" == typeof A && "undefined" == typeof B || (A, B);
"undefined" == typeof A && "undefined" != typeof B || (A, B);
"undefined" != typeof A && "undefined" == typeof B || (A, B);
"undefined" != typeof A && "undefined" != typeof B || (A, B);
"undefined" == typeof A || "undefined" == typeof B && B;
"undefined" != typeof A || "undefined" == typeof B && (A, B);
"undefined" != typeof A || "undefined" != typeof B && A;
"undefined" == typeof A || "undefined" != typeof B || B;
"undefined" != typeof A || "undefined" == typeof B || A;
"undefined" != typeof A || "undefined" != typeof B || (A, B);
}
}
typeof_defined_4: {
options = {
side_effects: true,
typeofs: true,
}
input: {
"object" == typeof A && "object" == typeof B && (A, B);
"object" == typeof A && "object" != typeof B && (A, B);
"object" != typeof A && "object" == typeof B && (A, B);
"object" != typeof A && "object" != typeof B && (A, B);
"object" == typeof A && "object" == typeof B || (A, B);
"object" == typeof A && "object" != typeof B || (A, B);
"object" != typeof A && "object" == typeof B || (A, B);
"object" != typeof A && "object" != typeof B || (A, B);
"object" == typeof A || "object" == typeof B && (A, B);
"object" == typeof A || "object" != typeof B && (A, B);
"object" != typeof A || "object" == typeof B && (A, B);
"object" != typeof A || "object" != typeof B && (A, B);
"object" == typeof A || "object" == typeof B || (A, B);
"object" == typeof A || "object" != typeof B || (A, B);
"object" != typeof A || "object" == typeof B || (A, B);
"object" != typeof A || "object" != typeof B || (A, B);
}
expect: {
"object" == typeof A && "object" != typeof B && B;
"object" != typeof A && "object" == typeof B && A;
"object" != typeof A && "object" != typeof B && (A, B);
"object" == typeof A && "object" == typeof B || (A, B);
"object" == typeof A && "object" != typeof B || (A, B);
"object" != typeof A && "object" == typeof B || (A, B);
"object" != typeof A && "object" != typeof B || (A, B);
"object" == typeof A || "object" == typeof B && A;
"object" == typeof A || "object" != typeof B && (A, B);
"object" != typeof A || "object" != typeof B && B;
"object" == typeof A || "object" == typeof B || (A, B);
"object" == typeof A || "object" != typeof B || A;
"object" != typeof A || "object" == typeof B || B;
}
}
emberjs_global: {
options = {
comparisons: true,
conditionals: true,
if_return: true,
passes: 2,
side_effects: true,
toplevel: true,
typeofs: true,
unused: true,
}
input: {
var a;
if (typeof A === "object") {
a = A;
} else if (typeof B === "object") {
a = B;
} else {
throw new Error("PASS");
}
}
expect: {
if ("object" != typeof A && "object" != typeof B)
throw new Error("PASS");
}
expect_stdout: Error("PASS")
}

View File

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

View File

@@ -259,6 +259,30 @@ describe("comments", function() {
assert.strictEqual(result.code, code); assert.strictEqual(result.code, code);
}); });
it("Should handle comments around parenthesis correctly", function() {
var code = [
"a();",
"/* foo */",
"(b())",
"/* bar */",
"c();",
].join("\n");
var result = UglifyJS.minify(code, {
compress: false,
mangle: false,
output: {
comments: "all",
},
});
if (result.error) throw result.error;
assert.strictEqual(result.code, [
"a();",
"/* foo */",
"b()",
"/* bar */;c();",
].join("\n"));
});
it("Should preserve comments around IIFE", function() { it("Should preserve comments around IIFE", function() {
var result = UglifyJS.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", { var result = UglifyJS.minify("/*a*/(/*b*/function(){/*c*/}/*d*/)/*e*/();", {
compress: false, compress: false,

View File

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