Compare commits
374 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
09269be974 | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e | ||
|
|
e2ec270b04 | ||
|
|
ed7a0a454e | ||
|
|
d819559a01 | ||
|
|
8ca49155a8 | ||
|
|
b95e3338d9 | ||
|
|
e40a0ee9c6 | ||
|
|
cb62bd98d3 | ||
|
|
f30790b11b | ||
|
|
5205dbcbf4 | ||
|
|
3ff625de7e | ||
|
|
4832bc5d88 | ||
|
|
7f342cb3e3 | ||
|
|
05e7d34ed4 | ||
|
|
86607156e3 | ||
|
|
0fe259e9c5 | ||
|
|
8701a99a15 | ||
|
|
1476c78b53 | ||
|
|
cb6a92892f | ||
|
|
f1556cb945 | ||
|
|
efffb81735 | ||
|
|
202f90ef8f | ||
|
|
c07ea17c01 | ||
|
|
edb4e3bd52 | ||
|
|
4113609dd4 | ||
|
|
7ac7b0872f | ||
|
|
86ae5881b7 | ||
|
|
fac003c64f | ||
|
|
2273655c17 | ||
|
|
01057cf76d | ||
|
|
032f096b7f | ||
|
|
4b334edf49 | ||
|
|
8ddcbc39e6 | ||
|
|
0b0eac1d5d | ||
|
|
b29fc8b27c | ||
|
|
5de369fa67 | ||
|
|
7918a50d52 | ||
|
|
21794c9b8d | ||
|
|
6c686ce593 | ||
|
|
db902af4c6 | ||
|
|
7d6907cb99 | ||
|
|
092d9affb8 | ||
|
|
8f681b1d17 | ||
|
|
90313875f7 | ||
|
|
3f18a61532 | ||
|
|
02a6ce07eb | ||
|
|
738fd52bc4 | ||
|
|
d18979bb23 | ||
|
|
8266993c6e | ||
|
|
9a137e8613 | ||
|
|
ef618332ea | ||
|
|
7f418978c9 | ||
|
|
04cc395c35 | ||
|
|
e008dc1bde | ||
|
|
ddf96cfda2 | ||
|
|
ebfd5c5c74 | ||
|
|
f2ad542679 | ||
|
|
c43118be4f | ||
|
|
93f3b2b114 | ||
|
|
bf000beae7 | ||
|
|
0e16d92786 | ||
|
|
2441827408 | ||
|
|
0aff037a35 | ||
|
|
74a2f53683 | ||
|
|
e20935c3f2 | ||
|
|
3e34f62a1c | ||
|
|
d21cb84696 | ||
|
|
3dd495ecdd | ||
|
|
b9f3ddfb30 | ||
|
|
77332a0315 | ||
|
|
85c56adbd1 | ||
|
|
8da3754e51 | ||
|
|
9a6b11f8e6 | ||
|
|
7ac6fdcc99 | ||
|
|
f6610baaa8 | ||
|
|
09b320e8a5 | ||
|
|
5a1e99d713 | ||
|
|
b762f2d6f4 | ||
|
|
172079a47f | ||
|
|
c58d3936a3 | ||
|
|
18302bf8e9 | ||
|
|
bc5047c1e7 | ||
|
|
206a54a746 | ||
|
|
32def5ebf5 | ||
|
|
ecc9f6b770 | ||
|
|
b37a68c84f | ||
|
|
c141ae6f8d | ||
|
|
97c464dbf5 | ||
|
|
3b28b915eb | ||
|
|
eb001dc1d9 | ||
|
|
aa9bdf416e | ||
|
|
8987780db6 | ||
|
|
30cfea2e7a | ||
|
|
f4e2fb9864 | ||
|
|
b80062c490 | ||
|
|
667fc4d08b | ||
|
|
6142117cdd | ||
|
|
ae28a24c7f | ||
|
|
ebe761cad0 | ||
|
|
fa7a7c5c5a | ||
|
|
557636f3b7 | ||
|
|
49fbe9c5ac | ||
|
|
2ac5086831 | ||
|
|
c6cfa04d10 | ||
|
|
346fa12e0e | ||
|
|
cda27b0970 | ||
|
|
3c74047368 | ||
|
|
94525d859f | ||
|
|
1127a2caf3 | ||
|
|
246d9d4e83 | ||
|
|
4c0b0177b6 | ||
|
|
38bfb73f06 | ||
|
|
bbedbf4ea0 | ||
|
|
2cfb5aa7da | ||
|
|
6c45101870 | ||
|
|
2c2fd89e34 | ||
|
|
f46281e2b7 | ||
|
|
25a18883f5 | ||
|
|
5b4b07e9a7 | ||
|
|
a8aa28a7a6 | ||
|
|
fe5a68f9d5 | ||
|
|
71e61153b1 | ||
|
|
c8b6f4733d | ||
|
|
a48f87abf2 | ||
|
|
2fd927a7cc | ||
|
|
8428326ea1 | ||
|
|
31f8209193 | ||
|
|
9b0f86f5a1 | ||
|
|
ee082ace1b | ||
|
|
ae67a49850 | ||
|
|
4178289c38 | ||
|
|
74ae16f9f8 | ||
|
|
1968203d83 | ||
|
|
86ea38a259 | ||
|
|
8a713e449f | ||
|
|
24aa07855b | ||
|
|
5fd723f143 | ||
|
|
516eaef50c | ||
|
|
4ae1fb3ed8 | ||
|
|
011123223b | ||
|
|
96439ca246 | ||
|
|
c927cea632 | ||
|
|
9f4b98f8e4 | ||
|
|
0f2ef3367c | ||
|
|
7e5b5cac97 | ||
|
|
c1346e06b7 | ||
|
|
0d2fe8e3ef | ||
|
|
f2b9c11e2a | ||
|
|
fe647b083e | ||
|
|
dfe4f6c6de | ||
|
|
a09c8ad666 | ||
|
|
ec598c351b | ||
|
|
eba0f93bc0 | ||
|
|
99800d4aa9 | ||
|
|
70d56c951a | ||
|
|
b810e2f8da | ||
|
|
1abe14296e | ||
|
|
6920e898d1 | ||
|
|
dd71639264 | ||
|
|
2dcc552ce0 | ||
|
|
55387e8fd0 | ||
|
|
7e3e9da860 | ||
|
|
00f509405b | ||
|
|
aceb0af36b | ||
|
|
4f0953f7e9 | ||
|
|
182a47bfb1 | ||
|
|
cd27f4ec38 | ||
|
|
8158b1bdcf | ||
|
|
aacf3edc68 | ||
|
|
8b89072190 | ||
|
|
395a17ccda | ||
|
|
3f355866cf | ||
|
|
71d52f147d | ||
|
|
eb7adaa6fc | ||
|
|
e5cf7972ea | ||
|
|
f81ff10a9b | ||
|
|
16d40915b4 | ||
|
|
e7c21e87e3 | ||
|
|
c4c2ef44d0 | ||
|
|
a845897758 | ||
|
|
32ea2c5530 | ||
|
|
bc61deeca9 | ||
|
|
6a5e74b44e | ||
|
|
54446341ee | ||
|
|
4e12a6f740 | ||
|
|
b35dfc2599 | ||
|
|
9e1da9235e | ||
|
|
a5ffe2c23f | ||
|
|
9282e7b0c6 | ||
|
|
5229cb2b1b | ||
|
|
458e3e15f0 | ||
|
|
c615a1e80a | ||
|
|
10a938cb79 | ||
|
|
4956ad311b | ||
|
|
145874e504 | ||
|
|
bd7be07c38 | ||
|
|
71ee91e716 | ||
|
|
4f70d2e28c | ||
|
|
4b6ca5e742 | ||
|
|
9306da3c58 | ||
|
|
1ac25fc032 | ||
|
|
5f046c724b | ||
|
|
af0262b7e5 | ||
|
|
6b3aeff1d8 | ||
|
|
20e4f8277f | ||
|
|
f3a487a368 | ||
|
|
2dde41615a | ||
|
|
8b69a3d18e | ||
|
|
d40950b741 | ||
|
|
7659ea1d2e | ||
|
|
bdeadffbf5 | ||
|
|
5e6f26445f | ||
|
|
f0a99125ee | ||
|
|
1e4de2e6d3 | ||
|
|
8b4dcd8f3e | ||
|
|
285401ced8 | ||
|
|
9db4c42380 | ||
|
|
94e5e00c03 | ||
|
|
dc6bcaa18e | ||
|
|
d58b184835 | ||
|
|
b3a57ff019 | ||
|
|
3d5bc08185 | ||
|
|
0692435f01 | ||
|
|
f67a6b0e43 | ||
|
|
343ea326c2 | ||
|
|
1c150c632f | ||
|
|
0a0f4f5591 | ||
|
|
931daa85bf | ||
|
|
00e4f7b3c1 | ||
|
|
11e63bc335 | ||
|
|
33405bb24b | ||
|
|
57dc4fb32f | ||
|
|
b85a358deb | ||
|
|
43697958f3 | ||
|
|
3f961bbba0 | ||
|
|
0a1e523cd5 | ||
|
|
4231f7323e | ||
|
|
da2de350c3 | ||
|
|
41beae4dd7 | ||
|
|
82db9188ac | ||
|
|
3dc9e140e4 | ||
|
|
fed0096556 | ||
|
|
2bdc8802dd | ||
|
|
5ef7cb372a | ||
|
|
4ad7b1dae4 | ||
|
|
9186859cb7 | ||
|
|
47c0713747 | ||
|
|
293c566d6c | ||
|
|
9c306406f1 | ||
|
|
9db0695b10 | ||
|
|
f2af093402 | ||
|
|
b9ad53d1ab | ||
|
|
b0eab71470 | ||
|
|
3493a182b2 | ||
|
|
27c5284d3d | ||
|
|
540220b91b | ||
|
|
84634da4b5 | ||
|
|
1743621889 | ||
|
|
f330ab743a | ||
|
|
4377e932ca | ||
|
|
bac14ba881 | ||
|
|
ec095ed647 | ||
|
|
17e73121fa | ||
|
|
f71e8fd948 | ||
|
|
3e62faa64f | ||
|
|
e9645e017f | ||
|
|
55b5f2a8aa | ||
|
|
4e0a22e5c8 | ||
|
|
1aa38051fb | ||
|
|
e62b879b48 | ||
|
|
c6c9f4f5a8 | ||
|
|
fec14379f6 | ||
|
|
79131cd647 | ||
|
|
c3f14a1481 | ||
|
|
7b13159cda | ||
|
|
95094b9c22 | ||
|
|
1ff8e9dd38 | ||
|
|
78309a293d | ||
|
|
695e182d59 | ||
|
|
dc33facfcb | ||
|
|
c70fb60384 | ||
|
|
793d61499b | ||
|
|
a277fe168d | ||
|
|
7d3b941e6e | ||
|
|
e95052a423 | ||
|
|
e667f0acb8 | ||
|
|
69ac794bc8 | ||
|
|
efdb65913b | ||
|
|
a1dedeb3ce | ||
|
|
d3c4a8e9e7 | ||
|
|
7e164aba8f | ||
|
|
22aedef849 | ||
|
|
58fae7dc07 | ||
|
|
5bf8d7e949 | ||
|
|
1df9d06f4a | ||
|
|
3408fc9d32 | ||
|
|
eae26756f1 | ||
|
|
43add9416b | ||
|
|
efcf167e5e | ||
|
|
6ed90913ca | ||
|
|
569c21e952 | ||
|
|
87c3a2c0ce | ||
|
|
baef8bf050 | ||
|
|
0813c5316f | ||
|
|
c88139492d | ||
|
|
cb45886512 | ||
|
|
050474ab44 | ||
|
|
f6c805ae1d | ||
|
|
9464d3c20f | ||
|
|
f18abd1b9c | ||
|
|
3be06ad085 | ||
|
|
265008c948 | ||
|
|
ff526be61d | ||
|
|
e005099fb1 | ||
|
|
504a436e9d | ||
|
|
3ca902258c | ||
|
|
fd0951231c | ||
|
|
9e29b6dad2 | ||
|
|
c391576d52 | ||
|
|
ac73c5d421 | ||
|
|
547f41beba | ||
|
|
daaefc17b9 | ||
|
|
1d407e761e | ||
|
|
2b44f4ae30 | ||
|
|
e51c3541da | ||
|
|
3bf194684b | ||
|
|
aae7d49d0c | ||
|
|
0459af2ecc | ||
|
|
04f2344efc | ||
|
|
bad9d5cf88 | ||
|
|
a0f5f862df | ||
|
|
41996be86f |
19
.github/ISSUE_TEMPLATE.md
vendored
19
.github/ISSUE_TEMPLATE.md
vendored
@@ -6,15 +6,24 @@
|
|||||||
|
|
||||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||||
|
|
||||||
**`uglify-js` version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input - ideally as small as possible.**
|
**JavaScript input**
|
||||||
|
|
||||||
|
<!--
|
||||||
|
A complete parsable JS program exhibiting the issue with
|
||||||
|
UglifyJS alone - without third party tools or libraries.
|
||||||
|
Ideally the input should be as small as possible.
|
||||||
|
Post a link to a gist if necessary.
|
||||||
|
|
||||||
|
Issues without a reproducible test case will be closed.
|
||||||
|
-->
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
**JavaScript output produced and/or the error or warning.**
|
**JavaScript output or error produced.**
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Note: the release version of uglify-js only supports ES5. Those wishing
|
Note: `uglify-js` only supports ES5.
|
||||||
to minify ES6 should use the experimental harmony branch.
|
Those wishing to minify ES6 should use `uglify-es`.
|
||||||
-->
|
-->
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
before_install: "npm install -g npm"
|
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.12"
|
- "0.12"
|
||||||
- "4"
|
- "4"
|
||||||
- "6"
|
- "6"
|
||||||
|
- "8"
|
||||||
env:
|
env:
|
||||||
- UGLIFYJS_TEST_ALL=1
|
- UGLIFYJS_TEST_ALL=1
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
sudo: false
|
sudo: false
|
||||||
|
cache:
|
||||||
|
directories: tmp
|
||||||
|
|||||||
28
appveyor.yml
28
appveyor.yml
@@ -1,24 +1,20 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- nodejs_version: "0.10"
|
- nodejs_version: "0.10"
|
||||||
- nodejs_version: "0.12"
|
- nodejs_version: "0.12"
|
||||||
- nodejs_version: "4.0"
|
- nodejs_version: "4"
|
||||||
- nodejs_version: "6.0"
|
- nodejs_version: "6"
|
||||||
|
- nodejs_version: "8"
|
||||||
|
install:
|
||||||
|
- ps: Install-Product node $env:nodejs_version
|
||||||
|
- set UGLIFYJS_TEST_ALL=1
|
||||||
|
- npm install
|
||||||
|
build: off
|
||||||
|
cache:
|
||||||
|
- tmp
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
|
|
||||||
platform:
|
|
||||||
- x86
|
|
||||||
- x64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
|
||||||
- npm install
|
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- node --version
|
- node --version
|
||||||
- npm --version
|
- npm --version
|
||||||
- npm test
|
- npm test
|
||||||
|
|
||||||
build: off
|
|
||||||
|
|||||||
176
bin/uglifyjs
176
bin/uglifyjs
@@ -3,11 +3,7 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
var info = require("../package.json");
|
var info = require("../package.json");
|
||||||
@@ -15,21 +11,31 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
};
|
};
|
||||||
program._name = info.name;
|
program.version(info.name + " " + info.version);
|
||||||
program.version(info.version);
|
|
||||||
program.parseArgv = program.parse;
|
program.parseArgv = program.parse;
|
||||||
program.parse = undefined;
|
program.parse = undefined;
|
||||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
||||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
||||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
var text = [];
|
||||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
var options = UglifyJS.default_options();
|
||||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
for (var option in options) {
|
||||||
|
text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
|
||||||
|
text.push(format_object(options[option]));
|
||||||
|
text.push("");
|
||||||
|
}
|
||||||
|
return text.join("\n");
|
||||||
|
};
|
||||||
|
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
||||||
|
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
||||||
|
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
||||||
|
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
||||||
|
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
||||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
@@ -37,9 +43,10 @@ program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("d
|
|||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
|
program.option("--no-rename", "Disable symbol expansion.");
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
||||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
||||||
program.option("--stats", "Display operations run time on STDERR.")
|
program.option("--timings", "Display operations run time on STDERR.")
|
||||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||||
program.option("--verbose", "Print diagnostic messages.");
|
program.option("--verbose", "Print diagnostic messages.");
|
||||||
program.option("--warn", "Print warning messages.");
|
program.option("--warn", "Print warning messages.");
|
||||||
@@ -55,11 +62,13 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
"compress",
|
"compress",
|
||||||
"ie8",
|
"ie8",
|
||||||
"mangle",
|
"mangle",
|
||||||
|
"rename",
|
||||||
"sourceMap",
|
"sourceMap",
|
||||||
"toplevel",
|
"toplevel",
|
||||||
"wrap"
|
"wrap"
|
||||||
].forEach(function(name) {
|
].forEach(function(name) {
|
||||||
if (name in program) {
|
if (name in program) {
|
||||||
|
if (name == "rename" && program[name]) return;
|
||||||
options[name] = program[name];
|
options[name] = program[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -96,17 +105,8 @@ if (program.mangleProps) {
|
|||||||
if (typeof options.mangle != "object") options.mangle = {};
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
options.mangle.properties = program.mangleProps;
|
options.mangle.properties = program.mangleProps;
|
||||||
}
|
}
|
||||||
var cache;
|
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
cache = JSON.parse(read_file(program.nameCache, "{}"));
|
options.nameCache = JSON.parse(read_file(program.nameCache, "{}"));
|
||||||
if (options.mangle) {
|
|
||||||
if (typeof options.mangle != "object") options.mangle = {};
|
|
||||||
options.mangle.cache = to_cache("vars");
|
|
||||||
if (options.mangle.properties) {
|
|
||||||
if (typeof options.mangle.properties != "object") options.mangle.properties = {};
|
|
||||||
options.mangle.properties.cache = to_cache("props");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (program.output == "ast") {
|
if (program.output == "ast") {
|
||||||
options.output = {
|
options.output = {
|
||||||
@@ -115,10 +115,10 @@ if (program.output == "ast") {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (program.parse) {
|
if (program.parse) {
|
||||||
if (program.parse.acorn || program.parse.spidermonkey) {
|
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
||||||
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
|
||||||
} else {
|
|
||||||
options.parse = program.parse;
|
options.parse = program.parse;
|
||||||
|
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
||||||
|
fatal("ERROR: inline source map only works with built-in parser");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var convert_path = function(name) {
|
var convert_path = function(name) {
|
||||||
@@ -140,7 +140,7 @@ if (program.verbose) {
|
|||||||
}
|
}
|
||||||
if (program.self) {
|
if (program.self) {
|
||||||
if (program.args.length) {
|
if (program.args.length) {
|
||||||
console.error("WARN: Ignoring input files since --self was passed");
|
print_error("WARN: Ignoring input files since --self was passed");
|
||||||
}
|
}
|
||||||
if (!options.wrap) options.wrap = "UglifyJS";
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||||
@@ -170,9 +170,9 @@ function convert_ast(fn) {
|
|||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||||
console.error("WARN:", msg);
|
print_error("WARN: " + msg);
|
||||||
};
|
};
|
||||||
if (program.stats) program.stats = Date.now();
|
if (program.timings) options.timings = true;
|
||||||
try {
|
try {
|
||||||
if (program.parse) {
|
if (program.parse) {
|
||||||
if (program.parse.acorn) {
|
if (program.parse.acorn) {
|
||||||
@@ -193,13 +193,13 @@ function run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
fatal(ex.stack);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
var result = UglifyJS.minify(files, options);
|
var result = UglifyJS.minify(files, options);
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
var ex = result.error;
|
var ex = result.error;
|
||||||
if (ex.name == "SyntaxError") {
|
if (ex.name == "SyntaxError") {
|
||||||
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
var col = ex.col;
|
var col = ex.col;
|
||||||
var lines = files[ex.filename].split(/\r?\n/);
|
var lines = files[ex.filename].split(/\r?\n/);
|
||||||
var line = lines[ex.line - 1];
|
var line = lines[ex.line - 1];
|
||||||
@@ -208,21 +208,48 @@ function run() {
|
|||||||
col = line.length;
|
col = line.length;
|
||||||
}
|
}
|
||||||
if (line) {
|
if (line) {
|
||||||
if (col > 40) {
|
var limit = 70;
|
||||||
line = line.slice(col - 40);
|
if (col > limit) {
|
||||||
col = 40;
|
line = line.slice(col - limit);
|
||||||
|
col = limit;
|
||||||
}
|
}
|
||||||
console.error(line.slice(0, 80));
|
print_error(line.slice(0, 80));
|
||||||
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ex.defs) {
|
if (ex.defs) {
|
||||||
console.error("Supported options:");
|
print_error("Supported options:");
|
||||||
console.error(ex.defs);
|
print_error(format_object(ex.defs));
|
||||||
}
|
}
|
||||||
fatal(ex.stack);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (program.output == "ast") {
|
||||||
console.log(JSON.stringify(result.ast, function(key, value) {
|
if (!options.compress && !options.mangle) {
|
||||||
|
result.ast.figure_out_scope({});
|
||||||
|
}
|
||||||
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
switch (key) {
|
||||||
|
case "thedef":
|
||||||
|
if (typeof value == "object" && typeof value.id == "number") {
|
||||||
|
return value.id;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case "enclosed":
|
||||||
|
return value.map(function(sym){
|
||||||
|
return sym.id;
|
||||||
|
});
|
||||||
|
case "variables":
|
||||||
|
case "functions":
|
||||||
|
case "globals":
|
||||||
|
if (value && value.size()) {
|
||||||
|
var ret = {};
|
||||||
|
value.each(function(val, key) {
|
||||||
|
// key/val inverted for readability.
|
||||||
|
ret[val.id] = key;
|
||||||
|
});
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
if (value instanceof UglifyJS.Dictionary) return;
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
@@ -238,7 +265,7 @@ function run() {
|
|||||||
return value;
|
return value;
|
||||||
}, 2));
|
}, 2));
|
||||||
} else if (program.output == "spidermonkey") {
|
} else if (program.output == "spidermonkey") {
|
||||||
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
print(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
@@ -252,18 +279,19 @@ function run() {
|
|||||||
fs.writeFileSync(program.output + ".map", result.map);
|
fs.writeFileSync(program.output + ".map", result.map);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log(result.code);
|
print(result.code);
|
||||||
}
|
}
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
||||||
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
}
|
||||||
}));
|
if (result.timings) for (var phase in result.timings) {
|
||||||
|
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
||||||
}
|
}
|
||||||
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fatal(message) {
|
function fatal(message) {
|
||||||
console.error(message.replace(/^\S*?Error:/, "ERROR:"));
|
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||||
|
print_error(message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,11 +331,11 @@ function read_file(path, default_value) {
|
|||||||
return fs.readFileSync(path, "utf8");
|
return fs.readFileSync(path, "utf8");
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
||||||
fatal(ex.stack);
|
fatal(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_js(flag, constants) {
|
function parse_js(flag) {
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
try {
|
try {
|
||||||
@@ -325,7 +353,7 @@ function parse_js(flag, constants) {
|
|||||||
if (node instanceof UglifyJS.AST_Assign) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
var name = node.left.print_to_string();
|
var name = node.left.print_to_string();
|
||||||
var value = node.right;
|
var value = node.right;
|
||||||
if (!constants) {
|
if (flag) {
|
||||||
options[name] = value;
|
options[name] = value;
|
||||||
} else if (value instanceof UglifyJS.AST_Array) {
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
options[name] = value.elements.map(to_string);
|
options[name] = value.elements.map(to_string);
|
||||||
@@ -348,37 +376,51 @@ function parse_js(flag, constants) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
if (flag) {
|
||||||
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
|
} else {
|
||||||
|
options[value] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_source_map() {
|
function parse_source_map() {
|
||||||
var parse = parse_js("sourceMap", true);
|
var parse = parse_js();
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
var hasContent = options && "content" in options;
|
||||||
var settings = parse(value, options);
|
var settings = parse(value, options);
|
||||||
if (!hasContent && settings.content && settings.content != "inline") {
|
if (!hasContent && settings.content && settings.content != "inline") {
|
||||||
console.error("INFO: Using input source map:", settings.content);
|
print_error("INFO: Using input source map: " + settings.content);
|
||||||
settings.content = read_file(settings.content, settings.content);
|
settings.content = read_file(settings.content, settings.content);
|
||||||
}
|
}
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function to_cache(key) {
|
|
||||||
if (cache[key]) {
|
|
||||||
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
|
||||||
} else {
|
|
||||||
cache[key] = {
|
|
||||||
cname: -1,
|
|
||||||
props: new UglifyJS.Dictionary()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return cache[key];
|
|
||||||
}
|
|
||||||
|
|
||||||
function skip_key(key) {
|
function skip_key(key) {
|
||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function format_object(obj) {
|
||||||
|
var lines = [];
|
||||||
|
var padding = "";
|
||||||
|
Object.keys(obj).map(function(name) {
|
||||||
|
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||||
|
return [ name, JSON.stringify(obj[name]) ];
|
||||||
|
}).forEach(function(tokens) {
|
||||||
|
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
||||||
|
});
|
||||||
|
return lines.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function print_error(msg) {
|
||||||
|
process.stderr.write(msg);
|
||||||
|
process.stderr.write("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
function print(txt) {
|
||||||
|
process.stdout.write(txt);
|
||||||
|
process.stdout.write("\n");
|
||||||
|
}
|
||||||
|
|||||||
57
lib/ast.js
57
lib/ast.js
@@ -87,7 +87,7 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
return ctor;
|
return ctor;
|
||||||
};
|
};
|
||||||
|
|
||||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before file raw", {
|
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
|
||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
var AST_Node = DEFNODE("Node", "start end", {
|
var AST_Node = DEFNODE("Node", "start end", {
|
||||||
@@ -134,11 +134,10 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
|||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value scope quote", {
|
var AST_Directive = DEFNODE("Directive", "value quote", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";",
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
scope: "[AST_Scope/S] The scope that this directive affects",
|
|
||||||
quote: "[string] the original quote character"
|
quote: "[string] the original quote character"
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -299,10 +298,9 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||||
$documentation: "Base class for all statements introducing a lexical scope",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
directives: "[string*/S] an array of directives declared in this scope",
|
|
||||||
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
@@ -354,11 +352,11 @@ var AST_Accessor = DEFNODE("Accessor", null, {
|
|||||||
$documentation: "A setter/getter function. The `name` property is always null."
|
$documentation: "A setter/getter function. The `name` property is always null."
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", null, {
|
var AST_Function = DEFNODE("Function", "inlined", {
|
||||||
$documentation: "A function expression"
|
$documentation: "A function expression"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", null, {
|
var AST_Defun = DEFNODE("Defun", "inlined", {
|
||||||
$documentation: "A function definition"
|
$documentation: "A function definition"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
@@ -495,10 +493,10 @@ var AST_Finally = DEFNODE("Finally", null, {
|
|||||||
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
/* -----[ VAR/CONST ]----- */
|
/* -----[ VAR ]----- */
|
||||||
|
|
||||||
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||||
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
$documentation: "Base class for `var` nodes (variable declarations/initializations)",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
definitions: "[AST_VarDef*] array of variable definitions"
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
},
|
},
|
||||||
@@ -516,14 +514,10 @@ var AST_Var = DEFNODE("Var", null, {
|
|||||||
$documentation: "A `var` statement"
|
$documentation: "A `var` statement"
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
|
|
||||||
var AST_Const = DEFNODE("Const", null, {
|
|
||||||
$documentation: "A `const` statement"
|
|
||||||
}, AST_Definitions);
|
|
||||||
|
|
||||||
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||||
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
$documentation: "A variable declaration; only appears in a AST_Definitions node",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
|
name: "[AST_SymbolVar] name of the variable",
|
||||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
@@ -689,8 +683,8 @@ var AST_Object = DEFNODE("Object", "properties", {
|
|||||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||||
$documentation: "Base class for literal object properties",
|
$documentation: "Base class for literal object properties",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
|
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
|
||||||
value: "[AST_Node] property value. For setters and getters this is an AST_Function."
|
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
@@ -728,17 +722,13 @@ var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
|||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", {
|
||||||
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
$documentation: "A declaration symbol (symbol in var, function name or argument, symbol in catch)",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||||
$documentation: "Symbol defining a variable",
|
$documentation: "Symbol defining a variable",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
|
||||||
$documentation: "A constant declaration"
|
|
||||||
}, AST_SymbolDeclaration);
|
|
||||||
|
|
||||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||||
$documentation: "Symbol naming a function argument",
|
$documentation: "Symbol naming a function argument",
|
||||||
}, AST_SymbolVar);
|
}, AST_SymbolVar);
|
||||||
@@ -867,7 +857,7 @@ TreeWalker.prototype = {
|
|||||||
if (!ret && descend) {
|
if (!ret && descend) {
|
||||||
descend.call(node);
|
descend.call(node);
|
||||||
}
|
}
|
||||||
this.pop(node);
|
this.pop();
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
@@ -881,9 +871,8 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function(node) {
|
pop: function() {
|
||||||
this.stack.pop();
|
if (this.stack.pop() instanceof AST_Lambda) {
|
||||||
if (node instanceof AST_Lambda) {
|
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -909,24 +898,6 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
in_boolean_context: function() {
|
|
||||||
var stack = this.stack;
|
|
||||||
var i = stack.length, self = stack[--i];
|
|
||||||
while (i > 0) {
|
|
||||||
var p = stack[--i];
|
|
||||||
if ((p instanceof AST_If && p.condition === self) ||
|
|
||||||
(p instanceof AST_Conditional && p.condition === self) ||
|
|
||||||
(p instanceof AST_DWLoop && p.condition === self) ||
|
|
||||||
(p instanceof AST_For && p.condition === self) ||
|
|
||||||
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
|
||||||
return false;
|
|
||||||
self = p;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
loopcontrol_target: function(node) {
|
loopcontrol_target: function(node) {
|
||||||
var stack = this.stack;
|
var stack = this.stack;
|
||||||
if (node.label) for (var i = stack.length; --i >= 0;) {
|
if (node.label) for (var i = stack.length; --i >= 0;) {
|
||||||
|
|||||||
4192
lib/compress.js
4192
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -27,31 +27,53 @@ function set_shorthand(name, options, keys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function init_cache(cache) {
|
||||||
|
if (!cache) return;
|
||||||
|
if (!("props" in cache)) {
|
||||||
|
cache.props = new Dictionary();
|
||||||
|
} else if (!(cache.props instanceof Dictionary)) {
|
||||||
|
cache.props = Dictionary.fromObject(cache.props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_json(cache) {
|
||||||
|
return {
|
||||||
|
props: cache.props.toObject()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function minify(files, options) {
|
function minify(files, options) {
|
||||||
var warn_function = AST_Node.warn_function;
|
var warn_function = AST_Node.warn_function;
|
||||||
try {
|
try {
|
||||||
if (typeof files == "string") {
|
|
||||||
files = [ files ];
|
|
||||||
}
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
|
nameCache: null,
|
||||||
output: {},
|
output: {},
|
||||||
parse: {},
|
parse: {},
|
||||||
|
rename: undefined,
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
|
timings: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
warnings: false,
|
warnings: false,
|
||||||
wrap: false,
|
wrap: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
var timings = options.timings && {
|
||||||
|
start: Date.now()
|
||||||
|
};
|
||||||
|
if (options.rename === undefined) {
|
||||||
|
options.rename = options.compress && options.mangle;
|
||||||
|
}
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("warnings", options, [ "compress" ]);
|
set_shorthand("warnings", options, [ "compress" ]);
|
||||||
|
var quoted_props;
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: null,
|
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||||
eval: false,
|
eval: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
@@ -59,6 +81,21 @@ function minify(files, options) {
|
|||||||
reserved: [],
|
reserved: [],
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
if (typeof options.mangle.properties != "object") {
|
||||||
|
options.mangle.properties = {};
|
||||||
|
}
|
||||||
|
if (options.mangle.properties.keep_quoted) {
|
||||||
|
quoted_props = options.mangle.properties.reserved;
|
||||||
|
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||||
|
options.mangle.properties.reserved = quoted_props;
|
||||||
|
}
|
||||||
|
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
||||||
|
options.mangle.properties.cache = options.nameCache.props || {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
init_cache(options.mangle.cache);
|
||||||
|
init_cache(options.mangle.properties.cache);
|
||||||
}
|
}
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
options.sourceMap = defaults(options.sourceMap, {
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
@@ -75,13 +112,17 @@ function minify(files, options) {
|
|||||||
warnings.push(warning);
|
warnings.push(warning);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if (timings) timings.parse = Date.now();
|
||||||
var toplevel;
|
var toplevel;
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
toplevel = files;
|
toplevel = files;
|
||||||
} else {
|
} else {
|
||||||
|
if (typeof files == "string") {
|
||||||
|
files = [ files ];
|
||||||
|
}
|
||||||
options.parse = options.parse || {};
|
options.parse = options.parse || {};
|
||||||
options.parse.toplevel = null;
|
options.parse.toplevel = null;
|
||||||
for (var name in files) {
|
for (var name in files) if (HOP(files, name)) {
|
||||||
options.parse.filename = name;
|
options.parse.filename = name;
|
||||||
options.parse.toplevel = parse(files[name], options.parse);
|
options.parse.toplevel = parse(files[name], options.parse);
|
||||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
@@ -92,22 +133,32 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
toplevel = options.parse.toplevel;
|
||||||
}
|
}
|
||||||
|
if (quoted_props) {
|
||||||
|
reserve_quoted_keys(toplevel, quoted_props);
|
||||||
|
}
|
||||||
if (options.wrap) {
|
if (options.wrap) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
}
|
}
|
||||||
if (options.compress) {
|
if (timings) timings.rename = Date.now();
|
||||||
|
if (options.rename) {
|
||||||
toplevel.figure_out_scope(options.mangle);
|
toplevel.figure_out_scope(options.mangle);
|
||||||
toplevel = new Compressor(options.compress).compress(toplevel);
|
toplevel.expand_names(options.mangle);
|
||||||
}
|
}
|
||||||
|
if (timings) timings.compress = Date.now();
|
||||||
|
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
|
if (timings) timings.scope = Date.now();
|
||||||
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||||
|
if (timings) timings.mangle = Date.now();
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
toplevel.figure_out_scope(options.mangle);
|
|
||||||
base54.reset();
|
base54.reset();
|
||||||
toplevel.compute_char_frequency(options.mangle);
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
toplevel.mangle_names(options.mangle);
|
toplevel.mangle_names(options.mangle);
|
||||||
if (options.mangle.properties) {
|
|
||||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (timings) timings.properties = Date.now();
|
||||||
|
if (options.mangle && options.mangle.properties) {
|
||||||
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||||
|
}
|
||||||
|
if (timings) timings.output = Date.now();
|
||||||
var result = {};
|
var result = {};
|
||||||
if (options.output.ast) {
|
if (options.output.ast) {
|
||||||
result.ast = toplevel;
|
result.ast = toplevel;
|
||||||
@@ -123,7 +174,9 @@ function minify(files, options) {
|
|||||||
root: options.sourceMap.root
|
root: options.sourceMap.root
|
||||||
});
|
});
|
||||||
if (options.sourceMap.includeSources) {
|
if (options.sourceMap.includeSources) {
|
||||||
for (var name in files) {
|
if (files instanceof AST_Toplevel) {
|
||||||
|
throw new Error("original source content unavailable");
|
||||||
|
} else for (var name in files) if (HOP(files, name)) {
|
||||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,6 +195,25 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (options.nameCache && options.mangle) {
|
||||||
|
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
||||||
|
if (options.mangle.properties && options.mangle.properties.cache) {
|
||||||
|
options.nameCache.props = to_json(options.mangle.properties.cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (timings) {
|
||||||
|
timings.end = Date.now();
|
||||||
|
result.timings = {
|
||||||
|
parse: 1e-3 * (timings.rename - timings.parse),
|
||||||
|
rename: 1e-3 * (timings.compress - timings.rename),
|
||||||
|
compress: 1e-3 * (timings.scope - timings.compress),
|
||||||
|
scope: 1e-3 * (timings.mangle - timings.scope),
|
||||||
|
mangle: 1e-3 * (timings.properties - timings.mangle),
|
||||||
|
properties: 1e-3 * (timings.output - timings.properties),
|
||||||
|
output: 1e-3 * (timings.end - timings.output),
|
||||||
|
total: 1e-3 * (timings.end - timings.start)
|
||||||
|
}
|
||||||
|
}
|
||||||
if (warnings.length) {
|
if (warnings.length) {
|
||||||
result.warnings = warnings;
|
result.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,23 +111,19 @@
|
|||||||
},
|
},
|
||||||
Property: function(M) {
|
Property: function(M) {
|
||||||
var key = M.key;
|
var key = M.key;
|
||||||
var name = key.type == "Identifier" ? key.name : key.value;
|
|
||||||
var args = {
|
var args = {
|
||||||
start : my_start_token(key),
|
start : my_start_token(key),
|
||||||
end : my_end_token(M.value),
|
end : my_end_token(M.value),
|
||||||
key : name,
|
key : key.type == "Identifier" ? key.name : key.value,
|
||||||
value : from_moz(M.value)
|
value : from_moz(M.value)
|
||||||
};
|
};
|
||||||
switch (M.kind) {
|
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
||||||
case "init":
|
args.key = new AST_SymbolAccessor({
|
||||||
return new AST_ObjectKeyVal(args);
|
name: args.key
|
||||||
case "set":
|
});
|
||||||
args.value.name = from_moz(key);
|
args.value = new AST_Accessor(args.value);
|
||||||
return new AST_ObjectSetter(args);
|
if (M.kind == "get") return new AST_ObjectGetter(args);
|
||||||
case "get":
|
if (M.kind == "set") return new AST_ObjectSetter(args);
|
||||||
args.value.name = from_moz(key);
|
|
||||||
return new AST_ObjectGetter(args);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ArrayExpression: function(M) {
|
ArrayExpression: function(M) {
|
||||||
return new AST_Array({
|
return new AST_Array({
|
||||||
@@ -172,7 +168,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
VariableDeclaration: function(M) {
|
VariableDeclaration: function(M) {
|
||||||
return new (M.kind === "const" ? AST_Const : AST_Var)({
|
return new AST_Var({
|
||||||
start : my_start_token(M),
|
start : my_start_token(M),
|
||||||
end : my_end_token(M),
|
end : my_end_token(M),
|
||||||
definitions : M.declarations.map(from_moz)
|
definitions : M.declarations.map(from_moz)
|
||||||
@@ -208,7 +204,7 @@
|
|||||||
Identifier: function(M) {
|
Identifier: function(M) {
|
||||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||||
return new ( p.type == "LabeledStatement" ? AST_Label
|
return new ( p.type == "LabeledStatement" ? AST_Label
|
||||||
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
|
||||||
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||||
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||||
: p.type == "CatchClause" ? AST_SymbolCatch
|
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||||
@@ -260,10 +256,7 @@
|
|||||||
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
||||||
|
|
||||||
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
||||||
return {
|
return to_moz_scope("Program", M);
|
||||||
type: "Program",
|
|
||||||
body: M.body.map(to_moz)
|
|
||||||
};
|
|
||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
|
def_to_moz(AST_Defun, function To_Moz_FunctionDeclaration(M) {
|
||||||
@@ -271,7 +264,7 @@
|
|||||||
type: "FunctionDeclaration",
|
type: "FunctionDeclaration",
|
||||||
id: to_moz(M.name),
|
id: to_moz(M.name),
|
||||||
params: M.argnames.map(to_moz),
|
params: M.argnames.map(to_moz),
|
||||||
body: to_moz_block(M)
|
body: to_moz_scope("BlockStatement", M)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -280,7 +273,7 @@
|
|||||||
type: "FunctionExpression",
|
type: "FunctionExpression",
|
||||||
id: to_moz(M.name),
|
id: to_moz(M.name),
|
||||||
params: M.argnames.map(to_moz),
|
params: M.argnames.map(to_moz),
|
||||||
body: to_moz_block(M)
|
body: to_moz_scope("BlockStatement", M)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -331,7 +324,7 @@
|
|||||||
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
||||||
return {
|
return {
|
||||||
type: "VariableDeclaration",
|
type: "VariableDeclaration",
|
||||||
kind: M instanceof AST_Const ? "const" : "var",
|
kind: "var",
|
||||||
declarations: M.definitions.map(to_moz)
|
declarations: M.definitions.map(to_moz)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -386,11 +379,10 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
||||||
var key = (
|
var key = {
|
||||||
is_identifier(M.key)
|
type: "Literal",
|
||||||
? {type: "Identifier", name: M.key}
|
value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
|
||||||
: {type: "Literal", value: M.key}
|
};
|
||||||
);
|
|
||||||
var kind;
|
var kind;
|
||||||
if (M instanceof AST_ObjectKeyVal) {
|
if (M instanceof AST_ObjectKeyVal) {
|
||||||
kind = "init";
|
kind = "init";
|
||||||
@@ -551,8 +543,8 @@
|
|||||||
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
moz_to_me = new Function("U2", "my_start_token", "my_end_token", "from_moz", "return(" + moz_to_me + ")")(
|
||||||
exports, my_start_token, my_end_token, from_moz
|
exports, my_start_token, my_end_token, from_moz
|
||||||
);
|
);
|
||||||
me_to_moz = new Function("to_moz", "to_moz_block", "return(" + me_to_moz + ")")(
|
me_to_moz = new Function("to_moz", "to_moz_block", "to_moz_scope", "return(" + me_to_moz + ")")(
|
||||||
to_moz, to_moz_block
|
to_moz, to_moz_block, to_moz_scope
|
||||||
);
|
);
|
||||||
MOZ_TO_ME[moztype] = moz_to_me;
|
MOZ_TO_ME[moztype] = moz_to_me;
|
||||||
def_to_moz(mytype, me_to_moz);
|
def_to_moz(mytype, me_to_moz);
|
||||||
@@ -610,4 +602,14 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function to_moz_scope(type, node) {
|
||||||
|
var body = node.body.map(to_moz);
|
||||||
|
if (node.body[0] instanceof AST_SimpleStatement && node.body[0].body instanceof AST_String) {
|
||||||
|
body.unshift(to_moz(new AST_EmptyStatement(node.body[0])));
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: type,
|
||||||
|
body: body
|
||||||
|
};
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
503
lib/output.js
503
lib/output.js
@@ -52,6 +52,7 @@ function is_some_comments(comment) {
|
|||||||
|
|
||||||
function OutputStream(options) {
|
function OutputStream(options) {
|
||||||
|
|
||||||
|
var readonly = !options;
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
@@ -70,8 +71,7 @@ function OutputStream(options) {
|
|||||||
semicolons : true,
|
semicolons : true,
|
||||||
shebang : true,
|
shebang : true,
|
||||||
source_map : null,
|
source_map : null,
|
||||||
space_colon : true,
|
webkit : false,
|
||||||
unescape_regexps : false,
|
|
||||||
width : 80,
|
width : 80,
|
||||||
wrap_iife : false,
|
wrap_iife : false,
|
||||||
}, true);
|
}, true);
|
||||||
@@ -110,7 +110,7 @@ function OutputStream(options) {
|
|||||||
var current_pos = 0;
|
var current_pos = 0;
|
||||||
var OUTPUT = "";
|
var OUTPUT = "";
|
||||||
|
|
||||||
function to_ascii(str, identifier) {
|
var to_utf8 = options.ascii_only ? function(str, identifier) {
|
||||||
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
||||||
var code = ch.charCodeAt(0).toString(16);
|
var code = ch.charCodeAt(0).toString(16);
|
||||||
if (code.length <= 2 && !identifier) {
|
if (code.length <= 2 && !identifier) {
|
||||||
@@ -121,6 +121,17 @@ function OutputStream(options) {
|
|||||||
return "\\u" + code;
|
return "\\u" + code;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} : function(str) {
|
||||||
|
var s = "";
|
||||||
|
for (var i = 0, len = str.length; i < len; i++) {
|
||||||
|
if (is_surrogate_pair_head(str[i]) && !is_surrogate_pair_tail(str[i + 1])
|
||||||
|
|| is_surrogate_pair_tail(str[i]) && !is_surrogate_pair_head(str[i - 1])) {
|
||||||
|
s += "\\u" + str.charCodeAt(i).toString(16);
|
||||||
|
} else {
|
||||||
|
s += str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
function make_string(str, quote) {
|
function make_string(str, quote) {
|
||||||
@@ -141,7 +152,7 @@ function OutputStream(options) {
|
|||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case "\ufeff": return "\\ufeff";
|
case "\ufeff": return "\\ufeff";
|
||||||
case "\0":
|
case "\0":
|
||||||
return /[0-7]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
return /[0-9]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
@@ -151,7 +162,7 @@ function OutputStream(options) {
|
|||||||
function quote_double() {
|
function quote_double() {
|
||||||
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
||||||
}
|
}
|
||||||
if (options.ascii_only) str = to_ascii(str);
|
str = to_utf8(str);
|
||||||
switch (options.quote_style) {
|
switch (options.quote_style) {
|
||||||
case 1:
|
case 1:
|
||||||
return quote_single();
|
return quote_single();
|
||||||
@@ -176,8 +187,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function make_name(name) {
|
function make_name(name) {
|
||||||
name = name.toString();
|
name = name.toString();
|
||||||
if (options.ascii_only)
|
name = to_utf8(name, true);
|
||||||
name = to_ascii(name, true);
|
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -190,13 +200,47 @@ function OutputStream(options) {
|
|||||||
var might_need_space = false;
|
var might_need_space = false;
|
||||||
var might_need_semicolon = false;
|
var might_need_semicolon = false;
|
||||||
var might_add_newline = 0;
|
var might_add_newline = 0;
|
||||||
|
var need_newline_indented = false;
|
||||||
|
var need_space = false;
|
||||||
|
var newline_insert = -1;
|
||||||
var last = "";
|
var last = "";
|
||||||
|
var mapping_token, mapping_name, mappings = options.source_map && [];
|
||||||
|
|
||||||
|
var do_add_mapping = mappings ? function() {
|
||||||
|
mappings.forEach(function(mapping) {
|
||||||
|
try {
|
||||||
|
options.source_map.add(
|
||||||
|
mapping.token.file,
|
||||||
|
mapping.line, mapping.col,
|
||||||
|
mapping.token.line, mapping.token.col,
|
||||||
|
!mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
|
||||||
|
);
|
||||||
|
} catch(ex) {
|
||||||
|
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||||
|
file: mapping.token.file,
|
||||||
|
line: mapping.token.line,
|
||||||
|
col: mapping.token.col,
|
||||||
|
cline: mapping.line,
|
||||||
|
ccol: mapping.col,
|
||||||
|
name: mapping.name || ""
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
mappings = [];
|
||||||
|
} : noop;
|
||||||
|
|
||||||
var ensure_line_len = options.max_line_len ? function() {
|
var ensure_line_len = options.max_line_len ? function() {
|
||||||
if (current_col > options.max_line_len) {
|
if (current_col > options.max_line_len) {
|
||||||
if (might_add_newline) {
|
if (might_add_newline) {
|
||||||
var left = OUTPUT.slice(0, might_add_newline);
|
var left = OUTPUT.slice(0, might_add_newline);
|
||||||
var right = OUTPUT.slice(might_add_newline);
|
var right = OUTPUT.slice(might_add_newline);
|
||||||
|
if (mappings) {
|
||||||
|
var delta = right.length - current_col;
|
||||||
|
mappings.forEach(function(mapping) {
|
||||||
|
mapping.line++;
|
||||||
|
mapping.col += delta;
|
||||||
|
});
|
||||||
|
}
|
||||||
OUTPUT = left + "\n" + right;
|
OUTPUT = left + "\n" + right;
|
||||||
current_line++;
|
current_line++;
|
||||||
current_pos++;
|
current_pos++;
|
||||||
@@ -206,7 +250,10 @@ function OutputStream(options) {
|
|||||||
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
might_add_newline = 0;
|
if (might_add_newline) {
|
||||||
|
might_add_newline = 0;
|
||||||
|
do_add_mapping();
|
||||||
|
}
|
||||||
} : noop;
|
} : noop;
|
||||||
|
|
||||||
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
||||||
@@ -214,6 +261,20 @@ function OutputStream(options) {
|
|||||||
function print(str) {
|
function print(str) {
|
||||||
str = String(str);
|
str = String(str);
|
||||||
var ch = str.charAt(0);
|
var ch = str.charAt(0);
|
||||||
|
if (need_newline_indented && ch) {
|
||||||
|
need_newline_indented = false;
|
||||||
|
if (ch != "\n") {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (need_space && ch) {
|
||||||
|
need_space = false;
|
||||||
|
if (!/[\s;})]/.test(ch)) {
|
||||||
|
space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newline_insert = -1;
|
||||||
var prev = last.charAt(last.length - 1);
|
var prev = last.charAt(last.length - 1);
|
||||||
if (might_need_semicolon) {
|
if (might_need_semicolon) {
|
||||||
might_need_semicolon = false;
|
might_need_semicolon = false;
|
||||||
@@ -266,6 +327,18 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
might_need_space = false;
|
might_need_space = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mapping_token) {
|
||||||
|
mappings.push({
|
||||||
|
token: mapping_token,
|
||||||
|
name: mapping_name,
|
||||||
|
line: current_line,
|
||||||
|
col: current_col
|
||||||
|
});
|
||||||
|
mapping_token = false;
|
||||||
|
if (!might_add_newline) do_add_mapping();
|
||||||
|
}
|
||||||
|
|
||||||
OUTPUT += str;
|
OUTPUT += str;
|
||||||
current_pos += str.length;
|
current_pos += str.length;
|
||||||
var a = str.split(/\r?\n/), n = a.length - 1;
|
var a = str.split(/\r?\n/), n = a.length - 1;
|
||||||
@@ -300,7 +373,13 @@ function OutputStream(options) {
|
|||||||
} : function(col, cont) { return cont() };
|
} : function(col, cont) { return cont() };
|
||||||
|
|
||||||
var newline = options.beautify ? function() {
|
var newline = options.beautify ? function() {
|
||||||
print("\n");
|
if (newline_insert < 0) return print("\n");
|
||||||
|
if (OUTPUT[newline_insert] != "\n") {
|
||||||
|
OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert);
|
||||||
|
current_pos++;
|
||||||
|
current_line++;
|
||||||
|
}
|
||||||
|
newline_insert++;
|
||||||
} : options.max_line_len ? function() {
|
} : options.max_line_len ? function() {
|
||||||
ensure_line_len();
|
ensure_line_len();
|
||||||
might_add_newline = OUTPUT.length;
|
might_add_newline = OUTPUT.length;
|
||||||
@@ -357,27 +436,12 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function colon() {
|
function colon() {
|
||||||
print(":");
|
print(":");
|
||||||
if (options.space_colon) space();
|
space();
|
||||||
};
|
};
|
||||||
|
|
||||||
var add_mapping = options.source_map ? function(token, name) {
|
var add_mapping = mappings ? function(token, name) {
|
||||||
try {
|
mapping_token = token;
|
||||||
if (token) options.source_map.add(
|
mapping_name = name;
|
||||||
token.file || "?",
|
|
||||||
current_line, current_col,
|
|
||||||
token.line, token.col,
|
|
||||||
(!name && token.type == "name") ? token.value : name
|
|
||||||
);
|
|
||||||
} catch(ex) {
|
|
||||||
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
|
||||||
file: token.file,
|
|
||||||
line: token.line,
|
|
||||||
col: token.col,
|
|
||||||
cline: current_line,
|
|
||||||
ccol: current_col,
|
|
||||||
name: name || ""
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} : noop;
|
} : noop;
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
@@ -387,6 +451,118 @@ function OutputStream(options) {
|
|||||||
return OUTPUT;
|
return OUTPUT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function prepend_comments(node) {
|
||||||
|
var self = this;
|
||||||
|
var start = node.start;
|
||||||
|
if (!start) return;
|
||||||
|
if (start.comments_before && start.comments_before._dumped === self) return;
|
||||||
|
var comments = start.comments_before;
|
||||||
|
if (!comments) {
|
||||||
|
comments = start.comments_before = [];
|
||||||
|
}
|
||||||
|
comments._dumped = self;
|
||||||
|
|
||||||
|
if (node instanceof AST_Exit && node.value) {
|
||||||
|
var tw = new TreeWalker(function(node) {
|
||||||
|
var parent = tw.parent();
|
||||||
|
if (parent instanceof AST_Exit
|
||||||
|
|| parent instanceof AST_Binary && parent.left === node
|
||||||
|
|| parent.TYPE == "Call" && parent.expression === node
|
||||||
|
|| parent instanceof AST_Conditional && parent.condition === node
|
||||||
|
|| parent instanceof AST_Dot && parent.expression === node
|
||||||
|
|| parent instanceof AST_Sequence && parent.expressions[0] === node
|
||||||
|
|| parent instanceof AST_Sub && parent.expression === node
|
||||||
|
|| parent instanceof AST_UnaryPostfix) {
|
||||||
|
var text = node.start.comments_before;
|
||||||
|
if (text && text._dumped !== self) {
|
||||||
|
text._dumped = self;
|
||||||
|
comments = comments.concat(text);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tw.push(node);
|
||||||
|
node.value.walk(tw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_pos == 0) {
|
||||||
|
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
||||||
|
print("#!" + comments.shift().value + "\n");
|
||||||
|
indent();
|
||||||
|
}
|
||||||
|
var preamble = options.preamble;
|
||||||
|
if (preamble) {
|
||||||
|
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
comments = comments.filter(comment_filter, node);
|
||||||
|
if (comments.length == 0) return;
|
||||||
|
var last_nlb = /(^|\n) *$/.test(OUTPUT);
|
||||||
|
comments.forEach(function(c, i) {
|
||||||
|
if (!last_nlb) {
|
||||||
|
if (c.nlb) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
last_nlb = true;
|
||||||
|
} else if (i > 0) {
|
||||||
|
space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (/comment[134]/.test(c.type)) {
|
||||||
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
||||||
|
indent();
|
||||||
|
last_nlb = true;
|
||||||
|
} else if (c.type == "comment2") {
|
||||||
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
|
last_nlb = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!last_nlb) {
|
||||||
|
if (start.nlb) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
} else {
|
||||||
|
space();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function append_comments(node, tail) {
|
||||||
|
var self = this;
|
||||||
|
var token = node.end;
|
||||||
|
if (!token) return;
|
||||||
|
var comments = token[tail ? "comments_before" : "comments_after"];
|
||||||
|
if (!comments || comments._dumped === self) return;
|
||||||
|
if (!(node instanceof AST_Statement || all(comments, function(c) {
|
||||||
|
return !/comment[134]/.test(c.type);
|
||||||
|
}))) return;
|
||||||
|
comments._dumped = self;
|
||||||
|
var insert = OUTPUT.length;
|
||||||
|
comments.filter(comment_filter, node).forEach(function(c, i) {
|
||||||
|
need_space = false;
|
||||||
|
if (need_newline_indented) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
need_newline_indented = false;
|
||||||
|
} else if (c.nlb && (i > 0 || !/(^|\n) *$/.test(OUTPUT))) {
|
||||||
|
print("\n");
|
||||||
|
indent();
|
||||||
|
} else if (i > 0 || !tail) {
|
||||||
|
space();
|
||||||
|
}
|
||||||
|
if (/comment[134]/.test(c.type)) {
|
||||||
|
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
||||||
|
need_newline_indented = true;
|
||||||
|
} else if (c.type == "comment2") {
|
||||||
|
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||||
|
need_space = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (OUTPUT.length > insert) newline_insert = insert;
|
||||||
|
}
|
||||||
|
|
||||||
var stack = [];
|
var stack = [];
|
||||||
return {
|
return {
|
||||||
get : get,
|
get : get,
|
||||||
@@ -403,7 +579,7 @@ function OutputStream(options) {
|
|||||||
last : function() { return last },
|
last : function() { return last },
|
||||||
semicolon : semicolon,
|
semicolon : semicolon,
|
||||||
force_semicolon : force_semicolon,
|
force_semicolon : force_semicolon,
|
||||||
to_ascii : to_ascii,
|
to_utf8 : to_utf8,
|
||||||
print_name : function(name) { print(make_name(name)) },
|
print_name : function(name) { print(make_name(name)) },
|
||||||
print_string : function(str, quote, escape_directive) {
|
print_string : function(str, quote, escape_directive) {
|
||||||
var encoded = encode_string(str, quote);
|
var encoded = encode_string(str, quote);
|
||||||
@@ -424,7 +600,8 @@ function OutputStream(options) {
|
|||||||
with_square : with_square,
|
with_square : with_square,
|
||||||
add_mapping : add_mapping,
|
add_mapping : add_mapping,
|
||||||
option : function(opt) { return options[opt] },
|
option : function(opt) { return options[opt] },
|
||||||
comment_filter : comment_filter,
|
prepend_comments: readonly ? noop : prepend_comments,
|
||||||
|
append_comments : readonly || comment_filter === return_false ? noop : append_comments,
|
||||||
line : function() { return current_line },
|
line : function() { return current_line },
|
||||||
col : function() { return current_col },
|
col : function() { return current_col },
|
||||||
pos : function() { return current_pos },
|
pos : function() { return current_pos },
|
||||||
@@ -447,18 +624,23 @@ function OutputStream(options) {
|
|||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
};
|
||||||
|
|
||||||
var use_asm = false;
|
|
||||||
var in_directive = false;
|
var in_directive = false;
|
||||||
|
var active_scope = null;
|
||||||
|
var use_asm = null;
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
var self = this, generator = self._codegen;
|
||||||
if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) {
|
if (self instanceof AST_Scope) {
|
||||||
use_asm = true;
|
active_scope = self;
|
||||||
|
}
|
||||||
|
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
|
||||||
|
use_asm = active_scope;
|
||||||
}
|
}
|
||||||
function doit() {
|
function doit() {
|
||||||
self.add_comments(stream);
|
stream.prepend_comments(self);
|
||||||
self.add_source_map(stream);
|
self.add_source_map(stream);
|
||||||
generator(self, stream);
|
generator(self, stream);
|
||||||
|
stream.append_comments(self);
|
||||||
}
|
}
|
||||||
stream.push_node(self);
|
stream.push_node(self);
|
||||||
if (force_parens || self.needs_parens(stream)) {
|
if (force_parens || self.needs_parens(stream)) {
|
||||||
@@ -467,84 +649,18 @@ function OutputStream(options) {
|
|||||||
doit();
|
doit();
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
if (self instanceof AST_Scope) {
|
if (self === use_asm) {
|
||||||
use_asm = prev_use_asm;
|
use_asm = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||||
var s = OutputStream(options);
|
var s = OutputStream(options);
|
||||||
if (!options) s._readonly = true;
|
|
||||||
this.print(s);
|
this.print(s);
|
||||||
return s.get();
|
return s.get();
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ comments ]----- */
|
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("add_comments", function(output){
|
|
||||||
if (output._readonly) return;
|
|
||||||
var self = this;
|
|
||||||
var start = self.start;
|
|
||||||
if (start && !start._comments_dumped) {
|
|
||||||
start._comments_dumped = true;
|
|
||||||
var comments = start.comments_before || [];
|
|
||||||
|
|
||||||
// XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112
|
|
||||||
// and https://github.com/mishoo/UglifyJS2/issues/372
|
|
||||||
if (self instanceof AST_Exit && self.value) {
|
|
||||||
self.value.walk(new TreeWalker(function(node){
|
|
||||||
if (node.start && node.start.comments_before) {
|
|
||||||
comments = comments.concat(node.start.comments_before);
|
|
||||||
node.start.comments_before = [];
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Function ||
|
|
||||||
node instanceof AST_Array ||
|
|
||||||
node instanceof AST_Object)
|
|
||||||
{
|
|
||||||
return true; // don't go inside.
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.pos() == 0) {
|
|
||||||
if (comments.length > 0 && output.option("shebang") && comments[0].type == "comment5") {
|
|
||||||
output.print("#!" + comments.shift().value + "\n");
|
|
||||||
output.indent();
|
|
||||||
}
|
|
||||||
var preamble = output.option("preamble");
|
|
||||||
if (preamble) {
|
|
||||||
output.print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
comments = comments.filter(output.comment_filter, self);
|
|
||||||
|
|
||||||
// Keep single line comments after nlb, after nlb
|
|
||||||
if (!output.option("beautify") && comments.length > 0 &&
|
|
||||||
/comment[134]/.test(comments[0].type) &&
|
|
||||||
output.col() !== 0 && comments[0].nlb)
|
|
||||||
{
|
|
||||||
output.print("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
comments.forEach(function(c){
|
|
||||||
if (/comment[134]/.test(c.type)) {
|
|
||||||
output.print("//" + c.value + "\n");
|
|
||||||
output.indent();
|
|
||||||
}
|
|
||||||
else if (c.type == "comment2") {
|
|
||||||
output.print("/*" + c.value + "*/");
|
|
||||||
if (start.nlb) {
|
|
||||||
output.print("\n");
|
|
||||||
output.indent();
|
|
||||||
} else {
|
|
||||||
output.space();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/* -----[ PARENTHESES ]----- */
|
/* -----[ PARENTHESES ]----- */
|
||||||
|
|
||||||
function PARENS(nodetype, func) {
|
function PARENS(nodetype, func) {
|
||||||
@@ -557,9 +673,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
PARENS(AST_Node, function(){
|
PARENS(AST_Node, return_false);
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// a function expression needs parens around it when it's provably
|
// a function expression needs parens around it when it's provably
|
||||||
// the first token to appear in a statement.
|
// the first token to appear in a statement.
|
||||||
@@ -568,6 +682,13 @@ function OutputStream(options) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (output.option('webkit')) {
|
||||||
|
var p = output.parent();
|
||||||
|
if (p instanceof AST_PropAccess && p.expression === this) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (output.option('wrap_iife')) {
|
if (output.option('wrap_iife')) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_Call && p.expression === this;
|
return p instanceof AST_Call && p.expression === this;
|
||||||
@@ -578,9 +699,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
// same goes for an object literal, because otherwise it would be
|
// same goes for an object literal, because otherwise it would be
|
||||||
// interpreted as a block of code.
|
// interpreted as a block of code.
|
||||||
PARENS(AST_Object, function(output){
|
PARENS(AST_Object, first_in_statement);
|
||||||
return first_in_statement(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
PARENS(AST_Unary, function(output){
|
PARENS(AST_Unary, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
@@ -634,14 +753,15 @@ function OutputStream(options) {
|
|||||||
// parens around it too, otherwise the call will be
|
// parens around it too, otherwise the call will be
|
||||||
// interpreted as passing the arguments to the upper New
|
// interpreted as passing the arguments to the upper New
|
||||||
// expression.
|
// expression.
|
||||||
try {
|
var parens = false;
|
||||||
this.walk(new TreeWalker(function(node){
|
this.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_Call) throw p;
|
if (parens || node instanceof AST_Scope) return true;
|
||||||
}));
|
if (node instanceof AST_Call) {
|
||||||
} catch(ex) {
|
parens = true;
|
||||||
if (ex !== p) throw ex;
|
return true;
|
||||||
return true;
|
}
|
||||||
}
|
}));
|
||||||
|
return parens;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -758,14 +878,21 @@ function OutputStream(options) {
|
|||||||
self.body.print(output);
|
self.body.print(output);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
function print_bracketed(body, output, allow_directives) {
|
function print_bracketed(self, output, allow_directives) {
|
||||||
if (body.length > 0) output.with_block(function(){
|
if (self.body.length > 0) {
|
||||||
display_body(body, false, output, allow_directives);
|
output.with_block(function() {
|
||||||
});
|
display_body(self.body, false, output, allow_directives);
|
||||||
else output.print("{}");
|
});
|
||||||
|
} else {
|
||||||
|
output.print("{");
|
||||||
|
output.with_indent(output.next_indent(), function() {
|
||||||
|
output.append_comments(self, true);
|
||||||
|
});
|
||||||
|
output.print("}");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
DEFPRINT(AST_BlockStatement, function(self, output){
|
DEFPRINT(AST_BlockStatement, function(self, output){
|
||||||
print_bracketed(self.body, output);
|
print_bracketed(self, output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_EmptyStatement, function(self, output){
|
DEFPRINT(AST_EmptyStatement, function(self, output){
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
@@ -860,7 +987,7 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
output.space();
|
output.space();
|
||||||
print_bracketed(self.body, output, true);
|
print_bracketed(self, output, true);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Lambda, function(self, output){
|
DEFPRINT(AST_Lambda, function(self, output){
|
||||||
self._do_print(output);
|
self._do_print(output);
|
||||||
@@ -991,7 +1118,7 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Try, function(self, output){
|
DEFPRINT(AST_Try, function(self, output){
|
||||||
output.print("try");
|
output.print("try");
|
||||||
output.space();
|
output.space();
|
||||||
print_bracketed(self.body, output);
|
print_bracketed(self, output);
|
||||||
if (self.bcatch) {
|
if (self.bcatch) {
|
||||||
output.space();
|
output.space();
|
||||||
self.bcatch.print(output);
|
self.bcatch.print(output);
|
||||||
@@ -1008,12 +1135,12 @@ function OutputStream(options) {
|
|||||||
self.argname.print(output);
|
self.argname.print(output);
|
||||||
});
|
});
|
||||||
output.space();
|
output.space();
|
||||||
print_bracketed(self.body, output);
|
print_bracketed(self, output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Finally, function(self, output){
|
DEFPRINT(AST_Finally, function(self, output){
|
||||||
output.print("finally");
|
output.print("finally");
|
||||||
output.space();
|
output.space();
|
||||||
print_bracketed(self.body, output);
|
print_bracketed(self, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ var/const ]----- */
|
/* -----[ var/const ]----- */
|
||||||
@@ -1033,24 +1160,19 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Var, function(self, output){
|
DEFPRINT(AST_Var, function(self, output){
|
||||||
self._do_print(output, "var");
|
self._do_print(output, "var");
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Const, function(self, output){
|
|
||||||
self._do_print(output, "const");
|
|
||||||
});
|
|
||||||
|
|
||||||
function parenthesize_for_noin(node, output, noin) {
|
function parenthesize_for_noin(node, output, noin) {
|
||||||
if (!noin) node.print(output);
|
var parens = false;
|
||||||
else try {
|
// need to take some precautions here:
|
||||||
// need to take some precautions here:
|
// https://github.com/mishoo/UglifyJS2/issues/60
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/60
|
if (noin) node.walk(new TreeWalker(function(node) {
|
||||||
node.walk(new TreeWalker(function(node){
|
if (parens || node instanceof AST_Scope) return true;
|
||||||
if (node instanceof AST_Binary && node.operator == "in")
|
if (node instanceof AST_Binary && node.operator == "in") {
|
||||||
throw output;
|
parens = true;
|
||||||
}));
|
return true;
|
||||||
node.print(output);
|
}
|
||||||
} catch(ex) {
|
}));
|
||||||
if (ex !== output) throw ex;
|
node.print(output, parens);
|
||||||
node.print(output, true);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_VarDef, function(self, output){
|
DEFPRINT(AST_VarDef, function(self, output){
|
||||||
@@ -1070,6 +1192,9 @@ function OutputStream(options) {
|
|||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
||||||
return;
|
return;
|
||||||
|
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||||
|
output.add_mapping(self.start);
|
||||||
|
}
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
self.args.forEach(function(expr, i){
|
self.args.forEach(function(expr, i){
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
@@ -1109,15 +1234,23 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Dot, function(self, output){
|
DEFPRINT(AST_Dot, function(self, output){
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
var prop = self.property;
|
||||||
if (!/[xa-f.)]/i.test(output.last())) {
|
if (output.option("ie8") && RESERVED_WORDS(prop)) {
|
||||||
output.print(".");
|
output.print("[");
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_string(prop);
|
||||||
|
output.print("]");
|
||||||
|
} else {
|
||||||
|
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
||||||
|
if (!/[xa-f.)]/i.test(output.last())) {
|
||||||
|
output.print(".");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
output.print(".");
|
||||||
|
// the name after dot would be mapped about here.
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_name(prop);
|
||||||
}
|
}
|
||||||
output.print(".");
|
|
||||||
// the name after dot would be mapped about here.
|
|
||||||
output.add_mapping(self.end);
|
|
||||||
output.print_name(self.property);
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Sub, function(self, output){
|
DEFPRINT(AST_Sub, function(self, output){
|
||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
@@ -1208,9 +1341,8 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
else output.print("{}");
|
else output.print("{}");
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
|
||||||
var key = self.key;
|
function print_property_name(key, quote, output) {
|
||||||
var quote = self.quote;
|
|
||||||
if (output.option("quote_keys")) {
|
if (output.option("quote_keys")) {
|
||||||
output.print_string(key + "");
|
output.print_string(key + "");
|
||||||
} else if ((typeof key == "number"
|
} else if ((typeof key == "number"
|
||||||
@@ -1227,20 +1359,24 @@ function OutputStream(options) {
|
|||||||
} else {
|
} else {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
||||||
|
print_property_name(self.key, self.quote, output);
|
||||||
output.colon();
|
output.colon();
|
||||||
self.value.print(output);
|
self.value.print(output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectSetter, function(self, output){
|
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, output) {
|
||||||
output.print("set");
|
output.print(type);
|
||||||
output.space();
|
output.space();
|
||||||
self.key.print(output);
|
print_property_name(this.key.name, this.quote, output);
|
||||||
self.value._do_print(output, true);
|
this.value._do_print(output, true);
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_ObjectSetter, function(self, output){
|
||||||
|
self._print_getter_setter("set", output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||||
output.print("get");
|
self._print_getter_setter("get", output);
|
||||||
output.space();
|
|
||||||
self.key.print(output);
|
|
||||||
self.value._do_print(output, true);
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Symbol, function(self, output){
|
DEFPRINT(AST_Symbol, function(self, output){
|
||||||
var def = self.definition();
|
var def = self.definition();
|
||||||
@@ -1264,46 +1400,13 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function regexp_safe_literal(code) {
|
|
||||||
return [
|
|
||||||
0x5c , // \
|
|
||||||
0x2f , // /
|
|
||||||
0x2e , // .
|
|
||||||
0x2b , // +
|
|
||||||
0x2a , // *
|
|
||||||
0x3f , // ?
|
|
||||||
0x28 , // (
|
|
||||||
0x29 , // )
|
|
||||||
0x5b , // [
|
|
||||||
0x5d , // ]
|
|
||||||
0x7b , // {
|
|
||||||
0x7d , // }
|
|
||||||
0x24 , // $
|
|
||||||
0x5e , // ^
|
|
||||||
0x3a , // :
|
|
||||||
0x7c , // |
|
|
||||||
0x21 , // !
|
|
||||||
0x0a , // \n
|
|
||||||
0x0d , // \r
|
|
||||||
0x00 , // \0
|
|
||||||
0xfeff , // Unicode BOM
|
|
||||||
0x2028 , // unicode "line separator"
|
|
||||||
0x2029 , // unicode "paragraph separator"
|
|
||||||
].indexOf(code) < 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
DEFPRINT(AST_RegExp, function(self, output){
|
DEFPRINT(AST_RegExp, function(self, output){
|
||||||
var str = self.getValue().toString();
|
var regexp = self.getValue();
|
||||||
if (output.option("ascii_only")) {
|
var str = regexp.toString();
|
||||||
str = output.to_ascii(str);
|
if (regexp.raw_source) {
|
||||||
} else if (output.option("unescape_regexps")) {
|
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
|
||||||
str = str.split("\\\\").map(function(str){
|
|
||||||
return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){
|
|
||||||
var code = parseInt(s.substr(2), 16);
|
|
||||||
return regexp_safe_literal(code) ? String.fromCharCode(code) : s;
|
|
||||||
});
|
|
||||||
}).join("\\\\");
|
|
||||||
}
|
}
|
||||||
|
str = output.to_utf8(str);
|
||||||
output.print(str);
|
output.print(str);
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||||
|
|||||||
239
lib/parse.js
239
lib/parse.js
@@ -115,8 +115,6 @@ var PUNC_BEFORE_EXPRESSION = makePredicate(characters("[{(,;:"));
|
|||||||
|
|
||||||
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
|
var PUNC_CHARS = makePredicate(characters("[]{}(),;:"));
|
||||||
|
|
||||||
var REGEXP_MODIFIERS = makePredicate(characters("gmsiy"));
|
|
||||||
|
|
||||||
/* -----[ Tokenizer ]----- */
|
/* -----[ Tokenizer ]----- */
|
||||||
|
|
||||||
// regexps adapted from http://xregexp.com/plugins/#unicode
|
// regexps adapted from http://xregexp.com/plugins/#unicode
|
||||||
@@ -134,6 +132,18 @@ function is_letter(code) {
|
|||||||
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function is_surrogate_pair_head(code) {
|
||||||
|
if (typeof code == "string")
|
||||||
|
code = code.charCodeAt(0);
|
||||||
|
return code >= 0xd800 && code <= 0xdbff;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_surrogate_pair_tail(code) {
|
||||||
|
if (typeof code == "string")
|
||||||
|
code = code.charCodeAt(0);
|
||||||
|
return code >= 0xdc00 && code <= 0xdfff;
|
||||||
|
}
|
||||||
|
|
||||||
function is_digit(code) {
|
function is_digit(code) {
|
||||||
return code >= 48 && code <= 57;
|
return code >= 48 && code <= 57;
|
||||||
};
|
};
|
||||||
@@ -285,7 +295,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
|
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
|
||||||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
|
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
|
||||||
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
|
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
|
||||||
prev_was_dot = (type == "punc" && value == ".");
|
if (type == "punc" && value == ".") {
|
||||||
|
prev_was_dot = true;
|
||||||
|
} else if (!is_comment) {
|
||||||
|
prev_was_dot = false;
|
||||||
|
}
|
||||||
var ret = {
|
var ret = {
|
||||||
type : type,
|
type : type,
|
||||||
value : value,
|
value : value,
|
||||||
@@ -303,11 +317,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
}
|
}
|
||||||
if (!is_comment) {
|
if (!is_comment) {
|
||||||
ret.comments_before = S.comments_before;
|
ret.comments_before = S.comments_before;
|
||||||
S.comments_before = [];
|
ret.comments_after = S.comments_before = [];
|
||||||
// make note of any newlines in the comments that came before
|
|
||||||
for (var i = 0, len = ret.comments_before.length; i < len; i++) {
|
|
||||||
ret.nlb = ret.nlb || ret.comments_before[i].nlb;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
S.newline_before = false;
|
S.newline_before = false;
|
||||||
return new AST_Token(ret);
|
return new AST_Token(ret);
|
||||||
@@ -473,31 +483,33 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
var read_regexp = with_eof_error("Unterminated regular expression", function(regexp){
|
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||||
var prev_backslash = false, ch, in_class = false;
|
var prev_backslash = false, ch, in_class = false;
|
||||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
||||||
parse_error("Unexpected line terminator");
|
parse_error("Unexpected line terminator");
|
||||||
} else if (prev_backslash) {
|
} else if (prev_backslash) {
|
||||||
regexp += "\\" + ch;
|
source += "\\" + ch;
|
||||||
prev_backslash = false;
|
prev_backslash = false;
|
||||||
} else if (ch == "[") {
|
} else if (ch == "[") {
|
||||||
in_class = true;
|
in_class = true;
|
||||||
regexp += ch;
|
source += ch;
|
||||||
} else if (ch == "]" && in_class) {
|
} else if (ch == "]" && in_class) {
|
||||||
in_class = false;
|
in_class = false;
|
||||||
regexp += ch;
|
source += ch;
|
||||||
} else if (ch == "/" && !in_class) {
|
} else if (ch == "/" && !in_class) {
|
||||||
break;
|
break;
|
||||||
} else if (ch == "\\") {
|
} else if (ch == "\\") {
|
||||||
prev_backslash = true;
|
prev_backslash = true;
|
||||||
} else {
|
} else {
|
||||||
regexp += ch;
|
source += ch;
|
||||||
}
|
}
|
||||||
var mods = read_name();
|
var mods = read_name();
|
||||||
try {
|
try {
|
||||||
return token("regexp", new RegExp(regexp, mods));
|
var regexp = new RegExp(source, mods);
|
||||||
|
regexp.raw_source = source;
|
||||||
|
return token("regexp", regexp);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
parse_error(e.message);
|
parse_error(e.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -678,9 +690,7 @@ var PRECEDENCE = (function(a, ret){
|
|||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
|
|
||||||
var STATEMENTS_WITH_LABELS = array_to_hash([ "for", "do", "while", "switch" ]);
|
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||||
|
|
||||||
var ATOMIC_START_TOKEN = array_to_hash([ "atom", "num", "string", "regexp", "name" ]);
|
|
||||||
|
|
||||||
/* -----[ Parser ]----- */
|
/* -----[ Parser ]----- */
|
||||||
|
|
||||||
@@ -694,7 +704,7 @@ function parse($TEXT, options) {
|
|||||||
shebang : true,
|
shebang : true,
|
||||||
strict : false,
|
strict : false,
|
||||||
toplevel : null,
|
toplevel : null,
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
var S = {
|
var S = {
|
||||||
input : (typeof $TEXT == "string"
|
input : (typeof $TEXT == "string"
|
||||||
@@ -764,10 +774,15 @@ function parse($TEXT, options) {
|
|||||||
|
|
||||||
function expect(punc) { return expect_token("punc", punc); };
|
function expect(punc) { return expect_token("punc", punc); };
|
||||||
|
|
||||||
|
function has_newline_before(token) {
|
||||||
|
return token.nlb || !all(token.comments_before, function(comment) {
|
||||||
|
return !comment.nlb;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function can_insert_semicolon() {
|
function can_insert_semicolon() {
|
||||||
return !options.strict && (
|
return !options.strict
|
||||||
S.token.nlb || is("eof") || is("punc", "}")
|
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function semicolon(optional) {
|
function semicolon(optional) {
|
||||||
@@ -785,7 +800,7 @@ function parse($TEXT, options) {
|
|||||||
function embed_tokens(parser) {
|
function embed_tokens(parser) {
|
||||||
return function() {
|
return function() {
|
||||||
var start = S.token;
|
var start = S.token;
|
||||||
var expr = parser();
|
var expr = parser.apply(null, arguments);
|
||||||
var end = prev();
|
var end = prev();
|
||||||
expr.start = start;
|
expr.start = start;
|
||||||
expr.end = end;
|
expr.end = end;
|
||||||
@@ -800,29 +815,24 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var statement = embed_tokens(function() {
|
var statement = embed_tokens(function(strict_defun) {
|
||||||
var tmp;
|
|
||||||
handle_regexp();
|
handle_regexp();
|
||||||
switch (S.token.type) {
|
switch (S.token.type) {
|
||||||
case "string":
|
case "string":
|
||||||
var dir = false;
|
if (S.in_directives) {
|
||||||
if (S.in_directives === true) {
|
var token = peek();
|
||||||
if ((is_token(peek(), "punc", ";") || peek().nlb) && S.token.raw.indexOf("\\") === -1) {
|
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);
|
S.input.add_directive(S.token.value);
|
||||||
} else {
|
} else {
|
||||||
S.in_directives = false;
|
S.in_directives = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var dir = S.in_directives, stat = simple_statement();
|
var dir = S.in_directives, stat = simple_statement();
|
||||||
if (dir) {
|
return dir ? new AST_Directive(stat.body) : stat;
|
||||||
return new AST_Directive({
|
|
||||||
start : stat.body.start,
|
|
||||||
end : stat.body.end,
|
|
||||||
quote : stat.body.quote,
|
|
||||||
value : stat.body.value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return stat;
|
|
||||||
case "num":
|
case "num":
|
||||||
case "regexp":
|
case "regexp":
|
||||||
case "operator":
|
case "operator":
|
||||||
@@ -854,75 +864,100 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case "keyword":
|
case "keyword":
|
||||||
switch (tmp = S.token.value, next(), tmp) {
|
switch (S.token.value) {
|
||||||
case "break":
|
case "break":
|
||||||
|
next();
|
||||||
return break_cont(AST_Break);
|
return break_cont(AST_Break);
|
||||||
|
|
||||||
case "continue":
|
case "continue":
|
||||||
|
next();
|
||||||
return break_cont(AST_Continue);
|
return break_cont(AST_Continue);
|
||||||
|
|
||||||
case "debugger":
|
case "debugger":
|
||||||
|
next();
|
||||||
semicolon();
|
semicolon();
|
||||||
return new AST_Debugger();
|
return new AST_Debugger();
|
||||||
|
|
||||||
case "do":
|
case "do":
|
||||||
|
next();
|
||||||
|
var body = in_loop(statement);
|
||||||
|
expect_token("keyword", "while");
|
||||||
|
var condition = parenthesised();
|
||||||
|
semicolon(true);
|
||||||
return new AST_Do({
|
return new AST_Do({
|
||||||
body : in_loop(statement),
|
body : body,
|
||||||
condition : (expect_token("keyword", "while"), tmp = parenthesised(), semicolon(true), tmp)
|
condition : condition
|
||||||
});
|
});
|
||||||
|
|
||||||
case "while":
|
case "while":
|
||||||
|
next();
|
||||||
return new AST_While({
|
return new AST_While({
|
||||||
condition : parenthesised(),
|
condition : parenthesised(),
|
||||||
body : in_loop(statement)
|
body : in_loop(statement)
|
||||||
});
|
});
|
||||||
|
|
||||||
case "for":
|
case "for":
|
||||||
|
next();
|
||||||
return for_();
|
return for_();
|
||||||
|
|
||||||
case "function":
|
case "function":
|
||||||
|
if (!strict_defun && S.input.has_directive("use strict")) {
|
||||||
|
croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
|
||||||
|
}
|
||||||
|
next();
|
||||||
return function_(AST_Defun);
|
return function_(AST_Defun);
|
||||||
|
|
||||||
case "if":
|
case "if":
|
||||||
|
next();
|
||||||
return if_();
|
return if_();
|
||||||
|
|
||||||
case "return":
|
case "return":
|
||||||
if (S.in_function == 0 && !options.bare_returns)
|
if (S.in_function == 0 && !options.bare_returns)
|
||||||
croak("'return' outside of function");
|
croak("'return' outside of function");
|
||||||
|
next();
|
||||||
|
var value = null;
|
||||||
|
if (is("punc", ";")) {
|
||||||
|
next();
|
||||||
|
} else if (!can_insert_semicolon()) {
|
||||||
|
value = expression(true);
|
||||||
|
semicolon();
|
||||||
|
}
|
||||||
return new AST_Return({
|
return new AST_Return({
|
||||||
value: ( is("punc", ";")
|
value: value
|
||||||
? (next(), null)
|
|
||||||
: can_insert_semicolon()
|
|
||||||
? null
|
|
||||||
: (tmp = expression(true), semicolon(), tmp) )
|
|
||||||
});
|
});
|
||||||
|
|
||||||
case "switch":
|
case "switch":
|
||||||
|
next();
|
||||||
return new AST_Switch({
|
return new AST_Switch({
|
||||||
expression : parenthesised(),
|
expression : parenthesised(),
|
||||||
body : in_loop(switch_body_)
|
body : in_loop(switch_body_)
|
||||||
});
|
});
|
||||||
|
|
||||||
case "throw":
|
case "throw":
|
||||||
if (S.token.nlb)
|
next();
|
||||||
|
if (has_newline_before(S.token))
|
||||||
croak("Illegal newline after 'throw'");
|
croak("Illegal newline after 'throw'");
|
||||||
|
var value = expression(true);
|
||||||
|
semicolon();
|
||||||
return new AST_Throw({
|
return new AST_Throw({
|
||||||
value: (tmp = expression(true), semicolon(), tmp)
|
value: value
|
||||||
});
|
});
|
||||||
|
|
||||||
case "try":
|
case "try":
|
||||||
|
next();
|
||||||
return try_();
|
return try_();
|
||||||
|
|
||||||
case "var":
|
case "var":
|
||||||
return tmp = var_(), semicolon(), tmp;
|
next();
|
||||||
|
var node = var_();
|
||||||
case "const":
|
semicolon();
|
||||||
return tmp = const_(), semicolon(), tmp;
|
return node;
|
||||||
|
|
||||||
case "with":
|
case "with":
|
||||||
if (S.input.has_directive("use strict")) {
|
if (S.input.has_directive("use strict")) {
|
||||||
croak("Strict mode may not include a with statement");
|
croak("Strict mode may not include a with statement");
|
||||||
}
|
}
|
||||||
|
next();
|
||||||
return new AST_With({
|
return new AST_With({
|
||||||
expression : parenthesised(),
|
expression : parenthesised(),
|
||||||
body : statement()
|
body : statement()
|
||||||
@@ -991,8 +1026,12 @@ function parse($TEXT, options) {
|
|||||||
? (next(), var_(true))
|
? (next(), var_(true))
|
||||||
: expression(true, true);
|
: expression(true, true);
|
||||||
if (is("operator", "in")) {
|
if (is("operator", "in")) {
|
||||||
if (init instanceof AST_Var && init.definitions.length > 1)
|
if (init instanceof AST_Var) {
|
||||||
croak("Only one variable declaration allowed in for..in loop");
|
if (init.definitions.length > 1)
|
||||||
|
croak("Only one variable declaration allowed in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
} else if (!is_assignable(init)) {
|
||||||
|
croak("Invalid left-hand side in for..in loop", init.start.line, init.start.col, init.start.pos);
|
||||||
|
}
|
||||||
next();
|
next();
|
||||||
return for_in(init);
|
return for_in(init);
|
||||||
}
|
}
|
||||||
@@ -1031,6 +1070,8 @@ function parse($TEXT, options) {
|
|||||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||||
if (in_statement && !name)
|
if (in_statement && !name)
|
||||||
unexpected();
|
unexpected();
|
||||||
|
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||||
|
unexpected(prev());
|
||||||
expect("(");
|
expect("(");
|
||||||
var argnames = [];
|
var argnames = [];
|
||||||
for (var first = true; !is("punc", ")");) {
|
for (var first = true; !is("punc", ")");) {
|
||||||
@@ -1045,7 +1086,7 @@ function parse($TEXT, options) {
|
|||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
S.in_loop = 0;
|
S.in_loop = 0;
|
||||||
S.labels = [];
|
S.labels = [];
|
||||||
var body = block_();
|
var body = block_(true);
|
||||||
if (S.input.has_directive("use strict")) {
|
if (S.input.has_directive("use strict")) {
|
||||||
if (name) strict_verify_symbol(name);
|
if (name) strict_verify_symbol(name);
|
||||||
argnames.forEach(strict_verify_symbol);
|
argnames.forEach(strict_verify_symbol);
|
||||||
@@ -1074,12 +1115,12 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function block_() {
|
function block_(strict_defun) {
|
||||||
expect("{");
|
expect("{");
|
||||||
var a = [];
|
var a = [];
|
||||||
while (!is("punc", "}")) {
|
while (!is("punc", "}")) {
|
||||||
if (is("eof")) unexpected();
|
if (is("eof")) unexpected();
|
||||||
a.push(statement());
|
a.push(statement(strict_defun));
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return a;
|
return a;
|
||||||
@@ -1153,16 +1194,13 @@ function parse($TEXT, options) {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function vardefs(no_in, in_const) {
|
function vardefs(no_in) {
|
||||||
var a = [];
|
var a = [];
|
||||||
for (;;) {
|
for (;;) {
|
||||||
a.push(new AST_VarDef({
|
a.push(new AST_VarDef({
|
||||||
start : S.token,
|
start : S.token,
|
||||||
name : as_symbol(in_const ? AST_SymbolConst : AST_SymbolVar),
|
name : as_symbol(AST_SymbolVar),
|
||||||
value : is("operator", "=")
|
value : is("operator", "=") ? (next(), expression(false, no_in)) : null,
|
||||||
? (next(), expression(false, no_in))
|
|
||||||
: in_const && S.input.has_directive("use strict")
|
|
||||||
? croak("Missing initializer in const declaration") : null,
|
|
||||||
end : prev()
|
end : prev()
|
||||||
}));
|
}));
|
||||||
if (!is("punc", ","))
|
if (!is("punc", ","))
|
||||||
@@ -1175,15 +1213,7 @@ function parse($TEXT, options) {
|
|||||||
var var_ = function(no_in) {
|
var var_ = function(no_in) {
|
||||||
return new AST_Var({
|
return new AST_Var({
|
||||||
start : prev(),
|
start : prev(),
|
||||||
definitions : vardefs(no_in, false),
|
definitions : vardefs(no_in),
|
||||||
end : prev()
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var const_ = function() {
|
|
||||||
return new AST_Const({
|
|
||||||
start : prev(),
|
|
||||||
definitions : vardefs(false, true),
|
|
||||||
end : prev()
|
end : prev()
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1198,19 +1228,20 @@ function parse($TEXT, options) {
|
|||||||
} else {
|
} else {
|
||||||
args = [];
|
args = [];
|
||||||
}
|
}
|
||||||
return subscripts(new AST_New({
|
var call = new AST_New({
|
||||||
start : start,
|
start : start,
|
||||||
expression : newexp,
|
expression : newexp,
|
||||||
args : args,
|
args : args,
|
||||||
end : prev()
|
end : prev()
|
||||||
}), allow_calls);
|
});
|
||||||
|
mark_pure(call);
|
||||||
|
return subscripts(call, allow_calls);
|
||||||
};
|
};
|
||||||
|
|
||||||
function as_atom_node() {
|
function as_atom_node() {
|
||||||
var tok = S.token, ret;
|
var tok = S.token, ret;
|
||||||
switch (tok.type) {
|
switch (tok.type) {
|
||||||
case "name":
|
case "name":
|
||||||
case "keyword":
|
|
||||||
ret = _make_symbol(AST_SymbolRef);
|
ret = _make_symbol(AST_SymbolRef);
|
||||||
break;
|
break;
|
||||||
case "num":
|
case "num":
|
||||||
@@ -1240,13 +1271,6 @@ function parse($TEXT, options) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "operator":
|
|
||||||
if (!is_identifier_string(tok.value)) {
|
|
||||||
croak("Invalid getter/setter name: " + tok.value,
|
|
||||||
tok.line, tok.col, tok.pos);
|
|
||||||
}
|
|
||||||
ret = _make_symbol(AST_SymbolRef);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
next();
|
next();
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1262,9 +1286,26 @@ function parse($TEXT, options) {
|
|||||||
case "(":
|
case "(":
|
||||||
next();
|
next();
|
||||||
var ex = expression(true);
|
var ex = expression(true);
|
||||||
|
var len = start.comments_before.length;
|
||||||
|
[].unshift.apply(ex.start.comments_before, start.comments_before);
|
||||||
|
start.comments_before = ex.start.comments_before;
|
||||||
|
start.comments_before_length = len;
|
||||||
|
if (len == 0 && start.comments_before.length > 0) {
|
||||||
|
var comment = start.comments_before[0];
|
||||||
|
if (!comment.nlb) {
|
||||||
|
comment.nlb = start.nlb;
|
||||||
|
start.nlb = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
start.comments_after = ex.start.comments_after;
|
||||||
ex.start = start;
|
ex.start = start;
|
||||||
ex.end = S.token;
|
|
||||||
expect(")");
|
expect(")");
|
||||||
|
var end = prev();
|
||||||
|
end.comments_before = ex.end.comments_before;
|
||||||
|
[].push.apply(ex.end.comments_after, end.comments_after);
|
||||||
|
end.comments_after = ex.end.comments_after;
|
||||||
|
ex.end = end;
|
||||||
|
if (ex instanceof AST_Call) mark_pure(ex);
|
||||||
return subscripts(ex, allow_calls);
|
return subscripts(ex, allow_calls);
|
||||||
case "[":
|
case "[":
|
||||||
return subscripts(array_(), allow_calls);
|
return subscripts(array_(), allow_calls);
|
||||||
@@ -1280,7 +1321,7 @@ function parse($TEXT, options) {
|
|||||||
func.end = prev();
|
func.end = prev();
|
||||||
return subscripts(func, allow_calls);
|
return subscripts(func, allow_calls);
|
||||||
}
|
}
|
||||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
if (ATOMIC_START_TOKEN(S.token.type)) {
|
||||||
return subscripts(as_atom_node(), allow_calls);
|
return subscripts(as_atom_node(), allow_calls);
|
||||||
}
|
}
|
||||||
unexpected();
|
unexpected();
|
||||||
@@ -1324,10 +1365,15 @@ function parse($TEXT, options) {
|
|||||||
var type = start.type;
|
var type = start.type;
|
||||||
var name = as_property_name();
|
var name = as_property_name();
|
||||||
if (type == "name" && !is("punc", ":")) {
|
if (type == "name" && !is("punc", ":")) {
|
||||||
|
var key = new AST_SymbolAccessor({
|
||||||
|
start: S.token,
|
||||||
|
name: as_property_name(),
|
||||||
|
end: prev()
|
||||||
|
});
|
||||||
if (name == "get") {
|
if (name == "get") {
|
||||||
a.push(new AST_ObjectGetter({
|
a.push(new AST_ObjectGetter({
|
||||||
start : start,
|
start : start,
|
||||||
key : as_atom_node(),
|
key : key,
|
||||||
value : create_accessor(),
|
value : create_accessor(),
|
||||||
end : prev()
|
end : prev()
|
||||||
}));
|
}));
|
||||||
@@ -1336,7 +1382,7 @@ function parse($TEXT, options) {
|
|||||||
if (name == "set") {
|
if (name == "set") {
|
||||||
a.push(new AST_ObjectSetter({
|
a.push(new AST_ObjectSetter({
|
||||||
start : start,
|
start : start,
|
||||||
key : as_atom_node(),
|
key : key,
|
||||||
value : create_accessor(),
|
value : create_accessor(),
|
||||||
end : prev()
|
end : prev()
|
||||||
}));
|
}));
|
||||||
@@ -1407,6 +1453,19 @@ function parse($TEXT, options) {
|
|||||||
return sym;
|
return sym;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function mark_pure(call) {
|
||||||
|
var start = call.start;
|
||||||
|
var comments = start.comments_before;
|
||||||
|
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
|
||||||
|
while (--i >= 0) {
|
||||||
|
var comment = comments[i];
|
||||||
|
if (/[@#]__PURE__/.test(comment.value)) {
|
||||||
|
call.pure = comment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var subscripts = function(expr, allow_calls) {
|
var subscripts = function(expr, allow_calls) {
|
||||||
var start = expr.start;
|
var start = expr.start;
|
||||||
if (is("punc", ".")) {
|
if (is("punc", ".")) {
|
||||||
@@ -1431,12 +1490,14 @@ function parse($TEXT, options) {
|
|||||||
}
|
}
|
||||||
if (allow_calls && is("punc", "(")) {
|
if (allow_calls && is("punc", "(")) {
|
||||||
next();
|
next();
|
||||||
return subscripts(new AST_Call({
|
var call = new AST_Call({
|
||||||
start : start,
|
start : start,
|
||||||
expression : expr,
|
expression : expr,
|
||||||
args : expr_list(")"),
|
args : expr_list(")"),
|
||||||
end : prev()
|
end : prev()
|
||||||
}), true);
|
});
|
||||||
|
mark_pure(call);
|
||||||
|
return subscripts(call, true);
|
||||||
}
|
}
|
||||||
return expr;
|
return expr;
|
||||||
};
|
};
|
||||||
@@ -1452,7 +1513,7 @@ function parse($TEXT, options) {
|
|||||||
return ex;
|
return ex;
|
||||||
}
|
}
|
||||||
var val = expr_atom(allow_calls);
|
var val = expr_atom(allow_calls);
|
||||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !S.token.nlb) {
|
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
||||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||||
val.start = start;
|
val.start = start;
|
||||||
val.end = S.token;
|
val.end = S.token;
|
||||||
@@ -1572,7 +1633,7 @@ function parse($TEXT, options) {
|
|||||||
var body = [];
|
var body = [];
|
||||||
S.input.push_directives_stack();
|
S.input.push_directives_stack();
|
||||||
while (!is("eof"))
|
while (!is("eof"))
|
||||||
body.push(statement());
|
body.push(statement(true));
|
||||||
S.input.pop_directives_stack();
|
S.input.pop_directives_stack();
|
||||||
var end = prev();
|
var end = prev();
|
||||||
var toplevel = options.toplevel;
|
var toplevel = options.toplevel;
|
||||||
|
|||||||
@@ -67,6 +67,34 @@ function find_builtins(reserved) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
|
function add(name) {
|
||||||
|
push_uniq(reserved, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
ast.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
||||||
|
add(node.key);
|
||||||
|
} else if (node instanceof AST_Sub) {
|
||||||
|
addStrings(node.property, add);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
function addStrings(node, add) {
|
||||||
|
node.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Sequence) {
|
||||||
|
addStrings(node.tail_node(), add);
|
||||||
|
} else if (node instanceof AST_String) {
|
||||||
|
add(node.value);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
addStrings(node.consequent, add);
|
||||||
|
addStrings(node.alternative, add);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
builtins: false,
|
builtins: false,
|
||||||
@@ -76,21 +104,24 @@ function mangle_properties(ast, options) {
|
|||||||
only_cache: false,
|
only_cache: false,
|
||||||
regex: null,
|
regex: null,
|
||||||
reserved: null,
|
reserved: null,
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
var reserved = options.reserved || [];
|
var reserved = options.reserved;
|
||||||
|
if (!Array.isArray(reserved)) reserved = [];
|
||||||
if (!options.builtins) find_builtins(reserved);
|
if (!options.builtins) find_builtins(reserved);
|
||||||
|
|
||||||
var cache = options.cache;
|
var cname = -1;
|
||||||
if (cache == null) {
|
var cache;
|
||||||
cache = {
|
if (options.cache) {
|
||||||
cname: -1,
|
cache = options.cache.props;
|
||||||
props: new Dictionary()
|
cache.each(function(mangled_name) {
|
||||||
};
|
push_uniq(reserved, mangled_name);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cache = new Dictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
var keep_quoted = options.keep_quoted;
|
|
||||||
|
|
||||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||||
@@ -103,12 +134,11 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
var unmangleable = [];
|
var unmangleable = [];
|
||||||
var to_keep = {};
|
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
add(node.key, keep_quoted && node.quote);
|
add(node.key);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter, since KeyVal is handled above
|
// setter or getter, since KeyVal is handled above
|
||||||
@@ -118,15 +148,14 @@ function mangle_properties(ast, options) {
|
|||||||
add(node.property);
|
add(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
addStrings(node.property, keep_quoted);
|
addStrings(node.property, add);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// step 2: transform the tree, renaming properties
|
// step 2: transform the tree, renaming properties
|
||||||
return ast.transform(new TreeTransformer(function(node){
|
return ast.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
if (!(keep_quoted && node.quote))
|
node.key = mangle(node.key);
|
||||||
node.key = mangle(node.key);
|
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
@@ -135,22 +164,9 @@ function mangle_properties(ast, options) {
|
|||||||
else if (node instanceof AST_Dot) {
|
else if (node instanceof AST_Dot) {
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||||
if (!keep_quoted)
|
node.property = mangleStrings(node.property);
|
||||||
node.property = mangleStrings(node.property);
|
|
||||||
}
|
}
|
||||||
// else if (node instanceof AST_String) {
|
|
||||||
// if (should_mangle(node.value)) {
|
|
||||||
// AST_Node.warn(
|
|
||||||
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
|
||||||
// file : node.start.file,
|
|
||||||
// line : node.start.line,
|
|
||||||
// col : node.start.col,
|
|
||||||
// prop : node.value
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
@@ -159,26 +175,20 @@ function mangle_properties(ast, options) {
|
|||||||
if (unmangleable.indexOf(name) >= 0) return false;
|
if (unmangleable.indexOf(name) >= 0) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
if (options.only_cache) {
|
if (options.only_cache) {
|
||||||
return cache.props.has(name);
|
return cache.has(name);
|
||||||
}
|
}
|
||||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (keep_quoted && name in to_keep) return false;
|
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name, keep) {
|
function add(name) {
|
||||||
if (keep) {
|
|
||||||
to_keep[name] = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (can_mangle(name))
|
if (can_mangle(name))
|
||||||
push_uniq(names_to_mangle, name);
|
push_uniq(names_to_mangle, name);
|
||||||
|
|
||||||
@@ -192,58 +202,29 @@ function mangle_properties(ast, options) {
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
var mangled = cache.props.get(name);
|
var mangled = cache.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||||
|
|
||||||
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
if (can_mangle(debug_mangled)) {
|
||||||
mangled = debug_mangled;
|
mangled = debug_mangled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// either debug mode is off, or it is on and we could not use the mangled name
|
// either debug mode is off, or it is on and we could not use the mangled name
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
|
||||||
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
|
||||||
// check so we don't collide with a quoted name.
|
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cname);
|
||||||
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
} while (!can_mangle(mangled));
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.set(name, mangled);
|
||||||
}
|
}
|
||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStrings(node, keep) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_Sequence) {
|
|
||||||
walk(node.expressions[node.expressions.length - 1]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_String) {
|
|
||||||
add(node.value, keep);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangleStrings(node) {
|
function mangleStrings(node) {
|
||||||
return node.transform(new TreeTransformer(function(node){
|
return node.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_Sequence) {
|
if (node instanceof AST_Sequence) {
|
||||||
|
|||||||
347
lib/scope.js
347
lib/scope.js
@@ -43,19 +43,21 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, index, orig) {
|
function SymbolDef(scope, orig, init) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
|
this.init = init;
|
||||||
|
this.eliminated = 0;
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
|
this.replaced = 0;
|
||||||
this.global = false;
|
this.global = false;
|
||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
this.index = index;
|
|
||||||
this.id = SymbolDef.next_id++;
|
this.id = SymbolDef.next_id++;
|
||||||
};
|
};
|
||||||
|
|
||||||
SymbolDef.next_id = 1;
|
SymbolDef.next_id = 1e6;
|
||||||
|
|
||||||
SymbolDef.prototype = {
|
SymbolDef.prototype = {
|
||||||
unmangleable: function(options) {
|
unmangleable: function(options) {
|
||||||
@@ -79,7 +81,7 @@ SymbolDef.prototype = {
|
|||||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
var def;
|
var def;
|
||||||
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
if (def = this.redefined()) {
|
||||||
this.mangled_name = def.mangled_name || def.name;
|
this.mangled_name = def.mangled_name || def.name;
|
||||||
} else
|
} else
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = s.next_mangled(options, this);
|
||||||
@@ -87,6 +89,9 @@ SymbolDef.prototype = {
|
|||||||
cache.set(this.name, this.mangled_name);
|
cache.set(this.name, this.mangled_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
redefined: function() {
|
||||||
|
return this.defun && this.defun.variables.get(this.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -146,7 +151,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node);
|
defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolDefun) {
|
else if (node instanceof AST_SymbolDefun) {
|
||||||
// Careful here, the scope where this should be defined is
|
// Careful here, the scope where this should be defined is
|
||||||
@@ -154,11 +159,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
// scope when we encounter the AST_Defun node (which is
|
// scope when we encounter the AST_Defun node (which is
|
||||||
// instanceof AST_Scope) but we get to the symbol a bit
|
// instanceof AST_Scope) but we get to the symbol a bit
|
||||||
// later.
|
// later.
|
||||||
(node.scope = defun.parent_scope).def_function(node);
|
(node.scope = defun.parent_scope).def_function(node, defun);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar
|
else if (node instanceof AST_SymbolVar) {
|
||||||
|| node instanceof AST_SymbolConst) {
|
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||||
defun.def_variable(node);
|
|
||||||
if (defun !== scope) {
|
if (defun !== scope) {
|
||||||
node.mark_enclosed(options);
|
node.mark_enclosed(options);
|
||||||
var def = scope.find_variable(node);
|
var def = scope.find_variable(node);
|
||||||
@@ -184,16 +188,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 2: find back references and eval
|
// pass 2: find back references and eval
|
||||||
var func = null;
|
self.globals = new Dictionary();
|
||||||
var globals = self.globals = new Dictionary();
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node instanceof AST_Lambda) {
|
|
||||||
var prev_func = func;
|
|
||||||
func = node;
|
|
||||||
descend();
|
|
||||||
func = prev_func;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_LoopControl && node.label) {
|
if (node instanceof AST_LoopControl && node.label) {
|
||||||
node.label.thedef.references.push(node);
|
node.label.thedef.references.push(node);
|
||||||
return true;
|
return true;
|
||||||
@@ -206,16 +202,25 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
|
||||||
node.scope.uses_arguments = true;
|
|
||||||
}
|
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
|
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
||||||
|
sym.scope.uses_arguments = true;
|
||||||
}
|
}
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
// ensure mangling works if catch reuses a scope variable
|
||||||
|
var def;
|
||||||
|
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
|
||||||
|
var s = node.scope;
|
||||||
|
while (s) {
|
||||||
|
push_uniq(s.enclosed, def);
|
||||||
|
if (s === def.scope) break;
|
||||||
|
s = s.parent_scope;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
@@ -232,14 +237,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
ref.reference(options);
|
ref.reference(options);
|
||||||
});
|
});
|
||||||
node.thedef = def;
|
node.thedef = def;
|
||||||
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
|
||||||
this.cname = options.cache.cname;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||||
@@ -247,7 +249,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
|
|||||||
if (globals.has(name)) {
|
if (globals.has(name)) {
|
||||||
return globals.get(name);
|
return globals.get(name);
|
||||||
} else {
|
} else {
|
||||||
var g = new SymbolDef(this, globals.size(), node);
|
var g = new SymbolDef(this, node);
|
||||||
g.undeclared = true;
|
g.undeclared = true;
|
||||||
g.global = true;
|
g.global = true;
|
||||||
globals.set(name, g);
|
globals.set(name, g);
|
||||||
@@ -268,7 +270,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
|||||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||||
this.uses_arguments = false;
|
this.uses_arguments = false;
|
||||||
this.def_variable(new AST_SymbolConst({
|
this.def_variable(new AST_SymbolFunarg({
|
||||||
name: "arguments",
|
name: "arguments",
|
||||||
start: this.start,
|
start: this.start,
|
||||||
end: this.end
|
end: this.end
|
||||||
@@ -301,32 +303,37 @@ AST_Scope.DEFMETHOD("find_variable", function(name){
|
|||||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init){
|
||||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
var def = this.def_variable(symbol, init);
|
||||||
|
if (!def.init) def.init = init;
|
||||||
|
this.functions.set(symbol.name, def);
|
||||||
|
return def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_Scope.DEFMETHOD("def_variable", function(symbol, init){
|
||||||
var def;
|
var def = this.variables.get(symbol.name);
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (def) {
|
||||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
def.orig.push(symbol);
|
||||||
|
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
|
||||||
|
def.init = init;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
def = new SymbolDef(this, symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.global = !this.parent_scope;
|
||||||
} else {
|
|
||||||
def = this.variables.get(symbol.name);
|
|
||||||
def.orig.push(symbol);
|
|
||||||
}
|
}
|
||||||
return symbol.thedef = def;
|
return symbol.thedef = def;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
function next_mangled(scope, options) {
|
||||||
var ext = this.enclosed;
|
var ext = scope.enclosed;
|
||||||
out: while (true) {
|
out: while (true) {
|
||||||
var m = base54(++this.cname);
|
var m = base54(++scope.cname);
|
||||||
if (!is_identifier(m)) continue; // skip over "do"
|
if (!is_identifier(m)) continue; // skip over "do"
|
||||||
|
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||||
// shadow a name reserved from mangling.
|
// shadow a name reserved from mangling.
|
||||||
if (options.reserved.indexOf(m) >= 0) continue;
|
if (member(m, options.reserved)) continue;
|
||||||
|
|
||||||
// we must ensure that the mangled name does not shadow a name
|
// we must ensure that the mangled name does not shadow a name
|
||||||
// from some parent scope that is referenced in this or in
|
// from some parent scope that is referenced in this or in
|
||||||
@@ -338,6 +345,18 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||||
|
return next_mangled(this, options);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("next_mangled", function(options){
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = next_mangled(this, options);
|
||||||
|
} while (member(name, this.mangled_names));
|
||||||
|
return name;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||||
@@ -351,43 +370,25 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
var name = next_mangled(this, options);
|
||||||
if (!tricky_name || tricky_name != name)
|
if (!tricky_name || tricky_name != name)
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
return this.definition().unmangleable(options);
|
var def = this.definition();
|
||||||
});
|
return !def || def.unmangleable(options);
|
||||||
|
|
||||||
// property accessors are not mangleable
|
|
||||||
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
AST_Label.DEFMETHOD("unmangleable", function(){
|
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||||
return this.definition().references.length == 0
|
return this.definition().references.length == 0
|
||||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("undeclared", function(){
|
|
||||||
return this.definition().undeclared;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Label.DEFMETHOD("undeclared", function(){
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("definition", function(){
|
AST_Symbol.DEFMETHOD("definition", function(){
|
||||||
return this.thedef;
|
return this.thedef;
|
||||||
});
|
});
|
||||||
@@ -396,22 +397,23 @@ AST_Symbol.DEFMETHOD("global", function(){
|
|||||||
return this.definition().global;
|
return this.definition().global;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||||
return defaults(options, {
|
options = defaults(options, {
|
||||||
eval : false,
|
eval : false,
|
||||||
ie8 : false,
|
ie8 : false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
reserved : [],
|
reserved : [],
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
});
|
});
|
||||||
|
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||||
|
// Never mangle arguments
|
||||||
|
push_uniq(options.reserved, "arguments");
|
||||||
|
return options;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
|
|
||||||
// Never mangle arguments
|
|
||||||
options.reserved.push('arguments');
|
|
||||||
|
|
||||||
// We only need to mangle declaration nodes. Special logic wired
|
// We only need to mangle declaration nodes. Special logic wired
|
||||||
// into the code generator will display the mangled name if it's
|
// into the code generator will display the mangled name if it's
|
||||||
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||||
@@ -419,12 +421,14 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
var lname = -1;
|
var lname = -1;
|
||||||
var to_mangle = [];
|
var to_mangle = [];
|
||||||
|
|
||||||
|
var mangled_names = this.mangled_names = [];
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.globals.each(function(symbol){
|
this.globals.each(collect);
|
||||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
if (options.cache.props) {
|
||||||
to_mangle.push(symbol);
|
options.cache.props.each(function(mangled_name) {
|
||||||
}
|
push_uniq(mangled_names, mangled_name);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
@@ -436,13 +440,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
return true; // don't descend again in TreeWalker
|
return true; // don't descend again in TreeWalker
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope) {
|
||||||
var p = tw.parent(), a = [];
|
node.variables.each(collect);
|
||||||
node.variables.each(function(symbol){
|
|
||||||
if (options.reserved.indexOf(symbol.name) < 0) {
|
|
||||||
a.push(symbol);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
to_mangle.push.apply(to_mangle, a);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
@@ -459,112 +457,141 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||||
|
|
||||||
if (options.cache) {
|
function collect(symbol) {
|
||||||
options.cache.cname = this.cname;
|
if (!member(symbol.name, options.reserved)) {
|
||||||
|
to_mangle.push(symbol);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||||
|
var cache = options.cache && options.cache.props;
|
||||||
|
var avoid = Object.create(null);
|
||||||
|
options.reserved.forEach(to_avoid);
|
||||||
|
this.globals.each(add_def);
|
||||||
|
this.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||||
|
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||||
|
}));
|
||||||
|
return avoid;
|
||||||
|
|
||||||
|
function to_avoid(name) {
|
||||||
|
avoid[name] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function add_def(def) {
|
||||||
|
var name = def.name;
|
||||||
|
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||||
|
else if (!def.unmangleable(options)) return;
|
||||||
|
to_avoid(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||||
|
base54.reset();
|
||||||
|
base54.sort();
|
||||||
|
options = this._default_mangler_options(options);
|
||||||
|
var avoid = this.find_colliding_names(options);
|
||||||
|
var cname = 0;
|
||||||
|
this.globals.each(rename);
|
||||||
|
this.walk(new TreeWalker(function(node) {
|
||||||
|
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||||
|
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||||
|
}));
|
||||||
|
|
||||||
|
function next_name() {
|
||||||
|
var name;
|
||||||
|
do {
|
||||||
|
name = base54(cname++);
|
||||||
|
} while (avoid[name] || !is_identifier(name));
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function rename(def) {
|
||||||
|
if (def.global && options.cache) return;
|
||||||
|
if (def.unmangleable(options)) return;
|
||||||
|
if (member(def.name, options.reserved)) return;
|
||||||
|
var d = def.redefined();
|
||||||
|
def.name = d ? d.name : next_name();
|
||||||
|
def.orig.forEach(function(sym) {
|
||||||
|
sym.name = def.name;
|
||||||
|
});
|
||||||
|
def.references.forEach(function(sym) {
|
||||||
|
sym.name = def.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Node.DEFMETHOD("tail_node", return_this);
|
||||||
|
AST_Sequence.DEFMETHOD("tail_node", function() {
|
||||||
|
return this.expressions[this.expressions.length - 1];
|
||||||
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
var tw = new TreeWalker(function(node){
|
try {
|
||||||
if (node instanceof AST_Constant)
|
AST_Node.prototype.print = function(stream, force_parens) {
|
||||||
base54.consider(node.print_to_string());
|
this._print(stream, force_parens);
|
||||||
else if (node instanceof AST_Return)
|
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
||||||
base54.consider("return");
|
base54.consider(this.name, -1);
|
||||||
else if (node instanceof AST_Throw)
|
} else if (options.properties) {
|
||||||
base54.consider("throw");
|
if (this instanceof AST_Dot) {
|
||||||
else if (node instanceof AST_Continue)
|
base54.consider(this.property, -1);
|
||||||
base54.consider("continue");
|
} else if (this instanceof AST_Sub) {
|
||||||
else if (node instanceof AST_Break)
|
skip_string(this.property);
|
||||||
base54.consider("break");
|
}
|
||||||
else if (node instanceof AST_Debugger)
|
}
|
||||||
base54.consider("debugger");
|
};
|
||||||
else if (node instanceof AST_Directive)
|
base54.consider(this.print_to_string(), 1);
|
||||||
base54.consider(node.value);
|
} finally {
|
||||||
else if (node instanceof AST_While)
|
AST_Node.prototype.print = AST_Node.prototype._print;
|
||||||
base54.consider("while");
|
}
|
||||||
else if (node instanceof AST_Do)
|
|
||||||
base54.consider("do while");
|
|
||||||
else if (node instanceof AST_If) {
|
|
||||||
base54.consider("if");
|
|
||||||
if (node.alternative) base54.consider("else");
|
|
||||||
}
|
|
||||||
else if (node instanceof AST_Var)
|
|
||||||
base54.consider("var");
|
|
||||||
else if (node instanceof AST_Const)
|
|
||||||
base54.consider("const");
|
|
||||||
else if (node instanceof AST_Lambda)
|
|
||||||
base54.consider("function");
|
|
||||||
else if (node instanceof AST_For)
|
|
||||||
base54.consider("for");
|
|
||||||
else if (node instanceof AST_ForIn)
|
|
||||||
base54.consider("for in");
|
|
||||||
else if (node instanceof AST_Switch)
|
|
||||||
base54.consider("switch");
|
|
||||||
else if (node instanceof AST_Case)
|
|
||||||
base54.consider("case");
|
|
||||||
else if (node instanceof AST_Default)
|
|
||||||
base54.consider("default");
|
|
||||||
else if (node instanceof AST_With)
|
|
||||||
base54.consider("with");
|
|
||||||
else if (node instanceof AST_ObjectSetter)
|
|
||||||
base54.consider("set" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectGetter)
|
|
||||||
base54.consider("get" + node.key);
|
|
||||||
else if (node instanceof AST_ObjectKeyVal)
|
|
||||||
base54.consider(node.key);
|
|
||||||
else if (node instanceof AST_New)
|
|
||||||
base54.consider("new");
|
|
||||||
else if (node instanceof AST_This)
|
|
||||||
base54.consider("this");
|
|
||||||
else if (node instanceof AST_Try)
|
|
||||||
base54.consider("try");
|
|
||||||
else if (node instanceof AST_Catch)
|
|
||||||
base54.consider("catch");
|
|
||||||
else if (node instanceof AST_Finally)
|
|
||||||
base54.consider("finally");
|
|
||||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
|
||||||
base54.consider(node.name);
|
|
||||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
|
||||||
base54.consider(node.operator);
|
|
||||||
else if (node instanceof AST_Dot)
|
|
||||||
base54.consider(node.property);
|
|
||||||
});
|
|
||||||
this.walk(tw);
|
|
||||||
base54.sort();
|
base54.sort();
|
||||||
|
|
||||||
|
function skip_string(node) {
|
||||||
|
if (node instanceof AST_String) {
|
||||||
|
base54.consider(node.value, -1);
|
||||||
|
} else if (node instanceof AST_Conditional) {
|
||||||
|
skip_string(node.consequent);
|
||||||
|
skip_string(node.alternative);
|
||||||
|
} else if (node instanceof AST_Sequence) {
|
||||||
|
skip_string(node.tail_node());
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||||
|
var digits = "0123456789".split("");
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(null);
|
||||||
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
leading.forEach(function(ch) {
|
||||||
chars.forEach(function(ch){ frequency[ch] = 0 });
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
|
digits.forEach(function(ch) {
|
||||||
|
frequency[ch] = 0;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
base54.consider = function(str){
|
base54.consider = function(str, delta) {
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
var code = str.charCodeAt(i);
|
frequency[str[i]] += delta;
|
||||||
if (code in frequency) ++frequency[code];
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
function compare(a, b) {
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
}
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(chars, function(a, b){
|
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||||
if (is_digit(a) && !is_digit(b)) return 1;
|
|
||||||
if (is_digit(b) && !is_digit(a)) return -1;
|
|
||||||
return frequency[b] - frequency[a];
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
base54.get = function(){ return chars };
|
|
||||||
base54.freq = function(){ return frequency };
|
|
||||||
function base54(num) {
|
function base54(num) {
|
||||||
var ret = "", base = 54;
|
var ret = "", base = 54;
|
||||||
num++;
|
num++;
|
||||||
do {
|
do {
|
||||||
num--;
|
num--;
|
||||||
ret += String.fromCharCode(chars[num % base]);
|
ret += chars[num % base];
|
||||||
num = Math.floor(num / base);
|
num = Math.floor(num / base);
|
||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
|
|||||||
@@ -60,17 +60,14 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
tw.push(this);
|
tw.push(this);
|
||||||
if (tw.before) x = tw.before(this, descend, in_list);
|
if (tw.before) x = tw.before(this, descend, in_list);
|
||||||
if (x === undefined) {
|
if (x === undefined) {
|
||||||
if (!tw.after) {
|
x = this;
|
||||||
x = this;
|
descend(x, tw);
|
||||||
descend(x, tw);
|
if (tw.after) {
|
||||||
} else {
|
|
||||||
tw.stack[tw.stack.length - 1] = x = this;
|
|
||||||
descend(x, tw);
|
|
||||||
y = tw.after(x, in_list);
|
y = tw.after(x, in_list);
|
||||||
if (y !== undefined) x = y;
|
if (y !== undefined) x = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tw.pop(this);
|
tw.pop();
|
||||||
return x;
|
return x;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
25
lib/utils.js
25
lib/utils.js
@@ -43,17 +43,6 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function array_to_hash(a) {
|
|
||||||
var ret = Object.create(null);
|
|
||||||
for (var i = 0; i < a.length; ++i)
|
|
||||||
ret[a[i]] = true;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
function slice(a, start) {
|
|
||||||
return Array.prototype.slice.call(a, start || 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
function characters(str) {
|
function characters(str) {
|
||||||
return str.split("");
|
return str.split("");
|
||||||
};
|
};
|
||||||
@@ -221,18 +210,6 @@ function mergeSort(array, cmp) {
|
|||||||
return _ms(array);
|
return _ms(array);
|
||||||
};
|
};
|
||||||
|
|
||||||
function set_difference(a, b) {
|
|
||||||
return a.filter(function(el){
|
|
||||||
return b.indexOf(el) < 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function set_intersection(a, b) {
|
|
||||||
return a.filter(function(el){
|
|
||||||
return b.indexOf(el) >= 0;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||||
// [1] https://github.com/marijnh/acorn
|
// [1] https://github.com/marijnh/acorn
|
||||||
function makePredicate(words) {
|
function makePredicate(words) {
|
||||||
@@ -347,7 +324,7 @@ function first_in_statement(stack) {
|
|||||||
if (p instanceof AST_Statement && p.body === node)
|
if (p instanceof AST_Statement && p.body === node)
|
||||||
return true;
|
return true;
|
||||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
(p.TYPE == "Call" && p.expression === node ) ||
|
||||||
(p instanceof AST_Dot && p.expression === node ) ||
|
(p instanceof AST_Dot && p.expression === node ) ||
|
||||||
(p instanceof AST_Sub && p.expression === node ) ||
|
(p instanceof AST_Sub && p.expression === node ) ||
|
||||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
(p instanceof AST_Conditional && p.condition === node ) ||
|
||||||
|
|||||||
33
package.json
33
package.json
@@ -4,20 +4,15 @@
|
|||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "http://lisperator.net/uglifyjs",
|
||||||
"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.0.2",
|
"version": "3.3.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
"maintainers": [
|
"maintainers": [
|
||||||
|
"Alex Lam <alexlamsl@gmail.com>",
|
||||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": "mishoo/UglifyJS2",
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
|
||||||
},
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
|
||||||
},
|
|
||||||
"main": "tools/node.js",
|
"main": "tools/node.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"uglifyjs": "bin/uglifyjs"
|
"uglifyjs": "bin/uglifyjs"
|
||||||
@@ -29,26 +24,16 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.9.0",
|
"commander": "~2.13.0",
|
||||||
"source-map": "~0.5.1"
|
"source-map": "~0.6.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~0.6.0",
|
"acorn": "~5.3.0",
|
||||||
"escodegen": "~1.3.3",
|
"mocha": "~3.5.1",
|
||||||
"esfuzz": "~0.3.1",
|
"semver": "~5.4.1"
|
||||||
"estraverse": "~1.5.1",
|
|
||||||
"mocha": "~2.3.4"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"uglify-to-browserify": "~1.0.0"
|
|
||||||
},
|
|
||||||
"browserify": {
|
|
||||||
"transform": [
|
|
||||||
"uglify-to-browserify"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
},
|
},
|
||||||
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
|
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var createHash = require("crypto").createHash;
|
var createHash = require("crypto").createHash;
|
||||||
|
var fetch = require("./fetch");
|
||||||
var fork = require("child_process").fork;
|
var fork = require("child_process").fork;
|
||||||
|
var zlib = require("zlib");
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc");
|
args.push("-mc");
|
||||||
}
|
}
|
||||||
args.push("--stats");
|
args.push("--timings");
|
||||||
var urls = [
|
var urls = [
|
||||||
"https://code.jquery.com/jquery-3.2.1.js",
|
"https://code.jquery.com/jquery-3.2.1.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||||
@@ -19,6 +21,7 @@ var urls = [
|
|||||||
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
"http://builds.emberjs.com/tags/v2.11.0/ember.prod.js",
|
||||||
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
"https://cdn.jsdelivr.net/lodash/4.17.4/lodash.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.js",
|
||||||
|
"https://raw.githubusercontent.com/kangax/html-minifier/v3.5.7/dist/htmlminifier.js",
|
||||||
];
|
];
|
||||||
var results = {};
|
var results = {};
|
||||||
var remaining = 2 * urls.length;
|
var remaining = 2 * urls.length;
|
||||||
@@ -29,14 +32,10 @@ function done() {
|
|||||||
var info = results[url];
|
var info = results[url];
|
||||||
console.log();
|
console.log();
|
||||||
console.log(url);
|
console.log(url);
|
||||||
var elapsed = 0;
|
console.log(info.log);
|
||||||
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
|
||||||
elapsed += 1e-3 * parseInt(time);
|
|
||||||
return "";
|
|
||||||
}));
|
|
||||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
|
||||||
console.log("Original:", info.input, "bytes");
|
console.log("Original:", info.input, "bytes");
|
||||||
console.log("Uglified:", info.output, "bytes");
|
console.log("Uglified:", info.output, "bytes");
|
||||||
|
console.log("GZipped: ", info.gzip, "bytes");
|
||||||
console.log("SHA1 sum:", info.sha1);
|
console.log("SHA1 sum:", info.sha1);
|
||||||
if (info.code) {
|
if (info.code) {
|
||||||
failures.push(url);
|
failures.push(url);
|
||||||
@@ -55,15 +54,21 @@ urls.forEach(function(url) {
|
|||||||
results[url] = {
|
results[url] = {
|
||||||
input: 0,
|
input: 0,
|
||||||
output: 0,
|
output: 0,
|
||||||
|
gzip: 0,
|
||||||
log: ""
|
log: ""
|
||||||
};
|
};
|
||||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
fetch(url, function(err, res) {
|
||||||
|
if (err) throw err;
|
||||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||||
res.on("data", function(data) {
|
res.on("data", function(data) {
|
||||||
results[url].input += data.length;
|
results[url].input += data.length;
|
||||||
}).pipe(uglifyjs.stdin);
|
}).pipe(uglifyjs.stdin);
|
||||||
uglifyjs.stdout.on("data", function(data) {
|
uglifyjs.stdout.on("data", function(data) {
|
||||||
results[url].output += data.length;
|
results[url].output += data.length;
|
||||||
|
}).pipe(zlib.createGzip({
|
||||||
|
level: zlib.Z_BEST_COMPRESSION
|
||||||
|
})).on("data", function(data) {
|
||||||
|
results[url].gzip += data.length;
|
||||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||||
results[url].sha1 = data.toString("hex");
|
results[url].sha1 = data.toString("hex");
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -128,50 +128,114 @@ constant_join_3: {
|
|||||||
|
|
||||||
for_loop: {
|
for_loop: {
|
||||||
options = {
|
options = {
|
||||||
unsafe : true,
|
evaluate: true,
|
||||||
unused : true,
|
reduce_funcs: true,
|
||||||
evaluate : true,
|
reduce_vars: true,
|
||||||
reduce_vars : true
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
function f0() {
|
function f0() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++) {
|
var b = 0;
|
||||||
console.log(a[i]);
|
for (var i = 0; i < a.length; i++)
|
||||||
}
|
b += a[i];
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0, len = a.length; i < len; i++) {
|
var b = 0;
|
||||||
console.log(a[i]);
|
for (var i = 0, len = a.length; i < len; i++)
|
||||||
}
|
b += a[i];
|
||||||
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < a.length; i++) {
|
|
||||||
a[i]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f0() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
console.log(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f1() {
|
|
||||||
var a = [1, 2, 3];
|
|
||||||
for (var i = 0; i < 3; i++)
|
|
||||||
console.log(a[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++)
|
for (var i = 0; i < a.length; i++)
|
||||||
a[i]++;
|
a[i]++;
|
||||||
|
return a[2];
|
||||||
}
|
}
|
||||||
|
console.log(f0(), f1(), f2());
|
||||||
}
|
}
|
||||||
|
expect: {
|
||||||
|
function f0() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = 0;
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
b += a[i];
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function f1() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
var b = 0;
|
||||||
|
for (var i = 0; i < 3; i++)
|
||||||
|
b += a[i];
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
var a = [1, 2, 3];
|
||||||
|
for (var i = 0; i < a.length; i++)
|
||||||
|
a[i]++;
|
||||||
|
return a[2];
|
||||||
|
}
|
||||||
|
console.log(f0(), f1(), f2());
|
||||||
|
}
|
||||||
|
expect_stdout: "6 6 4"
|
||||||
|
}
|
||||||
|
|
||||||
|
index: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a[0], a[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
length: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a.length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
index_length: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [ 1, 2 ];
|
||||||
|
console.log(a[0], a.length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ascii_only_false: {
|
ascii_only_false: {
|
||||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\08\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ asm_mixed: {
|
|||||||
hoist_vars : true,
|
hoist_vars : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
side_effects : true,
|
side_effects : true,
|
||||||
negate_iife : true
|
negate_iife : true
|
||||||
};
|
};
|
||||||
@@ -104,3 +103,65 @@ asm_mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
asm_toplevel: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
(function(){
|
||||||
|
0.0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_function_expression: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
var a = function() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
function f() {
|
||||||
|
0.0;
|
||||||
|
return function(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
||||||
|
}
|
||||||
|
|
||||||
|
asm_nested_functions: {
|
||||||
|
options = {}
|
||||||
|
input: {
|
||||||
|
0.0;
|
||||||
|
function a() {
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function b() {
|
||||||
|
0.0;
|
||||||
|
function c(){
|
||||||
|
"use asm";
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
function d(){
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
0.0;
|
||||||
|
}
|
||||||
|
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -73,4 +73,42 @@ dont_change_in_or_instanceof_expressions: {
|
|||||||
1 instanceof 1;
|
1 instanceof 1;
|
||||||
null instanceof null;
|
null instanceof null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self_comparison_1: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a === a;
|
||||||
|
a !== b;
|
||||||
|
b.c === a.c;
|
||||||
|
b.c !== b.c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a == a;
|
||||||
|
a !== b;
|
||||||
|
b.c === a.c;
|
||||||
|
b.c != b.c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_2: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
var o = {};
|
||||||
|
console.log(f != f, o === o);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
var o = {};
|
||||||
|
console.log(false, true);
|
||||||
|
}
|
||||||
|
expect_stdout: "false true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ concat_1: {
|
|||||||
var c = 1 + x() + 2 + "boo";
|
var c = 1 + x() + 2 + "boo";
|
||||||
var d = 1 + x() + 2 + 3 + "boo";
|
var d = 1 + x() + 2 + 3 + "boo";
|
||||||
var e = 1 + x() + 2 + "X3boo";
|
var e = 1 + x() + 2 + "X3boo";
|
||||||
var f = "\x00360\08\0";
|
var f = "\x00360\x008\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,22 +166,24 @@ cond_1: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var do_something; // if undeclared it's assumed to have side-effects
|
function foo(do_something, some_condition) {
|
||||||
if (some_condition()) {
|
if (some_condition) {
|
||||||
do_something(x);
|
do_something(x);
|
||||||
} else {
|
} else {
|
||||||
do_something(y);
|
do_something(y);
|
||||||
}
|
}
|
||||||
if (some_condition()) {
|
if (some_condition) {
|
||||||
side_effects(x);
|
side_effects(x);
|
||||||
} else {
|
} else {
|
||||||
side_effects(y);
|
side_effects(y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var do_something;
|
function foo(do_something, some_condition) {
|
||||||
do_something(some_condition() ? x : y);
|
do_something(some_condition ? x : y);
|
||||||
some_condition() ? side_effects(x) : side_effects(y);
|
some_condition ? side_effects(x) : side_effects(y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,16 +192,18 @@ cond_2: {
|
|||||||
conditionals: true
|
conditionals: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var x, FooBar;
|
function foo(x, FooBar, some_condition) {
|
||||||
if (some_condition()) {
|
if (some_condition) {
|
||||||
x = new FooBar(1);
|
x = new FooBar(1);
|
||||||
} else {
|
} else {
|
||||||
x = new FooBar(2);
|
x = new FooBar(2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x, FooBar;
|
function foo(x, FooBar, some_condition) {
|
||||||
x = new FooBar(some_condition() ? 1 : 2);
|
x = new FooBar(some_condition ? 1 : 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,11 +609,47 @@ cond_8c: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_9: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x, y) {
|
||||||
|
g() ? x(1) : x(2);
|
||||||
|
x ? (y || x)() : (y || x)();
|
||||||
|
x ? y(a, b) : y(d, b, c);
|
||||||
|
x ? y(a, b, c) : y(a, b, c);
|
||||||
|
x ? y(a, b, c) : y(a, b, f);
|
||||||
|
x ? y(a, b, c) : y(a, e, c);
|
||||||
|
x ? y(a, b, c) : y(a, e, f);
|
||||||
|
x ? y(a, b, c) : y(d, b, c);
|
||||||
|
x ? y(a, b, c) : y(d, b, f);
|
||||||
|
x ? y(a, b, c) : y(d, e, c);
|
||||||
|
x ? y(a, b, c) : y(d, e, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x, y) {
|
||||||
|
g() ? x(1) : x(2);
|
||||||
|
x, (y || x)();
|
||||||
|
x ? y(a, b) : y(d, b, c);
|
||||||
|
x, y(a, b, c);
|
||||||
|
y(a, b, x ? c : f);
|
||||||
|
y(a, x ? b : e, c);
|
||||||
|
x ? y(a, b, c) : y(a, e, f);
|
||||||
|
y(x ? a : d, b, c);
|
||||||
|
x ? y(a, b, c) : y(d, b, f);
|
||||||
|
x ? y(a, b, c) : y(d, e, c);
|
||||||
|
x ? y(a, b, c) : y(d, e, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ternary_boolean_consequent: {
|
ternary_boolean_consequent: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() { return a == b ? true : x; }
|
function f1() { return a == b ? true : x; }
|
||||||
@@ -637,7 +677,7 @@ ternary_boolean_alternative: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() { return a == b ? x : true; }
|
function f1() { return a == b ? x : true; }
|
||||||
@@ -1015,3 +1055,215 @@ delete_conditional_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2535_1: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (true || x()) y();
|
||||||
|
if (true && x()) y();
|
||||||
|
if (x() || true) y();
|
||||||
|
if (x() && true) y();
|
||||||
|
if (false || x()) y();
|
||||||
|
if (false && x()) y();
|
||||||
|
if (x() || false) y();
|
||||||
|
if (x() && false) y();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
x() && y();
|
||||||
|
(x(), 1) && y();
|
||||||
|
x() && y();
|
||||||
|
x() && y();
|
||||||
|
x() && y();
|
||||||
|
(x(), 0) && y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2535_2: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {}
|
||||||
|
function y() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
console.log((x() || true) || y());
|
||||||
|
console.log((y() || true) || x());
|
||||||
|
console.log((x() || true) && y());
|
||||||
|
console.log((y() || true) && x());
|
||||||
|
console.log((x() && true) || y());
|
||||||
|
console.log((y() && true) || x());
|
||||||
|
console.log((x() && true) && y());
|
||||||
|
console.log((y() && true) && x());
|
||||||
|
console.log((x() || false) || y());
|
||||||
|
console.log((y() || false) || x());
|
||||||
|
console.log((x() || false) && y());
|
||||||
|
console.log((y() || false) && x());
|
||||||
|
console.log((x() && false) || y());
|
||||||
|
console.log((y() && false) || x());
|
||||||
|
console.log((x() && false) && y());
|
||||||
|
console.log((y() && false) && x());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {}
|
||||||
|
function y() {
|
||||||
|
return "foo";
|
||||||
|
}
|
||||||
|
console.log(x() || !0);
|
||||||
|
console.log(y() || !0);
|
||||||
|
console.log((x(), y()));
|
||||||
|
console.log((y(), x()));
|
||||||
|
console.log(!!x() || y());
|
||||||
|
console.log(!!y() || x());
|
||||||
|
console.log(x() && y());
|
||||||
|
console.log(y() && x());
|
||||||
|
console.log(x() || y());
|
||||||
|
console.log(y() || x());
|
||||||
|
console.log(!!x() && y());
|
||||||
|
console.log(!!y() && x());
|
||||||
|
console.log((x(), y()));
|
||||||
|
console.log((y(), x()));
|
||||||
|
console.log(x() && !1);
|
||||||
|
console.log(y() && !1);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
"undefined",
|
||||||
|
"foo",
|
||||||
|
"true",
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
"false",
|
||||||
|
"undefined",
|
||||||
|
"foo",
|
||||||
|
"undefined",
|
||||||
|
"undefined",
|
||||||
|
"false",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2560: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function log(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
function foo() {
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
function bar() {
|
||||||
|
if (x !== (x = foo())) {
|
||||||
|
x(1);
|
||||||
|
} else {
|
||||||
|
x(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var x = function() {
|
||||||
|
console.log("init");
|
||||||
|
};
|
||||||
|
bar();
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function log(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
function bar() {
|
||||||
|
x !== (x = log) ? x(1) : x(2);
|
||||||
|
}
|
||||||
|
var x = function() {
|
||||||
|
console.log("init");
|
||||||
|
};
|
||||||
|
bar();
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (x()) {
|
||||||
|
var a;
|
||||||
|
y();
|
||||||
|
} else {
|
||||||
|
z();
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b;
|
||||||
|
x() ? y() : z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
to_and_or: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x ? y || z : z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [
|
||||||
|
0,
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
"foo",
|
||||||
|
false,
|
||||||
|
-1 / 0,
|
||||||
|
void 0,
|
||||||
|
];
|
||||||
|
values.forEach(function(x) {
|
||||||
|
values.forEach(function(y) {
|
||||||
|
values.forEach(function(z) {
|
||||||
|
console.log(x && y || z);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,166 +0,0 @@
|
|||||||
issue_1191: {
|
|
||||||
options = {
|
|
||||||
evaluate : true,
|
|
||||||
booleans : true,
|
|
||||||
comparisons : true,
|
|
||||||
dead_code : true,
|
|
||||||
conditionals : true,
|
|
||||||
side_effects : true,
|
|
||||||
unused : true,
|
|
||||||
hoist_funs : true,
|
|
||||||
if_return : true,
|
|
||||||
join_vars : true,
|
|
||||||
sequences : false,
|
|
||||||
collapse_vars : false,
|
|
||||||
reduce_vars : true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo(rot) {
|
|
||||||
const rotTol = 5;
|
|
||||||
if (rot < -rotTol || rot > rotTol)
|
|
||||||
bar();
|
|
||||||
baz();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo(rot) {
|
|
||||||
(rot < -5 || rot > 5) && bar();
|
|
||||||
baz();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1194: {
|
|
||||||
options = {
|
|
||||||
evaluate : true,
|
|
||||||
booleans : true,
|
|
||||||
comparisons : true,
|
|
||||||
dead_code : true,
|
|
||||||
conditionals : true,
|
|
||||||
side_effects : true,
|
|
||||||
unused : true,
|
|
||||||
hoist_funs : true,
|
|
||||||
if_return : true,
|
|
||||||
join_vars : true,
|
|
||||||
sequences : false,
|
|
||||||
collapse_vars : false,
|
|
||||||
reduce_vars : true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f1() {const a = "X"; return a + a;}
|
|
||||||
function f2() {const aa = "X"; return aa + aa;}
|
|
||||||
function f3() {const aaa = "X"; return aaa + aaa;}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f1(){return"XX"}
|
|
||||||
function f2(){return"XX"}
|
|
||||||
function f3(){return"XX"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1396: {
|
|
||||||
options = {
|
|
||||||
evaluate : true,
|
|
||||||
booleans : true,
|
|
||||||
comparisons : true,
|
|
||||||
dead_code : true,
|
|
||||||
conditionals : true,
|
|
||||||
side_effects : true,
|
|
||||||
unused : true,
|
|
||||||
hoist_funs : true,
|
|
||||||
if_return : true,
|
|
||||||
join_vars : true,
|
|
||||||
sequences : false,
|
|
||||||
collapse_vars : false,
|
|
||||||
reduce_vars : true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo(a) {
|
|
||||||
const VALUE = 1;
|
|
||||||
console.log(2 | VALUE);
|
|
||||||
console.log(VALUE + 1);
|
|
||||||
console.log(VALUE);
|
|
||||||
console.log(a & VALUE);
|
|
||||||
}
|
|
||||||
function bar() {
|
|
||||||
const s = "01234567890123456789";
|
|
||||||
console.log(s + s + s + s + s);
|
|
||||||
|
|
||||||
const CONSTANT = "abc";
|
|
||||||
console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo(a) {
|
|
||||||
console.log(3);
|
|
||||||
console.log(2);
|
|
||||||
console.log(1);
|
|
||||||
console.log(1 & a);
|
|
||||||
}
|
|
||||||
function bar() {
|
|
||||||
const s = "01234567890123456789";
|
|
||||||
console.log(s + s + s + s + s);
|
|
||||||
|
|
||||||
console.log("abcabcabcabcabc");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unused_regexp_literal: {
|
|
||||||
options = {
|
|
||||||
evaluate : true,
|
|
||||||
booleans : true,
|
|
||||||
comparisons : true,
|
|
||||||
dead_code : true,
|
|
||||||
conditionals : true,
|
|
||||||
side_effects : true,
|
|
||||||
unused : true,
|
|
||||||
hoist_funs : true,
|
|
||||||
if_return : true,
|
|
||||||
join_vars : true,
|
|
||||||
sequences : false,
|
|
||||||
collapse_vars : false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f(){ var a = /b/; }
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f(){}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
regexp_literal_not_const: {
|
|
||||||
options = {
|
|
||||||
evaluate : true,
|
|
||||||
booleans : true,
|
|
||||||
comparisons : true,
|
|
||||||
dead_code : true,
|
|
||||||
conditionals : true,
|
|
||||||
side_effects : true,
|
|
||||||
unused : true,
|
|
||||||
hoist_funs : true,
|
|
||||||
if_return : true,
|
|
||||||
join_vars : true,
|
|
||||||
sequences : false,
|
|
||||||
collapse_vars : false,
|
|
||||||
reduce_vars : true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function(){
|
|
||||||
var result;
|
|
||||||
const s = 'acdabcdeabbb';
|
|
||||||
const REGEXP_LITERAL = /ab*/g;
|
|
||||||
while (result = REGEXP_LITERAL.exec(s)) {
|
|
||||||
console.log(result[0]);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function() {
|
|
||||||
var result;
|
|
||||||
const REGEXP_LITERAL = /ab*/g;
|
|
||||||
while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
@@ -31,7 +31,7 @@ dead_code_2_should_warn: {
|
|||||||
function f() {
|
function f() {
|
||||||
g();
|
g();
|
||||||
x = 10;
|
x = 10;
|
||||||
throw "foo";
|
throw new Error("foo");
|
||||||
// completely discarding the `if` would introduce some
|
// completely discarding the `if` would introduce some
|
||||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||||
// we copy any declarations to the upper scope.
|
// we copy any declarations to the upper scope.
|
||||||
@@ -46,16 +46,20 @@ dead_code_2_should_warn: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
f();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
g();
|
g();
|
||||||
x = 10;
|
x = 10;
|
||||||
throw "foo";
|
throw new Error("foo");
|
||||||
var x;
|
var x;
|
||||||
function g(){};
|
function g(){};
|
||||||
}
|
}
|
||||||
|
f();
|
||||||
}
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: "<=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more: {
|
dead_code_constant_boolean_should_warn_more: {
|
||||||
@@ -78,141 +82,19 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
foo();
|
foo();
|
||||||
var moo;
|
var moo;
|
||||||
}
|
}
|
||||||
|
bar();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var foo;
|
var foo;
|
||||||
function bar() {}
|
function bar() {}
|
||||||
// nothing for the while
|
// nothing for the while
|
||||||
// as for the for, it should keep:
|
// as for the for, it should keep:
|
||||||
|
var moo;
|
||||||
var x = 10, y;
|
var x = 10, y;
|
||||||
var moo;
|
bar();
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_const_declaration: {
|
|
||||||
options = {
|
|
||||||
dead_code : true,
|
|
||||||
loops : true,
|
|
||||||
booleans : true,
|
|
||||||
conditionals : true,
|
|
||||||
evaluate : true,
|
|
||||||
reduce_vars : true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
var unused;
|
|
||||||
const CONST_FOO = false;
|
|
||||||
if (CONST_FOO) {
|
|
||||||
console.log("unreachable");
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var unused;
|
|
||||||
const CONST_FOO = !1;
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_const_annotation: {
|
|
||||||
options = {
|
|
||||||
dead_code : true,
|
|
||||||
loops : true,
|
|
||||||
booleans : true,
|
|
||||||
conditionals : true,
|
|
||||||
evaluate : true,
|
|
||||||
reduce_vars : true,
|
|
||||||
toplevel : true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
var unused;
|
|
||||||
/** @const */ var CONST_FOO_ANN = false;
|
|
||||||
if (CONST_FOO_ANN) {
|
|
||||||
console.log("unreachable");
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var unused;
|
|
||||||
var CONST_FOO_ANN = !1;
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_const_annotation_regex: {
|
|
||||||
options = {
|
|
||||||
dead_code : true,
|
|
||||||
loops : true,
|
|
||||||
booleans : true,
|
|
||||||
conditionals : true,
|
|
||||||
evaluate : true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
var unused;
|
|
||||||
// @constraint this shouldn't be a constant
|
|
||||||
var CONST_FOO_ANN = false;
|
|
||||||
if (CONST_FOO_ANN) {
|
|
||||||
console.log("reachable");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var unused;
|
|
||||||
var CONST_FOO_ANN = !1;
|
|
||||||
CONST_FOO_ANN && console.log('reachable');
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_const_annotation_complex_scope: {
|
|
||||||
options = {
|
|
||||||
dead_code : true,
|
|
||||||
loops : true,
|
|
||||||
booleans : true,
|
|
||||||
conditionals : true,
|
|
||||||
evaluate : true,
|
|
||||||
reduce_vars : true,
|
|
||||||
toplevel : true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
var unused_var;
|
|
||||||
/** @const */ var test = 'test';
|
|
||||||
// @const
|
|
||||||
var CONST_FOO_ANN = false;
|
|
||||||
var unused_var_2;
|
|
||||||
if (CONST_FOO_ANN) {
|
|
||||||
console.log("unreachable");
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
}
|
|
||||||
if (test === 'test') {
|
|
||||||
var beef = 'good';
|
|
||||||
/** @const */ var meat = 'beef';
|
|
||||||
var pork = 'bad';
|
|
||||||
if (meat === 'pork') {
|
|
||||||
console.log('also unreachable');
|
|
||||||
} else if (pork === 'good') {
|
|
||||||
console.log('reached, not const');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var unused_var;
|
|
||||||
var test = 'test';
|
|
||||||
var CONST_FOO_ANN = !1;
|
|
||||||
var unused_var_2;
|
|
||||||
var moo;
|
|
||||||
function bar() {}
|
|
||||||
var beef = 'good';
|
|
||||||
var meat = 'beef';
|
|
||||||
var pork = 'bad';
|
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
node_version: "<=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
try_catch_finally: {
|
try_catch_finally: {
|
||||||
@@ -220,6 +102,8 @@ try_catch_finally: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
@@ -256,3 +140,725 @@ try_catch_finally: {
|
|||||||
"1",
|
"1",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessor: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
get a() {},
|
||||||
|
set a(v){
|
||||||
|
this.b = 2;
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2233_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Array.isArray;
|
||||||
|
Boolean;
|
||||||
|
console.log;
|
||||||
|
Date;
|
||||||
|
decodeURI;
|
||||||
|
decodeURIComponent;
|
||||||
|
encodeURI;
|
||||||
|
encodeURIComponent;
|
||||||
|
Error.name;
|
||||||
|
escape;
|
||||||
|
eval;
|
||||||
|
EvalError;
|
||||||
|
Function.length;
|
||||||
|
isFinite;
|
||||||
|
isNaN;
|
||||||
|
JSON;
|
||||||
|
Math.random;
|
||||||
|
Number.isNaN;
|
||||||
|
parseFloat;
|
||||||
|
parseInt;
|
||||||
|
RegExp;
|
||||||
|
Object.defineProperty;
|
||||||
|
String.fromCharCode;
|
||||||
|
RangeError;
|
||||||
|
ReferenceError;
|
||||||
|
SyntaxError;
|
||||||
|
TypeError;
|
||||||
|
unescape;
|
||||||
|
URIError;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
global_timeout_and_interval_symbols: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
// These global symbols do not exist in the test sandbox
|
||||||
|
// and must be tested separately.
|
||||||
|
clearInterval;
|
||||||
|
clearTimeout;
|
||||||
|
setInterval;
|
||||||
|
setTimeout;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2233_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var RegExp;
|
||||||
|
Array.isArray;
|
||||||
|
RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Math.sin;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2233_3: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var RegExp;
|
||||||
|
Array.isArray;
|
||||||
|
RegExp;
|
||||||
|
UndeclaredGlobal;
|
||||||
|
function foo() {
|
||||||
|
var Number;
|
||||||
|
AnotherUndeclaredGlobal;
|
||||||
|
Math.sin;
|
||||||
|
Number.isNaN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
UndeclaredGlobal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
global_fns: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Boolean(1, 2);
|
||||||
|
decodeURI(1, 2);
|
||||||
|
decodeURIComponent(1, 2);
|
||||||
|
Date(1, 2);
|
||||||
|
encodeURI(1, 2);
|
||||||
|
encodeURIComponent(1, 2);
|
||||||
|
Error(1, 2);
|
||||||
|
escape(1, 2);
|
||||||
|
EvalError(1, 2);
|
||||||
|
isFinite(1, 2);
|
||||||
|
isNaN(1, 2);
|
||||||
|
Number(1, 2);
|
||||||
|
Object(1, 2);
|
||||||
|
parseFloat(1, 2);
|
||||||
|
parseInt(1, 2);
|
||||||
|
RangeError(1, 2);
|
||||||
|
ReferenceError(1, 2);
|
||||||
|
String(1, 2);
|
||||||
|
SyntaxError(1, 2);
|
||||||
|
TypeError(1, 2);
|
||||||
|
unescape(1, 2);
|
||||||
|
URIError(1, 2);
|
||||||
|
try {
|
||||||
|
Function(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RegExp(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
Function(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
RegExp(1, 2);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Array(NaN);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"SyntaxError",
|
||||||
|
"SyntaxError",
|
||||||
|
"RangeError",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_assignment: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
|
passes: 2,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f0(c) {
|
||||||
|
var a = 3 / c;
|
||||||
|
return a = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0(c) {
|
||||||
|
return 3 / c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_lvalues_drop_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f0(x) { var i = ++x; return x += i; }
|
||||||
|
function f1(x) { var a = (x -= 3); return x += a; }
|
||||||
|
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0(x) { var i = ++x; return x + i; }
|
||||||
|
function f1(x) { var a = (x -= 3); return x + a; }
|
||||||
|
function f2(x) { var z = x, a = ++z; return z + a; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_misc1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f10(x) { var a = 5, b = 3; return a += b; }
|
||||||
|
function f11(x) { var a = 5, b = 3; return a += --b; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f10(x) { return 5 + 3; }
|
||||||
|
function f11(x) { var b = 3; return 5 + --b; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return_assignment: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(a, b, c) {
|
||||||
|
return a = x(), b = y(), b = a && (c >>= 5);
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
return e = x();
|
||||||
|
}
|
||||||
|
function f3(e) {
|
||||||
|
return e = x();
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
var e;
|
||||||
|
return e = x();
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
try {
|
||||||
|
return a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
try {
|
||||||
|
return a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function y() {
|
||||||
|
console.log("y");
|
||||||
|
}
|
||||||
|
function test(inc) {
|
||||||
|
var counter = 0;
|
||||||
|
x = function() {
|
||||||
|
counter += inc;
|
||||||
|
if (inc < 0) throw counter;
|
||||||
|
return counter;
|
||||||
|
};
|
||||||
|
[ f1, f2, f3, f4, f5, f6 ].forEach(function(f, i) {
|
||||||
|
e = null;
|
||||||
|
try {
|
||||||
|
i += 1;
|
||||||
|
console.log("result " + f(10 * i, 100 * i, 1000 * i));
|
||||||
|
} catch (x) {
|
||||||
|
console.log("caught " + x);
|
||||||
|
}
|
||||||
|
if (null !== e) console.log("e: " + e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var x, e;
|
||||||
|
test(1);
|
||||||
|
test(-1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(a, b, c) {
|
||||||
|
return a = x(), y(), a && (c >> 5);
|
||||||
|
}
|
||||||
|
function f2() {
|
||||||
|
return e = x();
|
||||||
|
}
|
||||||
|
function f3(e) {
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
return x();
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
try {
|
||||||
|
return x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6(a) {
|
||||||
|
try {
|
||||||
|
return a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function y() {
|
||||||
|
console.log("y");
|
||||||
|
}
|
||||||
|
function test(inc) {
|
||||||
|
var counter = 0;
|
||||||
|
x = function() {
|
||||||
|
counter += inc;
|
||||||
|
if (inc < 0) throw counter;
|
||||||
|
return counter;
|
||||||
|
};
|
||||||
|
[ f1, f2, f3, f4, f5, f6 ].forEach(function(f, i) {
|
||||||
|
e = null;
|
||||||
|
try {
|
||||||
|
i += 1;
|
||||||
|
console.log("result " + f(10 * i, 100 * i, 1000 * i));
|
||||||
|
} catch (x) {
|
||||||
|
console.log("caught " + x);
|
||||||
|
}
|
||||||
|
if (null !== e) console.log("e: " + e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var x, e;
|
||||||
|
test(1);
|
||||||
|
test(-1);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"y",
|
||||||
|
"result 31",
|
||||||
|
"result 2",
|
||||||
|
"e: 2",
|
||||||
|
"result 3",
|
||||||
|
"result 4",
|
||||||
|
"result 5",
|
||||||
|
"6",
|
||||||
|
"result 6",
|
||||||
|
"caught -1",
|
||||||
|
"caught -2",
|
||||||
|
"caught -3",
|
||||||
|
"caught -4",
|
||||||
|
"50",
|
||||||
|
"result undefined",
|
||||||
|
"60",
|
||||||
|
"caught -6",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
throw_assignment: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {
|
||||||
|
throw a = x();
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
throw a = x();
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
var a;
|
||||||
|
throw a = x();
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6() {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f7() {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f8(a) {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f9() {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function test(inc) {
|
||||||
|
var counter = 0;
|
||||||
|
x = function() {
|
||||||
|
counter += inc;
|
||||||
|
if (inc < 0) throw counter;
|
||||||
|
return counter;
|
||||||
|
};
|
||||||
|
[ f1, f2, f3, f4, f5, f6, f7, f8, f9 ].forEach(function(f, i) {
|
||||||
|
a = null;
|
||||||
|
try {
|
||||||
|
f(10 * (1 + i));
|
||||||
|
} catch (x) {
|
||||||
|
console.log("caught " + x);
|
||||||
|
}
|
||||||
|
if (null !== a) console.log("a: " + a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var x, a;
|
||||||
|
test(1);
|
||||||
|
test(-1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1() {
|
||||||
|
throw a = x();
|
||||||
|
}
|
||||||
|
function f2(a) {
|
||||||
|
throw x();
|
||||||
|
}
|
||||||
|
function f3() {
|
||||||
|
throw x();
|
||||||
|
}
|
||||||
|
function f4() {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f5(a) {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f6() {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} catch (b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f7() {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f8(a) {
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function f9() {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
throw a = x();
|
||||||
|
} finally {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function test(inc) {
|
||||||
|
var counter = 0;
|
||||||
|
x = function() {
|
||||||
|
counter += inc;
|
||||||
|
if (inc < 0) throw counter;
|
||||||
|
return counter;
|
||||||
|
};
|
||||||
|
[ f1, f2, f3, f4, f5, f6, f7, f8, f9 ].forEach(function(f, i) {
|
||||||
|
a = null;
|
||||||
|
try {
|
||||||
|
f(10 * (1 + i));
|
||||||
|
} catch (x) {
|
||||||
|
console.log("caught " + x);
|
||||||
|
}
|
||||||
|
if (null !== a) console.log("a: " + a);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
var x, a;
|
||||||
|
test(1);
|
||||||
|
test(-1);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"caught 1",
|
||||||
|
"a: 1",
|
||||||
|
"caught 2",
|
||||||
|
"caught 3",
|
||||||
|
"4",
|
||||||
|
"a: 4",
|
||||||
|
"5",
|
||||||
|
"6",
|
||||||
|
"7",
|
||||||
|
"caught 7",
|
||||||
|
"a: 7",
|
||||||
|
"8",
|
||||||
|
"caught 8",
|
||||||
|
"9",
|
||||||
|
"caught 9",
|
||||||
|
"caught -1",
|
||||||
|
"caught -2",
|
||||||
|
"caught -3",
|
||||||
|
"null",
|
||||||
|
"50",
|
||||||
|
"undefined",
|
||||||
|
"null",
|
||||||
|
"caught -7",
|
||||||
|
"80",
|
||||||
|
"caught -8",
|
||||||
|
"undefined",
|
||||||
|
"caught -9",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2597: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(b) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return b = true;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
b && (a = "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var a = "FAIL";
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(b) {
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
throw "foo";
|
||||||
|
} catch (e) {
|
||||||
|
return b = true;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
b && (a = "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var a = "FAIL";
|
||||||
|
f();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2666: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = {
|
||||||
|
p: function() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log(typeof f().p());
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2692: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
reduce_vars: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = g;
|
||||||
|
function g() {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2701: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return a = function() {
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
console.log(typeof f()());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2749: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
(function() {
|
||||||
|
return b ? c = "FAIL" : b = 1;
|
||||||
|
try {
|
||||||
|
} catch (b) {
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2, c = "PASS";
|
||||||
|
while (a--)
|
||||||
|
b = void 0, b ? c = "FAIL" : b = 1;
|
||||||
|
var b;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
|||||||
and: {
|
and: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -76,7 +77,8 @@ and: {
|
|||||||
|
|
||||||
or: {
|
or: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -158,7 +160,8 @@ or: {
|
|||||||
|
|
||||||
unary_prefix: {
|
unary_prefix: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
a = !0 && b;
|
a = !0 && b;
|
||||||
@@ -250,22 +253,27 @@ unsafe_constant: {
|
|||||||
|
|
||||||
unsafe_object: {
|
unsafe_object: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:1}) + 1,
|
o + 1,
|
||||||
({a:1}).a + 1,
|
o.a + 1,
|
||||||
({a:1}).b + 1,
|
o.b + 1,
|
||||||
({a:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:1}) + 1,
|
o + 1,
|
||||||
2,
|
2,
|
||||||
({a:1}).b + 1,
|
o.b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -274,22 +282,27 @@ unsafe_object: {
|
|||||||
|
|
||||||
unsafe_object_nested: {
|
unsafe_object_nested: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 } };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1}}) + 1,
|
o + 1,
|
||||||
({a:{b:1}}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1}}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1}}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 } };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1}}) + 1,
|
o + 1,
|
||||||
({a:{b:1}}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1}}).b + 1,
|
o.b + 1,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -298,21 +311,26 @@ unsafe_object_nested: {
|
|||||||
|
|
||||||
unsafe_object_complex: {
|
unsafe_object_complex: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 }, b: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},b:1}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1},b:1}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1},b:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 }, b: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},b:1}).a + 1,
|
o.a + 1,
|
||||||
2,
|
2,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
@@ -322,22 +340,27 @@ unsafe_object_complex: {
|
|||||||
|
|
||||||
unsafe_object_repeated: {
|
unsafe_object_repeated: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
var o = { a: { b: 1 }, a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},a:1}) + 1,
|
o + 1,
|
||||||
({a:{b:1},a:1}).a + 1,
|
o.a + 1,
|
||||||
({a:{b:1},a:1}).b + 1,
|
o.b + 1,
|
||||||
({a:{b:1},a:1}).a.b + 1
|
o.a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
var o = { a: { b: 1 }, a: 1 };
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},a:1}) + 1,
|
o + 1,
|
||||||
2,
|
2,
|
||||||
({a:{b:1},a:1}).b + 1,
|
o.b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -347,6 +370,7 @@ unsafe_object_repeated: {
|
|||||||
unsafe_object_accessor: {
|
unsafe_object_accessor: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
@@ -370,10 +394,11 @@ unsafe_object_accessor: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_function: {
|
prop_function: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -386,9 +411,9 @@ unsafe_function: {
|
|||||||
expect: {
|
expect: {
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:function(){}}) + 1,
|
({a:{b:1},b:function(){}}) + 1,
|
||||||
({a:{b:1},b:function(){}}).a + 1,
|
({b:1}) + 1,
|
||||||
({a:{b:1},b:function(){}}).b + 1,
|
function(){} + 1,
|
||||||
({a:{b:1},b:function(){}}).a.b + 1
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -614,10 +639,11 @@ unsafe_string_bad_index: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_prototype_function: {
|
prototype_function: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate: true,
|
||||||
unsafe : true
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = ({valueOf: 0}) < 1;
|
var a = ({valueOf: 0}) < 1;
|
||||||
@@ -636,25 +662,28 @@ unsafe_prototype_function: {
|
|||||||
var d = ({toString: 0}) + "";
|
var d = ({toString: 0}) + "";
|
||||||
var e = (({valueOf: 0}) + "")[2];
|
var e = (({valueOf: 0}) + "")[2];
|
||||||
var f = (({toString: 0}) + "")[2];
|
var f = (({toString: 0}) + "")[2];
|
||||||
var g = ({valueOf: 0}).valueOf();
|
var g = 0();
|
||||||
var h = "" + ({toString: 0});
|
var h = 0();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
call_args: {
|
call_args: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
const a = 1;
|
var a = 1;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
+function(a) {
|
+function(a) {
|
||||||
return a;
|
return a;
|
||||||
}(a);
|
}(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
const a = 1;
|
var a = 1;
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+(1, 1);
|
+(1, 1);
|
||||||
}
|
}
|
||||||
@@ -664,19 +693,21 @@ call_args: {
|
|||||||
call_args_drop_param: {
|
call_args_drop_param: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
const a = 1;
|
var a = 1;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
+function(a) {
|
+function(a) {
|
||||||
return a;
|
return a;
|
||||||
}(a, b);
|
}(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
const a = 1;
|
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+(b, 1);
|
+(b, 1);
|
||||||
}
|
}
|
||||||
@@ -779,13 +810,15 @@ unsafe_charAt_noop: {
|
|||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
s.charAt(0),
|
s.charAt(0),
|
||||||
"string".charAt(x)
|
"string".charAt(x),
|
||||||
|
(typeof x).charAt()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(
|
console.log(
|
||||||
s.charAt(0),
|
s.charAt(0),
|
||||||
"string".charAt(x)
|
"string".charAt(x),
|
||||||
|
(typeof x)[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -989,3 +1022,321 @@ Infinity_NaN_undefined_LHS: {
|
|||||||
"}",
|
"}",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1964_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe_regexp: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var long_variable_name = /\s/;
|
||||||
|
console.log(long_variable_name.source);
|
||||||
|
return "a b c".split(long_variable_name)[1];
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var long_variable_name = /\s/;
|
||||||
|
console.log(long_variable_name.source);
|
||||||
|
return "a b c".split(long_variable_name)[1];
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"\\s",
|
||||||
|
"b",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1964_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe_regexp: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var long_variable_name = /\s/;
|
||||||
|
console.log(long_variable_name.source);
|
||||||
|
return "a b c".split(long_variable_name)[1];
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log(/\s/.source);
|
||||||
|
return "a b c".split(/\s/)[1];
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"\\s",
|
||||||
|
"b",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
array_slice_index: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log([1,2,3].slice(1)[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
string_charCodeAt: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("foo".charCodeAt("bar".length));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(NaN);
|
||||||
|
}
|
||||||
|
expect_stdout: "NaN"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(String.fromCharCode(65));
|
||||||
|
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
||||||
|
console.log(Math.pow(Math.PI, Math.E - Math.LN10));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("A");
|
||||||
|
console.log(7);
|
||||||
|
console.log(Math.cos(1.2345));
|
||||||
|
console.log(1.2543732512566947);
|
||||||
|
console.log(1.6093984514472044);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Math.E);
|
||||||
|
console.log(Math.LN10);
|
||||||
|
console.log(Math.LN2);
|
||||||
|
console.log(Math.LOG2E);
|
||||||
|
console.log(Math.LOG10E);
|
||||||
|
console.log(Math.PI);
|
||||||
|
console.log(Math.SQRT1_2);
|
||||||
|
console.log(Math.SQRT2);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2207_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(Number.MIN_VALUE);
|
||||||
|
console.log(Number.NaN);
|
||||||
|
console.log(Number.NEGATIVE_INFINITY);
|
||||||
|
console.log(Number.POSITIVE_INFINITY);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Number.MAX_VALUE);
|
||||||
|
console.log(5e-324);
|
||||||
|
console.log(NaN);
|
||||||
|
console.log(-1/0);
|
||||||
|
console.log(1/0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2231_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object.keys(void 0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Object.keys(void 0));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2231_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object.getOwnPropertyNames(null));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Object.getOwnPropertyNames(null));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { n: NaN };
|
||||||
|
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(false, false, true, true, "number");
|
||||||
|
}
|
||||||
|
expect_stdout: "false false true true 'number'"
|
||||||
|
}
|
||||||
|
|
||||||
|
self_comparison_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { n: NaN };
|
||||||
|
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(false, false, true, true, "number");
|
||||||
|
}
|
||||||
|
expect_stdout: "false false true true 'number'"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2535_1: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ((x() || true) || y()) z();
|
||||||
|
if ((x() || true) && y()) z();
|
||||||
|
if ((x() && true) || y()) z();
|
||||||
|
if ((x() && true) && y()) z();
|
||||||
|
if ((x() || false) || y()) z();
|
||||||
|
if ((x() || false) && y()) z();
|
||||||
|
if ((x() && false) || y()) z();
|
||||||
|
if ((x() && false) && y()) z();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (x(), 1) z();
|
||||||
|
if (x(), y()) z();
|
||||||
|
if (x() || y()) z();
|
||||||
|
if (x() && y()) z();
|
||||||
|
if (x() || y()) z();
|
||||||
|
if (x() && y()) z();
|
||||||
|
if (x(), y()) z();
|
||||||
|
if (x(), 0) z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2535_2: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(x() || true) || y();
|
||||||
|
(x() || true) && y();
|
||||||
|
(x() && true) || y();
|
||||||
|
(x() && true) && y();
|
||||||
|
(x() || false) || y();
|
||||||
|
(x() || false) && y();
|
||||||
|
(x() && false) || y();
|
||||||
|
(x() && false) && y();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x(),
|
||||||
|
x(), y(),
|
||||||
|
x() || y(),
|
||||||
|
x() && y(),
|
||||||
|
x() || y(),
|
||||||
|
x() && y(),
|
||||||
|
x(), y(),
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2535_3: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(Object(1) && 1 && 2);
|
||||||
|
console.log(Object(1) && true && 1 && 2 && Object(2));
|
||||||
|
console.log(Object(1) && true && 1 && null && 2 && Object(2));
|
||||||
|
console.log(2 == Object(1) || 0 || void 0 || null);
|
||||||
|
console.log(2 == Object(1) || 0 || void 0 || null || Object(2));
|
||||||
|
console.log(2 == Object(1) || 0 || void 0 || "ok" || null || Object(2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(Object(1) && 2);
|
||||||
|
console.log(Object(1) && Object(2));
|
||||||
|
console.log(Object(1) && null);
|
||||||
|
console.log(2 == Object(1) || null);
|
||||||
|
console.log(2 == Object(1) || Object(2));
|
||||||
|
console.log(2 == Object(1) || "ok");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1316,20]",
|
||||||
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1317,20]",
|
||||||
|
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1318,20]",
|
||||||
|
"WARN: Condition left of && always false [test/compress/evaluate.js:1318,20]",
|
||||||
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1319,20]",
|
||||||
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1320,20]",
|
||||||
|
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1321,20]",
|
||||||
|
"WARN: Condition left of || always true [test/compress/evaluate.js:1321,20]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -37,6 +37,7 @@ object: {
|
|||||||
VALUE: 42,
|
VALUE: 42,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
side_effects: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -120,7 +121,7 @@ mixed: {
|
|||||||
properties: true,
|
properties: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
const FOO = { BAR: 0 };
|
var FOO = { BAR: 0 };
|
||||||
console.log(FOO.BAR);
|
console.log(FOO.BAR);
|
||||||
console.log(++CONFIG.DEBUG);
|
console.log(++CONFIG.DEBUG);
|
||||||
console.log(++CONFIG.VALUE);
|
console.log(++CONFIG.VALUE);
|
||||||
@@ -130,7 +131,7 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
const FOO = { BAR: 0 };
|
var FOO = { BAR: 0 };
|
||||||
console.log("moo");
|
console.log("moo");
|
||||||
console.log(++CONFIG.DEBUG);
|
console.log(++CONFIG.DEBUG);
|
||||||
console.log(++CONFIG.VALUE);
|
console.log(++CONFIG.VALUE);
|
||||||
@@ -140,9 +141,9 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]',
|
||||||
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]',
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,3 +161,39 @@ issue_1801: {
|
|||||||
console.log(!0);
|
console.log(!0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1986: {
|
||||||
|
options = {
|
||||||
|
global_defs: {
|
||||||
|
"@alert": "console.log",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
alert(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2167: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
global_defs: {
|
||||||
|
"@isDevMode": "function(){}",
|
||||||
|
},
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (isDevMode()) {
|
||||||
|
greetOverlord();
|
||||||
|
}
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
doWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
666
test/compress/hoist_props.js
Normal file
666
test/compress/hoist_props.js
Normal file
@@ -0,0 +1,666 @@
|
|||||||
|
issue_2377_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
foo: 1,
|
||||||
|
bar: 2,
|
||||||
|
square: function(x) {
|
||||||
|
return x * x;
|
||||||
|
},
|
||||||
|
cube: function(x) {
|
||||||
|
return x * x * x;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(obj.foo, obj.cube(3));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj_foo = 1, obj_cube = function(x) {
|
||||||
|
return x * x * x;
|
||||||
|
};
|
||||||
|
console.log(obj_foo, obj_cube(3));
|
||||||
|
}
|
||||||
|
expect_stdout: "1 27"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2377_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
foo: 1,
|
||||||
|
bar: 2,
|
||||||
|
square: function(x) {
|
||||||
|
return x * x;
|
||||||
|
},
|
||||||
|
cube: function(x) {
|
||||||
|
return x * x * x;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(obj.foo, obj.cube(3));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, (x = 3, x * x * x));
|
||||||
|
var x;
|
||||||
|
}
|
||||||
|
expect_stdout: "1 27"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2377_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
hoist_props: true,
|
||||||
|
passes: 4,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
foo: 1,
|
||||||
|
bar: 2,
|
||||||
|
square: function(x) {
|
||||||
|
return x * x;
|
||||||
|
},
|
||||||
|
cube: function(x) {
|
||||||
|
return x * x * x;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(obj.foo, obj.cube(3));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 27);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 27"
|
||||||
|
}
|
||||||
|
|
||||||
|
direct_access_1: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
var obj = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in obj) a++;
|
||||||
|
console.log(a, obj.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
var obj = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
for (var k in obj) a++;
|
||||||
|
console.log(a, obj.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
direct_access_2: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { a: 1 };
|
||||||
|
var f = function(k) {
|
||||||
|
if (o[k]) return "PASS";
|
||||||
|
};
|
||||||
|
console.log(f("a"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { a: 1 };
|
||||||
|
console.log(function(k) {
|
||||||
|
if (o[k]) return "PASS";
|
||||||
|
}("a"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
direct_access_3: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { a: 1 };
|
||||||
|
o.b;
|
||||||
|
console.log(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { a: 1 };
|
||||||
|
o.b;
|
||||||
|
console.log(o.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
bar: function() {
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(obj.bar());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
bar: function() {
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
}.bar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
name_collision_1: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj_foo = 1;
|
||||||
|
var obj_bar = 2;
|
||||||
|
function f() {
|
||||||
|
var obj = {
|
||||||
|
foo: 3,
|
||||||
|
bar: 4,
|
||||||
|
"b-r": 5,
|
||||||
|
"b+r": 6,
|
||||||
|
"b!r": 7,
|
||||||
|
};
|
||||||
|
console.log(obj_foo, obj.foo, obj.bar, obj["b-r"], obj["b+r"], obj["b!r"]);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var obj_foo = 1;
|
||||||
|
var obj_bar = 2;
|
||||||
|
function f() {
|
||||||
|
var obj_foo$0 = 3,
|
||||||
|
obj_bar = 4,
|
||||||
|
obj_b_r = 5,
|
||||||
|
obj_b_r$0 = 6,
|
||||||
|
obj_b_r$1 = 7;
|
||||||
|
console.log(obj_foo, obj_foo$0, obj_bar, obj_b_r, obj_b_r$0, obj_b_r$1);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: "1 3 4 5 6 7"
|
||||||
|
}
|
||||||
|
|
||||||
|
name_collision_2: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: 1,
|
||||||
|
0: function(x) {
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
1: function(x) {
|
||||||
|
return x + 1;
|
||||||
|
}
|
||||||
|
}, o__$0 = 2, o__$1 = 3;
|
||||||
|
console.log(o.p === o.p, o[0](4), o[1](5), o__$0, o__$1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o_p = 1,
|
||||||
|
o__ = function(x) {
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
o__$2 = function(x) {
|
||||||
|
return x + 1;
|
||||||
|
},
|
||||||
|
o__$0 = 2,
|
||||||
|
o__$1 = 3;
|
||||||
|
console.log(o_p === o_p, o__(4), o__$2(5), o__$0, o__$1);
|
||||||
|
}
|
||||||
|
expect_stdout: "true 4 6 2 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
name_collision_3: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: 1,
|
||||||
|
0: function(x) {
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
1: function(x) {
|
||||||
|
return x + 1;
|
||||||
|
}
|
||||||
|
}, o__$0 = 2, o__$1 = 3;
|
||||||
|
console.log(o.p === o.p, o[0](4), o[1](5));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o_p = 1,
|
||||||
|
o__ = function(x) {
|
||||||
|
return x;
|
||||||
|
},
|
||||||
|
o__$2 = function(x) {
|
||||||
|
return x + 1;
|
||||||
|
},
|
||||||
|
o__$0 = 2,
|
||||||
|
o__$1 = 3;
|
||||||
|
console.log(o_p === o_p, o__(4), o__$2(5));
|
||||||
|
}
|
||||||
|
expect_stdout: "true 4 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_this_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
u: function() {
|
||||||
|
return this === this;
|
||||||
|
},
|
||||||
|
p: 1
|
||||||
|
};
|
||||||
|
console.log(o.p, o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_this_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
u: function() {
|
||||||
|
return this === this;
|
||||||
|
},
|
||||||
|
p: 1
|
||||||
|
};
|
||||||
|
console.log(o.p, o.p, o.u);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 1, function() {
|
||||||
|
return this === this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
contains_this_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
u: function() {
|
||||||
|
return this === this;
|
||||||
|
},
|
||||||
|
p: 1
|
||||||
|
};
|
||||||
|
console.log(o.p, o.p, o.u());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
u: function() {
|
||||||
|
return this === this;
|
||||||
|
},
|
||||||
|
p: 1
|
||||||
|
};
|
||||||
|
console.log(o.p, o.p, o.u());
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1 true"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_this: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
f: function(a) {
|
||||||
|
this.b = a;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(new o.f(o.a).b, o.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(new function(a) {
|
||||||
|
this.b = a;
|
||||||
|
}(1).b, 2);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_1: {
|
||||||
|
options = {
|
||||||
|
hoist_props: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: [ "x", "y" ],
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
var z = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_2: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: [ "x", "y" ],
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
var z = {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = {};
|
||||||
|
var y = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_3: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: "o",
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2473_4: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
top_retain: "o",
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var o = {
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
};
|
||||||
|
console.log(o.a, o.b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var o_a = 1, o_b = 2;
|
||||||
|
console.log(o_a, o_b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2508_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: [ 1 ],
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(x) {
|
||||||
|
console.log(x);
|
||||||
|
})([ 1 ]);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2508_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: { b: 2 },
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(x) {
|
||||||
|
console.log(x);
|
||||||
|
})({ b: 2 });
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2508_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: [ o ],
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: [ o ],
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2508_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
a: { b: o },
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
a: { b: o },
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2508_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f: function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f(o.f);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o_f = function(x) {
|
||||||
|
console.log(x);
|
||||||
|
};
|
||||||
|
o_f(o_f);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2519: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function testFunc() {
|
||||||
|
var dimensions = {
|
||||||
|
minX: 5,
|
||||||
|
maxX: 6,
|
||||||
|
};
|
||||||
|
var scale = 1;
|
||||||
|
var d = {
|
||||||
|
x: (dimensions.maxX + dimensions.minX) / 2,
|
||||||
|
};
|
||||||
|
return d.x * scale;
|
||||||
|
}
|
||||||
|
console.log(testFunc());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function testFunc() {
|
||||||
|
return 1 * ((6 + 5) / 2);
|
||||||
|
}
|
||||||
|
console.log(testFunc());
|
||||||
|
}
|
||||||
|
expect_stdout: "5.5"
|
||||||
|
}
|
||||||
@@ -88,3 +88,24 @@ sequences_funs: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2295: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
var a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(o) {
|
||||||
|
var a = o.a;
|
||||||
|
if (a) return a;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -302,3 +302,97 @@ issue_1437_conditionals: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_512: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
if (b()) {
|
||||||
|
c();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
if (!b()) throw e;
|
||||||
|
c();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_var_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
return;
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a;
|
||||||
|
if (u()) {
|
||||||
|
var b;
|
||||||
|
return v();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
var d;
|
||||||
|
if (w()) {
|
||||||
|
var e;
|
||||||
|
return x();
|
||||||
|
var f;
|
||||||
|
} else {
|
||||||
|
var g;
|
||||||
|
y();
|
||||||
|
var h;
|
||||||
|
}
|
||||||
|
var i;
|
||||||
|
z();
|
||||||
|
var j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a, b;
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
var a, b, c, d, e, f, g, h, i, j;
|
||||||
|
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if_if_return_return: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a) {
|
||||||
|
if (b)
|
||||||
|
return b;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
if (a)
|
||||||
|
return b || void 0;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ non_hoisted_function_after_return: {
|
|||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
if_return: true, join_vars: true, side_effects: true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function foo(x) {
|
function foo(x) {
|
||||||
@@ -38,7 +38,7 @@ non_hoisted_function_after_return_2a: {
|
|||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
if_return: true, join_vars: true, side_effects: true,
|
||||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -71,11 +71,13 @@ non_hoisted_function_after_return_2a: {
|
|||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
||||||
|
"WARN: pass 0: last_count: Infinity, count: 37",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||||
|
"WARN: pass 1: last_count: 37, count: 18",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +85,7 @@ non_hoisted_function_after_return_2b: {
|
|||||||
options = {
|
options = {
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
if_return: true, join_vars: true, side_effects: true,
|
||||||
collapse_vars: false
|
collapse_vars: false
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -109,10 +111,146 @@ non_hoisted_function_after_return_2b: {
|
|||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
// duplicate warnings no longer emitted
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
non_hoisted_function_after_return_strict: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
|
if_return: true, join_vars: true, side_effects: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
if (x) {
|
||||||
|
return bar();
|
||||||
|
not_called1();
|
||||||
|
} else {
|
||||||
|
return baz();
|
||||||
|
not_called2();
|
||||||
|
}
|
||||||
|
function bar() { return 7; }
|
||||||
|
return not_reached;
|
||||||
|
function UnusedFunction() {}
|
||||||
|
function baz() { return 8; }
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
return x ? bar() : baz();
|
||||||
|
function bar() { return 7 }
|
||||||
|
function baz() { return 8 }
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "8 7"
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:133,16]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:136,16]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:139,12]",
|
||||||
|
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:140,21]",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
non_hoisted_function_after_return_2a_strict: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
|
if_return: true, join_vars: true, side_effects: true,
|
||||||
|
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
if (x) {
|
||||||
|
return bar(1);
|
||||||
|
var a = not_called(1);
|
||||||
|
} else {
|
||||||
|
return bar(2);
|
||||||
|
var b = not_called(2);
|
||||||
|
}
|
||||||
|
var c = bar(3);
|
||||||
|
function bar(x) { return 7 - x; }
|
||||||
|
function nope() {}
|
||||||
|
return b || c;
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
return bar(x ? 1 : 2);
|
||||||
|
function bar(x) {
|
||||||
|
return 7 - x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "5 6"
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:175,16]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:175,16]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,16]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,16]",
|
||||||
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:175,20]",
|
||||||
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:182,21]",
|
||||||
|
"WARN: pass 0: last_count: Infinity, count: 48",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:180,12]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:180,12]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:183,12]",
|
||||||
|
"WARN: Dropping unused variable b [test/compress/issue-1034.js:178,20]",
|
||||||
|
"WARN: Dropping unused variable c [test/compress/issue-1034.js:180,16]",
|
||||||
|
"WARN: pass 1: last_count: 48, count: 29",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
non_hoisted_function_after_return_2b_strict: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||||
|
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||||
|
if_return: true, join_vars: true, side_effects: true,
|
||||||
|
collapse_vars: false
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
if (x) {
|
||||||
|
return bar(1);
|
||||||
|
} else {
|
||||||
|
return bar(2);
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
var c = bar(3);
|
||||||
|
function bar(x) {
|
||||||
|
return 7 - x;
|
||||||
|
}
|
||||||
|
return b || c;
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function foo(x) {
|
||||||
|
return bar(x ? 1 : 2);
|
||||||
|
function bar(x) { return 7 - x; }
|
||||||
|
}
|
||||||
|
console.log(foo(0), foo(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "5 6"
|
||||||
|
expect_warnings: [
|
||||||
|
// duplicate warnings no longer emitted
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,16]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,16]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
||||||
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:231,12]",
|
||||||
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:235,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,7 @@
|
|||||||
const_declaration: {
|
|
||||||
options = {
|
|
||||||
evaluate: true
|
|
||||||
};
|
|
||||||
|
|
||||||
input: {
|
|
||||||
const goog = goog || {};
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
const goog = goog || {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const_pragma: {
|
const_pragma: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -29,6 +17,7 @@ const_pragma: {
|
|||||||
not_const: {
|
not_const: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,90 +1,91 @@
|
|||||||
multiple_functions: {
|
multiple_functions: {
|
||||||
options = { if_return: true, hoist_funs: false };
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
|
|
||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window );
|
if ( window );
|
||||||
|
function f() {}
|
||||||
|
function g() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
single_function: {
|
single_function: {
|
||||||
options = { if_return: true, hoist_funs: false };
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
function f() {}
|
|
||||||
|
|
||||||
if ( window );
|
if ( window );
|
||||||
|
function f() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deeply_nested: {
|
deeply_nested: {
|
||||||
options = { if_return: true, hoist_funs: false };
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
|
|
||||||
if ( !document ) {
|
if ( !document ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function h() {}
|
function h() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
|
|
||||||
function h() {}
|
|
||||||
|
|
||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window )
|
if ( window )
|
||||||
if (document);
|
if (document);
|
||||||
|
function f() {}
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
not_hoisted_when_already_nested: {
|
not_hoisted_when_already_nested: {
|
||||||
options = { if_return: true, hoist_funs: false };
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( foo ) function f() {}
|
if ( foo ) function f() {}
|
||||||
|
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -94,3 +95,70 @@ not_hoisted_when_already_nested: {
|
|||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defun_if_return: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (!window) return;
|
||||||
|
else function g() {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (window) function g() {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_hoist_funs: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (!window) return;
|
||||||
|
else function g() {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
function g() {}
|
||||||
|
function h() {}
|
||||||
|
if (window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defun_else_if_return: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: false,
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (window) function g() {}
|
||||||
|
else return;
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function e() {
|
||||||
|
function f() {}
|
||||||
|
if (window) function g() {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -190,7 +190,6 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
|||||||
keep_fargs: true,
|
keep_fargs: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
cascade: true,
|
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
sequences: false,
|
sequences: false,
|
||||||
keep_infinity: false,
|
keep_infinity: false,
|
||||||
@@ -253,7 +252,6 @@ assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
|||||||
keep_fargs: true,
|
keep_fargs: true,
|
||||||
if_return: true,
|
if_return: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
cascade: true,
|
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
sequences: false,
|
sequences: false,
|
||||||
keep_infinity: true,
|
keep_infinity: true,
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ pure_function_calls: {
|
|||||||
unused : true,
|
unused : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
negate_iife : true,
|
negate_iife : true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -49,13 +48,13 @@ pure_function_calls: {
|
|||||||
a.b(), f.g();
|
a.b(), f.g();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:17,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,8]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:17,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:16,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:30,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:29,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:30,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:29,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:28,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:27,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:37,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:39,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,31]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +68,6 @@ pure_function_calls_toplevel: {
|
|||||||
unused : true,
|
unused : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
negate_iife : true,
|
negate_iife : true,
|
||||||
toplevel : true,
|
toplevel : true,
|
||||||
}
|
}
|
||||||
@@ -96,6 +94,13 @@ pure_function_calls_toplevel: {
|
|||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// pure top-level calls will be dropped regardless of the leading comments position
|
||||||
|
var MyClass = /*#__PURE__*//*@class*/(function(){
|
||||||
|
function MyClass() {}
|
||||||
|
MyClass.prototype.method = function() {};
|
||||||
|
return MyClass;
|
||||||
|
})();
|
||||||
|
|
||||||
// comment #__PURE__ comment
|
// comment #__PURE__ comment
|
||||||
bar(), baz(), quux();
|
bar(), baz(), quux();
|
||||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||||
@@ -105,15 +110,17 @@ pure_function_calls_toplevel: {
|
|||||||
a.b(), f.g();
|
a.b(), f.g();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:79,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:77,8]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:79,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:77,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:90,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:90,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:88,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:105,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:106,31]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:82,33]",
|
||||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:82,12]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:98,45]",
|
||||||
|
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:98,12]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,29 +155,29 @@ should_warn: {
|
|||||||
baz();
|
baz();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,61]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
|
||||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
|
||||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:135,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
"WARN: Boolean || always true [test/compress/issue-1261.js:136,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,23]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:136,23]",
|
||||||
|
"WARN: Condition left of || always true [test/compress/issue-1261.js:137,8]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:137,8]",
|
||||||
|
"WARN: Boolean && always false [test/compress/issue-1261.js:138,23]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
||||||
|
"WARN: Condition always false [test/compress/issue-1261.js:138,23]",
|
||||||
|
"WARN: Condition left of && always false [test/compress/issue-1261.js:139,8]",
|
||||||
|
"WARN: Condition always false [test/compress/issue-1261.js:139,8]",
|
||||||
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:140,23]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:140,23]",
|
||||||
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:141,8]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:141,31]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:141,8]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,24]",
|
||||||
|
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
||||||
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,31]",
|
||||||
|
"WARN: Condition always false [test/compress/issue-1261.js:144,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ string_plus_optimization: {
|
|||||||
unused : true,
|
unused : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
hoist_funs : true,
|
hoist_funs : true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -10,17 +12,19 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.b = 1;
|
x.x = 1;
|
||||||
x["a"] = 2 * x.b;
|
x["a"] = 2 * x.x;
|
||||||
console.log(x.b, x["a"]);
|
console.log(x.x, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: ""
|
debug: "",
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -30,16 +34,18 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["_$foo$_"] = 2 * x.a;
|
x["_$foo$_"] = 2 * x.x;
|
||||||
console.log(x.a, x["_$foo$_"]);
|
console.log(x.x, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
|
keep_quoted: false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -49,9 +55,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.a = 1;
|
x.x = 1;
|
||||||
x["b"] = 2 * x.a;
|
x["o"] = 2 * x.x;
|
||||||
console.log(x.a, x["b"]);
|
console.log(x.x, x["o"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
typeof_eq_undefined: {
|
typeof_eq_undefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -24,6 +25,7 @@ typeof_eq_undefined_ie8: {
|
|||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -45,7 +47,8 @@ typeof_eq_undefined_ie8: {
|
|||||||
|
|
||||||
undefined_redefined: {
|
undefined_redefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(undefined) {
|
function f(undefined) {
|
||||||
@@ -58,7 +61,8 @@ undefined_redefined: {
|
|||||||
|
|
||||||
undefined_redefined_mangle: {
|
undefined_redefined_mangle: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true
|
comparisons: true,
|
||||||
|
typeofs: true,
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ conditional_false_stray_else_in_loop: {
|
|||||||
hoist_vars : true,
|
hoist_vars : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
cascade : true,
|
|
||||||
conditionals : false,
|
conditionals : false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -85,15 +85,3 @@ unsafe_undefined: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime_error: {
|
|
||||||
input: {
|
|
||||||
const a = 1;
|
|
||||||
console.log(a++);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
const a = 1;
|
|
||||||
console.log(a++);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ chained_evaluation_1: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -28,6 +29,7 @@ chained_evaluation_2: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
issue_1639_1: {
|
issue_1639_1: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -26,7 +26,7 @@ issue_1639_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
||||||
if (--b, !1) var ignore = 0;
|
if (--b, 0) var ignore = 0;
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -35,7 +35,7 @@ issue_1639_1: {
|
|||||||
issue_1639_2: {
|
issue_1639_2: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
@@ -57,7 +57,7 @@ issue_1639_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
function f19() {
|
function f19() {
|
||||||
++a, 1;
|
++a, 0;
|
||||||
}
|
}
|
||||||
f19(),
|
f19(),
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
@@ -68,7 +68,7 @@ issue_1639_2: {
|
|||||||
issue_1639_3: {
|
issue_1639_3: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
f7: {
|
f7: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
cascade: true,
|
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -15,6 +14,7 @@ f7: {
|
|||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
passes: 3,
|
passes: 3,
|
||||||
properties: true,
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -38,7 +38,7 @@ f7: {
|
|||||||
"var b = 10;",
|
"var b = 10;",
|
||||||
"",
|
"",
|
||||||
"!function() {",
|
"!function() {",
|
||||||
" for (;b = 100, !1; ) ;",
|
" b = 100;",
|
||||||
"}(), console.log(100, b);",
|
"}(), console.log(100, b);",
|
||||||
]
|
]
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
side_effects_catch: {
|
side_effects_catch: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -34,6 +35,7 @@ side_effects_catch: {
|
|||||||
|
|
||||||
side_effects_else: {
|
side_effects_else: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -62,6 +64,7 @@ side_effects_else: {
|
|||||||
|
|
||||||
side_effects_finally: {
|
side_effects_finally: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -98,6 +101,7 @@ side_effects_finally: {
|
|||||||
|
|
||||||
side_effects_label: {
|
side_effects_label: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -130,6 +134,7 @@ side_effects_label: {
|
|||||||
|
|
||||||
side_effects_switch: {
|
side_effects_switch: {
|
||||||
options = {
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ case_1: {
|
|||||||
input: {
|
input: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a, true:
|
case a || true:
|
||||||
default:
|
default:
|
||||||
b = 2;
|
b = 2;
|
||||||
case true:
|
case true:
|
||||||
@@ -17,7 +17,7 @@ case_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a, true:
|
case a || true:
|
||||||
b = 2;
|
b = 2;
|
||||||
}
|
}
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
mangle_props: {
|
mangle_props: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
undefined: 1,
|
undefined: 1,
|
||||||
@@ -54,10 +56,12 @@ mangle_props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numeric_literal: {
|
numeric_literal: {
|
||||||
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
}
|
}
|
||||||
mangle_props = {}
|
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
0: 0,
|
0: 0,
|
||||||
@@ -82,7 +86,7 @@ numeric_literal: {
|
|||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' "42": 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' a: 5,',
|
' o: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' "1e+42": 8',
|
||||||
@@ -92,7 +96,7 @@ numeric_literal: {
|
|||||||
'',
|
'',
|
||||||
'console.log(obj[42], obj["42"]);',
|
'console.log(obj[42], obj["42"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||||
]
|
]
|
||||||
@@ -105,7 +109,9 @@ numeric_literal: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
identifier: {
|
identifier: {
|
||||||
mangle_props = {}
|
mangle = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
abstract: 1,
|
abstract: 1,
|
||||||
@@ -173,32 +179,32 @@ identifier: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var obj = {
|
var obj = {
|
||||||
a: 1,
|
e: 1,
|
||||||
b: 2,
|
t: 2,
|
||||||
c: 3,
|
n: 3,
|
||||||
d: 4,
|
a: 4,
|
||||||
e: 5,
|
i: 5,
|
||||||
f: 6,
|
o: 6,
|
||||||
g: 7,
|
r: 7,
|
||||||
h: 8,
|
l: 8,
|
||||||
i: 9,
|
s: 9,
|
||||||
j: 10,
|
c: 10,
|
||||||
k: 11,
|
f: 11,
|
||||||
l: 12,
|
u: 12,
|
||||||
m: 13,
|
d: 13,
|
||||||
n: 14,
|
h: 14,
|
||||||
o: 15,
|
p: 15,
|
||||||
p: 16,
|
b: 16,
|
||||||
q: 17,
|
v: 17,
|
||||||
r: 18,
|
w: 18,
|
||||||
s: 19,
|
y: 19,
|
||||||
t: 20,
|
g: 20,
|
||||||
u: 21,
|
m: 21,
|
||||||
v: 22,
|
k: 22,
|
||||||
w: 23,
|
x: 23,
|
||||||
x: 24,
|
j: 24,
|
||||||
y: 25,
|
z: 25,
|
||||||
z: 26,
|
q: 26,
|
||||||
A: 27,
|
A: 27,
|
||||||
B: 28,
|
B: 28,
|
||||||
C: 29,
|
C: 29,
|
||||||
@@ -229,11 +235,11 @@ identifier: {
|
|||||||
Z: 54,
|
Z: 54,
|
||||||
$: 55,
|
$: 55,
|
||||||
_: 56,
|
_: 56,
|
||||||
aa: 57,
|
ee: 57,
|
||||||
ba: 58,
|
te: 58,
|
||||||
ca: 59,
|
ne: 59,
|
||||||
da: 60,
|
ae: 60,
|
||||||
ea: 61,
|
ie: 61,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
unary_prefix: {
|
unary_prefix: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
iife_for: {
|
iife_for: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -26,6 +27,7 @@ iife_for: {
|
|||||||
iife_for_in: {
|
iife_for_in: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -51,6 +53,7 @@ iife_for_in: {
|
|||||||
iife_do: {
|
iife_do: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -80,6 +83,7 @@ iife_do: {
|
|||||||
iife_while: {
|
iife_while: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -130,5 +134,5 @@ label_while: {
|
|||||||
L: while (0) continue L;
|
L: while (0) continue L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(){L:;}"
|
expect_exact: "function f(){L:0}"
|
||||||
}
|
}
|
||||||
|
|||||||
31
test/compress/issue-1943.js
Normal file
31
test/compress/issue-1943.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
operator: {
|
||||||
|
input: {
|
||||||
|
a. //comment
|
||||||
|
typeof
|
||||||
|
}
|
||||||
|
expect_exact: "a.typeof;"
|
||||||
|
}
|
||||||
|
|
||||||
|
name: {
|
||||||
|
input: {
|
||||||
|
a. //comment
|
||||||
|
b
|
||||||
|
}
|
||||||
|
expect_exact: "a.b;"
|
||||||
|
}
|
||||||
|
|
||||||
|
keyword: {
|
||||||
|
input: {
|
||||||
|
a. //comment
|
||||||
|
default
|
||||||
|
}
|
||||||
|
expect_exact: "a.default;"
|
||||||
|
}
|
||||||
|
|
||||||
|
atom: {
|
||||||
|
input: {
|
||||||
|
a. //comment
|
||||||
|
true
|
||||||
|
}
|
||||||
|
expect_exact: "a.true;"
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
const ENV = 3;
|
var ENV = 3;
|
||||||
var FOO = 4;
|
var FOO = 4;
|
||||||
f(ENV * 10);
|
f(ENV * 10);
|
||||||
--FOO;
|
--FOO;
|
||||||
@@ -49,7 +49,7 @@ mixed: {
|
|||||||
x = DEBUG;
|
x = DEBUG;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
const ENV = 3;
|
var ENV = 3;
|
||||||
var FOO = 4;
|
var FOO = 4;
|
||||||
f(10);
|
f(10);
|
||||||
--FOO;
|
--FOO;
|
||||||
@@ -60,7 +60,7 @@ mixed: {
|
|||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,14]',
|
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||||
|
|||||||
33
test/compress/issue-2652.js
Normal file
33
test/compress/issue-2652.js
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
insert_semicolon: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a
|
||||||
|
/* foo */ var b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"var b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
unary_postfix: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a
|
||||||
|
/* foo */++b
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"a",
|
||||||
|
"/* foo */;",
|
||||||
|
"",
|
||||||
|
"++b;",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -64,3 +64,27 @@ strings_concat: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
regexp: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
RegExp("foo");
|
||||||
|
RegExp("bar", "ig");
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
/foo/;
|
||||||
|
/bar/ig;
|
||||||
|
RegExp(foo);
|
||||||
|
RegExp("bar", ig);
|
||||||
|
RegExp("should", "fail");
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:78,2]',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
warn: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
return g["call" + "er"].arguments;
|
||||||
|
}
|
||||||
|
// 3
|
||||||
|
console.log(f(1, 2, 3).length);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
// TypeError: Cannot read property 'arguments' of null
|
||||||
|
console.log(function g() {
|
||||||
|
return g.caller.arguments;
|
||||||
|
}().length);
|
||||||
|
}
|
||||||
|
expect_warnings: [
|
||||||
|
"WARN: Function.protoype.caller not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
"WARN: Function.protoype.arguments not supported [test/compress/issue-2719.js:17,19]",
|
||||||
|
]
|
||||||
|
}
|
||||||
498
test/compress/issue-281.js
Normal file
498
test/compress/issue-281.js
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
collapse_vars_constants: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(x) {
|
||||||
|
var a = 4, b = x.prop, c = 5, d = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (function() { return d - a * e - c; })();
|
||||||
|
}
|
||||||
|
function f2(x) {
|
||||||
|
var a = 4, b = x.prop, c = 5, not_used = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (function() { return -a * e - c; })();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(x) {
|
||||||
|
var b = x.prop, d = sideeffect1(), e = sideeffect2();
|
||||||
|
return b + (d - 4 * e - 5);
|
||||||
|
}
|
||||||
|
function f2(x) {
|
||||||
|
var b = x.prop;
|
||||||
|
sideeffect1();
|
||||||
|
return b + (-4 * sideeffect2() - 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modified: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f5(b) {
|
||||||
|
var a = function() {
|
||||||
|
return b;
|
||||||
|
}();
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f5(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f5(b) {
|
||||||
|
var a = b;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f5(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_scope: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1, b = 2, c = 3;
|
||||||
|
var a = c++, b = b /= a;
|
||||||
|
return function() {
|
||||||
|
return a;
|
||||||
|
}() + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a = 1, b = 2, c = 3;
|
||||||
|
b = b /= a = c++;
|
||||||
|
return a + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_undefined: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
unsafe: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var a, c;
|
||||||
|
console.log(function(undefined) {
|
||||||
|
return function() {
|
||||||
|
if (a)
|
||||||
|
return b;
|
||||||
|
if (c)
|
||||||
|
return d;
|
||||||
|
};
|
||||||
|
}(1)());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, c;
|
||||||
|
console.log(a ? b : c ? d : void 0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_3_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_4: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? console.log(true) : console.log(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? foo(true) : bar(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_5_off: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
sequences: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if ((function(){ return t })()) {
|
||||||
|
foo(true);
|
||||||
|
} else {
|
||||||
|
bar(false);
|
||||||
|
}
|
||||||
|
(function(){
|
||||||
|
console.log("something");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
t ? foo(true) : bar(false), void console.log("something");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_true: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: 'void console.log("test");'
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1254_negate_iife_nested: {
|
||||||
|
options = {
|
||||||
|
expression: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()()()()();
|
||||||
|
}
|
||||||
|
expect_exact: '(void console.log("test"))()()();'
|
||||||
|
}
|
||||||
|
|
||||||
|
negate_iife_issue_1073: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
new (function(a) {
|
||||||
|
return function Foo() {
|
||||||
|
this.x = a;
|
||||||
|
console.log(this);
|
||||||
|
};
|
||||||
|
}(7))();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function() {
|
||||||
|
this.x = 7,
|
||||||
|
console.log(this);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1288_side_effects: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (w) ;
|
||||||
|
else {
|
||||||
|
(function f() {})();
|
||||||
|
}
|
||||||
|
if (!x) {
|
||||||
|
(function() {
|
||||||
|
x = {};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
if (y)
|
||||||
|
(function() {})();
|
||||||
|
else
|
||||||
|
(function(z) {
|
||||||
|
return z;
|
||||||
|
})(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
w;
|
||||||
|
x || (x = {});
|
||||||
|
y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_var_for_in_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
for (b in (function() {
|
||||||
|
return x(a, b, c);
|
||||||
|
})()) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(a, b, c, d);
|
||||||
|
}
|
||||||
|
x(a, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
var a = 1, b = 2;
|
||||||
|
for (b in x(1, b, c)) {
|
||||||
|
var c = 3, d = 4;
|
||||||
|
x(1, b, c, d);
|
||||||
|
}
|
||||||
|
x(1, b, c, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1595_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a) {
|
||||||
|
return g(a + 1);
|
||||||
|
})(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
g(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1758: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return function() {
|
||||||
|
c--;
|
||||||
|
c--, c.toString();
|
||||||
|
return;
|
||||||
|
}();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(c) {
|
||||||
|
var undefined = 42;
|
||||||
|
return c--, c--, void c.toString();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
wrap_iife: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return function() {
|
||||||
|
console.log('test')
|
||||||
|
};
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: 'void console.log("test");'
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_iife_in_expression: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
foo = (function () {
|
||||||
|
return bar();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: 'foo=bar();'
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_iife_in_return_call: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
negate_iife: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
wrap_iife: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
return (function() {
|
||||||
|
console.log('test')
|
||||||
|
})();
|
||||||
|
})()();
|
||||||
|
}
|
||||||
|
expect_exact: '(void console.log("test"))();'
|
||||||
|
}
|
||||||
|
|
||||||
|
pure_annotation_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(function() {
|
||||||
|
console.log("hello");
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_exact: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
pure_annotation_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(function(n) {
|
||||||
|
console.log("hello", n);
|
||||||
|
}(42));
|
||||||
|
}
|
||||||
|
expect_exact: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_fargs: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function(a_1) {
|
||||||
|
a++;
|
||||||
|
}(a++ + (a && a.var));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
++a && a.var, a++;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_fargs: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
!function(a_1) {
|
||||||
|
a++;
|
||||||
|
}(a++ + (a && a.var));
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
++a && a.var, a++;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "3"
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
collapse: {
|
collapse: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -41,7 +41,7 @@ collapse: {
|
|||||||
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
return void 0 !== ('function' === typeof b ? b() : b) && c();
|
||||||
}
|
}
|
||||||
function f2(b) {
|
function f2(b) {
|
||||||
return b = c(), 'stirng' == typeof ('function' === typeof b ? b() : b) && d();
|
return 'stirng' == typeof ('function' === typeof (b = c()) ? b() : b) && d();
|
||||||
}
|
}
|
||||||
function f3(c) {
|
function f3(c) {
|
||||||
var a;
|
var a;
|
||||||
|
|||||||
@@ -17,6 +17,6 @@ wrongly_optimized: {
|
|||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
// TODO: optimize to `func(), bar()`
|
||||||
(func(), 0) || bar();
|
(func(), 1) && bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ wrongly_optimized: {
|
|||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
// TODO: optimize to `func(), bar()`
|
||||||
if (func(), !0) bar();
|
if (func(), 1) bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,45 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
regex: /asd/,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "123"
|
||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
regex: /asd/
|
properties: {
|
||||||
};
|
regex: /asd/,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
"aaaaaaaaaabbbbb";
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
}
|
expect_stdout: "123"
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ dont_mangle_arguments: {
|
|||||||
hoist_vars : true,
|
hoist_vars : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
side_effects : true,
|
side_effects : true,
|
||||||
negate_iife : false
|
negate_iife : false
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
this_binding_conditionals: {
|
this_binding_conditionals: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate : true
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(1 && a)();
|
(1 && a)();
|
||||||
@@ -51,6 +52,7 @@ this_binding_collapse_vars: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var c = a; c();
|
var c = a; c();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ eval_collapse_vars: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
|
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ issue979_reported: {
|
|||||||
options = {
|
options = {
|
||||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -32,7 +32,7 @@ issue979_test_negated_is_best: {
|
|||||||
options = {
|
options = {
|
||||||
sequences:true, properties:true, dead_code:true, conditionals:true,
|
sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||||
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f3() {
|
function f3() {
|
||||||
|
|||||||
@@ -146,55 +146,13 @@ parse_do_while_without_semicolon: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
keep_collapse_const_in_own_block_scope: {
|
|
||||||
options = {
|
|
||||||
join_vars: true,
|
|
||||||
loops: true
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var i=2;
|
|
||||||
const c=5;
|
|
||||||
while(i--)
|
|
||||||
console.log(i);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var i=2;
|
|
||||||
const c=5;
|
|
||||||
for(;i--;)
|
|
||||||
console.log(i);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_collapse_const_in_own_block_scope_2: {
|
|
||||||
options = {
|
|
||||||
join_vars: true,
|
|
||||||
loops: true
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
const c=5;
|
|
||||||
var i=2; // Moves to loop, while it did not in previous test
|
|
||||||
while(i--)
|
|
||||||
console.log(i);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
const c=5;
|
|
||||||
for(var i=2;i--;)
|
|
||||||
console.log(i);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
evaluate: {
|
evaluate: {
|
||||||
options = {
|
options = {
|
||||||
loops: true,
|
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
side_effects: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -480,3 +438,170 @@ do_switch: {
|
|||||||
} while (false);
|
} while (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
in_parenthesis_1: {
|
||||||
|
input: {
|
||||||
|
for (("foo" in {});0;);
|
||||||
|
}
|
||||||
|
expect_exact: 'for(("foo"in{});0;);'
|
||||||
|
}
|
||||||
|
|
||||||
|
in_parenthesis_2: {
|
||||||
|
input: {
|
||||||
|
for ((function(){ "foo" in {}; });0;);
|
||||||
|
}
|
||||||
|
expect_exact: 'for(function(){"foo"in{}};0;);'
|
||||||
|
}
|
||||||
|
|
||||||
|
init_side_effects: {
|
||||||
|
options = {
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
for (function() {}(), i = 0; i < 5; i++) console.log(i);
|
||||||
|
for (function() {}(); i < 10; i++) console.log(i);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (i = 0; i < 5; i++) console.log(i);
|
||||||
|
for (; i < 10; i++) console.log(i);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_condition: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var a = 0, b = 5; (a += 1, 3) - 3 && b > 0; b--) {
|
||||||
|
var c = function() {
|
||||||
|
b--;
|
||||||
|
}(a++);
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c;
|
||||||
|
var a = 0, b = 5;
|
||||||
|
a += 1, 0,
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_1: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (; ; ) break;
|
||||||
|
for (a(); ; ) break;
|
||||||
|
for (; b(); ) break;
|
||||||
|
for (c(); d(); ) break;
|
||||||
|
for (; ; e()) break;
|
||||||
|
for (f(); ; g()) break;
|
||||||
|
for (; h(); i()) break;
|
||||||
|
for (j(); k(); l()) break;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a();
|
||||||
|
b();
|
||||||
|
c();
|
||||||
|
d();
|
||||||
|
f();
|
||||||
|
h();
|
||||||
|
j();
|
||||||
|
k();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_2: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: while (x()) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_3: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
L1: for (var x = 0; x < 3; x++)
|
||||||
|
for (var y = 0; y < 2; y++)
|
||||||
|
break L1;
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_4: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var x = 0; x < 3; x++) {
|
||||||
|
var y = 0;
|
||||||
|
y < 2;
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 0"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2740_5: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L1: for (var x = 0; x < 3; x++) {
|
||||||
|
break L1;
|
||||||
|
L2: for (var y = 0; y < 2; y++) {
|
||||||
|
break L2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 0;
|
||||||
|
x < 3;
|
||||||
|
var y;
|
||||||
|
console.log(x,y);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,8 @@ negate_iife_1_off: {
|
|||||||
|
|
||||||
negate_iife_2: {
|
negate_iife_2: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true
|
inline: true,
|
||||||
|
negate_iife: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(function(){ return {} })().x = 10;
|
(function(){ return {} })().x = 10;
|
||||||
@@ -32,6 +33,7 @@ negate_iife_2: {
|
|||||||
|
|
||||||
negate_iife_2_side_effects: {
|
negate_iife_2_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
|
inline: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
@@ -58,6 +60,7 @@ negate_iife_3_evaluate: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -100,6 +103,7 @@ negate_iife_3_off_evaluate: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
negate_iife: false,
|
negate_iife: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -82,3 +82,19 @@ new_with_unary_prefix: {
|
|||||||
}
|
}
|
||||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dot_parenthesis_1: {
|
||||||
|
input: {
|
||||||
|
console.log(new (Math.random().constructor) instanceof Number);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(new(Math.random().constructor)instanceof Number);"
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_parenthesis_2: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof new function(){Math.random()}.constructor);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(typeof new function(){Math.random()}.constructor);"
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|||||||
38
test/compress/node_version.js
Normal file
38
test/compress/node_version.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
eval_let_6: {
|
||||||
|
input: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect_stdout: ""
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_let_4: {
|
||||||
|
input: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect_stdout: SyntaxError("Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")
|
||||||
|
node_version: "4"
|
||||||
|
}
|
||||||
|
|
||||||
|
eval_let_0: {
|
||||||
|
input: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
eval("let a;");
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
expect_stdout: SyntaxError("Unexpected identifier")
|
||||||
|
node_version: "<=0.12"
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
keep_properties: {
|
keep_properties: {
|
||||||
options = {
|
options = {
|
||||||
properties: false
|
evaluate: true,
|
||||||
};
|
properties: false,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
}
|
}
|
||||||
@@ -12,9 +13,12 @@ keep_properties: {
|
|||||||
|
|
||||||
dot_properties: {
|
dot_properties: {
|
||||||
options = {
|
options = {
|
||||||
|
evaluate: true,
|
||||||
properties: true,
|
properties: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
ie8: true,
|
ie8: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -35,9 +39,12 @@ dot_properties: {
|
|||||||
|
|
||||||
dot_properties_es5: {
|
dot_properties_es5: {
|
||||||
options = {
|
options = {
|
||||||
|
evaluate: true,
|
||||||
properties: true,
|
properties: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
ie8: false,
|
ie8: false,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -57,8 +64,8 @@ dot_properties_es5: {
|
|||||||
sub_properties: {
|
sub_properties: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
properties: true
|
properties: true,
|
||||||
};
|
}
|
||||||
input: {
|
input: {
|
||||||
a[0] = 0;
|
a[0] = 0;
|
||||||
a["0"] = 1;
|
a["0"] = 1;
|
||||||
@@ -77,18 +84,18 @@ sub_properties: {
|
|||||||
a[3.14] = 3;
|
a[3.14] = 3;
|
||||||
a.if = 4;
|
a.if = 4;
|
||||||
a["foo bar"] = 5;
|
a["foo bar"] = 5;
|
||||||
a[NaN] = 6;
|
a.NaN = 6;
|
||||||
a[null] = 7;
|
a.null = 7;
|
||||||
a[void 0] = 8;
|
a[void 0] = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluate_array_length: {
|
evaluate_array_length: {
|
||||||
options = {
|
options = {
|
||||||
|
evaluate: true,
|
||||||
properties: true,
|
properties: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
evaluate: true
|
}
|
||||||
};
|
|
||||||
input: {
|
input: {
|
||||||
a = [1, 2, 3].length;
|
a = [1, 2, 3].length;
|
||||||
a = [1, 2, 3].join()["len" + "gth"];
|
a = [1, 2, 3].join()["len" + "gth"];
|
||||||
@@ -105,10 +112,10 @@ evaluate_array_length: {
|
|||||||
|
|
||||||
evaluate_string_length: {
|
evaluate_string_length: {
|
||||||
options = {
|
options = {
|
||||||
|
evaluate: true,
|
||||||
properties: true,
|
properties: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
evaluate: true
|
}
|
||||||
};
|
|
||||||
input: {
|
input: {
|
||||||
a = "foo".length;
|
a = "foo".length;
|
||||||
a = ("foo" + "bar")["len" + "gth"];
|
a = ("foo" + "bar")["len" + "gth"];
|
||||||
@@ -124,9 +131,11 @@ evaluate_string_length: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_properties: {
|
mangle_properties: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: false
|
properties: {
|
||||||
};
|
keep_quoted: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
@@ -137,18 +146,21 @@ mangle_properties: {
|
|||||||
expect: {
|
expect: {
|
||||||
a["a"] = "bar";
|
a["a"] = "bar";
|
||||||
a.b = "red";
|
a.b = "red";
|
||||||
x = {c: 10};
|
x = {o: 10};
|
||||||
a.d(x.c, a.a);
|
a.r(x.o, a.a);
|
||||||
a['d']({b: "blue", a: "baz"});
|
a['r']({b: "blue", a: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_unquoted_properties: {
|
mangle_unquoted_properties: {
|
||||||
options = {
|
options = {
|
||||||
properties: false
|
evaluate: true,
|
||||||
|
properties: false,
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -177,24 +189,26 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.b = 2;
|
a.r = 2;
|
||||||
x = {"bar": 10, c: 7};
|
x = {"bar": 10, b: 7};
|
||||||
a.c = 9;
|
a.b = 9;
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
a['color'] = "red";
|
a['color'] = "red";
|
||||||
x = {bar: 10, c: 7};
|
x = {bar: 10, b: 7};
|
||||||
a.c = 9;
|
a.b = 9;
|
||||||
a.b = 3;
|
a.r = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug: {
|
mangle_debug: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: ""
|
properties: {
|
||||||
};
|
debug: "",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -206,9 +220,11 @@ mangle_debug: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_true: {
|
mangle_debug_true: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: true
|
properties: {
|
||||||
};
|
debug: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -220,9 +236,11 @@ mangle_debug_true: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_suffix: {
|
mangle_debug_suffix: {
|
||||||
mangle_props = {
|
mangle = {
|
||||||
debug: "XYZ"
|
properties: {
|
||||||
};
|
debug: "XYZ",
|
||||||
|
},
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -235,12 +253,15 @@ mangle_debug_suffix: {
|
|||||||
|
|
||||||
mangle_debug_suffix_keep_quoted: {
|
mangle_debug_suffix_keep_quoted: {
|
||||||
options = {
|
options = {
|
||||||
properties: false
|
evaluate: true,
|
||||||
|
properties: false,
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle = {
|
||||||
keep_quoted: true,
|
properties: {
|
||||||
debug: "XYZ",
|
debug: "XYZ",
|
||||||
reserved: []
|
keep_quoted: true,
|
||||||
|
reserved: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -546,12 +567,624 @@ native_prototype: {
|
|||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||||
|
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||||
|
Number.prototype.toFixed.call(Math.PI, 2);
|
||||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||||
|
RegExp.prototype.test.call(/foo/, "bar");
|
||||||
String.prototype.indexOf.call(e, "bar");
|
String.prototype.indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[].splice.apply(a, [1, 2, b, c]);
|
[].splice.apply(a, [1, 2, b, c]);
|
||||||
|
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||||
|
0..toFixed.call(Math.PI, 2);
|
||||||
({}).hasOwnProperty.call(d, "foo");
|
({}).hasOwnProperty.call(d, "foo");
|
||||||
|
/t/.test.call(/foo/, "bar");
|
||||||
"".indexOf.call(e, "bar");
|
"".indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessor_boolean: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get true() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set false(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b.true, b.false = 2, b.true);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get true(){return a},set false(c){a=c}};console.log(b.true,b.false=2,b.true);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_get_set: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get set() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set get(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b.set, b.get = 2, b.set);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get set(){return a},set get(c){a=c}};console.log(b.set,b.get=2,b.set);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_null_undefined: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get null() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set undefined(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b.null, b.undefined = 2, b.null);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get null(){return a},set undefined(c){a=c}};console.log(b.null,b.undefined=2,b.null);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_number: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get 42() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set 42(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b[42], b[42] = 2, b[42]);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get 42(){return a},set 42(c){a=c}};console.log(b[42],b[42]=2,b[42]);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_string: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get "a-b"() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set "a-b"(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b["a-b"], b["a-b"] = 2, b["a-b"]);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get"a-b"(){return a},set"a-b"(c){a=c}};console.log(b["a-b"],b["a-b"]=2,b["a-b"]);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_this: {
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
var b = {
|
||||||
|
get this() {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
set this(c) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(b.this, b.this = 2, b.this);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=1;var b={get this(){return a},set this(c){a=c}};console.log(b.this,b.this=2,b.this);'
|
||||||
|
expect_stdout: "1 2 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
a: 42,
|
||||||
|
p: function() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
a: 42,
|
||||||
|
p: function() {
|
||||||
|
return this.a;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
a = 42;
|
||||||
|
console.log({
|
||||||
|
p: function() {
|
||||||
|
return function() {
|
||||||
|
return this.a;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = 42;
|
||||||
|
console.log(function() {
|
||||||
|
return this.a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_4: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo() {}
|
||||||
|
console.log({
|
||||||
|
a: foo(),
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {}
|
||||||
|
console.log((foo(), function() {
|
||||||
|
return 42;
|
||||||
|
})());
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2208_5: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
p: "FAIL",
|
||||||
|
p: function() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
}.p());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2256: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
properties: {
|
||||||
|
keep_quoted: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({ "keep": 1 });
|
||||||
|
g.keep = g.change;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
g.keep = g.g;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lhs_prop_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(++{
|
||||||
|
a: 1
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(++{
|
||||||
|
a: 1
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
lhs_prop_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[1][0] = 42;
|
||||||
|
(function(a) {
|
||||||
|
a.b = "g";
|
||||||
|
})("abc");
|
||||||
|
(function(a) {
|
||||||
|
a[2] = "g";
|
||||||
|
})("def");
|
||||||
|
(function(a) {
|
||||||
|
a[""] = "g";
|
||||||
|
})("ghi");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[1][0] = 42;
|
||||||
|
"abc".b = "g";
|
||||||
|
"def"[2] = "g";
|
||||||
|
"ghi"[""] = "g";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
literal_duplicate_key_side_effects: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
a: "FAIL",
|
||||||
|
a: console.log ? "PASS" : "FAIL"
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(console.log ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_side_effects_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var C = 1;
|
||||||
|
console.log(C);
|
||||||
|
var obj = {
|
||||||
|
bar: function() {
|
||||||
|
return C + C;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(obj.bar());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
var obj = {
|
||||||
|
bar: function() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(obj.bar());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
prop_side_effects_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
properties: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var C = 1;
|
||||||
|
console.log(C);
|
||||||
|
var obj = {
|
||||||
|
"": function() {
|
||||||
|
return C + C;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(obj[""]());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1);
|
||||||
|
console.log(2);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_1: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
a: "FAIL",
|
||||||
|
get a() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
a: "FAIL",
|
||||||
|
get a() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor_2: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
return "PASS";
|
||||||
|
},
|
||||||
|
set a(v) {},
|
||||||
|
a: "FAIL"
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
return "PASS";
|
||||||
|
},
|
||||||
|
set a(v) {},
|
||||||
|
a: "FAIL"
|
||||||
|
}.a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
array_hole: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(
|
||||||
|
[ 1, 2, , 3][1],
|
||||||
|
[ 1, 2, , 3][2],
|
||||||
|
[ 1, 2, , 3][3]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(2, void 0, 3);
|
||||||
|
}
|
||||||
|
expect_stdout: "2 undefined 3"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_this: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new {
|
||||||
|
f: function(a) {
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
}.f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(a) {
|
||||||
|
this.a = a;
|
||||||
|
}(42);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2513: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function(Infinity, NaN, undefined) {
|
||||||
|
console.log("a"[1/0], "b"["Infinity"]);
|
||||||
|
console.log("c"[0/0], "d"["NaN"]);
|
||||||
|
console.log("e"[void 0], "f"["undefined"]);
|
||||||
|
}(0, 0, 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(Infinity, NaN, undefined) {
|
||||||
|
console.log("a"[1/0], "b"[1/0]);
|
||||||
|
console.log("c".NaN, "d".NaN);
|
||||||
|
console.log("e"[void 0], "f"[void 0]);
|
||||||
|
}(0, 0, 0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined undefined",
|
||||||
|
"undefined undefined",
|
||||||
|
"undefined undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const_prop_assign_strict: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function Simulator() {
|
||||||
|
/abc/.index = 1;
|
||||||
|
this._aircraft = [];
|
||||||
|
}
|
||||||
|
(function() {}).prototype.destroy = x();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function Simulator() {
|
||||||
|
this._aircraft = [];
|
||||||
|
}
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const_prop_assign_pure: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function Simulator() {
|
||||||
|
/abc/.index = 1;
|
||||||
|
this._aircraft = [];
|
||||||
|
}
|
||||||
|
(function() {}).prototype.destroy = x();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function Simulator() {
|
||||||
|
this._aircraft = [];
|
||||||
|
}
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
};
|
||||||
|
x.b = 2;
|
||||||
|
x[3] = function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
x["a"] = /foo/,
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var x = {
|
||||||
|
a: 1,
|
||||||
|
c: (console.log("c"), "C"),
|
||||||
|
b: 2,
|
||||||
|
3: function() {
|
||||||
|
console.log(x);
|
||||||
|
},
|
||||||
|
a: /foo/,
|
||||||
|
};
|
||||||
|
x.bar = x;
|
||||||
|
return x;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_props: true,
|
||||||
|
join_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
foo: 1,
|
||||||
|
};
|
||||||
|
o.bar = 2;
|
||||||
|
o.baz = 3;
|
||||||
|
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(1, 4, 6);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 4 6"
|
||||||
|
}
|
||||||
|
|
||||||
|
join_object_assignments_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var o = {
|
||||||
|
a: "PASS",
|
||||||
|
}, a = o.a;
|
||||||
|
o.a = "FAIL";
|
||||||
|
return a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -293,3 +293,245 @@ unary: {
|
|||||||
bar();
|
bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2629_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a();
|
||||||
|
/*@__PURE__*/ (b());
|
||||||
|
(/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */c();",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ (d(1)(2)(3));
|
||||||
|
(/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */e(1)(2)(3);",
|
||||||
|
"/* */f(1)(2)(3);",
|
||||||
|
"/* */g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
||||||
|
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */h.x(1).y(2).z(3);",
|
||||||
|
"/* */i.x(1).y(2).z(3);",
|
||||||
|
"/* */j.x(1).y(2).z(3);",
|
||||||
|
"/* */k.x(1).y(2).z(3);",
|
||||||
|
"/* */l.x(1).y(2).z(3);",
|
||||||
|
"/* */m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_4: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ x(), y());
|
||||||
|
(w(), /*@__PURE__*/ x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_5: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ x() ];
|
||||||
|
[ /*@__PURE__*/ x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2638: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(g() || h())(x(), y());
|
||||||
|
(/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */x(),y();",
|
||||||
|
"/* */(a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a();
|
||||||
|
/*@__PURE__*/ (new b());
|
||||||
|
new (/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ new d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */c;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ new (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ new (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ new (d(1)(2)(3));
|
||||||
|
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ new f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ new g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ new h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */e(1)(2)(3);",
|
||||||
|
"/* */new f(1)(2)(3);",
|
||||||
|
"/* */new g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||||
|
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new/* */h.x(1).y(2).z(3);",
|
||||||
|
"/* */new/* */i.x(1).y(2).z(3);",
|
||||||
|
"/* */new j.x(1).y(2).z(3);",
|
||||||
|
"/* */new k.x(1).y(2).z(3);",
|
||||||
|
"/* */new l.x(1).y(2).z(3);",
|
||||||
|
"/* */new m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_4: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ new x(), y());
|
||||||
|
(w(), /*@__PURE__*/ new x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_5: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ new x() ];
|
||||||
|
[ /*@__PURE__*/ new x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_6: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/new (g() || h())(x(), y());
|
||||||
|
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/* */x(),y();",
|
||||||
|
"/* */new(/* */a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
strict: {
|
strict: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: false,
|
||||||
reduce_vars: false,
|
reduce_vars: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -30,6 +31,7 @@ strict: {
|
|||||||
strict_reduce_vars: {
|
strict_reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -58,6 +60,7 @@ strict_reduce_vars: {
|
|||||||
unsafe: {
|
unsafe: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
|
reduce_funcs: false,
|
||||||
reduce_vars: false,
|
reduce_vars: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -84,6 +87,7 @@ unsafe: {
|
|||||||
unsafe_reduce_vars: {
|
unsafe_reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -119,3 +123,574 @@ chained: {
|
|||||||
a.b.c;
|
a.b.c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impure_getter_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).a;
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).b;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).a;
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).b;
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
impure_getter_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
// will produce incorrect output because getter is not pure
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).a;
|
||||||
|
({
|
||||||
|
get a() {
|
||||||
|
console.log(1);
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}).b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2110_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
f.g = g;
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
return f.g = function() {
|
||||||
|
return this;
|
||||||
|
}, f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2110_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
f.g = g;
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
function f() {}
|
||||||
|
f.g = function() {
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
return f.g();
|
||||||
|
}
|
||||||
|
console.log(typeof f());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
1..foo += "";
|
||||||
|
if (1..foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_5: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
1..foo += "";
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_immutable_6: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("FAIL");
|
||||||
|
else console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
if (a.foo += "") console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
set_mutable_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a.foo += "";
|
||||||
|
if (a.foo) console.log("PASS");
|
||||||
|
else console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
return console.log(1), {
|
||||||
|
y: function() {
|
||||||
|
return console.log(2), {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++,
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_4: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
if (x().y().z) {
|
||||||
|
console.log(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
console.log(1);
|
||||||
|
return {
|
||||||
|
y: function() {
|
||||||
|
console.log(2);
|
||||||
|
return {
|
||||||
|
z: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
x().y().z++;
|
||||||
|
x().y().z && console.log(3);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_5: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313_6: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x().y++;
|
||||||
|
x().y;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x().y++;
|
||||||
|
x();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2678: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1, c = "FAIL";
|
||||||
|
(function f() {
|
||||||
|
(a-- && f()).p;
|
||||||
|
return {
|
||||||
|
get p() {
|
||||||
|
c = "PASS";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
536
test/compress/rename.js
Normal file
536
test/compress/rename.js
Normal file
@@ -0,0 +1,536 @@
|
|||||||
|
mangle_catch: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="FAIL";try{throw 1}catch(o){a="PASS"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_ie8: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="FAIL";try{throw 1}catch(args){a="PASS"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_var: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
var a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="FAIL";try{throw 1}catch(o){var a="PASS"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_var_ie8: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
var a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="FAIL";try{throw 1}catch(args){var a="PASS"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_ie8_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_var_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
var a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_var_ie8_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (args) {
|
||||||
|
var a = "PASS";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_1: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_1_ie8: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_1_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_1_ie8_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_2: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_2_ie8: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_2_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_catch_redef_2_ie8_toplevel: {
|
||||||
|
rename = true
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw "FAIL1";
|
||||||
|
} catch (a) {
|
||||||
|
var a = "FAIL2";
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2120_1: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (t) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (t) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2120_2: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
function_iife_catch: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (n) {
|
||||||
|
var a = 1;
|
||||||
|
console.log(n, a);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_iife_catch_ie8: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(n) {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (n) {
|
||||||
|
var a = 1;
|
||||||
|
console.log(n, a);
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||||
|
expect_stdout: "0 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_catch_catch: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = 0;
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (o) {
|
||||||
|
var o = 3;
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||||
|
expect_stdout: [
|
||||||
|
"3",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
function_catch_catch_ie8: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = 0;
|
||||||
|
function f() {
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 2;
|
||||||
|
} catch (o) {
|
||||||
|
var o = 3;
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
||||||
|
expect_stdout: [
|
||||||
|
"3",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -17,7 +17,6 @@ return_undefined: {
|
|||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
hoist_vars : true,
|
hoist_vars : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
cascade : true,
|
|
||||||
negate_iife : true
|
negate_iife : true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
@@ -122,3 +121,25 @@ return_undefined: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return_void: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
return g();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
h();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
14
test/compress/sandbox.js
Normal file
14
test/compress/sandbox.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
console_log: {
|
||||||
|
input: {
|
||||||
|
console.log("%% %s");
|
||||||
|
console.log("%% %s", "%s");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("%% %s");
|
||||||
|
console.log("%% %s", "%s");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"%% %s",
|
||||||
|
"% %s",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -187,6 +187,7 @@ dont_screw_try_catch_undefined: {
|
|||||||
reduce_vars: {
|
reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -255,3 +256,139 @@ issue_1586_2: {
|
|||||||
}
|
}
|
||||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2120_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (t) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (t) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2120_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"aaaaaaaa";
|
||||||
|
var a = 1, b = "FAIL";
|
||||||
|
try {
|
||||||
|
throw 1;
|
||||||
|
} catch (c) {
|
||||||
|
try {
|
||||||
|
throw 0;
|
||||||
|
} catch (a) {
|
||||||
|
if (c) b = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2254_1: {
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(e) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (t) {
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2254_2: {
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(s) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"eeeeee";
|
||||||
|
try {
|
||||||
|
console.log(f("PASS"));
|
||||||
|
} catch (e) {}
|
||||||
|
function f(t) {
|
||||||
|
try {
|
||||||
|
throw "FAIL";
|
||||||
|
} catch (e) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -176,6 +176,11 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
|
// 5
|
||||||
|
x = function() {
|
||||||
|
foo in bar;
|
||||||
|
};
|
||||||
|
for (y = 5; false;);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// 1
|
// 1
|
||||||
@@ -188,6 +193,10 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
|
// 5
|
||||||
|
for (x = function() {
|
||||||
|
foo in bar;
|
||||||
|
}, y = 5; false;);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,13 +252,12 @@ negate_iife_for: {
|
|||||||
input: {
|
input: {
|
||||||
(function() {})();
|
(function() {})();
|
||||||
for (i = 0; i < 5; i++) console.log(i);
|
for (i = 0; i < 5; i++) console.log(i);
|
||||||
|
|
||||||
(function() {})();
|
(function() {})();
|
||||||
for (; i < 5; i++) console.log(i);
|
for (; i < 10; i++) console.log(i);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
|
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
|
||||||
for (function() {}(); i < 5; i++) console.log(i);
|
for (!function() {}(); i < 10; i++) console.log(i);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -309,7 +317,7 @@ unsafe_undefined: {
|
|||||||
|
|
||||||
issue_1685: {
|
issue_1685: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -333,7 +341,7 @@ issue_1685: {
|
|||||||
|
|
||||||
func_def_1: {
|
func_def_1: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -353,7 +361,7 @@ func_def_1: {
|
|||||||
|
|
||||||
func_def_2: {
|
func_def_2: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -371,7 +379,7 @@ func_def_2: {
|
|||||||
|
|
||||||
func_def_3: {
|
func_def_3: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -393,7 +401,7 @@ func_def_3: {
|
|||||||
|
|
||||||
func_def_4: {
|
func_def_4: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -419,7 +427,7 @@ func_def_4: {
|
|||||||
|
|
||||||
func_def_5: {
|
func_def_5: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -626,7 +634,7 @@ side_effects: {
|
|||||||
|
|
||||||
side_effects_cascade_1: {
|
side_effects_cascade_1: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -647,7 +655,7 @@ side_effects_cascade_1: {
|
|||||||
|
|
||||||
side_effects_cascade_2: {
|
side_effects_cascade_2: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -669,7 +677,7 @@ side_effects_cascade_2: {
|
|||||||
|
|
||||||
side_effects_cascade_3: {
|
side_effects_cascade_3: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
@@ -684,14 +692,14 @@ side_effects_cascade_3: {
|
|||||||
expect: {
|
expect: {
|
||||||
function f(a, b) {
|
function f(a, b) {
|
||||||
!(b += a) && ((b = a) || (b -= a, b ^= a)),
|
!(b += a) && ((b = a) || (b -= a, b ^= a)),
|
||||||
--a;
|
a--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_27: {
|
issue_27: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
collapse_vars: true,
|
||||||
passes: 2,
|
passes: 2,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -710,3 +718,144 @@ issue_27: {
|
|||||||
})(jQuery);
|
})(jQuery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2062: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a || (a++, a--), a++, --a && a.var;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2313: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
a++;
|
||||||
|
return 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
this.c++;
|
||||||
|
if (this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var foo = {
|
||||||
|
get c() {
|
||||||
|
return a++, 42;
|
||||||
|
},
|
||||||
|
set c(c) {
|
||||||
|
b++;
|
||||||
|
},
|
||||||
|
d: function() {
|
||||||
|
if (this.c++, this.c) console.log(a, b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foo.d();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
cascade_assignment_in_return: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
return a = x(), b(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
return b(x());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_defun: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x();
|
||||||
|
function f() {}
|
||||||
|
y();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
x(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_decl: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x();
|
||||||
|
y();
|
||||||
|
for (var c; 0;) z();
|
||||||
|
var d;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
w();
|
||||||
|
var b = x(), c, d;
|
||||||
|
for (y(); 0;) z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_init_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
unused: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
var b = 42;
|
||||||
|
for (var c = 5; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
var a;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function() {
|
||||||
|
for (var b = 42, c = 5, a; c > 0;) c--;
|
||||||
|
a = "FAIL";
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,3 +8,12 @@ octal_escape_sequence: {
|
|||||||
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1929: {
|
||||||
|
input: {
|
||||||
|
function f(s) {
|
||||||
|
return s.split(/[\\/]/);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
|
||||||
|
}
|
||||||
|
|||||||
@@ -714,6 +714,7 @@ issue_1705_2: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -816,3 +817,50 @@ issue_1758: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "0 3"
|
expect_stdout: "0 3"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2535: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
dead_code: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
switch(w(), 42) {
|
||||||
|
case 13: x();
|
||||||
|
case 42: y();
|
||||||
|
default: z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
w(), 42;
|
||||||
|
42;
|
||||||
|
y();
|
||||||
|
z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1750: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
switches: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
switch (true) {
|
||||||
|
case a, true:
|
||||||
|
default:
|
||||||
|
b = 2;
|
||||||
|
case true:
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
true;
|
||||||
|
a, true;
|
||||||
|
b = 2;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "0 2"
|
||||||
|
}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ condition_evaluate: {
|
|||||||
if (void 0 == null);
|
if (void 0 == null);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
while (!1);
|
while (0);
|
||||||
for (; !0;);
|
for (; 1;);
|
||||||
if (!0);
|
if (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +68,7 @@ label_if_break: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
L: if (true) {
|
L: if (true) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
typeof_evaluation: {
|
typeof_evaluation: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true
|
evaluate: true,
|
||||||
|
typeofs: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a = typeof 1;
|
a = typeof 1;
|
||||||
@@ -44,7 +45,7 @@ typeof_in_boolean_context: {
|
|||||||
function f2() { return g(), "Yes"; }
|
function f2() { return g(), "Yes"; }
|
||||||
foo();
|
foo();
|
||||||
console.log(1);
|
console.log(1);
|
||||||
var a = !(console.log(2), !0);
|
var a = !(console.log(2), 1);
|
||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -57,6 +58,246 @@ issue_1668: {
|
|||||||
if (typeof bar);
|
if (typeof bar);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
if (!0);
|
if (1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typeof_defun_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log("YES");
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
h = 42;
|
||||||
|
console.log("NOPE");
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
console.log("YUP");
|
||||||
|
}
|
||||||
|
g = 42;
|
||||||
|
"function" == typeof f && f();
|
||||||
|
"function" == typeof g && g();
|
||||||
|
"function" == typeof h && h();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function g() {
|
||||||
|
h = 42;
|
||||||
|
console.log("NOPE");
|
||||||
|
}
|
||||||
|
function h() {
|
||||||
|
console.log("YUP");
|
||||||
|
}
|
||||||
|
g = 42;
|
||||||
|
console.log("YES");
|
||||||
|
"function" == typeof g && g();
|
||||||
|
"function" == typeof h && h();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"YES",
|
||||||
|
"YUP",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
typeof_defun_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function() {
|
||||||
|
console.log(x);
|
||||||
|
};
|
||||||
|
var x = 0;
|
||||||
|
x++ < 2 && typeof f == "function" && f();
|
||||||
|
x++ < 2 && typeof f == "function" && f();
|
||||||
|
x++ < 2 && typeof f == "function" && f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = function() {
|
||||||
|
console.log(x);
|
||||||
|
};
|
||||||
|
var x = 0;
|
||||||
|
x++ < 2 && f();
|
||||||
|
x++ < 2 && f();
|
||||||
|
x++ < 2 && f();
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1",
|
||||||
|
"2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_defun_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}
|
||||||
|
console.log(typeof long_name, long_name());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicate_lambda_arg_name: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function long_name(long_name) {
|
||||||
|
return typeof long_name;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments() {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function object"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log(typeof arguments);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function arguments(arguments) {
|
||||||
|
console.log(typeof arguments);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2728_6: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
typeofs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function arguments(arguments) {
|
||||||
|
return typeof arguments;
|
||||||
|
}
|
||||||
|
console.log(typeof arguments, arguments());
|
||||||
|
}
|
||||||
|
expect_stdout: "function undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,3 +15,50 @@ unicode_parse_variables: {
|
|||||||
var l০ = 3;
|
var l০ = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2242_1: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d","\\ude00","\ud83d\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_2: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d","\\ude00","\\ud83d\\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\\ud83d"+"\\ude00","\\ud83d"+"@"+"\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2242_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log("\ud83d\ude00","\\ud83d@\\ude00");'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2569: {
|
||||||
|
input: {
|
||||||
|
new RegExp("[\udc42-\udcaa\udd74-\udd96\ude45-\ude4f\udea3-\udecc]");
|
||||||
|
}
|
||||||
|
expect_exact: 'new RegExp("[\\udc42-\\udcaa\\udd74-\\udd96\\ude45-\\ude4f\\udea3-\\udecc]");'
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ exports["defaults"] = defaults;
|
|||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
|
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["is_identifier"] = is_identifier;
|
exports["is_identifier"] = is_identifier;
|
||||||
|
|||||||
31
test/fetch.js
Normal file
31
test/fetch.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
var fs = require("fs");
|
||||||
|
var path = require("path");
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync("./tmp");
|
||||||
|
} catch (e) {
|
||||||
|
if (e.code != "EEXIST") throw e;
|
||||||
|
}
|
||||||
|
|
||||||
|
function local(url) {
|
||||||
|
return path.join("./tmp", encodeURIComponent(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
function read(url) {
|
||||||
|
return fs.createReadStream(local(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(url, callback) {
|
||||||
|
var result = read(url);
|
||||||
|
result.on("error", function(e) {
|
||||||
|
if (e.code != "ENOENT") return callback(e);
|
||||||
|
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||||
|
if (res.statusCode !== 200) return callback(res);
|
||||||
|
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
||||||
|
callback(null, read(url));
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
}).on("open", function() {
|
||||||
|
callback(null, result);
|
||||||
|
});
|
||||||
|
};
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
function f() {
|
|
||||||
const a;
|
|
||||||
}
|
|
||||||
|
|
||||||
function g() {
|
|
||||||
"use strict";
|
|
||||||
const a;
|
|
||||||
}
|
|
||||||
1
test/input/invalid/else.js
Normal file
1
test/input/invalid/else.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
if (0) else 1;
|
||||||
4
test/input/invalid/for-in_1.js
Normal file
4
test/input/invalid/for-in_1.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var a, b = [1, 2];
|
||||||
|
for (1, 2, a in b) {
|
||||||
|
console.log(a, b[a]);
|
||||||
|
}
|
||||||
4
test/input/invalid/for-in_2.js
Normal file
4
test/input/invalid/for-in_2.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
var c = [1, 2];
|
||||||
|
for (var a, b in c) {
|
||||||
|
console.log(a, c[a]);
|
||||||
|
}
|
||||||
1
test/input/invalid/return.js
Normal file
1
test/input/invalid/return.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
return 42;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
var a = bar(1+2);
|
var x = bar(1+2);
|
||||||
var b = baz(3+9);
|
var y = baz(3+9);
|
||||||
print('q' + 'u' + 'x', a, b);
|
print('q' + 'u' + 'x', x, y);
|
||||||
foo(5+6);
|
foo(5+6);
|
||||||
|
|||||||
1
test/input/issue-2082/sample.js
Normal file
1
test/input/issue-2082/sample.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log(x);
|
||||||
1
test/input/issue-2082/sample.js.map
Normal file
1
test/input/issue-2082/sample.js.map
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"version": 3,"sources": ["index.js"],"mappings": ";"}
|
||||||
10
test/input/issue-2310/input.js
Normal file
10
test/input/issue-2310/input.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
function foo() {
|
||||||
|
return function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var f = foo();
|
||||||
|
f();
|
||||||
|
})();
|
||||||
5
test/input/issue-505/input.js
Normal file
5
test/input/issue-505/input.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
function test(callback) {
|
||||||
|
'aaaaaaaaaaaaaaaa';
|
||||||
|
callback(err, data);
|
||||||
|
callback(err, data);
|
||||||
|
}
|
||||||
5
test/input/issue-505/output.js
Normal file
5
test/input/issue-505/output.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
function test(a){
|
||||||
|
"aaaaaaaaaaaaaaaa"
|
||||||
|
;a(err,data),a(err,data)
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7QUFDVjtDQUNBQSxFQUFTQyxJQUFLQyxNQUNkRixFQUFTQyxJQUFLQyJ9
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
new function(){console.log(3)};
|
new function(){console.log(3)};
|
||||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxHQUFyQyxZQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUErQyxJQUFyQyxXQUFnQkEsUUFBUUMsSUFBSSIsInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl19
|
||||||
|
|||||||
@@ -3,53 +3,73 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var site = "http://browserbench.org/JetStream/";
|
var site = "http://browserbench.org/JetStream";
|
||||||
if (typeof phantom == "undefined") {
|
if (typeof phantom == "undefined") {
|
||||||
// workaround for tty output truncation upon process.exit()
|
require("../tools/exit");
|
||||||
[process.stdout, process.stderr].forEach(function(stream){
|
|
||||||
if (stream._handle && stream._handle.setBlocking)
|
|
||||||
stream._handle.setBlocking(true);
|
|
||||||
});
|
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
|
var debug = args.indexOf("--debug");
|
||||||
|
if (debug >= 0) {
|
||||||
|
args.splice(debug, 1);
|
||||||
|
debug = true;
|
||||||
|
} else {
|
||||||
|
debug = false;
|
||||||
|
}
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc");
|
args.push("-mcb", "beautify=false,webkit");
|
||||||
}
|
}
|
||||||
args.push("--stats");
|
args.push("--timings");
|
||||||
var child_process = require("child_process");
|
var child_process = require("child_process");
|
||||||
try {
|
var fetch = require("./fetch");
|
||||||
require("phantomjs-prebuilt");
|
|
||||||
} catch(e) {
|
|
||||||
child_process.execSync("npm install phantomjs-prebuilt@2.1.14");
|
|
||||||
}
|
|
||||||
var http = require("http");
|
var http = require("http");
|
||||||
var server = http.createServer(function(request, response) {
|
var server = http.createServer(function(request, response) {
|
||||||
request.resume();
|
request.resume();
|
||||||
var url = decodeURIComponent(request.url.slice(1));
|
var url = site + request.url;
|
||||||
var stderr = "";
|
fetch(url, function(err, res) {
|
||||||
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
if (err) throw err;
|
||||||
silent: true
|
response.writeHead(200, {
|
||||||
}).on("exit", function(code) {
|
"Content-Type": {
|
||||||
console.log("uglifyjs", url.indexOf(site) == 0 ? url.slice(site.length) : url, args.join(" "));
|
css: "text/css",
|
||||||
console.log(stderr);
|
js: "application/javascript",
|
||||||
if (code) throw new Error("uglifyjs failed with code " + code);
|
png: "image/png"
|
||||||
});
|
}[url.slice(url.lastIndexOf(".") + 1)] || "text/html; charset=utf-8"
|
||||||
uglifyjs.stderr.on("data", function(data) {
|
});
|
||||||
stderr += data;
|
if (/\.js$/.test(url)) {
|
||||||
}).setEncoding("utf8");
|
var stderr = "";
|
||||||
uglifyjs.stdout.pipe(response);
|
var uglifyjs = child_process.fork("bin/uglifyjs", args, {
|
||||||
http.get(url, function(res) {
|
silent: true
|
||||||
res.pipe(uglifyjs.stdin);
|
}).on("exit", function(code) {
|
||||||
});
|
console.log("uglifyjs", url.slice(site.length + 1), args.join(" "));
|
||||||
}).listen().on("listening", function() {
|
console.log(stderr);
|
||||||
var phantomjs = require("phantomjs-prebuilt");
|
if (code) throw new Error("uglifyjs failed with code " + code);
|
||||||
var program = phantomjs.exec(process.argv[1], server.address().port);
|
});
|
||||||
program.stdout.pipe(process.stdout);
|
uglifyjs.stderr.on("data", function(data) {
|
||||||
program.stderr.pipe(process.stderr);
|
stderr += data;
|
||||||
program.on("exit", function(code) {
|
}).setEncoding("utf8");
|
||||||
server.close();
|
uglifyjs.stdout.pipe(response);
|
||||||
if (code) throw new Error("JetStream failed!");
|
res.pipe(uglifyjs.stdin);
|
||||||
console.log("JetStream completed successfully.");
|
} else {
|
||||||
|
res.pipe(response);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
}).listen();
|
||||||
|
server.on("listening", function() {
|
||||||
|
var port = server.address().port;
|
||||||
|
if (debug) {
|
||||||
|
console.log("http://localhost:" + port + "/");
|
||||||
|
} else {
|
||||||
|
child_process.exec("npm install phantomjs-prebuilt@2.1.14 --no-save", function(error) {
|
||||||
|
if (error) throw error;
|
||||||
|
var program = require("phantomjs-prebuilt").exec(process.argv[1], port);
|
||||||
|
program.stdout.pipe(process.stdout);
|
||||||
|
program.stderr.pipe(process.stderr);
|
||||||
|
program.on("exit", function(code) {
|
||||||
|
server.close();
|
||||||
|
if (code) throw new Error("JetStream failed!");
|
||||||
|
console.log("JetStream completed successfully.");
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
server.timeout = 0;
|
server.timeout = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -63,10 +83,6 @@ if (typeof phantom == "undefined") {
|
|||||||
phantom.exit(1);
|
phantom.exit(1);
|
||||||
};
|
};
|
||||||
var url = "http://localhost:" + require("system").args[1] + "/";
|
var url = "http://localhost:" + require("system").args[1] + "/";
|
||||||
page.onResourceRequested = function(requestData, networkRequest) {
|
|
||||||
if (/\.js$/.test(requestData.url))
|
|
||||||
networkRequest.changeUrl(url + encodeURIComponent(requestData.url));
|
|
||||||
}
|
|
||||||
page.onConsoleMessage = function(msg) {
|
page.onConsoleMessage = function(msg) {
|
||||||
if (/Error:/i.test(msg)) {
|
if (/Error:/i.test(msg)) {
|
||||||
console.error(msg);
|
console.error(msg);
|
||||||
@@ -77,8 +93,8 @@ if (typeof phantom == "undefined") {
|
|||||||
phantom.exit();
|
phantom.exit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
page.open(site, function(status) {
|
page.open(url, function(status) {
|
||||||
if (status != "success") phantomjs.exit(1);
|
if (status != "success") phantom.exit(1);
|
||||||
page.evaluate(function() {
|
page.evaluate(function() {
|
||||||
JetStream.switchToQuick();
|
JetStream.switchToQuick();
|
||||||
JetStream.start();
|
JetStream.start();
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe("Accessor tokens", function() {
|
|||||||
assert.equal(node.start.pos, 12);
|
assert.equal(node.start.pos, 12);
|
||||||
assert.equal(node.end.endpos, 46);
|
assert.equal(node.end.endpos, 46);
|
||||||
|
|
||||||
assert(node.key instanceof UglifyJS.AST_SymbolRef);
|
assert(node.key instanceof UglifyJS.AST_SymbolAccessor);
|
||||||
assert.equal(node.key.start.pos, 16);
|
assert.equal(node.key.start.pos, 16);
|
||||||
assert.equal(node.key.end.endpos, 22);
|
assert.equal(node.key.end.endpos, 22);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ function read(path) {
|
|||||||
describe("bin/uglifyjs", function () {
|
describe("bin/uglifyjs", function () {
|
||||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||||
it("should produce a functional build when using --self", function (done) {
|
it("should produce a functional build when using --self", function (done) {
|
||||||
this.timeout(15000);
|
this.timeout(30000);
|
||||||
|
|
||||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||||
|
|
||||||
@@ -19,7 +19,9 @@ describe("bin/uglifyjs", function () {
|
|||||||
eval(stdout);
|
eval(stdout);
|
||||||
|
|
||||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||||
assert.strictEqual(WrappedUglifyJS.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
var result = WrappedUglifyJS.minify("foo([true,,2+3]);");
|
||||||
|
assert.strictEqual(result.error, undefined);
|
||||||
|
assert.strictEqual(result.code, "foo([!0,,5]);");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -55,15 +57,15 @@ describe("bin/uglifyjs", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should append source map to output when using --source-map url=inline", function (done) {
|
it("Should append source map to output when using --source-map url=inline", function (done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
assert.strictEqual(stdout, "var bar=function(){function foo(bar){return bar}return foo}();\n" +
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not append source map to output when not using --source-map url=inline", function (done) {
|
it("should not append source map to output when not using --source-map url=inline", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
var command = uglifyjscmd + ' test/input/issue-1323/sample.js';
|
||||||
@@ -75,85 +77,102 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("should not consider source map file content as source map file name (issue #2082)", function (done) {
|
||||||
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-2082/sample.js",
|
||||||
|
"--source-map", "content=test/input/issue-2082/sample.js.map",
|
||||||
|
"--source-map", "url=inline",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
var stderrLines = stderr.split('\n');
|
||||||
|
assert.strictEqual(stderrLines[0], 'INFO: Using input source map: test/input/issue-2082/sample.js.map');
|
||||||
|
assert.notStrictEqual(stderrLines[1], 'INFO: Using input source map: {"version": 3,"sources": ["index.js"],"mappings": ";"}');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should work with --keep-fnames (mangle only)", function (done) {
|
it("Should work with --keep-fnames (mangle only)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --keep-fnames (mangle & compress)", function (done) {
|
it("Should work with --keep-fnames (mangle & compress)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with keep_fnames under mangler options", function (done) {
|
it("Should work with keep_fnames under mangler options", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
|
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fnames=true';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(f(g)()==5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (simple)", function (done) {
|
it("Should work with --define (simple)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(5);\n");
|
assert.strictEqual(stdout, "console.log(5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (nested)", function (done) {
|
it("Should work with --define (nested)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
|
var command = uglifyjscmd + ' test/input/global_defs/nested.js --define C.D=5,C.V=3 -c';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(3,5);\n");
|
assert.strictEqual(stdout, "console.log(3,5);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with --define (AST_Node)", function (done) {
|
it("Should work with --define (AST_Node)", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
|
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define console.log=stdout.println -c';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, "stdout.println(D);\n");
|
assert.strictEqual(stdout, "stdout.println(D);\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with `--beautify`", function (done) {
|
it("Should work with `--beautify`", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should work with `--beautify bracketize`", function (done) {
|
it("Should work with `--beautify bracketize`", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, read("test/input/issue-1482/bracketize.js"));
|
assert.strictEqual(stdout, read("test/input/issue-1482/bracketize.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should process inline source map", function(done) {
|
it("Should process inline source map", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/issue-520/input.js -mc toplevel --source-map content=inline,url=inline";
|
var command = uglifyjscmd + " test/input/issue-520/input.js -mc toplevel --source-map content=inline,url=inline";
|
||||||
@@ -173,7 +192,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||||
"",
|
"",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
||||||
@@ -260,229 +279,274 @@ describe("bin/uglifyjs", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (5--)", function(done) {
|
it("Should throw syntax error (5--)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_1.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/assign_1.js:1,18",
|
"Parse error at test/input/invalid/assign_1.js:1,18",
|
||||||
"console.log(1 || 5--);",
|
"console.log(1 || 5--);",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid use of -- operator"
|
"ERROR: Invalid use of -- operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (Math.random() /= 2)", function(done) {
|
it("Should throw syntax error (Math.random() /= 2)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_2.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/assign_2.js:1,32",
|
"Parse error at test/input/invalid/assign_2.js:1,32",
|
||||||
"console.log(2 || (Math.random() /= 2));",
|
"console.log(2 || (Math.random() /= 2));",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid assignment"
|
"ERROR: Invalid assignment"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (++this)", function(done) {
|
it("Should throw syntax error (++this)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_3.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/assign_3.js:1,17",
|
"Parse error at test/input/invalid/assign_3.js:1,17",
|
||||||
"console.log(3 || ++this);",
|
"console.log(3 || ++this);",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid use of ++ operator"
|
"ERROR: Invalid use of ++ operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (++null)", function(done) {
|
it("Should throw syntax error (++null)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
|
var command = uglifyjscmd + ' test/input/invalid/assign_4.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/assign_4.js:1,0",
|
"Parse error at test/input/invalid/assign_4.js:1,0",
|
||||||
"++null",
|
"++null",
|
||||||
"^",
|
"^",
|
||||||
"ERROR: Invalid use of ++ operator"
|
"ERROR: Invalid use of ++ operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (a.=)", function(done) {
|
it("Should throw syntax error (a.=)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_1.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/dot_1.js:1,2",
|
"Parse error at test/input/invalid/dot_1.js:1,2",
|
||||||
"a.=",
|
"a.=",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (=)"
|
"ERROR: Unexpected token: operator (=)"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (%.a)", function(done) {
|
it("Should throw syntax error (%.a)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_2.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/dot_2.js:1,0",
|
"Parse error at test/input/invalid/dot_2.js:1,0",
|
||||||
"%.a;",
|
"%.a;",
|
||||||
"^",
|
"^",
|
||||||
"ERROR: Unexpected token: operator (%)"
|
"ERROR: Unexpected token: operator (%)"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (a./();)", function(done) {
|
it("Should throw syntax error (a./();)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/dot_3.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/dot_3.js:1,2",
|
"Parse error at test/input/invalid/dot_3.js:1,2",
|
||||||
"a./();",
|
"a./();",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (/)"
|
"ERROR: Unexpected token: operator (/)"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error ({%: 1})", function(done) {
|
it("Should throw syntax error ({%: 1})", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/object.js';
|
var command = uglifyjscmd + ' test/input/invalid/object.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/object.js:1,13",
|
"Parse error at test/input/invalid/object.js:1,13",
|
||||||
"console.log({%: 1});",
|
"console.log({%: 1});",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator (%)"
|
"ERROR: Unexpected token: operator (%)"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
|
||||||
it("Should throw syntax error (const a)", function(done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/invalid/const.js';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
|
||||||
assert.ok(err);
|
|
||||||
assert.strictEqual(stdout, "");
|
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
|
||||||
"Parse error at test/input/invalid/const.js:7,11",
|
|
||||||
" const a;",
|
|
||||||
" ^",
|
|
||||||
"ERROR: Missing initializer in const declaration"
|
|
||||||
].join("\n"));
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (delete x)", function(done) {
|
it("Should throw syntax error (delete x)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/delete.js';
|
var command = uglifyjscmd + ' test/input/invalid/delete.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/delete.js:13,11",
|
"Parse error at test/input/invalid/delete.js:13,11",
|
||||||
" delete x;",
|
" delete x;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Calling delete on expression not allowed in strict mode"
|
"ERROR: Calling delete on expression not allowed in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (function g(arguments))", function(done) {
|
it("Should throw syntax error (function g(arguments))", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_1.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/function_1.js:4,11",
|
"Parse error at test/input/invalid/function_1.js:4,11",
|
||||||
"function g(arguments) {",
|
"function g(arguments) {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected arguments in strict mode"
|
"ERROR: Unexpected arguments in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (function eval())", function(done) {
|
it("Should throw syntax error (function eval())", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_2.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/function_2.js:4,9",
|
"Parse error at test/input/invalid/function_2.js:4,9",
|
||||||
"function eval() {",
|
"function eval() {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (iife arguments())", function(done) {
|
it("Should throw syntax error (iife arguments())", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
|
var command = uglifyjscmd + ' test/input/invalid/function_3.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/function_3.js:4,10",
|
"Parse error at test/input/invalid/function_3.js:4,10",
|
||||||
"!function arguments() {",
|
"!function arguments() {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected arguments in strict mode"
|
"ERROR: Unexpected arguments in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (catch(eval))", function(done) {
|
it("Should throw syntax error (catch(eval))", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/try.js';
|
var command = uglifyjscmd + ' test/input/invalid/try.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/try.js:7,18",
|
"Parse error at test/input/invalid/try.js:7,18",
|
||||||
" try {} catch (eval) {}",
|
" try {} catch (eval) {}",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (var eval)", function(done) {
|
it("Should throw syntax error (var eval)", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/invalid/var.js';
|
var command = uglifyjscmd + ' test/input/invalid/var.js';
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/var.js:7,8",
|
"Parse error at test/input/invalid/var.js:7,8",
|
||||||
" var eval;",
|
" var eval;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (else)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/else.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/else.js:1,7",
|
||||||
|
"if (0) else 1;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: keyword (else)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (return)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/return.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/return.js:1,0",
|
||||||
|
"return 42;",
|
||||||
|
"^",
|
||||||
|
"ERROR: 'return' outside of function"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in init)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_1.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-in_1.js:2,5",
|
||||||
|
"for (1, 2, a in b) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid left-hand side in for..in loop"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-in var)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/for-in_2.js';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-in_2.js:2,5",
|
||||||
|
"for (var a, b in c) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Only one variable declaration allowed in for..in loop"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
it("Should handle literal string as source map input", function(done) {
|
it("Should handle literal string as source map input", function(done) {
|
||||||
var command = [
|
var command = [
|
||||||
@@ -497,7 +561,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
|
|
||||||
assert.strictEqual(stdout, [
|
assert.strictEqual(stdout, [
|
||||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiWUFBQSxJQUFJQSxLQUFNLFFBQU5BLEtBQU1DLEdBQUEsTUFBSyxPQUFTQSxFQUN4QkMsU0FBUUMsSUFBSUgsSUFBSSJ9",
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||||
""
|
""
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
@@ -509,6 +573,25 @@ describe("bin/uglifyjs", function () {
|
|||||||
return JSON.stringify(map).replace(/"/g, '\\"');
|
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should include function calls in source map", function(done) {
|
||||||
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-2310/input.js",
|
||||||
|
"-c",
|
||||||
|
"--source-map", "url=inline",
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||||
|
""
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
it("Should dump AST as JSON", function(done) {
|
it("Should dump AST as JSON", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
@@ -520,4 +603,51 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it("Should print supported options on invalid option syntax", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/comments/filter.js -b ascii-only";
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `ascii-only` is not a supported option/.test(stderr), stderr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with --mangle reserved=[]", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=[callback]";
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, 'function test(callback){"aaaaaaaaaaaaaaaa";callback(err,data);callback(err,data)}\n');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with --mangle reserved=false", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js -m reserved=false";
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, 'function test(a){"aaaaaaaaaaaaaaaa";a(err,data);a(err,data)}\n');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should fail with --mangle-props reserved=[in]", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js --mangle-props reserved=[in]";
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.ok(/^Supported options:\n[\s\S]*?\nERROR: `reserved=\[in]` is not a supported option/.test(stderr), stderr);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should fail with --define a-b", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/issue-505/input.js --define a-b";
|
||||||
|
exec(command, function (err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr, "Error parsing arguments for 'define': a-b\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user