Compare commits
324 Commits
v2.8.23
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f751e64d49 | ||
|
|
60c56a24b9 | ||
|
|
c88139492d | ||
|
|
cb45886512 | ||
|
|
01f23cf5a1 | ||
|
|
99fb3e8f0d | ||
|
|
050474ab44 | ||
|
|
f6c805ae1d | ||
|
|
9464d3c20f | ||
|
|
f18abd1b9c | ||
|
|
3be06ad085 | ||
|
|
265008c948 | ||
|
|
756c9aa7dc | ||
|
|
07d6bfd707 | ||
|
|
81243c4e71 | ||
|
|
cd6e849555 | ||
|
|
ff526be61d | ||
|
|
e005099fb1 | ||
|
|
504a436e9d | ||
|
|
3ca902258c | ||
|
|
91de285166 | ||
|
|
4d8f289eb0 | ||
|
|
fd0951231c | ||
|
|
9e29b6dad2 | ||
|
|
c391576d52 | ||
|
|
ac73c5d421 | ||
|
|
547f41beba | ||
|
|
945ba64160 | ||
|
|
c699200398 | ||
|
|
daf44f2b21 | ||
|
|
daaefc17b9 | ||
|
|
1d407e761e | ||
|
|
2b44f4ae30 | ||
|
|
e51c3541da | ||
|
|
3bf194684b | ||
|
|
fcd90db30d | ||
|
|
e2888bdc43 | ||
|
|
fb50b7b627 | ||
|
|
aae7d49d0c | ||
|
|
9d59c693c2 | ||
|
|
0459af2ecc | ||
|
|
04f2344efc | ||
|
|
6ddb5bd94d | ||
|
|
bad9d5cf88 | ||
|
|
eda49605c5 | ||
|
|
a0f5f862df | ||
|
|
1e9ef17e32 | ||
|
|
41996be86f | ||
|
|
222100ea4c | ||
|
|
5fd8244a2e | ||
|
|
93db48a317 | ||
|
|
2944e3df7d | ||
|
|
c14e280585 | ||
|
|
bc3fa78e8c | ||
|
|
8c7c107765 | ||
|
|
e0ae8da089 | ||
|
|
81f1311b24 | ||
|
|
2433bb4e52 | ||
|
|
3dd328dce3 | ||
|
|
014f428153 | ||
|
|
a3b2eb75bd | ||
|
|
da295de82b | ||
|
|
4f8ca4626e | ||
|
|
e54748365c | ||
|
|
3fac29a017 | ||
|
|
b4c18f6b83 | ||
|
|
2d99d06601 | ||
|
|
98cf95e5b5 | ||
|
|
7313465cba | ||
|
|
2c7ee956fd | ||
|
|
ecf3563c45 | ||
|
|
dee5a27516 | ||
|
|
5a25d24b56 | ||
|
|
bffdc8dca8 | ||
|
|
69b5663653 | ||
|
|
ea9289771b | ||
|
|
2cb55b2ad0 | ||
|
|
73d6438773 | ||
|
|
5c6316a37d | ||
|
|
bbb5f2a89c | ||
|
|
76d19b60ad | ||
|
|
9e62628171 | ||
|
|
9bf72cf758 | ||
|
|
64d74432f6 | ||
|
|
45ce369480 | ||
|
|
ca32a09032 | ||
|
|
6f954aa3d0 | ||
|
|
f05d4f7af3 | ||
|
|
88e7a542cd | ||
|
|
4dcff038cb | ||
|
|
b4b9305db0 | ||
|
|
28cfb65c47 | ||
|
|
0f4f01b66c | ||
|
|
5d9f1da3ab | ||
|
|
d1aa09c5c7 | ||
|
|
6d5f341999 | ||
|
|
4ffb6fce76 | ||
|
|
71a8d0d236 | ||
|
|
1a498db2d3 | ||
|
|
44dfa5a318 | ||
|
|
251ff1d1af | ||
|
|
ec443e422c | ||
|
|
32deb365d5 | ||
|
|
2244743545 | ||
|
|
278577f3cb | ||
|
|
0d8597e904 | ||
|
|
c20bb99a62 | ||
|
|
2377171200 | ||
|
|
603d92effc | ||
|
|
17f0cc359f | ||
|
|
35bae3fcd0 | ||
|
|
4614b5b46e | ||
|
|
2f93058c6e | ||
|
|
a729c43e87 | ||
|
|
66e9039350 | ||
|
|
d717bf9ce8 | ||
|
|
5dea52266b | ||
|
|
fccefbeaca | ||
|
|
1e2b0aaa04 | ||
|
|
6a54de79b5 | ||
|
|
9e2290b29c | ||
|
|
97d0fc271d | ||
|
|
7906033e82 | ||
|
|
4bf21ce5c1 | ||
|
|
44d6b47bdc | ||
|
|
129e449c8e | ||
|
|
75c3c8963f | ||
|
|
d26b7522d9 | ||
|
|
2fd86d3cb0 | ||
|
|
8f7ab602e2 | ||
|
|
1dd339f95e | ||
|
|
c7063c1f38 | ||
|
|
f4a12b34f2 | ||
|
|
5d5c7934a5 | ||
|
|
8f4b45f4f8 | ||
|
|
952e2656eb | ||
|
|
240383a314 | ||
|
|
250b782b1e | ||
|
|
3c2b3aeddb | ||
|
|
aa605495f8 | ||
|
|
33a26d456b | ||
|
|
49d9ac1c43 | ||
|
|
c8e61448cb | ||
|
|
f704e9b65c | ||
|
|
0b77d861a8 | ||
|
|
e27dab7e7c | ||
|
|
80f3ad3ce0 | ||
|
|
22f7af205d | ||
|
|
8a7a4749c7 | ||
|
|
514fc68f4f | ||
|
|
478aaab469 | ||
|
|
ab217539e9 | ||
|
|
a942dc07c4 | ||
|
|
a0eaff750d | ||
|
|
57777b6cfa | ||
|
|
8d205f7f39 | ||
|
|
bc9bfd15a2 | ||
|
|
9fc1c4b3b5 | ||
|
|
c59bf5e8d8 | ||
|
|
d2d3a6e065 | ||
|
|
7755733716 | ||
|
|
b3a987b0df | ||
|
|
88a338f29e | ||
|
|
07734b000a | ||
|
|
85c1cba760 | ||
|
|
4bd31607f6 | ||
|
|
4728bc73ad | ||
|
|
52ce9a333c | ||
|
|
abbeb266b5 | ||
|
|
b11c5151bc | ||
|
|
962b1f3d40 | ||
|
|
3ee46e91e8 | ||
|
|
ee26e7f11b | ||
|
|
937f534392 | ||
|
|
1b2c02c944 | ||
|
|
0aa526e72c | ||
|
|
c2112d5886 | ||
|
|
5f6825f9ec | ||
|
|
7e80a979a7 | ||
|
|
b7bb706150 | ||
|
|
32c2cc33bb | ||
|
|
947b8750e8 | ||
|
|
88f6ff38d1 | ||
|
|
4198095a9c | ||
|
|
13ed445607 | ||
|
|
1db50c3b16 | ||
|
|
7f6b5d662b | ||
|
|
1c15d0db45 | ||
|
|
67461666dc | ||
|
|
45d81f881b | ||
|
|
8c7d23dfb1 | ||
|
|
7fa0dbdeb9 | ||
|
|
c644c1292d | ||
|
|
d224d71b8d | ||
|
|
27d3669800 | ||
|
|
110a1ac885 | ||
|
|
3f8fc3a316 | ||
|
|
88384cf351 | ||
|
|
72a9d799b6 | ||
|
|
766fafda8b | ||
|
|
842ac27efb | ||
|
|
0af42d1831 | ||
|
|
ff7f6139ba | ||
|
|
0db7caf13b | ||
|
|
d9bc6f303c | ||
|
|
6fd9b338dd | ||
|
|
d8d4e71b9e | ||
|
|
fb2f8d1a51 | ||
|
|
54a783ba84 | ||
|
|
63c432f4fa | ||
|
|
07785d0003 | ||
|
|
6eaeb19a4a | ||
|
|
2246c79318 | ||
|
|
dda58244b6 | ||
|
|
ca04508cd1 | ||
|
|
6b03b800b3 | ||
|
|
f9cab7ad61 | ||
|
|
0a3d780327 | ||
|
|
b0555a123a | ||
|
|
fa29344781 | ||
|
|
dcfc514c38 | ||
|
|
8ad8d7b717 | ||
|
|
0357e5923f | ||
|
|
f63803e3e3 | ||
|
|
63be1f3a4d | ||
|
|
e36e07fa77 | ||
|
|
d1b4f61f93 | ||
|
|
5b893c8ec3 | ||
|
|
8571a08a93 | ||
|
|
68cc14f846 | ||
|
|
f94497d1d6 | ||
|
|
eaf3911c31 | ||
|
|
91cdb93e57 | ||
|
|
634f231b78 | ||
|
|
6702cae918 | ||
|
|
6d2f77c180 | ||
|
|
accca2445f | ||
|
|
0bc4f6edb4 | ||
|
|
ce84a706a3 | ||
|
|
86b5248837 | ||
|
|
59e1601fb8 | ||
|
|
d35a9e7839 | ||
|
|
0465bd270d | ||
|
|
6780d0906c | ||
|
|
0b303379c0 | ||
|
|
d7ec2ecc12 | ||
|
|
2827fa8699 | ||
|
|
c80ec625ec | ||
|
|
5e78f20f1c | ||
|
|
1f75232062 | ||
|
|
028ff64e9a | ||
|
|
7a8cffd631 | ||
|
|
5b553aafe2 | ||
|
|
084437bc6d | ||
|
|
1cd9a2df9a | ||
|
|
7f3dbb6df7 | ||
|
|
e4d73d8b7c | ||
|
|
8220dbbea0 | ||
|
|
59e999597e | ||
|
|
cbcb3ac44e | ||
|
|
f07ab4666f | ||
|
|
a800356ad0 | ||
|
|
e076abdbf2 | ||
|
|
425613b0d2 | ||
|
|
69da8e53e0 | ||
|
|
bb6b3a773a | ||
|
|
364d20f8fb | ||
|
|
392ac4ff31 | ||
|
|
9ffed2bea6 | ||
|
|
5f7cb6939c | ||
|
|
64e7a00399 | ||
|
|
c99eaae360 | ||
|
|
34213ea2f8 | ||
|
|
da8c428a07 | ||
|
|
0d8dea9538 | ||
|
|
2babe737e0 | ||
|
|
2cce61c564 | ||
|
|
246ec416c0 | ||
|
|
6be9c752d5 | ||
|
|
76ed083e47 | ||
|
|
b31918bbf0 | ||
|
|
b14496c742 | ||
|
|
991fa99655 | ||
|
|
3d7f73114d | ||
|
|
dde9e293df | ||
|
|
34685a6f55 | ||
|
|
9812c826e0 | ||
|
|
2fac2bbfe4 | ||
|
|
242c61be94 | ||
|
|
e1cb1a0e3c | ||
|
|
af22b9c657 | ||
|
|
adee5023c0 | ||
|
|
7ee8f3512e | ||
|
|
dc5db9b6ca | ||
|
|
079aaa0d48 | ||
|
|
d4f17f29ae | ||
|
|
e99bc914ca | ||
|
|
025d34bfa2 | ||
|
|
c44c2d6c21 | ||
|
|
824ecfb8a2 | ||
|
|
ceebc466b9 | ||
|
|
35b31bdd4e | ||
|
|
c8b82583d2 | ||
|
|
9f9179ba1a | ||
|
|
872231a0ca | ||
|
|
36420183fd | ||
|
|
a8f8aa518b | ||
|
|
4c12cccff9 | ||
|
|
dcce4e5c66 | ||
|
|
56c0b834d6 | ||
|
|
6f864402d3 | ||
|
|
8909e9e1cb | ||
|
|
e80ed38772 | ||
|
|
9863f0efa3 | ||
|
|
e8664e63ef | ||
|
|
ddd30eeaaa | ||
|
|
a68953c491 | ||
|
|
fa5c4f2d03 | ||
|
|
9d7d365c2b | ||
|
|
ad344c5be3 | ||
|
|
96b89e34a3 | ||
|
|
4644becb9b | ||
|
|
f7460166dd | ||
|
|
32f76f7ff8 |
25
.github/ISSUE_TEMPLATE.md
vendored
25
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,9 +1,20 @@
|
|||||||
- Bug report or feature request? <!-- Note: sub-optimal but correct code is not a bug -->
|
**Bug report or feature request?**
|
||||||
- `uglify-js` version (`uglifyjs -V`)
|
|
||||||
- JavaScript input - ideally as small as possible.
|
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||||
- The `uglifyjs` CLI command executed or `minify()` options used.
|
|
||||||
- An example of JavaScript output produced and/or the error or warning.
|
**ES5 or ES6+ input?**
|
||||||
|
|
||||||
|
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||||
|
|
||||||
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
|
**JavaScript input** <!-- ideally as small as possible -->
|
||||||
|
|
||||||
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
|
**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,5 +1,4 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
before_install: "npm install -g npm"
|
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.12"
|
- "0.12"
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
#! /usr/bin/env node
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
var U2 = require("../tools/node");
|
|
||||||
var fs = require("fs");
|
|
||||||
var yargs = require("yargs");
|
|
||||||
var ARGS = yargs
|
|
||||||
.describe("o", "Output file")
|
|
||||||
.argv;
|
|
||||||
var files = ARGS._.slice();
|
|
||||||
var output = {
|
|
||||||
vars: {},
|
|
||||||
props: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ARGS.o) try {
|
|
||||||
output = JSON.parse(fs.readFileSync(ARGS.o, "utf8"));
|
|
||||||
} catch(ex) {}
|
|
||||||
|
|
||||||
files.forEach(getProps);
|
|
||||||
|
|
||||||
if (ARGS.o) {
|
|
||||||
fs.writeFileSync(ARGS.o, JSON.stringify(output, null, 2), "utf8");
|
|
||||||
} else {
|
|
||||||
console.log("%s", JSON.stringify(output, null, 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function getProps(filename) {
|
|
||||||
var code = fs.readFileSync(filename, "utf8");
|
|
||||||
var ast = U2.parse(code);
|
|
||||||
|
|
||||||
ast.walk(new U2.TreeWalker(function(node){
|
|
||||||
if (node instanceof U2.AST_ObjectKeyVal) {
|
|
||||||
add(node.key);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_ObjectProperty) {
|
|
||||||
add(node.key.name);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_Dot) {
|
|
||||||
add(node.property);
|
|
||||||
}
|
|
||||||
else if (node instanceof U2.AST_Sub) {
|
|
||||||
addStrings(node.property);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
|
|
||||||
function addStrings(node) {
|
|
||||||
var out = {};
|
|
||||||
try {
|
|
||||||
(function walk(node){
|
|
||||||
node.walk(new U2.TreeWalker(function(node){
|
|
||||||
if (node instanceof U2.AST_Seq) {
|
|
||||||
walk(node.cdr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof U2.AST_String) {
|
|
||||||
add(node.value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof U2.AST_Conditional) {
|
|
||||||
walk(node.consequent);
|
|
||||||
walk(node.alternative);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
throw out;
|
|
||||||
}));
|
|
||||||
})(node);
|
|
||||||
} catch(ex) {
|
|
||||||
if (ex !== out) throw ex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add(name) {
|
|
||||||
output.props[name] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
939
bin/uglifyjs
939
bin/uglifyjs
@@ -3,633 +3,382 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var UglifyJS = require("../tools/node");
|
// workaround for tty output truncation upon process.exit()
|
||||||
var sys = require("util");
|
[process.stdout, process.stderr].forEach(function(stream){
|
||||||
var yargs = require("yargs");
|
if (stream._handle && stream._handle.setBlocking)
|
||||||
var fs = require("fs");
|
stream._handle.setBlocking(true);
|
||||||
var path = require("path");
|
|
||||||
var acorn;
|
|
||||||
var screw_ie8 = true;
|
|
||||||
var ARGS = yargs
|
|
||||||
.usage("$0 input1.js [input2.js ...] [options]\n\
|
|
||||||
Use a single dash to read input from the standard input.\
|
|
||||||
\n\n\
|
|
||||||
NOTE: by default there is no mangling/compression.\n\
|
|
||||||
Without [options] it will simply parse input files and dump the AST\n\
|
|
||||||
with whitespace and comments discarded. To achieve compression and\n\
|
|
||||||
mangling you need to use `-c` and `-m`.\
|
|
||||||
")
|
|
||||||
.describe("source-map", "Specify an output file where to generate source map.")
|
|
||||||
.describe("source-map-root", "The path to the original source to be included in the source map.")
|
|
||||||
.describe("source-map-url", "The path to the source map to be added in //# sourceMappingURL. Defaults to the value passed with --source-map.")
|
|
||||||
.describe("source-map-inline", "Write base64-encoded source map to the end of js output. Disabled by default")
|
|
||||||
.describe("source-map-include-sources", "Pass this flag if you want to include the content of source files in the source map as sourcesContent property.")
|
|
||||||
.describe("in-source-map", "Input source map, useful if you're compressing JS that was generated from some other original code.")
|
|
||||||
.describe("screw-ie8", "Do not support Internet Explorer 6/7/8. This flag is enabled by default.")
|
|
||||||
.describe("support-ie8", "Support non-standard Internet Explorer 6/7/8 javascript.")
|
|
||||||
.describe("expr", "Parse a single expression, rather than a program (for parsing JSON)")
|
|
||||||
.describe("p", "Skip prefix for original filenames that appear in source maps. \
|
|
||||||
For example -p 3 will drop 3 directories from file names and ensure they are relative paths. \
|
|
||||||
You can also specify -p relative, which will make UglifyJS figure out itself the relative paths between original sources, \
|
|
||||||
the source map and the output file.")
|
|
||||||
.describe("o", "Output file (default STDOUT).")
|
|
||||||
.describe("b", "Beautify output/specify output options.")
|
|
||||||
.describe("m", "Mangle names/pass mangler options.")
|
|
||||||
.describe("r", "Reserved names to exclude from mangling.")
|
|
||||||
.describe("c", "Enable compressor/pass compressor options. \
|
|
||||||
Pass options like -c hoist_vars=false,if_return=false. \
|
|
||||||
Use -c with no argument to use the default compression options.")
|
|
||||||
.describe("d", "Global definitions")
|
|
||||||
.describe("e", "Embed everything in a big function, with a configurable parameter/argument list.")
|
|
||||||
|
|
||||||
.describe("comments", "Preserve copyright comments in the output. \
|
|
||||||
By default this works like Google Closure, keeping JSDoc-style comments that contain \"@license\" or \"@preserve\". \
|
|
||||||
You can optionally pass one of the following arguments to this flag:\n\
|
|
||||||
- \"all\" to keep all comments\n\
|
|
||||||
- a valid JS RegExp like `/foo/`or `/^!/` to keep only matching comments.\n\
|
|
||||||
\
|
|
||||||
Note that currently not *all* comments can be kept when compression is on, \
|
|
||||||
because of dead code removal or cascading statements into sequences.")
|
|
||||||
|
|
||||||
.describe("preamble", "Preamble to prepend to the output. You can use this to insert a \
|
|
||||||
comment, for example for licensing information. This will not be \
|
|
||||||
parsed, but the source map will adjust for its presence.")
|
|
||||||
|
|
||||||
.describe("stats", "Display operations run time on STDERR.")
|
|
||||||
.describe("acorn", "Use Acorn for parsing.")
|
|
||||||
.describe("spidermonkey", "Assume input files are SpiderMonkey AST format (as JSON).")
|
|
||||||
.describe("self", "Build itself (UglifyJS2) as a library (implies --wrap=UglifyJS --export-all)")
|
|
||||||
.describe("wrap", "Embed everything in a big function, making the “exports” and “global” variables available. \
|
|
||||||
You need to pass an argument to this option to specify the name that your module will take when included in, say, a browser.")
|
|
||||||
.describe("export-all", "Only used when --wrap, this tells UglifyJS to add code to automatically export all globals.")
|
|
||||||
.describe("lint", "Display some scope warnings")
|
|
||||||
.describe("v", "Verbose")
|
|
||||||
.describe("V", "Print version number and exit.")
|
|
||||||
.describe("noerr", "Don't throw an error for unknown options in -c, -b or -m.")
|
|
||||||
.describe("bare-returns", "Allow return outside of functions. Useful when minifying CommonJS modules.")
|
|
||||||
.describe("keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.")
|
|
||||||
.describe("quotes", "Quote style (0 - auto, 1 - single, 2 - double, 3 - original)")
|
|
||||||
.describe("reserved-file", "File containing reserved names")
|
|
||||||
.describe("reserve-domprops", "Make (most?) DOM properties reserved for --mangle-props")
|
|
||||||
.describe("mangle-props", "Mangle property names (0 - disabled, 1 - mangle all properties, 2 - mangle unquoted properies)")
|
|
||||||
.describe("mangle-regex", "Only mangle property names matching the regex")
|
|
||||||
.describe("name-cache", "File to hold mangled names mappings")
|
|
||||||
.describe("pure-funcs", "List of functions that can be safely removed if their return value is not used")
|
|
||||||
.describe("dump-spidermonkey-ast", "Dump SpiderMonkey AST to stdout.")
|
|
||||||
.describe("wrap-iife", "Wrap IIFEs in parenthesis. Note: this disables the negate_iife compression option")
|
|
||||||
|
|
||||||
.alias("p", "prefix")
|
|
||||||
.alias("o", "output")
|
|
||||||
.alias("v", "verbose")
|
|
||||||
.alias("b", "beautify")
|
|
||||||
.alias("m", "mangle")
|
|
||||||
.alias("c", "compress")
|
|
||||||
.alias("d", "define")
|
|
||||||
.alias("r", "reserved")
|
|
||||||
.alias("V", "version")
|
|
||||||
.alias("e", "enclose")
|
|
||||||
.alias("q", "quotes")
|
|
||||||
|
|
||||||
.string("source-map")
|
|
||||||
.string("source-map-root")
|
|
||||||
.string("source-map-url")
|
|
||||||
.string("b")
|
|
||||||
.string("beautify")
|
|
||||||
.string("m")
|
|
||||||
.string("mangle")
|
|
||||||
.string("mangle-props-debug")
|
|
||||||
.string("c")
|
|
||||||
.string("compress")
|
|
||||||
.string("d")
|
|
||||||
.string("define")
|
|
||||||
.string("e")
|
|
||||||
.string("enclose")
|
|
||||||
.string("comments")
|
|
||||||
.string("wrap")
|
|
||||||
.string("p")
|
|
||||||
.string("prefix")
|
|
||||||
.string("name-cache")
|
|
||||||
|
|
||||||
.array("reserved-file")
|
|
||||||
.array("pure-funcs")
|
|
||||||
|
|
||||||
.boolean("expr")
|
|
||||||
.boolean("source-map-inline")
|
|
||||||
.boolean("source-map-include-sources")
|
|
||||||
.boolean("screw-ie8")
|
|
||||||
.boolean("support-ie8")
|
|
||||||
.boolean("export-all")
|
|
||||||
.boolean("self")
|
|
||||||
.boolean("v")
|
|
||||||
.boolean("verbose")
|
|
||||||
.boolean("stats")
|
|
||||||
.boolean("acorn")
|
|
||||||
.boolean("spidermonkey")
|
|
||||||
.boolean("dump-spidermonkey-ast")
|
|
||||||
.boolean("lint")
|
|
||||||
.boolean("V")
|
|
||||||
.boolean("version")
|
|
||||||
.boolean("noerr")
|
|
||||||
.boolean("bare-returns")
|
|
||||||
.boolean("keep-fnames")
|
|
||||||
.boolean("reserve-domprops")
|
|
||||||
.boolean("wrap-iife")
|
|
||||||
|
|
||||||
.wrap(80)
|
|
||||||
|
|
||||||
.argv
|
|
||||||
;
|
|
||||||
|
|
||||||
normalize(ARGS);
|
|
||||||
|
|
||||||
if (ARGS.noerr) {
|
|
||||||
UglifyJS.DefaultsError.croak = function(msg, defs) {
|
|
||||||
print_error("WARN: " + msg);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.version || ARGS.V) {
|
|
||||||
var json = require("../package.json");
|
|
||||||
print(json.name + ' ' + json.version);
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.ast_help) {
|
|
||||||
var desc = UglifyJS.describe_ast();
|
|
||||||
print(typeof desc == "string" ? desc : JSON.stringify(desc, null, 2));
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.h || ARGS.help) {
|
|
||||||
print(yargs.help());
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.acorn) {
|
|
||||||
acorn = require("acorn");
|
|
||||||
}
|
|
||||||
|
|
||||||
var COMPRESS = getOptions("c", true);
|
|
||||||
var MANGLE = getOptions("m", true);
|
|
||||||
var BEAUTIFY = getOptions("b", true);
|
|
||||||
var RESERVED = null;
|
|
||||||
|
|
||||||
if (ARGS.reserved_file) ARGS.reserved_file.forEach(function(filename){
|
|
||||||
RESERVED = UglifyJS.readReservedFile(filename, RESERVED);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ARGS.reserve_domprops) {
|
var fs = require("fs");
|
||||||
RESERVED = UglifyJS.readDefaultReservedFile(RESERVED);
|
var info = require("../package.json");
|
||||||
}
|
var path = require("path");
|
||||||
|
var program = require("commander");
|
||||||
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
if (ARGS.d) {
|
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||||
if (COMPRESS) COMPRESS.global_defs = getOptions("d");
|
var files = {};
|
||||||
}
|
var options = {
|
||||||
|
compress: false,
|
||||||
if (ARGS.pure_funcs) {
|
mangle: false
|
||||||
if (COMPRESS) COMPRESS.pure_funcs = ARGS.pure_funcs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.r) {
|
|
||||||
if (MANGLE) MANGLE.except = ARGS.r.replace(/^\s+|\s+$/g).split(/\s*,+\s*/);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RESERVED && MANGLE) {
|
|
||||||
if (!MANGLE.except) MANGLE.except = RESERVED.vars;
|
|
||||||
else MANGLE.except = MANGLE.except.concat(RESERVED.vars);
|
|
||||||
}
|
|
||||||
|
|
||||||
function readNameCache(key) {
|
|
||||||
return UglifyJS.readNameCache(ARGS.name_cache, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
function writeNameCache(key, cache) {
|
|
||||||
return UglifyJS.writeNameCache(ARGS.name_cache, key, cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractRegex(str) {
|
|
||||||
if (/^\/.*\/[a-zA-Z]*$/.test(str)) {
|
|
||||||
var regex_pos = str.lastIndexOf("/");
|
|
||||||
return new RegExp(str.substr(1, regex_pos - 1), str.substr(regex_pos + 1));
|
|
||||||
} else {
|
|
||||||
throw new Error("Invalid regular expression: " + str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.quotes === true) {
|
|
||||||
ARGS.quotes = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.mangle_props === true) {
|
|
||||||
ARGS.mangle_props = 1;
|
|
||||||
} else if (ARGS.mangle_props === "unquoted") {
|
|
||||||
ARGS.mangle_props = 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
var OUTPUT_OPTIONS = {
|
|
||||||
beautify : BEAUTIFY ? true : false,
|
|
||||||
max_line_len : 32000,
|
|
||||||
preamble : ARGS.preamble || null,
|
|
||||||
quote_style : ARGS.quotes != null ? ARGS.quotes : 0,
|
|
||||||
};
|
};
|
||||||
|
program.version(info.name + ' ' + info.version);
|
||||||
if (ARGS.mangle_props == 2) {
|
program.parseArgv = program.parse;
|
||||||
OUTPUT_OPTIONS.keep_quoted_props = true;
|
program.parse = undefined;
|
||||||
if (COMPRESS && !("properties" in COMPRESS))
|
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
||||||
COMPRESS.properties = false;
|
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
||||||
|
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
||||||
|
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
||||||
|
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
||||||
|
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||||
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
|
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||||
|
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("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
|
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("--stats", "Display operations run time on STDERR.")
|
||||||
|
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||||
|
program.option("--verbose", "Print diagnostic messages.");
|
||||||
|
program.option("--warn", "Print warning messages.");
|
||||||
|
program.option("--wrap <name>", "Embed everything as a function with “exports” corresponding to “name” globally.");
|
||||||
|
program.arguments("[files...]").parseArgv(process.argv);
|
||||||
|
if (program.configFile) {
|
||||||
|
options = JSON.parse(read_file(program.configFile));
|
||||||
}
|
}
|
||||||
|
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||||
if (ARGS.support_ie8 === true && ARGS.screw_ie8 !== true) {
|
fatal("ERROR: cannot write source map to STDOUT");
|
||||||
screw_ie8 = false;
|
|
||||||
}
|
}
|
||||||
|
[
|
||||||
if (COMPRESS) COMPRESS.screw_ie8 = screw_ie8;
|
"compress",
|
||||||
if (MANGLE) MANGLE.screw_ie8 = screw_ie8;
|
"ie8",
|
||||||
OUTPUT_OPTIONS.screw_ie8 = screw_ie8;
|
"mangle",
|
||||||
|
"sourceMap",
|
||||||
if (ARGS.keep_fnames) {
|
"toplevel",
|
||||||
if (COMPRESS) COMPRESS.keep_fnames = true;
|
"wrap"
|
||||||
if (MANGLE) MANGLE.keep_fnames = true;
|
].forEach(function(name) {
|
||||||
|
if (name in program) {
|
||||||
|
options[name] = program[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (program.beautify) {
|
||||||
|
options.output = typeof program.beautify == "object" ? program.beautify : {};
|
||||||
|
if (!("beautify" in options.output)) {
|
||||||
|
options.output.beautify = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (program.comments) {
|
||||||
if (ARGS.wrap_iife) {
|
if (typeof options.output != "object") options.output = {};
|
||||||
if (COMPRESS) COMPRESS.negate_iife = false;
|
options.output.comments = typeof program.comments == "string" ? program.comments : "some";
|
||||||
OUTPUT_OPTIONS.wrap_iife = true;
|
|
||||||
}
|
}
|
||||||
|
if (program.define) {
|
||||||
if (BEAUTIFY)
|
if (typeof options.compress != "object") options.compress = {};
|
||||||
UglifyJS.merge(OUTPUT_OPTIONS, BEAUTIFY);
|
if (typeof options.compress.global_defs != "object") options.compress.global_defs = {};
|
||||||
|
for (var expr in program.define) {
|
||||||
if (ARGS.comments === "") {
|
options.compress.global_defs[expr] = program.define[expr];
|
||||||
OUTPUT_OPTIONS.comments = "some";
|
}
|
||||||
|
}
|
||||||
|
if (program.keepFnames) {
|
||||||
|
options.keep_fnames = true;
|
||||||
|
}
|
||||||
|
if (program.mangleProps) {
|
||||||
|
if (program.mangleProps.domprops) {
|
||||||
|
delete program.mangleProps.domprops;
|
||||||
|
} else {
|
||||||
|
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||||
|
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||||
|
require("../tools/domprops").forEach(function(name) {
|
||||||
|
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
|
options.mangle.properties = program.mangleProps;
|
||||||
|
}
|
||||||
|
var cache;
|
||||||
|
if (program.nameCache) {
|
||||||
|
cache = 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") {
|
||||||
|
options.output = {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (program.parse) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var convert_path = function(name) {
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
if (typeof program.sourceMap == "object" && "base" in program.sourceMap) {
|
||||||
|
convert_path = function() {
|
||||||
|
var base = program.sourceMap.base;
|
||||||
|
delete options.sourceMap.base;
|
||||||
|
return function(name) {
|
||||||
|
return path.relative(base, name);
|
||||||
|
};
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
if (program.verbose) {
|
||||||
|
options.warnings = "verbose";
|
||||||
|
} else if (program.warn) {
|
||||||
|
options.warnings = true;
|
||||||
|
}
|
||||||
|
if (program.self) {
|
||||||
|
if (program.args.length) {
|
||||||
|
console.error("WARN: Ignoring input files since --self was passed");
|
||||||
|
}
|
||||||
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
|
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||||
|
files[convert_path(name)] = read_file(name);
|
||||||
|
});
|
||||||
|
run();
|
||||||
|
} else if (program.args.length) {
|
||||||
|
simple_glob(program.args).forEach(function(name) {
|
||||||
|
files[convert_path(name)] = read_file(name);
|
||||||
|
});
|
||||||
|
run();
|
||||||
} else {
|
} else {
|
||||||
OUTPUT_OPTIONS.comments = ARGS.comments;
|
var chunks = [];
|
||||||
|
process.stdin.setEncoding("utf8");
|
||||||
|
process.stdin.on("data", function(chunk) {
|
||||||
|
chunks.push(chunk);
|
||||||
|
}).on("end", function() {
|
||||||
|
files = [ chunks.join("") ];
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
process.stdin.resume();
|
||||||
}
|
}
|
||||||
|
|
||||||
var files = ARGS._.slice();
|
function convert_ast(fn) {
|
||||||
|
return UglifyJS.AST_Node.from_mozilla_ast(Object.keys(files).reduce(fn, null));
|
||||||
if (process.platform === "win32")
|
|
||||||
files = UglifyJS.simple_glob(files);
|
|
||||||
|
|
||||||
if (ARGS.self) {
|
|
||||||
if (files.length > 0) {
|
|
||||||
print_error("WARN: Ignoring input files since --self was passed");
|
|
||||||
}
|
|
||||||
files = UglifyJS.FILES;
|
|
||||||
if (!ARGS.wrap) ARGS.wrap = "UglifyJS";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var ORIG_MAP = ARGS.in_source_map;
|
function run() {
|
||||||
|
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||||
if (ORIG_MAP && ORIG_MAP != "inline") {
|
console.error("WARN:", msg);
|
||||||
ORIG_MAP = JSON.parse(fs.readFileSync(ORIG_MAP));
|
};
|
||||||
if (files.length == 0) {
|
if (program.stats) program.stats = Date.now();
|
||||||
print_error("INFO: Using file from the input source map: " + ORIG_MAP.file);
|
try {
|
||||||
files = [ ORIG_MAP.file ];
|
if (program.parse) {
|
||||||
}
|
if (program.parse.acorn) {
|
||||||
}
|
files = convert_ast(function(toplevel, name) {
|
||||||
|
return require("acorn").parse(files[name], {
|
||||||
if (files.length == 0) {
|
locations: true,
|
||||||
files = [ "-" ];
|
program: toplevel,
|
||||||
}
|
sourceFile: name
|
||||||
|
});
|
||||||
if (ORIG_MAP == "inline") {
|
});
|
||||||
if (files.length > 1) {
|
} else if (program.parse.spidermonkey) {
|
||||||
print_error("ERROR: Inline source map only works with singular input");
|
files = convert_ast(function(toplevel, name) {
|
||||||
process.exit(1);
|
var obj = JSON.parse(files[name]);
|
||||||
}
|
if (!toplevel) return obj;
|
||||||
if (ARGS.acorn || ARGS.spidermonkey) {
|
toplevel.body = toplevel.body.concat(obj.body);
|
||||||
print_error("ERROR: Inline source map only works with built-in parser");
|
return toplevel;
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files.indexOf("-") >= 0 && ARGS.source_map) {
|
|
||||||
print_error("ERROR: Source map doesn't work with input from STDIN");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (files.filter(function(el){ return el == "-" }).length > 1) {
|
|
||||||
print_error("ERROR: Can read a single file from STDIN (two or more dashes specified)");
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
var STATS = {};
|
|
||||||
var TOPLEVEL = null;
|
|
||||||
var P_RELATIVE = ARGS.p && ARGS.p == "relative";
|
|
||||||
var SOURCES_CONTENT = {};
|
|
||||||
var index = 0;
|
|
||||||
|
|
||||||
!function cb() {
|
|
||||||
if (index == files.length) return done();
|
|
||||||
var file = files[index++];
|
|
||||||
read_whole_file(file, function (err, code) {
|
|
||||||
if (err) {
|
|
||||||
print_error("ERROR: can't read file: " + file);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
if (ORIG_MAP == "inline") {
|
|
||||||
ORIG_MAP = read_source_map(code);
|
|
||||||
}
|
|
||||||
if (ARGS.p != null) {
|
|
||||||
if (P_RELATIVE) {
|
|
||||||
file = path.relative(path.dirname(ARGS.source_map), file).replace(/\\/g, '/');
|
|
||||||
} else {
|
|
||||||
var p = parseInt(ARGS.p, 10);
|
|
||||||
if (!isNaN(p)) {
|
|
||||||
file = file.replace(/^\/+/, "").split(/\/+/).slice(ARGS.p).join("/");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SOURCES_CONTENT[file] = code;
|
|
||||||
time_it("parse", function(){
|
|
||||||
if (ARGS.spidermonkey) {
|
|
||||||
var program = JSON.parse(code);
|
|
||||||
if (!TOPLEVEL) TOPLEVEL = program;
|
|
||||||
else TOPLEVEL.body = TOPLEVEL.body.concat(program.body);
|
|
||||||
}
|
|
||||||
else if (ARGS.acorn) {
|
|
||||||
TOPLEVEL = acorn.parse(code, {
|
|
||||||
locations : true,
|
|
||||||
sourceFile : file,
|
|
||||||
program : TOPLEVEL
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
try {
|
} catch (ex) {
|
||||||
TOPLEVEL = UglifyJS.parse(code, {
|
fatal(ex);
|
||||||
filename : file,
|
}
|
||||||
toplevel : TOPLEVEL,
|
var result = UglifyJS.minify(files, options);
|
||||||
expression : ARGS.expr,
|
if (result.error) {
|
||||||
bare_returns : ARGS.bare_returns,
|
var ex = result.error;
|
||||||
});
|
if (ex.name == "SyntaxError") {
|
||||||
} catch(ex) {
|
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
var col = ex.col;
|
||||||
print_error("Parse error at " + file + ":" + ex.line + "," + ex.col);
|
var lines = files[ex.filename].split(/\r?\n/);
|
||||||
var col = ex.col;
|
var line = lines[ex.line - 1];
|
||||||
var line = code.split(/\r?\n/)[ex.line - (col ? 1 : 2)];
|
if (!line && !col) {
|
||||||
if (line) {
|
line = lines[ex.line - 2];
|
||||||
if (col > 40) {
|
col = line.length;
|
||||||
line = line.slice(col - 40);
|
}
|
||||||
col = 40;
|
if (line) {
|
||||||
}
|
if (col > 40) {
|
||||||
if (col) {
|
line = line.slice(col - 40);
|
||||||
print_error(line.slice(0, 80));
|
col = 40;
|
||||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
|
||||||
} else {
|
|
||||||
print_error(line.slice(-40));
|
|
||||||
print_error(line.slice(-40).replace(/\S/g, " ") + "^");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
print_error(ex.stack);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
throw ex;
|
|
||||||
}
|
}
|
||||||
};
|
console.error(line.slice(0, 80));
|
||||||
});
|
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||||
cb();
|
}
|
||||||
});
|
}
|
||||||
}();
|
if (ex.defs) {
|
||||||
|
console.error("Supported options:");
|
||||||
|
console.error(ex.defs);
|
||||||
|
}
|
||||||
|
fatal(ex);
|
||||||
|
} else if (program.output == "ast") {
|
||||||
|
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||||
|
if (skip_key(key)) return;
|
||||||
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
|
if (value instanceof UglifyJS.AST_Node) {
|
||||||
|
var result = {
|
||||||
|
_class: "AST_" + value.TYPE
|
||||||
|
};
|
||||||
|
value.CTOR.PROPS.forEach(function(prop) {
|
||||||
|
result[prop] = value[prop];
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}, 2));
|
||||||
|
} else if (program.output == "spidermonkey") {
|
||||||
|
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
}
|
||||||
|
}).ast.to_mozilla_ast(), null, 2));
|
||||||
|
} else if (program.output) {
|
||||||
|
fs.writeFileSync(program.output, result.code);
|
||||||
|
if (result.map) {
|
||||||
|
fs.writeFileSync(program.output + ".map", result.map);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log(result.code);
|
||||||
|
}
|
||||||
|
if (program.nameCache) {
|
||||||
|
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
||||||
|
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
|
||||||
|
}
|
||||||
|
|
||||||
function done() {
|
function fatal(message) {
|
||||||
var OUTPUT_FILE = ARGS.o;
|
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||||
|
console.error(message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
var SOURCE_MAP = (ARGS.source_map || ARGS.source_map_inline) ? UglifyJS.SourceMap({
|
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||||
file: P_RELATIVE ? path.relative(path.dirname(ARGS.source_map), OUTPUT_FILE) : OUTPUT_FILE,
|
// Example: "foo/bar/*baz??.*.js"
|
||||||
root: ARGS.source_map_root || ORIG_MAP && ORIG_MAP.sourceRoot,
|
// Argument `glob` may be a string or an array of strings.
|
||||||
orig: ORIG_MAP,
|
// Returns an array of strings. Garbage in, garbage out.
|
||||||
}) : null;
|
function simple_glob(glob) {
|
||||||
|
if (Array.isArray(glob)) {
|
||||||
OUTPUT_OPTIONS.source_map = SOURCE_MAP;
|
return [].concat.apply([], glob.map(simple_glob));
|
||||||
|
}
|
||||||
|
if (glob.match(/\*|\?/)) {
|
||||||
|
var dir = path.dirname(glob);
|
||||||
|
try {
|
||||||
|
var entries = fs.readdirSync(dir);
|
||||||
|
} catch (ex) {}
|
||||||
|
if (entries) {
|
||||||
|
var pattern = "^" + path.basename(glob)
|
||||||
|
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||||
|
.replace(/\*/g, "[^/\\\\]*")
|
||||||
|
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||||
|
var mod = process.platform === "win32" ? "i" : "";
|
||||||
|
var rx = new RegExp(pattern, mod);
|
||||||
|
var results = entries.filter(function(name) {
|
||||||
|
return rx.test(name);
|
||||||
|
}).map(function(name) {
|
||||||
|
return path.join(dir, name);
|
||||||
|
});
|
||||||
|
if (results.length) return results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [ glob ];
|
||||||
|
}
|
||||||
|
|
||||||
|
function read_file(path, default_value) {
|
||||||
try {
|
try {
|
||||||
var output = UglifyJS.OutputStream(OUTPUT_OPTIONS);
|
return fs.readFileSync(path, "utf8");
|
||||||
var compressor = COMPRESS && UglifyJS.Compressor(COMPRESS);
|
} catch (ex) {
|
||||||
} catch(ex) {
|
if (ex.code == "ENOENT" && default_value != null) return default_value;
|
||||||
if (ex instanceof UglifyJS.DefaultsError) {
|
fatal(ex);
|
||||||
print_error(ex.message);
|
|
||||||
print_error("Supported options:");
|
|
||||||
print_error(sys.inspect(ex.defs));
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ARGS.acorn || ARGS.spidermonkey) time_it("convert_ast", function(){
|
function parse_js(flag, constants) {
|
||||||
TOPLEVEL = UglifyJS.AST_Node.from_mozilla_ast(TOPLEVEL);
|
return function(value, options) {
|
||||||
});
|
options = options || {};
|
||||||
|
|
||||||
if (ARGS.wrap != null) {
|
|
||||||
TOPLEVEL = TOPLEVEL.wrap_commonjs(ARGS.wrap, ARGS.export_all);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.enclose != null) {
|
|
||||||
var arg_parameter_list = ARGS.enclose;
|
|
||||||
if (arg_parameter_list === true) {
|
|
||||||
arg_parameter_list = [];
|
|
||||||
}
|
|
||||||
else if (!(arg_parameter_list instanceof Array)) {
|
|
||||||
arg_parameter_list = [arg_parameter_list];
|
|
||||||
}
|
|
||||||
TOPLEVEL = TOPLEVEL.wrap_enclose(arg_parameter_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.mangle_props || ARGS.name_cache) (function(){
|
|
||||||
var reserved = RESERVED ? RESERVED.props : null;
|
|
||||||
var cache = readNameCache("props");
|
|
||||||
var regex;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
regex = ARGS.mangle_regex ? extractRegex(ARGS.mangle_regex) : null;
|
UglifyJS.minify(value, {
|
||||||
} catch (e) {
|
parse: {
|
||||||
print_error("ERROR: Invalid --mangle-regex: " + e.message);
|
expression: true
|
||||||
process.exit(1);
|
},
|
||||||
}
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
code: false
|
||||||
|
}
|
||||||
|
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
|
var name = node.left.print_to_string();
|
||||||
|
var value = node.right;
|
||||||
|
if (!constants) {
|
||||||
|
options[name] = value;
|
||||||
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
|
options[name] = value.elements.map(to_string);
|
||||||
|
} else {
|
||||||
|
options[name] = to_string(value);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_PropAccess) {
|
||||||
|
var name = node.print_to_string();
|
||||||
|
options[name] = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(node instanceof UglifyJS.AST_Sequence)) throw node;
|
||||||
|
|
||||||
TOPLEVEL = UglifyJS.mangle_properties(TOPLEVEL, {
|
function to_string(value) {
|
||||||
reserved : reserved,
|
return value instanceof UglifyJS.AST_Constant ? value.getValue() : value.print_to_string({
|
||||||
cache : cache,
|
quote_keys: true
|
||||||
only_cache : !ARGS.mangle_props,
|
});
|
||||||
regex : regex,
|
}
|
||||||
ignore_quoted : ARGS.mangle_props == 2,
|
|
||||||
debug : typeof ARGS.mangle_props_debug === "undefined" ? false : ARGS.mangle_props_debug
|
|
||||||
});
|
|
||||||
writeNameCache("props", cache);
|
|
||||||
})();
|
|
||||||
|
|
||||||
var SCOPE_IS_NEEDED = COMPRESS || MANGLE || ARGS.lint
|
|
||||||
var TL_CACHE = readNameCache("vars");
|
|
||||||
if (MANGLE) MANGLE.cache = TL_CACHE;
|
|
||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
|
||||||
time_it("scope", function(){
|
|
||||||
TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE });
|
|
||||||
if (ARGS.lint) {
|
|
||||||
TOPLEVEL.scope_warnings();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (COMPRESS) {
|
|
||||||
time_it("squeeze", function(){
|
|
||||||
TOPLEVEL = compressor.compress(TOPLEVEL);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SCOPE_IS_NEEDED) {
|
|
||||||
time_it("scope", function(){
|
|
||||||
TOPLEVEL.figure_out_scope(MANGLE || { screw_ie8: screw_ie8, cache: TL_CACHE });
|
|
||||||
if (MANGLE && !TL_CACHE) {
|
|
||||||
TOPLEVEL.compute_char_frequency(MANGLE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (MANGLE) time_it("mangle", function(){
|
|
||||||
TOPLEVEL.mangle_names(MANGLE);
|
|
||||||
});
|
|
||||||
|
|
||||||
writeNameCache("vars", TL_CACHE);
|
|
||||||
|
|
||||||
if (ARGS.source_map_include_sources) {
|
|
||||||
for (var file in SOURCES_CONTENT) {
|
|
||||||
if (SOURCES_CONTENT.hasOwnProperty(file)) {
|
|
||||||
SOURCE_MAP.get().setSourceContent(file, SOURCES_CONTENT[file]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.dump_spidermonkey_ast) {
|
|
||||||
print(JSON.stringify(TOPLEVEL.to_mozilla_ast(), null, 2));
|
|
||||||
} else {
|
|
||||||
time_it("generate", function(){
|
|
||||||
TOPLEVEL.print(output);
|
|
||||||
});
|
|
||||||
|
|
||||||
output = output.get();
|
|
||||||
|
|
||||||
if (SOURCE_MAP) {
|
|
||||||
if (ARGS.source_map_inline) {
|
|
||||||
var base64_string = new Buffer(SOURCE_MAP.toString()).toString('base64');
|
|
||||||
output += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + base64_string;
|
|
||||||
} else {
|
|
||||||
fs.writeFileSync(ARGS.source_map, SOURCE_MAP, "utf8");
|
|
||||||
var source_map_url = ARGS.source_map_url || (
|
|
||||||
P_RELATIVE
|
|
||||||
? path.relative(path.dirname(OUTPUT_FILE), ARGS.source_map)
|
|
||||||
: ARGS.source_map
|
|
||||||
);
|
|
||||||
output += "\n//# sourceMappingURL=" + source_map_url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (OUTPUT_FILE) {
|
|
||||||
fs.writeFileSync(OUTPUT_FILE, output, "utf8");
|
|
||||||
} else {
|
|
||||||
print(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ARGS.stats) {
|
|
||||||
print_error(UglifyJS.string_template("Timing information (compressed {count} files):", {
|
|
||||||
count: files.length
|
|
||||||
}));
|
|
||||||
for (var i in STATS) if (STATS.hasOwnProperty(i)) {
|
|
||||||
print_error(UglifyJS.string_template("- {name}: {time}s", {
|
|
||||||
name: i,
|
|
||||||
time: (STATS[i] / 1000).toFixed(3)
|
|
||||||
}));
|
}));
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* -----[ functions ]----- */
|
|
||||||
|
|
||||||
function normalize(o) {
|
|
||||||
for (var i in o) if (o.hasOwnProperty(i) && /-/.test(i)) {
|
|
||||||
o[i.replace(/-/g, "_")] = o[i];
|
|
||||||
delete o[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getOptions(flag, constants) {
|
|
||||||
var x = ARGS[flag];
|
|
||||||
if (x == null || x === false) return null;
|
|
||||||
var ret = {};
|
|
||||||
if (x !== "") {
|
|
||||||
if (Array.isArray(x)) x = x.map(function (v) { return "(" + v + ")"; }).join(", ");
|
|
||||||
|
|
||||||
var ast;
|
|
||||||
try {
|
|
||||||
ast = UglifyJS.parse(x, { cli: true, expression: true });
|
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
if (ex instanceof UglifyJS.JS_Parse_Error) {
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ast.walk(new UglifyJS.TreeWalker(function(node){
|
return options;
|
||||||
if (node instanceof UglifyJS.AST_Seq) return; // descend
|
|
||||||
if (node instanceof UglifyJS.AST_Assign) {
|
|
||||||
var name = node.left.print_to_string().replace(/-/g, "_");
|
|
||||||
var value = node.right;
|
|
||||||
if (constants)
|
|
||||||
value = new Function("return (" + value.print_to_string() + ")")();
|
|
||||||
ret[name] = value;
|
|
||||||
return true; // no descend
|
|
||||||
}
|
|
||||||
if (node instanceof UglifyJS.AST_Symbol || node instanceof UglifyJS.AST_Binary) {
|
|
||||||
var name = node.print_to_string().replace(/-/g, "_");
|
|
||||||
ret[name] = true;
|
|
||||||
return true; // no descend
|
|
||||||
}
|
|
||||||
print_error(node.TYPE)
|
|
||||||
print_error("Error parsing arguments for flag `" + flag + "': " + x);
|
|
||||||
process.exit(1);
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_whole_file(filename, cb) {
|
function parse_source_map() {
|
||||||
if (filename == "-") {
|
var parse = parse_js("sourceMap", true);
|
||||||
var chunks = [];
|
return function(value, options) {
|
||||||
process.stdin.setEncoding('utf-8');
|
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
||||||
process.stdin.on('data', function (chunk) {
|
var settings = parse(value, options);
|
||||||
chunks.push(chunk);
|
if (!hasContent && settings.content && settings.content != "inline") {
|
||||||
}).on('end', function () {
|
console.error("INFO: Using input source map:", settings.content);
|
||||||
cb(null, chunks.join(""));
|
settings.content = read_file(settings.content, settings.content);
|
||||||
});
|
}
|
||||||
process.openStdin();
|
return settings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function to_cache(key) {
|
||||||
|
if (cache[key]) {
|
||||||
|
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
||||||
} else {
|
} else {
|
||||||
fs.readFile(filename, "utf-8", cb);
|
cache[key] = {
|
||||||
|
cname: -1,
|
||||||
|
props: new UglifyJS.Dictionary()
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
return cache[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_source_map(code) {
|
function skip_key(key) {
|
||||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
return skip_keys.indexOf(key) >= 0;
|
||||||
if (!match) {
|
|
||||||
print_error("WARN: inline source map not found");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return JSON.parse(new Buffer(match[2], "base64"));
|
|
||||||
}
|
|
||||||
|
|
||||||
function time_it(name, cont) {
|
|
||||||
var t1 = new Date().getTime();
|
|
||||||
var ret = cont();
|
|
||||||
if (ARGS.stats) {
|
|
||||||
var spent = new Date().getTime() - t1;
|
|
||||||
if (STATS[name]) STATS[name] += spent;
|
|
||||||
else STATS[name] = spent;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function print_error(msg) {
|
|
||||||
console.error("%s", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
function print(txt) {
|
|
||||||
console.log("%s", txt);
|
|
||||||
}
|
}
|
||||||
|
|||||||
523
lib/ast.js
523
lib/ast.js
@@ -157,7 +157,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
|||||||
|
|
||||||
function walk_body(node, visitor) {
|
function walk_body(node, visitor) {
|
||||||
var body = node.body;
|
var body = node.body;
|
||||||
if (body instanceof AST_Statement) {
|
if (body instanceof AST_Node) {
|
||||||
body._walk(visitor);
|
body._walk(visitor);
|
||||||
}
|
}
|
||||||
else for (var i = 0, len = body.length; i < len; i++) {
|
else for (var i = 0, len = body.length; i < len; i++) {
|
||||||
@@ -182,21 +182,13 @@ var AST_BlockStatement = DEFNODE("BlockStatement", null, {
|
|||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||||
_walk: function(visitor) {
|
|
||||||
return visitor._visit(this);
|
|
||||||
}
|
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
||||||
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||||
},
|
|
||||||
_walk: function(visitor) {
|
|
||||||
return visitor._visit(this, function(){
|
|
||||||
this.body._walk(visitor);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
@@ -214,12 +206,13 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
clone: function(deep) {
|
clone: function(deep) {
|
||||||
var node = this._clone(deep);
|
var node = this._clone(deep);
|
||||||
if (deep) {
|
if (deep) {
|
||||||
var refs = node.label.references;
|
var label = node.label;
|
||||||
var label = this.label;
|
var def = this.label;
|
||||||
node.walk(new TreeWalker(function(node) {
|
node.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_LoopControl
|
if (node instanceof AST_LoopControl
|
||||||
&& node.label && node.label.thedef === label) {
|
&& node.label && node.label.thedef === def) {
|
||||||
refs.push(node);
|
node.label.thedef = label;
|
||||||
|
label.references.push(node);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
@@ -291,6 +284,10 @@ var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
|||||||
}
|
}
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
|
|
||||||
|
var AST_ForOf = DEFNODE("ForOf", null, {
|
||||||
|
$documentation: "A `for ... of` statement",
|
||||||
|
}, AST_ForIn);
|
||||||
|
|
||||||
var AST_With = DEFNODE("With", "expression", {
|
var AST_With = DEFNODE("With", "expression", {
|
||||||
$documentation: "A `with` statement",
|
$documentation: "A `with` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
@@ -318,6 +315,13 @@ var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_
|
|||||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||||
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||||
},
|
},
|
||||||
|
get_defun_scope: function () {
|
||||||
|
var self = this;
|
||||||
|
while (self.is_block_scope() && self.parent_scope) {
|
||||||
|
self = self.parent_scope;
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||||
@@ -325,75 +329,124 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
|
||||||
},
|
},
|
||||||
wrap_enclose: function(arg_parameter_pairs) {
|
wrap_commonjs: function(name) {
|
||||||
var self = this;
|
var body = this.body;
|
||||||
var args = [];
|
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||||
var parameters = [];
|
|
||||||
|
|
||||||
arg_parameter_pairs.forEach(function(pair) {
|
|
||||||
var splitAt = pair.lastIndexOf(":");
|
|
||||||
|
|
||||||
args.push(pair.substr(0, splitAt));
|
|
||||||
parameters.push(pair.substr(splitAt + 1));
|
|
||||||
});
|
|
||||||
|
|
||||||
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
|
|
||||||
wrapped_tl = parse(wrapped_tl);
|
wrapped_tl = parse(wrapped_tl);
|
||||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||||
return MAP.splice(self.body);
|
return MAP.splice(body);
|
||||||
}
|
|
||||||
}));
|
|
||||||
return wrapped_tl;
|
|
||||||
},
|
|
||||||
wrap_commonjs: function(name, export_all) {
|
|
||||||
var self = this;
|
|
||||||
var to_export = [];
|
|
||||||
if (export_all) {
|
|
||||||
self.figure_out_scope();
|
|
||||||
self.walk(new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_SymbolDeclaration && node.definition().global) {
|
|
||||||
if (!find_if(function(n){ return n.name == node.name }, to_export))
|
|
||||||
to_export.push(node);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
var wrapped_tl = "(function(exports, global){ '$ORIG'; '$EXPORTS'; global['" + name + "'] = exports; }({}, (function(){return this}())))";
|
|
||||||
wrapped_tl = parse(wrapped_tl);
|
|
||||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
|
||||||
if (node instanceof AST_Directive) {
|
|
||||||
switch (node.value) {
|
|
||||||
case "$ORIG":
|
|
||||||
return MAP.splice(self.body);
|
|
||||||
case "$EXPORTS":
|
|
||||||
var body = [];
|
|
||||||
to_export.forEach(function(sym){
|
|
||||||
body.push(new AST_SimpleStatement({
|
|
||||||
body: new AST_Assign({
|
|
||||||
left: new AST_Sub({
|
|
||||||
expression: new AST_SymbolRef({ name: "exports" }),
|
|
||||||
property: new AST_String({ value: sym.name }),
|
|
||||||
}),
|
|
||||||
operator: "=",
|
|
||||||
right: new AST_SymbolRef(sym),
|
|
||||||
}),
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
return MAP.splice(body);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
return wrapped_tl;
|
return wrapped_tl;
|
||||||
}
|
}
|
||||||
}, AST_Scope);
|
}, AST_Scope);
|
||||||
|
|
||||||
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
var AST_Expansion = DEFNODE("Expansion", "expression", {
|
||||||
|
$documentation: "An expandible argument, such as ...rest, a splat, such as [1,2,...all], or an expansion in a variable declaration, such as var [first, ...rest] = list",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "AST_Symbol the thing to be expanded"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
var self = this;
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
self.expression.walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_ArrowParametersOrSeq = DEFNODE("ArrowParametersOrSeq", "expressions", {
|
||||||
|
$documentation: "A set of arrow function parameters or a sequence expression. This is used because when the parser sees a \"(\" it could be the start of a seq, or the start of a parameter list of an arrow function.",
|
||||||
|
$propdoc: {
|
||||||
|
expressions: "[AST_Expression|AST_Destructuring|AST_Expansion*] array of expressions or argument names or destructurings."
|
||||||
|
},
|
||||||
|
as_params: function (croak) {
|
||||||
|
// We don't want anything which doesn't belong in a destructuring
|
||||||
|
var root = this;
|
||||||
|
return this.expressions.map(function to_fun_args(ex, _, __, default_seen_above) {
|
||||||
|
var insert_default = function(ex, default_value) {
|
||||||
|
if (default_value) {
|
||||||
|
return new AST_DefaultAssign({
|
||||||
|
start: ex.start,
|
||||||
|
left: ex,
|
||||||
|
operator: "=",
|
||||||
|
right: default_value,
|
||||||
|
end: default_value.end
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
if (ex instanceof AST_Object) {
|
||||||
|
return insert_default(new AST_Destructuring({
|
||||||
|
start: ex.start,
|
||||||
|
end: ex.end,
|
||||||
|
is_array: false,
|
||||||
|
names: ex.properties.map(to_fun_args)
|
||||||
|
}), default_seen_above);
|
||||||
|
} else if (ex instanceof AST_ObjectKeyVal) {
|
||||||
|
if (ex.key instanceof AST_SymbolRef) {
|
||||||
|
ex.key = to_fun_args(ex.key, 0, [ex.key]);
|
||||||
|
}
|
||||||
|
ex.value = to_fun_args(ex.value, 0, [ex.key]);
|
||||||
|
return insert_default(ex, default_seen_above);
|
||||||
|
} else if (ex instanceof AST_Hole) {
|
||||||
|
return ex;
|
||||||
|
} else if (ex instanceof AST_Destructuring) {
|
||||||
|
ex.names = ex.names.map(to_fun_args);
|
||||||
|
return insert_default(ex, default_seen_above);
|
||||||
|
} else if (ex instanceof AST_SymbolRef) {
|
||||||
|
return insert_default(new AST_SymbolFunarg({
|
||||||
|
name: ex.name,
|
||||||
|
start: ex.start,
|
||||||
|
end: ex.end
|
||||||
|
}), default_seen_above);
|
||||||
|
} else if (ex instanceof AST_Expansion) {
|
||||||
|
ex.expression = to_fun_args(ex.expression);
|
||||||
|
return insert_default(ex, default_seen_above);
|
||||||
|
} else if (ex instanceof AST_Array) {
|
||||||
|
return insert_default(new AST_Destructuring({
|
||||||
|
start: ex.start,
|
||||||
|
end: ex.end,
|
||||||
|
is_array: true,
|
||||||
|
names: ex.elements.map(to_fun_args)
|
||||||
|
}), default_seen_above);
|
||||||
|
} else if (ex instanceof AST_Assign) {
|
||||||
|
return insert_default(to_fun_args(ex.left, undefined, undefined, ex.right), default_seen_above);
|
||||||
|
} else if (ex instanceof AST_DefaultAssign) {
|
||||||
|
ex.left = to_fun_args(ex.left, 0, [ex.left]);
|
||||||
|
return ex;
|
||||||
|
} else {
|
||||||
|
croak("Invalid function parameter", ex.start.line, ex.start.col);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
as_expr: function() {
|
||||||
|
var exprs = this.expressions;
|
||||||
|
return exprs.length == 1 ? exprs[0] : new AST_Sequence({
|
||||||
|
expressions: exprs
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments is_generator", {
|
||||||
$documentation: "Base class for functions",
|
$documentation: "Base class for functions",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
is_generator: "[boolean] is generatorFn or not",
|
||||||
name: "[AST_SymbolDeclaration?] the name of this function",
|
name: "[AST_SymbolDeclaration?] the name of this function",
|
||||||
argnames: "[AST_SymbolFunarg*] array of function arguments",
|
argnames: "[AST_SymbolFunarg|AST_Destructuring|AST_Expansion|AST_DefaultAssign*] array of function arguments, destructurings, or expanding arguments",
|
||||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||||
},
|
},
|
||||||
|
args_as_names: function () {
|
||||||
|
var out = [];
|
||||||
|
for (var i = 0; i < this.argnames.length; i++) {
|
||||||
|
if (this.argnames[i] instanceof AST_Destructuring) {
|
||||||
|
out = out.concat(this.argnames[i].all_symbols());
|
||||||
|
} else {
|
||||||
|
out.push(this.argnames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
if (this.name) this.name._walk(visitor);
|
if (this.name) this.name._walk(visitor);
|
||||||
@@ -414,10 +467,78 @@ var AST_Function = DEFNODE("Function", null, {
|
|||||||
$documentation: "A function expression"
|
$documentation: "A function expression"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
var AST_Arrow = DEFNODE("Arrow", null, {
|
||||||
|
$documentation: "An ES6 Arrow function ((a) => b)"
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", null, {
|
var AST_Defun = DEFNODE("Defun", null, {
|
||||||
$documentation: "A function definition"
|
$documentation: "A function definition"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
/* -----[ DESTRUCTURING ]----- */
|
||||||
|
var AST_Destructuring = DEFNODE("Destructuring", "names is_array", {
|
||||||
|
$documentation: "A destructuring of several names. Used in destructuring assignment and with destructuring function argument names",
|
||||||
|
$propdoc: {
|
||||||
|
"names": "[AST_Node*] Array of properties or elements",
|
||||||
|
"is_array": "[Boolean] Whether the destructuring represents an object or array"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.names.forEach(function(name){
|
||||||
|
name._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
all_symbols: function() {
|
||||||
|
var out = [];
|
||||||
|
this.walk(new TreeWalker(function (node) {
|
||||||
|
if (node instanceof AST_Symbol) {
|
||||||
|
out.push(node);
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Expansion) {
|
||||||
|
out.push(node.expression);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_PrefixedTemplateString = DEFNODE("PrefixedTemplateString", "template_string prefix", {
|
||||||
|
$documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`",
|
||||||
|
$propdoc: {
|
||||||
|
template_string: "[AST_TemplateString] The template string",
|
||||||
|
prefix: "[AST_SymbolRef|AST_PropAccess] The prefix, which can be a symbol such as `foo` or a dotted expression such as `String.raw`."
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
this.prefix._walk(visitor);
|
||||||
|
this.template_string._walk(visitor);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var AST_TemplateString = DEFNODE("TemplateString", "segments", {
|
||||||
|
$documentation: "A template string literal",
|
||||||
|
$propdoc: {
|
||||||
|
segments: "[AST_TemplateSegment|AST_Expression]* One or more segments, starting with AST_TemplateSegment. AST_Expression may follow AST_TemplateSegment, but each AST_Expression must be followed by AST_TemplateSegment."
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
this.segments.forEach(function(seg, i){
|
||||||
|
if (i % 2 !== 0) {
|
||||||
|
seg._walk(visitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_TemplateSegment = DEFNODE("TemplateSegment", "value raw", {
|
||||||
|
$documentation: "A segment of a template string literal",
|
||||||
|
$propdoc: {
|
||||||
|
value: "Content of the segment",
|
||||||
|
raw: "Raw content of the segment"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ JUMPS ]----- */
|
/* -----[ JUMPS ]----- */
|
||||||
|
|
||||||
var AST_Jump = DEFNODE("Jump", null, {
|
var AST_Jump = DEFNODE("Jump", null, {
|
||||||
@@ -537,7 +658,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
|||||||
var AST_Catch = DEFNODE("Catch", "argname", {
|
var AST_Catch = DEFNODE("Catch", "argname", {
|
||||||
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
$documentation: "A `catch` node; only makes sense as part of a `try` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
argname: "[AST_SymbolCatch] symbol for the exception"
|
argname: "[AST_SymbolCatch|AST_Destructuring|AST_Expansion|AST_DefaultAssign] symbol for the exception"
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
@@ -572,14 +693,75 @@ var AST_Var = DEFNODE("Var", null, {
|
|||||||
$documentation: "A `var` statement"
|
$documentation: "A `var` statement"
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
|
|
||||||
|
var AST_Let = DEFNODE("Let", null, {
|
||||||
|
$documentation: "A `let` statement"
|
||||||
|
}, AST_Definitions);
|
||||||
|
|
||||||
var AST_Const = DEFNODE("Const", null, {
|
var AST_Const = DEFNODE("Const", null, {
|
||||||
$documentation: "A `const` statement"
|
$documentation: "A `const` statement"
|
||||||
}, AST_Definitions);
|
}, AST_Definitions);
|
||||||
|
|
||||||
|
var AST_NameImport = DEFNODE("NameImport", "foreign_name name", {
|
||||||
|
$documentation: "The part of the import statement that imports names from a module.",
|
||||||
|
$propdoc: {
|
||||||
|
foreign_name: "[AST_SymbolImportForeign] The name being imported (as specified in the module)",
|
||||||
|
name: "[AST_SymbolImport] The name as it becomes available to this module."
|
||||||
|
},
|
||||||
|
_walk: function (visitor) {
|
||||||
|
return visitor._visit(this, function() {
|
||||||
|
this.foreign_name._walk(visitor);
|
||||||
|
this.name._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
||||||
|
$documentation: "An `import` statement",
|
||||||
|
$propdoc: {
|
||||||
|
imported_name: "[AST_SymbolImport] The name of the variable holding the module's default export.",
|
||||||
|
imported_names: "[AST_NameImport*] The names of non-default imported variables",
|
||||||
|
module_name: "[AST_String] String literal describing where this module came from",
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function() {
|
||||||
|
if (this.imported_name) {
|
||||||
|
this.imported_name._walk(visitor);
|
||||||
|
}
|
||||||
|
if (this.imported_names) {
|
||||||
|
this.imported_names.forEach(function (name_import) {
|
||||||
|
name_import._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.module_name._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
|
||||||
|
$documentation: "An `export` statement",
|
||||||
|
$propdoc: {
|
||||||
|
exported_definition: "[AST_Defun|AST_Definitions|AST_DefClass?] An exported definition",
|
||||||
|
exported_value: "[AST_Node?] An exported value",
|
||||||
|
exported_names: "[AST_NameImport*?] List of exported names",
|
||||||
|
module_name: "[AST_String?] Name of the file to load exports from",
|
||||||
|
is_default: "[Boolean] Whether this is the default exported value of this module"
|
||||||
|
},
|
||||||
|
_walk: function (visitor) {
|
||||||
|
visitor._visit(this, function () {
|
||||||
|
if (this.exported_definition) {
|
||||||
|
this.exported_definition._walk(visitor);
|
||||||
|
}
|
||||||
|
if (this.exported_value) {
|
||||||
|
this.exported_value._walk(visitor);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
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|AST_SymbolConst|AST_Destructuring] 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) {
|
||||||
@@ -600,11 +782,11 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
|||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
this.expression._walk(visitor);
|
|
||||||
var args = this.args;
|
var args = this.args;
|
||||||
for (var i = 0, len = args.length; i < len; i++) {
|
for (var i = 0, len = args.length; i < len; i++) {
|
||||||
args[i]._walk(visitor);
|
args[i]._walk(visitor);
|
||||||
}
|
}
|
||||||
|
this.expression._walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -613,68 +795,16 @@ var AST_New = DEFNODE("New", null, {
|
|||||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
||||||
}, AST_Call);
|
}, AST_Call);
|
||||||
|
|
||||||
var AST_Seq = DEFNODE("Seq", "car cdr", {
|
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||||
$documentation: "A sequence expression (two comma-separated expressions)",
|
$documentation: "A sequence expression (comma-separated expressions)",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
car: "[AST_Node] first element in sequence",
|
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||||
cdr: "[AST_Node] second element in sequence"
|
|
||||||
},
|
|
||||||
$cons: function(x, y) {
|
|
||||||
var seq = new AST_Seq(x);
|
|
||||||
seq.car = x;
|
|
||||||
seq.cdr = y;
|
|
||||||
return seq;
|
|
||||||
},
|
|
||||||
$from_array: function(array) {
|
|
||||||
if (array.length == 0) return null;
|
|
||||||
if (array.length == 1) return array[0].clone();
|
|
||||||
var list = null;
|
|
||||||
for (var i = array.length; --i >= 0;) {
|
|
||||||
list = AST_Seq.cons(array[i], list);
|
|
||||||
}
|
|
||||||
var p = list;
|
|
||||||
while (p) {
|
|
||||||
if (p.cdr && !p.cdr.cdr) {
|
|
||||||
p.cdr = p.cdr.car;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = p.cdr;
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
},
|
|
||||||
to_array: function() {
|
|
||||||
var p = this, a = [];
|
|
||||||
while (p) {
|
|
||||||
a.push(p.car);
|
|
||||||
if (p.cdr && !(p.cdr instanceof AST_Seq)) {
|
|
||||||
a.push(p.cdr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = p.cdr;
|
|
||||||
}
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
add: function(node) {
|
|
||||||
var p = this;
|
|
||||||
while (p) {
|
|
||||||
if (!(p.cdr instanceof AST_Seq)) {
|
|
||||||
var cell = AST_Seq.cons(p.cdr, node);
|
|
||||||
return p.cdr = cell;
|
|
||||||
}
|
|
||||||
p = p.cdr;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
len: function() {
|
|
||||||
if (this.cdr instanceof AST_Seq) {
|
|
||||||
return this.cdr.len() + 1;
|
|
||||||
} else {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_walk: function(visitor) {
|
_walk: function(visitor) {
|
||||||
return visitor._visit(this, function(){
|
return visitor._visit(this, function(){
|
||||||
this.car._walk(visitor);
|
this.expressions.forEach(function(node) {
|
||||||
if (this.cdr) this.cdr._walk(visitor);
|
node._walk(visitor);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -727,7 +857,7 @@ var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, {
|
|||||||
$documentation: "Unary postfix expression, i.e. `i++`"
|
$documentation: "Unary postfix expression, i.e. `i++`"
|
||||||
}, AST_Unary);
|
}, AST_Unary);
|
||||||
|
|
||||||
var AST_Binary = DEFNODE("Binary", "left operator right", {
|
var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||||
$documentation: "Binary expression, i.e. `a + b`",
|
$documentation: "Binary expression, i.e. `a + b`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
left: "[AST_Node] left-hand side expression",
|
left: "[AST_Node] left-hand side expression",
|
||||||
@@ -762,6 +892,10 @@ var AST_Assign = DEFNODE("Assign", null, {
|
|||||||
$documentation: "An assignment expression — `a = b + 5`",
|
$documentation: "An assignment expression — `a = b + 5`",
|
||||||
}, AST_Binary);
|
}, AST_Binary);
|
||||||
|
|
||||||
|
var AST_DefaultAssign = DEFNODE("DefaultAssign", null, {
|
||||||
|
$documentation: "A default assignment expression like in `(a = 3) => a`"
|
||||||
|
}, AST_Binary);
|
||||||
|
|
||||||
/* -----[ LITERALS ]----- */
|
/* -----[ LITERALS ]----- */
|
||||||
|
|
||||||
var AST_Array = DEFNODE("Array", "elements", {
|
var AST_Array = DEFNODE("Array", "elements", {
|
||||||
@@ -797,11 +931,13 @@ 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|AST_Node] the property name converted to a string for ObjectKeyVal. For setters, getters and computed property this is an arbitrary AST_Node",
|
||||||
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(){
|
||||||
|
if (this.key instanceof AST_Node)
|
||||||
|
this.key._walk(visitor);
|
||||||
this.value._walk(visitor);
|
this.value._walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -814,26 +950,73 @@ var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", {
|
|||||||
}
|
}
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
var AST_ObjectSetter = DEFNODE("ObjectSetter", "quote static", {
|
||||||
|
$propdoc: {
|
||||||
|
quote: "[string|undefined] the original quote character, if any",
|
||||||
|
static: "[boolean] whether this is a static setter (classes only)"
|
||||||
|
},
|
||||||
$documentation: "An object setter property",
|
$documentation: "An object setter property",
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
var AST_ObjectGetter = DEFNODE("ObjectGetter", null, {
|
var AST_ObjectGetter = DEFNODE("ObjectGetter", "quote static", {
|
||||||
|
$propdoc: {
|
||||||
|
quote: "[string|undefined] the original quote character, if any",
|
||||||
|
static: "[boolean] whether this is a static getter (classes only)"
|
||||||
|
},
|
||||||
$documentation: "An object getter property",
|
$documentation: "An object getter property",
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_ConciseMethod = DEFNODE("ConciseMethod", "quote static is_generator", {
|
||||||
|
$propdoc: {
|
||||||
|
quote: "[string|undefined] the original quote character, if any",
|
||||||
|
static: "[boolean] whether this method is static (classes only)",
|
||||||
|
is_generator: "[boolean] is generatorFn or not",
|
||||||
|
},
|
||||||
|
$documentation: "An ES6 concise method inside an object or class"
|
||||||
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_Class = DEFNODE("Class", "name extends properties", {
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolClass|AST_SymbolDefClass?] optional class name.",
|
||||||
|
extends: "[AST_Node]? optional parent class",
|
||||||
|
properties: "[AST_ObjectProperty*] array of properties"
|
||||||
|
},
|
||||||
|
$documentation: "An ES6 class",
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, function(){
|
||||||
|
if (this.name) {
|
||||||
|
this.name._walk(visitor);
|
||||||
|
}
|
||||||
|
if (this.extends) {
|
||||||
|
this.extends._walk(visitor);
|
||||||
|
}
|
||||||
|
this.properties.forEach(function(prop){
|
||||||
|
prop._walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}, AST_Scope);
|
||||||
|
|
||||||
|
var AST_DefClass = DEFNODE("DefClass", null, {
|
||||||
|
$documentation: "A class definition",
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
|
var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||||
|
$documentation: "A class expression."
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[string] name of this symbol",
|
name: "[string] name of this symbol",
|
||||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||||
},
|
},
|
||||||
$documentation: "Base class for all symbols",
|
$documentation: "Base class for all symbols"
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, {
|
var AST_NewTarget = DEFNODE("NewTarget", null, {
|
||||||
$documentation: "The name of a property accessor (setter/getter function)"
|
$documentation: "A reference to new.target"
|
||||||
}, 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/const, function name or argument, symbol in catch)",
|
||||||
@@ -843,9 +1026,17 @@ var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
|||||||
$documentation: "Symbol defining a variable",
|
$documentation: "Symbol defining a variable",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolBlockDeclaration = DEFNODE("SymbolBlockDeclaration", null, {
|
||||||
|
$documentation: "Base class for block-scoped declaration symbols"
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||||
$documentation: "A constant declaration"
|
$documentation: "A constant declaration"
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolLet = DEFNODE("SymbolLet", null, {
|
||||||
|
$documentation: "A block-scoped `let` declaration"
|
||||||
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||||
$documentation: "Symbol naming a function argument",
|
$documentation: "Symbol naming a function argument",
|
||||||
@@ -855,13 +1046,33 @@ var AST_SymbolDefun = DEFNODE("SymbolDefun", null, {
|
|||||||
$documentation: "Symbol defining a function",
|
$documentation: "Symbol defining a function",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolMethod = DEFNODE("SymbolMethod", null, {
|
||||||
|
$documentation: "Symbol in an object defining a method",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
||||||
$documentation: "Symbol naming a function expression",
|
$documentation: "Symbol naming a function expression",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, {
|
||||||
|
$documentation: "Symbol naming a class's name in a class declaration. Lexically scoped to its containing scope, and accessible within the class."
|
||||||
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolClass = DEFNODE("SymbolClass", null, {
|
||||||
|
$documentation: "Symbol naming a class's name. Lexically scoped to the class."
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
||||||
$documentation: "Symbol naming the exception in catch",
|
$documentation: "Symbol naming the exception in catch",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolImport = DEFNODE("SymbolImport", null, {
|
||||||
|
$documentation: "Symbol refering to an imported name",
|
||||||
|
}, AST_SymbolBlockDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolImportForeign = DEFNODE("SymbolImportForeign", null, {
|
||||||
|
$documentation: "A symbol imported from a module, but it is defined in the other module, and its real name is irrelevant for this module's purposes",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_Label = DEFNODE("Label", "references", {
|
var AST_Label = DEFNODE("Label", "references", {
|
||||||
$documentation: "Symbol naming a label (declaration)",
|
$documentation: "Symbol naming a label (declaration)",
|
||||||
@@ -886,6 +1097,10 @@ var AST_This = DEFNODE("This", null, {
|
|||||||
$documentation: "The `this` symbol",
|
$documentation: "The `this` symbol",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_Super = DEFNODE("Super", null, {
|
||||||
|
$documentation: "The `super` symbol",
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_Constant = DEFNODE("Constant", null, {
|
var AST_Constant = DEFNODE("Constant", null, {
|
||||||
$documentation: "Base class for all constants",
|
$documentation: "Base class for all constants",
|
||||||
getValue: function() {
|
getValue: function() {
|
||||||
@@ -959,6 +1174,21 @@ var AST_True = DEFNODE("True", null, {
|
|||||||
value: true
|
value: true
|
||||||
}, AST_Boolean);
|
}, AST_Boolean);
|
||||||
|
|
||||||
|
/* -----[ Yield ]----- */
|
||||||
|
|
||||||
|
var AST_Yield = DEFNODE("Yield", "expression is_star", {
|
||||||
|
$documentation: "A `yield` statement",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node?] the value returned or thrown by this statement; could be null (representing undefined) but only when is_star is set to false",
|
||||||
|
is_star: "[Boolean] Whether this is a yield or yield* statement"
|
||||||
|
},
|
||||||
|
_walk: function(visitor) {
|
||||||
|
return visitor._visit(this, this.expression && function(){
|
||||||
|
this.expression._walk(visitor);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ TreeWalker ]----- */
|
/* -----[ TreeWalker ]----- */
|
||||||
|
|
||||||
function TreeWalker(callback) {
|
function TreeWalker(callback) {
|
||||||
@@ -981,17 +1211,22 @@ TreeWalker.prototype = {
|
|||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||||
},
|
},
|
||||||
push: function (node) {
|
push: function(node) {
|
||||||
if (node instanceof AST_Lambda) {
|
if (node instanceof AST_Lambda) {
|
||||||
this.directives = Object.create(this.directives);
|
this.directives = Object.create(this.directives);
|
||||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||||
this.directives[node.value] = node;
|
this.directives[node.value] = node;
|
||||||
|
} else if (node instanceof AST_Class) {
|
||||||
|
this.directives = Object.create(this.directives);
|
||||||
|
if (!this.directives["use strict"]) {
|
||||||
|
this.directives["use strict"] = node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function(node) {
|
pop: function(node) {
|
||||||
this.stack.pop();
|
this.stack.pop();
|
||||||
if (node instanceof AST_Lambda) {
|
if (node instanceof AST_Lambda || node instanceof AST_Class) {
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -1009,7 +1244,7 @@ TreeWalker.prototype = {
|
|||||||
var dir = this.directives[type];
|
var dir = this.directives[type];
|
||||||
if (dir) return dir;
|
if (dir) return dir;
|
||||||
var node = this.stack[this.stack.length - 1];
|
var node = this.stack[this.stack.length - 1];
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope && node.body) {
|
||||||
for (var i = 0; i < node.body.length; ++i) {
|
for (var i = 0; i < node.body.length; ++i) {
|
||||||
var st = node.body[i];
|
var st = node.body[i];
|
||||||
if (!(st instanceof AST_Directive)) break;
|
if (!(st instanceof AST_Directive)) break;
|
||||||
|
|||||||
1897
lib/compress.js
1897
lib/compress.js
File diff suppressed because it is too large
Load Diff
156
lib/minify.js
Normal file
156
lib/minify.js
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
var to_ascii = typeof atob == "undefined" ? function(b64) {
|
||||||
|
return new Buffer(b64, "base64").toString();
|
||||||
|
} : atob;
|
||||||
|
var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||||
|
return new Buffer(str).toString("base64");
|
||||||
|
} : btoa;
|
||||||
|
|
||||||
|
function read_source_map(code) {
|
||||||
|
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||||
|
if (!match) {
|
||||||
|
AST_Node.warn("inline source map not found");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return to_ascii(match[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function set_shorthand(name, options, keys) {
|
||||||
|
if (options[name]) {
|
||||||
|
keys.forEach(function(key) {
|
||||||
|
if (options[key]) {
|
||||||
|
if (typeof options[key] != "object") options[key] = {};
|
||||||
|
if (!(name in options[key])) options[key][name] = options[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function minify(files, options) {
|
||||||
|
var warn_function = AST_Node.warn_function;
|
||||||
|
try {
|
||||||
|
if (typeof files == "string") {
|
||||||
|
files = [ files ];
|
||||||
|
}
|
||||||
|
options = defaults(options, {
|
||||||
|
compress: {},
|
||||||
|
ie8: false,
|
||||||
|
keep_fnames: false,
|
||||||
|
mangle: {},
|
||||||
|
output: {},
|
||||||
|
parse: {},
|
||||||
|
sourceMap: false,
|
||||||
|
toplevel: false,
|
||||||
|
warnings: false,
|
||||||
|
wrap: false,
|
||||||
|
}, true);
|
||||||
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
|
set_shorthand("warnings", options, [ "compress" ]);
|
||||||
|
if (options.mangle) {
|
||||||
|
options.mangle = defaults(options.mangle, {
|
||||||
|
cache: null,
|
||||||
|
eval: false,
|
||||||
|
ie8: false,
|
||||||
|
keep_classnames: false,
|
||||||
|
keep_fnames: false,
|
||||||
|
properties: false,
|
||||||
|
reserved: [],
|
||||||
|
safari10: false,
|
||||||
|
toplevel: false,
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
if (options.sourceMap) {
|
||||||
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
|
content: null,
|
||||||
|
filename: null,
|
||||||
|
includeSources: false,
|
||||||
|
root: null,
|
||||||
|
url: null,
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
var warnings = [];
|
||||||
|
if (options.warnings && !AST_Node.warn_function) {
|
||||||
|
AST_Node.warn_function = function(warning) {
|
||||||
|
warnings.push(warning);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var toplevel;
|
||||||
|
if (files instanceof AST_Toplevel) {
|
||||||
|
toplevel = files;
|
||||||
|
} else {
|
||||||
|
options.parse = options.parse || {};
|
||||||
|
options.parse.toplevel = null;
|
||||||
|
for (var name in files) {
|
||||||
|
options.parse.filename = name;
|
||||||
|
options.parse.toplevel = parse(files[name], options.parse);
|
||||||
|
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
|
if (Object.keys(files).length > 1)
|
||||||
|
throw new Error("inline source map only works with singular input");
|
||||||
|
options.sourceMap.content = read_source_map(files[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
toplevel = options.parse.toplevel;
|
||||||
|
}
|
||||||
|
if (options.wrap) {
|
||||||
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
|
}
|
||||||
|
if (options.compress) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
|
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
|
}
|
||||||
|
if (options.mangle) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
|
base54.reset();
|
||||||
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
|
toplevel.mangle_names(options.mangle);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var result = {};
|
||||||
|
if (options.output.ast) {
|
||||||
|
result.ast = toplevel;
|
||||||
|
}
|
||||||
|
if (!HOP(options.output, "code") || options.output.code) {
|
||||||
|
if (options.sourceMap) {
|
||||||
|
if (typeof options.sourceMap.content == "string") {
|
||||||
|
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||||
|
}
|
||||||
|
options.output.source_map = SourceMap({
|
||||||
|
file: options.sourceMap.filename,
|
||||||
|
orig: options.sourceMap.content,
|
||||||
|
root: options.sourceMap.root
|
||||||
|
});
|
||||||
|
if (options.sourceMap.includeSources) {
|
||||||
|
for (var name in files) {
|
||||||
|
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete options.output.ast;
|
||||||
|
delete options.output.code;
|
||||||
|
var stream = OutputStream(options.output);
|
||||||
|
toplevel.print(stream);
|
||||||
|
result.code = stream.get();
|
||||||
|
if (options.sourceMap) {
|
||||||
|
result.map = options.output.source_map.toString();
|
||||||
|
if (options.sourceMap.url == "inline") {
|
||||||
|
result.code += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64," + to_base64(result.map);
|
||||||
|
} else if (options.sourceMap.url) {
|
||||||
|
result.code += "\n//# sourceMappingURL=" + options.sourceMap.url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (warnings.length) {
|
||||||
|
result.warnings = warnings;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} catch (ex) {
|
||||||
|
return { error: ex };
|
||||||
|
} finally {
|
||||||
|
AST_Node.warn_function = warn_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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_SymbolMethod({
|
||||||
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({
|
||||||
@@ -149,7 +145,11 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
SequenceExpression: function(M) {
|
SequenceExpression: function(M) {
|
||||||
return AST_Seq.from_array(M.expressions.map(from_moz));
|
return new AST_Sequence({
|
||||||
|
start : my_start_token(M),
|
||||||
|
end : my_end_token(M),
|
||||||
|
expressions: M.expressions.map(from_moz)
|
||||||
|
});
|
||||||
},
|
},
|
||||||
MemberExpression: function(M) {
|
MemberExpression: function(M) {
|
||||||
return new (M.computed ? AST_Sub : AST_Dot)({
|
return new (M.computed ? AST_Sub : AST_Dot)({
|
||||||
@@ -256,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) {
|
||||||
@@ -267,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)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -276,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)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -332,10 +329,10 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
def_to_moz(AST_Seq, function To_Moz_SequenceExpression(M) {
|
def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
|
||||||
return {
|
return {
|
||||||
type: "SequenceExpression",
|
type: "SequenceExpression",
|
||||||
expressions: M.to_array().map(to_moz)
|
expressions: M.expressions.map(to_moz)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -382,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_SymbolMethod ? 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";
|
||||||
@@ -547,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);
|
||||||
@@ -606,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
|
||||||
|
};
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
|
|||||||
464
lib/output.js
464
lib/output.js
@@ -54,9 +54,12 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
|
ascii_identifiers: undefined,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
bracketize : false,
|
bracketize : false,
|
||||||
comments : false,
|
comments : false,
|
||||||
|
ecma : 5,
|
||||||
|
ie8 : false,
|
||||||
indent_level : 4,
|
indent_level : 4,
|
||||||
indent_start : 0,
|
indent_start : 0,
|
||||||
inline_script : true,
|
inline_script : true,
|
||||||
@@ -66,9 +69,9 @@ function OutputStream(options) {
|
|||||||
preserve_line : false,
|
preserve_line : false,
|
||||||
quote_keys : false,
|
quote_keys : false,
|
||||||
quote_style : 0,
|
quote_style : 0,
|
||||||
screw_ie8 : true,
|
|
||||||
semicolons : true,
|
semicolons : true,
|
||||||
shebang : true,
|
shebang : true,
|
||||||
|
shorthand : undefined,
|
||||||
source_map : null,
|
source_map : null,
|
||||||
space_colon : true,
|
space_colon : true,
|
||||||
unescape_regexps : false,
|
unescape_regexps : false,
|
||||||
@@ -76,6 +79,12 @@ function OutputStream(options) {
|
|||||||
wrap_iife : false,
|
wrap_iife : false,
|
||||||
}, true);
|
}, true);
|
||||||
|
|
||||||
|
if (typeof options.ascii_identifiers === 'undefined')
|
||||||
|
options.ascii_identifiers = options.ascii_only;
|
||||||
|
|
||||||
|
if (options.shorthand === undefined)
|
||||||
|
options.shorthand = options.ecma > 5;
|
||||||
|
|
||||||
// Convert comment option to RegExp if neccessary and set up comments filter
|
// Convert comment option to RegExp if neccessary and set up comments filter
|
||||||
var comment_filter = return_false; // Default case, throw all comments away
|
var comment_filter = return_false; // Default case, throw all comments away
|
||||||
if (options.comments) {
|
if (options.comments) {
|
||||||
@@ -111,9 +120,19 @@ function OutputStream(options) {
|
|||||||
var OUTPUT = "";
|
var OUTPUT = "";
|
||||||
|
|
||||||
function to_ascii(str, identifier) {
|
function to_ascii(str, identifier) {
|
||||||
return str.replace(/[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
return str.replace(/[\ud800-\udbff][\udc00-\udfff]|[\u0000-\u001f\u007f-\uffff]/g, function(ch) {
|
||||||
var code = ch.charCodeAt(0).toString(16);
|
var code = get_full_char_code(ch, 0).toString(16);
|
||||||
if (code.length <= 2 && !identifier) {
|
|
||||||
|
if ((identifier && code.length === 1 && options.ecma >= 6) || code.length > 4) {
|
||||||
|
if (options.ecma < 6) {
|
||||||
|
if (identifier) {
|
||||||
|
return ch; // no \u{} support
|
||||||
|
}
|
||||||
|
return "\\u" + ch.charCodeAt(0).toString(16) + "\\u"
|
||||||
|
+ ch.charCodeAt(1).toString(16);
|
||||||
|
}
|
||||||
|
return "\\u{" + code + "}";
|
||||||
|
} else if (code.length <= 2 && !identifier) {
|
||||||
while (code.length < 2) code = "0" + code;
|
while (code.length < 2) code = "0" + code;
|
||||||
return "\\x" + code;
|
return "\\x" + code;
|
||||||
} else {
|
} else {
|
||||||
@@ -136,12 +155,12 @@ function OutputStream(options) {
|
|||||||
case "\t": return "\\t";
|
case "\t": return "\\t";
|
||||||
case "\b": return "\\b";
|
case "\b": return "\\b";
|
||||||
case "\f": return "\\f";
|
case "\f": return "\\f";
|
||||||
case "\x0B": return options.screw_ie8 ? "\\v" : "\\x0B";
|
case "\x0B": return options.ie8 ? "\\x0B" : "\\v";
|
||||||
case "\u2028": return "\\u2028";
|
case "\u2028": return "\\u2028";
|
||||||
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-7]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
@@ -151,7 +170,11 @@ function OutputStream(options) {
|
|||||||
function quote_double() {
|
function quote_double() {
|
||||||
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
||||||
}
|
}
|
||||||
|
function quote_template() {
|
||||||
|
return '`' + str.replace(/`/g, '\\`') + '`';
|
||||||
|
}
|
||||||
if (options.ascii_only) str = to_ascii(str);
|
if (options.ascii_only) str = to_ascii(str);
|
||||||
|
if (quote === "`") return quote_template();
|
||||||
switch (options.quote_style) {
|
switch (options.quote_style) {
|
||||||
case 1:
|
case 1:
|
||||||
return quote_single();
|
return quote_single();
|
||||||
@@ -176,7 +199,7 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function make_name(name) {
|
function make_name(name) {
|
||||||
name = name.toString();
|
name = name.toString();
|
||||||
if (options.ascii_only)
|
if (options.ascii_identifiers)
|
||||||
name = to_ascii(name, true);
|
name = to_ascii(name, true);
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
@@ -190,11 +213,7 @@ 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 last = null;
|
var last = "";
|
||||||
|
|
||||||
function last_char() {
|
|
||||||
return last.charAt(last.length - 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
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) {
|
||||||
@@ -217,11 +236,12 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function print(str) {
|
function print(str) {
|
||||||
str = String(str);
|
str = String(str);
|
||||||
var ch = str.charAt(0);
|
var ch = get_full_char(str, 0);
|
||||||
|
var prev = get_full_char(last, last.length - 1);
|
||||||
if (might_need_semicolon) {
|
if (might_need_semicolon) {
|
||||||
might_need_semicolon = false;
|
might_need_semicolon = false;
|
||||||
|
|
||||||
if ((!ch || ";}".indexOf(ch) < 0) && !/[;]$/.test(last)) {
|
if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
|
||||||
if (options.semicolons || requireSemicolonChars(ch)) {
|
if (options.semicolons || requireSemicolonChars(ch)) {
|
||||||
OUTPUT += ";";
|
OUTPUT += ";";
|
||||||
current_col++;
|
current_col++;
|
||||||
@@ -258,7 +278,6 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (might_need_space) {
|
if (might_need_space) {
|
||||||
var prev = last_char();
|
|
||||||
if ((is_identifier_char(prev)
|
if ((is_identifier_char(prev)
|
||||||
&& (is_identifier_char(ch) || ch == "\\"))
|
&& (is_identifier_char(ch) || ch == "\\"))
|
||||||
|| (ch == "/" && ch == prev)
|
|| (ch == "/" && ch == prev)
|
||||||
@@ -282,6 +301,10 @@ function OutputStream(options) {
|
|||||||
last = str;
|
last = str;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var star = function(){
|
||||||
|
print("*");
|
||||||
|
}
|
||||||
|
|
||||||
var space = options.beautify ? function() {
|
var space = options.beautify ? function() {
|
||||||
print(" ");
|
print(" ");
|
||||||
} : function() {
|
} : function() {
|
||||||
@@ -401,6 +424,7 @@ function OutputStream(options) {
|
|||||||
should_break : function() { return options.width && this.current_width() >= options.width },
|
should_break : function() { return options.width && this.current_width() >= options.width },
|
||||||
newline : newline,
|
newline : newline,
|
||||||
print : print,
|
print : print,
|
||||||
|
star : star,
|
||||||
space : space,
|
space : space,
|
||||||
comma : comma,
|
comma : comma,
|
||||||
colon : colon,
|
colon : colon,
|
||||||
@@ -420,6 +444,10 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
print(encoded);
|
print(encoded);
|
||||||
},
|
},
|
||||||
|
print_template_string_chars: function(str) {
|
||||||
|
var encoded = encode_string(str, '`').replace(/\${/g, "\\${");
|
||||||
|
return print(encoded.substr(1, encoded.length - 2));
|
||||||
|
},
|
||||||
encode_string : encode_string,
|
encode_string : encode_string,
|
||||||
next_indent : next_indent,
|
next_indent : next_indent,
|
||||||
with_indent : with_indent,
|
with_indent : with_indent,
|
||||||
@@ -580,6 +608,11 @@ function OutputStream(options) {
|
|||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PARENS(AST_Arrow, function(output){
|
||||||
|
var p = output.parent();
|
||||||
|
return p instanceof AST_PropAccess && p.expression === this;
|
||||||
|
});
|
||||||
|
|
||||||
// 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, function(output){
|
||||||
@@ -589,20 +622,29 @@ function OutputStream(options) {
|
|||||||
PARENS(AST_Unary, function(output){
|
PARENS(AST_Unary, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_PropAccess && p.expression === this
|
return p instanceof AST_PropAccess && p.expression === this
|
||||||
|| p instanceof AST_Call && p.expression === this;
|
|| p instanceof AST_Call && p.expression === this
|
||||||
|
|| p instanceof AST_Binary
|
||||||
|
&& p.operator === "**"
|
||||||
|
&& this instanceof AST_UnaryPrefix
|
||||||
|
&& p.left === this
|
||||||
|
&& this.operator !== "++"
|
||||||
|
&& this.operator !== "--";
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS(AST_Seq, function(output){
|
PARENS(AST_Sequence, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|
||||||
|| p instanceof AST_Unary // !(foo, bar, baz)
|
|| p instanceof AST_Unary // !(foo, bar, baz)
|
||||||
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8
|
||||||
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|
||||||
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
||||||
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|
||||||
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|
||||||
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
|
||||||
* ==> 20 (side effect, set a := 10 and b := 20) */
|
* ==> 20 (side effect, set a := 10 and b := 20) */
|
||||||
|
|| p instanceof AST_Arrow // x => (x, x)
|
||||||
|
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
|
||||||
|
|| (p instanceof AST_Class && p.extends === this) // class D extends (calls++, C) {}
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -629,6 +671,24 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
PARENS(AST_Yield, function(output){
|
||||||
|
var p = output.parent();
|
||||||
|
// (yield 1) + (yield 2)
|
||||||
|
// a = yield 3
|
||||||
|
if (p instanceof AST_Binary && p.operator !== "=")
|
||||||
|
return true;
|
||||||
|
// (yield 1) ? yield 2 : yield 3
|
||||||
|
if (p instanceof AST_Conditional && p.condition === this)
|
||||||
|
return true;
|
||||||
|
// -(yield 4)
|
||||||
|
if (p instanceof AST_Unary)
|
||||||
|
return true;
|
||||||
|
// (yield x).foo
|
||||||
|
// (yield x)['foo']
|
||||||
|
if (p instanceof AST_PropAccess && p.expression === this)
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
PARENS(AST_PropAccess, function(output){
|
PARENS(AST_PropAccess, function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_New && p.expression === this) {
|
if (p instanceof AST_New && p.expression === this) {
|
||||||
@@ -681,7 +741,7 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
PARENS([ AST_Assign, AST_Conditional ], function (output){
|
PARENS([ AST_Assign, AST_Conditional ], function(output){
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
// !(a = false) → true
|
// !(a = false) → true
|
||||||
if (p instanceof AST_Unary)
|
if (p instanceof AST_Unary)
|
||||||
@@ -698,6 +758,9 @@ function OutputStream(options) {
|
|||||||
// (a = foo)["prop"] —or— (a = foo).prop
|
// (a = foo)["prop"] —or— (a = foo).prop
|
||||||
if (p instanceof AST_PropAccess && p.expression === this)
|
if (p instanceof AST_PropAccess && p.expression === this)
|
||||||
return true;
|
return true;
|
||||||
|
// ({a, b} = {a: 1, b: 2}), a destructuring assignment
|
||||||
|
if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false)
|
||||||
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* -----[ PRINTERS ]----- */
|
/* -----[ PRINTERS ]----- */
|
||||||
@@ -706,6 +769,28 @@ function OutputStream(options) {
|
|||||||
output.print_string(self.value, self.quote);
|
output.print_string(self.value, self.quote);
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_Expansion, function (self, output) {
|
||||||
|
output.print('...');
|
||||||
|
self.expression.print(output);
|
||||||
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_Destructuring, function (self, output) {
|
||||||
|
output.print(self.is_array ? "[" : "{");
|
||||||
|
var first = true;
|
||||||
|
var len = self.names.length;
|
||||||
|
self.names.forEach(function (name, i) {
|
||||||
|
if (first) first = false; else { output.comma(); output.space(); }
|
||||||
|
name.print(output);
|
||||||
|
// If the final element is a hole, we need to make sure it
|
||||||
|
// doesn't look like a trailing comma, by inserting an actual
|
||||||
|
// trailing comma.
|
||||||
|
if (i === len - 1 && name instanceof AST_Hole)
|
||||||
|
output.comma();
|
||||||
|
})
|
||||||
|
output.print(self.is_array ? "]" : "}");
|
||||||
|
});
|
||||||
|
|
||||||
DEFPRINT(AST_Debugger, function(self, output){
|
DEFPRINT(AST_Debugger, function(self, output){
|
||||||
output.print("debugger");
|
output.print("debugger");
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
@@ -830,7 +915,11 @@ function OutputStream(options) {
|
|||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
self.init.print(output);
|
self.init.print(output);
|
||||||
output.space();
|
output.space();
|
||||||
output.print("in");
|
if (self instanceof AST_ForOf) {
|
||||||
|
output.print("of");
|
||||||
|
} else {
|
||||||
|
output.print("in");
|
||||||
|
}
|
||||||
output.space();
|
output.space();
|
||||||
self.object.print(output);
|
self.object.print(output);
|
||||||
});
|
});
|
||||||
@@ -852,10 +941,19 @@ function OutputStream(options) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
if (!nokeyword) {
|
if (!nokeyword) {
|
||||||
output.print("function");
|
output.print("function");
|
||||||
|
if (this.is_generator) {
|
||||||
|
output.star();
|
||||||
|
}
|
||||||
|
if (self.name) {
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (self.name) {
|
if (self.name instanceof AST_Symbol) {
|
||||||
output.space();
|
|
||||||
self.name.print(output);
|
self.name.print(output);
|
||||||
|
} else if (nokeyword && self.name instanceof AST_Node) {
|
||||||
|
output.with_square(function() {
|
||||||
|
self.name.print(output); // Computed method name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
self.argnames.forEach(function(arg, i){
|
self.argnames.forEach(function(arg, i){
|
||||||
@@ -870,6 +968,56 @@ function OutputStream(options) {
|
|||||||
self._do_print(output);
|
self._do_print(output);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_PrefixedTemplateString, function(self, output) {
|
||||||
|
self.prefix.print(output);
|
||||||
|
self.template_string.print(output);
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_TemplateString, function(self, output) {
|
||||||
|
var is_tagged = output.parent() instanceof AST_PrefixedTemplateString;
|
||||||
|
|
||||||
|
output.print("`");
|
||||||
|
for (var i = 0; i < self.segments.length; i++) {
|
||||||
|
if (!(self.segments[i] instanceof AST_TemplateSegment)) {
|
||||||
|
output.print("${");
|
||||||
|
self.segments[i].print(output);
|
||||||
|
output.print("}");
|
||||||
|
} else if (is_tagged) {
|
||||||
|
output.print(self.segments[i].raw);
|
||||||
|
} else {
|
||||||
|
output.print_template_string_chars(self.segments[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
output.print("`");
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Arrow.DEFMETHOD("_do_print", function(output){
|
||||||
|
var self = this;
|
||||||
|
var parent = output.parent();
|
||||||
|
var needs_parens = parent instanceof AST_Binary ||
|
||||||
|
parent instanceof AST_Unary ||
|
||||||
|
(parent instanceof AST_Call && self === parent.expression);
|
||||||
|
if (needs_parens) { output.print("(") }
|
||||||
|
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
|
||||||
|
self.argnames[0].print(output);
|
||||||
|
} else {
|
||||||
|
output.with_parens(function(){
|
||||||
|
self.argnames.forEach(function(arg, i){
|
||||||
|
if (i) output.comma();
|
||||||
|
arg.print(output);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
output.space();
|
||||||
|
output.print('=>');
|
||||||
|
output.space();
|
||||||
|
if (self.body instanceof AST_Node) {
|
||||||
|
this.body.print(output);
|
||||||
|
} else {
|
||||||
|
print_bracketed(this.body, output);
|
||||||
|
}
|
||||||
|
if (needs_parens) { output.print(")") }
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ exits ]----- */
|
/* -----[ exits ]----- */
|
||||||
AST_Exit.DEFMETHOD("_do_print", function(output, kind){
|
AST_Exit.DEFMETHOD("_do_print", function(output, kind){
|
||||||
output.print(kind);
|
output.print(kind);
|
||||||
@@ -886,6 +1034,17 @@ function OutputStream(options) {
|
|||||||
self._do_print(output, "throw");
|
self._do_print(output, "throw");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* -----[ yield ]----- */
|
||||||
|
|
||||||
|
DEFPRINT(AST_Yield, function(self, output){
|
||||||
|
var star = self.is_star ? "*" : "";
|
||||||
|
output.print("yield" + star);
|
||||||
|
if (self.expression) {
|
||||||
|
output.space();
|
||||||
|
self.expression.print(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ loop control ]----- */
|
/* -----[ loop control ]----- */
|
||||||
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
|
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
|
||||||
output.print(kind);
|
output.print(kind);
|
||||||
@@ -906,7 +1065,7 @@ function OutputStream(options) {
|
|||||||
function make_then(self, output) {
|
function make_then(self, output) {
|
||||||
var b = self.body;
|
var b = self.body;
|
||||||
if (output.option("bracketize")
|
if (output.option("bracketize")
|
||||||
|| !output.option("screw_ie8") && b instanceof AST_Do)
|
|| output.option("ie8") && b instanceof AST_Do)
|
||||||
return make_block(b, output);
|
return make_block(b, output);
|
||||||
// The squeezer replaces "block"-s that contain only a single
|
// The squeezer replaces "block"-s that contain only a single
|
||||||
// statement with the statement itself; technically, the AST
|
// statement with the statement itself; technically, the AST
|
||||||
@@ -1034,12 +1193,107 @@ function OutputStream(options) {
|
|||||||
if (!avoid_semicolon)
|
if (!avoid_semicolon)
|
||||||
output.semicolon();
|
output.semicolon();
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Let, function(self, output){
|
||||||
|
self._do_print(output, "let");
|
||||||
|
});
|
||||||
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){
|
DEFPRINT(AST_Const, function(self, output){
|
||||||
self._do_print(output, "const");
|
self._do_print(output, "const");
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Import, function(self, output) {
|
||||||
|
output.print("import");
|
||||||
|
output.space();
|
||||||
|
if (self.imported_name) {
|
||||||
|
self.imported_name.print(output);
|
||||||
|
}
|
||||||
|
if (self.imported_name && self.imported_names) {
|
||||||
|
output.print(",");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.imported_names) {
|
||||||
|
if (self.imported_names.length === 1 && self.imported_names[0].foreign_name.name === "*") {
|
||||||
|
self.imported_names[0].print(output);
|
||||||
|
} else {
|
||||||
|
output.print("{");
|
||||||
|
self.imported_names.forEach(function (name_import, i) {
|
||||||
|
output.space();
|
||||||
|
name_import.print(output);
|
||||||
|
if (i < self.imported_names.length - 1) {
|
||||||
|
output.print(",");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
output.space();
|
||||||
|
output.print("}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self.imported_name || self.imported_names) {
|
||||||
|
output.space();
|
||||||
|
output.print("from")
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
self.module_name.print(output);
|
||||||
|
output.semicolon();
|
||||||
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_NameImport, function(self, output) {
|
||||||
|
var definition = self.name.definition();
|
||||||
|
var names_are_different =
|
||||||
|
(definition && definition.mangled_name || self.name.name) !==
|
||||||
|
self.foreign_name.name;
|
||||||
|
if (names_are_different) {
|
||||||
|
output.print(self.foreign_name.name);
|
||||||
|
output.space();
|
||||||
|
output.print("as");
|
||||||
|
output.space();
|
||||||
|
self.name.print(output);
|
||||||
|
} else {
|
||||||
|
self.name.print(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
DEFPRINT(AST_Export, function(self, output) {
|
||||||
|
output.print("export");
|
||||||
|
output.space();
|
||||||
|
if (self.is_default) {
|
||||||
|
output.print("default");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.exported_names) {
|
||||||
|
output.space();
|
||||||
|
|
||||||
|
if (self.exported_names.length === 1 && self.exported_names[0].name.name === "*") {
|
||||||
|
self.exported_names[0].print(output);
|
||||||
|
} else {
|
||||||
|
output.print("{");
|
||||||
|
self.exported_names.forEach(function (name_import, i) {
|
||||||
|
output.space();
|
||||||
|
name_import.print(output);
|
||||||
|
if (i < self.exported_names.length - 1) {
|
||||||
|
output.print(",");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
output.space();
|
||||||
|
output.print("}");
|
||||||
|
}
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
else if (self.exported_value) {
|
||||||
|
self.exported_value.print(output);
|
||||||
|
} else if (self.exported_definition) {
|
||||||
|
self.exported_definition.print(output);
|
||||||
|
}
|
||||||
|
if (self.module_name) {
|
||||||
|
output.space();
|
||||||
|
output.print("from");
|
||||||
|
output.space();
|
||||||
|
self.module_name.print(output);
|
||||||
|
}
|
||||||
|
output.semicolon();
|
||||||
|
});
|
||||||
|
|
||||||
function parenthesize_for_noin(node, output, noin) {
|
function parenthesize_for_noin(node, output, noin) {
|
||||||
if (!noin) node.print(output);
|
if (!noin) node.print(output);
|
||||||
@@ -1087,18 +1341,19 @@ function OutputStream(options) {
|
|||||||
AST_Call.prototype._codegen(self, output);
|
AST_Call.prototype._codegen(self, output);
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Seq.DEFMETHOD("_do_print", function(output){
|
AST_Sequence.DEFMETHOD("_do_print", function(output){
|
||||||
this.car.print(output);
|
this.expressions.forEach(function(node, index) {
|
||||||
if (this.cdr) {
|
if (index > 0) {
|
||||||
output.comma();
|
output.comma();
|
||||||
if (output.should_break()) {
|
if (output.should_break()) {
|
||||||
output.newline();
|
output.newline();
|
||||||
output.indent();
|
output.indent();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.cdr.print(output);
|
node.print(output);
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Seq, function(self, output){
|
DEFPRINT(AST_Sequence, function(self, output){
|
||||||
self._do_print(output);
|
self._do_print(output);
|
||||||
// var p = output.parent();
|
// var p = output.parent();
|
||||||
// if (p instanceof AST_Statement) {
|
// if (p instanceof AST_Statement) {
|
||||||
@@ -1211,9 +1466,35 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
else output.print("{}");
|
else output.print("{}");
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
DEFPRINT(AST_Class, function(self, output){
|
||||||
var key = self.key;
|
output.print("class");
|
||||||
var quote = self.quote;
|
output.space();
|
||||||
|
if (self.name) {
|
||||||
|
self.name.print(output);
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.extends) {
|
||||||
|
output.print("extends");
|
||||||
|
output.space();
|
||||||
|
self.extends.print(output);
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.properties.length > 0) output.with_block(function(){
|
||||||
|
self.properties.forEach(function(prop, i){
|
||||||
|
if (i) {
|
||||||
|
output.newline();
|
||||||
|
}
|
||||||
|
output.indent();
|
||||||
|
prop.print(output);
|
||||||
|
});
|
||||||
|
output.newline();
|
||||||
|
});
|
||||||
|
else output.print("{}");
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_NewTarget, function(self, output) {
|
||||||
|
output.print("new.target");
|
||||||
|
});
|
||||||
|
AST_ObjectProperty.DEFMETHOD("print_property_name", function(key, quote, output) {
|
||||||
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"
|
||||||
@@ -1221,7 +1502,7 @@ function OutputStream(options) {
|
|||||||
&& +key + "" == key)
|
&& +key + "" == key)
|
||||||
&& parseFloat(key) >= 0) {
|
&& parseFloat(key) >= 0) {
|
||||||
output.print(make_num(key));
|
output.print(make_num(key));
|
||||||
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) {
|
} else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) {
|
||||||
if (quote && output.option("keep_quoted_props")) {
|
if (quote && output.option("keep_quoted_props")) {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
} else {
|
} else {
|
||||||
@@ -1230,29 +1511,98 @@ function OutputStream(options) {
|
|||||||
} else {
|
} else {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
}
|
}
|
||||||
output.colon();
|
});
|
||||||
self.value.print(output);
|
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
||||||
|
function get_name(self) {
|
||||||
|
var def = self.definition();
|
||||||
|
return def ? def.mangled_name || def.name : self.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
var allowShortHand = output.option("shorthand");
|
||||||
|
if (allowShortHand &&
|
||||||
|
self.value instanceof AST_Symbol &&
|
||||||
|
is_identifier_string(self.key) &&
|
||||||
|
get_name(self.value) === self.key
|
||||||
|
) {
|
||||||
|
self.print_property_name(self.key, self.quote, output);
|
||||||
|
|
||||||
|
} else if (allowShortHand &&
|
||||||
|
self.value instanceof AST_DefaultAssign &&
|
||||||
|
self.value.left instanceof AST_Symbol &&
|
||||||
|
is_identifier_string(self.key) &&
|
||||||
|
get_name(self.value.left) === self.key
|
||||||
|
) {
|
||||||
|
self.print_property_name(self.key, self.quote, output);
|
||||||
|
output.print("=");
|
||||||
|
self.value.right.print(output);
|
||||||
|
} else {
|
||||||
|
if (!(self.key instanceof AST_Node)) {
|
||||||
|
self.print_property_name(self.key, self.quote, output);
|
||||||
|
} else {
|
||||||
|
output.with_square(function() {
|
||||||
|
self.key.print(output);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
output.colon();
|
||||||
|
self.value.print(output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, self, output) {
|
||||||
|
if (self.static) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
output.print(type);
|
||||||
|
output.space();
|
||||||
|
if (self.key instanceof AST_SymbolMethod) {
|
||||||
|
self.print_property_name(self.key.name, self.quote, output);
|
||||||
|
} else {
|
||||||
|
output.with_square(function() {
|
||||||
|
self.key.print(output);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
self.value._do_print(output, true);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectSetter, function(self, output){
|
DEFPRINT(AST_ObjectSetter, function(self, output){
|
||||||
output.print("set");
|
self._print_getter_setter("set", self, output);
|
||||||
output.space();
|
|
||||||
self.key.print(output);
|
|
||||||
self.value._do_print(output, true);
|
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||||
output.print("get");
|
self._print_getter_setter("get", self, output);
|
||||||
output.space();
|
});
|
||||||
self.key.print(output);
|
DEFPRINT(AST_ConciseMethod, function(self, output){
|
||||||
|
if (self.static) {
|
||||||
|
output.print("static");
|
||||||
|
output.space();
|
||||||
|
}
|
||||||
|
if (self.is_generator) {
|
||||||
|
output.print("*");
|
||||||
|
}
|
||||||
|
if (self.key instanceof AST_SymbolMethod) {
|
||||||
|
self.print_property_name(self.key.name, self.quote, output);
|
||||||
|
} else {
|
||||||
|
output.with_square(function() {
|
||||||
|
self.key.print(output);
|
||||||
|
});
|
||||||
|
}
|
||||||
self.value._do_print(output, true);
|
self.value._do_print(output, true);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Symbol, function(self, output){
|
AST_Symbol.DEFMETHOD("_do_print", function(output){
|
||||||
var def = self.definition();
|
var def = this.definition();
|
||||||
output.print_name(def ? def.mangled_name || def.name : self.name);
|
output.print_name(def ? def.mangled_name || def.name : this.name);
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_Symbol, function (self, output) {
|
||||||
|
self._do_print(output);
|
||||||
|
});
|
||||||
|
DEFPRINT(AST_SymbolDeclaration, function(self, output){
|
||||||
|
self._do_print(output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Hole, noop);
|
DEFPRINT(AST_Hole, noop);
|
||||||
DEFPRINT(AST_This, function(self, output){
|
DEFPRINT(AST_This, function(self, output){
|
||||||
output.print("this");
|
output.print("this");
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Super, function(self, output){
|
||||||
|
output.print("super");
|
||||||
|
});
|
||||||
DEFPRINT(AST_Constant, function(self, output){
|
DEFPRINT(AST_Constant, function(self, output){
|
||||||
output.print(self.getValue());
|
output.print(self.getValue());
|
||||||
});
|
});
|
||||||
|
|||||||
1603
lib/parse.js
1603
lib/parse.js
File diff suppressed because one or more lines are too long
@@ -43,19 +43,37 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function find_builtins() {
|
function find_builtins(reserved) {
|
||||||
|
|
||||||
|
// Compatibility fix for some standard defined globals not defined on every js environment
|
||||||
|
var new_globals = ["Symbol", "Map", "Promise", "Proxy", "Reflect", "Set", "WeakMap", "WeakSet"];
|
||||||
|
var objects = {};
|
||||||
|
var global_ref = typeof global === "object" ? global : self;
|
||||||
|
|
||||||
|
new_globals.forEach(function (new_global) {
|
||||||
|
objects[new_global] = global_ref[new_global] || new Function();
|
||||||
|
});
|
||||||
|
|
||||||
// NaN will be included due to Number.NaN
|
// NaN will be included due to Number.NaN
|
||||||
var a = [
|
[
|
||||||
"null",
|
"null",
|
||||||
"true",
|
"true",
|
||||||
"false",
|
"false",
|
||||||
"Infinity",
|
"Infinity",
|
||||||
"-Infinity",
|
"-Infinity",
|
||||||
"undefined",
|
"undefined",
|
||||||
];
|
].forEach(add);
|
||||||
[ Object, Array, Function, Number,
|
[ Object, Array, Function, Number,
|
||||||
String, Boolean, Error, Math,
|
String, Boolean, Error, Math,
|
||||||
Date, RegExp
|
Date, RegExp, objects.Symbol, ArrayBuffer,
|
||||||
|
DataView, decodeURI, decodeURIComponent,
|
||||||
|
encodeURI, encodeURIComponent, eval, EvalError,
|
||||||
|
Float32Array, Float64Array, Int8Array, Int16Array,
|
||||||
|
Int32Array, isFinite, isNaN, JSON, objects.Map, parseFloat,
|
||||||
|
parseInt, objects.Promise, objects.Proxy, RangeError, ReferenceError,
|
||||||
|
objects.Reflect, objects.Set, SyntaxError, TypeError, Uint8Array,
|
||||||
|
Uint8ClampedArray, Uint16Array, Uint32Array, URIError,
|
||||||
|
objects.WeakMap, objects.WeakSet
|
||||||
].forEach(function(ctor){
|
].forEach(function(ctor){
|
||||||
Object.getOwnPropertyNames(ctor).map(add);
|
Object.getOwnPropertyNames(ctor).map(add);
|
||||||
if (ctor.prototype) {
|
if (ctor.prototype) {
|
||||||
@@ -63,24 +81,23 @@ function find_builtins() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
function add(name) {
|
function add(name) {
|
||||||
push_uniq(a, name);
|
push_uniq(reserved, name);
|
||||||
}
|
}
|
||||||
return a;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
|
builtins: false,
|
||||||
cache: null,
|
cache: null,
|
||||||
debug: false,
|
debug: false,
|
||||||
ignore_quoted: false,
|
keep_quoted: false,
|
||||||
only_cache: false,
|
only_cache: false,
|
||||||
regex: null,
|
regex: null,
|
||||||
reserved: null,
|
reserved: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
var reserved = options.reserved;
|
var reserved = options.reserved || [];
|
||||||
if (reserved == null)
|
if (!options.builtins) find_builtins(reserved);
|
||||||
reserved = find_builtins();
|
|
||||||
|
|
||||||
var cache = options.cache;
|
var cache = options.cache;
|
||||||
if (cache == null) {
|
if (cache == null) {
|
||||||
@@ -91,12 +108,12 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
var ignore_quoted = options.ignore_quoted;
|
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'
|
||||||
// the same as passing an empty string.
|
// the same as passing an empty string.
|
||||||
var debug = (options.debug !== false);
|
var debug = options.debug !== false;
|
||||||
var debug_name_suffix;
|
var debug_name_suffix;
|
||||||
if (debug) {
|
if (debug) {
|
||||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||||
@@ -104,12 +121,12 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
var unmangleable = [];
|
var unmangleable = [];
|
||||||
var ignored = {};
|
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, ignore_quoted && node.quote);
|
add(node.key, keep_quoted && node.quote);
|
||||||
}
|
}
|
||||||
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
|
||||||
@@ -119,14 +136,17 @@ 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, ignore_quoted);
|
addStrings(node.property, keep_quoted);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_ConciseMethod) {
|
||||||
|
add(node.name.name);
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 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 (!(ignore_quoted && node.quote))
|
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) {
|
||||||
@@ -137,9 +157,14 @@ function mangle_properties(ast, options) {
|
|||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
if (!ignore_quoted)
|
if (!keep_quoted)
|
||||||
node.property = mangleStrings(node.property);
|
node.property = mangleStrings(node.property);
|
||||||
}
|
}
|
||||||
|
else if (node instanceof AST_ConciseMethod) {
|
||||||
|
if (should_mangle(node.name.name)) {
|
||||||
|
node.name.name = mangle(node.name.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
// else if (node instanceof AST_String) {
|
// else if (node instanceof AST_String) {
|
||||||
// if (should_mangle(node.value)) {
|
// if (should_mangle(node.value)) {
|
||||||
// AST_Node.warn(
|
// AST_Node.warn(
|
||||||
@@ -167,16 +192,16 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
if (ignore_quoted && name in ignored) return false;
|
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.props.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name, ignore) {
|
function add(name, keep) {
|
||||||
if (ignore) {
|
if (keep) {
|
||||||
ignored[name] = true;
|
to_keep[name] = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,19 +224,19 @@ function mangle_properties(ast, options) {
|
|||||||
// 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) && !(ignore_quoted && debug_mangled in ignored)) {
|
if (can_mangle(debug_mangled) && !(keep_quoted && debug_mangled in to_keep)) {
|
||||||
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 'ignored' set
|
// Note: `can_mangle()` does not check if the name collides with the `to_keep` set
|
||||||
// (filled with quoted properties when ignore_quoted set). Make sure we add this
|
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
||||||
// check so we don't collide with a quoted name.
|
// check so we don't collide with a quoted name.
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cache.cname);
|
||||||
} while (!can_mangle(mangled) || (ignore_quoted && mangled in ignored));
|
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.props.set(name, mangled);
|
||||||
@@ -219,17 +244,17 @@ function mangle_properties(ast, options) {
|
|||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStrings(node, ignore) {
|
function addStrings(node, keep) {
|
||||||
var out = {};
|
var out = {};
|
||||||
try {
|
try {
|
||||||
(function walk(node){
|
(function walk(node){
|
||||||
node.walk(new TreeWalker(function(node){
|
node.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_Seq) {
|
if (node instanceof AST_Sequence) {
|
||||||
walk(node.cdr);
|
walk(node.expressions[node.expressions.length - 1]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_String) {
|
if (node instanceof AST_String) {
|
||||||
add(node.value, ignore);
|
add(node.value, keep);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Conditional) {
|
if (node instanceof AST_Conditional) {
|
||||||
@@ -247,8 +272,9 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
function mangleStrings(node) {
|
function mangleStrings(node) {
|
||||||
return node.transform(new TreeTransformer(function(node){
|
return node.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_Seq) {
|
if (node instanceof AST_Sequence) {
|
||||||
node.cdr = mangleStrings(node.cdr);
|
var last = node.expressions.length - 1;
|
||||||
|
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_String) {
|
else if (node instanceof AST_String) {
|
||||||
node.value = mangle(node.value);
|
node.value = mangle(node.value);
|
||||||
@@ -260,5 +286,4 @@ function mangle_properties(ast, options) {
|
|||||||
return node;
|
return node;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
271
lib/scope.js
271
lib/scope.js
@@ -49,7 +49,9 @@ function SymbolDef(scope, index, orig) {
|
|||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
this.global = false;
|
this.global = false;
|
||||||
|
this.export = false;
|
||||||
this.mangled_name = null;
|
this.mangled_name = null;
|
||||||
|
this.object_destructuring_arg = false;
|
||||||
this.undeclared = false;
|
this.undeclared = false;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.id = SymbolDef.next_id++;
|
this.id = SymbolDef.next_id++;
|
||||||
@@ -62,11 +64,17 @@ SymbolDef.prototype = {
|
|||||||
if (!options) options = {};
|
if (!options) options = {};
|
||||||
|
|
||||||
return (this.global && !options.toplevel)
|
return (this.global && !options.toplevel)
|
||||||
|
|| this.export
|
||||||
|
|| this.object_destructuring_arg
|
||||||
|| this.undeclared
|
|| this.undeclared
|
||||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||||
|| (options.keep_fnames
|
|| (options.keep_fnames
|
||||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
|| this.orig[0] instanceof AST_SymbolDefun))
|
||||||
|
|| this.orig[0] instanceof AST_SymbolMethod
|
||||||
|
|| (options.keep_classnames
|
||||||
|
&& (this.orig[0] instanceof AST_SymbolClass
|
||||||
|
|| this.orig[0] instanceof AST_SymbolDefClass));
|
||||||
},
|
},
|
||||||
mangle: function(options) {
|
mangle: function(options) {
|
||||||
var cache = options.cache && options.cache.props;
|
var cache = options.cache && options.cache.props;
|
||||||
@@ -76,7 +84,7 @@ SymbolDef.prototype = {
|
|||||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||||
var s = this.scope;
|
var s = this.scope;
|
||||||
var sym = this.orig[0];
|
var sym = this.orig[0];
|
||||||
if (!options.screw_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 (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||||
@@ -93,7 +101,8 @@ SymbolDef.prototype = {
|
|||||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
cache: null,
|
cache: null,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
|
safari10: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
@@ -101,15 +110,35 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
var scope = self.parent_scope = null;
|
var scope = self.parent_scope = null;
|
||||||
var labels = new Dictionary();
|
var labels = new Dictionary();
|
||||||
var defun = null;
|
var defun = null;
|
||||||
|
var in_destructuring = null;
|
||||||
|
var in_export = false;
|
||||||
|
var in_block = 0;
|
||||||
|
var for_scopes = [];
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
if (node instanceof AST_Catch) {
|
if (node.is_block_scope()) {
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
scope = new AST_Scope(node);
|
scope = new AST_Scope(node);
|
||||||
scope.init_scope_vars(save_scope);
|
scope.init_scope_vars(save_scope);
|
||||||
|
if (!(node instanceof AST_Scope)) {
|
||||||
|
scope.uses_with = save_scope.uses_with;
|
||||||
|
scope.uses_eval = save_scope.uses_eval;
|
||||||
|
scope.directives = save_scope.directives;
|
||||||
|
}
|
||||||
|
if (options.safari10) {
|
||||||
|
if (node instanceof AST_For || node instanceof AST_ForIn) {
|
||||||
|
for_scopes.push(scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
descend();
|
descend();
|
||||||
scope = save_scope;
|
scope = save_scope;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Destructuring && node.is_array === false) {
|
||||||
|
in_destructuring = node; // These don't nest
|
||||||
|
descend();
|
||||||
|
in_destructuring = null;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope) {
|
||||||
node.init_scope_vars(scope);
|
node.init_scope_vars(scope);
|
||||||
var save_scope = scope;
|
var save_scope = scope;
|
||||||
@@ -123,6 +152,22 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
labels = save_labels;
|
labels = save_labels;
|
||||||
return true; // don't descend again in TreeWalker
|
return true; // don't descend again in TreeWalker
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Export) {
|
||||||
|
in_export = true;
|
||||||
|
descend();
|
||||||
|
in_export = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_BlockStatement
|
||||||
|
|| node instanceof AST_Switch
|
||||||
|
|| node instanceof AST_Try
|
||||||
|
|| node instanceof AST_Catch
|
||||||
|
|| node instanceof AST_Finally) {
|
||||||
|
in_block++;
|
||||||
|
descend();
|
||||||
|
in_block--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (node instanceof AST_LabeledStatement) {
|
if (node instanceof AST_LabeledStatement) {
|
||||||
var l = node.label;
|
var l = node.label;
|
||||||
if (labels.has(l.name)) {
|
if (labels.has(l.name)) {
|
||||||
@@ -141,12 +186,15 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
if (node instanceof AST_Symbol) {
|
if (node instanceof AST_Symbol) {
|
||||||
node.scope = scope;
|
node.scope = scope;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_SymbolFunarg) {
|
||||||
|
node.object_destructuring_arg = !!in_destructuring;
|
||||||
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
node.thedef = node;
|
node.thedef = node;
|
||||||
node.references = [];
|
node.references = [];
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolLambda) {
|
if (node instanceof AST_SymbolLambda) {
|
||||||
defun.def_function(node);
|
defun.def_function(node, in_export, in_block);
|
||||||
}
|
}
|
||||||
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 +202,28 @@ 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);
|
var parent_lambda = defun.parent_scope;
|
||||||
|
while (parent_lambda.is_block_scope()) {
|
||||||
|
parent_lambda = parent_lambda.parent_scope;
|
||||||
|
}
|
||||||
|
(node.scope = parent_lambda).def_function(node, in_export, in_block);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolClass) {
|
||||||
|
defun.def_variable(node, in_export, in_block);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolImport) {
|
||||||
|
scope.def_variable(node, in_export, in_block);
|
||||||
|
}
|
||||||
|
else if (node instanceof AST_SymbolDefClass) {
|
||||||
|
// This deals with the name of the class being available
|
||||||
|
// inside the class.
|
||||||
|
(node.scope = defun.parent_scope).def_function(node, in_export, in_block);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolVar
|
else if (node instanceof AST_SymbolVar
|
||||||
|
|| node instanceof AST_SymbolLet
|
||||||
|| node instanceof AST_SymbolConst) {
|
|| node instanceof AST_SymbolConst) {
|
||||||
defun.def_variable(node);
|
var def = ((node instanceof AST_SymbolBlockDeclaration) ? scope : defun).def_variable(node, in_export, in_block);
|
||||||
|
def.destructuring = in_destructuring;
|
||||||
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);
|
||||||
@@ -169,7 +234,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_SymbolCatch) {
|
else if (node instanceof AST_SymbolCatch) {
|
||||||
scope.def_variable(node).defun = defun;
|
scope.def_variable(node, in_export, in_block).defun = defun;
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_LabelRef) {
|
else if (node instanceof AST_LabelRef) {
|
||||||
var sym = labels.get(node.name);
|
var sym = labels.get(node.name);
|
||||||
@@ -185,6 +250,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
|
|
||||||
// pass 2: find back references and eval
|
// pass 2: find back references and eval
|
||||||
var func = null;
|
var func = null;
|
||||||
|
var cls = null;
|
||||||
var globals = 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) {
|
if (node instanceof AST_Lambda) {
|
||||||
@@ -194,6 +260,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
func = prev_func;
|
func = prev_func;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (node instanceof AST_Class) {
|
||||||
|
var prev_cls = cls;
|
||||||
|
cls = node;
|
||||||
|
descend();
|
||||||
|
cls = prev_cls;
|
||||||
|
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;
|
||||||
@@ -220,7 +293,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 3: fix up any scoping issue with IE8
|
// pass 3: fix up any scoping issue with IE8
|
||||||
if (!options.screw_ie8) {
|
if (options.ie8) {
|
||||||
self.walk(new TreeWalker(function(node, descend) {
|
self.walk(new TreeWalker(function(node, descend) {
|
||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
var name = node.name;
|
var name = node.name;
|
||||||
@@ -237,6 +310,19 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pass 4: add symbol definitions to loop scopes
|
||||||
|
// Safari/Webkit bug workaround - loop init let variable shadowing argument.
|
||||||
|
// https://github.com/mishoo/UglifyJS2/issues/1753
|
||||||
|
// https://bugs.webkit.org/show_bug.cgi?id=171041
|
||||||
|
if (options.safari10) {
|
||||||
|
for (var i = 0; i < for_scopes.length; i++) {
|
||||||
|
var scope = for_scopes[i];
|
||||||
|
scope.parent_scope.variables.each(function(def) {
|
||||||
|
push_uniq(scope.enclosed, def);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.cname = options.cache.cname;
|
this.cname = options.cache.cname;
|
||||||
}
|
}
|
||||||
@@ -265,10 +351,27 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
|||||||
this.cname = -1; // the current index for mangling functions/variables
|
this.cname = -1; // the current index for mangling functions/variables
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Node.DEFMETHOD("is_block_scope", function(){
|
||||||
|
return false; // Behaviour will be overridden by AST_Block
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Block.DEFMETHOD("is_block_scope", function(){
|
||||||
|
return (
|
||||||
|
!(this instanceof AST_Lambda) &&
|
||||||
|
!(this instanceof AST_Toplevel) &&
|
||||||
|
!(this instanceof AST_Class) &&
|
||||||
|
!(this instanceof AST_SwitchBranch)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_IterationStatement.DEFMETHOD("is_block_scope", function(){
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
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_SymbolVar({
|
this.def_variable(new AST_SymbolConst({
|
||||||
name: "arguments",
|
name: "arguments",
|
||||||
start: this.start,
|
start: this.start,
|
||||||
end: this.end
|
end: this.end
|
||||||
@@ -301,16 +404,24 @@ 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, in_export, in_block){
|
||||||
this.functions.set(symbol.name, this.def_variable(symbol));
|
this.functions.set(symbol.name, this.def_variable(symbol, in_export, in_block));
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
AST_Scope.DEFMETHOD("def_variable", function(symbol, in_export, in_block){
|
||||||
var def;
|
var def;
|
||||||
if (!this.variables.has(symbol.name)) {
|
if (!this.variables.has(symbol.name)) {
|
||||||
def = new SymbolDef(this, this.variables.size(), symbol);
|
def = new SymbolDef(this, this.variables.size(), symbol);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
def.global = !this.parent_scope;
|
def.object_destructuring_arg = symbol.object_destructuring_arg;
|
||||||
|
if (in_export) {
|
||||||
|
def.export = true;
|
||||||
|
}
|
||||||
|
if (in_block && symbol instanceof AST_SymbolBlockDeclaration) {
|
||||||
|
def.global = false;
|
||||||
|
} else {
|
||||||
|
def.global = !this.parent_scope;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
def = this.variables.get(symbol.name);
|
def = this.variables.get(symbol.name);
|
||||||
def.orig.push(symbol);
|
def.orig.push(symbol);
|
||||||
@@ -325,8 +436,8 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||||||
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 excepted from mangling.
|
// shadow a name reserved from mangling.
|
||||||
if (options.except.indexOf(m) >= 0) continue;
|
if (options.reserved.indexOf(m) >= 0) 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
|
||||||
@@ -358,12 +469,8 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
});
|
});
|
||||||
|
|
||||||
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
|
||||||
@@ -399,10 +506,10 @@ AST_Symbol.DEFMETHOD("global", function(){
|
|||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||||
return defaults(options, {
|
return defaults(options, {
|
||||||
eval : false,
|
eval : false,
|
||||||
except : [],
|
ie8 : false,
|
||||||
|
keep_classnames: false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
screw_ie8 : true,
|
reserved : [],
|
||||||
sort : false, // Ignored. Flag retained for backwards compatibility.
|
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -411,7 +518,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
|
|
||||||
// Never mangle arguments
|
// Never mangle arguments
|
||||||
options.except.push('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
|
||||||
@@ -422,7 +529,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.globals.each(function(symbol){
|
this.globals.each(function(symbol){
|
||||||
if (options.except.indexOf(symbol.name) < 0) {
|
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||||
to_mangle.push(symbol);
|
to_mangle.push(symbol);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -439,7 +546,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope) {
|
||||||
var p = tw.parent(), a = [];
|
var p = tw.parent(), a = [];
|
||||||
node.variables.each(function(symbol){
|
node.variables.each(function(symbol){
|
||||||
if (options.except.indexOf(symbol.name) < 0) {
|
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||||
a.push(symbol);
|
a.push(symbol);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -452,13 +559,19 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (options.screw_ie8 && node instanceof AST_SymbolCatch) {
|
var mangle_with_block_scope =
|
||||||
|
(!options.ie8 && node instanceof AST_SymbolCatch) ||
|
||||||
|
node instanceof AST_SymbolBlockDeclaration;
|
||||||
|
if (mangle_with_block_scope) {
|
||||||
to_mangle.push(node.definition());
|
to_mangle.push(node.definition());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.walk(tw);
|
this.walk(tw);
|
||||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
to_mangle.forEach(function(def){
|
||||||
|
if (def.destructuring && !def.destructuring.is_array) return;
|
||||||
|
def.mangle(options);
|
||||||
|
});
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
options.cache.cname = this.cname;
|
options.cache.cname = this.cname;
|
||||||
@@ -509,21 +622,27 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
|||||||
else if (node instanceof AST_With)
|
else if (node instanceof AST_With)
|
||||||
base54.consider("with");
|
base54.consider("with");
|
||||||
else if (node instanceof AST_ObjectSetter)
|
else if (node instanceof AST_ObjectSetter)
|
||||||
base54.consider("set" + node.key);
|
base54.consider("set" + (typeof node.key === "string" ? node.key : ""));
|
||||||
else if (node instanceof AST_ObjectGetter)
|
else if (node instanceof AST_ObjectGetter)
|
||||||
base54.consider("get" + node.key);
|
base54.consider("get" + (typeof node.key === "string" ? node.key : ""));
|
||||||
else if (node instanceof AST_ObjectKeyVal)
|
else if (node instanceof AST_ObjectKeyVal && typeof node.key === "string")
|
||||||
|
base54.consider(node.key);
|
||||||
|
else if (node instanceof AST_ConciseMethod && typeof node.key === "string")
|
||||||
base54.consider(node.key);
|
base54.consider(node.key);
|
||||||
else if (node instanceof AST_New)
|
else if (node instanceof AST_New)
|
||||||
base54.consider("new");
|
base54.consider("new");
|
||||||
else if (node instanceof AST_This)
|
else if (node instanceof AST_This)
|
||||||
base54.consider("this");
|
base54.consider("this");
|
||||||
|
else if (node instanceof AST_Super)
|
||||||
|
base54.consider("super");
|
||||||
else if (node instanceof AST_Try)
|
else if (node instanceof AST_Try)
|
||||||
base54.consider("try");
|
base54.consider("try");
|
||||||
else if (node instanceof AST_Catch)
|
else if (node instanceof AST_Catch)
|
||||||
base54.consider("catch");
|
base54.consider("catch");
|
||||||
else if (node instanceof AST_Finally)
|
else if (node instanceof AST_Finally)
|
||||||
base54.consider("finally");
|
base54.consider("finally");
|
||||||
|
else if (node instanceof AST_Yield)
|
||||||
|
base54.consider("yield");
|
||||||
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||||
base54.consider(node.name);
|
base54.consider(node.name);
|
||||||
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||||
@@ -573,89 +692,3 @@ var base54 = (function() {
|
|||||||
};
|
};
|
||||||
return base54;
|
return base54;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
|
|
||||||
options = defaults(options, {
|
|
||||||
assign_to_global : true,
|
|
||||||
eval : true,
|
|
||||||
func_arguments : true,
|
|
||||||
nested_defuns : true,
|
|
||||||
undeclared : false, // this makes a lot of noise
|
|
||||||
unreferenced : true,
|
|
||||||
});
|
|
||||||
var tw = new TreeWalker(function(node){
|
|
||||||
if (options.undeclared
|
|
||||||
&& node instanceof AST_SymbolRef
|
|
||||||
&& node.undeclared())
|
|
||||||
{
|
|
||||||
// XXX: this also warns about JS standard names,
|
|
||||||
// i.e. Object, Array, parseInt etc. Should add a list of
|
|
||||||
// exceptions.
|
|
||||||
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
|
|
||||||
name: node.name,
|
|
||||||
file: node.start.file,
|
|
||||||
line: node.start.line,
|
|
||||||
col: node.start.col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.assign_to_global)
|
|
||||||
{
|
|
||||||
var sym = null;
|
|
||||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef)
|
|
||||||
sym = node.left;
|
|
||||||
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef)
|
|
||||||
sym = node.init;
|
|
||||||
if (sym
|
|
||||||
&& (sym.undeclared()
|
|
||||||
|| (sym.global() && sym.scope !== sym.definition().scope))) {
|
|
||||||
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
|
|
||||||
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
|
|
||||||
name: sym.name,
|
|
||||||
file: sym.start.file,
|
|
||||||
line: sym.start.line,
|
|
||||||
col: sym.start.col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (options.eval
|
|
||||||
&& node instanceof AST_SymbolRef
|
|
||||||
&& node.undeclared()
|
|
||||||
&& node.name == "eval") {
|
|
||||||
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
|
|
||||||
}
|
|
||||||
if (options.unreferenced
|
|
||||||
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label)
|
|
||||||
&& !(node instanceof AST_SymbolCatch)
|
|
||||||
&& node.unreferenced()) {
|
|
||||||
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
|
|
||||||
type: node instanceof AST_Label ? "Label" : "Symbol",
|
|
||||||
name: node.name,
|
|
||||||
file: node.start.file,
|
|
||||||
line: node.start.line,
|
|
||||||
col: node.start.col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.func_arguments
|
|
||||||
&& node instanceof AST_Lambda
|
|
||||||
&& node.uses_arguments) {
|
|
||||||
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
|
|
||||||
name: node.name ? node.name.name : "anonymous",
|
|
||||||
file: node.start.file,
|
|
||||||
line: node.start.line,
|
|
||||||
col: node.start.col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (options.nested_defuns
|
|
||||||
&& node instanceof AST_Defun
|
|
||||||
&& !(tw.parent() instanceof AST_Scope)) {
|
|
||||||
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
|
|
||||||
name: node.name.name,
|
|
||||||
type: tw.parent().TYPE,
|
|
||||||
file: node.start.file,
|
|
||||||
line: node.start.line,
|
|
||||||
col: node.start.col
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.walk(tw);
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -163,10 +163,18 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (self.value) self.value = self.value.transform(tw);
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_(AST_Destructuring, function(self, tw) {
|
||||||
|
self.names = do_list(self.names, tw);
|
||||||
|
});
|
||||||
|
|
||||||
_(AST_Lambda, function(self, tw){
|
_(AST_Lambda, function(self, tw){
|
||||||
if (self.name) self.name = self.name.transform(tw);
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
self.argnames = do_list(self.argnames, tw);
|
self.argnames = do_list(self.argnames, tw);
|
||||||
self.body = do_list(self.body, tw);
|
if (self.body instanceof AST_Node) {
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
} else {
|
||||||
|
self.body = do_list(self.body, tw);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_Call, function(self, tw){
|
_(AST_Call, function(self, tw){
|
||||||
@@ -174,9 +182,8 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.args = do_list(self.args, tw);
|
self.args = do_list(self.args, tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_Seq, function(self, tw){
|
_(AST_Sequence, function(self, tw){
|
||||||
self.car = self.car.transform(tw);
|
self.expressions = do_list(self.expressions, tw);
|
||||||
self.cdr = self.cdr.transform(tw);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_(AST_Dot, function(self, tw){
|
_(AST_Dot, function(self, tw){
|
||||||
@@ -188,6 +195,10 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
self.property = self.property.transform(tw);
|
self.property = self.property.transform(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_(AST_Yield, function(self, tw){
|
||||||
|
if (self.expression) self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
_(AST_Unary, function(self, tw){
|
_(AST_Unary, function(self, tw){
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
@@ -212,7 +223,36 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
});
|
});
|
||||||
|
|
||||||
_(AST_ObjectProperty, function(self, tw){
|
_(AST_ObjectProperty, function(self, tw){
|
||||||
|
if (self.key instanceof AST_Node) {
|
||||||
|
self.key = self.key.transform(tw);
|
||||||
|
}
|
||||||
self.value = self.value.transform(tw);
|
self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
_(AST_Class, function(self, tw){
|
||||||
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
|
if (self.extends) self.extends = self.extends.transform(tw);
|
||||||
|
self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Expansion, function(self, tw){
|
||||||
|
self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_Export, function(self, tw){
|
||||||
|
if (self.exported_value) self.exported_value = self.exported_value.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_TemplateString, function(self, tw) {
|
||||||
|
for (var i = 0; i < self.segments.length; i++) {
|
||||||
|
if (!(self.segments[i] instanceof AST_TemplateSegment)) {
|
||||||
|
self.segments[i] = self.segments[i].transform(tw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_(AST_PrefixedTemplateString, function(self, tw) {
|
||||||
|
self.template_string = self.template_string.transform(tw);
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ function first_in_statement(stack) {
|
|||||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
for (var i = 0, p; p = stack.parent(i); i++) {
|
||||||
if (p instanceof AST_Statement && p.body === node)
|
if (p instanceof AST_Statement && p.body === node)
|
||||||
return true;
|
return true;
|
||||||
if ((p instanceof AST_Seq && p.car === node ) ||
|
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) ||
|
||||||
(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 ) ||
|
||||||
|
|||||||
23
package.json
23
package.json
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "uglify-js",
|
"name": "uglify-es",
|
||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"homepage": "http://lisperator.net/uglifyjs",
|
"homepage": "https://github.com/mishoo/UglifyJS2/tree/harmony",
|
||||||
"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": "2.8.22",
|
"version": "3.0.7",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -29,24 +29,13 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"source-map": "~0.5.1",
|
"commander": "~2.9.0",
|
||||||
"yargs": "~3.10.0"
|
"source-map": "~0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~0.6.0",
|
"acorn": "~5.0.3",
|
||||||
"escodegen": "~1.3.3",
|
|
||||||
"esfuzz": "~0.3.1",
|
|
||||||
"estraverse": "~1.5.1",
|
|
||||||
"mocha": "~2.3.4"
|
"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"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ var createHash = require("crypto").createHash;
|
|||||||
var fork = require("child_process").fork;
|
var fork = require("child_process").fork;
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc", "warnings=false");
|
args.push("-mc");
|
||||||
}
|
}
|
||||||
args.push("--stats");
|
args.push("--stats");
|
||||||
var urls = [
|
var urls = [
|
||||||
"https://code.jquery.com/jquery-3.1.1.js",
|
"https://code.jquery.com/jquery-3.2.1.js",
|
||||||
"https://code.angularjs.org/1.6.1/angular.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/mathjs/3.9.0/math.js",
|
||||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||||
@@ -29,11 +29,11 @@ function done() {
|
|||||||
var info = results[url];
|
var info = results[url];
|
||||||
console.log();
|
console.log();
|
||||||
console.log(url);
|
console.log(url);
|
||||||
console.log(info.log);
|
|
||||||
var elapsed = 0;
|
var elapsed = 0;
|
||||||
info.log.replace(/: ([0-9]+\.[0-9]{3})s/g, function(match, time) {
|
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
||||||
elapsed += parseFloat(time);
|
elapsed += 1e-3 * parseInt(time);
|
||||||
});
|
return "";
|
||||||
|
}));
|
||||||
console.log("Run-time:", elapsed.toFixed(3), "s");
|
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");
|
||||||
|
|||||||
67
test/compress/angular-inject.js
vendored
67
test/compress/angular-inject.js
vendored
@@ -1,67 +0,0 @@
|
|||||||
ng_inject_defun: {
|
|
||||||
options = {
|
|
||||||
angular: true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
/*@ngInject*/
|
|
||||||
function Controller(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function Controller(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}
|
|
||||||
Controller.$inject=['dependency']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ng_inject_assignment: {
|
|
||||||
options = {
|
|
||||||
angular: true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
/*@ngInject*/
|
|
||||||
var Controller = function(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var Controller = function(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}
|
|
||||||
Controller.$inject=['dependency']
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ng_inject_inline: {
|
|
||||||
options = {
|
|
||||||
angular: true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
angular.module('a').
|
|
||||||
factory('b',
|
|
||||||
/*@ngInject*/
|
|
||||||
function(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}).
|
|
||||||
directive('c',
|
|
||||||
/*@ngInject*/
|
|
||||||
function(anotherDependency) {
|
|
||||||
return anotherDependency;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
angular.module('a').
|
|
||||||
factory('b',[
|
|
||||||
'dependency',
|
|
||||||
function(dependency) {
|
|
||||||
return dependency;
|
|
||||||
}]).
|
|
||||||
directive('c',[
|
|
||||||
'anotherDependency',
|
|
||||||
function(anotherDependency) {
|
|
||||||
return anotherDependency;
|
|
||||||
}])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// NOTE trailing comma doesn't contribute to length of an array
|
||||||
|
// That also means the array changes length if previous element is a hole too and got cut off
|
||||||
holes_and_undefined: {
|
holes_and_undefined: {
|
||||||
input: {
|
input: {
|
||||||
w = [1,,];
|
w = [1,,];
|
||||||
@@ -91,6 +93,79 @@ constant_join_2: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spread_with_variable_as_last_element: {
|
||||||
|
input: {
|
||||||
|
var values = [4, 5, 6];
|
||||||
|
var a = [1, 2, 3, ...values];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [4, 5, 6];
|
||||||
|
var a = [1, 2, 3, ...values];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_variable_in_middle: {
|
||||||
|
input: {
|
||||||
|
var values = [4, 5, 6];
|
||||||
|
var a = [1, 2, 3, ...values, 7,,,];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [4, 5, 6];
|
||||||
|
var a = [1, 2, 3, ...values, 7,,,];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_variable_at_front: {
|
||||||
|
input: {
|
||||||
|
var values = [1, 2, 3];
|
||||||
|
var a = [...values, 4, 5, 6];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [1, 2, 3];
|
||||||
|
var a = [...values, 4, 5, 6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_variable_at_front_after_elisions: {
|
||||||
|
input: {
|
||||||
|
var values = [1, 2, 3];
|
||||||
|
var a = [,,,...values, 4, 5, 6];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var values = [1, 2, 3];
|
||||||
|
var a = [,,,...values, 4, 5, 6];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_array_at_end: {
|
||||||
|
input: {
|
||||||
|
var a = [1, 2, ...[4, 5, 6]];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [1, 2, ...[4, 5, 6]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_logical_expression_at_end: {
|
||||||
|
options = { evaluate: true }
|
||||||
|
input: {
|
||||||
|
var a = [1, 2, 3, ...[2+2]]
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [1, 2, 3, ...[4]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spread_with_logical_expression_at_middle: {
|
||||||
|
options = { evaluate: true }
|
||||||
|
input: {
|
||||||
|
var a = [1, 1, ...[1+1, 1+2, 2+3], 8]
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [1, 1, ...[2, 3, 5], 8]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constant_join_3: {
|
constant_join_3: {
|
||||||
options = {
|
options = {
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
|
|||||||
137
test/compress/arrow.js
Normal file
137
test/compress/arrow.js
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
arrow_functions_without_body: {
|
||||||
|
input: {
|
||||||
|
var a1 = () => 42;
|
||||||
|
var a2 = (p) => p;
|
||||||
|
var a3 = p => p;
|
||||||
|
var a4 = (...p) => p;
|
||||||
|
var a5 = (b, c) => b + c;
|
||||||
|
var a6 = (b, ...c) => b + c[0];
|
||||||
|
var a7 = (...b) => b.join();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a1 = () => 42;
|
||||||
|
var a2 = (p) => p;
|
||||||
|
var a3 = p => p;
|
||||||
|
var a4 = (...p) => p;
|
||||||
|
var a5 = (b, c) => b + c;
|
||||||
|
var a6 = (b, ...c) => b + c[0];
|
||||||
|
var a7 = (...b) => b.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_functions_with_body: {
|
||||||
|
input: {
|
||||||
|
var a1 = () => {
|
||||||
|
var a = 42 * Math.random();
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a2 = (p) => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a3 = p => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a4 = (...p) => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a5 = (b, c) => {
|
||||||
|
var result = b * c + b / c;
|
||||||
|
return result
|
||||||
|
};
|
||||||
|
var a6 = (b, ...c) => {
|
||||||
|
var result = b;
|
||||||
|
for (var i = 0; i < c.length; i++)
|
||||||
|
result += c[i];
|
||||||
|
return result
|
||||||
|
};
|
||||||
|
var a7 = (...b) => {
|
||||||
|
b.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a1 = () => {
|
||||||
|
var a = 42 * Math.random();
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a2 = (p) => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a3 = p => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a4 = (...p) => {
|
||||||
|
var a = Math.random() * p;
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
var a5 = (b, c) => {
|
||||||
|
var result = b * c + b / c;
|
||||||
|
return result
|
||||||
|
};
|
||||||
|
var a6 = (b, ...c) => {
|
||||||
|
var result = b;
|
||||||
|
for (var i = 0; i < c.length; i++)
|
||||||
|
result += c[i];
|
||||||
|
return result
|
||||||
|
};
|
||||||
|
var a7 = (...b) => {
|
||||||
|
b.join();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_function_with_single_parameter_with_default: {
|
||||||
|
input: {
|
||||||
|
var foo = (a = 0) => doSomething(a);
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=(a=0)=>doSomething(a);"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_binding_pattern: {
|
||||||
|
input: {
|
||||||
|
var foo = ([]) => "foo";
|
||||||
|
var bar = ({}) => "bar";
|
||||||
|
var with_default = (foo = "default") => foo;
|
||||||
|
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
|
||||||
|
var array_after_spread = (...[foo]) => foo;
|
||||||
|
var array_after_spread = (...{foo}) => foo;
|
||||||
|
var computed = ({ [compute()]: x }) => {};
|
||||||
|
var array_hole = ([, , ...x] = [1, 2]) => {};
|
||||||
|
var object_trailing_elision = ({foo,}) => {};
|
||||||
|
var spread_empty_array = (...[]) => "foo";
|
||||||
|
var spread_empty_object = (...{}) => "foo";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = ([]) => "foo";
|
||||||
|
var bar = ({}) => "bar";
|
||||||
|
var with_default = (foo = "default") => foo;
|
||||||
|
var object_with_default = ({foo = "default", bar: baz = "default"}) => foo;
|
||||||
|
var array_after_spread = (...[foo]) => foo;
|
||||||
|
var array_after_spread = (...{foo}) => foo;
|
||||||
|
var computed = ({ [compute()]: x }) => {};
|
||||||
|
var array_hole = ([, , ...x] = [1, 2]) => {};
|
||||||
|
var object_trailing_elision = ({foo,}) => {};
|
||||||
|
var spread_empty_array = (...[]) => "foo";
|
||||||
|
var spread_empty_object = (...{}) => "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_binding_pattern_strict: {
|
||||||
|
input: {
|
||||||
|
var foo = ([,]) => "foo";
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo=([,])=>"foo";'
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_with_regexp: {
|
||||||
|
input: {
|
||||||
|
num => /\d{11,14}/.test( num )
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
num => /\d{11,14}/.test( num )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ ascii_only_true: {
|
|||||||
options = {}
|
options = {}
|
||||||
beautify = {
|
beautify = {
|
||||||
ascii_only : true,
|
ascii_only : true,
|
||||||
screw_ie8 : true,
|
ie8 : false,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -20,7 +20,7 @@ ascii_only_false: {
|
|||||||
options = {}
|
options = {}
|
||||||
beautify = {
|
beautify = {
|
||||||
ascii_only : false,
|
ascii_only : false,
|
||||||
screw_ie8 : true,
|
ie8 : false,
|
||||||
beautify : false,
|
beautify : false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -33,4 +33,3 @@ ascii_only_false: {
|
|||||||
}
|
}
|
||||||
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\\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\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
177
test/compress/block-scope.js
Normal file
177
test/compress/block-scope.js
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
|
||||||
|
let_statement: {
|
||||||
|
input: {
|
||||||
|
let x = 6;
|
||||||
|
}
|
||||||
|
expect_exact: "let x=6;"
|
||||||
|
}
|
||||||
|
|
||||||
|
do_not_hoist_let: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
if (FOO) {
|
||||||
|
let let1;
|
||||||
|
let let2;
|
||||||
|
var var1;
|
||||||
|
var var2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
var var1, var2;
|
||||||
|
if (FOO) {
|
||||||
|
let let1;
|
||||||
|
let let2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_not_remove_anon_blocks_if_they_have_decls: {
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
{
|
||||||
|
let x;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var x;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const y;
|
||||||
|
class Zee {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let y;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
var y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x(){
|
||||||
|
{
|
||||||
|
let x
|
||||||
|
}
|
||||||
|
var x;
|
||||||
|
{
|
||||||
|
const y;
|
||||||
|
class Zee {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let y
|
||||||
|
}
|
||||||
|
var y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_unused_in_global_block: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
let x;
|
||||||
|
const y;
|
||||||
|
class Zee {};
|
||||||
|
var w;
|
||||||
|
}
|
||||||
|
let ex;
|
||||||
|
const why;
|
||||||
|
class Zed {};
|
||||||
|
var wut;
|
||||||
|
console.log(x, y, Zee);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var w;
|
||||||
|
let ex;
|
||||||
|
const why;
|
||||||
|
class Zed {};
|
||||||
|
var wut;
|
||||||
|
console.log(x, y, Zee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regression_block_scope_resolves: {
|
||||||
|
mangle = { };
|
||||||
|
options = {
|
||||||
|
dead_code: false
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
(function () {
|
||||||
|
if(1) {
|
||||||
|
let x;
|
||||||
|
const y;
|
||||||
|
class Zee {};
|
||||||
|
}
|
||||||
|
if(1) {
|
||||||
|
let ex;
|
||||||
|
const why;
|
||||||
|
class Zi {};
|
||||||
|
}
|
||||||
|
console.log(x, y, Zee, ex, why, Zi);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function () {
|
||||||
|
if (1) {
|
||||||
|
let o;
|
||||||
|
const n;
|
||||||
|
class c {};
|
||||||
|
}
|
||||||
|
if (1) {
|
||||||
|
let o;
|
||||||
|
const n;
|
||||||
|
class c {};
|
||||||
|
}
|
||||||
|
console.log(x, y, Zee, ex, why, Zi);
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_block_scope_mangler: {
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var fn = function(code) {
|
||||||
|
switch (code) {
|
||||||
|
case 1:
|
||||||
|
let apple = code + 1;
|
||||||
|
let dog = code + 4;
|
||||||
|
console.log(apple, dog);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
let banana = code + 2;
|
||||||
|
console.log(banana);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
let cat = code + 3;
|
||||||
|
console.log(cat);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var fn = function(o) {
|
||||||
|
switch (o) {
|
||||||
|
case 1:
|
||||||
|
let e = o + 1
|
||||||
|
let c = o + 4;
|
||||||
|
console.log(e, c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
let l = o + 2;
|
||||||
|
console.log(l);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
let a = o + 3;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ collapse_vars_side_effects_1: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -68,11 +68,10 @@ collapse_vars_side_effects_1: {
|
|||||||
log(x, s.charAt(i++), y, 7);
|
log(x, s.charAt(i++), y, 7);
|
||||||
}
|
}
|
||||||
function f4() {
|
function f4() {
|
||||||
var log = console.log.bind(console),
|
var i = 10,
|
||||||
i = 10,
|
|
||||||
x = i += 2,
|
x = i += 2,
|
||||||
y = i += 3;
|
y = i += 3;
|
||||||
log(x, i += 4, y, i);
|
console.log.bind(console)(x, i += 4, y, i);
|
||||||
}
|
}
|
||||||
f1(), f2(), f3(), f4();
|
f1(), f2(), f3(), f4();
|
||||||
}
|
}
|
||||||
@@ -151,7 +150,7 @@ collapse_vars_issue_721: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
define(["require", "exports", 'handlebars'], function (require, exports, hb) {
|
define(["require", "exports", 'handlebars'], function (require, exports, hb) {
|
||||||
@@ -217,7 +216,7 @@ collapse_vars_properties: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(obj) {
|
function f1(obj) {
|
||||||
@@ -244,7 +243,7 @@ collapse_vars_if: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -294,7 +293,7 @@ collapse_vars_while: {
|
|||||||
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:false, unused:true, hoist_funs:true,
|
comparisons:true, evaluate:true, booleans:true, loops:false, 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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(y) {
|
function f1(y) {
|
||||||
@@ -393,9 +392,9 @@ collapse_vars_do_while: {
|
|||||||
}
|
}
|
||||||
function f3(y) {
|
function f3(y) {
|
||||||
function fn(n) { console.log(n); }
|
function fn(n) { console.log(n); }
|
||||||
var a = 2;
|
var a = 2, x = 7;
|
||||||
do {
|
do {
|
||||||
fn(a = 7);
|
fn(a = x);
|
||||||
break;
|
break;
|
||||||
} while (y);
|
} while (y);
|
||||||
}
|
}
|
||||||
@@ -468,8 +467,9 @@ collapse_vars_do_while_drop_assign: {
|
|||||||
}
|
}
|
||||||
function f3(y) {
|
function f3(y) {
|
||||||
function fn(n) { console.log(n); }
|
function fn(n) { console.log(n); }
|
||||||
|
var x = 7;
|
||||||
do {
|
do {
|
||||||
fn(7);
|
fn(x);
|
||||||
break;
|
break;
|
||||||
} while (y);
|
} while (y);
|
||||||
}
|
}
|
||||||
@@ -670,8 +670,8 @@ collapse_vars_lvalues: {
|
|||||||
function f4(x) { var a = (x -= 3); return x + a; }
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
function f5(x) { var w = e1(), v = e2(), c = v = --x; return (w = x) - c; }
|
function f5(x) { var w = e1(), v = e2(), c = v = --x; return (w = x) - c; }
|
||||||
function f6(x) { var w = e1(), v = e2(); return (v = --x) - (w = x); }
|
function f6(x) { var w = e1(), v = e2(); return (v = --x) - (w = x); }
|
||||||
function f7(x) { var w = e1(), v = e2(), c = v - x; return (w = x) - c; }
|
function f7(x) { var w = e1(); return (w = x) - (e2() - x); }
|
||||||
function f8(x) { var w = e1(), v = e2(); return (w = x) - (v - x); }
|
function f8(x) { var w = e1(); return (w = x) - (e2() - x); }
|
||||||
function f9(x) { var w = e1(); return e2() - x - (w = x); }
|
function f9(x) { var w = e1(); return e2() - x - (w = x); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -700,10 +700,10 @@ collapse_vars_lvalues_drop_assign: {
|
|||||||
function f2(x) { var z = x, a = ++z; return z += a; }
|
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||||
function f3(x) { var a = (x -= 3); return x + a; }
|
function f3(x) { var a = (x -= 3); return x + a; }
|
||||||
function f4(x) { var a = (x -= 3); return x + a; }
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
function f5(x) { var v = (e1(), e2()), c = v = --x; return x - c; }
|
function f5(x) { e1(); var v = e2(), c = v = --x; return x - c; }
|
||||||
function f6(x) { e1(), e2(); return --x - x; }
|
function f6(x) { e1(), e2(); return --x - x; }
|
||||||
function f7(x) { var v = (e1(), e2()), c = v - x; return x - c; }
|
function f7(x) { e1(); return x - (e2() - x); }
|
||||||
function f8(x) { var v = (e1(), e2()); return x - (v - x); }
|
function f8(x) { e1(); return x - (e2() - x); }
|
||||||
function f9(x) { e1(); return e2() - x - x; }
|
function f9(x) { e1(); return e2() - x - x; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -712,7 +712,7 @@ collapse_vars_misc1: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f0(o, a, h) {
|
function f0(o, a, h) {
|
||||||
@@ -789,7 +789,7 @@ collapse_vars_repeated: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -812,19 +812,17 @@ collapse_vars_repeated: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f1() {
|
function f1() {
|
||||||
return -3
|
return -3;
|
||||||
}
|
}
|
||||||
function f2(x) {
|
function f2(x) {
|
||||||
return x
|
return x;
|
||||||
}
|
}
|
||||||
(function(x){
|
(function(x){
|
||||||
var a = "GOOD" + x, e = "BAD", e = a;
|
console.log("GOOD!!");
|
||||||
console.log(e + "!");
|
})(),
|
||||||
})("!"),
|
|
||||||
(function(x){
|
(function(x){
|
||||||
var a = "GOOD" + x, e = "BAD" + x, e = a;
|
console.log("GOOD!!");
|
||||||
console.log(e + "!");
|
})();
|
||||||
})("!");
|
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -833,7 +831,7 @@ collapse_vars_closures: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function constant_vars_can_be_replaced_in_any_scope() {
|
function constant_vars_can_be_replaced_in_any_scope() {
|
||||||
@@ -923,7 +921,7 @@ collapse_vars_try: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -1048,10 +1046,9 @@ collapse_vars_object: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0(x, y) {
|
function f0(x, y) {
|
||||||
var z = x + y;
|
|
||||||
return {
|
return {
|
||||||
get b() { return 7; },
|
get b() { return 7; },
|
||||||
r: z
|
r: x + y
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function f1(x, y) {
|
function f1(x, y) {
|
||||||
@@ -1121,7 +1118,7 @@ collapse_vars_constants: {
|
|||||||
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, cascade:true, side_effects:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1(x) {
|
function f1(x) {
|
||||||
@@ -1159,7 +1156,7 @@ collapse_vars_arguments: {
|
|||||||
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, cascade:true, side_effects:true,
|
||||||
toplevel:true
|
toplevel:true, reduce_vars:true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var outer = function() {
|
var outer = function() {
|
||||||
@@ -1286,6 +1283,7 @@ collapse_vars_regexp: {
|
|||||||
join_vars: true,
|
join_vars: true,
|
||||||
cascade: true,
|
cascade: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f1() {
|
function f1() {
|
||||||
@@ -1319,8 +1317,8 @@ collapse_vars_regexp: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
(function(){
|
(function(){
|
||||||
var result, s = "acdabcdeabbb", rx = /ab*/g;
|
var result, rx = /ab*/g;
|
||||||
while (result = rx.exec(s))
|
while (result = rx.exec("acdabcdeabbb"))
|
||||||
console.log(result[0]);
|
console.log(result[0]);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -1330,6 +1328,7 @@ collapse_vars_regexp: {
|
|||||||
issue_1537: {
|
issue_1537: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var k = '';
|
var k = '';
|
||||||
@@ -1341,11 +1340,112 @@ issue_1537: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1562: {
|
issue_1537_for_of: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
|
input: {
|
||||||
|
var k = '';
|
||||||
|
for (k of {prop: 'val'}){}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var k = '';
|
||||||
|
for (k of {prop: 'val'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1537_destructuring_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
[x] = [y];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
[x] = [y];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1537_destructuring_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = foo();
|
||||||
|
[x] = [1];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = foo();
|
||||||
|
[x] = [1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1537_destructuring_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = Math.random();
|
||||||
|
({p: x = 9} = {v: 1});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = Math.random();
|
||||||
|
({p: x = 9} = {v: 1});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1537_destructuring_for_in: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
(function() {
|
||||||
|
for ([[x], y] in a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
(function() {
|
||||||
|
for ([[x], y] in a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1537_destructuring_for_of: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
(function() {
|
||||||
|
for ([[x], y] of a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var x = 1, y = 2;
|
||||||
|
(function() {
|
||||||
|
for ([[x], y] of a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1562: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
var v = 1, B = 2;
|
var v = 1, B = 2;
|
||||||
for (v in objs) f(B);
|
for (v in objs) f(B);
|
||||||
@@ -1363,14 +1463,11 @@ issue_1562: {
|
|||||||
var v = 1;
|
var v = 1;
|
||||||
for (v in objs) f(2);
|
for (v in objs) f(2);
|
||||||
|
|
||||||
var x = 3;
|
while(5) bar(10);
|
||||||
while(x + 2) bar(10);
|
|
||||||
|
|
||||||
var y = 4;
|
do bar(20); while(6);
|
||||||
do bar(20); while(y + 2);
|
|
||||||
|
|
||||||
var z = 5;
|
for (; f(7) ;) bar(30);
|
||||||
for (; f(z + 2) ;) bar(30);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1592,3 +1689,644 @@ var_side_effects_3: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduce_vars_assign: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = 1;
|
||||||
|
a = [].length,
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a = 1;
|
||||||
|
a = [].length,
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}, foo = bar();
|
||||||
|
log(foo);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(x) {
|
||||||
|
console.log(x);
|
||||||
|
})(bar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: false,
|
||||||
|
toplevel: true,
|
||||||
|
unused: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = bar();
|
||||||
|
!function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}(foo);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function(x) {
|
||||||
|
console.log(x);
|
||||||
|
}(bar());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var_defs: {
|
||||||
|
options = {
|
||||||
|
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,
|
||||||
|
keep_fargs:true, if_return:true, join_vars:true, cascade:true, side_effects:true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f1 = function(x, y) {
|
||||||
|
var a, b, r = x + y, q = r * r, z = q - r, a = z, b = 7;
|
||||||
|
console.log(a + b);
|
||||||
|
};
|
||||||
|
f1("1", 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f1 = function(x, y) {
|
||||||
|
var r = x + y, a = r * r - r, b = 7;
|
||||||
|
console.log(a + b);
|
||||||
|
};
|
||||||
|
f1("1", 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "97"
|
||||||
|
}
|
||||||
|
|
||||||
|
assignment: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a;
|
||||||
|
a = x;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_init: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x, y) {
|
||||||
|
var a = x;
|
||||||
|
var b = y;
|
||||||
|
for (a; b;);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x, y) {
|
||||||
|
var b = y;
|
||||||
|
for (x; b;);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_case: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x, y, z) {
|
||||||
|
var a = x();
|
||||||
|
var b = y();
|
||||||
|
var c = z;
|
||||||
|
switch (a) {
|
||||||
|
default: d();
|
||||||
|
case b: e();
|
||||||
|
case c: f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x, y, z) {
|
||||||
|
var c = z;
|
||||||
|
switch (x()) {
|
||||||
|
default: d();
|
||||||
|
case y(): e();
|
||||||
|
case c: f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_27: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(jQuery) {
|
||||||
|
var $;
|
||||||
|
$ = jQuery;
|
||||||
|
$("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(jQuery) {
|
||||||
|
jQuery("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
modified: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1(b) {
|
||||||
|
var a = b;
|
||||||
|
return b + a;
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
var a = b;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
function f3(b) {
|
||||||
|
var a = b++;
|
||||||
|
return b + a;
|
||||||
|
}
|
||||||
|
function f4(b) {
|
||||||
|
var a = b++;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
function f5(b) {
|
||||||
|
var a = function() {
|
||||||
|
return b;
|
||||||
|
}();
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f1(1), f2(1), f3(1), f4(1), f5(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(b) {
|
||||||
|
return b + b;
|
||||||
|
}
|
||||||
|
function f2(b) {
|
||||||
|
var a = b;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
function f3(b) {
|
||||||
|
var a = b++;
|
||||||
|
return b + a;
|
||||||
|
}
|
||||||
|
function f4(b) {
|
||||||
|
var a = b++;
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
function f5(b) {
|
||||||
|
var a = function() {
|
||||||
|
return b;
|
||||||
|
}();
|
||||||
|
return b++ + a;
|
||||||
|
}
|
||||||
|
console.log(f1(1), f2(1), f3(1), f4(1), f5(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "2 2 3 3 2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1858: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(x) {
|
||||||
|
var a = {}, b = a.b = x;
|
||||||
|
return a.b + b;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(x) {
|
||||||
|
var a = {}, b = a.b = x;
|
||||||
|
return a.b + b;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
anonymous_function: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
f ^= 0;
|
||||||
|
return f * a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
f ^= 0;
|
||||||
|
return f * a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_property: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = [];
|
||||||
|
var b = 0;
|
||||||
|
a[b++] = function() { return 42;};
|
||||||
|
var c = a[b++]();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = [];
|
||||||
|
var b = 0;
|
||||||
|
a[b++] = function() { return 42;};
|
||||||
|
var c = a[b++]();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
undeclared: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(x, y) {
|
||||||
|
var a;
|
||||||
|
a = x;
|
||||||
|
b = y;
|
||||||
|
return b + a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(x, y) {
|
||||||
|
var a;
|
||||||
|
a = x;
|
||||||
|
b = y;
|
||||||
|
return b + a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ref_scope: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: 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 function() {
|
||||||
|
return a;
|
||||||
|
}() + b;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2;
|
||||||
|
var a = 3 / a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 3 / (a = 2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
var a = 2;
|
||||||
|
a = 3 / a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a = 3 / (a = 2);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
chained_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = a, c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
var c = a, c = b;
|
||||||
|
b++;
|
||||||
|
return c;
|
||||||
|
}(1, 2));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean_binary_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
a++;
|
||||||
|
(function() {} || a || 3).toString();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a++;
|
||||||
|
(function() {} || a || 3).toString();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean_binary_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
c += 1;
|
||||||
|
(function() {
|
||||||
|
c = 1 + c;
|
||||||
|
} || 9).toString();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
c += 1;
|
||||||
|
(function() {
|
||||||
|
c = 1 + c;
|
||||||
|
} || 9).toString();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
inner_lvalues: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = 10;
|
||||||
|
var a = (--b || a || 3).toString(), c = --b + -a;
|
||||||
|
console.log(null, a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 10;
|
||||||
|
var a = (--b || a || 3).toString(), c = --b + -a;
|
||||||
|
console.log(null, a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
double_def: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = x, a = a && y;
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = x;
|
||||||
|
(a = a && y)();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toplevel_single_reference: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
for (var b in x) {
|
||||||
|
var a = b;
|
||||||
|
b(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
for (var b in x)
|
||||||
|
b(a = b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused_orig: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
console.log(function(b) {
|
||||||
|
var a;
|
||||||
|
var c = b;
|
||||||
|
for (var d in c) {
|
||||||
|
var a = c[0];
|
||||||
|
return --b + a;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
} catch (e) {
|
||||||
|
--b + a;
|
||||||
|
}
|
||||||
|
a && a.NaN;
|
||||||
|
}([2]), a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
console.log(function(b) {
|
||||||
|
var a;
|
||||||
|
var c = b;
|
||||||
|
for (var d in c)
|
||||||
|
return --b + (a = c[0]);
|
||||||
|
a && a.NaN;
|
||||||
|
}([2]), a);
|
||||||
|
}
|
||||||
|
expect_stdout: "3 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_315: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(s) {
|
||||||
|
var w, _i, _len, _ref, _results;
|
||||||
|
_ref = s.trim().split(" ");
|
||||||
|
_results = [];
|
||||||
|
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||||
|
w = _ref[_i];
|
||||||
|
_results.push(w.toLowerCase());
|
||||||
|
}
|
||||||
|
return _results;
|
||||||
|
}("test"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var w, _i, _len, _ref, _results;
|
||||||
|
for (_results = [], _i = 0, _len = (_ref = "test".trim().split(" ")).length; _i < _len ; _i++)
|
||||||
|
w = _ref[_i], _results.push(w.toLowerCase());
|
||||||
|
return _results;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
lvalues_def: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
var a = b++, b = +function() {}();
|
||||||
|
a && a[a++];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
var a = b++, b = +void 0;
|
||||||
|
a && a[a++];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
compound_assignment: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
a += a + 2;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
a += a + 2;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "4"
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_const_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_const_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
++a;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -979,12 +979,12 @@ delete_conditional_1: {
|
|||||||
console.log(delete (1 ? 0 / 0 : x));
|
console.log(delete (1 ? 0 / 0 : x));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -1006,12 +1006,12 @@ delete_conditional_2: {
|
|||||||
console.log(delete (0 ? x : 0 / 0));
|
console.log(delete (0 ? x : 0 / 0));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((Infinity, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,28 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dead_code_block_decls_die: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
booleans : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
if (0) {
|
||||||
|
let foo = 6;
|
||||||
|
const bar = 12;
|
||||||
|
class Baz {};
|
||||||
|
var qux;
|
||||||
|
}
|
||||||
|
console.log(foo, bar, Baz);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var qux;
|
||||||
|
console.log(foo, bar, Baz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dead_code_const_declaration: {
|
dead_code_const_declaration: {
|
||||||
options = {
|
options = {
|
||||||
dead_code : true,
|
dead_code : true,
|
||||||
@@ -256,3 +278,19 @@ try_catch_finally: {
|
|||||||
"1",
|
"1",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
accessor: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
get a() {},
|
||||||
|
set a(v){
|
||||||
|
this.b = 2;
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|||||||
332
test/compress/destructuring.js
Normal file
332
test/compress/destructuring.js
Normal file
@@ -0,0 +1,332 @@
|
|||||||
|
destructuring_arrays: {
|
||||||
|
input: {
|
||||||
|
{const [aa, bb] = cc;}
|
||||||
|
{const [aa, [bb, cc]] = dd;}
|
||||||
|
{let [aa, bb] = cc;}
|
||||||
|
{let [aa, [bb, cc]] = dd;}
|
||||||
|
var [aa, bb] = cc;
|
||||||
|
var [aa, [bb, cc]] = dd;
|
||||||
|
var [,[,,,,,],,,zz,] = xx; // Trailing comma
|
||||||
|
var [,,zzz,,] = xxx; // Trailing comma after hole
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
{const [aa, bb] = cc;}
|
||||||
|
{const [aa, [bb, cc]] = dd;}
|
||||||
|
{let [aa, bb] = cc;}
|
||||||
|
{let [aa, [bb, cc]] = dd;}
|
||||||
|
var [aa, bb] = cc;
|
||||||
|
var [aa, [bb, cc]] = dd;
|
||||||
|
var [,[,,,,,],,,zz] = xx;
|
||||||
|
var [,,zzz,,] = xxx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_arrays_holes: {
|
||||||
|
input: {
|
||||||
|
var [,,,,] = a;
|
||||||
|
var [,,b,] = c;
|
||||||
|
var [d,,] = e;
|
||||||
|
}
|
||||||
|
expect_exact: "var[,,,,]=a;var[,,b]=c;var[d,,]=e;"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_objects: {
|
||||||
|
input: {
|
||||||
|
{const {aa, bb} = {aa:1, bb:2};}
|
||||||
|
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
{let {aa, bb} = {aa:1, bb:2};}
|
||||||
|
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
var {aa, bb} = {aa:1, bb:2};
|
||||||
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
{const {aa, bb} = {aa:1, bb:2};}
|
||||||
|
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
{let {aa, bb} = {aa:1, bb:2};}
|
||||||
|
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
var {aa, bb} = {aa:1, bb:2};
|
||||||
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_objects_trailing_elision: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var {cc,} = foo;
|
||||||
|
}
|
||||||
|
expect_exact: "var{cc}=foo;"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_destructuring_objects: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const [{a},b] = c;
|
||||||
|
let [{a},b] = c;
|
||||||
|
var [{a},b] = c;
|
||||||
|
}
|
||||||
|
expect_exact: 'const[{a},b]=c;let[{a},b]=c;var[{a},b]=c;';
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_constdef_in_loops: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (const [x,y] in pairs);
|
||||||
|
for (const [a] = 0;;);
|
||||||
|
for (const {c} of cees);
|
||||||
|
}
|
||||||
|
expect_exact: "for(const[x,y]in pairs);for(const[a]=0;;);for(const{c}of cees);"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_letdef_in_loops: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (let [x,y] in pairs);
|
||||||
|
for (let [a] = 0;;);
|
||||||
|
for (let {c} of cees);
|
||||||
|
}
|
||||||
|
expect_exact: "for(let[x,y]in pairs);for(let[a]=0;;);for(let{c}of cees);"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_vardef_in_loops: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var [x,y] in pairs);
|
||||||
|
for (var [a] = 0;;);
|
||||||
|
for (var {c} of cees);
|
||||||
|
}
|
||||||
|
expect_exact: "for(var[x,y]in pairs);for(var[a]=0;;);for(var{c}of cees);"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_expressions: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({a, b});
|
||||||
|
[{a}];
|
||||||
|
f({x});
|
||||||
|
}
|
||||||
|
expect_exact: "({a,b});[{a}];f({x});"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_remove_unused_1: {
|
||||||
|
options = {
|
||||||
|
unused: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = [1];
|
||||||
|
var [b] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = {b: 1};
|
||||||
|
var {b} = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function c() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = [[1]];
|
||||||
|
var [[b]] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function d() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = {b: {b:1}};
|
||||||
|
var {b:{b}} = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function e() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = [1, 2, 3, 4, 5];
|
||||||
|
var x = [[1, 2, 3]];
|
||||||
|
var y = {h: 1};
|
||||||
|
var [b, ...c] = a;
|
||||||
|
var [...[e, f]] = x;
|
||||||
|
var [...{g: h}] = y;
|
||||||
|
f(b, c, e, f, g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
var a = [1];
|
||||||
|
var [b] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
var a = {b: 1};
|
||||||
|
var {b} = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function c() {
|
||||||
|
var a = [[1]];
|
||||||
|
var [[b]] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function d() {
|
||||||
|
var a = {b: {b:1}};
|
||||||
|
var {b:{b}} = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function e() {
|
||||||
|
var a = [1, 2, 3, 4, 5];
|
||||||
|
var x = [[1, 2, 3]];
|
||||||
|
var y = {h: 1};
|
||||||
|
var [b, ...c] = a;
|
||||||
|
var [...[e, f]] = x;
|
||||||
|
var [...{g: h}] = y;
|
||||||
|
f(b, c, e, f, g);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_remove_unused_2: {
|
||||||
|
options = {
|
||||||
|
unused: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = [,,1];
|
||||||
|
var [b] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
var unused = "foo";
|
||||||
|
var a = [{a: [1]}];
|
||||||
|
var [{b: a}] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
var a = [,,1];
|
||||||
|
var [b] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
function b() {
|
||||||
|
var a = [{a: [1]}];
|
||||||
|
var [{b: a}] = a;
|
||||||
|
f(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object_destructuring_may_need_parentheses: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({a, b} = {a: 1, b: 2});
|
||||||
|
}
|
||||||
|
expect_exact: "({a,b}={a:1,b:2});"
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_with_undefined_as_default_assignment: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[foo = undefined] = bar;
|
||||||
|
[foo = void 0] = bar;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[foo] = bar;
|
||||||
|
[foo] = bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_dont_evaluate_with_undefined_as_default_assignment: {
|
||||||
|
options = {
|
||||||
|
evaluate: false
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[foo = undefined] = bar;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
[foo = void 0] = bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{const [aa, [bb, cc]] = dd;}
|
||||||
|
{let [aa, [bb, cc]] = dd;}
|
||||||
|
var [aa, [bb, cc]] = dd;
|
||||||
|
[aa, [bb, cc]] = dd;
|
||||||
|
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
|
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||||
|
const [{a},b] = c;
|
||||||
|
let [{a},b] = c;
|
||||||
|
var [{a},b] = c;
|
||||||
|
[{a},b] = c;
|
||||||
|
for (const [x,y] in pairs);
|
||||||
|
for (let [x,y] in pairs);
|
||||||
|
for (var [x,y] in pairs);
|
||||||
|
for ([x,y] in pairs);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
{const [aa, [bb, cc]] = dd;}
|
||||||
|
{let [aa, [bb, cc]] = dd;}
|
||||||
|
var [aa, [bb, cc]] = dd;
|
||||||
|
[aa, [bb, cc]] = dd;
|
||||||
|
{const {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
{let {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};}
|
||||||
|
var {aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}};
|
||||||
|
({aa, bb: {cc, dd}} = {aa:1, bb: {cc:2, dd: 3}});
|
||||||
|
const [{a},b] = c;
|
||||||
|
let [{a},b] = c;
|
||||||
|
var [{a},b] = c;
|
||||||
|
[{a},b] = c;
|
||||||
|
for (const [x,y] in pairs);
|
||||||
|
for (let [x,y] in pairs);
|
||||||
|
for (var [x,y] in pairs);
|
||||||
|
for ([x,y] in pairs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let { foo: [, , ...a] } = { foo: [1, 2, 3, 4], bar: 5 };
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1886: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
let [a] = [1];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let [a] = [1];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: "1"
|
||||||
|
}
|
||||||
10
test/compress/directives.js
Normal file
10
test/compress/directives.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
class_directives_compression: {
|
||||||
|
input: {
|
||||||
|
class foo {
|
||||||
|
foo() {
|
||||||
|
"use strict";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "class foo{foo(){}}"
|
||||||
|
}
|
||||||
@@ -164,6 +164,87 @@ used_var_in_catch: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unused_block_decls_in_catch: {
|
||||||
|
options = { unused: true };
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
try {
|
||||||
|
foo();
|
||||||
|
} catch(ex) {
|
||||||
|
let x = 10;
|
||||||
|
const y = 10;
|
||||||
|
class Zee {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
try {
|
||||||
|
foo();
|
||||||
|
} catch(ex) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
used_block_decls_in_catch: {
|
||||||
|
options = { unused: true };
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
try {
|
||||||
|
foo();
|
||||||
|
} catch(ex) {
|
||||||
|
let x = 10;
|
||||||
|
const y = 10;
|
||||||
|
class Zee {};
|
||||||
|
}
|
||||||
|
console.log(x, y, Zee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
try {
|
||||||
|
foo();
|
||||||
|
} catch(ex) {}
|
||||||
|
console.log(x, y, Zee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused_block_decls: {
|
||||||
|
options = { unused: true };
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
{
|
||||||
|
const x;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let y;
|
||||||
|
}
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
console.log(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused_keep_harmony_destructuring: {
|
||||||
|
options = { unused: true };
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
var {x, y} = foo;
|
||||||
|
var a = foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
var {x, y} = foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
keep_fnames: {
|
keep_fnames: {
|
||||||
options = { unused: true, keep_fnames: true, unsafe: true };
|
options = { unused: true, keep_fnames: true, unsafe: true };
|
||||||
input: {
|
input: {
|
||||||
@@ -935,7 +1016,8 @@ issue_1715_3: {
|
|||||||
try {
|
try {
|
||||||
console;
|
console;
|
||||||
} catch (a) {
|
} catch (a) {
|
||||||
var a = x();
|
var a;
|
||||||
|
x();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f();
|
f();
|
||||||
@@ -1029,3 +1111,145 @@ delete_assign_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_var: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log(a, b);
|
||||||
|
var a = 1, b = 2;
|
||||||
|
console.log(a, b);
|
||||||
|
var a = 3;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(a, b);
|
||||||
|
var a = 1, b = 2;
|
||||||
|
console.log(a, b);
|
||||||
|
a = 3;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"undefined undefined",
|
||||||
|
"1 2",
|
||||||
|
"3 2",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1830_1: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
L: for (var b = console.log(1); !1;) continue L;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
L: for (console.log(1); !1;) continue L;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1830_2: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
L: for (var a = 1, b = console.log(a); --a;) continue L;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a = 1;
|
||||||
|
L: for (console.log(a); --a;) continue L;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1838: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var b = a;
|
||||||
|
while (c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"function f() {",
|
||||||
|
" for (a; c; ) ;",
|
||||||
|
"}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
var_catch_toplevel: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
a--;
|
||||||
|
try {
|
||||||
|
a++;
|
||||||
|
} catch(a) {
|
||||||
|
if (a) var a;
|
||||||
|
var a = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
a--;
|
||||||
|
try {
|
||||||
|
a++;
|
||||||
|
} catch(a) {
|
||||||
|
var a;
|
||||||
|
}
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_const: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
return a = 2, a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -224,6 +224,100 @@ positive_zero: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pow: {
|
||||||
|
options = { evaluate: true }
|
||||||
|
input: {
|
||||||
|
var a = 5 ** 3;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_sequence: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 2 ** 3 ** 2;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 512;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_mixed: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 5 + 2 ** 3 + 5;
|
||||||
|
var b = 5 * 3 ** 2;
|
||||||
|
var c = 5 ** 3 * 2;
|
||||||
|
var d = 5 ** +3;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 18;
|
||||||
|
var b = 45;
|
||||||
|
var c = 250;
|
||||||
|
var d = 125;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_with_right_side_evaluating_to_unary: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = (4 - 7) ** foo;
|
||||||
|
var b = ++bar ** 3;
|
||||||
|
var c = --baz ** 2;
|
||||||
|
}
|
||||||
|
expect_exact: "var a=(-3)**foo;var b=++bar**3;var c=--baz**2;"
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_with_number_constants: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 5 ** NaN;
|
||||||
|
/* NaN exponent results to NaN */
|
||||||
|
var b = 42 ** +0;
|
||||||
|
/* +0 exponent results to NaN */
|
||||||
|
var c = 42 ** -0;
|
||||||
|
/* -0 exponent results to NaN */
|
||||||
|
var d = NaN ** 1;
|
||||||
|
/* NaN with non-zero exponent is NaN */
|
||||||
|
var e = 2 ** Infinity;
|
||||||
|
/* abs(base) > 1 with Infinity as exponent is Infinity */
|
||||||
|
var f = 2 ** -Infinity;
|
||||||
|
/* abs(base) > 1 with -Infinity as exponent is +0 */
|
||||||
|
var g = (-7) ** (0.5);
|
||||||
|
var h = 2324334 ** 34343443;
|
||||||
|
var i = (-2324334) ** 34343443;
|
||||||
|
var j = 2 ** (-3);
|
||||||
|
var k = 2.0 ** -3;
|
||||||
|
var l = 2.0 ** (5 - 7);
|
||||||
|
var m = 3 ** -10; // Result will be 0.000016935087808430286, which is too long
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = NaN;
|
||||||
|
var b = 1;
|
||||||
|
var c = 1;
|
||||||
|
var d = NaN;
|
||||||
|
var e = 1/0;
|
||||||
|
var f = 0;
|
||||||
|
var g = NaN;
|
||||||
|
var h = 1/0;
|
||||||
|
var i = -1/0;
|
||||||
|
var j = .125;
|
||||||
|
var k = .125;
|
||||||
|
var l = .25;
|
||||||
|
var m = 3 ** -10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsafe_constant: {
|
unsafe_constant: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
@@ -922,12 +1016,12 @@ delete_binary_1: {
|
|||||||
console.log(delete (true && (0 / 0)));
|
console.log(delete (true && (0 / 0)));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -948,12 +1042,12 @@ delete_binary_2: {
|
|||||||
console.log(delete (false || (0 / 0)));
|
console.log(delete (false || (0 / 0)));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((Infinity, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
28
test/compress/expansions.js
Normal file
28
test/compress/expansions.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
|
||||||
|
expand_arguments: {
|
||||||
|
input: {
|
||||||
|
func(a, ...rest);
|
||||||
|
func(...all);
|
||||||
|
}
|
||||||
|
expect_exact: "func(a,...rest);func(...all);"
|
||||||
|
}
|
||||||
|
|
||||||
|
expand_expression_arguments: {
|
||||||
|
input: {
|
||||||
|
f(...a.b);
|
||||||
|
f(...a.b());
|
||||||
|
f(...(a));
|
||||||
|
f(...(a.b));
|
||||||
|
f(...a[i]);
|
||||||
|
}
|
||||||
|
expect_exact: "f(...a.b);f(...a.b());f(...a);f(...a.b);f(...a[i]);"
|
||||||
|
}
|
||||||
|
|
||||||
|
expand_parameters: {
|
||||||
|
input: {
|
||||||
|
(function (a, ...b){});
|
||||||
|
(function (...args){});
|
||||||
|
}
|
||||||
|
expect_exact: "(function(a,...b){});(function(...args){});"
|
||||||
|
}
|
||||||
|
|
||||||
52
test/compress/expression.js
Normal file
52
test/compress/expression.js
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
pow: {
|
||||||
|
input: {
|
||||||
|
var a = 2 ** 7;
|
||||||
|
var b = 3;
|
||||||
|
b **= 2;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 2 ** 7;
|
||||||
|
var b = 3;
|
||||||
|
b **= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_with_number_constants: {
|
||||||
|
input: {
|
||||||
|
var a = 5 ** NaN;
|
||||||
|
var b = 42 ** +0;
|
||||||
|
var c = 42 ** -0;
|
||||||
|
var d = NaN ** 1;
|
||||||
|
var e = 2 ** Infinity;
|
||||||
|
var f = 2 ** -Infinity;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 5 ** NaN;
|
||||||
|
var b = 42 ** +0;
|
||||||
|
var c = 42 ** -0;
|
||||||
|
var d = NaN ** 1;
|
||||||
|
var e = 2 ** (1/0);
|
||||||
|
var f = 2 ** (-1/0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_with_parentheses: {
|
||||||
|
input: {
|
||||||
|
var g = (-7) ** (0.5);
|
||||||
|
var h = 2324334 ** 34343443;
|
||||||
|
var i = (-2324334) ** 34343443;
|
||||||
|
var j = 2 ** (-3);
|
||||||
|
var k = 2.0 ** -3;
|
||||||
|
var l = 2.0 ** (5 - 7);
|
||||||
|
}
|
||||||
|
expect_exact: "var g=(-7)**.5;var h=2324334**34343443;var i=(-2324334)**34343443;var j=2**-3;var k=2**-3;var l=2**(5-7);"
|
||||||
|
}
|
||||||
|
|
||||||
|
pow_with_unary_between_brackets: {
|
||||||
|
input: {
|
||||||
|
var a = (-(+5)) ** 3;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = (-+5)**3;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -93,3 +93,77 @@ issue_485_crashing_1530: {
|
|||||||
this, void 0;
|
this, void 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_1841_1: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 10;
|
||||||
|
!function(arg) {
|
||||||
|
for (var key in "hi")
|
||||||
|
var n = arg.baz, n = [ b = 42 ];
|
||||||
|
}(--b);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 10;
|
||||||
|
!function() {
|
||||||
|
for (var key in "hi")
|
||||||
|
b = 42;
|
||||||
|
}(--b);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_exact: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1841_2: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
pure_getters: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 10;
|
||||||
|
!function(arg) {
|
||||||
|
for (var key in "hi")
|
||||||
|
var n = arg.baz, n = [ b = 42 ];
|
||||||
|
}(--b);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 10;
|
||||||
|
!function(arg) {
|
||||||
|
for (var key in "hi")
|
||||||
|
arg.baz, b = 42;
|
||||||
|
}(--b);
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_exact: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
function_returning_constant_literal: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
toplevel: true,
|
||||||
|
evaluate: true,
|
||||||
|
cascade: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function greeter() {
|
||||||
|
return { message: 'Hello there' };
|
||||||
|
}
|
||||||
|
var greeting = greeter();
|
||||||
|
console.log(greeting.message);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("Hello there");
|
||||||
|
}
|
||||||
|
expect_stdout: "Hello there"
|
||||||
|
}
|
||||||
|
|||||||
511
test/compress/harmony.js
Normal file
511
test/compress/harmony.js
Normal file
@@ -0,0 +1,511 @@
|
|||||||
|
arrow_function_parens: {
|
||||||
|
input: {
|
||||||
|
something && (() => {});
|
||||||
|
}
|
||||||
|
expect_exact: "something&&(()=>{});"
|
||||||
|
}
|
||||||
|
arrow_function_parens_2: {
|
||||||
|
input: {
|
||||||
|
(() => null)();
|
||||||
|
}
|
||||||
|
expect_exact: "(()=>null)();"
|
||||||
|
}
|
||||||
|
|
||||||
|
typeof_arrow_functions: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = typeof (x) => null;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=\"function\";"
|
||||||
|
}
|
||||||
|
|
||||||
|
classes: {
|
||||||
|
input: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor() {
|
||||||
|
};
|
||||||
|
foo() {};
|
||||||
|
};
|
||||||
|
class NoSemi {
|
||||||
|
constructor(...args) {
|
||||||
|
}
|
||||||
|
foo() {}
|
||||||
|
};
|
||||||
|
class ChildClass extends SomeClass {};
|
||||||
|
var asExpression = class AsExpression {};
|
||||||
|
var nameless = class {};
|
||||||
|
}
|
||||||
|
expect_exact: "class SomeClass{constructor(){}foo(){}}class NoSemi{constructor(...args){}foo(){}}class ChildClass extends SomeClass{}var asExpression=class AsExpression{};var nameless=class{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
class_statics: {
|
||||||
|
input: {
|
||||||
|
x = class {
|
||||||
|
static staticMethod() {}
|
||||||
|
static get foo() {}
|
||||||
|
static set bar() {}
|
||||||
|
static() { /* "static" can be a method name! */ }
|
||||||
|
get() { /* "get" can be a method name! */ }
|
||||||
|
set() { /* "set" can be a method name! */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "x=class{static staticMethod(){}static get foo(){}static set bar(){}static(){}get(){}set(){}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
class_name_can_be_mangled: {
|
||||||
|
mangle = { };
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
class Foo {
|
||||||
|
}
|
||||||
|
var class1 = Foo
|
||||||
|
var class2 = class Bar {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
class a { }
|
||||||
|
var n = a
|
||||||
|
var r = class a {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_name_can_be_preserved: {
|
||||||
|
mangle = {
|
||||||
|
keep_classnames: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
(class Baz { });
|
||||||
|
class Foo {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
(class Baz { });
|
||||||
|
class Foo {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
classes_can_have_generators: {
|
||||||
|
input: {
|
||||||
|
class Foo {
|
||||||
|
*bar() {}
|
||||||
|
static *baz() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class Foo {
|
||||||
|
*bar() {}
|
||||||
|
static *baz() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
classes_can_have_computed_generators: {
|
||||||
|
input: {
|
||||||
|
class C4 {
|
||||||
|
*['constructor']() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class C4 {
|
||||||
|
*['constructor']() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
classes_can_have_computed_static: {
|
||||||
|
input: {
|
||||||
|
class C4 {
|
||||||
|
static ['constructor']() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class C4 {
|
||||||
|
static ['constructor']() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class_methods_and_getters_with_keep_quoted_props_enabled: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3,
|
||||||
|
keep_quoted_props: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class clss {
|
||||||
|
a() {}
|
||||||
|
"b"() {}
|
||||||
|
get c() { return "c"}
|
||||||
|
get "d"() { return "d"}
|
||||||
|
set e(a) { doSomething(a); }
|
||||||
|
set 'f'(a) { doSomething(b); }
|
||||||
|
static g() {}
|
||||||
|
static "h"() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'class clss{a(){}"b"(){}get c(){return"c"}get"d"(){return"d"}set e(a){doSomething(a)}set\'f\'(a){doSomething(b)}static g(){}static"h"(){}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
classes_with_expression_as_expand: {
|
||||||
|
input: {
|
||||||
|
class D extends (calls++, C) {}
|
||||||
|
}
|
||||||
|
expect_exact: "class D extends(calls++,C){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target: {
|
||||||
|
input: {
|
||||||
|
new.target;
|
||||||
|
new.target.name;
|
||||||
|
}
|
||||||
|
expect_exact: "new.target;new.target.name;"
|
||||||
|
}
|
||||||
|
|
||||||
|
number_literals: {
|
||||||
|
input: {
|
||||||
|
0b1001;
|
||||||
|
0B1001;
|
||||||
|
0o11;
|
||||||
|
0O11;
|
||||||
|
}
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
9;
|
||||||
|
9;
|
||||||
|
9;
|
||||||
|
9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
import_statement: {
|
||||||
|
input: {
|
||||||
|
import "mod-name";
|
||||||
|
import Foo from "bar";
|
||||||
|
import { Bar, Baz } from 'lel';
|
||||||
|
import Bar, { Foo } from 'lel';
|
||||||
|
import { Bar as kex, Baz as food } from 'lel';
|
||||||
|
}
|
||||||
|
expect_exact: 'import"mod-name";import Foo from"bar";import{Bar,Baz}from"lel";import Bar,{Foo}from"lel";import{Bar as kex,Baz as food}from"lel";'
|
||||||
|
}
|
||||||
|
|
||||||
|
import_all_statement: {
|
||||||
|
input: {
|
||||||
|
import * from 'lel';
|
||||||
|
import * as Lel from 'lel';
|
||||||
|
}
|
||||||
|
expect_exact: 'import*from"lel";import*as Lel from"lel";'
|
||||||
|
}
|
||||||
|
|
||||||
|
export_statement: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default 1 + 2;
|
||||||
|
export var foo = 4;
|
||||||
|
export let foo = 6;
|
||||||
|
export const foo = 6;
|
||||||
|
export function foo() {};
|
||||||
|
export class foo { };
|
||||||
|
}
|
||||||
|
expect_exact: "export default 3;export var foo=4;export let foo=6;export const foo=6;export function foo(){};export class foo{};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_object_expression: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default {
|
||||||
|
foo: 1 + 2,
|
||||||
|
bar() { return 4; },
|
||||||
|
get baz() { return this.foo; },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "export default{foo:3,bar(){return 4},get baz(){return this.foo}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_default_array: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default [ 1 + 2, foo ];
|
||||||
|
}
|
||||||
|
expect_exact: "export default[3,foo];"
|
||||||
|
}
|
||||||
|
|
||||||
|
export_module_statement: {
|
||||||
|
input: {
|
||||||
|
export * from "a.js";
|
||||||
|
export {A} from "a.js";
|
||||||
|
export {A, B} from "a.js";
|
||||||
|
export {C};
|
||||||
|
}
|
||||||
|
expect_exact: 'export*from"a.js";export{A}from"a.js";export{A,B}from"a.js";export{C};'
|
||||||
|
}
|
||||||
|
|
||||||
|
import_statement_mangling: {
|
||||||
|
mangle = { toplevel: true };
|
||||||
|
input: {
|
||||||
|
import Foo from "foo";
|
||||||
|
import Bar, {Food} from "lel";
|
||||||
|
import {What as Whatever} from "lel";
|
||||||
|
Foo();
|
||||||
|
Bar();
|
||||||
|
Food();
|
||||||
|
Whatever();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import l from "foo";
|
||||||
|
import e, {Food as o} from "lel";
|
||||||
|
import {What as f} from "lel";
|
||||||
|
l();
|
||||||
|
e();
|
||||||
|
o();
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export_statement_mangling: {
|
||||||
|
mangle = { };
|
||||||
|
input: {
|
||||||
|
export var foo = 6;
|
||||||
|
export function bar() { }
|
||||||
|
export class Baz { }
|
||||||
|
bar(foo, Baz)
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export var foo = 6;
|
||||||
|
export function bar() { }
|
||||||
|
export class Baz { }
|
||||||
|
bar(foo, Baz)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://github.com/mishoo/UglifyJS2/issues/1021
|
||||||
|
regression_for_of_const: {
|
||||||
|
input: {
|
||||||
|
for (const x of y) {}
|
||||||
|
for (const x in y) {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (const x of y);for (const x in y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fabio: My patches accidentally caused a crash whenever
|
||||||
|
// there's an extraneous set of parens around an object.
|
||||||
|
regression_cannot_destructure: {
|
||||||
|
input: {
|
||||||
|
var x = ({ x : 3 });
|
||||||
|
x(({ x: 3 }));
|
||||||
|
}
|
||||||
|
expect_exact: "var x={x:3};x({x:3});";
|
||||||
|
}
|
||||||
|
|
||||||
|
regression_cannot_use_of: {
|
||||||
|
input: {
|
||||||
|
function of() {
|
||||||
|
}
|
||||||
|
var of = "is a valid variable name";
|
||||||
|
of = { of: "is ok" };
|
||||||
|
x.of;
|
||||||
|
of: foo()
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function of(){}
|
||||||
|
var of="is a valid variable name";
|
||||||
|
of={of:"is ok"};
|
||||||
|
x.of;
|
||||||
|
foo(); /* Label statement missing? No prob. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fat_arrow_as_param: {
|
||||||
|
input: {
|
||||||
|
foo(x => x);
|
||||||
|
foo(x => x, y => y);
|
||||||
|
|
||||||
|
foo(x => (x, x));
|
||||||
|
foo(x => (x, x), y => (y, y));
|
||||||
|
}
|
||||||
|
expect_exact: "foo(x=>x);foo(x=>x,y=>y);foo(x=>(x,x));foo(x=>(x,x),y=>(y,y));"
|
||||||
|
}
|
||||||
|
|
||||||
|
default_assign: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b = 3) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
g = ([[] = 123]) => {};
|
||||||
|
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
|
||||||
|
|
||||||
|
function i([[x, y, z] = [4, 5, 6]] = []) {
|
||||||
|
console.log(b);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
g = ([[] = 123]) => {};
|
||||||
|
h = ([[x, y, z] = [4, 5, 6]] = []) => {};
|
||||||
|
|
||||||
|
function i([[x, y, z] = [4, 5, 6]] = []) {
|
||||||
|
console.log(b);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expansion: {
|
||||||
|
options = {
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, ...b) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1613: {
|
||||||
|
mangle = { toplevel: true };
|
||||||
|
input: {
|
||||||
|
const name = 1;
|
||||||
|
const foo = {
|
||||||
|
name
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "const n=1;const c={name:n};"
|
||||||
|
}
|
||||||
|
|
||||||
|
format_methods: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class A extends B {constructor(a){x()} static s(b,c){y()} run(d,e,f){z()}}
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"class A extends B {",
|
||||||
|
" constructor(a) {",
|
||||||
|
" x();",
|
||||||
|
" }",
|
||||||
|
" static s(b, c) {",
|
||||||
|
" y();",
|
||||||
|
" }",
|
||||||
|
" run(d, e, f) {",
|
||||||
|
" z();",
|
||||||
|
" }",
|
||||||
|
"}",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1898: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class Foo {
|
||||||
|
bar() {
|
||||||
|
for (const x of [ 6, 5 ]) {
|
||||||
|
for (let y of [ 4, 3 ]) {
|
||||||
|
for (var z of [ 2, 1 ]) {
|
||||||
|
console.log(x, y, z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new Foo().bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class Foo {
|
||||||
|
bar() {
|
||||||
|
for (const n of [ 6, 5 ])
|
||||||
|
for (let r of [ 4, 3 ])
|
||||||
|
for (var o of [ 2, 1 ])
|
||||||
|
console.log(n, r, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new Foo().bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1753: {
|
||||||
|
mangle = { safari10: true };
|
||||||
|
input: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor(props) {
|
||||||
|
let pickedSets = [];
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
pickedSets.push({
|
||||||
|
mainDrawNumbers: [],
|
||||||
|
extraDrawNumbers: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor(r) {
|
||||||
|
let a = [];
|
||||||
|
for (let s = 0; s < 6; s++)
|
||||||
|
a.push({
|
||||||
|
mainDrawNumbers: [],
|
||||||
|
extraDrawNumbers: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1753_disable: {
|
||||||
|
mangle = { safari10: false }
|
||||||
|
input: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor(props) {
|
||||||
|
let pickedSets = [];
|
||||||
|
for (let i = 0; i < 6; i++) {
|
||||||
|
pickedSets.push({
|
||||||
|
mainDrawNumbers: [],
|
||||||
|
extraDrawNumbers: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class SomeClass {
|
||||||
|
constructor(r) {
|
||||||
|
let a = [];
|
||||||
|
for (let r = 0; r < 6; r++)
|
||||||
|
a.push({
|
||||||
|
mainDrawNumbers: [],
|
||||||
|
extraDrawNumbers: []
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
85
test/compress/hoist.js
Normal file
85
test/compress/hoist.js
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
|
||||||
|
hoist_vars: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
bar();
|
||||||
|
var var1;
|
||||||
|
var var2;
|
||||||
|
}
|
||||||
|
function b(anArg) {
|
||||||
|
bar();
|
||||||
|
var var1;
|
||||||
|
var anArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
var var1, var2; // Vars go up and are joined
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
function b(anArg) {
|
||||||
|
var var1;
|
||||||
|
bar();
|
||||||
|
// But vars named like arguments go away!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_funs: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a() {
|
||||||
|
bar();
|
||||||
|
function foo() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
function foo() {} // Funs go up
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_no_destructurings: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
hoist_funs: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function a([anArg]) {
|
||||||
|
bar();
|
||||||
|
var var1;
|
||||||
|
var anArg; // Because anArg is already declared, this goes away!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a([anArg]) {
|
||||||
|
var var1;
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dont_hoist_var_destructurings: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
hoist_funs: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
// If foo is null or undefined, this should be an exception
|
||||||
|
var {x,y} = foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
var {x,y} = foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,3 +53,12 @@ html_comment_in_string_literal: {
|
|||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
expect_exact: 'function f(){return"\\x3c!--HTML--\\x3ecomment in\\x3c!--string literal--\\x3e"}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html_comment_after_multiline_comment: {
|
||||||
|
input: {
|
||||||
|
var foo; /*
|
||||||
|
*/--> var bar;
|
||||||
|
var foobar;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo;var foobar;"
|
||||||
|
}
|
||||||
|
|||||||
8
test/compress/issue-1001.js
Normal file
8
test/compress/issue-1001.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
parenthesis_strings_in_parenthesis: {
|
||||||
|
input: {
|
||||||
|
var foo = ('(');
|
||||||
|
a(')');
|
||||||
|
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo="(";a(")");'
|
||||||
|
}
|
||||||
30
test/compress/issue-1043.js
Normal file
30
test/compress/issue-1043.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
issue_1043: {
|
||||||
|
options = {
|
||||||
|
side_effects: true
|
||||||
|
};
|
||||||
|
|
||||||
|
input: {
|
||||||
|
function* range(start = 0, end = null, step = 1) {
|
||||||
|
if (end == null) {
|
||||||
|
end = start;
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = start; i < end; i += step) {
|
||||||
|
yield i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect: {
|
||||||
|
function* range(start = 0, end = null, step = 1) {
|
||||||
|
if (null == end) {
|
||||||
|
end = start;
|
||||||
|
start = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = start; i < end; i += step)
|
||||||
|
yield i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
test/compress/issue-1044.js
Normal file
9
test/compress/issue-1044.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
issue_1044: {
|
||||||
|
options = { evaluate: true, conditionals: true };
|
||||||
|
input: {
|
||||||
|
const mixed = Base ? class extends Base {} : class {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const mixed = Base ? class extends Base {} : class {}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
test/compress/issue-1212.js
Normal file
76
test/compress/issue-1212.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
issue_1212_debug_false: {
|
||||||
|
options = {
|
||||||
|
global_defs : { DEBUG: false },
|
||||||
|
sequences : true,
|
||||||
|
properties : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : 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,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class foo {
|
||||||
|
bar() {
|
||||||
|
if (DEBUG)
|
||||||
|
console.log("DEV");
|
||||||
|
else
|
||||||
|
console.log("PROD");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new foo().bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class foo{
|
||||||
|
bar() { console.log("PROD") }
|
||||||
|
}
|
||||||
|
(new foo).bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1212_debug_true: {
|
||||||
|
options = {
|
||||||
|
global_defs : { DEBUG: true },
|
||||||
|
sequences : true,
|
||||||
|
properties : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : 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,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class foo {
|
||||||
|
bar() {
|
||||||
|
if (DEBUG)
|
||||||
|
console.log("DEV");
|
||||||
|
else
|
||||||
|
console.log("PROD");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
new foo().bar();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
class foo{
|
||||||
|
bar() { console.log("DEV") }
|
||||||
|
}
|
||||||
|
(new foo).bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: true
|
keep_quoted: true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -19,7 +19,7 @@ issue_1321_no_debug: {
|
|||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: true,
|
keep_quoted: true,
|
||||||
debug: ""
|
debug: ""
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -39,7 +39,7 @@ issue_1321_debug: {
|
|||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: false
|
keep_quoted: false
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ typeof_eq_undefined: {
|
|||||||
typeof_eq_undefined_ie8: {
|
typeof_eq_undefined_ie8: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
screw_ie8: false
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
|
|||||||
291
test/compress/issue-1466.js
Normal file
291
test/compress/issue-1466.js
Normal file
@@ -0,0 +1,291 @@
|
|||||||
|
same_variable_in_multiple_for_loop: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
let a = 100;
|
||||||
|
console.log(i, a);
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
console.log(i, a);
|
||||||
|
let c = 2;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (let o = 0; o < 3; o++) {
|
||||||
|
let l = 100;
|
||||||
|
console.log(o, l);
|
||||||
|
for (let o = 0; o < 2; o++) {
|
||||||
|
console.log(o, l);
|
||||||
|
let c = 2;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
same_variable_in_multiple_forOf: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let tmp of test) {
|
||||||
|
console.log(tmp);
|
||||||
|
let dd;
|
||||||
|
dd = [ "e", "f", "g" ];
|
||||||
|
for (let tmp of dd) {
|
||||||
|
console.log(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let o of test) {
|
||||||
|
console.log(o);
|
||||||
|
let e;
|
||||||
|
e = [ "e", "f", "g" ];
|
||||||
|
for (let o of e)
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
same_variable_in_multiple_forIn: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: false,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let tmp in test) {
|
||||||
|
console.log(tmp);
|
||||||
|
let dd;
|
||||||
|
dd = [ "e", "f", "g" ];
|
||||||
|
for (let tmp in test) {
|
||||||
|
console.log(tmp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let o in test) {
|
||||||
|
console.log(o);
|
||||||
|
let e;
|
||||||
|
e = [ "e", "f", "g" ];
|
||||||
|
for (let o in test)
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
different_variable_in_multiple_for_loop: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
let a = 100;
|
||||||
|
console.log(i, a);
|
||||||
|
for (let j = 0; j < 2; j++) {
|
||||||
|
console.log(j, a);
|
||||||
|
let c = 2;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (let o = 0; o < 3; o++) {
|
||||||
|
let l = 100;
|
||||||
|
console.log(o, l);
|
||||||
|
for (let o = 0; o < 2; o++) {
|
||||||
|
console.log(o, l);
|
||||||
|
let c = 2;
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
different_variable_in_multiple_forOf: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: true,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let tmp of test) {
|
||||||
|
console.log(tmp);
|
||||||
|
let dd;
|
||||||
|
dd = [ "e", "f", "g" ];
|
||||||
|
for (let t of dd) {
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let o of test) {
|
||||||
|
console.log(o);
|
||||||
|
let e;
|
||||||
|
e = [ "e", "f", "g" ];
|
||||||
|
for (let o of e)
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
different_variable_in_multiple_forIn: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: false,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let tmp in test) {
|
||||||
|
console.log(tmp);
|
||||||
|
let dd;
|
||||||
|
dd = [ "e", "f", "g" ];
|
||||||
|
for (let t in test) {
|
||||||
|
console.log(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var test = [ "a", "b", "c" ];
|
||||||
|
for (let o in test) {
|
||||||
|
console.log(o);
|
||||||
|
let e;
|
||||||
|
e = [ "e", "f", "g" ];
|
||||||
|
for (let o in test)
|
||||||
|
console.log(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
more_variable_in_multiple_for: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
dead_code: true,
|
||||||
|
conditionals: true,
|
||||||
|
comparisons: true,
|
||||||
|
evaluate: true,
|
||||||
|
booleans: true,
|
||||||
|
loops: true,
|
||||||
|
unused: false,
|
||||||
|
keep_fargs: true,
|
||||||
|
if_return: true,
|
||||||
|
join_vars: true,
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
mangle = {}
|
||||||
|
input: {
|
||||||
|
for (let a = 9, i = 0; i < 20; i += a) {
|
||||||
|
let b = a++ + i;
|
||||||
|
console.log(a, b, i);
|
||||||
|
for (let k = b, m = b*b, i = 0; i < 10; i++) {
|
||||||
|
console.log(a, b, m, k, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (let o = 9, l = 0; l < 20; l += o) {
|
||||||
|
let c = o++ + l;
|
||||||
|
console.log(o, c, l);
|
||||||
|
for (let l = c, e = c * c, f = 0; f < 10; f++)
|
||||||
|
console.log(o, c, e, l, f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
screw_ie8: {
|
screw_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
try { throw "foo"; } catch (x) { console.log(x); }
|
try { throw "foo"; } catch (x) { console.log(x); }
|
||||||
@@ -16,10 +16,10 @@ screw_ie8: {
|
|||||||
|
|
||||||
support_ie8: {
|
support_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
try { throw "foo"; } catch (x) { console.log(x); }
|
try { throw "foo"; } catch (x) { console.log(x); }
|
||||||
|
|||||||
@@ -18,9 +18,7 @@ chained_evaluation_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function() {
|
||||||
var c;
|
f(1).bar = 1;
|
||||||
c = f(1);
|
|
||||||
c.bar = 1;
|
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
@@ -46,9 +44,8 @@ chained_evaluation_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function() {
|
||||||
var c, b = "long piece of string";
|
var b = "long piece of string";
|
||||||
c = f(b);
|
f(b).bar = b;
|
||||||
c.bar = b;
|
|
||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,11 +35,11 @@ f7: {
|
|||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_exact: [
|
expect_exact: [
|
||||||
"var a = 100, b = 10;",
|
"var b = 10;",
|
||||||
"",
|
"",
|
||||||
"!function() {",
|
"!function() {",
|
||||||
" for (;b = a, !1; ) ;",
|
" for (;b = 100, !1; ) ;",
|
||||||
"}(), console.log(a, b);",
|
"}(), console.log(100, b);",
|
||||||
]
|
]
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
mangle_catch: {
|
mangle_catch: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -22,11 +22,11 @@ mangle_catch: {
|
|||||||
|
|
||||||
mangle_catch_ie8: {
|
mangle_catch_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -44,11 +44,11 @@ mangle_catch_ie8: {
|
|||||||
|
|
||||||
mangle_catch_var: {
|
mangle_catch_var: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -66,11 +66,11 @@ mangle_catch_var: {
|
|||||||
|
|
||||||
mangle_catch_var_ie8: {
|
mangle_catch_var_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -88,11 +88,11 @@ mangle_catch_var_ie8: {
|
|||||||
|
|
||||||
mangle_catch_toplevel: {
|
mangle_catch_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -110,11 +110,11 @@ mangle_catch_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_ie8_toplevel: {
|
mangle_catch_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -132,11 +132,11 @@ mangle_catch_ie8_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_var_toplevel: {
|
mangle_catch_var_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -154,11 +154,11 @@ mangle_catch_var_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_var_ie8_toplevel: {
|
mangle_catch_var_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -176,11 +176,11 @@ mangle_catch_var_ie8_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_redef_1: {
|
mangle_catch_redef_1: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -198,11 +198,11 @@ mangle_catch_redef_1: {
|
|||||||
|
|
||||||
mangle_catch_redef_1_ie8: {
|
mangle_catch_redef_1_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -220,11 +220,11 @@ mangle_catch_redef_1_ie8: {
|
|||||||
|
|
||||||
mangle_catch_redef_1_toplevel: {
|
mangle_catch_redef_1_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -242,11 +242,11 @@ mangle_catch_redef_1_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_redef_1_ie8_toplevel: {
|
mangle_catch_redef_1_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -264,11 +264,11 @@ mangle_catch_redef_1_ie8_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_redef_2: {
|
mangle_catch_redef_2: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -285,11 +285,11 @@ mangle_catch_redef_2: {
|
|||||||
|
|
||||||
mangle_catch_redef_2_ie8: {
|
mangle_catch_redef_2_ie8: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -306,11 +306,11 @@ mangle_catch_redef_2_ie8: {
|
|||||||
|
|
||||||
mangle_catch_redef_2_toplevel: {
|
mangle_catch_redef_2_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -327,11 +327,11 @@ mangle_catch_redef_2_toplevel: {
|
|||||||
|
|
||||||
mangle_catch_redef_2_ie8_toplevel: {
|
mangle_catch_redef_2_ie8_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
function_iife_catch: {
|
function_iife_catch: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
@@ -21,7 +21,7 @@ function_iife_catch: {
|
|||||||
|
|
||||||
function_iife_catch_ie8: {
|
function_iife_catch_ie8: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(n) {
|
function f(n) {
|
||||||
@@ -42,7 +42,7 @@ function_iife_catch_ie8: {
|
|||||||
|
|
||||||
function_catch_catch: {
|
function_catch_catch: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = 0;
|
var o = 0;
|
||||||
@@ -70,7 +70,7 @@ function_catch_catch: {
|
|||||||
|
|
||||||
function_catch_catch_ie8: {
|
function_catch_catch_ie8: {
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = 0;
|
var o = 0;
|
||||||
|
|||||||
@@ -103,137 +103,3 @@ numeric_literal: {
|
|||||||
"8 7 8",
|
"8 7 8",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier: {
|
|
||||||
mangle_props = {}
|
|
||||||
input: {
|
|
||||||
var obj = {
|
|
||||||
abstract: 1,
|
|
||||||
boolean: 2,
|
|
||||||
byte: 3,
|
|
||||||
char: 4,
|
|
||||||
class: 5,
|
|
||||||
double: 6,
|
|
||||||
enum: 7,
|
|
||||||
export: 8,
|
|
||||||
extends: 9,
|
|
||||||
final: 10,
|
|
||||||
float: 11,
|
|
||||||
goto: 12,
|
|
||||||
implements: 13,
|
|
||||||
import: 14,
|
|
||||||
int: 15,
|
|
||||||
interface: 16,
|
|
||||||
let: 17,
|
|
||||||
long: 18,
|
|
||||||
native: 19,
|
|
||||||
package: 20,
|
|
||||||
private: 21,
|
|
||||||
protected: 22,
|
|
||||||
public: 23,
|
|
||||||
short: 24,
|
|
||||||
static: 25,
|
|
||||||
super: 26,
|
|
||||||
synchronized: 27,
|
|
||||||
this: 28,
|
|
||||||
throws: 29,
|
|
||||||
transient: 30,
|
|
||||||
volatile: 31,
|
|
||||||
yield: 32,
|
|
||||||
false: 33,
|
|
||||||
null: 34,
|
|
||||||
true: 35,
|
|
||||||
break: 36,
|
|
||||||
case: 37,
|
|
||||||
catch: 38,
|
|
||||||
const: 39,
|
|
||||||
continue: 40,
|
|
||||||
debugger: 41,
|
|
||||||
default: 42,
|
|
||||||
delete: 43,
|
|
||||||
do: 44,
|
|
||||||
else: 45,
|
|
||||||
finally: 46,
|
|
||||||
for: 47,
|
|
||||||
function: 48,
|
|
||||||
if: 49,
|
|
||||||
in: 50,
|
|
||||||
instanceof: 51,
|
|
||||||
new: 52,
|
|
||||||
return: 53,
|
|
||||||
switch: 54,
|
|
||||||
throw: 55,
|
|
||||||
try: 56,
|
|
||||||
typeof: 57,
|
|
||||||
var: 58,
|
|
||||||
void: 59,
|
|
||||||
while: 60,
|
|
||||||
with: 61,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var obj = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
c: 3,
|
|
||||||
d: 4,
|
|
||||||
e: 5,
|
|
||||||
f: 6,
|
|
||||||
g: 7,
|
|
||||||
h: 8,
|
|
||||||
i: 9,
|
|
||||||
j: 10,
|
|
||||||
k: 11,
|
|
||||||
l: 12,
|
|
||||||
m: 13,
|
|
||||||
n: 14,
|
|
||||||
o: 15,
|
|
||||||
p: 16,
|
|
||||||
q: 17,
|
|
||||||
r: 18,
|
|
||||||
s: 19,
|
|
||||||
t: 20,
|
|
||||||
u: 21,
|
|
||||||
v: 22,
|
|
||||||
w: 23,
|
|
||||||
x: 24,
|
|
||||||
y: 25,
|
|
||||||
z: 26,
|
|
||||||
A: 27,
|
|
||||||
B: 28,
|
|
||||||
C: 29,
|
|
||||||
D: 30,
|
|
||||||
F: 31,
|
|
||||||
G: 32,
|
|
||||||
false: 33,
|
|
||||||
null: 34,
|
|
||||||
true: 35,
|
|
||||||
H: 36,
|
|
||||||
I: 37,
|
|
||||||
J: 38,
|
|
||||||
K: 39,
|
|
||||||
L: 40,
|
|
||||||
M: 41,
|
|
||||||
N: 42,
|
|
||||||
O: 43,
|
|
||||||
P: 44,
|
|
||||||
Q: 45,
|
|
||||||
R: 46,
|
|
||||||
S: 47,
|
|
||||||
T: 48,
|
|
||||||
U: 49,
|
|
||||||
V: 50,
|
|
||||||
W: 51,
|
|
||||||
X: 52,
|
|
||||||
Y: 53,
|
|
||||||
Z: 54,
|
|
||||||
$: 55,
|
|
||||||
_: 56,
|
|
||||||
aa: 57,
|
|
||||||
ba: 58,
|
|
||||||
ca: 59,
|
|
||||||
da: 60,
|
|
||||||
ea: 61,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ unary_prefix: {
|
|||||||
return x;
|
return x;
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect_exact: "console.log(-2/3);"
|
||||||
console.log(function() {
|
|
||||||
return -2 / 3;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
134
test/compress/issue-1833.js
Normal file
134
test/compress/issue-1833.js
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
iife_for: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
L: for (;;) break L;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
!function() {
|
||||||
|
L: for (;;) break L;
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_for_in: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
L: for (var a in x) break L;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
!function() {
|
||||||
|
L: for (var a in x) break L;
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_do: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
L: do {
|
||||||
|
break L;
|
||||||
|
} while (1);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
!function() {
|
||||||
|
L: do {
|
||||||
|
break L;
|
||||||
|
} while (1);
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_while: {
|
||||||
|
options = {
|
||||||
|
negate_iife: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {
|
||||||
|
L: while (1) break L;
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
!function() {
|
||||||
|
L: while (1) break L;
|
||||||
|
}();
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label_do: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
L: do {
|
||||||
|
continue L;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
L: do {
|
||||||
|
continue L;
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label_while: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
dead_code: true,
|
||||||
|
loops: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
L: while (0) continue L;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function f(){L:;}"
|
||||||
|
}
|
||||||
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;"
|
||||||
|
}
|
||||||
34
test/compress/issue-203.js
Normal file
34
test/compress/issue-203.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
compress_new_function: {
|
||||||
|
options = {
|
||||||
|
unsafe: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new Function("aa, bb", 'return aa;');
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Function("a", "b", "return a");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_new_function_with_destruct: {
|
||||||
|
options = {
|
||||||
|
unsafe: true,
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new Function("aa, [bb]", 'return aa;');
|
||||||
|
new Function("aa, {bb}", 'return aa;');
|
||||||
|
new Function("[[aa]], [{bb}]", 'return aa;');
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Function("a", "[b]", "return a");
|
||||||
|
Function("a", "{bb}", "return a");
|
||||||
|
Function("[[a]]", "[{bb}]", 'return a');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -159,7 +159,7 @@ negate_iife_4: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(){ return t })() ? console.log(true) : console.log(false), function(){
|
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||||
console.log("something");
|
console.log("something");
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -183,7 +183,7 @@ negate_iife_5: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||||
console.log("something");
|
console.log("something");
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -207,7 +207,7 @@ negate_iife_5_off: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function(){ return t })() ? foo(true) : bar(false), function(){
|
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||||
console.log("something");
|
console.log("something");
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
|
|||||||
9
test/compress/issue-926.js
Normal file
9
test/compress/issue-926.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
template_strings: {
|
||||||
|
input: {
|
||||||
|
foo(
|
||||||
|
`<span>${contents}</span>`,
|
||||||
|
`<a href="${url}">${text}</a>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
expect_exact: "foo(`<span>${contents}</span>`,`<a href=\"${url}\">${text}</a>`);"
|
||||||
|
}
|
||||||
40
test/compress/join-vars.js
Normal file
40
test/compress/join-vars.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
only_vars: {
|
||||||
|
options = { join_vars: true };
|
||||||
|
input: {
|
||||||
|
let netmaskBinary = '';
|
||||||
|
for (let i = 0; i < netmaskBits; ++i) {
|
||||||
|
netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let netmaskBinary = '';
|
||||||
|
for (let i = 0; i < netmaskBits; ++i) netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1079_with_vars: {
|
||||||
|
options = { join_vars: true };
|
||||||
|
input: {
|
||||||
|
var netmaskBinary = '';
|
||||||
|
for (var i = 0; i < netmaskBits; ++i) {
|
||||||
|
netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var netmaskBinary = '', i = 0; i < netmaskBits; ++i) netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1079_with_mixed: {
|
||||||
|
options = { join_vars: true };
|
||||||
|
input: {
|
||||||
|
var netmaskBinary = '';
|
||||||
|
for (let i = 0; i < netmaskBits; ++i) {
|
||||||
|
netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var netmaskBinary = ''
|
||||||
|
for (let i = 0; i < netmaskBits; ++i) netmaskBinary += '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -245,7 +245,7 @@ issue_1532: {
|
|||||||
issue_186: {
|
issue_186: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -264,7 +264,7 @@ issue_186: {
|
|||||||
issue_186_ie8: {
|
issue_186_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -283,7 +283,7 @@ issue_186_ie8: {
|
|||||||
issue_186_beautify: {
|
issue_186_beautify: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -310,7 +310,7 @@ issue_186_beautify: {
|
|||||||
issue_186_beautify_ie8: {
|
issue_186_beautify_ie8: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -340,7 +340,7 @@ issue_186_bracketize: {
|
|||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -360,7 +360,7 @@ issue_186_bracketize_ie8: {
|
|||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -380,7 +380,7 @@ issue_186_beautify_bracketize: {
|
|||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
@@ -412,7 +412,7 @@ issue_186_beautify_bracketize_ie8: {
|
|||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
bracketize: true,
|
bracketize: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = 3;
|
var x = 3;
|
||||||
|
|||||||
@@ -25,11 +25,9 @@ negate_iife_2: {
|
|||||||
negate_iife: true
|
negate_iife: true
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(function(){ return {} })().x = 10; // should not transform this one
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function(){ return {} })().x = 10;
|
(function(){ return {} })().x = 10;
|
||||||
}
|
}
|
||||||
|
expect_exact: "({}).x=10;"
|
||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_2_side_effects: {
|
negate_iife_2_side_effects: {
|
||||||
@@ -38,11 +36,9 @@ negate_iife_2_side_effects: {
|
|||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(){ return {} })().x = 10; // should not transform this one
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function(){ return {} })().x = 10;
|
(function(){ return {} })().x = 10;
|
||||||
}
|
}
|
||||||
|
expect_exact: "({}).x=10;"
|
||||||
}
|
}
|
||||||
|
|
||||||
negate_iife_3: {
|
negate_iife_3: {
|
||||||
|
|||||||
@@ -82,3 +82,19 @@ new_with_unary_prefix: {
|
|||||||
}
|
}
|
||||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_with_assignement_expression: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
new x(a = 5 * 2, b = [1, 2, 3], c = {a: "a", b: "b", cd: "c" + "d"});
|
||||||
|
new y([a, b] = [3, 4]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
new x(a = 10, b = [1, 2, 3], c = {a: "a", b: "b", cd: "cd"});
|
||||||
|
new y([a, b] = [3, 4]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
512
test/compress/object.js
Normal file
512
test/compress/object.js
Normal file
@@ -0,0 +1,512 @@
|
|||||||
|
getter_setter: {
|
||||||
|
input: {
|
||||||
|
var get = "bar";
|
||||||
|
var a = {
|
||||||
|
get,
|
||||||
|
set: "foo",
|
||||||
|
get bar() {
|
||||||
|
return this.get;
|
||||||
|
},
|
||||||
|
get 5() {
|
||||||
|
return "five";
|
||||||
|
},
|
||||||
|
get 0xf55() {
|
||||||
|
return "f five five";
|
||||||
|
},
|
||||||
|
get "five"() {
|
||||||
|
return 5;
|
||||||
|
},
|
||||||
|
set one(value) {
|
||||||
|
this._one = value;
|
||||||
|
},
|
||||||
|
set 9(value) {
|
||||||
|
this._nine = value;
|
||||||
|
},
|
||||||
|
set 0b1010(value) {
|
||||||
|
this._ten = value;
|
||||||
|
},
|
||||||
|
set "eleven"(value) {
|
||||||
|
this._eleven = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var b = {
|
||||||
|
get() { return "gift"; },
|
||||||
|
set: function(code) { return "Storing code " + code; }
|
||||||
|
};
|
||||||
|
var c = {
|
||||||
|
["get"]: "foo",
|
||||||
|
["set"]: "bar"
|
||||||
|
};
|
||||||
|
var d = {
|
||||||
|
get: "foo",
|
||||||
|
set: "bar"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var get = "bar";
|
||||||
|
var a = {
|
||||||
|
get,
|
||||||
|
set: "foo",
|
||||||
|
get bar() {
|
||||||
|
return this.get;
|
||||||
|
},
|
||||||
|
get 5() {
|
||||||
|
return "five";
|
||||||
|
},
|
||||||
|
get 0xf55() {
|
||||||
|
return "f five five";
|
||||||
|
},
|
||||||
|
get "five"() {
|
||||||
|
return 5;
|
||||||
|
},
|
||||||
|
set one(value) {
|
||||||
|
this._one = value;
|
||||||
|
},
|
||||||
|
set 9(value) {
|
||||||
|
this._nine = value;
|
||||||
|
},
|
||||||
|
set 0b1010(value) {
|
||||||
|
this._ten = value;
|
||||||
|
},
|
||||||
|
set "eleven"(value) {
|
||||||
|
this._eleven = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var b = {
|
||||||
|
get() { return "gift"; },
|
||||||
|
set: function(code) { return "Storing code " + code; }
|
||||||
|
};
|
||||||
|
var c = {
|
||||||
|
["get"]: "foo",
|
||||||
|
["set"]: "bar"
|
||||||
|
};
|
||||||
|
var d = {
|
||||||
|
get: "foo",
|
||||||
|
set: "bar"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getter_setter_mangler: {
|
||||||
|
mangle = {}
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(get,set) {
|
||||||
|
return {
|
||||||
|
get,
|
||||||
|
set,
|
||||||
|
get g(){},
|
||||||
|
set s(n){},
|
||||||
|
c,
|
||||||
|
a:1,
|
||||||
|
m(){}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function f(n,t){return{get:n,set:t,get g(){},set s(n){},c,a:1,m(){}}}"
|
||||||
|
}
|
||||||
|
|
||||||
|
use_shorthand_opportunity: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = 123;
|
||||||
|
var obj = {foo: foo};
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=123;var obj={foo};"
|
||||||
|
}
|
||||||
|
|
||||||
|
computed_property_names: {
|
||||||
|
input: {
|
||||||
|
obj({ ["x" + "x"]: 6 });
|
||||||
|
}
|
||||||
|
expect_exact: 'obj({["x"+"x"]:6});'
|
||||||
|
}
|
||||||
|
|
||||||
|
computed_property_names_evaluated_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
obj({
|
||||||
|
[1 + 1]: 2,
|
||||||
|
["x" + "x"]: 6
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_exact: 'obj({[2]:2,["xx"]:6});'
|
||||||
|
}
|
||||||
|
|
||||||
|
computed_property_names_evaluated_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = something();
|
||||||
|
|
||||||
|
var obj = {
|
||||||
|
[foo]() {
|
||||||
|
return "blah";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo=something();var obj={[foo](){return"blah"}};'
|
||||||
|
}
|
||||||
|
|
||||||
|
shorthand_properties: {
|
||||||
|
mangle = true;
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
var prop = 1;
|
||||||
|
const value = {prop};
|
||||||
|
return value;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var n = 1;
|
||||||
|
const r = {prop:n};
|
||||||
|
return r;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x = {
|
||||||
|
foo(a, b) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y = {
|
||||||
|
foo([{a}]) {
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
bar(){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "x={foo(a,b){return x}};y={foo([{a}]){return a},bar(){}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_with_computed_property: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
return { /* stuff */ }
|
||||||
|
},
|
||||||
|
[1 + 2]() {
|
||||||
|
return 3;
|
||||||
|
},
|
||||||
|
["1" + "4"]() {
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = {
|
||||||
|
[Symbol.iterator]() {
|
||||||
|
return { /* stuff */ }
|
||||||
|
},
|
||||||
|
[3]() {
|
||||||
|
return 3;
|
||||||
|
},
|
||||||
|
["14"]() {
|
||||||
|
return 14;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_with_computed_property2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
[[1]](){
|
||||||
|
return "success";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
doSomething(foo[[1]]());
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo={[[1]](){return"success"}};doSomething(foo[[1]]());'
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_with_various_property_names: {
|
||||||
|
input: {
|
||||||
|
var get = "bar";
|
||||||
|
var a = {
|
||||||
|
bar() {
|
||||||
|
return this.get;
|
||||||
|
},
|
||||||
|
5() {
|
||||||
|
return "five";
|
||||||
|
},
|
||||||
|
0xf55() {
|
||||||
|
return "f five five";
|
||||||
|
},
|
||||||
|
"five"() {
|
||||||
|
return 5;
|
||||||
|
},
|
||||||
|
0b1010(value) {
|
||||||
|
this._ten = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var get = "bar";
|
||||||
|
var a = {
|
||||||
|
bar() {
|
||||||
|
return this.get;
|
||||||
|
},
|
||||||
|
5() {
|
||||||
|
return "five";
|
||||||
|
},
|
||||||
|
0xf55() {
|
||||||
|
return "f five five";
|
||||||
|
},
|
||||||
|
"five"() {
|
||||||
|
return 5;
|
||||||
|
},
|
||||||
|
0b1010(value) {
|
||||||
|
this._ten = value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_and_mangle_props: {
|
||||||
|
mangle_props = {
|
||||||
|
regex: /_/
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
function x() {
|
||||||
|
obj = {
|
||||||
|
_foo() { return 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function x() {
|
||||||
|
obj = {
|
||||||
|
a() { return 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_generators: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x = {
|
||||||
|
*foo(a, b) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
y = {
|
||||||
|
*foo([{a}]) {
|
||||||
|
yield a;
|
||||||
|
},
|
||||||
|
bar(){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "x={*foo(a,b){return x}};y={*foo([{a}]){yield a},bar(){}};"
|
||||||
|
}
|
||||||
|
|
||||||
|
concise_methods_and_keyword_names: {
|
||||||
|
input: {
|
||||||
|
x = {
|
||||||
|
catch() {},
|
||||||
|
throw() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x={catch(){},throw(){}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getter_setter_with_computed_value: {
|
||||||
|
input: {
|
||||||
|
class C {
|
||||||
|
get ['a']() {
|
||||||
|
return 'A';
|
||||||
|
}
|
||||||
|
set ['a'](value) {
|
||||||
|
do_something(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var x = {
|
||||||
|
get [a.b]() {
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class MyArray extends Array {
|
||||||
|
get [Symbol.species]() {
|
||||||
|
return Array;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'class C{get["a"](){return"A"}set["a"](value){do_something(a)}}var x={get[a.b](){return 42}};class MyArray extends Array{get[Symbol.species](){return Array}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
property_with_operator_value: {
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
"*": 1,
|
||||||
|
get "*"() {
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
|
*"*"() {
|
||||||
|
return 3;
|
||||||
|
},
|
||||||
|
"%": 1,
|
||||||
|
get "%"() {
|
||||||
|
return 2;
|
||||||
|
},
|
||||||
|
*"%"() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class bar {
|
||||||
|
get "*"() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
*"*"() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
get "%"() {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
*"%"() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo={"*":1,get"*"(){return 2},*"*"(){return 3},"%":1,get"%"(){return 2},*"%"(){return 3}};class bar{get"*"(){return 1}*"*"(){return 2}get"%"(){return 1}*"%"(){return 2}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
property_with_unprintable: {
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
"\x00\x01": "foo",
|
||||||
|
get "\x00\x01"() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
set "\x00\x01"(foo) {
|
||||||
|
save(foo);
|
||||||
|
},
|
||||||
|
*"\x00\x01"() {
|
||||||
|
return "foobar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class bar {
|
||||||
|
get "\x00\x01"() {
|
||||||
|
return "bar"
|
||||||
|
}
|
||||||
|
set "\x00\x01"(foo) {
|
||||||
|
save(foo);
|
||||||
|
}
|
||||||
|
*"\x00\x01"() {
|
||||||
|
return "foobar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo={"\\0\x01":"foo",get"\\0\x01"(){return"bar"},set"\\0\x01"(foo){save(foo)},*"\\0\x01"(){return"foobar"}};class bar{get"\\0\x01"(){return"bar"}set"\\0\x01"(foo){save(foo)}*"\\0\x01"(){return"foobar"}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
property_with_unprintable_ascii_only: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = {
|
||||||
|
"\x00\x01": "foo",
|
||||||
|
get "\x00\x01"() {
|
||||||
|
return "bar";
|
||||||
|
},
|
||||||
|
set "\x00\x01"(foo) {
|
||||||
|
save(foo);
|
||||||
|
},
|
||||||
|
*"\x00\x01"() {
|
||||||
|
return "foobar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class bar {
|
||||||
|
get "\x00\x01"() {
|
||||||
|
return "bar"
|
||||||
|
}
|
||||||
|
set "\x00\x01"(foo) {
|
||||||
|
save(foo);
|
||||||
|
}
|
||||||
|
*"\x00\x01"() {
|
||||||
|
return "foobar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo={"\\0\\x01":"foo",get"\\0\\x01"(){return"bar"},set"\\0\\x01"(foo){save(foo)},*"\\0\\x01"(){return"foobar"}};class bar{get"\\0\\x01"(){return"bar"}set"\\0\\x01"(foo){save(foo)}*"\\0\\x01"(){return"foobar"}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
property_with_unprintable_ascii_only_static: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
class foo {
|
||||||
|
static get "\x02\x03"() {
|
||||||
|
return "bar";
|
||||||
|
}
|
||||||
|
static set "\x04\x05"(foo) {
|
||||||
|
save(foo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'class foo{static get"\\x02\\x03"(){return"bar"}static set"\\x04\\x05"(foo){save(foo)}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
methods_and_getters_with_keep_quoted_props_enabled: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3,
|
||||||
|
keep_quoted_props: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var obj = {
|
||||||
|
a() {},
|
||||||
|
"b"() {},
|
||||||
|
get c() { return "c"},
|
||||||
|
get "d"() { return "d"},
|
||||||
|
set e(a) { doSomething(a); },
|
||||||
|
set f(a) { doSomething(b); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var obj={a(){},"b"(){},get c(){return"c"},get"d"(){return"d"},set e(a){doSomething(a)},set f(a){doSomething(b)}};'
|
||||||
|
}
|
||||||
|
|
||||||
|
allow_assignments_to_property_values: {
|
||||||
|
input: {
|
||||||
|
var foo = {123: foo = 123} = {foo: "456"};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = {123: foo = 123} = {foo: "456"};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
variable_as_computed_property: {
|
||||||
|
input: {
|
||||||
|
function getLine(header) {
|
||||||
|
return {
|
||||||
|
[header]: {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function getLine(header){return{[header]:{}}}"
|
||||||
|
}
|
||||||
180
test/compress/parameters.js
Normal file
180
test/compress/parameters.js
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
arrow_functions: {
|
||||||
|
input: {
|
||||||
|
(a) => b; // 1 args
|
||||||
|
(a, b) => c; // n args
|
||||||
|
() => b; // 0 args
|
||||||
|
(a) => (b) => c; // func returns func returns func
|
||||||
|
(a) => ((b) => c); // So these parens are dropped
|
||||||
|
() => (b,c) => d; // func returns func returns func
|
||||||
|
a=>{return b;}
|
||||||
|
a => 'lel'; // Dropping the parens
|
||||||
|
}
|
||||||
|
expect_exact: "a=>b;(a,b)=>c;()=>b;a=>b=>c;a=>b=>c;()=>(b,c)=>d;a=>b;a=>\"lel\";"
|
||||||
|
}
|
||||||
|
|
||||||
|
arrow_return: {
|
||||||
|
input: {
|
||||||
|
() => {};
|
||||||
|
() => { return; };
|
||||||
|
a => { return 1; }
|
||||||
|
a => { return -b }
|
||||||
|
a => { return b; var b; }
|
||||||
|
(x, y) => { return x - y; }
|
||||||
|
}
|
||||||
|
expect_exact: "()=>{};()=>{};a=>1;a=>-b;a=>{return b;var b};(x,y)=>x-y;"
|
||||||
|
}
|
||||||
|
|
||||||
|
regression_arrow_functions_and_hoist: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
hoist_funs: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(a) => b;
|
||||||
|
}
|
||||||
|
expect_exact: "a=>b;"
|
||||||
|
}
|
||||||
|
|
||||||
|
regression_assign_arrow_functions: {
|
||||||
|
input: {
|
||||||
|
oninstall = e => false;
|
||||||
|
oninstall = () => false;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
oninstall=e=>false;
|
||||||
|
oninstall=()=>false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_arguments_1: {
|
||||||
|
input: {
|
||||||
|
(function ( a ) { });
|
||||||
|
(function ( [ a ] ) { });
|
||||||
|
(function ( [ a, b ] ) { });
|
||||||
|
(function ( [ [ a ] ] ) { });
|
||||||
|
(function ( [ [ a, b ] ] ) { });
|
||||||
|
(function ( [ a, [ b ] ] ) { });
|
||||||
|
(function ( [ [ b ], a ] ) { });
|
||||||
|
|
||||||
|
(function ( { a } ) { });
|
||||||
|
(function ( { a, b } ) { });
|
||||||
|
|
||||||
|
(function ( [ { a } ] ) { });
|
||||||
|
(function ( [ { a, b } ] ) { });
|
||||||
|
(function ( [ a, { b } ] ) { });
|
||||||
|
(function ( [ { b }, a ] ) { });
|
||||||
|
|
||||||
|
( [ a ] ) => { };
|
||||||
|
( [ a, b ] ) => { };
|
||||||
|
|
||||||
|
( { a } ) => { };
|
||||||
|
( { a, b, c, d, e } ) => { };
|
||||||
|
|
||||||
|
( [ a ] ) => b;
|
||||||
|
( [ a, b ] ) => c;
|
||||||
|
|
||||||
|
( { a } ) => b;
|
||||||
|
( { a, b } ) => c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a){});
|
||||||
|
(function([a]){});
|
||||||
|
(function([a,b]){});
|
||||||
|
(function([[a]]){});
|
||||||
|
(function([[a,b]]){});
|
||||||
|
(function([a,[b]]){});
|
||||||
|
(function([[b],a]){});
|
||||||
|
|
||||||
|
(function({a}){});
|
||||||
|
(function({a,b}){});
|
||||||
|
|
||||||
|
(function([{a}]){});
|
||||||
|
(function([{a,b}]){});
|
||||||
|
(function([a,{b}]){});
|
||||||
|
(function([{b},a]){});
|
||||||
|
|
||||||
|
([a])=>{};
|
||||||
|
([a,b])=>{};
|
||||||
|
|
||||||
|
({a})=>{};
|
||||||
|
({a,b,c,d,e})=>{};
|
||||||
|
|
||||||
|
([a])=>b;
|
||||||
|
([a,b])=>c;
|
||||||
|
|
||||||
|
({a})=>b;
|
||||||
|
({a,b})=>c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_arguments_2: {
|
||||||
|
input: {
|
||||||
|
(function([]) {});
|
||||||
|
(function({}) {});
|
||||||
|
(function([,,,,,]) {});
|
||||||
|
(function ([a, {b: c}]) {});
|
||||||
|
(function ([...args]) {});
|
||||||
|
(function ({x,}) {});
|
||||||
|
class a { *method({ [thrower()]: x } = {}) {}};
|
||||||
|
(function(a, b, c, d, [{e: [...f]}]){})(1, 2, 3, 4, [{e: [1, 2, 3]}]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function([]) {});
|
||||||
|
(function({}) {});
|
||||||
|
(function([,,,,,]) {});
|
||||||
|
(function ([a, {b: c}]) {});
|
||||||
|
(function ([...args]) {});
|
||||||
|
(function ({x,}) {});
|
||||||
|
class a { *method({ [thrower()]: x } = {}) {}};
|
||||||
|
(function(a, b, c, d, [{e: [...f]}]){})(1, 2, 3, 4, [{e: [1, 2, 3]}]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destructuring_arguments_3: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function fn3({x: {y: {z: {} = 42}}}) {}
|
||||||
|
const { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||||
|
let { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||||
|
var { cover = (function () {}), xCover = (0, function() {}) } = {};
|
||||||
|
}
|
||||||
|
expect_exact: "function fn3({x:{y:{z:{}=42}}}){}const{cover=function(){},xCover=(0,function(){})}={};let{cover=function(){},xCover=(0,function(){})}={};var{cover=function(){},xCover=(0,function(){})}={};"
|
||||||
|
}
|
||||||
|
|
||||||
|
default_arguments: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x(a = 6) { }
|
||||||
|
function x(a = (6 + 5)) { }
|
||||||
|
function x({ foo } = {}, [ bar ] = [ 1 ]) { }
|
||||||
|
}
|
||||||
|
expect_exact: "function x(a=6){}function x(a=6+5){}function x({foo}={},[bar]=[1]){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
default_values_in_destructurings: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function x({a=(4), b}) {}
|
||||||
|
function x([b, c=(12)]) {}
|
||||||
|
var { x = (6), y } = x;
|
||||||
|
var [ x, y = (6) ] = x;
|
||||||
|
}
|
||||||
|
expect_exact: "function x({a=4,b}){}function x([b,c=12]){}var{x=6,y}=x;var[x,y=6]=x;"
|
||||||
|
}
|
||||||
|
|
||||||
|
accept_duplicated_parameters_in_non_strict_without_spread_or_default_assignment: {
|
||||||
|
input: {
|
||||||
|
function a(b, b){}
|
||||||
|
function b({c: test, c: test}){}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a(b, b){}
|
||||||
|
function b({c: test, c: test}){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ keep_properties: {
|
|||||||
dot_properties: {
|
dot_properties: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
screw_ie8: false
|
ie8: true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
@@ -36,7 +36,7 @@ dot_properties: {
|
|||||||
dot_properties_es5: {
|
dot_properties_es5: {
|
||||||
options = {
|
options = {
|
||||||
properties: true,
|
properties: true,
|
||||||
screw_ie8: true
|
ie8: false,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
@@ -125,7 +125,7 @@ evaluate_string_length: {
|
|||||||
|
|
||||||
mangle_properties: {
|
mangle_properties: {
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: false
|
keep_quoted: false
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
@@ -148,7 +148,8 @@ mangle_unquoted_properties: {
|
|||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: true
|
builtins: true,
|
||||||
|
keep_quoted: true
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -233,12 +234,13 @@ mangle_debug_suffix: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_suffix_ignore_quoted: {
|
mangle_debug_suffix_keep_quoted: {
|
||||||
options = {
|
options = {
|
||||||
properties: false
|
properties: false
|
||||||
}
|
}
|
||||||
mangle_props = {
|
mangle_props = {
|
||||||
ignore_quoted: true,
|
builtins: true,
|
||||||
|
keep_quoted: true,
|
||||||
debug: "XYZ",
|
debug: "XYZ",
|
||||||
reserved: []
|
reserved: []
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,3 +119,62 @@ 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: {}
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,22 +41,20 @@ reduce_vars: {
|
|||||||
var A = 1;
|
var A = 1;
|
||||||
(function() {
|
(function() {
|
||||||
console.log(-3);
|
console.log(-3);
|
||||||
console.log(-4);
|
console.log(A - 5);
|
||||||
})();
|
})();
|
||||||
(function f1() {
|
(function f1() {
|
||||||
var a = 2;
|
var a = 2;
|
||||||
console.log(-3);
|
console.log(a - 5);
|
||||||
eval("console.log(a);");
|
eval("console.log(a);");
|
||||||
})();
|
})();
|
||||||
(function f2(eval) {
|
(function f2(eval) {
|
||||||
var a = 2;
|
var a = 2;
|
||||||
console.log(-3);
|
console.log(a - 5);
|
||||||
eval("console.log(a);");
|
eval("console.log(a);");
|
||||||
})(eval);
|
})(eval);
|
||||||
(function() {
|
"yes";
|
||||||
return "yes";
|
console.log(A + 1);
|
||||||
})();
|
|
||||||
console.log(2);
|
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -66,7 +64,7 @@ modified: {
|
|||||||
conditionals : true,
|
conditionals : true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
unused : true
|
unused : true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f0() {
|
function f0() {
|
||||||
@@ -136,12 +134,11 @@ modified: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var b = 2;
|
3;
|
||||||
b = 3;
|
|
||||||
console.log(1 + b);
|
|
||||||
console.log(b + 3);
|
|
||||||
console.log(4);
|
console.log(4);
|
||||||
console.log(1 + b + 3);
|
console.log(6);
|
||||||
|
console.log(4);
|
||||||
|
console.log(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f3() {
|
function f3() {
|
||||||
@@ -300,7 +297,7 @@ unsafe_evaluate_array: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe_evaluate_equality: {
|
unsafe_evaluate_equality_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
@@ -308,47 +305,62 @@ unsafe_evaluate_equality: {
|
|||||||
unused : true
|
unused : true
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f0(){
|
function f0() {
|
||||||
var a = {};
|
var a = {};
|
||||||
console.log(a === a);
|
return a === a;
|
||||||
}
|
}
|
||||||
|
function f1() {
|
||||||
function f1(){
|
|
||||||
var a = [];
|
var a = [];
|
||||||
console.log(a === a);
|
return a === a;
|
||||||
}
|
}
|
||||||
|
console.log(f0(), f1());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f0() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
function f1() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
console.log(f0(), f1());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
function f2(){
|
unsafe_evaluate_equality_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate : true,
|
||||||
|
passes : 2,
|
||||||
|
reduce_vars : true,
|
||||||
|
unsafe : true,
|
||||||
|
unused : true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f2() {
|
||||||
var a = {a:1, b:2};
|
var a = {a:1, b:2};
|
||||||
var b = a;
|
var b = a;
|
||||||
var c = a;
|
var c = a;
|
||||||
console.log(b === c);
|
return b === c;
|
||||||
}
|
}
|
||||||
|
function f3() {
|
||||||
function f3(){
|
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
var b = a;
|
var b = a;
|
||||||
var c = a;
|
var c = a;
|
||||||
console.log(b === c);
|
return b === c;
|
||||||
}
|
}
|
||||||
|
console.log(f2(), f3());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0(){
|
function f2() {
|
||||||
console.log(true);
|
return true;
|
||||||
}
|
}
|
||||||
|
function f3() {
|
||||||
function f1(){
|
return true;
|
||||||
console.log(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f2(){
|
|
||||||
console.log(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function f3(){
|
|
||||||
console.log(true);
|
|
||||||
}
|
}
|
||||||
|
console.log(f2(), f3());
|
||||||
}
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
passes: {
|
passes: {
|
||||||
@@ -375,12 +387,11 @@ passes: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
var b = 2;
|
3;
|
||||||
b = 3;
|
|
||||||
console.log(1 + b);
|
|
||||||
console.log(b + 3);
|
|
||||||
console.log(4);
|
console.log(4);
|
||||||
console.log(1 + b + 3);
|
console.log(6);
|
||||||
|
console.log(4);
|
||||||
|
console.log(7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -573,7 +584,7 @@ inner_var_label: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inner_var_for: {
|
inner_var_for_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -602,6 +613,29 @@ inner_var_for: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inner_var_for_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = 1;
|
||||||
|
for (var b = 1; --b;) var a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
a = 1;
|
||||||
|
for (var b = 1; --b;) var a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
inner_var_for_in_1: {
|
inner_var_for_in_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -1639,7 +1673,7 @@ redefine_arguments_1: {
|
|||||||
return typeof arguments;
|
return typeof arguments;
|
||||||
}
|
}
|
||||||
function g() {
|
function g() {
|
||||||
return"number";
|
return "number";
|
||||||
}
|
}
|
||||||
function h(x) {
|
function h(x) {
|
||||||
var arguments = x;
|
var arguments = x;
|
||||||
@@ -1678,9 +1712,7 @@ redefine_arguments_2: {
|
|||||||
console.log(function() {
|
console.log(function() {
|
||||||
var arguments;
|
var arguments;
|
||||||
return typeof arguments;
|
return typeof arguments;
|
||||||
}(), function() {
|
}(), "number", function(x) {
|
||||||
return"number";
|
|
||||||
}(), function(x) {
|
|
||||||
var arguments = x;
|
var arguments = x;
|
||||||
return typeof arguments;
|
return typeof arguments;
|
||||||
}());
|
}());
|
||||||
@@ -1717,7 +1749,10 @@ redefine_arguments_3: {
|
|||||||
console.log(function() {
|
console.log(function() {
|
||||||
var arguments;
|
var arguments;
|
||||||
return typeof arguments;
|
return typeof arguments;
|
||||||
}(), "number", "undefined");
|
}(), "number", function(x) {
|
||||||
|
var arguments = x;
|
||||||
|
return typeof arguments;
|
||||||
|
}());
|
||||||
}
|
}
|
||||||
expect_stdout: "object number undefined"
|
expect_stdout: "object number undefined"
|
||||||
}
|
}
|
||||||
@@ -1789,9 +1824,7 @@ redefine_farg_2: {
|
|||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
var a;
|
var a;
|
||||||
return typeof a;
|
return typeof a;
|
||||||
}([]), function() {
|
}([]), "number",function(a, b) {
|
||||||
return "number";
|
|
||||||
}(),function(a, b) {
|
|
||||||
var a = b;
|
var a = b;
|
||||||
return typeof a;
|
return typeof a;
|
||||||
}([]));
|
}([]));
|
||||||
@@ -1828,10 +1861,7 @@ redefine_farg_3: {
|
|||||||
console.log(function(a) {
|
console.log(function(a) {
|
||||||
var a;
|
var a;
|
||||||
return typeof a;
|
return typeof a;
|
||||||
}([]), "number", function(a) {
|
}([]), "number", "undefined");
|
||||||
var a = void 0;
|
|
||||||
return typeof a;
|
|
||||||
}([]));
|
|
||||||
}
|
}
|
||||||
expect_stdout: "object number undefined"
|
expect_stdout: "object number undefined"
|
||||||
}
|
}
|
||||||
@@ -1951,7 +1981,6 @@ pure_getters_2: {
|
|||||||
var a = a && a.b;
|
var a = a && a.b;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
|
||||||
var a = a && a.b;
|
var a = a && a.b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1995,3 +2024,516 @@ catch_var: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var_assign_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
console.log(2);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_assign_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
if (a = 2) console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
if (2) console.log(2);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_assign_3: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
while (a = 2);
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
while (a = 2);
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var_assign_4: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function a() {
|
||||||
|
a = 2;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function a() {
|
||||||
|
a = 2,
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var_assign_5: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
!function(b) {
|
||||||
|
a = 2;
|
||||||
|
console.log(a, b);
|
||||||
|
}(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
!function(b) {
|
||||||
|
a = 2,
|
||||||
|
console.log(a, b);
|
||||||
|
}(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "2 undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_assign_6: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = function(){}(a = 1);
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a = function(){}(a = 1);
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
immutable: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = "test";
|
||||||
|
console.log(a.indexOf("e"));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
console.log("test".indexOf("e"));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1814_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 42;
|
||||||
|
!function() {
|
||||||
|
var b = a;
|
||||||
|
!function(a) {
|
||||||
|
console.log(a++, b);
|
||||||
|
}(0);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 42;
|
||||||
|
!function() {
|
||||||
|
!function(a) {
|
||||||
|
console.log(a++, 42);
|
||||||
|
}(0);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "0 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1814_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = "32";
|
||||||
|
!function() {
|
||||||
|
var b = a + 1;
|
||||||
|
!function(a) {
|
||||||
|
console.log(a++, b);
|
||||||
|
}(0);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = "32";
|
||||||
|
!function() {
|
||||||
|
!function(a) {
|
||||||
|
console.log(a++, "321");
|
||||||
|
}(0);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "0 '321'"
|
||||||
|
}
|
||||||
|
|
||||||
|
try_abort: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
var a = 1;
|
||||||
|
throw "";
|
||||||
|
var b = 2;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
try {
|
||||||
|
var a = 1;
|
||||||
|
throw "";
|
||||||
|
var b = 2;
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
console.log(a, b);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1 undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean_binary_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
void 0 && (a = 1);
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
void 0;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
cond_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
void 0 ? (a = 1) : 0;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a;
|
||||||
|
void 0 ? (a = 1) : 0;
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
iife_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
!function() {
|
||||||
|
var a = 1, b = 0;
|
||||||
|
!function() {
|
||||||
|
b++;
|
||||||
|
return;
|
||||||
|
a = 2;
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
!function() {
|
||||||
|
var a = 1, b = 0;
|
||||||
|
!function() {
|
||||||
|
b++;
|
||||||
|
return;
|
||||||
|
a = 2;
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1850_1: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1850_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: "funcs",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
(function() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1850_3: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: "vars",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1850_4: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
}
|
||||||
|
var a = 1;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
(function() {
|
||||||
|
console.log(a, a, a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1865: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(some) {
|
||||||
|
some.thing = false;
|
||||||
|
}
|
||||||
|
console.log(function() {
|
||||||
|
var some = { thing: true };
|
||||||
|
f(some);
|
||||||
|
return some.thing;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(some) {
|
||||||
|
some.thing = false;
|
||||||
|
}
|
||||||
|
console.log(function() {
|
||||||
|
var some = { thing: true };
|
||||||
|
f(some);
|
||||||
|
return some.thing;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1922_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
arguments[0] = 2;
|
||||||
|
return a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
arguments[0] = 2;
|
||||||
|
return a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "2"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1922_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var a;
|
||||||
|
eval("a = 1");
|
||||||
|
return a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var a;
|
||||||
|
eval("a = 1");
|
||||||
|
return a;
|
||||||
|
}(1));
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
accessor: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}.b, a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
console.log({
|
||||||
|
get a() {
|
||||||
|
a = 2;
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
b: 1
|
||||||
|
}.b, a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
do_screw: {
|
do_screw: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
ascii_only: true,
|
ascii_only: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -14,10 +14,10 @@ do_screw: {
|
|||||||
|
|
||||||
dont_screw: {
|
dont_screw: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
ascii_only: true,
|
ascii_only: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -28,7 +28,7 @@ dont_screw: {
|
|||||||
|
|
||||||
do_screw_constants: {
|
do_screw_constants: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
f(undefined, Infinity);
|
f(undefined, Infinity);
|
||||||
@@ -38,7 +38,7 @@ do_screw_constants: {
|
|||||||
|
|
||||||
dont_screw_constants: {
|
dont_screw_constants: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
f(undefined, Infinity);
|
f(undefined, Infinity);
|
||||||
@@ -47,9 +47,15 @@ dont_screw_constants: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_screw_try_catch: {
|
do_screw_try_catch: {
|
||||||
options = { screw_ie8: true };
|
options = {
|
||||||
mangle = { screw_ie8: true };
|
ie8: false,
|
||||||
beautify = { screw_ie8: true };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
good = function(e){
|
good = function(e){
|
||||||
return function(error){
|
return function(error){
|
||||||
@@ -75,9 +81,15 @@ do_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch: {
|
dont_screw_try_catch: {
|
||||||
options = { screw_ie8: false };
|
options = {
|
||||||
mangle = { screw_ie8: false };
|
ie8: true,
|
||||||
beautify = { screw_ie8: false };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
bad = function(e){
|
bad = function(e){
|
||||||
return function(error){
|
return function(error){
|
||||||
@@ -103,9 +115,15 @@ dont_screw_try_catch: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
do_screw_try_catch_undefined: {
|
do_screw_try_catch_undefined: {
|
||||||
options = { screw_ie8: true };
|
options = {
|
||||||
mangle = { screw_ie8: true };
|
ie8: false,
|
||||||
beautify = { screw_ie8: true };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: false,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b){
|
function a(b){
|
||||||
try {
|
try {
|
||||||
@@ -132,9 +150,15 @@ do_screw_try_catch_undefined: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dont_screw_try_catch_undefined: {
|
dont_screw_try_catch_undefined: {
|
||||||
options = { screw_ie8: false };
|
options = {
|
||||||
mangle = { screw_ie8: false };
|
ie8: true,
|
||||||
beautify = { screw_ie8: false };
|
}
|
||||||
|
mangle = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
function a(b){
|
function a(b){
|
||||||
try {
|
try {
|
||||||
@@ -164,11 +188,11 @@ reduce_vars: {
|
|||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
@@ -196,10 +220,10 @@ reduce_vars: {
|
|||||||
|
|
||||||
issue_1586_1: {
|
issue_1586_1: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: false,
|
ie8: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
@@ -215,10 +239,10 @@ issue_1586_1: {
|
|||||||
|
|
||||||
issue_1586_2: {
|
issue_1586_2: {
|
||||||
options = {
|
options = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
screw_ie8: true,
|
ie8: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f() {
|
function f() {
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ issue_1758: {
|
|||||||
console.log(function(c) {
|
console.log(function(c) {
|
||||||
var undefined = 42;
|
var undefined = 42;
|
||||||
return function() {
|
return function() {
|
||||||
return c--, c--, c.toString(), void 0;
|
return c--, c--, void c.toString();
|
||||||
}();
|
}();
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
@@ -481,12 +481,12 @@ delete_seq_1: {
|
|||||||
console.log(delete (1, 0 / 0));
|
console.log(delete (1, 0 / 0));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((0 / 0, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -505,12 +505,12 @@ delete_seq_2: {
|
|||||||
console.log(delete (1, 2, 0 / 0));
|
console.log(delete (1, 2, 0 / 0));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((0 / 0, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -530,12 +530,12 @@ delete_seq_3: {
|
|||||||
console.log(delete (1, 2, 0 / 0));
|
console.log(delete (1, 2, 0 / 0));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((void 0, !0));
|
console.log(!0);
|
||||||
console.log((Infinity, !0));
|
console.log(!0);
|
||||||
console.log((1 / 0, !0));
|
console.log(!0);
|
||||||
console.log((NaN, !0));
|
console.log(!0);
|
||||||
console.log((0 / 0, !0));
|
console.log(!0);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -606,7 +606,131 @@ delete_seq_6: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
var a;
|
||||||
console.log((a, !0));
|
console.log(!0);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
0, a(), 1, b(), 2, c(), 3;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a(), b(), c();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_cascade_1: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
a -= 42;
|
||||||
|
if (a < 0) a = 0;
|
||||||
|
b.a = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
(a -= 42) < 0 && (a = 0), b.a = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_cascade_2: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
b = a,
|
||||||
|
!a + (b += a) || (b += a),
|
||||||
|
b = a,
|
||||||
|
b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
b = a,
|
||||||
|
!a + (b += a) || (b += a),
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_cascade_3: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
conditionals: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a, b) {
|
||||||
|
"foo" ^ (b += a),
|
||||||
|
b ? false : (b = a) ? -1 : (b -= a) - (b ^= a),
|
||||||
|
a-- || !a,
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a, b) {
|
||||||
|
!(b += a) && ((b = a) || (b -= a, b ^= a)),
|
||||||
|
--a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_27: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
passes: 2,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(jQuery) {
|
||||||
|
var $;
|
||||||
|
$ = jQuery;
|
||||||
|
$("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(jQuery) {
|
||||||
|
jQuery("body").addClass("foo");
|
||||||
|
})(jQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reassign_const: {
|
||||||
|
options = {
|
||||||
|
cascade: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
a++;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
const a = 1;
|
||||||
|
return a++, a;
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
9
test/compress/super.js
Normal file
9
test/compress/super.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
super_can_be_parsed: {
|
||||||
|
input: {
|
||||||
|
super(1,2);
|
||||||
|
super.meth();
|
||||||
|
}
|
||||||
|
expect_exact: "super(1,2);super.meth();"
|
||||||
|
}
|
||||||
|
|
||||||
402
test/compress/template-string.js
Normal file
402
test/compress/template-string.js
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
template_strings: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
``;
|
||||||
|
`xx\`x`;
|
||||||
|
`${ foo + 2 }`;
|
||||||
|
` foo ${ bar + `baz ${ qux }` }`;
|
||||||
|
}
|
||||||
|
expect_exact: "``;`xx\\`x`;`${foo+2}`;` foo ${bar+`baz ${qux}`}`;";
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_prefixes: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
String.raw`foo`;
|
||||||
|
foo `bar`;
|
||||||
|
}
|
||||||
|
expect_exact: "String.raw`foo`;foo`bar`;";
|
||||||
|
}
|
||||||
|
|
||||||
|
template_strings_ascii_only: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true,
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `foo
|
||||||
|
bar
|
||||||
|
ↂωↂ`;
|
||||||
|
var bar = `\``;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=`foo\\n bar\\n \\u2182\\u03c9\\u2182`;var bar=`\\``;"
|
||||||
|
}
|
||||||
|
|
||||||
|
template_strings_without_ascii_only: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `foo
|
||||||
|
bar
|
||||||
|
ↂωↂ`
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=`foo\\n bar\\n ↂωↂ`;"
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_with_constant_expression: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `${4 + 4} equals 4 + 4`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `8 equals 4 + 4`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_with_predefined_constants: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `This is ${undefined}`;
|
||||||
|
var bar = `This is ${NaN}`;
|
||||||
|
var baz = `This is ${null}`;
|
||||||
|
var foofoo = `This is ${Infinity}`;
|
||||||
|
var foobar = "This is ${1/0}";
|
||||||
|
var foobaz = 'This is ${1/0}';
|
||||||
|
var barfoo = "This is ${NaN}";
|
||||||
|
var bazfoo = "This is ${null}";
|
||||||
|
var bazbaz = `This is ${1/0}`;
|
||||||
|
var barbar = `This is ${0/0}`;
|
||||||
|
var barbar = "This is ${0/0}";
|
||||||
|
var barber = 'This is ${0/0}';
|
||||||
|
|
||||||
|
var a = `${4**11}`; // 8 in template vs 7 chars - 4194304
|
||||||
|
var b = `${4**12}`; // 8 in template vs 8 chars - 16777216
|
||||||
|
var c = `${4**14}`; // 8 in template vs 9 chars - 268435456
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `This is undefined`;
|
||||||
|
var bar = `This is NaN`;
|
||||||
|
var baz = `This is null`;
|
||||||
|
var foofoo = `This is ${1/0}`;
|
||||||
|
var foobar = "This is ${1/0}";
|
||||||
|
var foobaz = 'This is ${1/0}';
|
||||||
|
var barfoo = "This is ${NaN}";
|
||||||
|
var bazfoo = "This is ${null}";
|
||||||
|
var bazbaz = `This is ${1/0}`;
|
||||||
|
var barbar = `This is NaN`;
|
||||||
|
var barbar = "This is ${0/0}";
|
||||||
|
var barber = 'This is ${0/0}';
|
||||||
|
|
||||||
|
var a = `4194304`;
|
||||||
|
var b = `16777216`; // Potential for further concatentation
|
||||||
|
var c = `${4**14}`; // Not worth converting
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_evaluate_with_many_segments: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello ${guest()}, welcome to ${location()}${"."}`;
|
||||||
|
var bar = `${1}${2}${3}${4}${5}${6}${7}${8}${9}${0}`;
|
||||||
|
var baz = `${foobar()}${foobar()}${foobar()}${foobar()}`;
|
||||||
|
var buzz = `${1}${foobar()}${2}${foobar()}${3}${foobar()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello ${guest()}, welcome to ${location()}.`;
|
||||||
|
var bar = `1234567890`;
|
||||||
|
var baz = `${foobar()}${foobar()}${foobar()}${foobar()}`;
|
||||||
|
var buzz = `1${foobar()}2${foobar()}3${foobar()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_with_many_segments: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello ${guest()}, welcome to ${location()}${"."}`;
|
||||||
|
var bar = `${1}${2}${3}${4}${5}${6}${7}${8}${9}${0}`;
|
||||||
|
var baz = `${foobar()}${foobar()}${foobar()}${foobar()}`;
|
||||||
|
var buzz = `${1}${foobar()}${2}${foobar()}${3}${foobar()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello ${guest()}, welcome to ${location()}${"."}`;
|
||||||
|
var bar = `${1}${2}${3}${4}${5}${6}${7}${8}${9}${0}`;
|
||||||
|
var baz = `${foobar()}${foobar()}${foobar()}${foobar()}`;
|
||||||
|
var buzz = `${1}${foobar()}${2}${foobar()}${3}${foobar()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template_string_to_normal_string: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 0
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `This is ${undefined}`;
|
||||||
|
var bar = "Decimals " + `${1}${2}${3}${4}${5}${6}${7}${8}${9}${0}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `This is undefined`;
|
||||||
|
var bar = "Decimals 1234567890";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template_concattenating_string: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 3 // Yes, keep quotes
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = "Have a nice " + `day. ${`day. ` + `day.`}`;
|
||||||
|
var bar = "Have a nice " + `${day()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = "Have a nice day. day. day.";
|
||||||
|
var bar = "Have a nice " + `${day()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate_nested_templates: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
quote_style: 0
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var baz = `${`${`${`foo`}`}`}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var baz = `foo`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enforce_double_quotes: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 1
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${'world'}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${"world"}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enforce_single_quotes: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 2
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${"world"}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${'world'}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enforce_double_quotes_and_evaluate: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 1
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${'world'}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello world`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enforce_single_quotes_and_evaluate: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 2
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello ${"world"}`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = `Hello world`;
|
||||||
|
var bar = `Hello world`;
|
||||||
|
var baz = `Hello ${world()}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
respect_inline_script: {
|
||||||
|
beautify = {
|
||||||
|
inline_script: true,
|
||||||
|
quote_style: 3
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = `</script>${content}`;
|
||||||
|
var bar = `<!--`;
|
||||||
|
var baz = `-->`;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=`<\\/script>${content}`;var bar=`\\x3c!--`;var baz=`--\\x3e`;";
|
||||||
|
}
|
||||||
|
|
||||||
|
do_not_optimize_tagged_template_1: {
|
||||||
|
beautify = {
|
||||||
|
quote_style: 0
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = tag`Shall not be optimized. ${"But " + "this " + "is " + "fine."}`;
|
||||||
|
var bar = tag`Don't even mind changing my quotes!`;
|
||||||
|
}
|
||||||
|
expect_exact:
|
||||||
|
'var foo=tag`Shall not be optimized. ${"But this is fine."}`;var bar=tag`Don\'t even mind changing my quotes!`;';
|
||||||
|
}
|
||||||
|
|
||||||
|
do_not_optimize_tagged_template_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = tag`test` + " something out";
|
||||||
|
}
|
||||||
|
expect_exact: 'var foo=tag`test`+" something out";';
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_raw_content_in_tagged_template: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var foo = tag`\u0020\u{20}\u{00020}\x20\40\040 `;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=tag`\\u0020\\u{20}\\u{00020}\\x20\\40\\040 `;";
|
||||||
|
}
|
||||||
|
|
||||||
|
allow_chained_templates: {
|
||||||
|
input: {
|
||||||
|
var foo = tag`a``b``c``d`;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var foo = tag`a``b``c``d`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
check_escaped_chars: {
|
||||||
|
input: {
|
||||||
|
var foo = `\u0020\u{20}\u{00020}\x20\40\040 `;
|
||||||
|
}
|
||||||
|
expect_exact: "var foo=` `;";
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_dollar_curly: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\$\{ beep \}`)
|
||||||
|
console.log(`${1-0}\${2-0}$\{3-0}${4-0}`)
|
||||||
|
console.log(`$${""}{not an expression}`)
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(`\\${ beep }`);console.log(`1\\${2-0}\\${3-0}4`);console.log(`\\${not an expression}`);"
|
||||||
|
}
|
||||||
|
|
||||||
|
template_starting_with_newline: {
|
||||||
|
options = {
|
||||||
|
dead_code: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(e) {
|
||||||
|
return `
|
||||||
|
this is a template string!`;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "function foo(e){return`\\nthis is a template string!`}"
|
||||||
|
}
|
||||||
|
|
||||||
|
template_with_newline: {
|
||||||
|
options = {
|
||||||
|
dead_code: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(e) {
|
||||||
|
return `yep,
|
||||||
|
this is a template string!`;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "function foo(e){return`yep,\\nthis is a template string!`}"
|
||||||
|
}
|
||||||
|
|
||||||
|
template_ending_with_newline: {
|
||||||
|
options = {
|
||||||
|
dead_code: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(e) {
|
||||||
|
return `this is a template string!
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect_exact: "function foo(e){return`this is a template string!\\n`}"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1856: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\\n\\r\\u2028\\u2029\n\r\u2028\u2029`);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(`\\\\n\\\\r\\\\u2028\\\\u2029\\n\\r\\u2028\\u2029`);"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1856_ascii_only: {
|
||||||
|
beautify = {
|
||||||
|
ascii_only: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`\\n\\r\\u2028\\u2029\n\r\u2028\u2029`);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(`\\\\n\\\\r\\\\u2028\\\\u2029\\n\\r\\u2028\\u2029`);"
|
||||||
|
}
|
||||||
12
test/compress/try-catch.js
Normal file
12
test/compress/try-catch.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
catch_destructuring_with_sequence: {
|
||||||
|
beautify = {
|
||||||
|
ecma: 6
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
throw {};
|
||||||
|
} catch ({xCover = (0, function() {})} ) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "try{throw{}}catch({xCover=(0,function(){})}){}"
|
||||||
|
}
|
||||||
@@ -15,3 +15,106 @@ unicode_parse_variables: {
|
|||||||
var l০ = 3;
|
var l০ = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unicode_escaped_identifier: {
|
||||||
|
beautify = {ecma: 6}
|
||||||
|
input: {
|
||||||
|
var \u{61} = "foo";
|
||||||
|
var \u{10000} = "bar";
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="foo";var \u{10000}="bar";';
|
||||||
|
}
|
||||||
|
|
||||||
|
unicode_identifier_ascii_only: {
|
||||||
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var \u{0061} = "hi";
|
||||||
|
var bar = "h\u{0065}llo";
|
||||||
|
var \u{10000} = "testing \u{101111}";
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="hi";var bar="hello";var \\u{10000}="testing \\u{101111}";'
|
||||||
|
}
|
||||||
|
|
||||||
|
unicode_string_literals: {
|
||||||
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var a = "6 length unicode character: \u{101111}";
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="6 length unicode character: \\u{101111}";'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't escape identifiers below es6 (or in this case double escaped in expect_exact)
|
||||||
|
unicode_output_es5_surrogates: {
|
||||||
|
beautify = {ascii_only: true, ecma: 5}
|
||||||
|
input: {
|
||||||
|
var \u{10000} = "6 length unicode character: \u{10FFFF}";
|
||||||
|
}
|
||||||
|
expect_exact: 'var \u{10000}="6 length unicode character: \\udbff\\udfff";'
|
||||||
|
}
|
||||||
|
|
||||||
|
check_escape_style: {
|
||||||
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var a = "\x01";
|
||||||
|
var \ua0081 = "\x10"; // \u0081 only in ID_Continue
|
||||||
|
var \u0100 = "\u0100";
|
||||||
|
var \u1000 = "\u1000";
|
||||||
|
var \u{10000} = "\u{10000}";
|
||||||
|
var \u{2f800} = "\u{100000}";
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="\\x01";var \\ua0081="\\x10";var \\u0100="\\u0100";var \\u1000="\\u1000";var \\u{10000}="\\u{10000}";var \\u{2f800}="\\u{100000}";'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't escape identifiers below es6, no escaped identifiers support and no \u{} syntax
|
||||||
|
check_escape_style_es5: {
|
||||||
|
beautify = {ascii_only: true, ecma: 5}
|
||||||
|
input: {
|
||||||
|
var a = "\x01";
|
||||||
|
var \ua0081 = "\x10"; // \u0081 only in ID_Continue
|
||||||
|
var \u0100 = "\u0100";
|
||||||
|
var \u1000 = "\u1000";
|
||||||
|
var \u{10000} = "\u{10000}"; // Identifier won't be escaped in es 5.1
|
||||||
|
var \u{2f800} = "\u{100000}"; // Same
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="\\x01";var \\ua0081="\\x10";var \\u0100="\\u0100";var \\u1000="\\u1000";var \ud800\udc00="\\ud800\\udc00";var \ud87e\udc00="\\udbc0\\udc00";'
|
||||||
|
}
|
||||||
|
|
||||||
|
ID_continue_with_surrogate_pair: {
|
||||||
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var \u{2f800}\u{2f800}\u{2f800}\u{2f800} = "\u{100000}\u{100000}\u{100000}\u{100000}\u{100000}";
|
||||||
|
}
|
||||||
|
expect_exact: 'var \\u{2f800}\\u{2f800}\\u{2f800}\\u{2f800}="\\u{100000}\\u{100000}\\u{100000}\\u{100000}\\u{100000}";'
|
||||||
|
}
|
||||||
|
|
||||||
|
escape_non_escaped_identifier: {
|
||||||
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var µþ = "µþ";
|
||||||
|
}
|
||||||
|
expect_exact: 'var \\u00b5\\u00fe="\\xb5\\xfe";'
|
||||||
|
}
|
||||||
|
|
||||||
|
non_escape_2_non_escape: {
|
||||||
|
beautify = {ascii_only: false, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var µþ = "µþ";
|
||||||
|
}
|
||||||
|
expect_exact: 'var µþ="µþ";'
|
||||||
|
}
|
||||||
|
|
||||||
|
non_escape_2_half_escape1: {
|
||||||
|
beautify = {ascii_only: false, ascii_identifiers: true, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var µþ = "µþ";
|
||||||
|
}
|
||||||
|
expect_exact: 'var \\u00b5\\u00fe="µþ";'
|
||||||
|
}
|
||||||
|
|
||||||
|
non_escape_2_half_escape2: {
|
||||||
|
beautify = {ascii_only: true, ascii_identifiers: false, ecma: 6}
|
||||||
|
input: {
|
||||||
|
var µþ = "µþ";
|
||||||
|
}
|
||||||
|
expect_exact: 'var µþ="\\xb5\\xfe";'
|
||||||
|
}
|
||||||
192
test/compress/yield.js
Normal file
192
test/compress/yield.js
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
generators: {
|
||||||
|
input: {
|
||||||
|
function* fn() {};
|
||||||
|
}
|
||||||
|
expect_exact: "function*fn(){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
generators_yield: {
|
||||||
|
input: {
|
||||||
|
function* fn() {
|
||||||
|
yield remote();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*fn(){yield remote()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
generators_yield_assign: {
|
||||||
|
input: {
|
||||||
|
function* fn() {
|
||||||
|
var x = {};
|
||||||
|
x.prop = yield 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*fn(){var x={};x.prop=yield 5}"
|
||||||
|
}
|
||||||
|
|
||||||
|
generator_yield_undefined: {
|
||||||
|
input: {
|
||||||
|
function* fn() {
|
||||||
|
yield;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*fn(){yield}"
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_optimize_expression: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function* f1() { yield; }
|
||||||
|
function* f2() { yield undefined; }
|
||||||
|
function* f3() { yield null; }
|
||||||
|
function* f4() { yield* undefined; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function* f1() { yield }
|
||||||
|
function* f2() { yield; }
|
||||||
|
function* f3() { yield null; }
|
||||||
|
function* f4() { yield* void 0; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_statements: {
|
||||||
|
input: {
|
||||||
|
function* fn() {
|
||||||
|
var a = (yield 1) + (yield 2);
|
||||||
|
var b = (yield 3) === (yield 4);
|
||||||
|
var c = (yield 5) << (yield 6);
|
||||||
|
var d = yield 7;
|
||||||
|
var e = (yield 8) ? yield 9 : yield 10;
|
||||||
|
var f = -(yield 11);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*fn(){var a=(yield 1)+(yield 2);var b=(yield 3)===(yield 4);var c=(yield 5)<<(yield 6);var d=yield 7;var e=(yield 8)?yield 9:yield 10;var f=-(yield 11)}"
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_as_identifier_in_function_in_generator: {
|
||||||
|
input: {
|
||||||
|
var g = function*() {
|
||||||
|
function h() {
|
||||||
|
yield = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var g = function*() {
|
||||||
|
function h() {
|
||||||
|
yield = 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_before_punctuators: {
|
||||||
|
input: {
|
||||||
|
iter = (function*() {
|
||||||
|
assignmentResult = [ x = yield ] = value;
|
||||||
|
})();
|
||||||
|
function* g1() { (yield) }
|
||||||
|
function* g2() { [yield] }
|
||||||
|
function* g3() { return {yield} } // Added return to avoid {} drop
|
||||||
|
function* g4() { yield, yield; }
|
||||||
|
function* g5() { (yield) ? yield : yield; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
iter = (function*() {
|
||||||
|
assignmentResult = [ x = yield ] = value;
|
||||||
|
})();
|
||||||
|
function* g1() { (yield) }
|
||||||
|
function* g2() { [yield] }
|
||||||
|
function* g3() { return {yield} }
|
||||||
|
function* g4() { yield, yield; }
|
||||||
|
function* g5() { (yield) ? yield : yield; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_as_identifier_outside_strict_mode: {
|
||||||
|
input: {
|
||||||
|
import yield from "bar";
|
||||||
|
yield = 123;
|
||||||
|
while (true) {
|
||||||
|
yield:
|
||||||
|
for(;;) break yield;
|
||||||
|
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
while (true)
|
||||||
|
yield: for(;;) continue yield;
|
||||||
|
function yield(){}
|
||||||
|
function foo(...yield){}
|
||||||
|
try { new Error("") } catch (yield) {}
|
||||||
|
var yield = "foo";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import yield from "bar";
|
||||||
|
yield = 123;
|
||||||
|
while (true) {
|
||||||
|
yield:
|
||||||
|
for(;;) break yield;
|
||||||
|
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
while (true)
|
||||||
|
yield: for(;;) continue yield;
|
||||||
|
function yield(){}
|
||||||
|
function foo(...yield){}
|
||||||
|
try { new Error("") } catch (yield) {}
|
||||||
|
var yield = "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
empty_generator_as_parameter_with_side_effects: {
|
||||||
|
options = {
|
||||||
|
side_effects: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var GeneratorPrototype = Object.getPrototypeOf(
|
||||||
|
Object.getPrototypeOf(function*() {}())
|
||||||
|
);
|
||||||
|
evaluate(GeneratorPrototype);
|
||||||
|
}
|
||||||
|
expect_exact: "var GeneratorPrototype=Object.getPrototypeOf(Object.getPrototypeOf(function*(){}()));evaluate(GeneratorPrototype);"
|
||||||
|
}
|
||||||
|
|
||||||
|
empty_generator_as_parameter_without_side_effects: {
|
||||||
|
options = {
|
||||||
|
side_effects: false
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var GeneratorPrototype = Object.getPrototypeOf(
|
||||||
|
Object.getPrototypeOf(function*() {}())
|
||||||
|
);
|
||||||
|
evaluate(GeneratorPrototype);
|
||||||
|
}
|
||||||
|
expect_exact: "var GeneratorPrototype=Object.getPrototypeOf(Object.getPrototypeOf(function*(){}()));evaluate(GeneratorPrototype);"
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_dot: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function* foo(){
|
||||||
|
yield x.foo;
|
||||||
|
(yield x).foo;
|
||||||
|
yield (yield obj.foo()).bar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: "function*foo(){yield x.foo;(yield x).foo;yield(yield obj.foo()).bar()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
yield_sub: {
|
||||||
|
options = {
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function* foo(){
|
||||||
|
yield x['foo'];
|
||||||
|
(yield x)['foo'];
|
||||||
|
yield (yield obj.foo())['bar']();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'function*foo(){yield x["foo"];(yield x)["foo"];yield(yield obj.foo())["bar"]()}'
|
||||||
|
}
|
||||||
13
test/exports.js
Normal file
13
test/exports.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
exports["Compressor"] = Compressor;
|
||||||
|
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||||
|
exports["OutputStream"] = OutputStream;
|
||||||
|
exports["SourceMap"] = SourceMap;
|
||||||
|
exports["TreeWalker"] = TreeWalker;
|
||||||
|
exports["base54"] = base54;
|
||||||
|
exports["defaults"] = defaults;
|
||||||
|
exports["mangle_properties"] = mangle_properties;
|
||||||
|
exports["minify"] = minify;
|
||||||
|
exports["parse"] = parse;
|
||||||
|
exports["string_template"] = string_template;
|
||||||
|
exports["tokenizer"] = tokenizer;
|
||||||
|
exports["is_identifier"] = is_identifier;
|
||||||
1
test/input/invalid/assign_4.js
Normal file
1
test/input/invalid/assign_4.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
++null
|
||||||
8
test/input/invalid/const.js
Normal file
8
test/input/invalid/const.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
const a;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
"use strict";
|
||||||
|
const a;
|
||||||
|
}
|
||||||
14
test/input/invalid/delete.js
Normal file
14
test/input/invalid/delete.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
function f(x) {
|
||||||
|
delete 42;
|
||||||
|
delete (0, x);
|
||||||
|
delete null;
|
||||||
|
delete x;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g(x) {
|
||||||
|
"use strict";
|
||||||
|
delete 42;
|
||||||
|
delete (0, x);
|
||||||
|
delete null;
|
||||||
|
delete x;
|
||||||
|
}
|
||||||
1
test/input/invalid/dot_1.js
Normal file
1
test/input/invalid/dot_1.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
a.=
|
||||||
1
test/input/invalid/dot_2.js
Normal file
1
test/input/invalid/dot_2.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
%.a;
|
||||||
1
test/input/invalid/dot_3.js
Normal file
1
test/input/invalid/dot_3.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
a./();
|
||||||
1
test/input/invalid/else.js
Normal file
1
test/input/invalid/else.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
if (0) else 1;
|
||||||
6
test/input/invalid/function_1.js
Normal file
6
test/input/invalid/function_1.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
function f(arguments) {
|
||||||
|
}
|
||||||
|
|
||||||
|
function g(arguments) {
|
||||||
|
"use strict";
|
||||||
|
}
|
||||||
6
test/input/invalid/function_2.js
Normal file
6
test/input/invalid/function_2.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
function arguments() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function eval() {
|
||||||
|
"use strict";
|
||||||
|
}
|
||||||
6
test/input/invalid/function_3.js
Normal file
6
test/input/invalid/function_3.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
!function eval() {
|
||||||
|
}();
|
||||||
|
|
||||||
|
!function arguments() {
|
||||||
|
"use strict";
|
||||||
|
}();
|
||||||
1
test/input/invalid/object.js
Normal file
1
test/input/invalid/object.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log({%: 1});
|
||||||
1
test/input/invalid/return.js
Normal file
1
test/input/invalid/return.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
return 42;
|
||||||
8
test/input/invalid/try.js
Normal file
8
test/input/invalid/try.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
try {} catch (eval) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
"use strict";
|
||||||
|
try {} catch (eval) {}
|
||||||
|
}
|
||||||
8
test/input/invalid/var.js
Normal file
8
test/input/invalid/var.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
function f() {
|
||||||
|
var eval;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
"use strict";
|
||||||
|
var eval;
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ if (typeof phantom == "undefined") {
|
|||||||
});
|
});
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc", "warnings=false");
|
args.push("-mc");
|
||||||
}
|
}
|
||||||
args.push("--stats");
|
args.push("--stats");
|
||||||
var child_process = require("child_process");
|
var child_process = require("child_process");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("Accessor tokens", function() {
|
describe("Accessor tokens", function() {
|
||||||
@@ -16,8 +16,8 @@ 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_SymbolMethod);
|
||||||
assert.equal(node.key.start.pos, 16);
|
assert.equal(node.key.start.pos, 12);
|
||||||
assert.equal(node.key.end.endpos, 22);
|
assert.equal(node.key.end.endpos, 22);
|
||||||
|
|
||||||
assert(node.value instanceof UglifyJS.AST_Accessor);
|
assert(node.value instanceof UglifyJS.AST_Accessor);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("arguments", function() {
|
describe("arguments", function() {
|
||||||
@@ -27,4 +27,253 @@ describe("arguments", function() {
|
|||||||
assert.strictEqual(ast.body[0].body[0].uses_arguments, true);
|
assert.strictEqual(ast.body[0].body[0].uses_arguments, true);
|
||||||
assert.strictEqual(ast.body[0].body[0].body[0].uses_arguments, false);
|
assert.strictEqual(ast.body[0].body[0].body[0].uses_arguments, false);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
it("Should parse a function containing default assignment correctly", function() {
|
||||||
|
var ast = UglifyJS.parse("function foo(a = 123) {}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo(a = a) {}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].right instanceof UglifyJS.AST_SymbolRef);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse a function containing default assignments in destructuring correctly", function() {
|
||||||
|
var ast = UglifyJS.parse("function foo([a = 123]) {}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo({a = 123}) {}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].key, "a");
|
||||||
|
|
||||||
|
// Property a of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo({a: a = 123}) {}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 1);
|
||||||
|
|
||||||
|
// Content destructuring of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
|
||||||
|
// Property a of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.right instanceof UglifyJS.AST_Number);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse a function containing default assignments in complex destructuring correctly", function() {
|
||||||
|
var ast = UglifyJS.parse("function foo([a, [b = 123]]){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[1] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].is_array, true);
|
||||||
|
|
||||||
|
// Check content of second destructuring element (which is the nested destructuring pattern)
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0] instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].names[0].operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo([a, {b: c = 123}]){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[1] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].is_array, false);
|
||||||
|
|
||||||
|
// Check content of second destructuring element (which is the nested destructuring pattern)
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].names[0].key, "b");
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
|
||||||
|
// Property b of second argument
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].value.left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].argnames[0].names[1].names[0].value.right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo({a, b: {b = 123}}){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[1] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[1].key, "b");
|
||||||
|
assert(ast.body[0].argnames[0].names[1].value instanceof UglifyJS.AST_Destructuring);
|
||||||
|
|
||||||
|
// Check content of nested destructuring in first parameter
|
||||||
|
var content = ast.body[0].argnames[0].names[1].value
|
||||||
|
assert.strictEqual(content.is_array, false);
|
||||||
|
assert.strictEqual(content.names.length, 1);
|
||||||
|
assert(content.names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(content.names[0].key, "b");
|
||||||
|
assert(content.names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(content.names[0].value.left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(content.names[0].value.operator, "=");
|
||||||
|
assert(content.names[0].value.right instanceof UglifyJS.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo({a: {b = 123}}){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 1);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_Destructuring);
|
||||||
|
|
||||||
|
// Check content of nested destructuring
|
||||||
|
content = ast.body[0].argnames[0].names[0].value
|
||||||
|
assert.strictEqual(content.is_array, false);
|
||||||
|
assert.strictEqual(content.names.length, 1);
|
||||||
|
assert(content.names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(content.names[0].key, "b");
|
||||||
|
assert(content.names[0].value instanceof UglifyJS.AST_DefaultAssign);
|
||||||
|
assert(content.names[0].value.left instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(content.names[0].value.operator, "=");
|
||||||
|
assert(content.names[0].value.right instanceof UglifyJS.AST_Number);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse spread correctly", function() {
|
||||||
|
var ast = UglifyJS.parse("function foo(a, b, ...c){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 3);
|
||||||
|
|
||||||
|
// Check parameters
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[1] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[2] instanceof UglifyJS.AST_Expansion);
|
||||||
|
assert(ast.body[0].argnames[2].expression instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo([a, b, ...c]){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, true);
|
||||||
|
|
||||||
|
// Check content first parameter
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[1] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[2] instanceof UglifyJS.AST_Expansion);
|
||||||
|
assert(ast.body[0].argnames[0].names[2].expression instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo([a, b, [c, ...d]]){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, true);
|
||||||
|
|
||||||
|
// Check content outer destructuring array
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[1] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[2] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[2].is_array, true);
|
||||||
|
|
||||||
|
// Check content nested destructuring array
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[2].names.length, 2);
|
||||||
|
assert(ast.body[0].argnames[0].names[2].names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[2].names[1] instanceof UglifyJS.AST_Expansion);
|
||||||
|
assert(ast.body[0].argnames[0].names[2].names[1].expression instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = UglifyJS.parse("function foo({a: [b, ...c]}){}");
|
||||||
|
assert(ast.body[0] instanceof UglifyJS.AST_Defun);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].argnames[0] instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].is_array, false);
|
||||||
|
|
||||||
|
// Check outer destructuring object
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].argnames[0].names[0] instanceof UglifyJS.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value instanceof UglifyJS.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].value.is_array, true);
|
||||||
|
|
||||||
|
// Check content nested destructuring array
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].names[0].value.names.length, 2);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.names[0] instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.names[1] instanceof UglifyJS.AST_Expansion);
|
||||||
|
assert(ast.body[0].argnames[0].names[0].value.names[1].expression instanceof UglifyJS.AST_SymbolFunarg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
402
test/mocha/arrow.js
Normal file
402
test/mocha/arrow.js
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("Arrow functions", function() {
|
||||||
|
it("Should not accept spread tokens on non-last parameters or without arguments parentheses", function() {
|
||||||
|
var tests = [
|
||||||
|
"var a = ...a => {return a.join()}",
|
||||||
|
"var b = (a, ...b, c) => { return a + b.join() + c}",
|
||||||
|
"var c = (...a, b) => a.join()"
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
e.message === "Unexpected token: expand (...)";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should not accept holes in object binding patterns, while still allowing a trailing elision", function() {
|
||||||
|
var tests = [
|
||||||
|
"f = ({, , ...x} = [1, 2]) => {};"
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
e.message === "Unexpected token: punc (,)";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should not accept newlines before arrow token", function() {
|
||||||
|
var tests = [
|
||||||
|
"f = foo\n=> 'foo';",
|
||||||
|
"f = (foo, bar)\n=> 'foo';",
|
||||||
|
"f = ()\n=> 'foo';",
|
||||||
|
"foo((bar)\n=>'baz';);"
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
e.message === "Unexpected newline before arrow (=>)";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should not accept arrow functions in the middle or end of an expression", function() {
|
||||||
|
var tests = [
|
||||||
|
"typeof x => 0",
|
||||||
|
"0 + x => 0"
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
e.message === "Unexpected token: arrow (=>)";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse a function containing default assignment correctly", function() {
|
||||||
|
var ast = uglify.parse("var a = (a = 123) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = (a = a) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].right instanceof uglify.AST_SymbolRef);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse a function containing default assignments in destructuring correctly", function() {
|
||||||
|
var ast = uglify.parse("var a = ([a = 123]) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ({a = 123}) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
|
||||||
|
// First object element in first argument
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ({a: a = 123}) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// First argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 1);
|
||||||
|
|
||||||
|
// Content destructuring of first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_ObjectProperty);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.right instanceof uglify.AST_Number);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse a function containing default assignments in complex destructuring correctly", function() {
|
||||||
|
var ast = uglify.parse("var a = ([a, [b = 123]]) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].is_array, true);
|
||||||
|
|
||||||
|
// Check content of second destructuring element (which is the nested destructuring pattern)
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0] instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ([a, {b: c = 123}]) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, true);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].is_array, false);
|
||||||
|
|
||||||
|
// Check content of second destructuring element (which is the nested destructuring pattern)
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].key, "b");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].value instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].value.left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].value.operator, "=");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].names[0].value.right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ({a, b: {b = 123}}) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 2);
|
||||||
|
|
||||||
|
// First argument, property 1
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value instanceof uglify.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
// First argument, property 2
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[1].key, "b");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1].value instanceof uglify.AST_Destructuring);
|
||||||
|
|
||||||
|
// Check content of nested destructuring
|
||||||
|
var content = ast.body[0].definitions[0].value.argnames[0].names[1].value
|
||||||
|
assert.strictEqual(content.is_array, false);
|
||||||
|
assert.strictEqual(content.names.length, 1);
|
||||||
|
assert(content.names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
|
||||||
|
// Content of first property in nested destructuring
|
||||||
|
assert.strictEqual(content.names[0].key, "b");
|
||||||
|
assert(content.names[0].value instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(content.names[0].value.left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(content.names[0].value.operator, "=");
|
||||||
|
assert(content.names[0].value.right instanceof uglify.AST_Number);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ({a: {b = 123}}) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, false);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 1);
|
||||||
|
|
||||||
|
// Check whole destructuring structure of first argument
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value instanceof uglify.AST_Destructuring);
|
||||||
|
|
||||||
|
// Check content of nested destructuring
|
||||||
|
content = ast.body[0].definitions[0].value.argnames[0].names[0].value
|
||||||
|
assert.strictEqual(content.is_array, false);
|
||||||
|
assert.strictEqual(content.names.length, 1);
|
||||||
|
assert(content.names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
|
||||||
|
// Check first property of nested destructuring
|
||||||
|
assert.strictEqual(content.names[0].key, "b");
|
||||||
|
assert(content.names[0].value instanceof uglify.AST_DefaultAssign);
|
||||||
|
assert(content.names[0].value.left instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert.strictEqual(content.names[0].value.operator, "=");
|
||||||
|
assert(content.names[0].value.right instanceof uglify.AST_Number);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should parse spread correctly", function() {
|
||||||
|
var ast = uglify.parse("var a = (a, b, ...c) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 3);
|
||||||
|
|
||||||
|
// Check parameters
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[1] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[2] instanceof uglify.AST_Expansion);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[2].expression instanceof uglify.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ([a, b, ...c]) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, true);
|
||||||
|
|
||||||
|
// Check content first parameter
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2] instanceof uglify.AST_Expansion);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2].expression instanceof uglify.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ([a, b, [c, ...d]]) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, true);
|
||||||
|
|
||||||
|
// Check content outer destructuring array
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[1] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[2].is_array, true);
|
||||||
|
|
||||||
|
// Check content nested destructuring array
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[2].names.length, 2);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2].names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2].names[1] instanceof uglify.AST_Expansion);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[2].names[1].expression instanceof uglify.AST_SymbolFunarg);
|
||||||
|
|
||||||
|
|
||||||
|
ast = uglify.parse("var a = ({a: [b, ...c]}) => {}");
|
||||||
|
assert(ast.body[0] instanceof uglify.AST_Var);
|
||||||
|
assert.strictEqual(ast.body[0].definitions.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0] instanceof uglify.AST_VarDef);
|
||||||
|
assert(ast.body[0].definitions[0].name instanceof uglify.AST_SymbolVar);
|
||||||
|
assert(ast.body[0].definitions[0].value instanceof uglify.AST_Arrow);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames.length, 1);
|
||||||
|
|
||||||
|
// Check first parameter
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0] instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].is_array, false);
|
||||||
|
|
||||||
|
// Check outer destructuring object
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names.length, 1);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0] instanceof uglify.AST_ObjectKeyVal);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].key, "a");
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value instanceof uglify.AST_Destructuring);
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].value.is_array, true);
|
||||||
|
|
||||||
|
// Check content nested destructuring array
|
||||||
|
assert.strictEqual(ast.body[0].definitions[0].value.argnames[0].names[0].value.names.length, 2);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.names[0] instanceof uglify.AST_SymbolFunarg);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.names[1] instanceof uglify.AST_Expansion);
|
||||||
|
assert(ast.body[0].definitions[0].value.argnames[0].names[0].value.names[1].expression instanceof uglify.AST_SymbolFunarg);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should handle arrow function with bind", function() {
|
||||||
|
function minify(code) {
|
||||||
|
return uglify.minify(code, {
|
||||||
|
mangle: false
|
||||||
|
}).code;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.strictEqual(
|
||||||
|
minify(minify("test(((index) => { console.log(this, index); }).bind(this, 1));")),
|
||||||
|
"test((index=>{console.log(this,index)}).bind(this,1));"
|
||||||
|
);
|
||||||
|
assert.strictEqual(
|
||||||
|
minify(minify('test(((index) => { console.log(this, index); })["bind"](this, 1));')),
|
||||||
|
"test((index=>{console.log(this,index)}).bind(this,1));"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
34
test/mocha/builtins.js
Normal file
34
test/mocha/builtins.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
var UglifyJS = require("../../");
|
||||||
|
var assert = require("assert");
|
||||||
|
|
||||||
|
describe("builtins", function() {
|
||||||
|
it ("Should not mangle builtins", function() {
|
||||||
|
var test = "function foo(something){\n" +
|
||||||
|
" return [Object,Array,Function,Number,String,Boolean,Error,Math,Date,RegExp,Symbol,Map,Promise,Proxy,Reflect,Set,WeakMap,WeakSet,Float32Array,something];\n" +
|
||||||
|
"};";
|
||||||
|
|
||||||
|
var result = UglifyJS.minify(test, {parse: {bare_returns: true}}).code;
|
||||||
|
|
||||||
|
assert.strictEqual(result.indexOf("something"), -1);
|
||||||
|
|
||||||
|
assert.notEqual(result.indexOf("Object"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Array"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Function"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Number"), -1);
|
||||||
|
assert.notEqual(result.indexOf("String"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Boolean"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Error"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Math"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Date"), -1);
|
||||||
|
assert.notEqual(result.indexOf("RegExp"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Symbol"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Promise"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Proxy"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Reflect"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Set"), -1);
|
||||||
|
assert.notEqual(result.indexOf("WeakMap"), -1);
|
||||||
|
assert.notEqual(result.indexOf("WeakSet"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Map"), -1);
|
||||||
|
assert.notEqual(result.indexOf("Float32Array"), -1);
|
||||||
|
});
|
||||||
|
});
|
||||||
57
test/mocha/class.js
Normal file
57
test/mocha/class.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("Class", function() {
|
||||||
|
it("Should not accept spread on non-last parameters in methods", function() {
|
||||||
|
var tests = [
|
||||||
|
"class foo { bar(...a, b) { return a.join(b) } }",
|
||||||
|
"class foo { bar(a, b, ...c, d) { return c.join(a + b) + d } }",
|
||||||
|
"class foo { *bar(...a, b) { return a.join(b) } }",
|
||||||
|
"class foo { *bar(a, b, ...c, d) { return c.join(a + b) + d } }"
|
||||||
|
];
|
||||||
|
var test = function(code) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
/^Unexpected token: /.test(e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(test(tests[i]), error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should return the correct token for class methods", function() {
|
||||||
|
var tests = [
|
||||||
|
{
|
||||||
|
code: "class foo{static test(){}}",
|
||||||
|
token_value_start: "static",
|
||||||
|
token_value_end: "}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "class bar{*procedural(){}}",
|
||||||
|
token_value_start: "*",
|
||||||
|
token_value_end: "}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "class foobar{aMethod(){}}",
|
||||||
|
token_value_start: "aMethod",
|
||||||
|
token_value_end: "}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: "class foobaz{get something(){}}",
|
||||||
|
token_value_start: "get",
|
||||||
|
token_value_end: "}"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
var ast = uglify.parse(tests[i].code);
|
||||||
|
assert.strictEqual(ast.body[0].properties[0].start.value, tests[i].token_value_start);
|
||||||
|
assert.strictEqual(ast.body[0].properties[0].end.value, tests[i].token_value_end);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -2,6 +2,10 @@ var assert = require("assert");
|
|||||||
var exec = require("child_process").exec;
|
var exec = require("child_process").exec;
|
||||||
var readFileSync = require("fs").readFileSync;
|
var readFileSync = require("fs").readFileSync;
|
||||||
|
|
||||||
|
function read(path) {
|
||||||
|
return readFileSync(path, "utf8");
|
||||||
|
}
|
||||||
|
|
||||||
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) {
|
||||||
@@ -15,12 +19,12 @@ describe("bin/uglifyjs", function () {
|
|||||||
eval(stdout);
|
eval(stdout);
|
||||||
|
|
||||||
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
assert.strictEqual(typeof WrappedUglifyJS, 'object');
|
||||||
assert.strictEqual(true, WrappedUglifyJS.parse('foo;') instanceof WrappedUglifyJS.AST_Node);
|
assert.strictEqual(WrappedUglifyJS.minify("foo([true,,2+3]);").code, "foo([!0,,5]);");
|
||||||
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should be able to filter comments correctly with `--comment all`", function (done) {
|
it("Should be able to filter comments correctly with `--comments all`", function (done) {
|
||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
@@ -50,18 +54,18 @@ describe("bin/uglifyjs", function () {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should append source map to output when using --source-map-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-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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should not append source map to output when not using --source-map-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';
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
@@ -72,130 +76,134 @@ describe("bin/uglifyjs", function () {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
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) {
|
|
||||||
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");
|
|
||||||
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';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
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");
|
|
||||||
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';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
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");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("Should work with --define (simple)", function (done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(5);\n");
|
|
||||||
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';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, "console.log(3,5);\n");
|
|
||||||
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';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, "stdout.println(D);\n");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("Should work with `--beautify`", function (done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/default.js", "utf8"));
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("Should work with `--beautify bracketize`", function (done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
if (err) throw err;
|
|
||||||
|
|
||||||
assert.strictEqual(stdout, readFileSync("test/input/issue-1482/bracketize.js", "utf8"));
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
it("Should process inline source map", function(done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js -mc toplevel --in-source-map inline --source-map-inline';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
exec(command, function (err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
|
|
||||||
assert.strictEqual(stdout, readFileSync("test/input/issue-520/output.js", "utf8"));
|
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();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
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';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
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");
|
||||||
|
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';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
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");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with --define (simple)", function (done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/global_defs/simple.js --define D=5 -c';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, "console.log(5);\n");
|
||||||
|
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';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, "console.log(3,5);\n");
|
||||||
|
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';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, "stdout.println(D);\n");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with `--beautify`", function (done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, read("test/input/issue-1482/default.js"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should work with `--beautify bracketize`", function (done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/issue-1482/input.js -b bracketize';
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, read("test/input/issue-1482/bracketize.js"));
|
||||||
|
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";
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, read("test/input/issue-520/output.js"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should warn for missing inline source map", function(done) {
|
it("Should warn for missing inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-1323/sample.js --in-source-map inline';
|
var command = uglifyjscmd + " test/input/issue-1323/sample.js --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
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}();",
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxHQUFJQSxLQUFNLFdBQ04sUUFBU0MsS0FBS0QsS0FDVixNQUFPQSxLQUdYLE1BQU9DIn0=",
|
||||||
|
"",
|
||||||
|
].join("\n"));
|
||||||
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
assert.strictEqual(stderr, "WARN: inline source map not found\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with multiple input and inline source map", function(done) {
|
it("Should fail with multiple input and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js test/input/issue-520/output.js --in-source-map inline --source-map-inline';
|
var command = uglifyjscmd + " test/input/issue-520/input.js test/input/issue-520/output.js --source-map content=inline,url=inline";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with singular input\n");
|
assert.strictEqual(stderr.split(/\n/)[0], "ERROR: inline source map only works with singular input");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with acorn and inline source map", function(done) {
|
it("Should fail with acorn and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --acorn';
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p acorn";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
it("Should fail with SpiderMonkey and inline source map", function(done) {
|
||||||
var command = uglifyjscmd + ' test/input/issue-520/input.js --in-source-map inline --source-map-inline --spidermonkey';
|
var command = uglifyjscmd + " test/input/issue-520/input.js --source-map content=inline,url=inline -p spidermonkey";
|
||||||
|
|
||||||
exec(command, function (err, stdout, stderr) {
|
exec(command, function (err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stderr, "ERROR: Inline source map only works with built-in parser\n");
|
assert.strictEqual(stderr, "ERROR: inline source map only works with built-in parser\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -208,7 +216,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
||||||
assert.strictEqual(lines[1], "function f(a{}");
|
assert.strictEqual(lines[1], "function f(a{}");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token punc «{», expected punc «,»");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token punc «{», expected punc «,»");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -221,7 +229,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
||||||
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
||||||
assert.strictEqual(lines[2], "\t\t \t ^");
|
assert.strictEqual(lines[2], "\t\t \t ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Invalid syntax: 0abc");
|
assert.strictEqual(lines[3], "ERROR: Invalid syntax: 0abc");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -234,7 +242,7 @@ describe("bin/uglifyjs", function () {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
||||||
assert.strictEqual(lines[1], "foo, bar(");
|
assert.strictEqual(lines[1], "foo, bar(");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -247,63 +255,299 @@ describe("bin/uglifyjs", function () {
|
|||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
||||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
||||||
assert.strictEqual(lines[2], " ^");
|
assert.strictEqual(lines[2], " ^");
|
||||||
assert.strictEqual(lines[3], "SyntaxError: Unexpected token: eof (undefined)");
|
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof (undefined)");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should support hyphen as shorthand", function(done) {
|
|
||||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep-fnames=true';
|
|
||||||
|
|
||||||
exec(command, function (err, stdout) {
|
|
||||||
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");
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
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--);",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: 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));",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: 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,18",
|
"Parse error at test/input/invalid/assign_3.js:1,17",
|
||||||
"console.log(3 || ++this);",
|
"console.log(3 || ++this);",
|
||||||
" ^",
|
" ^",
|
||||||
"SyntaxError: Invalid use of ++ operator"
|
"ERROR: Invalid use of ++ operator"
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (++null)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/assign_4.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/assign_4.js:1,0",
|
||||||
|
"++null",
|
||||||
|
"^",
|
||||||
|
"ERROR: Invalid use of ++ operator"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (a.=)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/dot_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/dot_1.js:1,2",
|
||||||
|
"a.=",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: operator (=)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (%.a)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/dot_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/dot_2.js:1,0",
|
||||||
|
"%.a;",
|
||||||
|
"^",
|
||||||
|
"ERROR: Unexpected token: operator (%)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (a./();)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/dot_3.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/dot_3.js:1,2",
|
||||||
|
"a./();",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: operator (/)"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error ({%: 1})", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/object.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/object.js:1,13",
|
||||||
|
"console.log({%: 1});",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: operator (%)"
|
||||||
|
].join("\n"));
|
||||||
|
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) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/delete.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/delete.js:13,11",
|
||||||
|
" delete x;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Calling delete on expression not allowed in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (function g(arguments))", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/function_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/function_1.js:4,11",
|
||||||
|
"function g(arguments) {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected arguments in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (function eval())", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/function_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/function_2.js:4,9",
|
||||||
|
"function eval() {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected eval in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (iife arguments())", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/function_3.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/function_3.js:4,10",
|
||||||
|
"!function arguments() {",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected arguments in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (catch(eval))", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/try.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/try.js:7,18",
|
||||||
|
" try {} catch (eval) {}",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected eval identifier as parameter inside strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (var eval)", function(done) {
|
||||||
|
var command = uglifyjscmd + ' test/input/invalid/var.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/var.js:7,8",
|
||||||
|
" var eval;",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected eval in strict mode"
|
||||||
|
].join("\n"));
|
||||||
|
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 handle literal string as source map input", function(done) {
|
||||||
|
var command = [
|
||||||
|
uglifyjscmd,
|
||||||
|
"test/input/issue-1236/simple.js",
|
||||||
|
"--source-map",
|
||||||
|
'content="' + read_map() + '",url=inline'
|
||||||
|
].join(" ");
|
||||||
|
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
assert.strictEqual(stdout, [
|
||||||
|
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||||
|
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiWUFBQSxJQUFJQSxLQUFNLFFBQU5BLEtBQU1DLEdBQUEsTUFBSyxPQUFTQSxFQUN4QkMsU0FBUUMsSUFBSUgsSUFBSSJ9",
|
||||||
|
""
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
function read_map() {
|
||||||
|
var map = JSON.parse(read("./test/input/issue-1236/simple.js.map"));
|
||||||
|
delete map.sourcesContent;
|
||||||
|
return JSON.stringify(map).replace(/"/g, '\\"');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("Should dump AST as JSON", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/global_defs/simple.js -mco ast";
|
||||||
|
exec(command, function (err, stdout) {
|
||||||
|
if (err) throw err;
|
||||||
|
|
||||||
|
var ast = JSON.parse(stdout);
|
||||||
|
assert.strictEqual(ast._class, "AST_Toplevel");
|
||||||
|
assert.ok(Array.isArray(ast.body));
|
||||||
|
done();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
var UglifyJS = require('../../');
|
var UglifyJS = require("../node");
|
||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
|
|
||||||
describe("comment filters", function() {
|
describe("comment filters", function() {
|
||||||
@@ -75,7 +75,6 @@ describe("comment filters", function() {
|
|||||||
|
|
||||||
it("Should handle shebang and preamble correctly", function() {
|
it("Should handle shebang and preamble correctly", function() {
|
||||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||||
fromString: true,
|
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" }
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
@@ -83,7 +82,6 @@ describe("comment filters", function() {
|
|||||||
|
|
||||||
it("Should handle preamble without shebang correctly", function() {
|
it("Should handle preamble without shebang correctly", function() {
|
||||||
var code = UglifyJS.minify("var x = 10;", {
|
var code = UglifyJS.minify("var x = 10;", {
|
||||||
fromString: true,
|
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" }
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Comment", function() {
|
describe("Comment", function() {
|
||||||
it("Should recognize eol of single line comments", function() {
|
it("Should recognize eol of single line comments", function() {
|
||||||
@@ -20,7 +20,7 @@ describe("Comment", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
uglify.parse(tests[i], {fromString: true})
|
uglify.parse(tests[i]);
|
||||||
}, fail, tests[i]);
|
}, fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -31,7 +31,8 @@ describe("Comment", function() {
|
|||||||
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
|
"/*Some comment 2\r\n\r\n\r\n*/\r\n>\n\n\n\n\n\n",
|
||||||
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
|
"/*Some comment 3\r\r\r*/\r>\n\n\n\n\n\n",
|
||||||
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
|
"/*Some comment 4\u2028\u2028\u2028*/\u2028>\n\n\n\n\n\n",
|
||||||
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n"
|
"/*Some comment 5\u2029\u2029\u2029*/\u2029>\n\n\n\n\n\n",
|
||||||
|
"/*Some comment 6\udbff\udfff\udbff\udfff\n\n\n*/\n>\n\n\n\n\n"
|
||||||
];
|
];
|
||||||
|
|
||||||
var fail = function(e) {
|
var fail = function(e) {
|
||||||
@@ -43,7 +44,7 @@ describe("Comment", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.throws(function() {
|
assert.throws(function() {
|
||||||
uglify.parse(tests[i], {fromString: true})
|
uglify.parse(tests[i]);
|
||||||
}, fail, tests[i]);
|
}, fail, tests[i]);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,9 +6,7 @@ describe("comment before constant", function() {
|
|||||||
|
|
||||||
it("Should test comment before constant is retained and output after mangle.", function() {
|
it("Should test comment before constant is retained and output after mangle.", function() {
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true,
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
mangle: {},
|
|
||||||
output: { comments: true },
|
output: { comments: true },
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
assert.strictEqual(result.code, 'function f(){/*c1*/var/*c2*/n=/*c3*/!1;return n}');
|
||||||
@@ -16,12 +14,9 @@ describe("comment before constant", function() {
|
|||||||
|
|
||||||
it("Should test code works when comments disabled.", function() {
|
it("Should test code works when comments disabled.", function() {
|
||||||
var result = Uglify.minify(js, {
|
var result = Uglify.minify(js, {
|
||||||
fromString: true,
|
|
||||||
compress: { collapse_vars: false, reduce_vars: false },
|
compress: { collapse_vars: false, reduce_vars: false },
|
||||||
mangle: {},
|
|
||||||
output: { comments: false },
|
output: { comments: false },
|
||||||
});
|
});
|
||||||
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
assert.strictEqual(result.code, 'function f(){var n=!1;return n}');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
138
test/mocha/destructuring.js
Normal file
138
test/mocha/destructuring.js
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("Destructuring", function() {
|
||||||
|
it("Should generate similar trees for destructuring in left hand side expressions, definitions, functions and arrow functions", function() {
|
||||||
|
var patterns = [
|
||||||
|
"[]",
|
||||||
|
"{}",
|
||||||
|
|
||||||
|
"[a, b, c]",
|
||||||
|
"{a: b, c: d}",
|
||||||
|
"{a}",
|
||||||
|
"{a, b}",
|
||||||
|
|
||||||
|
"{a: {}}",
|
||||||
|
"{a: []}",
|
||||||
|
"[{}]",
|
||||||
|
"[[]]",
|
||||||
|
"{a: {b}}",
|
||||||
|
|
||||||
|
// Can't do `a = 123` with lhs expression, so only test in destructuring
|
||||||
|
"[foo = bar]",
|
||||||
|
"{a = 123}",
|
||||||
|
"[{foo: abc = 123}]",
|
||||||
|
"{foo: [abc = 123]}",
|
||||||
|
|
||||||
|
"[...foo]",
|
||||||
|
"[...{}]",
|
||||||
|
"[...[]]"
|
||||||
|
|
||||||
|
// Can't do `...` because that is an invalid lhs expression, spread in array destructuring should be fine though
|
||||||
|
];
|
||||||
|
|
||||||
|
var types = [
|
||||||
|
{
|
||||||
|
name: "lhs",
|
||||||
|
symbolType: uglify.AST_SymbolRef,
|
||||||
|
tree: function (ast) {
|
||||||
|
return ast.body[0].body.left;
|
||||||
|
},
|
||||||
|
generate: function (code) {
|
||||||
|
return "(" + code + " = a)";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "var",
|
||||||
|
symbolType: uglify.AST_SymbolVar,
|
||||||
|
tree: function (ast) {
|
||||||
|
return ast.body[0].definitions[0].name;
|
||||||
|
},
|
||||||
|
generate: function (code) {
|
||||||
|
return "var " + code + " = a";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "function",
|
||||||
|
symbolType: uglify.AST_SymbolFunarg,
|
||||||
|
tree: function (ast) {
|
||||||
|
return ast.body[0].argnames[0];
|
||||||
|
},
|
||||||
|
generate: function (code) {
|
||||||
|
return "function a(" + code + ") {}";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "arrow",
|
||||||
|
symbolType: uglify.AST_SymbolFunarg,
|
||||||
|
tree: function (ast) {
|
||||||
|
return ast.body[0].definitions[0].value.argnames[0];
|
||||||
|
},
|
||||||
|
generate: function (code) {
|
||||||
|
return "var a = (" + code + ") => {}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var walker = function(type, ref, code, result) {
|
||||||
|
var w = new uglify.TreeWalker(function(node) {
|
||||||
|
if (w.parent() instanceof uglify.AST_DefaultAssign &&
|
||||||
|
w.parent().right === node
|
||||||
|
) {
|
||||||
|
return true; // Don't check the content of the default assignment
|
||||||
|
|
||||||
|
} else if (node instanceof uglify.AST_Symbol) {
|
||||||
|
assert(node instanceof type.symbolType,
|
||||||
|
node.TYPE + " while " + type.symbolType.TYPE + " expected at pos " +
|
||||||
|
node.start.pos + " in `" + code + "` (" + ref + ")"
|
||||||
|
);
|
||||||
|
|
||||||
|
result.push([
|
||||||
|
new uglify.AST_Symbol({
|
||||||
|
start: node.start,
|
||||||
|
name: node.name,
|
||||||
|
end: node.end
|
||||||
|
}),
|
||||||
|
w.parent()
|
||||||
|
]);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.push([node, w.parent()]);
|
||||||
|
});
|
||||||
|
|
||||||
|
return w;
|
||||||
|
};
|
||||||
|
|
||||||
|
var getNodeType = function(node) {
|
||||||
|
return node[0].TYPE + (node[1] ? " " + node[1].TYPE : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < patterns.length; i++) {
|
||||||
|
var results = [];
|
||||||
|
|
||||||
|
for (var j = 0; j < types.length; j++) {
|
||||||
|
var code = types[j].generate(patterns[i])
|
||||||
|
var ast = types[j].tree(
|
||||||
|
uglify.parse(code)
|
||||||
|
);
|
||||||
|
results.push([]);
|
||||||
|
ast.walk(walker(
|
||||||
|
types[j],
|
||||||
|
"`" + patterns[i] + "` on " + types[j].name,
|
||||||
|
code,
|
||||||
|
results[j]
|
||||||
|
));
|
||||||
|
|
||||||
|
if (j > 0) {
|
||||||
|
assert.deepEqual(
|
||||||
|
results[0].map(getNodeType),
|
||||||
|
results[j].map(getNodeType),
|
||||||
|
"AST disagree on " + patterns[i] + " with " + types[j].name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
var assert = require("assert");
|
var assert = require("assert");
|
||||||
var uglify = require("../../");
|
var uglify = require("../node");
|
||||||
|
|
||||||
describe("Directives", function() {
|
describe("Directives", function() {
|
||||||
it ("Should allow tokenizer to store directives state", function() {
|
it ("Should allow tokenizer to store directives state", function() {
|
||||||
@@ -62,10 +62,10 @@ describe("Directives", function() {
|
|||||||
it("Should know which strings are directive and which ones are not", function() {
|
it("Should know which strings are directive and which ones are not", function() {
|
||||||
var test_directive = function(tokenizer, test) {
|
var test_directive = function(tokenizer, test) {
|
||||||
test.directives.map(function(directive) {
|
test.directives.map(function(directive) {
|
||||||
assert.strictEqual(tokenizer.has_directive(directive), true, directive + " in " + test.input);
|
assert.strictEqual(tokenizer.has_directive(directive), true, "Didn't found directive `" + directive + "` at the end of `" + test.input + '`');
|
||||||
});
|
});
|
||||||
test.non_directives.map(function(fake_directive) {
|
test.non_directives.map(function(fake_directive) {
|
||||||
assert.strictEqual(tokenizer.has_directive(fake_directive), false, fake_directive + " in " + test.input);
|
assert.strictEqual(tokenizer.has_directive(fake_directive), false, "Unexpectedly found directive `" + fake_directive + "` at the end of `" + test.input + '`');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,6 +156,16 @@ describe("Directives", function() {
|
|||||||
input: '"use strict";try{"use asm";',
|
input: '"use strict";try{"use asm";',
|
||||||
directives: ["use strict"],
|
directives: ["use strict"],
|
||||||
non_directives: ["use\nstrict", "use \nstrict", "use asm"]
|
non_directives: ["use\nstrict", "use \nstrict", "use asm"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 'class foo {',
|
||||||
|
directives: ["use strict"],
|
||||||
|
non_directives: ["use\nstrict", "use asm"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 'class foo {}',
|
||||||
|
directives: [],
|
||||||
|
non_directives: ["use strict", "use asm", "use\nstrict"]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -197,7 +207,7 @@ describe("Directives", function() {
|
|||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(
|
uglify.minify(
|
||||||
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
'"use strict";\'use strict\';"use strict";"use strict";;\'use strict\';console.log(\'use strict\');',
|
||||||
{fromString: true, output: {beautify: true, quote_style: 3}, compress: false}
|
{output: {beautify: true, quote_style: 3}, compress: false}
|
||||||
).code,
|
).code,
|
||||||
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
'"use strict";\n\n\'use strict\';\n\n"use strict";\n\n"use strict";\n\n;\'use strict\';\n\nconsole.log(\'use strict\');'
|
||||||
);
|
);
|
||||||
@@ -225,7 +235,7 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, quote_style: 3, compress: false, mangle: false}).code,
|
uglify.minify(tests[i][0], {compress: false, mangle: false}).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
@@ -234,7 +244,7 @@ describe("Directives", function() {
|
|||||||
|
|
||||||
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
it("Should add double semicolon when relying on automatic semicolon insertion", function() {
|
||||||
var code = uglify.minify('"use strict";"use\\x20strict";',
|
var code = uglify.minify('"use strict";"use\\x20strict";',
|
||||||
{fromString: true, output: {semicolons: false}, compress: false}
|
{output: {semicolons: false}, compress: false}
|
||||||
).code;
|
).code;
|
||||||
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
assert.strictEqual(code, '"use strict";;"use strict"\n');
|
||||||
});
|
});
|
||||||
@@ -340,7 +350,7 @@ describe("Directives", function() {
|
|||||||
];
|
];
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, output:{quote_style: tests[i][1]}, compress: false}).code,
|
uglify.minify(tests[i][0], {output:{quote_style: tests[i][1]}, compress: false}).code,
|
||||||
tests[i][2],
|
tests[i][2],
|
||||||
tests[i][0] + " using mode " + tests[i][1]
|
tests[i][0] + " using mode " + tests[i][1]
|
||||||
);
|
);
|
||||||
@@ -351,21 +361,71 @@ describe("Directives", function() {
|
|||||||
var tests = [
|
var tests = [
|
||||||
[
|
[
|
||||||
'"use strict";"use strict";"use strict";"use foo";"use strict";;"use sloppy";doSomething("foo");',
|
'"use strict";"use strict";"use strict";"use foo";"use strict";;"use sloppy";doSomething("foo");',
|
||||||
'"use strict";"use foo";doSomething("foo");'
|
'"use strict";"use foo";doSomething("foo");',
|
||||||
|
'function f(){ "use strict" }',
|
||||||
|
'function f(){ "use asm" }',
|
||||||
|
'function f(){ "use nondirective" }',
|
||||||
|
'function f(){ ;"use strict" }',
|
||||||
|
'function f(){ "use \n"; }',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
// Nothing gets optimised in the compressor because "use asm" is the first statement
|
// Nothing gets optimised in the compressor because "use asm" is the first statement
|
||||||
'"use asm";"use\\x20strict";1+1;',
|
'"use asm";"use\\x20strict";1+1;',
|
||||||
'"use asm";;"use strict";1+1;' // Yet, the parser noticed that "use strict" wasn't a directive
|
'"use asm";;"use strict";1+1;', // Yet, the parser noticed that "use strict" wasn't a directive
|
||||||
|
'function f(){"use strict"}',
|
||||||
|
'function f(){"use asm"}',
|
||||||
|
'function f(){"use nondirective"}',
|
||||||
|
'function f(){}',
|
||||||
|
'function f(){}',
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
for (var i = 0; i < tests.length; i++) {
|
for (var i = 0; i < tests.length; i++) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
uglify.minify(tests[i][0], {fromString: true, compress: {collapse_vars: true, side_effects: true}}).code,
|
uglify.minify(tests[i][0]).code,
|
||||||
tests[i][1],
|
tests[i][1],
|
||||||
tests[i][0]
|
tests[i][0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
it("Should be detect implicit usages of strict mode from tree walker", function() {
|
||||||
|
var tests = [
|
||||||
|
{
|
||||||
|
input: 'class foo {bar(){_check_}}',
|
||||||
|
directives: ["use strict"],
|
||||||
|
non_directives: ["use bar"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: 'class foo {bar(){}}_check_',
|
||||||
|
directives: [],
|
||||||
|
non_directives: ["use strict", "use bar"]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
var checked;
|
||||||
|
var checkWalker = new uglify.TreeWalker(function(node, descend) {
|
||||||
|
if (node instanceof uglify.AST_Symbol && node.name === "_check_") {
|
||||||
|
checked = true;
|
||||||
|
for (var j = 0; j < tests[i].directives.length; j++) {
|
||||||
|
assert.ok(checkWalker.has_directive(tests[i].directives[j]),
|
||||||
|
"Did not found directive '" + tests[i].directives[j] + "' in test " + tests[i].input)
|
||||||
|
}
|
||||||
|
for (var k = 0; k < tests[i].non_directives.length; k++) {
|
||||||
|
assert.equal(checkWalker.has_directive(tests[i].non_directives[k]), undefined,
|
||||||
|
"Found directive '" + tests[i].non_directives[k] + "' in test " + tests[i].input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (; i < tests.length; i++) {
|
||||||
|
// Do tests - iterate the ast in each test - check only when _check_ occurs - fail when no _check_ has been found
|
||||||
|
checked = false;
|
||||||
|
var ast = uglify.parse(tests[i].input);
|
||||||
|
ast.walk(checkWalker);
|
||||||
|
if (!checked) {
|
||||||
|
throw "No _check_ symbol found in " + tests[i].input;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
35
test/mocha/eof.js
Normal file
35
test/mocha/eof.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("EOF", function() {
|
||||||
|
it("Should test code for at least throwing syntax error when incomplete", function() {
|
||||||
|
var error = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error;
|
||||||
|
}
|
||||||
|
var parse = function(test) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Chops off 1 char at a time until limit or start of string is reached
|
||||||
|
// The passed code must still be valid when unchopped
|
||||||
|
var test_eol = function(input, chopLimit) {
|
||||||
|
if (chopLimit === undefined) {
|
||||||
|
chopLimit = input.length - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.doesNotThrow(parse(input), "Expected valid code for \n" + input);
|
||||||
|
|
||||||
|
for (var i = input.length - 1; chopLimit > 0; chopLimit--, i--) {
|
||||||
|
var code = input.substr(0, i);
|
||||||
|
assert.throws(parse(code), error, code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test_eol("var \\u1234", 7); // Incomplete identifier
|
||||||
|
test_eol("'Incomplete string'");
|
||||||
|
test_eol("/Unterminated regex/");
|
||||||
|
test_eol("` Unterminated template string`");
|
||||||
|
test_eol("/* Unfinishing multiline comment */");
|
||||||
|
});
|
||||||
|
});
|
||||||
40
test/mocha/export.js
Normal file
40
test/mocha/export.js
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("Export", function() {
|
||||||
|
it ("Should parse export directives", function() {
|
||||||
|
|
||||||
|
var inputs = [
|
||||||
|
['export * from "a.js"', ['*'], "a.js"],
|
||||||
|
['export {A} from "a.js"', ['A'], "a.js"],
|
||||||
|
['export {A as X} from "a.js"', ['X'], "a.js"],
|
||||||
|
['export {A as Foo, B} from "a.js"', ['Foo', 'B'], "a.js"],
|
||||||
|
['export {A, B} from "a.js"', ['A', 'B'], "a.js"],
|
||||||
|
];
|
||||||
|
|
||||||
|
var test = function(code) {
|
||||||
|
return uglify.parse(code);
|
||||||
|
};
|
||||||
|
|
||||||
|
var extractNames = function(symbols) {
|
||||||
|
var ret = [];
|
||||||
|
for (var i = 0; i < symbols.length; i++) {
|
||||||
|
ret.push(symbols[i].name.name)
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var i = 0; i < inputs.length; i++) {
|
||||||
|
var ast = test(inputs[i][0]);
|
||||||
|
var names = inputs[i][1];
|
||||||
|
var filename = inputs[i][2];
|
||||||
|
assert(ast instanceof uglify.AST_Toplevel);
|
||||||
|
assert.equal(ast.body.length, 1);
|
||||||
|
var st = ast.body[0];
|
||||||
|
assert(st instanceof uglify.AST_Export);
|
||||||
|
var actualNames = extractNames(st.exported_names);
|
||||||
|
assert.deepEqual(actualNames, names);
|
||||||
|
assert.equal(st.module_name.value, filename)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
32
test/mocha/expression.js
Normal file
32
test/mocha/expression.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var uglify = require("../node");
|
||||||
|
|
||||||
|
describe("Expression", function() {
|
||||||
|
it("Should not allow the first exponentiation operator to be prefixed with an unary operator", function() {
|
||||||
|
var tests = [
|
||||||
|
"+5 ** 3",
|
||||||
|
"-5 ** 3",
|
||||||
|
"~5 ** 3",
|
||||||
|
"!5 ** 3",
|
||||||
|
"void 5 ** 3",
|
||||||
|
"typeof 5 ** 3",
|
||||||
|
"delete 5 ** 3",
|
||||||
|
"var a = -(5) ** 3;"
|
||||||
|
];
|
||||||
|
|
||||||
|
var fail = function(e) {
|
||||||
|
return e instanceof uglify.JS_Parse_Error &&
|
||||||
|
/^Unexpected token: operator \((?:[!+~-]|void|typeof|delete)\)/.test(e.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var exec = function(test) {
|
||||||
|
return function() {
|
||||||
|
uglify.parse(test);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tests.length; i++) {
|
||||||
|
assert.throws(exec(tests[i]), fail, tests[i]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user