Compare commits
248 Commits
v3.2.1
...
harmony-v3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
01f23cf5a1 | ||
|
|
99fb3e8f0d | ||
|
|
756c9aa7dc | ||
|
|
07d6bfd707 | ||
|
|
81243c4e71 | ||
|
|
cd6e849555 | ||
|
|
91de285166 | ||
|
|
4d8f289eb0 | ||
|
|
945ba64160 | ||
|
|
c699200398 | ||
|
|
daf44f2b21 | ||
|
|
fcd90db30d | ||
|
|
e2888bdc43 | ||
|
|
fb50b7b627 | ||
|
|
9d59c693c2 | ||
|
|
6ddb5bd94d | ||
|
|
eda49605c5 | ||
|
|
1e9ef17e32 | ||
|
|
222100ea4c | ||
|
|
93db48a317 | ||
|
|
2944e3df7d | ||
|
|
e0ae8da089 | ||
|
|
81f1311b24 | ||
|
|
2433bb4e52 | ||
|
|
3fac29a017 | ||
|
|
b4c18f6b83 | ||
|
|
73d6438773 | ||
|
|
5c6316a37d | ||
|
|
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 |
11
.github/ISSUE_TEMPLATE.md
vendored
11
.github/ISSUE_TEMPLATE.md
vendored
@@ -8,16 +8,7 @@
|
|||||||
|
|
||||||
**Uglify version (`uglifyjs -V`)**
|
**Uglify version (`uglifyjs -V`)**
|
||||||
|
|
||||||
**JavaScript input**
|
**JavaScript input** <!-- ideally as small as possible -->
|
||||||
|
|
||||||
<!--
|
|
||||||
A complete parsable JS program exhibiting the issue with
|
|
||||||
UglifyJS alone - without third party tools or libraries.
|
|
||||||
Ideally the input should be as small as possible.
|
|
||||||
Post a link to a gist if necessary.
|
|
||||||
|
|
||||||
Issues without a reproducible test case will be closed.
|
|
||||||
-->
|
|
||||||
|
|
||||||
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
**The `uglifyjs` CLI command executed or `minify()` options used.**
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
|
before_install: "npm install -g npm"
|
||||||
node_js:
|
node_js:
|
||||||
- "0.10"
|
- "0.10"
|
||||||
- "0.12"
|
- "0.12"
|
||||||
- "4"
|
- "4"
|
||||||
- "6"
|
- "6"
|
||||||
- "8"
|
|
||||||
env:
|
env:
|
||||||
- UGLIFYJS_TEST_ALL=1
|
- UGLIFYJS_TEST_ALL=1
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
sudo: false
|
sudo: false
|
||||||
cache:
|
|
||||||
directories: tmp
|
|
||||||
|
|||||||
656
README.md
656
README.md
@@ -1,14 +1,12 @@
|
|||||||
UglifyJS 3
|
uglify-es
|
||||||
==========
|
=========
|
||||||
|
[](https://travis-ci.org/mishoo/UglifyJS2)
|
||||||
|
|
||||||
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
**uglify-es** is an ECMAScript 2015 parser, minifier, compressor and beautifier toolkit.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage) that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
- **The `uglify-es` API and CLI is compatible with `uglify-js@3.x`.**
|
||||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
- **`uglify-es` is not backwards compatible with the `uglify-js@2.x` API and CLI.**
|
||||||
- `uglify-js` only supports ECMAScript 5 (ES5).
|
|
||||||
- Those wishing to minify
|
|
||||||
ES2015+ (ES6+) should use the `npm` package [**uglify-es**](https://github.com/mishoo/UglifyJS2/tree/harmony).
|
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -18,11 +16,11 @@ First make sure you have installed the latest version of [node.js](http://nodejs
|
|||||||
|
|
||||||
From NPM for use as a command line app:
|
From NPM for use as a command line app:
|
||||||
|
|
||||||
npm install uglify-js -g
|
npm install uglify-es -g
|
||||||
|
|
||||||
From NPM for programmatic use:
|
From NPM for programmatic use:
|
||||||
|
|
||||||
npm install uglify-js
|
npm install uglify-es
|
||||||
|
|
||||||
# Command line usage
|
# Command line usage
|
||||||
|
|
||||||
@@ -45,7 +43,6 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
|
|
||||||
```
|
```
|
||||||
-h, --help Print usage information.
|
-h, --help Print usage information.
|
||||||
`--help options` for details on available options.
|
|
||||||
-V, --version Print version number.
|
-V, --version Print version number.
|
||||||
-p, --parse <options> Specify parser options:
|
-p, --parse <options> Specify parser options:
|
||||||
`acorn` Use Acorn for parsing.
|
`acorn` Use Acorn for parsing.
|
||||||
@@ -111,7 +108,7 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
By default UglifyJS will not try to be IE-proof.
|
By default UglifyJS will not try to be IE-proof.
|
||||||
--keep-fnames Do not mangle/drop function names. Useful for
|
--keep-fnames Do not mangle/drop function names. Useful for
|
||||||
code relying on Function.prototype.name.
|
code relying on Function.prototype.name.
|
||||||
--name-cache <file> File to hold mangled name mappings.
|
--name-cache File to hold mangled name mappings.
|
||||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||||
--source-map [options] Enable source map/specify source map options:
|
--source-map [options] Enable source map/specify source map options:
|
||||||
`base` Path to compute relative paths from input files.
|
`base` Path to compute relative paths from input files.
|
||||||
@@ -127,8 +124,8 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
the source map.
|
the source map.
|
||||||
`url` If specified, path to the source map to append in
|
`url` If specified, path to the source map to append in
|
||||||
`//# sourceMappingURL`.
|
`//# sourceMappingURL`.
|
||||||
--timings Display operations run time on STDERR.
|
--stats Display operations run time on STDERR.
|
||||||
--toplevel Compress and/or mangle variables in top level scope.
|
--toplevel Compress and/or mangle variables in toplevel scope.
|
||||||
--verbose Print diagnostic messages.
|
--verbose Print diagnostic messages.
|
||||||
--warn Print warning messages.
|
--warn Print warning messages.
|
||||||
--wrap <name> Embed everything in a big function, making the
|
--wrap <name> Embed everything in a big function, making the
|
||||||
@@ -150,19 +147,19 @@ debugging your compressed JavaScript. To get a source map, pass
|
|||||||
|
|
||||||
Additional options:
|
Additional options:
|
||||||
|
|
||||||
- `--source-map "filename='<NAME>'"` to specify the name of the source map.
|
- `--source-map filename=<NAME>` to specify the name of the source map.
|
||||||
|
|
||||||
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
- `--source-map root=<URL>` to pass the URL where the original files can be found.
|
||||||
|
|
||||||
- `--source-map "url='<URL>'"` to specify the URL where the source map can be found.
|
|
||||||
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
Otherwise UglifyJS assumes HTTP `X-SourceMap` is being used and will omit the
|
||||||
`//# sourceMappingURL=` directive.
|
`//# sourceMappingURL=` directive.
|
||||||
|
|
||||||
|
- `--source-map url=<URL>` to specify the URL where the source map can be found.
|
||||||
|
|
||||||
For example:
|
For example:
|
||||||
|
|
||||||
uglifyjs js/file1.js js/file2.js \
|
uglifyjs js/file1.js js/file2.js \
|
||||||
-o foo.min.js -c -m \
|
-o foo.min.js -c -m \
|
||||||
--source-map "root='http://foo.com/src',url='foo.min.js.map'"
|
--source-map root="http://foo.com/src",url=foo.min.js.map
|
||||||
|
|
||||||
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
The above will compress and mangle `file1.js` and `file2.js`, will drop the
|
||||||
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
output in `foo.min.js` and the source map in `foo.min.js.map`. The source
|
||||||
@@ -181,8 +178,8 @@ CoffeeScript → compiled JS, UglifyJS can generate a map from CoffeeScript →
|
|||||||
compressed JS by mapping every token in the compiled JS to its original
|
compressed JS by mapping every token in the compiled JS to its original
|
||||||
location.
|
location.
|
||||||
|
|
||||||
To use this feature pass `--source-map "content='/path/to/input/source.map'"`
|
To use this feature pass `--source-map content="/path/to/input/source.map"`
|
||||||
or `--source-map "content=inline"` if the source map is included inline with
|
or `--source-map content=inline` if the source map is included inline with
|
||||||
the sources.
|
the sources.
|
||||||
|
|
||||||
## CLI compress options
|
## CLI compress options
|
||||||
@@ -203,68 +200,40 @@ Example:
|
|||||||
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
||||||
(comma-separated) options are supported:
|
(comma-separated) options are supported:
|
||||||
|
|
||||||
- `toplevel` (default `false`) -- mangle names declared in the top level scope.
|
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||||
|
default).
|
||||||
|
|
||||||
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or `with` are used.
|
- `eval` — mangle names visible in scopes where `eval` or `with` are used
|
||||||
|
(disabled by default).
|
||||||
|
|
||||||
When mangling is enabled but you want to prevent certain names from being
|
When mangling is enabled but you want to prevent certain names from being
|
||||||
mangled, you can declare those names with `--mangle reserved` — pass a
|
mangled, you can declare those names with `--mangle reserved` — pass a
|
||||||
comma-separated list of names. For example:
|
comma-separated list of names. For example:
|
||||||
|
|
||||||
uglifyjs ... -m reserved=['$','require','exports']
|
uglifyjs ... -m reserved=[$,require,exports]
|
||||||
|
|
||||||
to prevent the `require`, `exports` and `$` names from being changed.
|
to prevent the `require`, `exports` and `$` names from being changed.
|
||||||
|
|
||||||
### CLI mangling property names (`--mangle-props`)
|
### CLI mangling property names (`--mangle-props`)
|
||||||
|
|
||||||
**Note:** THIS WILL PROBABLY BREAK YOUR CODE. Mangling property names
|
**Note:** this will probably break your code. Mangling property names is a
|
||||||
is a separate step, different from variable name mangling. Pass
|
separate step, different from variable name mangling. Pass
|
||||||
`--mangle-props` to enable it. It will mangle all properties in the
|
`--mangle-props`. It will mangle all properties that are seen in some
|
||||||
input code with the exception of built in DOM properties and properties
|
object literal, or that are assigned to. For example:
|
||||||
in core JavaScript classes. For example:
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// example.js
|
|
||||||
var x = {
|
var x = {
|
||||||
baz_: 0,
|
foo: 1
|
||||||
foo_: 1,
|
|
||||||
calc: function() {
|
|
||||||
return this.foo_ + this.baz_;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
x.bar_ = 2;
|
|
||||||
x["baz_"] = 3;
|
x.bar = 2;
|
||||||
console.log(x.calc());
|
x["baz"] = 3;
|
||||||
```
|
x[condition ? "moo" : "boo"] = 4;
|
||||||
Mangle all properties (except for JavaScript `builtins`):
|
console.log(x.something());
|
||||||
```bash
|
|
||||||
$ uglifyjs example.js -c -m --mangle-props
|
|
||||||
```
|
|
||||||
```javascript
|
|
||||||
var x={o:0,_:1,l:function(){return this._+this.o}};x.t=2,x.o=3,console.log(x.l());
|
|
||||||
```
|
|
||||||
Mangle all properties except for `reserved` properties:
|
|
||||||
```bash
|
|
||||||
$ uglifyjs example.js -c -m --mangle-props reserved=[foo_,bar_]
|
|
||||||
```
|
|
||||||
```javascript
|
|
||||||
var x={o:0,foo_:1,_:function(){return this.foo_+this.o}};x.bar_=2,x.o=3,console.log(x._());
|
|
||||||
```
|
|
||||||
Mangle all properties matching a `regex`:
|
|
||||||
```bash
|
|
||||||
$ uglifyjs example.js -c -m --mangle-props regex=/_$/
|
|
||||||
```
|
|
||||||
```javascript
|
|
||||||
var x={o:0,_:1,calc:function(){return this._+this.o}};x.l=2,x.o=3,console.log(x.calc());
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Combining mangle properties options:
|
In the above code, `foo`, `bar`, `baz`, `moo` and `boo` will be replaced
|
||||||
```bash
|
with single characters, while `something()` will be left as is.
|
||||||
$ uglifyjs example.js -c -m --mangle-props regex=/_$/,reserved=[bar_]
|
|
||||||
```
|
|
||||||
```javascript
|
|
||||||
var x={o:0,_:1,calc:function(){return this._+this.o}};x.bar_=2,x.o=3,console.log(x.calc());
|
|
||||||
```
|
|
||||||
|
|
||||||
In order for this to be of any use, we avoid mangling standard JS names by
|
In order for this to be of any use, we avoid mangling standard JS names by
|
||||||
default (`--mangle-props builtins` to override).
|
default (`--mangle-props builtins` to override).
|
||||||
@@ -273,7 +242,7 @@ A default exclusion file is provided in `tools/domprops.json` which should
|
|||||||
cover most standard JS and DOM properties defined in various browsers. Pass
|
cover most standard JS and DOM properties defined in various browsers. Pass
|
||||||
`--mangle-props domprops` to disable this feature.
|
`--mangle-props domprops` to disable this feature.
|
||||||
|
|
||||||
A regular expression can be used to define which property names should be
|
You can also use a regular expression to define which property names should be
|
||||||
mangled. For example, `--mangle-props regex=/^_/` will only mangle property
|
mangled. For example, `--mangle-props regex=/^_/` will only mangle property
|
||||||
names that start with an underscore.
|
names that start with an underscore.
|
||||||
|
|
||||||
@@ -301,20 +270,9 @@ Using quoted property name (`o["foo"]`) reserves the property name (`foo`)
|
|||||||
so that it is not mangled throughout the entire script even when used in an
|
so that it is not mangled throughout the entire script even when used in an
|
||||||
unquoted style (`o.foo`). Example:
|
unquoted style (`o.foo`). Example:
|
||||||
|
|
||||||
```javascript
|
|
||||||
// stuff.js
|
|
||||||
var o = {
|
|
||||||
"foo": 1,
|
|
||||||
bar: 3
|
|
||||||
};
|
|
||||||
o.foo += o.bar;
|
|
||||||
console.log(o.foo);
|
|
||||||
```
|
|
||||||
```bash
|
```bash
|
||||||
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m
|
$ echo 'var o={"foo":1, bar:3}; o.foo += o.bar; console.log(o.foo);' | uglifyjs --mangle-props keep_quoted -mc
|
||||||
```
|
var o={foo:1,a:3};o.foo+=o.a,console.log(o.foo);
|
||||||
```javascript
|
|
||||||
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Debugging property name mangling
|
### Debugging property name mangling
|
||||||
@@ -325,13 +283,6 @@ would mangle to `o._$foo$_` with this option. This allows property mangling
|
|||||||
of a large codebase while still being able to debug the code and identify
|
of a large codebase while still being able to debug the code and identify
|
||||||
where mangling is breaking things.
|
where mangling is breaking things.
|
||||||
|
|
||||||
```bash
|
|
||||||
$ uglifyjs stuff.js --mangle-props debug -c -m
|
|
||||||
```
|
|
||||||
```javascript
|
|
||||||
var o={_$foo$_:1,_$bar$_:3};o._$foo$_+=o._$bar$_,console.log(o._$foo$_);
|
|
||||||
```
|
|
||||||
|
|
||||||
You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then
|
You can also pass a custom suffix using `--mangle-props debug=XYZ`. This would then
|
||||||
mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a
|
mangle `o.foo` to `o._$foo$XYZ_`. You can change this each time you compile a
|
||||||
script to identify how a property got mangled. One technique is to pass a
|
script to identify how a property got mangled. One technique is to pass a
|
||||||
@@ -345,137 +296,30 @@ identify mistakes like writing mangled keys to storage.
|
|||||||
Assuming installation via NPM, you can load UglifyJS in your application
|
Assuming installation via NPM, you can load UglifyJS in your application
|
||||||
like this:
|
like this:
|
||||||
```javascript
|
```javascript
|
||||||
var UglifyJS = require("uglify-js");
|
var UglifyJS = require("uglify-es");
|
||||||
```
|
```
|
||||||
|
|
||||||
There is a single high level function, **`minify(code, options)`**,
|
There is a single high level minification function, `minify(files, options)`, which will
|
||||||
which will perform all minification [phases](#minify-options) in a configurable
|
performs all the steps in a configurable manner.
|
||||||
manner. By default `minify()` will enable the options [`compress`](#compress-options)
|
Example:
|
||||||
and [`mangle`](#mangle-options). Example:
|
|
||||||
```javascript
|
```javascript
|
||||||
var code = "function add(first, second) { return first + second; }";
|
var result = UglifyJS.minify("var b = function() {};");
|
||||||
var result = UglifyJS.minify(code);
|
console.log(result.code); // minified output
|
||||||
console.log(result.error); // runtime error, or `undefined` if no error
|
console.log(result.error); // runtime error
|
||||||
console.log(result.code); // minified output: function add(n,d){return n+d}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can `minify` more than one JavaScript file at a time by using an object
|
You can also compress multiple files:
|
||||||
for the first argument where the keys are file names and the values are source
|
|
||||||
code:
|
|
||||||
```javascript
|
```javascript
|
||||||
var code = {
|
var result = UglifyJS.minify({
|
||||||
"file1.js": "function add(first, second) { return first + second; }",
|
"file1.js": "var a = function() {};",
|
||||||
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
"file2.js": "var b = function() {};"
|
||||||
};
|
});
|
||||||
var result = UglifyJS.minify(code);
|
|
||||||
console.log(result.code);
|
console.log(result.code);
|
||||||
// function add(d,n){return d+n}console.log(add(3,7));
|
|
||||||
```
|
|
||||||
|
|
||||||
The `toplevel` option:
|
|
||||||
```javascript
|
|
||||||
var code = {
|
|
||||||
"file1.js": "function add(first, second) { return first + second; }",
|
|
||||||
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
|
||||||
};
|
|
||||||
var options = { toplevel: true };
|
|
||||||
var result = UglifyJS.minify(code, options);
|
|
||||||
console.log(result.code);
|
|
||||||
// console.log(3+7);
|
|
||||||
```
|
|
||||||
|
|
||||||
The `nameCache` option:
|
|
||||||
```javascript
|
|
||||||
var options = {
|
|
||||||
mangle: {
|
|
||||||
toplevel: true,
|
|
||||||
},
|
|
||||||
nameCache: {}
|
|
||||||
};
|
|
||||||
var result1 = UglifyJS.minify({
|
|
||||||
"file1.js": "function add(first, second) { return first + second; }"
|
|
||||||
}, options);
|
|
||||||
var result2 = UglifyJS.minify({
|
|
||||||
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
|
||||||
}, options);
|
|
||||||
console.log(result1.code);
|
|
||||||
// function n(n,r){return n+r}
|
|
||||||
console.log(result2.code);
|
|
||||||
// console.log(n(3,7));
|
|
||||||
```
|
|
||||||
|
|
||||||
You may persist the name cache to the file system in the following way:
|
|
||||||
```javascript
|
|
||||||
var cacheFileName = "/tmp/cache.json";
|
|
||||||
var options = {
|
|
||||||
mangle: {
|
|
||||||
properties: true,
|
|
||||||
},
|
|
||||||
nameCache: JSON.parse(fs.readFileSync(cacheFileName, "utf8"))
|
|
||||||
};
|
|
||||||
fs.writeFileSync("part1.js", UglifyJS.minify({
|
|
||||||
"file1.js": fs.readFileSync("file1.js", "utf8"),
|
|
||||||
"file2.js": fs.readFileSync("file2.js", "utf8")
|
|
||||||
}, options).code, "utf8");
|
|
||||||
fs.writeFileSync("part2.js", UglifyJS.minify({
|
|
||||||
"file3.js": fs.readFileSync("file3.js", "utf8"),
|
|
||||||
"file4.js": fs.readFileSync("file4.js", "utf8")
|
|
||||||
}, options).code, "utf8");
|
|
||||||
fs.writeFileSync(cacheFileName, JSON.stringify(options.nameCache), "utf8");
|
|
||||||
```
|
|
||||||
|
|
||||||
An example of a combination of `minify()` options:
|
|
||||||
```javascript
|
|
||||||
var code = {
|
|
||||||
"file1.js": "function add(first, second) { return first + second; }",
|
|
||||||
"file2.js": "console.log(add(1 + 2, 3 + 4));"
|
|
||||||
};
|
|
||||||
var options = {
|
|
||||||
toplevel: true,
|
|
||||||
compress: {
|
|
||||||
global_defs: {
|
|
||||||
"@console.log": "alert"
|
|
||||||
},
|
|
||||||
passes: 2
|
|
||||||
},
|
|
||||||
output: {
|
|
||||||
beautify: false,
|
|
||||||
preamble: "/* uglified */"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var result = UglifyJS.minify(code, options);
|
|
||||||
console.log(result.code);
|
|
||||||
// /* uglified */
|
|
||||||
// alert(10);"
|
|
||||||
```
|
|
||||||
|
|
||||||
To produce warnings:
|
|
||||||
```javascript
|
|
||||||
var code = "function f(){ var u; return 2 + 3; }";
|
|
||||||
var options = { warnings: true };
|
|
||||||
var result = UglifyJS.minify(code, options);
|
|
||||||
console.log(result.error); // runtime error, `undefined` in this case
|
|
||||||
console.log(result.warnings); // [ 'Dropping unused variable u [0:1,18]' ]
|
|
||||||
console.log(result.code); // function f(){return 5}
|
|
||||||
```
|
|
||||||
|
|
||||||
An error example:
|
|
||||||
```javascript
|
|
||||||
var result = UglifyJS.minify({"foo.js" : "if (0) else console.log(1);"});
|
|
||||||
console.log(JSON.stringify(result.error));
|
|
||||||
// {"message":"Unexpected token: keyword (else)","filename":"foo.js","line":1,"col":7,"pos":7}
|
|
||||||
```
|
|
||||||
Note: unlike `uglify-js@2.x`, the `3.x` API does not throw errors. To
|
|
||||||
achieve a similar effect one could do the following:
|
|
||||||
```javascript
|
|
||||||
var result = UglifyJS.minify(code, options);
|
|
||||||
if (result.error) throw result.error;
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
- `warnings` (default `false`) — pass `true` to display compressor warnings.
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
|
||||||
|
|
||||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
- `parse` (default `{}`) — pass an object if you wish to specify some
|
||||||
additional [parse options](#parse-options).
|
additional [parse options](#parse-options).
|
||||||
@@ -499,22 +343,13 @@ if (result.error) throw result.error;
|
|||||||
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
- `toplevel` (default `false`) - set to `true` if you wish to enable top level
|
||||||
variable and function name mangling and to drop unused variables and functions.
|
variable and function name mangling and to drop unused variables and functions.
|
||||||
|
|
||||||
- `nameCache` (default `null`) - pass an empty object `{}` or a previously
|
|
||||||
used `nameCache` object if you wish to cache mangled variable and
|
|
||||||
property names across multiple invocations of `minify()`. Note: this is
|
|
||||||
a read/write property. `minify()` will read the name cache state of this
|
|
||||||
object and update it during minification so that it may be
|
|
||||||
reused or externally persisted by the user.
|
|
||||||
|
|
||||||
- `ie8` (default `false`) - set to `true` to support IE8.
|
- `ie8` (default `false`) - set to `true` to support IE8.
|
||||||
|
|
||||||
- `keep_fnames` (default: `false`) - pass `true` to prevent discarding or mangling
|
## Minify option structure
|
||||||
of function names. Useful for code relying on `Function.prototype.name`.
|
|
||||||
|
|
||||||
## Minify options structure
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
{
|
{
|
||||||
|
warnings: false,
|
||||||
parse: {
|
parse: {
|
||||||
// parse options
|
// parse options
|
||||||
},
|
},
|
||||||
@@ -534,10 +369,8 @@ if (result.error) throw result.error;
|
|||||||
sourceMap: {
|
sourceMap: {
|
||||||
// source map options
|
// source map options
|
||||||
},
|
},
|
||||||
nameCache: null, // or specify a name cache object
|
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
warnings: false,
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -591,87 +424,99 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
## Parse options
|
## Parse options
|
||||||
|
|
||||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
- `bare_returns` (default `false`) -- support top level `return` statements
|
||||||
|
|
||||||
- `html5_comments` (default `true`)
|
- `html5_comments` (default `true`)
|
||||||
|
|
||||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
- `shebang` (default `true`) -- support `#!command` as the first line
|
||||||
|
|
||||||
## Compress options
|
## Compress options
|
||||||
|
|
||||||
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
- `sequences` (default: true) -- join consecutive simple statements using the
|
||||||
for example `!!a ? b : c → a ? b : c`
|
comma operator. May be set to a positive integer to specify the maximum number
|
||||||
|
of consecutive comma sequences that will be generated. If this option is set to
|
||||||
|
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
||||||
|
to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
|
||||||
|
is grandfathered to be equivalent to `true` and as such means `200`. On rare
|
||||||
|
occasions the default sequences limit leads to very slow compress times in which
|
||||||
|
case a value of `20` or less is recommended.
|
||||||
|
|
||||||
- `cascade` (default: `true`) -- small optimization for sequences, transform
|
- `properties` -- rewrite property access using the dot notation, for
|
||||||
`x, x` into `x` and `x = something(), x` into `x = something()`
|
example `foo["bar"] → foo.bar`
|
||||||
|
|
||||||
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
- `dead_code` -- remove unreachable code
|
||||||
side effects permitting.
|
|
||||||
|
|
||||||
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
- `drop_debugger` -- remove `debugger;` statements
|
||||||
e.g. `!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
|
|
||||||
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
|
||||||
|
|
||||||
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
|
- `unsafe` (default: false) -- apply "unsafe" transformations (discussion below)
|
||||||
|
|
||||||
|
- `unsafe_comps` (default: false) -- Reverse `<` and `<=` to `>` and `>=` to
|
||||||
|
allow improved compression. This might be unsafe when an at least one of two
|
||||||
|
operands is an object with computed values due the use of methods like `get`,
|
||||||
|
or `valueOf`. This could cause change in execution order after operands in the
|
||||||
|
comparison are switching. Compression only works if both `comparisons` and
|
||||||
|
`unsafe_comps` are both set to true.
|
||||||
|
|
||||||
|
- `unsafe_math` (default: false) -- optimize numerical expressions like
|
||||||
|
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||||
|
|
||||||
|
- `unsafe_proto` (default: false) -- optimize expressions like
|
||||||
|
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||||
|
|
||||||
|
- `conditionals` -- apply optimizations for `if`-s and conditional
|
||||||
expressions
|
expressions
|
||||||
|
|
||||||
- `dead_code` (default: `true`) -- remove unreachable code
|
- `comparisons` -- apply certain optimizations to binary nodes, for example:
|
||||||
|
`!(a <= b) → a > b` (only when `unsafe_comps`), attempts to negate binary
|
||||||
|
nodes, e.g. `a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||||
|
|
||||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
- `evaluate` -- attempt to evaluate constant expressions
|
||||||
`console.*` functions. If you wish to drop a specific function call
|
|
||||||
such as `console.info` and/or retain side effects from function arguments
|
|
||||||
after dropping the function call then use `pure_funcs` instead.
|
|
||||||
|
|
||||||
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
|
- `booleans` -- various optimizations for boolean context, for example `!!a
|
||||||
|
? b : c → a ? b : c`
|
||||||
|
|
||||||
- `evaluate` (default: `true`) -- attempt to evaluate constant expressions
|
- `loops` -- optimizations for `do`, `while` and `for` loops when we can
|
||||||
|
statically determine the condition
|
||||||
|
|
||||||
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
- `unused` -- drop unreferenced functions and variables (simple direct variable
|
||||||
from terminal statements without `return`, e.g. in bookmarklets.
|
assignments do not count as references unless set to `"keep_assign"`)
|
||||||
|
|
||||||
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
- `toplevel` -- drop unreferenced functions (`"funcs"`) and/or variables (`"vars"`)
|
||||||
|
in the toplevel scope (`false` by default, `true` to drop both unreferenced
|
||||||
|
functions and variables)
|
||||||
|
|
||||||
- `hoist_funs` (default: `true`) -- hoist function declarations
|
- `top_retain` -- prevent specific toplevel functions and variables from `unused`
|
||||||
|
removal (can be array, comma-separated, RegExp or function. Implies `toplevel`)
|
||||||
|
|
||||||
- `hoist_props` (default: `true`) -- hoist properties from constant object and
|
- `hoist_funs` -- hoist function declarations
|
||||||
array literals into regular variables subject to a set of constraints. For example:
|
|
||||||
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
|
|
||||||
works best with `mangle` enabled, the `compress` option `passes` set to `2` or higher,
|
|
||||||
and the `compress` option `toplevel` enabled.
|
|
||||||
|
|
||||||
- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
|
- `hoist_vars` (default: false) -- hoist `var` declarations (this is `false`
|
||||||
by default because it seems to increase the size of the output in general)
|
by default because it seems to increase the size of the output in general)
|
||||||
|
|
||||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
- `if_return` -- optimizations for if/return and if/continue
|
||||||
|
|
||||||
- `inline` (default: `true`) -- embed simple functions
|
- `join_vars` -- join consecutive `var` statements
|
||||||
|
|
||||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
- `cascade` -- small optimization for sequences, transform `x, x` into `x`
|
||||||
|
and `x = something(), x` into `x = something()`
|
||||||
|
|
||||||
- `keep_fargs` (default: `true`) -- Prevents the compressor from discarding unused
|
- `collapse_vars` -- Collapse single-use `var` and `const` definitions
|
||||||
function arguments. You need this for code which relies on `Function.length`.
|
when possible.
|
||||||
|
|
||||||
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
- `reduce_vars` -- Improve optimization on variables assigned with and
|
||||||
compressor from discarding function names. Useful for code relying on
|
used as constant values.
|
||||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
|
||||||
|
|
||||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
- `warnings` -- display warnings when dropping unreachable code or unused
|
||||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
declarations etc.
|
||||||
|
|
||||||
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
|
- `negate_iife` -- negate "Immediately-Called Function Expressions"
|
||||||
when we can statically determine the condition.
|
|
||||||
|
|
||||||
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
|
|
||||||
where the return value is discarded, to avoid the parens that the
|
where the return value is discarded, to avoid the parens that the
|
||||||
code generator would insert.
|
code generator would insert.
|
||||||
|
|
||||||
- `passes` (default: `1`) -- The maximum number of times to run compress.
|
- `pure_getters` -- the default is `false`. If you pass `true` for
|
||||||
In some cases more than one pass leads to further compressed code. Keep in
|
this, UglifyJS will assume that object property access
|
||||||
mind more passes will take more time.
|
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
||||||
|
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||||
|
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||||
|
|
||||||
- `properties` (default: `true`) -- rewrite property access using the dot notation, for
|
- `pure_funcs` -- default `null`. You can pass an array of names and
|
||||||
example `foo["bar"] → foo.bar`
|
|
||||||
|
|
||||||
- `pure_funcs` (default: `null`) -- You can pass an array of names and
|
|
||||||
UglifyJS will assume that those functions do not produce side
|
UglifyJS will assume that those functions do not produce side
|
||||||
effects. DANGER: will not check if the name is redefined in scope.
|
effects. DANGER: will not check if the name is redefined in scope.
|
||||||
An example case here, for instance `var q = Math.floor(a/b)`. If
|
An example case here, for instance `var q = Math.floor(a/b)`. If
|
||||||
@@ -682,90 +527,47 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
|||||||
statement would get discarded. The current implementation adds some
|
statement would get discarded. The current implementation adds some
|
||||||
overhead (compression will be slower).
|
overhead (compression will be slower).
|
||||||
|
|
||||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
- `drop_console` -- default `false`. Pass `true` to discard calls to
|
||||||
this, UglifyJS will assume that object property access
|
`console.*` functions. If you wish to drop a specific function call
|
||||||
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
such as `console.info` and/or retain side effects from function arguments
|
||||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
after dropping the function call then use `pure_funcs` instead.
|
||||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
|
||||||
|
|
||||||
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
|
- `expression` -- default `false`. Pass `true` to preserve completion values
|
||||||
inlined as function expressions when permissible allowing further
|
from terminal statements without `return`, e.g. in bookmarklets.
|
||||||
optimization. Enabled by default. Option depends on `reduce_vars`
|
|
||||||
being enabled. Some code runs faster in the Chrome V8 engine if this
|
|
||||||
option is disabled. Does not negatively impact other major browsers.
|
|
||||||
|
|
||||||
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
- `keep_fargs` -- default `true`. Prevents the
|
||||||
used as constant values.
|
compressor from discarding unused function arguments. You need this
|
||||||
|
for code which relies on `Function.length`.
|
||||||
|
|
||||||
- `sequences` (default: `true`) -- join consecutive simple statements using the
|
- `keep_fnames` -- default `false`. Pass `true` to prevent the
|
||||||
comma operator. May be set to a positive integer to specify the maximum number
|
compressor from discarding function names. Useful for code relying on
|
||||||
of consecutive comma sequences that will be generated. If this option is set to
|
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
||||||
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
|
||||||
to disable. The smallest `sequences` length is `2`. A `sequences` value of `1`
|
|
||||||
is grandfathered to be equivalent to `true` and as such means `200`. On rare
|
|
||||||
occasions the default sequences limit leads to very slow compress times in which
|
|
||||||
case a value of `20` or less is recommended.
|
|
||||||
|
|
||||||
- `side_effects` (default: `true`) -- Pass `false` to disable potentially dropping
|
- `passes` -- default `1`. Number of times to run compress with a maximum of 3.
|
||||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
In some cases more than one pass leads to further compressed code. Keep in
|
||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
mind more passes will take more time.
|
||||||
example: `/*@__PURE__*/foo();`
|
|
||||||
|
|
||||||
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
- `keep_infinity` -- default `false`. Pass `true` to prevent `Infinity` from
|
||||||
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||||
|
|
||||||
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
|
- `side_effects` -- default `false`. Pass `true` to potentially drop functions
|
||||||
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
marked as "pure". A function call is marked as "pure" if a comment annotation
|
||||||
both unreferenced functions and variables)
|
`/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For example:
|
||||||
|
`/*@__PURE__*/foo()`;
|
||||||
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
|
|
||||||
variables from `unused` removal (can be array, comma-separated, RegExp or
|
|
||||||
function. Implies `toplevel`)
|
|
||||||
|
|
||||||
- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
|
|
||||||
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
|
||||||
earlier versions due to known issues.
|
|
||||||
|
|
||||||
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
|
|
||||||
|
|
||||||
- `unsafe_comps` (default: `false`) -- Reverse `<` and `<=` to `>` and `>=` to
|
|
||||||
allow improved compression. This might be unsafe when an at least one of two
|
|
||||||
operands is an object with computed values due the use of methods like `get`,
|
|
||||||
or `valueOf`. This could cause change in execution order after operands in the
|
|
||||||
comparison are switching. Compression only works if both `comparisons` and
|
|
||||||
`unsafe_comps` are both set to true.
|
|
||||||
|
|
||||||
- `unsafe_Func` (default: `false`) -- compress and mangle `Function(args, code)`
|
|
||||||
when both `args` and `code` are string literals.
|
|
||||||
|
|
||||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
|
||||||
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
|
||||||
|
|
||||||
- `unsafe_proto` (default: `false`) -- optimize expressions like
|
|
||||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
|
||||||
|
|
||||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
|
||||||
`RegExp` values the same way as if they are constants.
|
|
||||||
|
|
||||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
|
||||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
|
||||||
|
|
||||||
- `warnings` (default: `false`) -- display warnings when dropping unreachable
|
|
||||||
code or unused declarations etc.
|
|
||||||
|
|
||||||
## Mangle options
|
## Mangle options
|
||||||
|
|
||||||
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
|
- `reserved` - pass an array of identifiers that should be excluded from mangling
|
||||||
where `eval` or `with` are used.
|
|
||||||
|
|
||||||
- `keep_fnames` (default `false`) -- Pass `true` to not mangle function names.
|
- `toplevel` — mangle names declared in the toplevel scope (disabled by
|
||||||
Useful for code relying on `Function.prototype.name`. See also: the `keep_fnames`
|
default).
|
||||||
[compress option](#compress-options).
|
|
||||||
|
|
||||||
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
|
- `eval` — mangle names visible in scopes where eval or with are used
|
||||||
excluded from mangling. Example: `["foo", "bar"]`.
|
(disabled by default).
|
||||||
|
|
||||||
- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
|
- `keep_fnames` -- default `false`. Pass `true` to not mangle
|
||||||
top level scope.
|
function names. Useful for code relying on `Function.prototype.name`.
|
||||||
|
See also: the `keep_fnames` [compress option](#compress-options).
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@@ -791,19 +593,10 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
|||||||
|
|
||||||
### Mangle properties options
|
### Mangle properties options
|
||||||
|
|
||||||
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
|
- `regex` — Pass a RegExp to only mangle certain names
|
||||||
DOM properties. Not recommended to override this setting.
|
- `keep_quoted` — Only mangle unquoted property names
|
||||||
|
- `debug` — Mangle names with the original name still present. Defaults to `false`.
|
||||||
- `debug` (default: `false`) -— Mangle names with the original name still present.
|
Pass an empty string to enable, or a non-empty string to set the suffix.
|
||||||
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
|
||||||
|
|
||||||
- `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
|
|
||||||
|
|
||||||
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
|
|
||||||
names matching the regular expression.
|
|
||||||
|
|
||||||
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
|
|
||||||
`reserved` array.
|
|
||||||
|
|
||||||
## Output options
|
## Output options
|
||||||
|
|
||||||
@@ -811,72 +604,49 @@ The code generator tries to output shortest code possible by default. In
|
|||||||
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
||||||
can pass additional arguments that control the code output:
|
can pass additional arguments that control the code output:
|
||||||
|
|
||||||
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
|
||||||
regexps (affects directives with non-ascii characters becoming invalid)
|
|
||||||
|
|
||||||
- `beautify` (default `true`) -- whether to actually beautify the output.
|
- `beautify` (default `true`) -- whether to actually beautify the output.
|
||||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||||
when you want to generate minified code, in order to specify additional
|
when you want to generate minified code, in order to specify additional
|
||||||
arguments, so you can use `-b beautify=false` to override it.
|
arguments, so you can use `-b beautify=false` to override it.
|
||||||
|
- `indent_level` (default 4)
|
||||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
- `indent_start` (default 0) -- prefix all lines by that many spaces
|
||||||
`do`, `while` or `with` statements, even if their body is a single
|
|
||||||
statement.
|
|
||||||
|
|
||||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
|
||||||
comments, `"some"` to preserve some comments, a regular expression string
|
|
||||||
(e.g. `/^!/`) or a function.
|
|
||||||
|
|
||||||
- `indent_level` (default `4`)
|
|
||||||
|
|
||||||
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
|
||||||
|
|
||||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
|
||||||
`</script` in strings
|
|
||||||
|
|
||||||
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
|
||||||
quotes from property names in object literals.
|
|
||||||
|
|
||||||
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
|
|
||||||
|
|
||||||
- `preamble` (default `null`) -- when passed it must be a string and
|
|
||||||
it will be prepended to the output literally. The source map will
|
|
||||||
adjust for this text. Can be used to insert a comment containing
|
|
||||||
licensing information, for example.
|
|
||||||
|
|
||||||
- `preserve_line` (default `false`) -- pass `true` to preserve lines, but it
|
|
||||||
only works if `beautify` is set to `false`.
|
|
||||||
|
|
||||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||||
objects
|
objects
|
||||||
|
- `space_colon` (default `true`) -- insert a space after the colon signs
|
||||||
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
||||||
quoted property names and directives as well):
|
regexps (affects directives with non-ascii characters becoming invalid)
|
||||||
- `0` -- prefers double quotes, switches to single quotes when there are
|
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||||
more double quotes in the string itself. `0` is best for gzip size.
|
`</script` in strings
|
||||||
- `1` -- always use single quotes
|
- `width` (default 80) -- only takes effect when beautification is on, this
|
||||||
- `2` -- always use double quotes
|
|
||||||
- `3` -- always use the original quotes
|
|
||||||
|
|
||||||
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
|
||||||
you pass `false` then whenever possible we will use a newline instead of a
|
|
||||||
semicolon, leading to more readable output of uglified code (size before
|
|
||||||
gzip could be smaller; size after gzip insignificantly larger).
|
|
||||||
|
|
||||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
|
||||||
|
|
||||||
- `webkit` (default `false`) -- enable workarounds for WebKit bugs.
|
|
||||||
PhantomJS users should set this option to `true`.
|
|
||||||
|
|
||||||
- `width` (default `80`) -- only takes effect when beautification is on, this
|
|
||||||
specifies an (orientative) line width that the beautifier will try to
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
obey. It refers to the width of the line text (excluding indentation).
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
It doesn't work very well currently, but it does make the code generated
|
It doesn't work very well currently, but it does make the code generated
|
||||||
by UglifyJS more readable.
|
by UglifyJS more readable.
|
||||||
|
- `max_line_len` (default 32000) -- maximum line length (for uglified code)
|
||||||
|
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||||
|
`do`, `while` or `with` statements, even if their body is a single
|
||||||
|
statement.
|
||||||
|
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
||||||
|
you pass `false` then whenever possible we will use a newline instead of a
|
||||||
|
semicolon, leading to more readable output of uglified code (size before
|
||||||
|
gzip could be smaller; size after gzip insignificantly larger).
|
||||||
|
- `preamble` (default `null`) -- when passed it must be a string and
|
||||||
|
it will be prepended to the output literally. The source map will
|
||||||
|
adjust for this text. Can be used to insert a comment containing
|
||||||
|
licensing information, for example.
|
||||||
|
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
||||||
|
quoted property names and directives as well):
|
||||||
|
- `0` -- prefers double quotes, switches to single quotes when there are
|
||||||
|
more double quotes in the string itself.
|
||||||
|
- `1` -- always use single quotes
|
||||||
|
- `2` -- always use double quotes
|
||||||
|
- `3` -- always use the original quotes
|
||||||
|
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
||||||
|
quotes from property names in object literals.
|
||||||
|
- `ecma` (default `5`) -- set output printing mode. This will only change the
|
||||||
|
output in direct control of the beautifier. Non-compatible features in the
|
||||||
|
abstract syntax tree will still be outputted as is.
|
||||||
|
|
||||||
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
|
|
||||||
function expressions. See
|
|
||||||
[#640](https://github.com/mishoo/UglifyJS2/issues/640) for more details.
|
|
||||||
|
|
||||||
# Miscellaneous
|
# Miscellaneous
|
||||||
|
|
||||||
@@ -919,6 +689,7 @@ when this flag is on:
|
|||||||
- `new Object()` → `{}`
|
- `new Object()` → `{}`
|
||||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||||
|
- `typeof foo == "undefined"` → `foo === void 0`
|
||||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
||||||
scope; we do it because the variable name will be mangled, typically
|
scope; we do it because the variable name will be mangled, typically
|
||||||
reduced to a single character)
|
reduced to a single character)
|
||||||
@@ -945,8 +716,8 @@ Another way of doing that is to declare your globals as constants in a
|
|||||||
separate file and include it into the build. For example you can have a
|
separate file and include it into the build. For example you can have a
|
||||||
`build/defines.js` file with the following:
|
`build/defines.js` file with the following:
|
||||||
```javascript
|
```javascript
|
||||||
var DEBUG = false;
|
const DEBUG = false;
|
||||||
var PRODUCTION = true;
|
const PRODUCTION = true;
|
||||||
// etc.
|
// etc.
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -966,7 +737,7 @@ You can also use conditional compilation via the programmatic API. With the diff
|
|||||||
property name is `global_defs` and is a compressor property:
|
property name is `global_defs` and is a compressor property:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
var result = uglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
||||||
compress: {
|
compress: {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
global_defs: {
|
global_defs: {
|
||||||
@@ -976,32 +747,6 @@ var result = UglifyJS.minify(fs.readFileSync("input.js", "utf8"), {
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
To replace an identifier with an arbitrary non-constant expression it is
|
|
||||||
necessary to prefix the `global_defs` key with `"@"` to instruct UglifyJS
|
|
||||||
to parse the value as an expression:
|
|
||||||
```javascript
|
|
||||||
UglifyJS.minify("alert('hello');", {
|
|
||||||
compress: {
|
|
||||||
global_defs: {
|
|
||||||
"@alert": "console.log"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).code;
|
|
||||||
// returns: 'console.log("hello");'
|
|
||||||
```
|
|
||||||
|
|
||||||
Otherwise it would be replaced as string literal:
|
|
||||||
```javascript
|
|
||||||
UglifyJS.minify("alert('hello');", {
|
|
||||||
compress: {
|
|
||||||
global_defs: {
|
|
||||||
"alert": "console.log"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).code;
|
|
||||||
// returns: '"console.log"("hello");'
|
|
||||||
```
|
|
||||||
|
|
||||||
### Using native Uglify AST with `minify()`
|
### Using native Uglify AST with `minify()`
|
||||||
```javascript
|
```javascript
|
||||||
// example: parse only, produce native Uglify AST
|
// example: parse only, produce native Uglify AST
|
||||||
@@ -1035,12 +780,6 @@ var result = UglifyJS.minify(ast, {
|
|||||||
// result.code contains the minified code in string form.
|
// result.code contains the minified code in string form.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Working with Uglify AST
|
|
||||||
|
|
||||||
Transversal and transformation of the native AST can be performed through
|
|
||||||
[`TreeWalker`](http://lisperator.net/uglifyjs/walk) and
|
|
||||||
[`TreeTransformer`](http://lisperator.net/uglifyjs/transform) respectively.
|
|
||||||
|
|
||||||
### ESTree / SpiderMonkey AST
|
### ESTree / SpiderMonkey AST
|
||||||
|
|
||||||
UglifyJS has its own abstract syntax tree format; for
|
UglifyJS has its own abstract syntax tree format; for
|
||||||
@@ -1071,30 +810,3 @@ in total it's a bit more than just using UglifyJS's own parser.
|
|||||||
|
|
||||||
[acorn]: https://github.com/ternjs/acorn
|
[acorn]: https://github.com/ternjs/acorn
|
||||||
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
[sm-spec]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k
|
||||||
|
|
||||||
### Uglify Fast Minify Mode
|
|
||||||
|
|
||||||
It's not well known, but whitespace removal and symbol mangling accounts
|
|
||||||
for 95% of the size reduction in minified code for most JavaScript - not
|
|
||||||
elaborate code transforms. One can simply disable `compress` to speed up
|
|
||||||
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
|
|
||||||
comparable minify speeds and gzip sizes to
|
|
||||||
[`butternut`](https://www.npmjs.com/package/butternut):
|
|
||||||
|
|
||||||
| d3.js | minify size | gzip size | minify time (seconds) |
|
|
||||||
| --- | ---: | ---: | ---: |
|
|
||||||
| original | 451,131 | 108,733 | - |
|
|
||||||
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
|
|
||||||
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
|
|
||||||
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
|
|
||||||
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
|
|
||||||
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
|
|
||||||
|
|
||||||
To enable fast minify mode from the CLI use:
|
|
||||||
```
|
|
||||||
uglifyjs file.js -m
|
|
||||||
```
|
|
||||||
To enable fast minify mode with the API use:
|
|
||||||
```js
|
|
||||||
UglifyJS.minify(code, { compress: false, mangle: true });
|
|
||||||
```
|
|
||||||
|
|||||||
136
bin/uglifyjs
136
bin/uglifyjs
@@ -15,31 +15,20 @@ var path = require("path");
|
|||||||
var program = require("commander");
|
var program = require("commander");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "enclosed", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {
|
var options = {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false
|
mangle: false
|
||||||
};
|
};
|
||||||
program.version(info.name + " " + info.version);
|
program.version(info.name + ' ' + info.version);
|
||||||
program.parseArgv = program.parse;
|
program.parseArgv = program.parse;
|
||||||
program.parse = undefined;
|
program.parse = undefined;
|
||||||
if (process.argv.indexOf("ast") >= 0) program.helpInformation = UglifyJS.describe_ast;
|
program.option("-p, --parse <options>", "Specify parser options.", parse_js("parse", true));
|
||||||
else if (process.argv.indexOf("options") >= 0) program.helpInformation = function() {
|
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js("compress", true));
|
||||||
var text = [];
|
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js("mangle", true));
|
||||||
var options = UglifyJS.default_options();
|
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js("mangle-props", true));
|
||||||
for (var option in options) {
|
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js("beautify", true));
|
||||||
text.push("--" + (option == "output" ? "beautify" : option == "sourceMap" ? "source-map" : option) + " options:");
|
|
||||||
text.push(format_object(options[option]));
|
|
||||||
text.push("");
|
|
||||||
}
|
|
||||||
return text.join("\n");
|
|
||||||
};
|
|
||||||
program.option("-p, --parse <options>", "Specify parser options.", parse_js());
|
|
||||||
program.option("-c, --compress [options]", "Enable compressor/specify compressor options.", parse_js());
|
|
||||||
program.option("-m, --mangle [options]", "Mangle names/specify mangler options.", parse_js());
|
|
||||||
program.option("--mangle-props [options]", "Mangle properties/specify mangler options.", parse_js());
|
|
||||||
program.option("-b, --beautify [options]", "Beautify output/specify output options.", parse_js());
|
|
||||||
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||||
@@ -47,10 +36,9 @@ program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("d
|
|||||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||||
program.option("--no-rename", "Disable symbol expansion.");
|
|
||||||
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
program.option("--self", "Build UglifyJS as a library (implies --wrap UglifyJS)");
|
||||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_source_map());
|
||||||
program.option("--timings", "Display operations run time on STDERR.")
|
program.option("--stats", "Display operations run time on STDERR.")
|
||||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||||
program.option("--verbose", "Print diagnostic messages.");
|
program.option("--verbose", "Print diagnostic messages.");
|
||||||
program.option("--warn", "Print warning messages.");
|
program.option("--warn", "Print warning messages.");
|
||||||
@@ -66,13 +54,11 @@ if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
|||||||
"compress",
|
"compress",
|
||||||
"ie8",
|
"ie8",
|
||||||
"mangle",
|
"mangle",
|
||||||
"rename",
|
|
||||||
"sourceMap",
|
"sourceMap",
|
||||||
"toplevel",
|
"toplevel",
|
||||||
"wrap"
|
"wrap"
|
||||||
].forEach(function(name) {
|
].forEach(function(name) {
|
||||||
if (name in program) {
|
if (name in program) {
|
||||||
if (name == "rename" && program[name]) return;
|
|
||||||
options[name] = program[name];
|
options[name] = program[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -109,8 +95,17 @@ if (program.mangleProps) {
|
|||||||
if (typeof options.mangle != "object") options.mangle = {};
|
if (typeof options.mangle != "object") options.mangle = {};
|
||||||
options.mangle.properties = program.mangleProps;
|
options.mangle.properties = program.mangleProps;
|
||||||
}
|
}
|
||||||
|
var cache;
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
options.nameCache = JSON.parse(read_file(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") {
|
if (program.output == "ast") {
|
||||||
options.output = {
|
options.output = {
|
||||||
@@ -119,10 +114,10 @@ if (program.output == "ast") {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (program.parse) {
|
if (program.parse) {
|
||||||
if (!program.parse.acorn && !program.parse.spidermonkey) {
|
if (program.parse.acorn || program.parse.spidermonkey) {
|
||||||
|
if (program.sourceMap) fatal("ERROR: inline source map only works with built-in parser");
|
||||||
|
} else {
|
||||||
options.parse = program.parse;
|
options.parse = program.parse;
|
||||||
} else if (program.sourceMap && program.sourceMap.content == "inline") {
|
|
||||||
fatal("ERROR: inline source map only works with built-in parser");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var convert_path = function(name) {
|
var convert_path = function(name) {
|
||||||
@@ -144,7 +139,7 @@ if (program.verbose) {
|
|||||||
}
|
}
|
||||||
if (program.self) {
|
if (program.self) {
|
||||||
if (program.args.length) {
|
if (program.args.length) {
|
||||||
print_error("WARN: Ignoring input files since --self was passed");
|
console.error("WARN: Ignoring input files since --self was passed");
|
||||||
}
|
}
|
||||||
if (!options.wrap) options.wrap = "UglifyJS";
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
simple_glob(UglifyJS.FILES).forEach(function(name) {
|
||||||
@@ -174,9 +169,9 @@ function convert_ast(fn) {
|
|||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||||
print_error("WARN: " + msg);
|
console.error("WARN:", msg);
|
||||||
};
|
};
|
||||||
if (program.timings) options.timings = true;
|
if (program.stats) program.stats = Date.now();
|
||||||
try {
|
try {
|
||||||
if (program.parse) {
|
if (program.parse) {
|
||||||
if (program.parse.acorn) {
|
if (program.parse.acorn) {
|
||||||
@@ -203,7 +198,7 @@ function run() {
|
|||||||
if (result.error) {
|
if (result.error) {
|
||||||
var ex = result.error;
|
var ex = result.error;
|
||||||
if (ex.name == "SyntaxError") {
|
if (ex.name == "SyntaxError") {
|
||||||
print_error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
console.error("Parse error at " + ex.filename + ":" + ex.line + "," + ex.col);
|
||||||
var col = ex.col;
|
var col = ex.col;
|
||||||
var lines = files[ex.filename].split(/\r?\n/);
|
var lines = files[ex.filename].split(/\r?\n/);
|
||||||
var line = lines[ex.line - 1];
|
var line = lines[ex.line - 1];
|
||||||
@@ -212,22 +207,21 @@ function run() {
|
|||||||
col = line.length;
|
col = line.length;
|
||||||
}
|
}
|
||||||
if (line) {
|
if (line) {
|
||||||
var limit = 70;
|
if (col > 40) {
|
||||||
if (col > limit) {
|
line = line.slice(col - 40);
|
||||||
line = line.slice(col - limit);
|
col = 40;
|
||||||
col = limit;
|
|
||||||
}
|
}
|
||||||
print_error(line.slice(0, 80));
|
console.error(line.slice(0, 80));
|
||||||
print_error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
console.error(line.slice(0, col).replace(/\S/g, " ") + "^");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ex.defs) {
|
if (ex.defs) {
|
||||||
print_error("Supported options:");
|
console.error("Supported options:");
|
||||||
print_error(format_object(ex.defs));
|
console.error(ex.defs);
|
||||||
}
|
}
|
||||||
fatal(ex);
|
fatal(ex);
|
||||||
} else if (program.output == "ast") {
|
} else if (program.output == "ast") {
|
||||||
print(JSON.stringify(result.ast, function(key, value) {
|
console.log(JSON.stringify(result.ast, function(key, value) {
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
if (value instanceof UglifyJS.Dictionary) return;
|
if (value instanceof UglifyJS.Dictionary) return;
|
||||||
@@ -243,7 +237,7 @@ function run() {
|
|||||||
return value;
|
return value;
|
||||||
}, 2));
|
}, 2));
|
||||||
} else if (program.output == "spidermonkey") {
|
} else if (program.output == "spidermonkey") {
|
||||||
print(JSON.stringify(UglifyJS.minify(result.code, {
|
console.log(JSON.stringify(UglifyJS.minify(result.code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
@@ -257,19 +251,19 @@ function run() {
|
|||||||
fs.writeFileSync(program.output + ".map", result.map);
|
fs.writeFileSync(program.output + ".map", result.map);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print(result.code);
|
console.log(result.code);
|
||||||
}
|
}
|
||||||
if (program.nameCache) {
|
if (program.nameCache) {
|
||||||
fs.writeFileSync(program.nameCache, JSON.stringify(options.nameCache));
|
fs.writeFileSync(program.nameCache, JSON.stringify(cache, function(key, value) {
|
||||||
}
|
return value instanceof UglifyJS.Dictionary ? value.toObject() : value;
|
||||||
if (result.timings) for (var phase in result.timings) {
|
}));
|
||||||
print_error("- " + phase + ": " + result.timings[phase].toFixed(3) + "s");
|
|
||||||
}
|
}
|
||||||
|
if (program.stats) console.error("Elapsed:", Date.now() - program.stats);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fatal(message) {
|
function fatal(message) {
|
||||||
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
if (message instanceof Error) message = message.stack.replace(/^\S*?Error:/, "ERROR:")
|
||||||
print_error(message);
|
console.error(message);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,7 +307,7 @@ function read_file(path, default_value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_js(flag) {
|
function parse_js(flag, constants) {
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
try {
|
try {
|
||||||
@@ -331,7 +325,7 @@ function parse_js(flag) {
|
|||||||
if (node instanceof UglifyJS.AST_Assign) {
|
if (node instanceof UglifyJS.AST_Assign) {
|
||||||
var name = node.left.print_to_string();
|
var name = node.left.print_to_string();
|
||||||
var value = node.right;
|
var value = node.right;
|
||||||
if (flag) {
|
if (!constants) {
|
||||||
options[name] = value;
|
options[name] = value;
|
||||||
} else if (value instanceof UglifyJS.AST_Array) {
|
} else if (value instanceof UglifyJS.AST_Array) {
|
||||||
options[name] = value.elements.map(to_string);
|
options[name] = value.elements.map(to_string);
|
||||||
@@ -354,51 +348,37 @@ function parse_js(flag) {
|
|||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
} catch(ex) {
|
} catch(ex) {
|
||||||
if (flag) {
|
fatal("Error parsing arguments for '" + flag + "': " + value);
|
||||||
fatal("Error parsing arguments for '" + flag + "': " + value);
|
|
||||||
} else {
|
|
||||||
options[value] = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function parse_source_map() {
|
function parse_source_map() {
|
||||||
var parse = parse_js();
|
var parse = parse_js("sourceMap", true);
|
||||||
return function(value, options) {
|
return function(value, options) {
|
||||||
var hasContent = options && "content" in options;
|
var hasContent = options && options.sourceMap && "content" in options.sourceMap;
|
||||||
var settings = parse(value, options);
|
var settings = parse(value, options);
|
||||||
if (!hasContent && settings.content && settings.content != "inline") {
|
if (!hasContent && settings.content && settings.content != "inline") {
|
||||||
print_error("INFO: Using input source map: " + settings.content);
|
console.error("INFO: Using input source map:", settings.content);
|
||||||
settings.content = read_file(settings.content, settings.content);
|
settings.content = read_file(settings.content, settings.content);
|
||||||
}
|
}
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function to_cache(key) {
|
||||||
|
if (cache[key]) {
|
||||||
|
cache[key].props = UglifyJS.Dictionary.fromObject(cache[key].props);
|
||||||
|
} else {
|
||||||
|
cache[key] = {
|
||||||
|
cname: -1,
|
||||||
|
props: new UglifyJS.Dictionary()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return cache[key];
|
||||||
|
}
|
||||||
|
|
||||||
function skip_key(key) {
|
function skip_key(key) {
|
||||||
return skip_keys.indexOf(key) >= 0;
|
return skip_keys.indexOf(key) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function format_object(obj) {
|
|
||||||
var lines = [];
|
|
||||||
var padding = "";
|
|
||||||
Object.keys(obj).map(function(name) {
|
|
||||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
|
||||||
return [ name, JSON.stringify(obj[name]) ];
|
|
||||||
}).forEach(function(tokens) {
|
|
||||||
lines.push(" " + tokens[0] + padding.slice(tokens[0].length - 2) + tokens[1]);
|
|
||||||
});
|
|
||||||
return lines.join("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function print_error(msg) {
|
|
||||||
process.stderr.write(msg);
|
|
||||||
process.stderr.write("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
function print(txt) {
|
|
||||||
process.stdout.write(txt);
|
|
||||||
process.stdout.write("\n");
|
|
||||||
}
|
|
||||||
|
|||||||
420
lib/ast.js
420
lib/ast.js
@@ -134,10 +134,11 @@ var AST_Debugger = DEFNODE("Debugger", null, {
|
|||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value quote", {
|
var AST_Directive = DEFNODE("Directive", "value scope quote", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";",
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
|
scope: "[AST_Scope/S] The scope that this directive affects",
|
||||||
quote: "[string] the original quote character"
|
quote: "[string] the original quote character"
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -156,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++) {
|
||||||
@@ -283,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: {
|
||||||
@@ -298,9 +303,10 @@ var AST_With = DEFNODE("With", "expression", {
|
|||||||
|
|
||||||
/* -----[ scope and functions ]----- */
|
/* -----[ scope and functions ]----- */
|
||||||
|
|
||||||
var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent_scope enclosed cname", {
|
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
|
||||||
$documentation: "Base class for all statements introducing a lexical scope",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
directives: "[string*/S] an array of directives declared in this scope",
|
||||||
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
variables: "[Object/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
||||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
functions: "[Object/S] like `variables`, but only lists function declarations",
|
||||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||||
@@ -309,6 +315,13 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
|||||||
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", {
|
||||||
@@ -329,13 +342,111 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
|||||||
}
|
}
|
||||||
}, 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);
|
||||||
@@ -352,14 +463,82 @@ var AST_Accessor = DEFNODE("Accessor", null, {
|
|||||||
$documentation: "A setter/getter function. The `name` property is always null."
|
$documentation: "A setter/getter function. The `name` property is always null."
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", "inlined", {
|
var AST_Function = DEFNODE("Function", null, {
|
||||||
$documentation: "A function expression"
|
$documentation: "A function expression"
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", "inlined", {
|
var AST_Arrow = DEFNODE("Arrow", null, {
|
||||||
|
$documentation: "An ES6 Arrow function ((a) => b)"
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
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, {
|
||||||
@@ -479,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(){
|
||||||
@@ -493,10 +672,10 @@ var AST_Finally = DEFNODE("Finally", null, {
|
|||||||
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
$documentation: "A `finally` node; only makes sense as part of a `try` statement"
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
/* -----[ VAR ]----- */
|
/* -----[ VAR/CONST ]----- */
|
||||||
|
|
||||||
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||||
$documentation: "Base class for `var` nodes (variable declarations/initializations)",
|
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
definitions: "[AST_VarDef*] array of variable definitions"
|
definitions: "[AST_VarDef*] array of variable definitions"
|
||||||
},
|
},
|
||||||
@@ -514,10 +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, {
|
||||||
|
$documentation: "A `const` statement"
|
||||||
|
}, 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] 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) {
|
||||||
@@ -648,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", {
|
||||||
@@ -683,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 AST_SymbolAccessor.",
|
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_Accessor."
|
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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -700,35 +950,94 @@ 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, function name or argument, symbol in catch)",
|
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||||
$documentation: "Symbol defining a variable",
|
$documentation: "Symbol defining a variable",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolBlockDeclaration = DEFNODE("SymbolBlockDeclaration", null, {
|
||||||
|
$documentation: "Base class for block-scoped declaration symbols"
|
||||||
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||||
|
$documentation: "A constant declaration"
|
||||||
|
}, 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",
|
||||||
}, AST_SymbolVar);
|
}, AST_SymbolVar);
|
||||||
@@ -737,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)",
|
||||||
@@ -768,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() {
|
||||||
@@ -841,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) {
|
||||||
@@ -857,7 +1205,7 @@ TreeWalker.prototype = {
|
|||||||
if (!ret && descend) {
|
if (!ret && descend) {
|
||||||
descend.call(node);
|
descend.call(node);
|
||||||
}
|
}
|
||||||
this.pop();
|
this.pop(node);
|
||||||
return ret;
|
return ret;
|
||||||
},
|
},
|
||||||
parent: function(n) {
|
parent: function(n) {
|
||||||
@@ -868,11 +1216,17 @@ TreeWalker.prototype = {
|
|||||||
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() {
|
pop: function(node) {
|
||||||
if (this.stack.pop() instanceof AST_Lambda) {
|
this.stack.pop();
|
||||||
|
if (node instanceof AST_Lambda || node instanceof AST_Class) {
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -890,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;
|
||||||
@@ -898,6 +1252,24 @@ TreeWalker.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
in_boolean_context: function() {
|
||||||
|
var stack = this.stack;
|
||||||
|
var i = stack.length, self = stack[--i];
|
||||||
|
while (i > 0) {
|
||||||
|
var p = stack[--i];
|
||||||
|
if ((p instanceof AST_If && p.condition === self) ||
|
||||||
|
(p instanceof AST_Conditional && p.condition === self) ||
|
||||||
|
(p instanceof AST_DWLoop && p.condition === self) ||
|
||||||
|
(p instanceof AST_For && p.condition === self) ||
|
||||||
|
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")))
|
||||||
|
return false;
|
||||||
|
self = p;
|
||||||
|
}
|
||||||
|
},
|
||||||
loopcontrol_target: function(node) {
|
loopcontrol_target: function(node) {
|
||||||
var stack = this.stack;
|
var stack = this.stack;
|
||||||
if (node.label) for (var i = stack.length; --i >= 0;) {
|
if (node.label) for (var i = stack.length; --i >= 0;) {
|
||||||
|
|||||||
3006
lib/compress.js
3006
lib/compress.js
File diff suppressed because it is too large
Load Diff
100
lib/minify.js
100
lib/minify.js
@@ -27,77 +27,40 @@ function set_shorthand(name, options, keys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function init_cache(cache) {
|
|
||||||
if (!cache) return;
|
|
||||||
if (!("cname" in cache)) cache.cname = -1;
|
|
||||||
if (!("props" in cache)) {
|
|
||||||
cache.props = new Dictionary();
|
|
||||||
} else if (!(cache.props instanceof Dictionary)) {
|
|
||||||
cache.props = Dictionary.fromObject(cache.props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function to_json(cache) {
|
|
||||||
return {
|
|
||||||
cname: cache.cname,
|
|
||||||
props: cache.props.toObject()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function minify(files, options) {
|
function minify(files, options) {
|
||||||
var warn_function = AST_Node.warn_function;
|
var warn_function = AST_Node.warn_function;
|
||||||
try {
|
try {
|
||||||
|
if (typeof files == "string") {
|
||||||
|
files = [ files ];
|
||||||
|
}
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
compress: {},
|
compress: {},
|
||||||
ie8: false,
|
ie8: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
mangle: {},
|
mangle: {},
|
||||||
nameCache: null,
|
|
||||||
output: {},
|
output: {},
|
||||||
parse: {},
|
parse: {},
|
||||||
rename: undefined,
|
|
||||||
sourceMap: false,
|
sourceMap: false,
|
||||||
timings: false,
|
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
warnings: false,
|
warnings: false,
|
||||||
wrap: false,
|
wrap: false,
|
||||||
}, true);
|
}, true);
|
||||||
var timings = options.timings && {
|
|
||||||
start: Date.now()
|
|
||||||
};
|
|
||||||
if (options.rename === undefined) {
|
|
||||||
options.rename = options.compress && options.mangle;
|
|
||||||
}
|
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("warnings", options, [ "compress" ]);
|
set_shorthand("warnings", options, [ "compress" ]);
|
||||||
var quoted_props;
|
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
cache: null,
|
||||||
eval: false,
|
eval: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
|
keep_classnames: false,
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
properties: false,
|
properties: false,
|
||||||
reserved: [],
|
reserved: [],
|
||||||
|
safari10: false,
|
||||||
toplevel: false,
|
toplevel: false,
|
||||||
}, true);
|
}, true);
|
||||||
if (options.mangle.properties) {
|
|
||||||
if (typeof options.mangle.properties != "object") {
|
|
||||||
options.mangle.properties = {};
|
|
||||||
}
|
|
||||||
if (options.mangle.properties.keep_quoted) {
|
|
||||||
quoted_props = options.mangle.properties.reserved;
|
|
||||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
|
||||||
options.mangle.properties.reserved = quoted_props;
|
|
||||||
}
|
|
||||||
if (options.nameCache && !("cache" in options.mangle.properties)) {
|
|
||||||
options.mangle.properties.cache = options.nameCache.props || {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
init_cache(options.mangle.cache);
|
|
||||||
init_cache(options.mangle.properties.cache);
|
|
||||||
}
|
}
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
options.sourceMap = defaults(options.sourceMap, {
|
options.sourceMap = defaults(options.sourceMap, {
|
||||||
@@ -114,17 +77,13 @@ function minify(files, options) {
|
|||||||
warnings.push(warning);
|
warnings.push(warning);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (timings) timings.parse = Date.now();
|
|
||||||
var toplevel;
|
var toplevel;
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
toplevel = files;
|
toplevel = files;
|
||||||
} else {
|
} else {
|
||||||
if (typeof files == "string") {
|
|
||||||
files = [ files ];
|
|
||||||
}
|
|
||||||
options.parse = options.parse || {};
|
options.parse = options.parse || {};
|
||||||
options.parse.toplevel = null;
|
options.parse.toplevel = null;
|
||||||
for (var name in files) if (HOP(files, name)) {
|
for (var name in files) {
|
||||||
options.parse.filename = name;
|
options.parse.filename = name;
|
||||||
options.parse.toplevel = parse(files[name], options.parse);
|
options.parse.toplevel = parse(files[name], options.parse);
|
||||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
@@ -135,32 +94,22 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
toplevel = options.parse.toplevel;
|
toplevel = options.parse.toplevel;
|
||||||
}
|
}
|
||||||
if (quoted_props) {
|
|
||||||
reserve_quoted_keys(toplevel, quoted_props);
|
|
||||||
}
|
|
||||||
if (options.wrap) {
|
if (options.wrap) {
|
||||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||||
}
|
}
|
||||||
if (timings) timings.rename = Date.now();
|
if (options.compress) {
|
||||||
if (options.rename) {
|
|
||||||
toplevel.figure_out_scope(options.mangle);
|
toplevel.figure_out_scope(options.mangle);
|
||||||
toplevel.expand_names(options.mangle);
|
toplevel = new Compressor(options.compress).compress(toplevel);
|
||||||
}
|
}
|
||||||
if (timings) timings.compress = Date.now();
|
|
||||||
if (options.compress) toplevel = new Compressor(options.compress).compress(toplevel);
|
|
||||||
if (timings) timings.scope = Date.now();
|
|
||||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
|
||||||
if (timings) timings.mangle = Date.now();
|
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
|
toplevel.figure_out_scope(options.mangle);
|
||||||
base54.reset();
|
base54.reset();
|
||||||
toplevel.compute_char_frequency(options.mangle);
|
toplevel.compute_char_frequency(options.mangle);
|
||||||
toplevel.mangle_names(options.mangle);
|
toplevel.mangle_names(options.mangle);
|
||||||
|
if (options.mangle.properties) {
|
||||||
|
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (timings) timings.properties = Date.now();
|
|
||||||
if (options.mangle && options.mangle.properties) {
|
|
||||||
toplevel = mangle_properties(toplevel, options.mangle.properties);
|
|
||||||
}
|
|
||||||
if (timings) timings.output = Date.now();
|
|
||||||
var result = {};
|
var result = {};
|
||||||
if (options.output.ast) {
|
if (options.output.ast) {
|
||||||
result.ast = toplevel;
|
result.ast = toplevel;
|
||||||
@@ -176,9 +125,7 @@ function minify(files, options) {
|
|||||||
root: options.sourceMap.root
|
root: options.sourceMap.root
|
||||||
});
|
});
|
||||||
if (options.sourceMap.includeSources) {
|
if (options.sourceMap.includeSources) {
|
||||||
if (files instanceof AST_Toplevel) {
|
for (var name in files) {
|
||||||
throw new Error("original source content unavailable");
|
|
||||||
} else for (var name in files) if (HOP(files, name)) {
|
|
||||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,25 +144,6 @@ function minify(files, options) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (options.nameCache && options.mangle) {
|
|
||||||
if (options.mangle.cache) options.nameCache.vars = to_json(options.mangle.cache);
|
|
||||||
if (options.mangle.properties && options.mangle.properties.cache) {
|
|
||||||
options.nameCache.props = to_json(options.mangle.properties.cache);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (timings) {
|
|
||||||
timings.end = Date.now();
|
|
||||||
result.timings = {
|
|
||||||
parse: 1e-3 * (timings.rename - timings.parse),
|
|
||||||
rename: 1e-3 * (timings.compress - timings.rename),
|
|
||||||
compress: 1e-3 * (timings.scope - timings.compress),
|
|
||||||
scope: 1e-3 * (timings.mangle - timings.scope),
|
|
||||||
mangle: 1e-3 * (timings.properties - timings.mangle),
|
|
||||||
properties: 1e-3 * (timings.output - timings.properties),
|
|
||||||
output: 1e-3 * (timings.end - timings.output),
|
|
||||||
total: 1e-3 * (timings.end - timings.start)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (warnings.length) {
|
if (warnings.length) {
|
||||||
result.warnings = warnings;
|
result.warnings = warnings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,7 +118,7 @@
|
|||||||
value : from_moz(M.value)
|
value : from_moz(M.value)
|
||||||
};
|
};
|
||||||
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
if (M.kind == "init") return new AST_ObjectKeyVal(args);
|
||||||
args.key = new AST_SymbolAccessor({
|
args.key = new AST_SymbolMethod({
|
||||||
name: args.key
|
name: args.key
|
||||||
});
|
});
|
||||||
args.value = new AST_Accessor(args.value);
|
args.value = new AST_Accessor(args.value);
|
||||||
@@ -168,7 +168,7 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
VariableDeclaration: function(M) {
|
VariableDeclaration: function(M) {
|
||||||
return new AST_Var({
|
return new (M.kind === "const" ? AST_Const : AST_Var)({
|
||||||
start : my_start_token(M),
|
start : my_start_token(M),
|
||||||
end : my_end_token(M),
|
end : my_end_token(M),
|
||||||
definitions : M.declarations.map(from_moz)
|
definitions : M.declarations.map(from_moz)
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
Identifier: function(M) {
|
Identifier: function(M) {
|
||||||
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
|
||||||
return new ( p.type == "LabeledStatement" ? AST_Label
|
return new ( p.type == "LabeledStatement" ? AST_Label
|
||||||
: p.type == "VariableDeclarator" && p.id === M ? AST_SymbolVar
|
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar)
|
||||||
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg)
|
||||||
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg)
|
||||||
: p.type == "CatchClause" ? AST_SymbolCatch
|
: p.type == "CatchClause" ? AST_SymbolCatch
|
||||||
@@ -324,7 +324,7 @@
|
|||||||
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
def_to_moz(AST_Definitions, function To_Moz_VariableDeclaration(M) {
|
||||||
return {
|
return {
|
||||||
type: "VariableDeclaration",
|
type: "VariableDeclaration",
|
||||||
kind: "var",
|
kind: M instanceof AST_Const ? "const" : "var",
|
||||||
declarations: M.definitions.map(to_moz)
|
declarations: M.definitions.map(to_moz)
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -381,7 +381,7 @@
|
|||||||
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
def_to_moz(AST_ObjectProperty, function To_Moz_Property(M) {
|
||||||
var key = {
|
var key = {
|
||||||
type: "Literal",
|
type: "Literal",
|
||||||
value: M.key instanceof AST_SymbolAccessor ? M.key.name : M.key
|
value: M.key instanceof AST_SymbolMethod ? M.key.name : M.key
|
||||||
};
|
};
|
||||||
var kind;
|
var kind;
|
||||||
if (M instanceof AST_ObjectKeyVal) {
|
if (M instanceof AST_ObjectKeyVal) {
|
||||||
|
|||||||
645
lib/output.js
645
lib/output.js
@@ -54,9 +54,11 @@ 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,
|
ie8 : false,
|
||||||
indent_level : 4,
|
indent_level : 4,
|
||||||
indent_start : 0,
|
indent_start : 0,
|
||||||
@@ -69,12 +71,20 @@ function OutputStream(options) {
|
|||||||
quote_style : 0,
|
quote_style : 0,
|
||||||
semicolons : true,
|
semicolons : true,
|
||||||
shebang : true,
|
shebang : true,
|
||||||
|
shorthand : undefined,
|
||||||
source_map : null,
|
source_map : null,
|
||||||
webkit : false,
|
space_colon : true,
|
||||||
|
unescape_regexps : false,
|
||||||
width : 80,
|
width : 80,
|
||||||
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) {
|
||||||
@@ -109,10 +119,20 @@ function OutputStream(options) {
|
|||||||
var current_pos = 0;
|
var current_pos = 0;
|
||||||
var OUTPUT = "";
|
var OUTPUT = "";
|
||||||
|
|
||||||
var to_utf8 = options.ascii_only ? function(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 {
|
||||||
@@ -120,12 +140,6 @@ function OutputStream(options) {
|
|||||||
return "\\u" + code;
|
return "\\u" + code;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} : function(str) {
|
|
||||||
return str.replace(/[\ud800-\udbff](?![\udc00-\udfff])/g, function(ch) {
|
|
||||||
return "\\u" + ch.charCodeAt(0).toString(16);
|
|
||||||
}).replace(/(^|[^\ud800-\udbff])([\udc00-\udfff])/g, function(match, prefix, ch) {
|
|
||||||
return prefix + "\\u" + ch.charCodeAt(0).toString(16);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function make_string(str, quote) {
|
function make_string(str, quote) {
|
||||||
@@ -146,7 +160,7 @@ function OutputStream(options) {
|
|||||||
case "\u2029": return "\\u2029";
|
case "\u2029": return "\\u2029";
|
||||||
case "\ufeff": return "\\ufeff";
|
case "\ufeff": return "\\ufeff";
|
||||||
case "\0":
|
case "\0":
|
||||||
return /[0-9]/.test(str.charAt(i+1)) ? "\\x00" : "\\0";
|
return /[0-7]/.test(get_full_char(str, i+1)) ? "\\x00" : "\\0";
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
});
|
});
|
||||||
@@ -156,7 +170,11 @@ function OutputStream(options) {
|
|||||||
function quote_double() {
|
function quote_double() {
|
||||||
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
return '"' + str.replace(/\x22/g, '\\"') + '"';
|
||||||
}
|
}
|
||||||
str = to_utf8(str);
|
function quote_template() {
|
||||||
|
return '`' + str.replace(/`/g, '\\`') + '`';
|
||||||
|
}
|
||||||
|
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();
|
||||||
@@ -181,7 +199,8 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function make_name(name) {
|
function make_name(name) {
|
||||||
name = name.toString();
|
name = name.toString();
|
||||||
name = to_utf8(name, true);
|
if (options.ascii_identifiers)
|
||||||
|
name = to_ascii(name, true);
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -195,43 +214,12 @@ function OutputStream(options) {
|
|||||||
var might_need_semicolon = false;
|
var might_need_semicolon = false;
|
||||||
var might_add_newline = 0;
|
var might_add_newline = 0;
|
||||||
var last = "";
|
var last = "";
|
||||||
var mapping_token, mapping_name, mappings = options.source_map && [];
|
|
||||||
|
|
||||||
var do_add_mapping = mappings ? function() {
|
|
||||||
mappings.forEach(function(mapping) {
|
|
||||||
try {
|
|
||||||
options.source_map.add(
|
|
||||||
mapping.token.file,
|
|
||||||
mapping.line, mapping.col,
|
|
||||||
mapping.token.line, mapping.token.col,
|
|
||||||
!mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name
|
|
||||||
);
|
|
||||||
} catch(ex) {
|
|
||||||
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
|
||||||
file: mapping.token.file,
|
|
||||||
line: mapping.token.line,
|
|
||||||
col: mapping.token.col,
|
|
||||||
cline: mapping.line,
|
|
||||||
ccol: mapping.col,
|
|
||||||
name: mapping.name || ""
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mappings = [];
|
|
||||||
} : noop;
|
|
||||||
|
|
||||||
var ensure_line_len = options.max_line_len ? function() {
|
var ensure_line_len = options.max_line_len ? function() {
|
||||||
if (current_col > options.max_line_len) {
|
if (current_col > options.max_line_len) {
|
||||||
if (might_add_newline) {
|
if (might_add_newline) {
|
||||||
var left = OUTPUT.slice(0, might_add_newline);
|
var left = OUTPUT.slice(0, might_add_newline);
|
||||||
var right = OUTPUT.slice(might_add_newline);
|
var right = OUTPUT.slice(might_add_newline);
|
||||||
if (mappings) {
|
|
||||||
var delta = right.length - current_col;
|
|
||||||
mappings.forEach(function(mapping) {
|
|
||||||
mapping.line++;
|
|
||||||
mapping.col += delta;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
OUTPUT = left + "\n" + right;
|
OUTPUT = left + "\n" + right;
|
||||||
current_line++;
|
current_line++;
|
||||||
current_pos++;
|
current_pos++;
|
||||||
@@ -241,18 +229,15 @@ function OutputStream(options) {
|
|||||||
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (might_add_newline) {
|
might_add_newline = 0;
|
||||||
might_add_newline = 0;
|
|
||||||
do_add_mapping();
|
|
||||||
}
|
|
||||||
} : noop;
|
} : noop;
|
||||||
|
|
||||||
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
||||||
|
|
||||||
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 = last.charAt(last.length - 1);
|
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;
|
||||||
|
|
||||||
@@ -304,18 +289,6 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
might_need_space = false;
|
might_need_space = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mapping_token) {
|
|
||||||
mappings.push({
|
|
||||||
token: mapping_token,
|
|
||||||
name: mapping_name,
|
|
||||||
line: current_line,
|
|
||||||
col: current_col
|
|
||||||
});
|
|
||||||
mapping_token = false;
|
|
||||||
if (!might_add_newline) do_add_mapping();
|
|
||||||
}
|
|
||||||
|
|
||||||
OUTPUT += str;
|
OUTPUT += str;
|
||||||
current_pos += str.length;
|
current_pos += str.length;
|
||||||
var a = str.split(/\r?\n/), n = a.length - 1;
|
var a = str.split(/\r?\n/), n = a.length - 1;
|
||||||
@@ -328,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() {
|
||||||
@@ -407,12 +384,27 @@ function OutputStream(options) {
|
|||||||
|
|
||||||
function colon() {
|
function colon() {
|
||||||
print(":");
|
print(":");
|
||||||
space();
|
if (options.space_colon) space();
|
||||||
};
|
};
|
||||||
|
|
||||||
var add_mapping = mappings ? function(token, name) {
|
var add_mapping = options.source_map ? function(token, name) {
|
||||||
mapping_token = token;
|
try {
|
||||||
mapping_name = name;
|
if (token) options.source_map.add(
|
||||||
|
token.file || "?",
|
||||||
|
current_line, current_col,
|
||||||
|
token.line, token.col,
|
||||||
|
(!name && token.type == "name") ? token.value : name
|
||||||
|
);
|
||||||
|
} catch(ex) {
|
||||||
|
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
|
||||||
|
file: token.file,
|
||||||
|
line: token.line,
|
||||||
|
col: token.col,
|
||||||
|
cline: current_line,
|
||||||
|
ccol: current_col,
|
||||||
|
name: name || ""
|
||||||
|
})
|
||||||
|
}
|
||||||
} : noop;
|
} : noop;
|
||||||
|
|
||||||
function get() {
|
function get() {
|
||||||
@@ -432,13 +424,14 @@ 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,
|
||||||
last : function() { return last },
|
last : function() { return last },
|
||||||
semicolon : semicolon,
|
semicolon : semicolon,
|
||||||
force_semicolon : force_semicolon,
|
force_semicolon : force_semicolon,
|
||||||
to_utf8 : to_utf8,
|
to_ascii : to_ascii,
|
||||||
print_name : function(name) { print(make_name(name)) },
|
print_name : function(name) { print(make_name(name)) },
|
||||||
print_string : function(str, quote, escape_directive) {
|
print_string : function(str, quote, escape_directive) {
|
||||||
var encoded = encode_string(str, quote);
|
var encoded = encode_string(str, quote);
|
||||||
@@ -451,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,
|
||||||
@@ -482,17 +479,13 @@ function OutputStream(options) {
|
|||||||
nodetype.DEFMETHOD("_codegen", generator);
|
nodetype.DEFMETHOD("_codegen", generator);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var use_asm = false;
|
||||||
var in_directive = false;
|
var in_directive = false;
|
||||||
var active_scope = null;
|
|
||||||
var use_asm = null;
|
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
AST_Node.DEFMETHOD("print", function(stream, force_parens){
|
||||||
var self = this, generator = self._codegen;
|
var self = this, generator = self._codegen, prev_use_asm = use_asm;
|
||||||
if (self instanceof AST_Scope) {
|
if (self instanceof AST_Directive && self.value == "use asm" && stream.parent() instanceof AST_Scope) {
|
||||||
active_scope = self;
|
use_asm = true;
|
||||||
}
|
|
||||||
else if (!use_asm && self instanceof AST_Directive && self.value == "use asm") {
|
|
||||||
use_asm = active_scope;
|
|
||||||
}
|
}
|
||||||
function doit() {
|
function doit() {
|
||||||
self.add_comments(stream);
|
self.add_comments(stream);
|
||||||
@@ -506,11 +499,10 @@ function OutputStream(options) {
|
|||||||
doit();
|
doit();
|
||||||
}
|
}
|
||||||
stream.pop_node();
|
stream.pop_node();
|
||||||
if (self === use_asm) {
|
if (self instanceof AST_Scope) {
|
||||||
use_asm = null;
|
use_asm = prev_use_asm;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
AST_Node.DEFMETHOD("_print", AST_Node.prototype.print);
|
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("print_to_string", function(options){
|
AST_Node.DEFMETHOD("print_to_string", function(options){
|
||||||
var s = OutputStream(options);
|
var s = OutputStream(options);
|
||||||
@@ -608,13 +600,6 @@ function OutputStream(options) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output.option('webkit')) {
|
|
||||||
var p = output.parent();
|
|
||||||
if (p instanceof AST_PropAccess && p.expression === this) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output.option('wrap_iife')) {
|
if (output.option('wrap_iife')) {
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
return p instanceof AST_Call && p.expression === this;
|
return p instanceof AST_Call && p.expression === this;
|
||||||
@@ -623,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){
|
||||||
@@ -632,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_Sequence, 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) {}
|
||||||
;
|
;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -672,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,15 +698,14 @@ function OutputStream(options) {
|
|||||||
// parens around it too, otherwise the call will be
|
// parens around it too, otherwise the call will be
|
||||||
// interpreted as passing the arguments to the upper New
|
// interpreted as passing the arguments to the upper New
|
||||||
// expression.
|
// expression.
|
||||||
var parens = false;
|
try {
|
||||||
this.walk(new TreeWalker(function(node) {
|
this.walk(new TreeWalker(function(node){
|
||||||
if (parens || node instanceof AST_Scope) return true;
|
if (node instanceof AST_Call) throw p;
|
||||||
if (node instanceof AST_Call) {
|
}));
|
||||||
parens = true;
|
} catch(ex) {
|
||||||
return true;
|
if (ex !== p) throw ex;
|
||||||
}
|
return true;
|
||||||
}));
|
}
|
||||||
return parens;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -742,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 ]----- */
|
||||||
@@ -750,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();
|
||||||
@@ -874,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);
|
||||||
});
|
});
|
||||||
@@ -896,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){
|
||||||
@@ -914,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);
|
||||||
@@ -930,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);
|
||||||
@@ -1078,22 +1193,122 @@ 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){
|
||||||
|
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) {
|
||||||
var parens = false;
|
if (!noin) node.print(output);
|
||||||
// need to take some precautions here:
|
else try {
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/60
|
// need to take some precautions here:
|
||||||
if (noin) node.walk(new TreeWalker(function(node) {
|
// https://github.com/mishoo/UglifyJS2/issues/60
|
||||||
if (parens || node instanceof AST_Scope) return true;
|
node.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_Binary && node.operator == "in") {
|
if (node instanceof AST_Binary && node.operator == "in")
|
||||||
parens = true;
|
throw output;
|
||||||
return true;
|
}));
|
||||||
}
|
node.print(output);
|
||||||
}));
|
} catch(ex) {
|
||||||
node.print(output, parens);
|
if (ex !== output) throw ex;
|
||||||
|
node.print(output, true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_VarDef, function(self, output){
|
DEFPRINT(AST_VarDef, function(self, output){
|
||||||
@@ -1113,9 +1328,6 @@ function OutputStream(options) {
|
|||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
if (self instanceof AST_New && !need_constructor_parens(self, output))
|
||||||
return;
|
return;
|
||||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
|
||||||
output.add_mapping(self.start);
|
|
||||||
}
|
|
||||||
output.with_parens(function(){
|
output.with_parens(function(){
|
||||||
self.args.forEach(function(expr, i){
|
self.args.forEach(function(expr, i){
|
||||||
if (i) output.comma();
|
if (i) output.comma();
|
||||||
@@ -1155,23 +1367,15 @@ function OutputStream(options) {
|
|||||||
DEFPRINT(AST_Dot, function(self, output){
|
DEFPRINT(AST_Dot, function(self, output){
|
||||||
var expr = self.expression;
|
var expr = self.expression;
|
||||||
expr.print(output);
|
expr.print(output);
|
||||||
var prop = self.property;
|
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
||||||
if (output.option("ie8") && RESERVED_WORDS(prop)) {
|
if (!/[xa-f.)]/i.test(output.last())) {
|
||||||
output.print("[");
|
output.print(".");
|
||||||
output.add_mapping(self.end);
|
|
||||||
output.print_string(prop);
|
|
||||||
output.print("]");
|
|
||||||
} else {
|
|
||||||
if (expr instanceof AST_Number && expr.getValue() >= 0) {
|
|
||||||
if (!/[xa-f.)]/i.test(output.last())) {
|
|
||||||
output.print(".");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
output.print(".");
|
|
||||||
// the name after dot would be mapped about here.
|
|
||||||
output.add_mapping(self.end);
|
|
||||||
output.print_name(prop);
|
|
||||||
}
|
}
|
||||||
|
output.print(".");
|
||||||
|
// the name after dot would be mapped about here.
|
||||||
|
output.add_mapping(self.end);
|
||||||
|
output.print_name(self.property);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Sub, function(self, output){
|
DEFPRINT(AST_Sub, function(self, output){
|
||||||
self.expression.print(output);
|
self.expression.print(output);
|
||||||
@@ -1262,8 +1466,35 @@ function OutputStream(options) {
|
|||||||
});
|
});
|
||||||
else output.print("{}");
|
else output.print("{}");
|
||||||
});
|
});
|
||||||
|
DEFPRINT(AST_Class, function(self, output){
|
||||||
function print_property_name(key, quote, output) {
|
output.print("class");
|
||||||
|
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"
|
||||||
@@ -1280,33 +1511,98 @@ function OutputStream(options) {
|
|||||||
} else {
|
} else {
|
||||||
output.print_string(key, quote);
|
output.print_string(key, quote);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
DEFPRINT(AST_ObjectKeyVal, function(self, output){
|
|
||||||
print_property_name(self.key, self.quote, output);
|
|
||||||
output.colon();
|
|
||||||
self.value.print(output);
|
|
||||||
});
|
});
|
||||||
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, 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.print(type);
|
||||||
output.space();
|
output.space();
|
||||||
print_property_name(this.key.name, this.quote, output);
|
if (self.key instanceof AST_SymbolMethod) {
|
||||||
this.value._do_print(output, true);
|
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){
|
||||||
self._print_getter_setter("set", output);
|
self._print_getter_setter("set", self, output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_ObjectGetter, function(self, output){
|
DEFPRINT(AST_ObjectGetter, function(self, output){
|
||||||
self._print_getter_setter("get", output);
|
self._print_getter_setter("get", self, output);
|
||||||
});
|
});
|
||||||
DEFPRINT(AST_Symbol, function(self, output){
|
DEFPRINT(AST_ConciseMethod, function(self, output){
|
||||||
var def = self.definition();
|
if (self.static) {
|
||||||
output.print_name(def ? def.mangled_name || def.name : self.name);
|
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);
|
||||||
|
});
|
||||||
|
AST_Symbol.DEFMETHOD("_do_print", function(output){
|
||||||
|
var def = this.definition();
|
||||||
|
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());
|
||||||
});
|
});
|
||||||
@@ -1321,13 +1617,46 @@ function OutputStream(options) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function regexp_safe_literal(code) {
|
||||||
|
return [
|
||||||
|
0x5c , // \
|
||||||
|
0x2f , // /
|
||||||
|
0x2e , // .
|
||||||
|
0x2b , // +
|
||||||
|
0x2a , // *
|
||||||
|
0x3f , // ?
|
||||||
|
0x28 , // (
|
||||||
|
0x29 , // )
|
||||||
|
0x5b , // [
|
||||||
|
0x5d , // ]
|
||||||
|
0x7b , // {
|
||||||
|
0x7d , // }
|
||||||
|
0x24 , // $
|
||||||
|
0x5e , // ^
|
||||||
|
0x3a , // :
|
||||||
|
0x7c , // |
|
||||||
|
0x21 , // !
|
||||||
|
0x0a , // \n
|
||||||
|
0x0d , // \r
|
||||||
|
0x00 , // \0
|
||||||
|
0xfeff , // Unicode BOM
|
||||||
|
0x2028 , // unicode "line separator"
|
||||||
|
0x2029 , // unicode "paragraph separator"
|
||||||
|
].indexOf(code) < 0;
|
||||||
|
};
|
||||||
|
|
||||||
DEFPRINT(AST_RegExp, function(self, output){
|
DEFPRINT(AST_RegExp, function(self, output){
|
||||||
var regexp = self.getValue();
|
var str = self.getValue().toString();
|
||||||
var str = regexp.toString();
|
if (output.option("ascii_only")) {
|
||||||
if (regexp.raw_source) {
|
str = output.to_ascii(str);
|
||||||
str = "/" + regexp.raw_source + str.slice(str.lastIndexOf("/"));
|
} else if (output.option("unescape_regexps")) {
|
||||||
|
str = str.split("\\\\").map(function(str){
|
||||||
|
return str.replace(/\\u[0-9a-fA-F]{4}|\\x[0-9a-fA-F]{2}/g, function(s){
|
||||||
|
var code = parseInt(s.substr(2), 16);
|
||||||
|
return regexp_safe_literal(code) ? String.fromCharCode(code) : s;
|
||||||
|
});
|
||||||
|
}).join("\\\\");
|
||||||
}
|
}
|
||||||
str = output.to_utf8(str);
|
|
||||||
output.print(str);
|
output.print(str);
|
||||||
var p = output.parent();
|
var p = output.parent();
|
||||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self)
|
||||||
|
|||||||
1500
lib/parse.js
1500
lib/parse.js
File diff suppressed because one or more lines are too long
@@ -44,6 +44,16 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function find_builtins(reserved) {
|
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
|
||||||
[
|
[
|
||||||
"null",
|
"null",
|
||||||
@@ -55,7 +65,15 @@ function find_builtins(reserved) {
|
|||||||
].forEach(add);
|
].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) {
|
||||||
@@ -67,34 +85,6 @@ function find_builtins(reserved) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function reserve_quoted_keys(ast, reserved) {
|
|
||||||
function add(name) {
|
|
||||||
push_uniq(reserved, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ast.walk(new TreeWalker(function(node) {
|
|
||||||
if (node instanceof AST_ObjectKeyVal && node.quote) {
|
|
||||||
add(node.key);
|
|
||||||
} else if (node instanceof AST_Sub) {
|
|
||||||
addStrings(node.property, add);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function addStrings(node, add) {
|
|
||||||
node.walk(new TreeWalker(function(node) {
|
|
||||||
if (node instanceof AST_Sequence) {
|
|
||||||
addStrings(node.tail_node(), add);
|
|
||||||
} else if (node instanceof AST_String) {
|
|
||||||
add(node.value);
|
|
||||||
} else if (node instanceof AST_Conditional) {
|
|
||||||
addStrings(node.consequent, add);
|
|
||||||
addStrings(node.alternative, add);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
function mangle_properties(ast, options) {
|
function mangle_properties(ast, options) {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
builtins: false,
|
builtins: false,
|
||||||
@@ -104,10 +94,9 @@ function mangle_properties(ast, options) {
|
|||||||
only_cache: false,
|
only_cache: false,
|
||||||
regex: null,
|
regex: null,
|
||||||
reserved: null,
|
reserved: null,
|
||||||
}, true);
|
});
|
||||||
|
|
||||||
var reserved = options.reserved;
|
var reserved = options.reserved || [];
|
||||||
if (!Array.isArray(reserved)) reserved = [];
|
|
||||||
if (!options.builtins) find_builtins(reserved);
|
if (!options.builtins) find_builtins(reserved);
|
||||||
|
|
||||||
var cache = options.cache;
|
var cache = options.cache;
|
||||||
@@ -119,6 +108,7 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var regex = options.regex;
|
var regex = options.regex;
|
||||||
|
var keep_quoted = options.keep_quoted;
|
||||||
|
|
||||||
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
// note debug is either false (disabled), or a string of the debug suffix to use (enabled).
|
||||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||||
@@ -131,11 +121,12 @@ function mangle_properties(ast, options) {
|
|||||||
|
|
||||||
var names_to_mangle = [];
|
var names_to_mangle = [];
|
||||||
var unmangleable = [];
|
var unmangleable = [];
|
||||||
|
var to_keep = {};
|
||||||
|
|
||||||
// step 1: find candidates to mangle
|
// step 1: find candidates to mangle
|
||||||
ast.walk(new TreeWalker(function(node){
|
ast.walk(new TreeWalker(function(node){
|
||||||
if (node instanceof AST_ObjectKeyVal) {
|
if (node instanceof AST_ObjectKeyVal) {
|
||||||
add(node.key);
|
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
|
||||||
@@ -145,14 +136,18 @@ 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, add);
|
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) {
|
||||||
node.key = mangle(node.key);
|
if (!(keep_quoted && node.quote))
|
||||||
|
node.key = mangle(node.key);
|
||||||
}
|
}
|
||||||
else if (node instanceof AST_ObjectProperty) {
|
else if (node instanceof AST_ObjectProperty) {
|
||||||
// setter or getter
|
// setter or getter
|
||||||
@@ -161,9 +156,27 @@ function mangle_properties(ast, options) {
|
|||||||
else if (node instanceof AST_Dot) {
|
else if (node instanceof AST_Dot) {
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
}
|
}
|
||||||
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
else if (node instanceof AST_Sub) {
|
||||||
node.property = mangleStrings(node.property);
|
if (!keep_quoted)
|
||||||
|
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) {
|
||||||
|
// if (should_mangle(node.value)) {
|
||||||
|
// AST_Node.warn(
|
||||||
|
// "Found \"{prop}\" property candidate for mangling in an arbitrary string [{file}:{line},{col}]", {
|
||||||
|
// file : node.start.file,
|
||||||
|
// line : node.start.line,
|
||||||
|
// col : node.start.col,
|
||||||
|
// prop : node.value
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// only function declarations after this line
|
// only function declarations after this line
|
||||||
@@ -179,13 +192,19 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function should_mangle(name) {
|
function should_mangle(name) {
|
||||||
|
if (keep_quoted && name in to_keep) return false;
|
||||||
if (regex && !regex.test(name)) return false;
|
if (regex && !regex.test(name)) return false;
|
||||||
if (reserved.indexOf(name) >= 0) return false;
|
if (reserved.indexOf(name) >= 0) return false;
|
||||||
return cache.props.has(name)
|
return cache.props.has(name)
|
||||||
|| names_to_mangle.indexOf(name) >= 0;
|
|| names_to_mangle.indexOf(name) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(name) {
|
function add(name, keep) {
|
||||||
|
if (keep) {
|
||||||
|
to_keep[name] = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (can_mangle(name))
|
if (can_mangle(name))
|
||||||
push_uniq(names_to_mangle, name);
|
push_uniq(names_to_mangle, name);
|
||||||
|
|
||||||
@@ -205,16 +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)) {
|
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 `to_keep` set
|
||||||
|
// (filled with quoted properties when `keep_quoted` is set). Make sure we add this
|
||||||
|
// check so we don't collide with a quoted name.
|
||||||
do {
|
do {
|
||||||
mangled = base54(++cache.cname);
|
mangled = base54(++cache.cname);
|
||||||
} while (!can_mangle(mangled));
|
} while (!can_mangle(mangled) || keep_quoted && mangled in to_keep);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.props.set(name, mangled);
|
cache.props.set(name, mangled);
|
||||||
@@ -222,6 +244,32 @@ function mangle_properties(ast, options) {
|
|||||||
return mangled;
|
return mangled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addStrings(node, keep) {
|
||||||
|
var out = {};
|
||||||
|
try {
|
||||||
|
(function walk(node){
|
||||||
|
node.walk(new TreeWalker(function(node){
|
||||||
|
if (node instanceof AST_Sequence) {
|
||||||
|
walk(node.expressions[node.expressions.length - 1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_String) {
|
||||||
|
add(node.value, keep);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Conditional) {
|
||||||
|
walk(node.consequent);
|
||||||
|
walk(node.alternative);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw out;
|
||||||
|
}));
|
||||||
|
})(node);
|
||||||
|
} catch(ex) {
|
||||||
|
if (ex !== out) throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function mangleStrings(node) {
|
function mangleStrings(node) {
|
||||||
return node.transform(new TreeTransformer(function(node){
|
return node.transform(new TreeTransformer(function(node){
|
||||||
if (node instanceof AST_Sequence) {
|
if (node instanceof AST_Sequence) {
|
||||||
|
|||||||
433
lib/scope.js
433
lib/scope.js
@@ -43,16 +43,17 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
function SymbolDef(scope, orig) {
|
function SymbolDef(scope, index, orig) {
|
||||||
this.name = orig.name;
|
this.name = orig.name;
|
||||||
this.orig = [ orig ];
|
this.orig = [ orig ];
|
||||||
this.eliminated = 0;
|
|
||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.references = [];
|
this.references = [];
|
||||||
this.replaced = 0;
|
|
||||||
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.id = SymbolDef.next_id++;
|
this.id = SymbolDef.next_id++;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -63,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;
|
||||||
@@ -80,7 +87,7 @@ SymbolDef.prototype = {
|
|||||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||||
s = s.parent_scope;
|
s = s.parent_scope;
|
||||||
var def;
|
var def;
|
||||||
if (def = this.redefined()) {
|
if (this.defun && (def = this.defun.variables.get(this.name))) {
|
||||||
this.mangled_name = def.mangled_name || def.name;
|
this.mangled_name = def.mangled_name || def.name;
|
||||||
} else
|
} else
|
||||||
this.mangled_name = s.next_mangled(options, this);
|
this.mangled_name = s.next_mangled(options, this);
|
||||||
@@ -88,9 +95,6 @@ SymbolDef.prototype = {
|
|||||||
cache.set(this.name, this.mangled_name);
|
cache.set(this.name, this.mangled_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
redefined: function() {
|
|
||||||
return this.defun && this.defun.variables.get(this.name);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -98,6 +102,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
cache: null,
|
cache: null,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
|
safari10: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
@@ -105,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;
|
||||||
@@ -127,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)) {
|
||||||
@@ -145,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
|
||||||
@@ -158,10 +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_SymbolVar) {
|
else if (node instanceof AST_SymbolClass) {
|
||||||
defun.def_variable(node);
|
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
|
||||||
|
|| node instanceof AST_SymbolLet
|
||||||
|
|| node instanceof AST_SymbolConst) {
|
||||||
|
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);
|
||||||
@@ -172,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);
|
||||||
@@ -187,8 +249,24 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
// pass 2: find back references and eval
|
// pass 2: find back references and eval
|
||||||
self.globals = new Dictionary();
|
var func = null;
|
||||||
|
var cls = null;
|
||||||
|
var globals = self.globals = new Dictionary();
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
|
if (node instanceof AST_Lambda) {
|
||||||
|
var prev_func = func;
|
||||||
|
func = node;
|
||||||
|
descend();
|
||||||
|
func = prev_func;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_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;
|
||||||
@@ -201,25 +279,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
var sym = node.scope.find_variable(name);
|
var sym = node.scope.find_variable(name);
|
||||||
|
if (node.scope instanceof AST_Lambda && name == "arguments") {
|
||||||
|
node.scope.uses_arguments = true;
|
||||||
|
}
|
||||||
if (!sym) {
|
if (!sym) {
|
||||||
sym = self.def_global(node);
|
sym = self.def_global(node);
|
||||||
} else if (sym.scope instanceof AST_Lambda && name == "arguments") {
|
|
||||||
sym.scope.uses_arguments = true;
|
|
||||||
}
|
}
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ensure mangling works if catch reuses a scope variable
|
|
||||||
var def;
|
|
||||||
if (node instanceof AST_SymbolCatch && (def = node.definition().redefined())) {
|
|
||||||
var s = node.scope;
|
|
||||||
while (s) {
|
|
||||||
push_uniq(s.enclosed, def);
|
|
||||||
if (s === def.scope) break;
|
|
||||||
s = s.parent_scope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
|
|
||||||
@@ -236,12 +305,24 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
|||||||
ref.reference(options);
|
ref.reference(options);
|
||||||
});
|
});
|
||||||
node.thedef = def;
|
node.thedef = def;
|
||||||
node.reference(options);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
@@ -252,7 +333,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
|
|||||||
if (globals.has(name)) {
|
if (globals.has(name)) {
|
||||||
return globals.get(name);
|
return globals.get(name);
|
||||||
} else {
|
} else {
|
||||||
var g = new SymbolDef(this, node);
|
var g = new SymbolDef(this, globals.size(), node);
|
||||||
g.undeclared = true;
|
g.undeclared = true;
|
||||||
g.global = true;
|
g.global = true;
|
||||||
globals.set(name, g);
|
globals.set(name, g);
|
||||||
@@ -270,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_SymbolFunarg({
|
this.def_variable(new AST_SymbolConst({
|
||||||
name: "arguments",
|
name: "arguments",
|
||||||
start: this.start,
|
start: this.start,
|
||||||
end: this.end
|
end: this.end
|
||||||
@@ -306,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, 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);
|
||||||
@@ -331,7 +437,7 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
|
|||||||
|
|
||||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||||
// shadow a name reserved from mangling.
|
// shadow a name reserved from mangling.
|
||||||
if (member(m, options.reserved)) 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
|
||||||
@@ -364,17 +470,31 @@ AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
|||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
return !def || def.unmangleable(options);
|
return def && def.unmangleable(options);
|
||||||
});
|
});
|
||||||
|
|
||||||
// labels are always mangleable
|
// labels are always mangleable
|
||||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
AST_Label.DEFMETHOD("unmangleable", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||||
return this.definition().references.length == 0
|
return this.definition().references.length == 0
|
||||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
AST_Symbol.DEFMETHOD("undeclared", function(){
|
||||||
|
return this.definition().undeclared;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_LabelRef.DEFMETHOD("undeclared", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
AST_Label.DEFMETHOD("undeclared", function(){
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
AST_Symbol.DEFMETHOD("definition", function(){
|
AST_Symbol.DEFMETHOD("definition", function(){
|
||||||
return this.thedef;
|
return this.thedef;
|
||||||
});
|
});
|
||||||
@@ -383,23 +503,23 @@ AST_Symbol.DEFMETHOD("global", function(){
|
|||||||
return this.definition().global;
|
return this.definition().global;
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
|
||||||
options = defaults(options, {
|
return defaults(options, {
|
||||||
eval : false,
|
eval : false,
|
||||||
ie8 : false,
|
ie8 : false,
|
||||||
|
keep_classnames: false,
|
||||||
keep_fnames : false,
|
keep_fnames : false,
|
||||||
reserved : [],
|
reserved : [],
|
||||||
toplevel : false,
|
toplevel : false,
|
||||||
});
|
});
|
||||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
|
||||||
// Never mangle arguments
|
|
||||||
push_uniq(options.reserved, "arguments");
|
|
||||||
return options;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
|
|
||||||
|
// Never mangle arguments
|
||||||
|
options.reserved.push('arguments');
|
||||||
|
|
||||||
// We only need to mangle declaration nodes. Special logic wired
|
// We only need to mangle declaration nodes. Special logic wired
|
||||||
// into the code generator will display the mangled name if it's
|
// into the code generator will display the mangled name if it's
|
||||||
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
// present (and for AST_SymbolRef-s it'll use the mangled name of
|
||||||
@@ -408,7 +528,11 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
var to_mangle = [];
|
var to_mangle = [];
|
||||||
|
|
||||||
if (options.cache) {
|
if (options.cache) {
|
||||||
this.globals.each(collect);
|
this.globals.each(function(symbol){
|
||||||
|
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||||
|
to_mangle.push(symbol);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var tw = new TreeWalker(function(node, descend){
|
var tw = new TreeWalker(function(node, descend){
|
||||||
@@ -420,7 +544,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
return true; // don't descend again in TreeWalker
|
return true; // don't descend again in TreeWalker
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Scope) {
|
if (node instanceof AST_Scope) {
|
||||||
node.variables.each(collect);
|
var p = tw.parent(), a = [];
|
||||||
|
node.variables.each(function(symbol){
|
||||||
|
if (options.reserved.indexOf(symbol.name) < 0) {
|
||||||
|
a.push(symbol);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
to_mangle.push.apply(to_mangle, a);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_Label) {
|
if (node instanceof AST_Label) {
|
||||||
@@ -429,157 +559,132 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
|||||||
node.mangled_name = name;
|
node.mangled_name = name;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!options.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;
|
||||||
}
|
}
|
||||||
|
|
||||||
function collect(symbol) {
|
|
||||||
if (!member(symbol.name, options.reserved)) {
|
|
||||||
to_mangle.push(symbol);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
|
||||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
|
||||||
var cache = options.cache && options.cache.props;
|
|
||||||
var prefixes = Object.create(null);
|
|
||||||
options.reserved.forEach(add_prefix);
|
|
||||||
this.globals.each(add_def);
|
|
||||||
this.walk(new TreeWalker(function(node) {
|
|
||||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
|
||||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
|
||||||
}));
|
|
||||||
var prefix, i = 0;
|
|
||||||
do {
|
|
||||||
prefix = create_name(i++);
|
|
||||||
} while (prefixes[prefix]);
|
|
||||||
return prefix;
|
|
||||||
|
|
||||||
function add_prefix(name) {
|
|
||||||
if (/[0-9]$/.test(name)) {
|
|
||||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function add_def(def) {
|
|
||||||
var name = def.name;
|
|
||||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
|
||||||
else if (!def.unmangleable(options)) return;
|
|
||||||
add_prefix(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_name(num) {
|
|
||||||
var name = "";
|
|
||||||
do {
|
|
||||||
name += letters[num % letters.length];
|
|
||||||
num = Math.floor(num / letters.length);
|
|
||||||
} while (num);
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
|
||||||
options = this._default_mangler_options(options);
|
|
||||||
var prefix = this.find_unique_prefix(options);
|
|
||||||
this.globals.each(rename);
|
|
||||||
this.walk(new TreeWalker(function(node) {
|
|
||||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
|
||||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
|
||||||
}));
|
|
||||||
|
|
||||||
function rename(def) {
|
|
||||||
if (def.global || def.unmangleable(options)) return;
|
|
||||||
if (member(def.name, options.reserved)) return;
|
|
||||||
var d = def.redefined();
|
|
||||||
def.name = d ? d.name : prefix + def.id;
|
|
||||||
def.orig.forEach(function(sym) {
|
|
||||||
sym.name = def.name;
|
|
||||||
});
|
|
||||||
def.references.forEach(function(sym) {
|
|
||||||
sym.name = def.name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AST_Node.DEFMETHOD("tail_node", return_this);
|
|
||||||
AST_Sequence.DEFMETHOD("tail_node", function() {
|
|
||||||
return this.expressions[this.expressions.length - 1];
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||||
options = this._default_mangler_options(options);
|
options = this._default_mangler_options(options);
|
||||||
try {
|
var tw = new TreeWalker(function(node){
|
||||||
AST_Node.prototype.print = function(stream, force_parens) {
|
if (node instanceof AST_Constant)
|
||||||
this._print(stream, force_parens);
|
base54.consider(node.print_to_string());
|
||||||
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
else if (node instanceof AST_Return)
|
||||||
base54.consider(this.name, -1);
|
base54.consider("return");
|
||||||
} else if (options.properties) {
|
else if (node instanceof AST_Throw)
|
||||||
if (this instanceof AST_Dot) {
|
base54.consider("throw");
|
||||||
base54.consider(this.property, -1);
|
else if (node instanceof AST_Continue)
|
||||||
} else if (this instanceof AST_Sub) {
|
base54.consider("continue");
|
||||||
skip_string(this.property);
|
else if (node instanceof AST_Break)
|
||||||
}
|
base54.consider("break");
|
||||||
}
|
else if (node instanceof AST_Debugger)
|
||||||
};
|
base54.consider("debugger");
|
||||||
base54.consider(this.print_to_string(), 1);
|
else if (node instanceof AST_Directive)
|
||||||
} finally {
|
base54.consider(node.value);
|
||||||
AST_Node.prototype.print = AST_Node.prototype._print;
|
else if (node instanceof AST_While)
|
||||||
}
|
base54.consider("while");
|
||||||
base54.sort();
|
else if (node instanceof AST_Do)
|
||||||
|
base54.consider("do while");
|
||||||
function skip_string(node) {
|
else if (node instanceof AST_If) {
|
||||||
if (node instanceof AST_String) {
|
base54.consider("if");
|
||||||
base54.consider(node.value, -1);
|
if (node.alternative) base54.consider("else");
|
||||||
} else if (node instanceof AST_Conditional) {
|
|
||||||
skip_string(node.consequent);
|
|
||||||
skip_string(node.alternative);
|
|
||||||
} else if (node instanceof AST_Sequence) {
|
|
||||||
skip_string(node.tail_node());
|
|
||||||
}
|
}
|
||||||
}
|
else if (node instanceof AST_Var)
|
||||||
|
base54.consider("var");
|
||||||
|
else if (node instanceof AST_Const)
|
||||||
|
base54.consider("const");
|
||||||
|
else if (node instanceof AST_Lambda)
|
||||||
|
base54.consider("function");
|
||||||
|
else if (node instanceof AST_For)
|
||||||
|
base54.consider("for");
|
||||||
|
else if (node instanceof AST_ForIn)
|
||||||
|
base54.consider("for in");
|
||||||
|
else if (node instanceof AST_Switch)
|
||||||
|
base54.consider("switch");
|
||||||
|
else if (node instanceof AST_Case)
|
||||||
|
base54.consider("case");
|
||||||
|
else if (node instanceof AST_Default)
|
||||||
|
base54.consider("default");
|
||||||
|
else if (node instanceof AST_With)
|
||||||
|
base54.consider("with");
|
||||||
|
else if (node instanceof AST_ObjectSetter)
|
||||||
|
base54.consider("set" + (typeof node.key === "string" ? node.key : ""));
|
||||||
|
else if (node instanceof AST_ObjectGetter)
|
||||||
|
base54.consider("get" + (typeof node.key === "string" ? node.key : ""));
|
||||||
|
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);
|
||||||
|
else if (node instanceof AST_New)
|
||||||
|
base54.consider("new");
|
||||||
|
else if (node instanceof AST_This)
|
||||||
|
base54.consider("this");
|
||||||
|
else if (node instanceof AST_Super)
|
||||||
|
base54.consider("super");
|
||||||
|
else if (node instanceof AST_Try)
|
||||||
|
base54.consider("try");
|
||||||
|
else if (node instanceof AST_Catch)
|
||||||
|
base54.consider("catch");
|
||||||
|
else if (node instanceof AST_Finally)
|
||||||
|
base54.consider("finally");
|
||||||
|
else if (node instanceof AST_Yield)
|
||||||
|
base54.consider("yield");
|
||||||
|
else if (node instanceof AST_Symbol && node.unmangleable(options))
|
||||||
|
base54.consider(node.name);
|
||||||
|
else if (node instanceof AST_Unary || node instanceof AST_Binary)
|
||||||
|
base54.consider(node.operator);
|
||||||
|
else if (node instanceof AST_Dot)
|
||||||
|
base54.consider(node.property);
|
||||||
|
});
|
||||||
|
this.walk(tw);
|
||||||
|
base54.sort();
|
||||||
});
|
});
|
||||||
|
|
||||||
var base54 = (function() {
|
var base54 = (function() {
|
||||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
var string = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
|
||||||
var digits = "0123456789".split("");
|
|
||||||
var chars, frequency;
|
var chars, frequency;
|
||||||
function reset() {
|
function reset() {
|
||||||
frequency = Object.create(null);
|
frequency = Object.create(null);
|
||||||
leading.forEach(function(ch) {
|
chars = string.split("").map(function(ch){ return ch.charCodeAt(0) });
|
||||||
frequency[ch] = 0;
|
chars.forEach(function(ch){ frequency[ch] = 0 });
|
||||||
});
|
|
||||||
digits.forEach(function(ch) {
|
|
||||||
frequency[ch] = 0;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
base54.consider = function(str, delta) {
|
base54.consider = function(str){
|
||||||
for (var i = str.length; --i >= 0;) {
|
for (var i = str.length; --i >= 0;) {
|
||||||
frequency[str[i]] += delta;
|
var code = str.charCodeAt(i);
|
||||||
|
if (code in frequency) ++frequency[code];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
function compare(a, b) {
|
|
||||||
return frequency[b] - frequency[a];
|
|
||||||
}
|
|
||||||
base54.sort = function() {
|
base54.sort = function() {
|
||||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
chars = mergeSort(chars, function(a, b){
|
||||||
|
if (is_digit(a) && !is_digit(b)) return 1;
|
||||||
|
if (is_digit(b) && !is_digit(a)) return -1;
|
||||||
|
return frequency[b] - frequency[a];
|
||||||
|
});
|
||||||
};
|
};
|
||||||
base54.reset = reset;
|
base54.reset = reset;
|
||||||
reset();
|
reset();
|
||||||
|
base54.get = function(){ return chars };
|
||||||
|
base54.freq = function(){ return frequency };
|
||||||
function base54(num) {
|
function base54(num) {
|
||||||
var ret = "", base = 54;
|
var ret = "", base = 54;
|
||||||
num++;
|
num++;
|
||||||
do {
|
do {
|
||||||
num--;
|
num--;
|
||||||
ret += chars[num % base];
|
ret += String.fromCharCode(chars[num % base]);
|
||||||
num = Math.floor(num / base);
|
num = Math.floor(num / base);
|
||||||
base = 64;
|
base = 64;
|
||||||
} while (num > 0);
|
} while (num > 0);
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (y !== undefined) x = y;
|
if (y !== undefined) x = y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tw.pop();
|
tw.pop(this);
|
||||||
return x;
|
return x;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -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){
|
||||||
@@ -187,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);
|
||||||
});
|
});
|
||||||
@@ -211,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);
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -43,6 +43,13 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
function array_to_hash(a) {
|
||||||
|
var ret = Object.create(null);
|
||||||
|
for (var i = 0; i < a.length; ++i)
|
||||||
|
ret[a[i]] = true;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
function slice(a, start) {
|
function slice(a, start) {
|
||||||
return Array.prototype.slice.call(a, start || 0);
|
return Array.prototype.slice.call(a, start || 0);
|
||||||
};
|
};
|
||||||
|
|||||||
17
package.json
17
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": "3.2.1",
|
"version": "3.0.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -29,16 +29,15 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"commander": "~2.12.1",
|
"commander": "~2.9.0",
|
||||||
"source-map": "~0.6.1"
|
"source-map": "~0.5.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~5.2.1",
|
"acorn": "~5.0.3",
|
||||||
"mocha": "~3.5.1",
|
"mocha": "~2.3.4"
|
||||||
"semver": "~5.4.1"
|
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "node test/run-tests.js"
|
"test": "node test/run-tests.js"
|
||||||
},
|
},
|
||||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
"keywords": ["uglify", "uglify-js", "minify", "minifier"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,14 +4,12 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var createHash = require("crypto").createHash;
|
var createHash = require("crypto").createHash;
|
||||||
var fetch = require("./fetch");
|
|
||||||
var fork = require("child_process").fork;
|
var fork = require("child_process").fork;
|
||||||
var zlib = require("zlib");
|
|
||||||
var args = process.argv.slice(2);
|
var args = process.argv.slice(2);
|
||||||
if (!args.length) {
|
if (!args.length) {
|
||||||
args.push("-mc");
|
args.push("-mc");
|
||||||
}
|
}
|
||||||
args.push("--timings");
|
args.push("--stats");
|
||||||
var urls = [
|
var urls = [
|
||||||
"https://code.jquery.com/jquery-3.2.1.js",
|
"https://code.jquery.com/jquery-3.2.1.js",
|
||||||
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.js",
|
||||||
@@ -31,10 +29,14 @@ 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;
|
||||||
|
console.log(info.log.replace(/Elapsed: ([0-9]+)\s*/g, function(match, time) {
|
||||||
|
elapsed += 1e-3 * parseInt(time);
|
||||||
|
return "";
|
||||||
|
}));
|
||||||
|
console.log("Run-time:", elapsed.toFixed(3), "s");
|
||||||
console.log("Original:", info.input, "bytes");
|
console.log("Original:", info.input, "bytes");
|
||||||
console.log("Uglified:", info.output, "bytes");
|
console.log("Uglified:", info.output, "bytes");
|
||||||
console.log("GZipped: ", info.gzip, "bytes");
|
|
||||||
console.log("SHA1 sum:", info.sha1);
|
console.log("SHA1 sum:", info.sha1);
|
||||||
if (info.code) {
|
if (info.code) {
|
||||||
failures.push(url);
|
failures.push(url);
|
||||||
@@ -53,21 +55,15 @@ urls.forEach(function(url) {
|
|||||||
results[url] = {
|
results[url] = {
|
||||||
input: 0,
|
input: 0,
|
||||||
output: 0,
|
output: 0,
|
||||||
gzip: 0,
|
|
||||||
log: ""
|
log: ""
|
||||||
};
|
};
|
||||||
fetch(url, function(err, res) {
|
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
||||||
if (err) throw err;
|
|
||||||
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
var uglifyjs = fork("bin/uglifyjs", args, { silent: true });
|
||||||
res.on("data", function(data) {
|
res.on("data", function(data) {
|
||||||
results[url].input += data.length;
|
results[url].input += data.length;
|
||||||
}).pipe(uglifyjs.stdin);
|
}).pipe(uglifyjs.stdin);
|
||||||
uglifyjs.stdout.on("data", function(data) {
|
uglifyjs.stdout.on("data", function(data) {
|
||||||
results[url].output += data.length;
|
results[url].output += data.length;
|
||||||
}).pipe(zlib.createGzip({
|
|
||||||
level: zlib.Z_BEST_COMPRESSION
|
|
||||||
})).on("data", function(data) {
|
|
||||||
results[url].gzip += data.length;
|
|
||||||
}).pipe(createHash("sha1")).on("data", function(data) {
|
}).pipe(createHash("sha1")).on("data", function(data) {
|
||||||
results[url].sha1 = data.toString("hex");
|
results[url].sha1 = data.toString("hex");
|
||||||
done();
|
done();
|
||||||
|
|||||||
@@ -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,
|
||||||
@@ -128,114 +203,50 @@ constant_join_3: {
|
|||||||
|
|
||||||
for_loop: {
|
for_loop: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
unsafe : true,
|
||||||
reduce_funcs: true,
|
unused : true,
|
||||||
reduce_vars: true,
|
evaluate : true,
|
||||||
unsafe: true,
|
reduce_vars : true
|
||||||
unused: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
function f0() {
|
function f0() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
var b = 0;
|
for (var i = 0; i < a.length; i++) {
|
||||||
for (var i = 0; i < a.length; i++)
|
console.log(a[i]);
|
||||||
b += a[i];
|
}
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
var b = 0;
|
for (var i = 0, len = a.length; i < len; i++) {
|
||||||
for (var i = 0, len = a.length; i < len; i++)
|
console.log(a[i]);
|
||||||
b += a[i];
|
}
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++)
|
for (var i = 0; i < a.length; i++) {
|
||||||
a[i]++;
|
a[i]++;
|
||||||
return a[2];
|
}
|
||||||
}
|
}
|
||||||
console.log(f0(), f1(), f2());
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0() {
|
function f0() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
var b = 0;
|
|
||||||
for (var i = 0; i < 3; i++)
|
for (var i = 0; i < 3; i++)
|
||||||
b += a[i];
|
console.log(a[i]);
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function f1() {
|
function f1() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
var b = 0;
|
|
||||||
for (var i = 0; i < 3; i++)
|
for (var i = 0; i < 3; i++)
|
||||||
b += a[i];
|
console.log(a[i]);
|
||||||
return b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() {
|
function f2() {
|
||||||
var a = [1, 2, 3];
|
var a = [1, 2, 3];
|
||||||
for (var i = 0; i < a.length; i++)
|
for (var i = 0; i < a.length; i++)
|
||||||
a[i]++;
|
a[i]++;
|
||||||
return a[2];
|
|
||||||
}
|
}
|
||||||
console.log(f0(), f1(), f2());
|
|
||||||
}
|
}
|
||||||
expect_stdout: "6 6 4"
|
|
||||||
}
|
|
||||||
|
|
||||||
index: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = [ 1, 2 ];
|
|
||||||
console.log(a[0], a[1]);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, 2);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
length: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = [ 1, 2 ];
|
|
||||||
console.log(a.length);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(2);
|
|
||||||
}
|
|
||||||
expect_stdout: "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
index_length: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = [ 1, 2 ];
|
|
||||||
console.log(a[0], a.length);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, 2);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 2"
|
|
||||||
}
|
}
|
||||||
|
|||||||
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 )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ ascii_only_true: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\b\\t\\n\\v\\f\\r\\x0e\\x0f"+"\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f"+\' !"# ... }~\\x7f\\x80\\x81 ... \\xfe\\xff\\u0fff\\uffff\'}'
|
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\'}'
|
||||||
}
|
}
|
||||||
|
|
||||||
ascii_only_false: {
|
ascii_only_false: {
|
||||||
@@ -31,5 +31,5 @@ ascii_only_false: {
|
|||||||
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
"\x20\x21\x22\x23 ... \x7d\x7e\x7f\x80\x81 ... \xfe\xff\u0fff\uffff";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: 'function f(){return"\\x000\\x001\\x007\\x008\\0"+"\\0\x01\x02\x03\x04\x05\x06\x07\\b\\t\\n\\v\\f\\r\x0e\x0f"+"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"+\' !"# ... }~\x7f\x80\x81 ... \xfe\xff\u0fff\uffff\'}'
|
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\'}'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,65 +104,3 @@ asm_mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
asm_toplevel: {
|
|
||||||
options = {}
|
|
||||||
input: {
|
|
||||||
"use asm";
|
|
||||||
0.0;
|
|
||||||
function f() {
|
|
||||||
0.0;
|
|
||||||
(function(){
|
|
||||||
0.0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
expect_exact: '"use asm";0.0;function f(){0.0;(function(){0.0})}0.0;'
|
|
||||||
}
|
|
||||||
|
|
||||||
asm_function_expression: {
|
|
||||||
options = {}
|
|
||||||
input: {
|
|
||||||
0.0;
|
|
||||||
var a = function() {
|
|
||||||
"use asm";
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
function f() {
|
|
||||||
0.0;
|
|
||||||
return function(){
|
|
||||||
"use asm";
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
expect_exact: '0;var a=function(){"use asm";0.0};function f(){0;return function(){"use asm";0.0};0}0;'
|
|
||||||
}
|
|
||||||
|
|
||||||
asm_nested_functions: {
|
|
||||||
options = {}
|
|
||||||
input: {
|
|
||||||
0.0;
|
|
||||||
function a() {
|
|
||||||
"use asm";
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
function b() {
|
|
||||||
0.0;
|
|
||||||
function c(){
|
|
||||||
"use asm";
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
function d(){
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
0.0;
|
|
||||||
}
|
|
||||||
expect_exact: '0;function a(){"use asm";0.0}0;function b(){0;function c(){"use asm";0.0}0;function d(){0}0}0;'
|
|
||||||
}
|
|
||||||
|
|||||||
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);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -73,42 +73,4 @@ dont_change_in_or_instanceof_expressions: {
|
|||||||
1 instanceof 1;
|
1 instanceof 1;
|
||||||
null instanceof null;
|
null instanceof null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self_comparison_1: {
|
|
||||||
options = {
|
|
||||||
comparisons: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
a === a;
|
|
||||||
a !== b;
|
|
||||||
b.c === a.c;
|
|
||||||
b.c !== b.c;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
a == a;
|
|
||||||
a !== b;
|
|
||||||
b.c === a.c;
|
|
||||||
b.c != b.c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self_comparison_2: {
|
|
||||||
options = {
|
|
||||||
comparisons: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {}
|
|
||||||
var o = {};
|
|
||||||
console.log(f != f, o === o);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {}
|
|
||||||
var o = {};
|
|
||||||
console.log(false, true);
|
|
||||||
}
|
|
||||||
expect_stdout: "false true"
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,7 @@ concat_1: {
|
|||||||
var c = 1 + x() + 2 + "boo";
|
var c = 1 + x() + 2 + "boo";
|
||||||
var d = 1 + x() + 2 + 3 + "boo";
|
var d = 1 + x() + 2 + 3 + "boo";
|
||||||
var e = 1 + x() + 2 + "X3boo";
|
var e = 1 + x() + 2 + "X3boo";
|
||||||
var f = "\x00360\x008\0";
|
var f = "\x00360\08\0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1015,103 +1015,3 @@ delete_conditional_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2535_1: {
|
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
conditionals: true,
|
|
||||||
evaluate: true,
|
|
||||||
passes: 2,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
if (true || x()) y();
|
|
||||||
if (true && x()) y();
|
|
||||||
if (x() || true) y();
|
|
||||||
if (x() && true) y();
|
|
||||||
if (false || x()) y();
|
|
||||||
if (false && x()) y();
|
|
||||||
if (x() || false) y();
|
|
||||||
if (x() && false) y();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
y();
|
|
||||||
x() && y();
|
|
||||||
(x(), 1) && y();
|
|
||||||
x() && y();
|
|
||||||
x() && y();
|
|
||||||
x() && y();
|
|
||||||
(x(), 0) && y();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2535_2: {
|
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
conditionals: true,
|
|
||||||
evaluate: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function x() {}
|
|
||||||
function y() {
|
|
||||||
return "foo";
|
|
||||||
}
|
|
||||||
console.log((x() || true) || y());
|
|
||||||
console.log((y() || true) || x());
|
|
||||||
console.log((x() || true) && y());
|
|
||||||
console.log((y() || true) && x());
|
|
||||||
console.log((x() && true) || y());
|
|
||||||
console.log((y() && true) || x());
|
|
||||||
console.log((x() && true) && y());
|
|
||||||
console.log((y() && true) && x());
|
|
||||||
console.log((x() || false) || y());
|
|
||||||
console.log((y() || false) || x());
|
|
||||||
console.log((x() || false) && y());
|
|
||||||
console.log((y() || false) && x());
|
|
||||||
console.log((x() && false) || y());
|
|
||||||
console.log((y() && false) || x());
|
|
||||||
console.log((x() && false) && y());
|
|
||||||
console.log((y() && false) && x());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function x() {}
|
|
||||||
function y() {
|
|
||||||
return "foo";
|
|
||||||
}
|
|
||||||
console.log(x() || !0);
|
|
||||||
console.log(y() || !0);
|
|
||||||
console.log((x(), y()));
|
|
||||||
console.log((y(), x()));
|
|
||||||
console.log(!!x() || y());
|
|
||||||
console.log(!!y() || x());
|
|
||||||
console.log(x() && y());
|
|
||||||
console.log(y() && x());
|
|
||||||
console.log(x() || y());
|
|
||||||
console.log(y() || x());
|
|
||||||
console.log(!!x() && y());
|
|
||||||
console.log(!!y() && x());
|
|
||||||
console.log((x(), y()));
|
|
||||||
console.log((y(), x()));
|
|
||||||
console.log(x() && !1);
|
|
||||||
console.log(y() && !1);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"true",
|
|
||||||
"foo",
|
|
||||||
"foo",
|
|
||||||
"undefined",
|
|
||||||
"foo",
|
|
||||||
"true",
|
|
||||||
"undefined",
|
|
||||||
"undefined",
|
|
||||||
"foo",
|
|
||||||
"foo",
|
|
||||||
"false",
|
|
||||||
"undefined",
|
|
||||||
"foo",
|
|
||||||
"undefined",
|
|
||||||
"undefined",
|
|
||||||
"false",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
166
test/compress/const.js
Normal file
166
test/compress/const.js
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
issue_1191: {
|
||||||
|
options = {
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
comparisons : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
side_effects : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
sequences : false,
|
||||||
|
collapse_vars : false,
|
||||||
|
reduce_vars : true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(rot) {
|
||||||
|
const rotTol = 5;
|
||||||
|
if (rot < -rotTol || rot > rotTol)
|
||||||
|
bar();
|
||||||
|
baz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(rot) {
|
||||||
|
(rot < -5 || rot > 5) && bar();
|
||||||
|
baz();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1194: {
|
||||||
|
options = {
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
comparisons : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
side_effects : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
sequences : false,
|
||||||
|
collapse_vars : false,
|
||||||
|
reduce_vars : true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f1() {const a = "X"; return a + a;}
|
||||||
|
function f2() {const aa = "X"; return aa + aa;}
|
||||||
|
function f3() {const aaa = "X"; return aaa + aaa;}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f1(){return"XX"}
|
||||||
|
function f2(){return"XX"}
|
||||||
|
function f3(){return"XX"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_1396: {
|
||||||
|
options = {
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
comparisons : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
side_effects : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
sequences : false,
|
||||||
|
collapse_vars : false,
|
||||||
|
reduce_vars : true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo(a) {
|
||||||
|
const VALUE = 1;
|
||||||
|
console.log(2 | VALUE);
|
||||||
|
console.log(VALUE + 1);
|
||||||
|
console.log(VALUE);
|
||||||
|
console.log(a & VALUE);
|
||||||
|
}
|
||||||
|
function bar() {
|
||||||
|
const s = "01234567890123456789";
|
||||||
|
console.log(s + s + s + s + s);
|
||||||
|
|
||||||
|
const CONSTANT = "abc";
|
||||||
|
console.log(CONSTANT + CONSTANT + CONSTANT + CONSTANT + CONSTANT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo(a) {
|
||||||
|
console.log(3);
|
||||||
|
console.log(2);
|
||||||
|
console.log(1);
|
||||||
|
console.log(1 & a);
|
||||||
|
}
|
||||||
|
function bar() {
|
||||||
|
const s = "01234567890123456789";
|
||||||
|
console.log(s + s + s + s + s);
|
||||||
|
|
||||||
|
console.log("abcabcabcabcabc");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unused_regexp_literal: {
|
||||||
|
options = {
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
comparisons : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
side_effects : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
sequences : false,
|
||||||
|
collapse_vars : false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(){ var a = /b/; }
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
regexp_literal_not_const: {
|
||||||
|
options = {
|
||||||
|
evaluate : true,
|
||||||
|
booleans : true,
|
||||||
|
comparisons : true,
|
||||||
|
dead_code : true,
|
||||||
|
conditionals : true,
|
||||||
|
side_effects : true,
|
||||||
|
unused : true,
|
||||||
|
hoist_funs : true,
|
||||||
|
if_return : true,
|
||||||
|
join_vars : true,
|
||||||
|
sequences : false,
|
||||||
|
collapse_vars : false,
|
||||||
|
reduce_vars : true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(){
|
||||||
|
var result;
|
||||||
|
const s = 'acdabcdeabbb';
|
||||||
|
const REGEXP_LITERAL = /ab*/g;
|
||||||
|
while (result = REGEXP_LITERAL.exec(s)) {
|
||||||
|
console.log(result[0]);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
var result;
|
||||||
|
const REGEXP_LITERAL = /ab*/g;
|
||||||
|
while (result = REGEXP_LITERAL.exec("acdabcdeabbb")) console.log(result[0]);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
@@ -31,7 +31,7 @@ dead_code_2_should_warn: {
|
|||||||
function f() {
|
function f() {
|
||||||
g();
|
g();
|
||||||
x = 10;
|
x = 10;
|
||||||
throw new Error("foo");
|
throw "foo";
|
||||||
// completely discarding the `if` would introduce some
|
// completely discarding the `if` would introduce some
|
||||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
||||||
// we copy any declarations to the upper scope.
|
// we copy any declarations to the upper scope.
|
||||||
@@ -46,60 +46,16 @@ dead_code_2_should_warn: {
|
|||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f();
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
g();
|
g();
|
||||||
x = 10;
|
x = 10;
|
||||||
throw new Error("foo");
|
throw "foo";
|
||||||
var x;
|
var x;
|
||||||
function g(){};
|
function g(){};
|
||||||
}
|
}
|
||||||
f();
|
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
|
||||||
node_version: "<=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_2_should_warn_strict: {
|
|
||||||
options = {
|
|
||||||
dead_code: true
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
function f() {
|
|
||||||
g();
|
|
||||||
x = 10;
|
|
||||||
throw new Error("foo");
|
|
||||||
// completely discarding the `if` would introduce some
|
|
||||||
// bugs. UglifyJS v1 doesn't deal with this issue; in v2
|
|
||||||
// we copy any declarations to the upper scope.
|
|
||||||
if (x) {
|
|
||||||
y();
|
|
||||||
var x;
|
|
||||||
function g(){};
|
|
||||||
// but nested declarations should not be kept.
|
|
||||||
(function(){
|
|
||||||
var q;
|
|
||||||
function y(){};
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function f() {
|
|
||||||
g();
|
|
||||||
x = 10;
|
|
||||||
throw new Error("foo");
|
|
||||||
var x;
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more: {
|
dead_code_constant_boolean_should_warn_more: {
|
||||||
@@ -122,55 +78,163 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
foo();
|
foo();
|
||||||
var moo;
|
var moo;
|
||||||
}
|
}
|
||||||
bar();
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var foo;
|
var foo;
|
||||||
function bar() {}
|
function bar() {}
|
||||||
// nothing for the while
|
// nothing for the while
|
||||||
// as for the for, it should keep:
|
// as for the for, it should keep:
|
||||||
var moo;
|
|
||||||
var x = 10, y;
|
var x = 10, y;
|
||||||
bar();
|
var moo;
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
node_version: "<=4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more_strict: {
|
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: {
|
||||||
options = {
|
options = {
|
||||||
dead_code : true,
|
dead_code : true,
|
||||||
loops : true,
|
loops : true,
|
||||||
booleans : true,
|
booleans : true,
|
||||||
conditionals : true,
|
conditionals : true,
|
||||||
evaluate : true,
|
evaluate : true,
|
||||||
side_effects : true,
|
reduce_vars : true,
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
var unused;
|
||||||
while (!((foo && bar) || (x + "0"))) {
|
const CONST_FOO = false;
|
||||||
|
if (CONST_FOO) {
|
||||||
console.log("unreachable");
|
console.log("unreachable");
|
||||||
var foo;
|
var moo;
|
||||||
function bar() {}
|
function bar() {}
|
||||||
}
|
}
|
||||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
|
||||||
asdf();
|
|
||||||
foo();
|
|
||||||
var moo;
|
|
||||||
}
|
|
||||||
bar();
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
var unused;
|
||||||
var foo;
|
const CONST_FOO = !1;
|
||||||
// nothing for the while
|
|
||||||
// as for the for, it should keep:
|
|
||||||
var moo;
|
var moo;
|
||||||
var x = 10, y;
|
function bar() {}
|
||||||
bar();
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true,
|
||||||
|
reduce_vars : true,
|
||||||
|
toplevel : true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
/** @const */ var CONST_FOO_ANN = false;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("unreachable");
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation_regex: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused;
|
||||||
|
// @constraint this shouldn't be a constant
|
||||||
|
var CONST_FOO_ANN = false;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("reachable");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused;
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
CONST_FOO_ANN && console.log('reachable');
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
dead_code_const_annotation_complex_scope: {
|
||||||
|
options = {
|
||||||
|
dead_code : true,
|
||||||
|
loops : true,
|
||||||
|
booleans : true,
|
||||||
|
conditionals : true,
|
||||||
|
evaluate : true,
|
||||||
|
reduce_vars : true,
|
||||||
|
toplevel : true,
|
||||||
|
};
|
||||||
|
input: {
|
||||||
|
var unused_var;
|
||||||
|
/** @const */ var test = 'test';
|
||||||
|
// @const
|
||||||
|
var CONST_FOO_ANN = false;
|
||||||
|
var unused_var_2;
|
||||||
|
if (CONST_FOO_ANN) {
|
||||||
|
console.log("unreachable");
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
}
|
||||||
|
if (test === 'test') {
|
||||||
|
var beef = 'good';
|
||||||
|
/** @const */ var meat = 'beef';
|
||||||
|
var pork = 'bad';
|
||||||
|
if (meat === 'pork') {
|
||||||
|
console.log('also unreachable');
|
||||||
|
} else if (pork === 'good') {
|
||||||
|
console.log('reached, not const');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var unused_var;
|
||||||
|
var test = 'test';
|
||||||
|
var CONST_FOO_ANN = !1;
|
||||||
|
var unused_var_2;
|
||||||
|
var moo;
|
||||||
|
function bar() {}
|
||||||
|
var beef = 'good';
|
||||||
|
var meat = 'beef';
|
||||||
|
var pork = 'bad';
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
node_version: ">=4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try_catch_finally: {
|
try_catch_finally: {
|
||||||
@@ -178,8 +242,6 @@ try_catch_finally: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
passes: 2,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
@@ -232,188 +294,3 @@ accessor: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2233_1: {
|
|
||||||
options = {
|
|
||||||
pure_getters: "strict",
|
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
Array.isArray;
|
|
||||||
Boolean;
|
|
||||||
console.log;
|
|
||||||
Date;
|
|
||||||
decodeURI;
|
|
||||||
decodeURIComponent;
|
|
||||||
encodeURI;
|
|
||||||
encodeURIComponent;
|
|
||||||
Error.name;
|
|
||||||
escape;
|
|
||||||
eval;
|
|
||||||
EvalError;
|
|
||||||
Function.length;
|
|
||||||
isFinite;
|
|
||||||
isNaN;
|
|
||||||
JSON;
|
|
||||||
Math.random;
|
|
||||||
Number.isNaN;
|
|
||||||
parseFloat;
|
|
||||||
parseInt;
|
|
||||||
RegExp;
|
|
||||||
Object.defineProperty;
|
|
||||||
String.fromCharCode;
|
|
||||||
RangeError;
|
|
||||||
ReferenceError;
|
|
||||||
SyntaxError;
|
|
||||||
TypeError;
|
|
||||||
unescape;
|
|
||||||
URIError;
|
|
||||||
}
|
|
||||||
expect: {}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
global_timeout_and_interval_symbols: {
|
|
||||||
options = {
|
|
||||||
pure_getters: "strict",
|
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
// These global symbols do not exist in the test sandbox
|
|
||||||
// and must be tested separately.
|
|
||||||
clearInterval;
|
|
||||||
clearTimeout;
|
|
||||||
setInterval;
|
|
||||||
setTimeout;
|
|
||||||
}
|
|
||||||
expect: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2233_2: {
|
|
||||||
options = {
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var RegExp;
|
|
||||||
Array.isArray;
|
|
||||||
RegExp;
|
|
||||||
UndeclaredGlobal;
|
|
||||||
function foo() {
|
|
||||||
var Number;
|
|
||||||
AnotherUndeclaredGlobal;
|
|
||||||
Math.sin;
|
|
||||||
Number.isNaN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var RegExp;
|
|
||||||
UndeclaredGlobal;
|
|
||||||
function foo() {
|
|
||||||
var Number;
|
|
||||||
AnotherUndeclaredGlobal;
|
|
||||||
Number.isNaN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2233_3: {
|
|
||||||
options = {
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var RegExp;
|
|
||||||
Array.isArray;
|
|
||||||
RegExp;
|
|
||||||
UndeclaredGlobal;
|
|
||||||
function foo() {
|
|
||||||
var Number;
|
|
||||||
AnotherUndeclaredGlobal;
|
|
||||||
Math.sin;
|
|
||||||
Number.isNaN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
UndeclaredGlobal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
global_fns: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
Boolean(1, 2);
|
|
||||||
decodeURI(1, 2);
|
|
||||||
decodeURIComponent(1, 2);
|
|
||||||
Date(1, 2);
|
|
||||||
encodeURI(1, 2);
|
|
||||||
encodeURIComponent(1, 2);
|
|
||||||
Error(1, 2);
|
|
||||||
escape(1, 2);
|
|
||||||
EvalError(1, 2);
|
|
||||||
isFinite(1, 2);
|
|
||||||
isNaN(1, 2);
|
|
||||||
Number(1, 2);
|
|
||||||
Object(1, 2);
|
|
||||||
parseFloat(1, 2);
|
|
||||||
parseInt(1, 2);
|
|
||||||
RangeError(1, 2);
|
|
||||||
ReferenceError(1, 2);
|
|
||||||
String(1, 2);
|
|
||||||
SyntaxError(1, 2);
|
|
||||||
TypeError(1, 2);
|
|
||||||
unescape(1, 2);
|
|
||||||
URIError(1, 2);
|
|
||||||
try {
|
|
||||||
Function(1, 2);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RegExp(1, 2);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Array(NaN);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
try {
|
|
||||||
Function(1, 2);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
RegExp(1, 2);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Array(NaN);
|
|
||||||
} catch (e) {
|
|
||||||
console.log(e.name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"SyntaxError",
|
|
||||||
"SyntaxError",
|
|
||||||
"RangeError",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
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: {
|
||||||
@@ -649,6 +730,37 @@ drop_value: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
const b = 2;
|
||||||
|
return 1 + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
const b = 2;
|
||||||
|
b = 3;
|
||||||
|
return 1 + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
function g() {
|
||||||
|
const b = 2;
|
||||||
|
b = 3;
|
||||||
|
return 1 + b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
issue_1539: {
|
issue_1539: {
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
@@ -673,7 +785,6 @@ issue_1539: {
|
|||||||
vardef_value: {
|
vardef_value: {
|
||||||
options = {
|
options = {
|
||||||
keep_fnames: false,
|
keep_fnames: false,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -735,7 +846,6 @@ assign_chain: {
|
|||||||
issue_1583: {
|
issue_1583: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: true,
|
keep_fargs: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -753,11 +863,11 @@ issue_1583: {
|
|||||||
expect: {
|
expect: {
|
||||||
function m(t) {
|
function m(t) {
|
||||||
(function(e) {
|
(function(e) {
|
||||||
t = function() {
|
t = (function() {
|
||||||
return (function(a) {
|
return (function(a) {
|
||||||
return function(a) {};
|
return a;
|
||||||
})();
|
})(function(a) {});
|
||||||
}();
|
})();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -787,6 +897,10 @@ issue_1709: {
|
|||||||
var x = 1;
|
var x = 1;
|
||||||
return x;
|
return x;
|
||||||
}(),
|
}(),
|
||||||
|
function y() {
|
||||||
|
const y = 2;
|
||||||
|
return y;
|
||||||
|
}(),
|
||||||
function z() {
|
function z() {
|
||||||
function z() {}
|
function z() {}
|
||||||
return z;
|
return z;
|
||||||
@@ -799,6 +913,10 @@ issue_1709: {
|
|||||||
var x = 1;
|
var x = 1;
|
||||||
return x;
|
return x;
|
||||||
}(),
|
}(),
|
||||||
|
function() {
|
||||||
|
const y = 2;
|
||||||
|
return y;
|
||||||
|
}(),
|
||||||
function() {
|
function() {
|
||||||
function z() {}
|
function z() {}
|
||||||
return z;
|
return z;
|
||||||
@@ -1082,7 +1200,6 @@ var_catch_toplevel: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -1093,7 +1210,6 @@ var_catch_toplevel: {
|
|||||||
a--;
|
a--;
|
||||||
try {
|
try {
|
||||||
a++;
|
a++;
|
||||||
x();
|
|
||||||
} catch(a) {
|
} catch(a) {
|
||||||
if (a) var a;
|
if (a) var a;
|
||||||
var a = 10;
|
var a = 10;
|
||||||
@@ -1103,8 +1219,9 @@ var_catch_toplevel: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
|
a--;
|
||||||
try {
|
try {
|
||||||
x();
|
a++;
|
||||||
} catch(a) {
|
} catch(a) {
|
||||||
var a;
|
var a;
|
||||||
}
|
}
|
||||||
@@ -1112,132 +1229,7 @@ var_catch_toplevel: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2105_1: {
|
reassign_const: {
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 3,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
!function(factory) {
|
|
||||||
factory();
|
|
||||||
}( function() {
|
|
||||||
return function(fn) {
|
|
||||||
fn()().prop();
|
|
||||||
}( function() {
|
|
||||||
function bar() {
|
|
||||||
var quux = function() {
|
|
||||||
console.log("PASS");
|
|
||||||
}, foo = function() {
|
|
||||||
console.log;
|
|
||||||
quux();
|
|
||||||
};
|
|
||||||
return { prop: foo };
|
|
||||||
}
|
|
||||||
return bar;
|
|
||||||
} );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
({
|
|
||||||
prop: function() {
|
|
||||||
console.log;
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
}).prop();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2105_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 3,
|
|
||||||
properties: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
!function(factory) {
|
|
||||||
factory();
|
|
||||||
}( function() {
|
|
||||||
return function(fn) {
|
|
||||||
fn()().prop();
|
|
||||||
}( function() {
|
|
||||||
function bar() {
|
|
||||||
var quux = function() {
|
|
||||||
console.log("PASS");
|
|
||||||
}, foo = function() {
|
|
||||||
console.log;
|
|
||||||
quux();
|
|
||||||
};
|
|
||||||
return { prop: foo };
|
|
||||||
}
|
|
||||||
return bar;
|
|
||||||
} );
|
|
||||||
});
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2226_1: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f1() {
|
|
||||||
var a = b;
|
|
||||||
a += c;
|
|
||||||
}
|
|
||||||
function f2(a) {
|
|
||||||
a <<= b;
|
|
||||||
}
|
|
||||||
function f3(a) {
|
|
||||||
--a;
|
|
||||||
}
|
|
||||||
function f4() {
|
|
||||||
var a = b;
|
|
||||||
return a *= c;
|
|
||||||
}
|
|
||||||
function f5(a) {
|
|
||||||
x(a /= b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f1() {
|
|
||||||
b;
|
|
||||||
c;
|
|
||||||
}
|
|
||||||
function f2(a) {
|
|
||||||
b;
|
|
||||||
}
|
|
||||||
function f3(a) {
|
|
||||||
0;
|
|
||||||
}
|
|
||||||
function f4() {
|
|
||||||
var a = b;
|
|
||||||
return a *= c;
|
|
||||||
}
|
|
||||||
function f5(a) {
|
|
||||||
x(a /= b);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2226_2: {
|
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
@@ -1245,137 +1237,19 @@ issue_2226_2: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function(a, b) {
|
function f() {
|
||||||
a += b;
|
const a = 1;
|
||||||
|
a = 2;
|
||||||
return a;
|
return a;
|
||||||
}(1, 2));
|
}
|
||||||
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function(a, b) {
|
function f() {
|
||||||
return a += b;
|
const a = 1;
|
||||||
}(1, 2));
|
return a = 2, a;
|
||||||
}
|
}
|
||||||
expect_stdout: "3"
|
console.log(f());
|
||||||
}
|
|
||||||
|
|
||||||
issue_2226_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function(a, b) {
|
|
||||||
a += b;
|
|
||||||
return a;
|
|
||||||
}(1, 2));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(function(a, b) {
|
|
||||||
return a += 2;
|
|
||||||
}(1));
|
|
||||||
}
|
|
||||||
expect_stdout: "3"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2288: {
|
|
||||||
options = {
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
beautify: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo(o) {
|
|
||||||
for (var j = o.a, i = 0; i < 0; i++);
|
|
||||||
for (var i = 0; i < 0; i++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo(o) {
|
|
||||||
o.a;
|
|
||||||
for (var i = 0; i < 0; i++);
|
|
||||||
for (i = 0; i < 0; i++);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2516_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo() {
|
|
||||||
function qux(x) {
|
|
||||||
bar.call(null, x);
|
|
||||||
}
|
|
||||||
function bar(x) {
|
|
||||||
var FOUR = 4;
|
|
||||||
var trouble = x || never_called();
|
|
||||||
var value = (FOUR - 1) * trouble;
|
|
||||||
console.log(value == 6 ? "PASS" : value);
|
|
||||||
}
|
|
||||||
Baz = qux;
|
|
||||||
}
|
|
||||||
var Baz;
|
|
||||||
foo();
|
|
||||||
Baz(2);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo() {
|
|
||||||
Baz = function(x) {
|
|
||||||
(function(x) {
|
|
||||||
var trouble = x || never_called();
|
|
||||||
var value = (4 - 1) * trouble;
|
|
||||||
console.log(6 == value ? "PASS" : value);
|
|
||||||
}).call(null, x);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var Baz;
|
|
||||||
foo();
|
|
||||||
Baz(2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2516_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
passes: 2,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo() {
|
|
||||||
function qux(x) {
|
|
||||||
bar.call(null, x);
|
|
||||||
}
|
|
||||||
function bar(x) {
|
|
||||||
var FOUR = 4;
|
|
||||||
var trouble = x || never_called();
|
|
||||||
var value = (FOUR - 1) * trouble;
|
|
||||||
console.log(value == 6 ? "PASS" : value);
|
|
||||||
}
|
|
||||||
Baz = qux;
|
|
||||||
}
|
|
||||||
var Baz;
|
|
||||||
foo();
|
|
||||||
Baz(2);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo() {
|
|
||||||
Baz = function(x) {
|
|
||||||
(function(x) {
|
|
||||||
var value = (4 - 1) * (x || never_called());
|
|
||||||
console.log(6 == value ? "PASS" : value);
|
|
||||||
}).call(null, x);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
var Baz;
|
|
||||||
foo();
|
|
||||||
Baz(2);
|
|
||||||
}
|
}
|
||||||
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
and: {
|
and: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -77,8 +76,7 @@ and: {
|
|||||||
|
|
||||||
or: {
|
or: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -160,8 +158,7 @@ or: {
|
|||||||
|
|
||||||
unary_prefix: {
|
unary_prefix: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
a = !0 && b;
|
a = !0 && b;
|
||||||
@@ -227,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,
|
||||||
@@ -253,27 +344,22 @@ unsafe_constant: {
|
|||||||
|
|
||||||
unsafe_object: {
|
unsafe_object: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
reduce_funcs: true,
|
unsafe : true
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { a: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:1}) + 1,
|
||||||
o.a + 1,
|
({a:1}).a + 1,
|
||||||
o.b + 1,
|
({a:1}).b + 1,
|
||||||
o.a.b + 1
|
({a:1}).a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { a: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:1}) + 1,
|
||||||
2,
|
2,
|
||||||
o.b + 1,
|
({a:1}).b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -282,27 +368,22 @@ unsafe_object: {
|
|||||||
|
|
||||||
unsafe_object_nested: {
|
unsafe_object_nested: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
reduce_funcs: true,
|
unsafe : true
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { a: { b: 1 } };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1}}) + 1,
|
||||||
o.a + 1,
|
({a:{b:1}}).a + 1,
|
||||||
o.b + 1,
|
({a:{b:1}}).b + 1,
|
||||||
o.a.b + 1
|
({a:{b:1}}).a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { a: { b: 1 } };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1}}) + 1,
|
||||||
o.a + 1,
|
({a:{b:1}}).a + 1,
|
||||||
o.b + 1,
|
({a:{b:1}}).b + 1,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -311,26 +392,21 @@ unsafe_object_nested: {
|
|||||||
|
|
||||||
unsafe_object_complex: {
|
unsafe_object_complex: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
reduce_funcs: true,
|
unsafe : true
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { a: { b: 1 }, b: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1},b:1}) + 1,
|
||||||
o.a + 1,
|
({a:{b:1},b:1}).a + 1,
|
||||||
o.b + 1,
|
({a:{b:1},b:1}).b + 1,
|
||||||
o.a.b + 1
|
({a:{b:1},b:1}).a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { a: { b: 1 }, b: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1},b:1}) + 1,
|
||||||
o.a + 1,
|
({a:{b:1},b:1}).a + 1,
|
||||||
2,
|
2,
|
||||||
2
|
2
|
||||||
);
|
);
|
||||||
@@ -340,27 +416,22 @@ unsafe_object_complex: {
|
|||||||
|
|
||||||
unsafe_object_repeated: {
|
unsafe_object_repeated: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
reduce_funcs: true,
|
unsafe : true
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var o = { a: { b: 1 }, a: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1},a:1}) + 1,
|
||||||
o.a + 1,
|
({a:{b:1},a:1}).a + 1,
|
||||||
o.b + 1,
|
({a:{b:1},a:1}).b + 1,
|
||||||
o.a.b + 1
|
({a:{b:1},a:1}).a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var o = { a: { b: 1 }, a: 1 };
|
|
||||||
console.log(
|
console.log(
|
||||||
o + 1,
|
({a:{b:1},a:1}) + 1,
|
||||||
2,
|
2,
|
||||||
o.b + 1,
|
({a:{b:1},a:1}).b + 1,
|
||||||
1..b + 1
|
1..b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -370,7 +441,6 @@ unsafe_object_repeated: {
|
|||||||
unsafe_object_accessor: {
|
unsafe_object_accessor: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
@@ -394,11 +464,10 @@ unsafe_object_accessor: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prop_function: {
|
unsafe_function: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
properties: true,
|
unsafe : true
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
@@ -411,9 +480,9 @@ prop_function: {
|
|||||||
expect: {
|
expect: {
|
||||||
console.log(
|
console.log(
|
||||||
({a:{b:1},b:function(){}}) + 1,
|
({a:{b:1},b:function(){}}) + 1,
|
||||||
({b:1}) + 1,
|
({a:{b:1},b:function(){}}).a + 1,
|
||||||
function(){} + 1,
|
({a:{b:1},b:function(){}}).b + 1,
|
||||||
2
|
({a:{b:1},b:function(){}}).a.b + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -639,11 +708,10 @@ unsafe_string_bad_index: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
prototype_function: {
|
unsafe_prototype_function: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate : true,
|
||||||
properties: true,
|
unsafe : true
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = ({valueOf: 0}) < 1;
|
var a = ({valueOf: 0}) < 1;
|
||||||
@@ -662,28 +730,25 @@ prototype_function: {
|
|||||||
var d = ({toString: 0}) + "";
|
var d = ({toString: 0}) + "";
|
||||||
var e = (({valueOf: 0}) + "")[2];
|
var e = (({valueOf: 0}) + "")[2];
|
||||||
var f = (({toString: 0}) + "")[2];
|
var f = (({toString: 0}) + "")[2];
|
||||||
var g = 0();
|
var g = ({valueOf: 0}).valueOf();
|
||||||
var h = 0();
|
var h = "" + ({toString: 0});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
call_args: {
|
call_args: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
const a = 1;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
+function(a) {
|
+function(a) {
|
||||||
return a;
|
return a;
|
||||||
}(a);
|
}(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
const a = 1;
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+(1, 1);
|
+(1, 1);
|
||||||
}
|
}
|
||||||
@@ -693,21 +758,19 @@ call_args: {
|
|||||||
call_args_drop_param: {
|
call_args_drop_param: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 1;
|
const a = 1;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
+function(a) {
|
+function(a) {
|
||||||
return a;
|
return a;
|
||||||
}(a, b);
|
}(a, b);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
const a = 1;
|
||||||
console.log(1);
|
console.log(1);
|
||||||
+(b, 1);
|
+(b, 1);
|
||||||
}
|
}
|
||||||
@@ -810,15 +873,13 @@ unsafe_charAt_noop: {
|
|||||||
input: {
|
input: {
|
||||||
console.log(
|
console.log(
|
||||||
s.charAt(0),
|
s.charAt(0),
|
||||||
"string".charAt(x),
|
"string".charAt(x)
|
||||||
(typeof x).charAt()
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(
|
console.log(
|
||||||
s.charAt(0),
|
s.charAt(0),
|
||||||
"string".charAt(x),
|
"string".charAt(x)
|
||||||
(typeof x)[0]
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1022,321 +1083,3 @@ Infinity_NaN_undefined_LHS: {
|
|||||||
"}",
|
"}",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1964_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unsafe_regexp: false,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
var long_variable_name = /\s/;
|
|
||||||
console.log(long_variable_name.source);
|
|
||||||
return "a b c".split(long_variable_name)[1];
|
|
||||||
}
|
|
||||||
console.log(f());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
var long_variable_name = /\s/;
|
|
||||||
console.log(long_variable_name.source);
|
|
||||||
return "a b c".split(long_variable_name)[1];
|
|
||||||
}
|
|
||||||
console.log(f());
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"\\s",
|
|
||||||
"b",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1964_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unsafe_regexp: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
var long_variable_name = /\s/;
|
|
||||||
console.log(long_variable_name.source);
|
|
||||||
return "a b c".split(long_variable_name)[1];
|
|
||||||
}
|
|
||||||
console.log(f());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
console.log(/\s/.source);
|
|
||||||
return "a b c".split(/\s/)[1];
|
|
||||||
}
|
|
||||||
console.log(f());
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"\\s",
|
|
||||||
"b",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
array_slice_index: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log([1,2,3].slice(1)[1]);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
expect_stdout: "3"
|
|
||||||
}
|
|
||||||
|
|
||||||
string_charCodeAt: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log("foo".charCodeAt("bar".length));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(NaN);
|
|
||||||
}
|
|
||||||
expect_stdout: "NaN"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2207_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(String.fromCharCode(65));
|
|
||||||
console.log(Math.max(3, 6, 2, 7, 3, 4));
|
|
||||||
console.log(Math.cos(1.2345));
|
|
||||||
console.log(Math.cos(1.2345) - Math.sin(4.321));
|
|
||||||
console.log(Math.pow(Math.PI, Math.E - Math.LN10));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log("A");
|
|
||||||
console.log(7);
|
|
||||||
console.log(Math.cos(1.2345));
|
|
||||||
console.log(1.2543732512566947);
|
|
||||||
console.log(1.6093984514472044);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2207_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(Math.E);
|
|
||||||
console.log(Math.LN10);
|
|
||||||
console.log(Math.LN2);
|
|
||||||
console.log(Math.LOG2E);
|
|
||||||
console.log(Math.LOG10E);
|
|
||||||
console.log(Math.PI);
|
|
||||||
console.log(Math.SQRT1_2);
|
|
||||||
console.log(Math.SQRT2);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(Math.E);
|
|
||||||
console.log(Math.LN10);
|
|
||||||
console.log(Math.LN2);
|
|
||||||
console.log(Math.LOG2E);
|
|
||||||
console.log(Math.LOG10E);
|
|
||||||
console.log(Math.PI);
|
|
||||||
console.log(Math.SQRT1_2);
|
|
||||||
console.log(Math.SQRT2);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2207_3: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(Number.MAX_VALUE);
|
|
||||||
console.log(Number.MIN_VALUE);
|
|
||||||
console.log(Number.NaN);
|
|
||||||
console.log(Number.NEGATIVE_INFINITY);
|
|
||||||
console.log(Number.POSITIVE_INFINITY);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(Number.MAX_VALUE);
|
|
||||||
console.log(5e-324);
|
|
||||||
console.log(NaN);
|
|
||||||
console.log(-1/0);
|
|
||||||
console.log(1/0);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2231_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(Object.keys(void 0));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(Object.keys(void 0));
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2231_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
unsafe: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(Object.getOwnPropertyNames(null));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(Object.getOwnPropertyNames(null));
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
self_comparison_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = { n: NaN };
|
|
||||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(false, false, true, true, "number");
|
|
||||||
}
|
|
||||||
expect_stdout: "false false true true 'number'"
|
|
||||||
}
|
|
||||||
|
|
||||||
self_comparison_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = { n: NaN };
|
|
||||||
console.log(o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n, typeof o.n);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(false, false, true, true, "number");
|
|
||||||
}
|
|
||||||
expect_stdout: "false false true true 'number'"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2535_1: {
|
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
evaluate: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
if ((x() || true) || y()) z();
|
|
||||||
if ((x() || true) && y()) z();
|
|
||||||
if ((x() && true) || y()) z();
|
|
||||||
if ((x() && true) && y()) z();
|
|
||||||
if ((x() || false) || y()) z();
|
|
||||||
if ((x() || false) && y()) z();
|
|
||||||
if ((x() && false) || y()) z();
|
|
||||||
if ((x() && false) && y()) z();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
if (x(), 1) z();
|
|
||||||
if (x(), y()) z();
|
|
||||||
if (x() || y()) z();
|
|
||||||
if (x() && y()) z();
|
|
||||||
if (x() || y()) z();
|
|
||||||
if (x() && y()) z();
|
|
||||||
if (x(), y()) z();
|
|
||||||
if (x(), 0) z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2535_2: {
|
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
evaluate: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(x() || true) || y();
|
|
||||||
(x() || true) && y();
|
|
||||||
(x() && true) || y();
|
|
||||||
(x() && true) && y();
|
|
||||||
(x() || false) || y();
|
|
||||||
(x() || false) && y();
|
|
||||||
(x() && false) || y();
|
|
||||||
(x() && false) && y();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
x(),
|
|
||||||
x(), y(),
|
|
||||||
x() || y(),
|
|
||||||
x() && y(),
|
|
||||||
x() || y(),
|
|
||||||
x() && y(),
|
|
||||||
x(), y(),
|
|
||||||
x();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2535_3: {
|
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
evaluate: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(Object(1) && 1 && 2);
|
|
||||||
console.log(Object(1) && true && 1 && 2 && Object(2));
|
|
||||||
console.log(Object(1) && true && 1 && null && 2 && Object(2));
|
|
||||||
console.log(2 == Object(1) || 0 || void 0 || null);
|
|
||||||
console.log(2 == Object(1) || 0 || void 0 || null || Object(2));
|
|
||||||
console.log(2 == Object(1) || 0 || void 0 || "ok" || null || Object(2));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(Object(1) && 2);
|
|
||||||
console.log(Object(1) && Object(2));
|
|
||||||
console.log(Object(1) && null);
|
|
||||||
console.log(2 == Object(1) || null);
|
|
||||||
console.log(2 == Object(1) || Object(2));
|
|
||||||
console.log(2 == Object(1) || "ok");
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
expect_warnings: [
|
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1316,20]",
|
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1317,20]",
|
|
||||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1318,20]",
|
|
||||||
"WARN: Condition left of && always false [test/compress/evaluate.js:1318,20]",
|
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1319,20]",
|
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1320,20]",
|
|
||||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:1321,20]",
|
|
||||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1321,20]",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,10 +19,8 @@ iifes_returning_constants_keep_fargs_true: {
|
|||||||
booleans : true,
|
booleans : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
reduce_funcs : true,
|
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
cascade : true,
|
cascade : true,
|
||||||
inline : true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(){ return -1.23; }());
|
(function(){ return -1.23; }());
|
||||||
@@ -56,10 +54,8 @@ iifes_returning_constants_keep_fargs_false: {
|
|||||||
booleans : true,
|
booleans : true,
|
||||||
if_return : true,
|
if_return : true,
|
||||||
join_vars : true,
|
join_vars : true,
|
||||||
reduce_funcs : true,
|
|
||||||
reduce_vars : true,
|
reduce_vars : true,
|
||||||
cascade : true,
|
cascade : true,
|
||||||
inline : true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(){ return -1.23; }());
|
(function(){ return -1.23; }());
|
||||||
@@ -86,8 +82,6 @@ issue_485_crashing_1530: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
(function(a) {
|
(function(a) {
|
||||||
@@ -95,14 +89,15 @@ issue_485_crashing_1530: {
|
|||||||
var b = 42;
|
var b = 42;
|
||||||
})(this);
|
})(this);
|
||||||
}
|
}
|
||||||
expect: {}
|
expect: {
|
||||||
|
this, void 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1841_1: {
|
issue_1841_1: {
|
||||||
options = {
|
options = {
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -129,7 +124,6 @@ issue_1841_2: {
|
|||||||
options = {
|
options = {
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
pure_getters: false,
|
pure_getters: false,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -154,13 +148,11 @@ issue_1841_2: {
|
|||||||
|
|
||||||
function_returning_constant_literal: {
|
function_returning_constant_literal: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
properties: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
unsafe: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
|
evaluate: true,
|
||||||
|
cascade: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -175,480 +167,3 @@ function_returning_constant_literal: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "Hello there"
|
expect_stdout: "Hello there"
|
||||||
}
|
}
|
||||||
|
|
||||||
hoist_funs: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
function f() {}
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
function g() {}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1 'function' 'function'",
|
|
||||||
"2 'function' 'function'",
|
|
||||||
"4 'function' 'function'",
|
|
||||||
"5 'function' 'function'",
|
|
||||||
"6 'function' 'function'",
|
|
||||||
]
|
|
||||||
node_version: "<=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
hoist_funs_strict: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
function f() {}
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
function g() {}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function g() {}
|
|
||||||
console.log(1, typeof f, typeof g);
|
|
||||||
if (console.log(2, typeof f, typeof g))
|
|
||||||
console.log(3, typeof f, typeof g);
|
|
||||||
else {
|
|
||||||
console.log(4, typeof f, typeof g);
|
|
||||||
function f() {}
|
|
||||||
console.log(5, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
console.log(6, typeof f, typeof g);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1 'undefined' 'function'",
|
|
||||||
"2 'undefined' 'function'",
|
|
||||||
"4 'function' 'function'",
|
|
||||||
"5 'function' 'function'",
|
|
||||||
"6 'undefined' 'function'",
|
|
||||||
]
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_203: {
|
|
||||||
options = {
|
|
||||||
keep_fargs: false,
|
|
||||||
side_effects: true,
|
|
||||||
unsafe_Func: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var m = {};
|
|
||||||
var fn = Function("require", "module", "exports", "module.exports = 42;");
|
|
||||||
fn(null, m, m.exports);
|
|
||||||
console.log(m.exports);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var m = {};
|
|
||||||
var fn = Function("n,o", "o.exports=42");
|
|
||||||
fn(null, m, m.exports);
|
|
||||||
console.log(m.exports);
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
no_webkit: {
|
|
||||||
beautify = {
|
|
||||||
webkit: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function() {
|
|
||||||
1 + 1;
|
|
||||||
}.a = 1);
|
|
||||||
}
|
|
||||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
webkit: {
|
|
||||||
beautify = {
|
|
||||||
webkit: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function() {
|
|
||||||
1 + 1;
|
|
||||||
}.a = 1);
|
|
||||||
}
|
|
||||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2084: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
conditionals: true,
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var c = 0;
|
|
||||||
!function() {
|
|
||||||
!function(c) {
|
|
||||||
c = 1 + c;
|
|
||||||
var c = 0;
|
|
||||||
function f14(a_1) {
|
|
||||||
if (c = 1 + c, 0 !== 23..toString())
|
|
||||||
c = 1 + c, a_1 && (a_1[0] = 0);
|
|
||||||
}
|
|
||||||
f14();
|
|
||||||
}(-1);
|
|
||||||
}();
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var c = 0;
|
|
||||||
!function(c) {
|
|
||||||
c = 1 + c,
|
|
||||||
c = 1 + (c = 0),
|
|
||||||
0 !== 23..toString() && (c = 1 + c);
|
|
||||||
}(-1),
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: "0"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2097: {
|
|
||||||
options = {
|
|
||||||
negate_iife: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (e) {
|
|
||||||
console.log(arguments[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f(1);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
!function() {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (e) {
|
|
||||||
console.log(arguments[0]);
|
|
||||||
}
|
|
||||||
}(1);
|
|
||||||
}
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2101: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
a = {};
|
|
||||||
console.log(function() {
|
|
||||||
return function() {
|
|
||||||
return this.a;
|
|
||||||
}();
|
|
||||||
}() === function() {
|
|
||||||
return a;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
a = {};
|
|
||||||
console.log(function() {
|
|
||||||
return this.a;
|
|
||||||
}() === a);
|
|
||||||
}
|
|
||||||
expect_stdout: "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
inner_ref: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function(a) {
|
|
||||||
return function() {
|
|
||||||
return a;
|
|
||||||
}();
|
|
||||||
}(1), function(a) {
|
|
||||||
return function(a) {
|
|
||||||
return a;
|
|
||||||
}();
|
|
||||||
}(2));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(function(a) {
|
|
||||||
return a;
|
|
||||||
}(1), function(a) {
|
|
||||||
return a;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_stdout: "1 undefined"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2107: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var c = 0;
|
|
||||||
!function() {
|
|
||||||
c++;
|
|
||||||
}(c++ + new function() {
|
|
||||||
this.a = 0;
|
|
||||||
var a = (c = c + 1) + (c = 1 + c);
|
|
||||||
return c++ + a;
|
|
||||||
}());
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var c = 0;
|
|
||||||
c++, new function() {
|
|
||||||
this.a = 0, c = 1 + (c += 1), c++;
|
|
||||||
}(), c++, console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: "5"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2114_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
if_return: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var c = 0;
|
|
||||||
!function(a) {
|
|
||||||
a = 0;
|
|
||||||
}([ {
|
|
||||||
0: c = c + 1,
|
|
||||||
length: c = 1 + c
|
|
||||||
}, typeof void function a() {
|
|
||||||
var b = function f1(a) {
|
|
||||||
}(b && (b.b += (c = c + 1, 0)));
|
|
||||||
}() ]);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var c = 0;
|
|
||||||
c = 1 + (c += 1), function() {
|
|
||||||
var b = void (b && (b.b += (c += 1, 0)));
|
|
||||||
}();
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2114_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
if_return: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
passes: 2,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var c = 0;
|
|
||||||
!function(a) {
|
|
||||||
a = 0;
|
|
||||||
}([ {
|
|
||||||
0: c = c + 1,
|
|
||||||
length: c = 1 + c
|
|
||||||
}, typeof void function a() {
|
|
||||||
var b = function f1(a) {
|
|
||||||
}(b && (b.b += (c = c + 1, 0)));
|
|
||||||
}() ]);
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var c = 0;
|
|
||||||
c = 1 + (c += 1), function() {
|
|
||||||
var b = void (b && (b.b += (c += 1, 0)));
|
|
||||||
}();
|
|
||||||
console.log(c);
|
|
||||||
}
|
|
||||||
expect_stdout: "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2428: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 3,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unsafe: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function bar(k) {
|
|
||||||
console.log(k);
|
|
||||||
}
|
|
||||||
function foo(x) {
|
|
||||||
return bar(x);
|
|
||||||
}
|
|
||||||
function baz(a) {
|
|
||||||
foo(a);
|
|
||||||
}
|
|
||||||
baz(42);
|
|
||||||
baz("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function baz(a) {
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
baz(42);
|
|
||||||
baz("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"42",
|
|
||||||
"PASS",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2531_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function outer() {
|
|
||||||
function inner(value) {
|
|
||||||
function closure() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return function() {
|
|
||||||
return closure();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return inner("Hello");
|
|
||||||
}
|
|
||||||
console.log("Greeting:", outer()());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function outer() {
|
|
||||||
return function(value) {
|
|
||||||
return function() {
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
}("Hello");
|
|
||||||
}
|
|
||||||
console.log("Greeting:", outer()());
|
|
||||||
}
|
|
||||||
expect_stdout: "Greeting: Hello"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2531_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function outer() {
|
|
||||||
function inner(value) {
|
|
||||||
function closure() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return function() {
|
|
||||||
return closure();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return inner("Hello");
|
|
||||||
}
|
|
||||||
console.log("Greeting:", outer()());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function outer() {
|
|
||||||
return function() {
|
|
||||||
return "Hello";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
console.log("Greeting:", outer()());
|
|
||||||
}
|
|
||||||
expect_stdout: "Greeting: Hello"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2531_3: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function outer() {
|
|
||||||
function inner(value) {
|
|
||||||
function closure() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
return function() {
|
|
||||||
return closure();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return inner("Hello");
|
|
||||||
}
|
|
||||||
console.log("Greeting:", outer()());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log("Greeting:", "Hello");
|
|
||||||
}
|
|
||||||
expect_stdout: "Greeting: Hello"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ object: {
|
|||||||
VALUE: 42,
|
VALUE: 42,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
side_effects: true,
|
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -121,7 +120,7 @@ mixed: {
|
|||||||
properties: true,
|
properties: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var FOO = { BAR: 0 };
|
const FOO = { BAR: 0 };
|
||||||
console.log(FOO.BAR);
|
console.log(FOO.BAR);
|
||||||
console.log(++CONFIG.DEBUG);
|
console.log(++CONFIG.DEBUG);
|
||||||
console.log(++CONFIG.VALUE);
|
console.log(++CONFIG.VALUE);
|
||||||
@@ -131,7 +130,7 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var FOO = { BAR: 0 };
|
const FOO = { BAR: 0 };
|
||||||
console.log("moo");
|
console.log("moo");
|
||||||
console.log(++CONFIG.DEBUG);
|
console.log(++CONFIG.DEBUG);
|
||||||
console.log(++CONFIG.VALUE);
|
console.log(++CONFIG.VALUE);
|
||||||
@@ -141,9 +140,9 @@ mixed: {
|
|||||||
console.log(CONFIG);
|
console.log(CONFIG);
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:126,22]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:127,22]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:128,22]',
|
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:129,8]',
|
||||||
'WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:130,8]',
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,39 +160,3 @@ issue_1801: {
|
|||||||
console.log(!0);
|
console.log(!0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1986: {
|
|
||||||
options = {
|
|
||||||
global_defs: {
|
|
||||||
"@alert": "console.log",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
alert(42);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2167: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
dead_code: true,
|
|
||||||
evaluate: true,
|
|
||||||
global_defs: {
|
|
||||||
"@isDevMode": "function(){}",
|
|
||||||
},
|
|
||||||
passes: 2,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
if (isDevMode()) {
|
|
||||||
greetOverlord();
|
|
||||||
}
|
|
||||||
doWork();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
doWork();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,666 +0,0 @@
|
|||||||
issue_2377_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj = {
|
|
||||||
foo: 1,
|
|
||||||
bar: 2,
|
|
||||||
square: function(x) {
|
|
||||||
return x * x;
|
|
||||||
},
|
|
||||||
cube: function(x) {
|
|
||||||
return x * x * x;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
console.log(obj.foo, obj.cube(3));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var obj_foo = 1, obj_cube = function(x) {
|
|
||||||
return x * x * x;
|
|
||||||
};
|
|
||||||
console.log(obj_foo, obj_cube(3));
|
|
||||||
}
|
|
||||||
expect_stdout: "1 27"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2377_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
hoist_props: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj = {
|
|
||||||
foo: 1,
|
|
||||||
bar: 2,
|
|
||||||
square: function(x) {
|
|
||||||
return x * x;
|
|
||||||
},
|
|
||||||
cube: function(x) {
|
|
||||||
return x * x * x;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
console.log(obj.foo, obj.cube(3));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, function(x) {
|
|
||||||
return x * x * x;
|
|
||||||
}(3));
|
|
||||||
}
|
|
||||||
expect_stdout: "1 27"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2377_3: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
hoist_props: true,
|
|
||||||
passes: 3,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj = {
|
|
||||||
foo: 1,
|
|
||||||
bar: 2,
|
|
||||||
square: function(x) {
|
|
||||||
return x * x;
|
|
||||||
},
|
|
||||||
cube: function(x) {
|
|
||||||
return x * x * x;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
console.log(obj.foo, obj.cube(3));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, 27);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 27"
|
|
||||||
}
|
|
||||||
|
|
||||||
direct_access_1: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 0;
|
|
||||||
var obj = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
for (var k in obj) a++;
|
|
||||||
console.log(a, obj.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 0;
|
|
||||||
var obj = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
for (var k in obj) a++;
|
|
||||||
console.log(a, obj.a);
|
|
||||||
}
|
|
||||||
expect_stdout: "2 1"
|
|
||||||
}
|
|
||||||
|
|
||||||
direct_access_2: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = { a: 1 };
|
|
||||||
var f = function(k) {
|
|
||||||
if (o[k]) return "PASS";
|
|
||||||
};
|
|
||||||
console.log(f("a"));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = { a: 1 };
|
|
||||||
console.log(function(k) {
|
|
||||||
if (o[k]) return "PASS";
|
|
||||||
}("a"));
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
direct_access_3: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = { a: 1 };
|
|
||||||
o.b;
|
|
||||||
console.log(o.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = { a: 1 };
|
|
||||||
o.b;
|
|
||||||
console.log(o.a);
|
|
||||||
}
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
single_use: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj = {
|
|
||||||
bar: function() {
|
|
||||||
return 42;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
console.log(obj.bar());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log({
|
|
||||||
bar: function() {
|
|
||||||
return 42;
|
|
||||||
},
|
|
||||||
}.bar());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
name_collision_1: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var obj_foo = 1;
|
|
||||||
var obj_bar = 2;
|
|
||||||
function f() {
|
|
||||||
var obj = {
|
|
||||||
foo: 3,
|
|
||||||
bar: 4,
|
|
||||||
"b-r": 5,
|
|
||||||
"b+r": 6,
|
|
||||||
"b!r": 7,
|
|
||||||
};
|
|
||||||
console.log(obj_foo, obj.foo, obj.bar, obj["b-r"], obj["b+r"], obj["b!r"]);
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var obj_foo = 1;
|
|
||||||
var obj_bar = 2;
|
|
||||||
function f() {
|
|
||||||
var obj_foo$0 = 3,
|
|
||||||
obj_bar = 4,
|
|
||||||
obj_b_r = 5,
|
|
||||||
obj_b_r$0 = 6,
|
|
||||||
obj_b_r$1 = 7;
|
|
||||||
console.log(obj_foo, obj_foo$0, obj_bar, obj_b_r, obj_b_r$0, obj_b_r$1);
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_stdout: "1 3 4 5 6 7"
|
|
||||||
}
|
|
||||||
|
|
||||||
name_collision_2: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
p: 1,
|
|
||||||
0: function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
1: function(x) {
|
|
||||||
return x + 1;
|
|
||||||
}
|
|
||||||
}, o__$0 = 2, o__$1 = 3;
|
|
||||||
console.log(o.p === o.p, o[0](4), o[1](5), o__$0, o__$1);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o_p = 1,
|
|
||||||
o__ = function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
o__$2 = function(x) {
|
|
||||||
return x + 1;
|
|
||||||
},
|
|
||||||
o__$0 = 2,
|
|
||||||
o__$1 = 3;
|
|
||||||
console.log(o_p === o_p, o__(4), o__$2(5), o__$0, o__$1);
|
|
||||||
}
|
|
||||||
expect_stdout: "true 4 6 2 3"
|
|
||||||
}
|
|
||||||
|
|
||||||
name_collision_3: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
p: 1,
|
|
||||||
0: function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
1: function(x) {
|
|
||||||
return x + 1;
|
|
||||||
}
|
|
||||||
}, o__$0 = 2, o__$1 = 3;
|
|
||||||
console.log(o.p === o.p, o[0](4), o[1](5));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o_p = 1,
|
|
||||||
o__ = function(x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
o__$2 = function(x) {
|
|
||||||
return x + 1;
|
|
||||||
},
|
|
||||||
o__$0 = 2,
|
|
||||||
o__$1 = 3;
|
|
||||||
console.log(o_p === o_p, o__(4), o__$2(5));
|
|
||||||
}
|
|
||||||
expect_stdout: "true 4 6"
|
|
||||||
}
|
|
||||||
|
|
||||||
contains_this_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
u: function() {
|
|
||||||
return this === this;
|
|
||||||
},
|
|
||||||
p: 1
|
|
||||||
};
|
|
||||||
console.log(o.p, o.p);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, 1);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 1"
|
|
||||||
}
|
|
||||||
|
|
||||||
contains_this_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
u: function() {
|
|
||||||
return this === this;
|
|
||||||
},
|
|
||||||
p: 1
|
|
||||||
};
|
|
||||||
console.log(o.p, o.p, o.u);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1, 1, function() {
|
|
||||||
return this === this;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
contains_this_3: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
u: function() {
|
|
||||||
return this === this;
|
|
||||||
},
|
|
||||||
p: 1
|
|
||||||
};
|
|
||||||
console.log(o.p, o.p, o.u());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = {
|
|
||||||
u: function() {
|
|
||||||
return this === this;
|
|
||||||
},
|
|
||||||
p: 1
|
|
||||||
};
|
|
||||||
console.log(o.p, o.p, o.u());
|
|
||||||
}
|
|
||||||
expect_stdout: "1 1 true"
|
|
||||||
}
|
|
||||||
|
|
||||||
new_this: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
f: function(a) {
|
|
||||||
this.b = a;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(new o.f(o.a).b, o.b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(new function(a) {
|
|
||||||
this.b = a;
|
|
||||||
}(1).b, 2);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2473_1: {
|
|
||||||
options = {
|
|
||||||
hoist_props: false,
|
|
||||||
reduce_vars: true,
|
|
||||||
top_retain: [ "x", "y" ],
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var x = {};
|
|
||||||
var y = [];
|
|
||||||
var z = {};
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var x = {};
|
|
||||||
var y = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2473_2: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
top_retain: [ "x", "y" ],
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var x = {};
|
|
||||||
var y = [];
|
|
||||||
var z = {};
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var x = {};
|
|
||||||
var y = [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2473_3: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
top_retain: "o",
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
console.log(o.a, o.b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
console.log(o.a, o.b);
|
|
||||||
}
|
|
||||||
expect_stdout: "1 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2473_4: {
|
|
||||||
options = {
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
top_retain: "o",
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function() {
|
|
||||||
var o = {
|
|
||||||
a: 1,
|
|
||||||
b: 2,
|
|
||||||
};
|
|
||||||
console.log(o.a, o.b);
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function() {
|
|
||||||
var o_a = 1, o_b = 2;
|
|
||||||
console.log(o_a, o_b);
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_stdout: "1 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2508_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: [ 1 ],
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function(x) {
|
|
||||||
console.log(x);
|
|
||||||
})([ 1 ]);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2508_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: { b: 2 },
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
(function(x) {
|
|
||||||
console.log(x);
|
|
||||||
})({ b: 2 });
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2508_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: [ o ],
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = {
|
|
||||||
a: [ o ],
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2508_4: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
a: { b: o },
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o = {
|
|
||||||
a: { b: o },
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.a);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2508_5: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = {
|
|
||||||
f: function(x) {
|
|
||||||
console.log(x);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
o.f(o.f);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var o_f = function(x) {
|
|
||||||
console.log(x);
|
|
||||||
};
|
|
||||||
o_f(o_f);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2519: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
hoist_props: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function testFunc() {
|
|
||||||
var dimensions = {
|
|
||||||
minX: 5,
|
|
||||||
maxX: 6,
|
|
||||||
};
|
|
||||||
var scale = 1;
|
|
||||||
var d = {
|
|
||||||
x: (dimensions.maxX + dimensions.minX) / 2,
|
|
||||||
};
|
|
||||||
return d.x * scale;
|
|
||||||
}
|
|
||||||
console.log(testFunc());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function testFunc() {
|
|
||||||
return 1 * ((6 + 5) / 2);
|
|
||||||
}
|
|
||||||
console.log(testFunc());
|
|
||||||
}
|
|
||||||
expect_stdout: "5.5"
|
|
||||||
}
|
|
||||||
@@ -88,24 +88,3 @@ sequences_funs: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2295: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
hoist_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo(o) {
|
|
||||||
var a = o.a;
|
|
||||||
if (a) return a;
|
|
||||||
var a = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo(o) {
|
|
||||||
var a = o.a;
|
|
||||||
if (a) return a;
|
|
||||||
a = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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;"
|
||||||
|
}
|
||||||
|
|||||||
@@ -302,27 +302,3 @@ issue_1437_conditionals: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_512: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
if_return: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function a() {
|
|
||||||
if (b()) {
|
|
||||||
c();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function a() {
|
|
||||||
if (!b()) throw e;
|
|
||||||
c();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
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(")");'
|
||||||
|
}
|
||||||
@@ -71,13 +71,11 @@ non_hoisted_function_after_return_2a: {
|
|||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:51,16]",
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
"WARN: Dropping unused variable a [test/compress/issue-1034.js:48,20]",
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
"WARN: Dropping unused function nope [test/compress/issue-1034.js:55,21]",
|
||||||
"WARN: pass 0: last_count: Infinity, count: 37",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:53,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:56,12]",
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
"WARN: Dropping unused variable b [test/compress/issue-1034.js:51,20]",
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||||
"WARN: pass 1: last_count: 37, count: 18",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,146 +109,10 @@ non_hoisted_function_after_return_2b: {
|
|||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
// duplicate warnings no longer emitted
|
// duplicate warnings no longer emitted
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:95,16]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:95,16]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,12]",
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
|
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,12]",
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
|
"WARN: Dropping unreachable code [test/compress/issue-1034.js:101,12]",
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
non_hoisted_function_after_return_strict: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
if (x) {
|
|
||||||
return bar();
|
|
||||||
not_called1();
|
|
||||||
} else {
|
|
||||||
return baz();
|
|
||||||
not_called2();
|
|
||||||
}
|
|
||||||
function bar() { return 7; }
|
|
||||||
return not_reached;
|
|
||||||
function UnusedFunction() {}
|
|
||||||
function baz() { return 8; }
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
return x ? bar() : baz();
|
|
||||||
function bar() { return 7 }
|
|
||||||
function baz() { return 8 }
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect_stdout: "8 7"
|
|
||||||
expect_warnings: [
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:133,16]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:136,16]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:139,12]",
|
|
||||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:140,21]",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
non_hoisted_function_after_return_2a_strict: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
|
||||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
if (x) {
|
|
||||||
return bar(1);
|
|
||||||
var a = not_called(1);
|
|
||||||
} else {
|
|
||||||
return bar(2);
|
|
||||||
var b = not_called(2);
|
|
||||||
}
|
|
||||||
var c = bar(3);
|
|
||||||
function bar(x) { return 7 - x; }
|
|
||||||
function nope() {}
|
|
||||||
return b || c;
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
return bar(x ? 1 : 2);
|
|
||||||
function bar(x) {
|
|
||||||
return 7 - x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect_stdout: "5 6"
|
|
||||||
expect_warnings: [
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:175,16]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:175,16]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:178,16]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:178,16]",
|
|
||||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:175,20]",
|
|
||||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:182,21]",
|
|
||||||
"WARN: pass 0: last_count: Infinity, count: 48",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:180,12]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:180,12]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:183,12]",
|
|
||||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:178,20]",
|
|
||||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:180,16]",
|
|
||||||
"WARN: pass 1: last_count: 48, count: 29",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
non_hoisted_function_after_return_2b_strict: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
|
||||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
|
||||||
if_return: true, join_vars: true, cascade: true, side_effects: true,
|
|
||||||
collapse_vars: false
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
if (x) {
|
|
||||||
return bar(1);
|
|
||||||
} else {
|
|
||||||
return bar(2);
|
|
||||||
var b;
|
|
||||||
}
|
|
||||||
var c = bar(3);
|
|
||||||
function bar(x) {
|
|
||||||
return 7 - x;
|
|
||||||
}
|
|
||||||
return b || c;
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
function foo(x) {
|
|
||||||
return bar(x ? 1 : 2);
|
|
||||||
function bar(x) { return 7 - x; }
|
|
||||||
}
|
|
||||||
console.log(foo(0), foo(1));
|
|
||||||
}
|
|
||||||
expect_stdout: "5 6"
|
|
||||||
expect_warnings: [
|
|
||||||
// duplicate warnings no longer emitted
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:229,16]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:229,16]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:231,12]",
|
|
||||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:231,12]",
|
|
||||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:235,12]",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,19 @@
|
|||||||
|
const_declaration: {
|
||||||
|
options = {
|
||||||
|
evaluate: true
|
||||||
|
};
|
||||||
|
|
||||||
|
input: {
|
||||||
|
const goog = goog || {};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const goog = goog || {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const_pragma: {
|
const_pragma: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -17,7 +29,6 @@ const_pragma: {
|
|||||||
not_const: {
|
not_const: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,91 +1,90 @@
|
|||||||
multiple_functions: {
|
multiple_functions: {
|
||||||
options = {
|
options = { if_return: true, hoist_funs: false };
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
|
function f() {}
|
||||||
|
function g() {}
|
||||||
|
|
||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window );
|
if ( window );
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
single_function: {
|
single_function: {
|
||||||
options = {
|
options = { if_return: true, hoist_funs: false };
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( window );
|
|
||||||
function f() {}
|
function f() {}
|
||||||
|
|
||||||
|
if ( window );
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deeply_nested: {
|
deeply_nested: {
|
||||||
options = {
|
options = { if_return: true, hoist_funs: false };
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function f() {}
|
function f() {}
|
||||||
function g() {}
|
function g() {}
|
||||||
|
|
||||||
if ( !document ) {
|
if ( !document ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
function h() {}
|
function h() {}
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
( function() {
|
( function() {
|
||||||
|
function f() {}
|
||||||
|
function g() {}
|
||||||
|
|
||||||
|
function h() {}
|
||||||
|
|
||||||
// NOTE: other compression steps will reduce this
|
// NOTE: other compression steps will reduce this
|
||||||
// down to just `window`.
|
// down to just `window`.
|
||||||
if ( window )
|
if ( window )
|
||||||
if (document);
|
if (document);
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
function h() {}
|
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
not_hoisted_when_already_nested: {
|
not_hoisted_when_already_nested: {
|
||||||
options = {
|
options = { if_return: true, hoist_funs: false };
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
( function() {
|
( function() {
|
||||||
if ( !window ) {
|
if ( !window ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( foo ) function f() {}
|
if ( foo ) function f() {}
|
||||||
|
|
||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -95,70 +94,3 @@ not_hoisted_when_already_nested: {
|
|||||||
} )();
|
} )();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defun_if_return: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
if (!window) return;
|
|
||||||
else function g() {}
|
|
||||||
function h() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
if (window) function g() {}
|
|
||||||
function h() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defun_hoist_funs: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: true,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
if (!window) return;
|
|
||||||
else function g() {}
|
|
||||||
function h() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
function g() {}
|
|
||||||
function h() {}
|
|
||||||
if (window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
defun_else_if_return: {
|
|
||||||
options = {
|
|
||||||
hoist_funs: false,
|
|
||||||
if_return: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
if (window) function g() {}
|
|
||||||
else return;
|
|
||||||
function h() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function e() {
|
|
||||||
function f() {}
|
|
||||||
if (window) function g() {}
|
|
||||||
function h() {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -96,13 +96,6 @@ pure_function_calls_toplevel: {
|
|||||||
})();
|
})();
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// pure top-level calls will be dropped regardless of the leading comments position
|
|
||||||
var MyClass = /*#__PURE__*//*@class*/(function(){
|
|
||||||
function MyClass() {}
|
|
||||||
MyClass.prototype.method = function() {};
|
|
||||||
return MyClass;
|
|
||||||
})();
|
|
||||||
|
|
||||||
// comment #__PURE__ comment
|
// comment #__PURE__ comment
|
||||||
bar(), baz(), quux();
|
bar(), baz(), quux();
|
||||||
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
a.b(), /* @__PURE__ */ c.d.e(), f.g();
|
||||||
@@ -117,12 +110,10 @@ pure_function_calls_toplevel: {
|
|||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:92,37]",
|
||||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:92,16]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:90,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:107,8]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:108,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:101,31]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:84,33]",
|
||||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:84,12]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:100,45]",
|
|
||||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:100,12]",
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,29 +148,29 @@ should_warn: {
|
|||||||
baz();
|
baz();
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,61]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,61]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:128,23]",
|
||||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:137,23]",
|
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:128,23]",
|
||||||
"WARN: Boolean || always true [test/compress/issue-1261.js:138,23]",
|
"WARN: Boolean || always true [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:138,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:129,23]",
|
||||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:139,8]",
|
"WARN: Condition left of || always true [test/compress/issue-1261.js:130,8]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:139,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:130,8]",
|
||||||
"WARN: Boolean && always false [test/compress/issue-1261.js:140,23]",
|
"WARN: Boolean && always false [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:140,23]",
|
"WARN: Condition always false [test/compress/issue-1261.js:131,23]",
|
||||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:141,8]",
|
"WARN: Condition left of && always false [test/compress/issue-1261.js:132,8]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:141,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:132,8]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:142,23]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:133,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:133,23]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:142,23]",
|
"WARN: Condition always true [test/compress/issue-1261.js:133,23]",
|
||||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:143,8]",
|
"WARN: + in boolean context always true [test/compress/issue-1261.js:134,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:134,31]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:134,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,23]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:145,24]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,24]",
|
||||||
"WARN: Condition always true [test/compress/issue-1261.js:145,8]",
|
"WARN: Condition always true [test/compress/issue-1261.js:136,8]",
|
||||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:146,31]",
|
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:137,31]",
|
||||||
"WARN: Condition always false [test/compress/issue-1261.js:146,8]",
|
"WARN: Condition always false [test/compress/issue-1261.js:137,8]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
issue_1321_no_debug: {
|
issue_1321_no_debug: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
keep_quoted: true
|
||||||
keep_quoted: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -12,19 +10,17 @@ issue_1321_no_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.x = 1;
|
x.b = 1;
|
||||||
x["a"] = 2 * x.x;
|
x["a"] = 2 * x.b;
|
||||||
console.log(x.x, x["a"]);
|
console.log(x.b, x["a"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_debug: {
|
issue_1321_debug: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
keep_quoted: true,
|
||||||
debug: "",
|
debug: ""
|
||||||
keep_quoted: true,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -34,18 +30,16 @@ issue_1321_debug: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.x = 1;
|
x.a = 1;
|
||||||
x["_$foo$_"] = 2 * x.x;
|
x["_$foo$_"] = 2 * x.a;
|
||||||
console.log(x.x, x["_$foo$_"]);
|
console.log(x.a, x["_$foo$_"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1321_with_quoted: {
|
issue_1321_with_quoted: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
keep_quoted: false
|
||||||
keep_quoted: false,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var x = {};
|
var x = {};
|
||||||
@@ -55,9 +49,9 @@ issue_1321_with_quoted: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var x = {};
|
var x = {};
|
||||||
x.x = 1;
|
x.a = 1;
|
||||||
x["o"] = 2 * x.x;
|
x["b"] = 2 * x.a;
|
||||||
console.log(x.x, x["o"]);
|
console.log(x.a, x["b"]);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
typeof_eq_undefined: {
|
typeof_eq_undefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true
|
||||||
typeofs: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -25,7 +24,6 @@ typeof_eq_undefined_ie8: {
|
|||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
typeofs: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = typeof b != "undefined";
|
var a = typeof b != "undefined";
|
||||||
@@ -47,8 +45,7 @@ typeof_eq_undefined_ie8: {
|
|||||||
|
|
||||||
undefined_redefined: {
|
undefined_redefined: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true
|
||||||
typeofs: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
function f(undefined) {
|
function f(undefined) {
|
||||||
@@ -61,8 +58,7 @@ undefined_redefined: {
|
|||||||
|
|
||||||
undefined_redefined_mangle: {
|
undefined_redefined_mangle: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true
|
||||||
typeofs: true,
|
|
||||||
}
|
}
|
||||||
mangle = {}
|
mangle = {}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
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
|
||||||
|
}
|
||||||
@@ -85,3 +85,15 @@ unsafe_undefined: {
|
|||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runtime_error: {
|
||||||
|
input: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a++);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const a = 1;
|
||||||
|
console.log(a++);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ chained_evaluation_1: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -29,7 +28,6 @@ chained_evaluation_2: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ issue_1639_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
for (var a = 100, b = 10, L1 = 5; --L1 > 0;)
|
||||||
if (--b, 0) var ignore = 0;
|
if (--b, !1) var ignore = 0;
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
@@ -57,7 +57,7 @@ issue_1639_2: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 100, b = 10;
|
var a = 100, b = 10;
|
||||||
function f19() {
|
function f19() {
|
||||||
++a, 0;
|
++a, 1;
|
||||||
}
|
}
|
||||||
f19(),
|
f19(),
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ f7: {
|
|||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
passes: 3,
|
passes: 3,
|
||||||
properties: true,
|
properties: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -39,7 +38,7 @@ f7: {
|
|||||||
"var b = 10;",
|
"var b = 10;",
|
||||||
"",
|
"",
|
||||||
"!function() {",
|
"!function() {",
|
||||||
" b = 100;",
|
" for (;b = 100, !1; ) ;",
|
||||||
"}(), console.log(100, b);",
|
"}(), console.log(100, b);",
|
||||||
]
|
]
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
side_effects_catch: {
|
side_effects_catch: {
|
||||||
options = {
|
options = {
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -35,7 +34,6 @@ side_effects_catch: {
|
|||||||
|
|
||||||
side_effects_else: {
|
side_effects_else: {
|
||||||
options = {
|
options = {
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -64,7 +62,6 @@ side_effects_else: {
|
|||||||
|
|
||||||
side_effects_finally: {
|
side_effects_finally: {
|
||||||
options = {
|
options = {
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -101,7 +98,6 @@ side_effects_finally: {
|
|||||||
|
|
||||||
side_effects_label: {
|
side_effects_label: {
|
||||||
options = {
|
options = {
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -134,7 +130,6 @@ side_effects_label: {
|
|||||||
|
|
||||||
side_effects_switch: {
|
side_effects_switch: {
|
||||||
options = {
|
options = {
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ case_1: {
|
|||||||
input: {
|
input: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a || true:
|
case a, true:
|
||||||
default:
|
default:
|
||||||
b = 2;
|
b = 2;
|
||||||
case true:
|
case true:
|
||||||
@@ -17,7 +17,7 @@ case_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var a = 0, b = 1;
|
var a = 0, b = 1;
|
||||||
switch (true) {
|
switch (true) {
|
||||||
case a || true:
|
case a, true:
|
||||||
b = 2;
|
b = 2;
|
||||||
}
|
}
|
||||||
console.log(a, b);
|
console.log(a, b);
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
mangle_props: {
|
mangle_props: {
|
||||||
mangle = {
|
mangle_props = {}
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
undefined: 1,
|
undefined: 1,
|
||||||
@@ -56,12 +54,10 @@ mangle_props: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
numeric_literal: {
|
numeric_literal: {
|
||||||
mangle = {
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
}
|
}
|
||||||
|
mangle_props = {}
|
||||||
input: {
|
input: {
|
||||||
var obj = {
|
var obj = {
|
||||||
0: 0,
|
0: 0,
|
||||||
@@ -86,7 +82,7 @@ numeric_literal: {
|
|||||||
' 42: 2,',
|
' 42: 2,',
|
||||||
' "42": 3,',
|
' "42": 3,',
|
||||||
' 37: 4,',
|
' 37: 4,',
|
||||||
' o: 5,',
|
' a: 5,',
|
||||||
' 1e42: 6,',
|
' 1e42: 6,',
|
||||||
' b: 7,',
|
' b: 7,',
|
||||||
' "1e+42": 8',
|
' "1e+42": 8',
|
||||||
@@ -96,7 +92,7 @@ numeric_literal: {
|
|||||||
'',
|
'',
|
||||||
'console.log(obj[42], obj["42"]);',
|
'console.log(obj[42], obj["42"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[37], obj["o"], obj[37], obj["37"]);',
|
'console.log(obj[37], obj["a"], obj[37], obj["37"]);',
|
||||||
'',
|
'',
|
||||||
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
'console.log(obj[1e42], obj["b"], obj["1e+42"]);',
|
||||||
]
|
]
|
||||||
@@ -107,139 +103,3 @@ numeric_literal: {
|
|||||||
"8 7 8",
|
"8 7 8",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
identifier: {
|
|
||||||
mangle = {
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
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 = {
|
|
||||||
e: 1,
|
|
||||||
t: 2,
|
|
||||||
n: 3,
|
|
||||||
a: 4,
|
|
||||||
i: 5,
|
|
||||||
o: 6,
|
|
||||||
r: 7,
|
|
||||||
l: 8,
|
|
||||||
s: 9,
|
|
||||||
c: 10,
|
|
||||||
f: 11,
|
|
||||||
u: 12,
|
|
||||||
d: 13,
|
|
||||||
h: 14,
|
|
||||||
p: 15,
|
|
||||||
b: 16,
|
|
||||||
v: 17,
|
|
||||||
w: 18,
|
|
||||||
y: 19,
|
|
||||||
g: 20,
|
|
||||||
m: 21,
|
|
||||||
k: 22,
|
|
||||||
x: 23,
|
|
||||||
j: 24,
|
|
||||||
z: 25,
|
|
||||||
q: 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,
|
|
||||||
ee: 57,
|
|
||||||
te: 58,
|
|
||||||
ne: 59,
|
|
||||||
ae: 60,
|
|
||||||
ie: 61,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
unary_prefix: {
|
unary_prefix: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
iife_for: {
|
iife_for: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -27,7 +26,6 @@ iife_for: {
|
|||||||
iife_for_in: {
|
iife_for_in: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -53,7 +51,6 @@ iife_for_in: {
|
|||||||
iife_do: {
|
iife_do: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -83,7 +80,6 @@ iife_do: {
|
|||||||
iife_while: {
|
iife_while: {
|
||||||
options = {
|
options = {
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -134,5 +130,5 @@ label_while: {
|
|||||||
L: while (0) continue L;
|
L: while (0) continue L;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect_exact: "function f(){L:0}"
|
expect_exact: "function f(){L:;}"
|
||||||
}
|
}
|
||||||
|
|||||||
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ mixed: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var ENV = 3;
|
const ENV = 3;
|
||||||
var FOO = 4;
|
var FOO = 4;
|
||||||
f(ENV * 10);
|
f(ENV * 10);
|
||||||
--FOO;
|
--FOO;
|
||||||
@@ -49,7 +49,7 @@ mixed: {
|
|||||||
x = DEBUG;
|
x = DEBUG;
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var ENV = 3;
|
const ENV = 3;
|
||||||
var FOO = 4;
|
var FOO = 4;
|
||||||
f(10);
|
f(10);
|
||||||
--FOO;
|
--FOO;
|
||||||
@@ -60,7 +60,7 @@ mixed: {
|
|||||||
x = 0;
|
x = 0;
|
||||||
}
|
}
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,14]',
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||||
|
|||||||
@@ -1,498 +0,0 @@
|
|||||||
collapse_vars_constants: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f1(x) {
|
|
||||||
var a = 4, b = x.prop, c = 5, d = sideeffect1(), e = sideeffect2();
|
|
||||||
return b + (function() { return d - a * e - c; })();
|
|
||||||
}
|
|
||||||
function f2(x) {
|
|
||||||
var a = 4, b = x.prop, c = 5, not_used = sideeffect1(), e = sideeffect2();
|
|
||||||
return b + (function() { return -a * e - c; })();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f1(x) {
|
|
||||||
var b = x.prop, d = sideeffect1(), e = sideeffect2();
|
|
||||||
return b + (d - 4 * e - 5);
|
|
||||||
}
|
|
||||||
function f2(x) {
|
|
||||||
var b = x.prop;
|
|
||||||
sideeffect1();
|
|
||||||
return b + (-4 * sideeffect2() - 5);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
modified: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f5(b) {
|
|
||||||
var a = function() {
|
|
||||||
return b;
|
|
||||||
}();
|
|
||||||
return b++ + a;
|
|
||||||
}
|
|
||||||
console.log(f5(1));
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f5(b) {
|
|
||||||
var a = b;
|
|
||||||
return b++ + a;
|
|
||||||
}
|
|
||||||
console.log(f5(1));
|
|
||||||
}
|
|
||||||
expect_stdout: "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
ref_scope: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function() {
|
|
||||||
var a = 1, b = 2, c = 3;
|
|
||||||
var a = c++, b = b /= a;
|
|
||||||
return function() {
|
|
||||||
return a;
|
|
||||||
}() + b;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(function() {
|
|
||||||
var a = 1, b = 2, c = 3;
|
|
||||||
b = b /= a = c++;
|
|
||||||
return a + b;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
safe_undefined: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
if_return: true,
|
|
||||||
inline: true,
|
|
||||||
unsafe: false,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
mangle = {}
|
|
||||||
input: {
|
|
||||||
var a, c;
|
|
||||||
console.log(function(undefined) {
|
|
||||||
return function() {
|
|
||||||
if (a)
|
|
||||||
return b;
|
|
||||||
if (c)
|
|
||||||
return d;
|
|
||||||
};
|
|
||||||
}(1)());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a, c;
|
|
||||||
console.log(a ? b : c ? d : void 0);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_3: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
t ? console.log(true) : console.log(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_3_off: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
t ? console.log(true) : console.log(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_4: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
sequences: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
|
||||||
(function(){
|
|
||||||
console.log("something");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
t ? console.log(true) : console.log(false), void console.log("something");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_5: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
sequences: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
if ((function(){ return t })()) {
|
|
||||||
foo(true);
|
|
||||||
} else {
|
|
||||||
bar(false);
|
|
||||||
}
|
|
||||||
(function(){
|
|
||||||
console.log("something");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
t ? foo(true) : bar(false), void console.log("something");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_5_off: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
|
||||||
sequences: true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
if ((function(){ return t })()) {
|
|
||||||
foo(true);
|
|
||||||
} else {
|
|
||||||
bar(false);
|
|
||||||
}
|
|
||||||
(function(){
|
|
||||||
console.log("something");
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
t ? foo(true) : bar(false), void console.log("something");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1254_negate_iife_true: {
|
|
||||||
options = {
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function() {
|
|
||||||
return function() {
|
|
||||||
console.log('test')
|
|
||||||
};
|
|
||||||
})()();
|
|
||||||
}
|
|
||||||
expect_exact: 'void console.log("test");'
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1254_negate_iife_nested: {
|
|
||||||
options = {
|
|
||||||
expression: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function() {
|
|
||||||
return function() {
|
|
||||||
console.log('test')
|
|
||||||
};
|
|
||||||
})()()()()();
|
|
||||||
}
|
|
||||||
expect_exact: '(void console.log("test"))()()();'
|
|
||||||
}
|
|
||||||
|
|
||||||
negate_iife_issue_1073: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
unused: true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
new (function(a) {
|
|
||||||
return function Foo() {
|
|
||||||
this.x = a;
|
|
||||||
console.log(this);
|
|
||||||
};
|
|
||||||
}(7))();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
new function() {
|
|
||||||
this.x = 7,
|
|
||||||
console.log(this);
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1288_side_effects: {
|
|
||||||
options = {
|
|
||||||
conditionals: true,
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
if (w) ;
|
|
||||||
else {
|
|
||||||
(function f() {})();
|
|
||||||
}
|
|
||||||
if (!x) {
|
|
||||||
(function() {
|
|
||||||
x = {};
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
if (y)
|
|
||||||
(function() {})();
|
|
||||||
else
|
|
||||||
(function(z) {
|
|
||||||
return z;
|
|
||||||
})(0);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
w;
|
|
||||||
x || (x = {});
|
|
||||||
y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inner_var_for_in_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
var a = 1, b = 2;
|
|
||||||
for (b in (function() {
|
|
||||||
return x(a, b, c);
|
|
||||||
})()) {
|
|
||||||
var c = 3, d = 4;
|
|
||||||
x(a, b, c, d);
|
|
||||||
}
|
|
||||||
x(a, b, c, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
var a = 1, b = 2;
|
|
||||||
for (b in x(1, b, c)) {
|
|
||||||
var c = 3, d = 4;
|
|
||||||
x(1, b, c, d);
|
|
||||||
}
|
|
||||||
x(1, b, c, d);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1595_3: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function f(a) {
|
|
||||||
return g(a + 1);
|
|
||||||
})(2);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
g(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1758: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(function(c) {
|
|
||||||
var undefined = 42;
|
|
||||||
return function() {
|
|
||||||
c--;
|
|
||||||
c--, c.toString();
|
|
||||||
return;
|
|
||||||
}();
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(function(c) {
|
|
||||||
var undefined = 42;
|
|
||||||
return c--, c--, void c.toString();
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_stdout: "undefined"
|
|
||||||
}
|
|
||||||
wrap_iife: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
wrap_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function() {
|
|
||||||
return function() {
|
|
||||||
console.log('test')
|
|
||||||
};
|
|
||||||
})()();
|
|
||||||
}
|
|
||||||
expect_exact: 'void console.log("test");'
|
|
||||||
}
|
|
||||||
|
|
||||||
wrap_iife_in_expression: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
wrap_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
foo = (function () {
|
|
||||||
return bar();
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
expect_exact: 'foo=bar();'
|
|
||||||
}
|
|
||||||
|
|
||||||
wrap_iife_in_return_call: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
wrap_iife: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(function() {
|
|
||||||
return (function() {
|
|
||||||
console.log('test')
|
|
||||||
})();
|
|
||||||
})()();
|
|
||||||
}
|
|
||||||
expect_exact: '(void console.log("test"))();'
|
|
||||||
}
|
|
||||||
|
|
||||||
pure_annotation_1: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/(function() {
|
|
||||||
console.log("hello");
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_exact: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
pure_annotation_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/(function(n) {
|
|
||||||
console.log("hello", n);
|
|
||||||
}(42));
|
|
||||||
}
|
|
||||||
expect_exact: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
drop_fargs: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
!function(a_1) {
|
|
||||||
a++;
|
|
||||||
}(a++ + (a && a.var));
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 1;
|
|
||||||
++a && a.var, a++;
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "3"
|
|
||||||
}
|
|
||||||
|
|
||||||
keep_fargs: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
!function(a_1) {
|
|
||||||
a++;
|
|
||||||
}(a++ + (a && a.var));
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 1;
|
|
||||||
++a && a.var, a++;
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "3"
|
|
||||||
}
|
|
||||||
@@ -17,6 +17,6 @@ wrongly_optimized: {
|
|||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
// TODO: optimize to `func(), bar()`
|
||||||
(func(), 1) && bar();
|
(func(), 0) || bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ wrongly_optimized: {
|
|||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
// TODO: optimize to `func(), bar()`
|
// TODO: optimize to `func(), bar()`
|
||||||
if (func(), 1) bar();
|
if (func(), !0) bar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,37 @@
|
|||||||
dont_reuse_prop: {
|
dont_reuse_prop: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
regex: /asd/
|
||||||
regex: /asd/,
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
"aaaaaaaaaabbbbb";
|
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"aaaaaaaaaabbbbb";
|
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect_stdout: "123"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unmangleable_props_should_always_be_reserved: {
|
unmangleable_props_should_always_be_reserved: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
regex: /asd/
|
||||||
regex: /asd/,
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
"aaaaaaaaaabbbbb";
|
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.asd = 256;
|
obj.asd = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"aaaaaaaaaabbbbb";
|
|
||||||
var obj = {};
|
var obj = {};
|
||||||
obj.b = 256;
|
obj.b = 256;
|
||||||
obj.a = 123;
|
obj.a = 123;
|
||||||
console.log(obj.a);
|
console.log(obj.a);
|
||||||
}
|
}
|
||||||
expect_stdout: "123"
|
}
|
||||||
}
|
|
||||||
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>`);"
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
this_binding_conditionals: {
|
this_binding_conditionals: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate : true
|
||||||
side_effects: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(1 && a)();
|
(1 && a)();
|
||||||
@@ -52,7 +51,6 @@ this_binding_collapse_vars: {
|
|||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
var c = a; c();
|
var c = a; c();
|
||||||
|
|||||||
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -146,13 +146,55 @@ parse_do_while_without_semicolon: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
keep_collapse_const_in_own_block_scope: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
loops: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var i=2;
|
||||||
|
const c=5;
|
||||||
|
while(i--)
|
||||||
|
console.log(i);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var i=2;
|
||||||
|
const c=5;
|
||||||
|
for(;i--;)
|
||||||
|
console.log(i);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_collapse_const_in_own_block_scope_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
loops: true
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const c=5;
|
||||||
|
var i=2; // Moves to loop, while it did not in previous test
|
||||||
|
while(i--)
|
||||||
|
console.log(i);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const c=5;
|
||||||
|
for(var i=2;i--;)
|
||||||
|
console.log(i);
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
evaluate: {
|
evaluate: {
|
||||||
options = {
|
options = {
|
||||||
|
loops: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
loops: true,
|
|
||||||
passes: 2,
|
|
||||||
side_effects: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -438,57 +480,3 @@ do_switch: {
|
|||||||
} while (false);
|
} while (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_parenthesis_1: {
|
|
||||||
input: {
|
|
||||||
for (("foo" in {});0;);
|
|
||||||
}
|
|
||||||
expect_exact: 'for(("foo"in{});0;);'
|
|
||||||
}
|
|
||||||
|
|
||||||
in_parenthesis_2: {
|
|
||||||
input: {
|
|
||||||
for ((function(){ "foo" in {}; });0;);
|
|
||||||
}
|
|
||||||
expect_exact: 'for(function(){"foo"in{}};0;);'
|
|
||||||
}
|
|
||||||
|
|
||||||
init_side_effects: {
|
|
||||||
options = {
|
|
||||||
loops: true,
|
|
||||||
side_effects: true,
|
|
||||||
};
|
|
||||||
input: {
|
|
||||||
for (function() {}(), i = 0; i < 5; i++) console.log(i);
|
|
||||||
for (function() {}(); i < 10; i++) console.log(i);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
for (i = 0; i < 5; i++) console.log(i);
|
|
||||||
for (; i < 10; i++) console.log(i);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
dead_code_condition: {
|
|
||||||
options = {
|
|
||||||
dead_code: true,
|
|
||||||
evaluate: true,
|
|
||||||
loops: true,
|
|
||||||
sequences: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
for (var a = 0, b = 5; (a += 1, 3) - 3 && b > 0; b--) {
|
|
||||||
var c = function() {
|
|
||||||
b--;
|
|
||||||
}(a++);
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var c;
|
|
||||||
var a = 0, b = 5;
|
|
||||||
a += 1, 0,
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -22,8 +22,7 @@ negate_iife_1_off: {
|
|||||||
|
|
||||||
negate_iife_2: {
|
negate_iife_2: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
negate_iife: true
|
||||||
negate_iife: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
(function(){ return {} })().x = 10;
|
(function(){ return {} })().x = 10;
|
||||||
@@ -33,7 +32,6 @@ negate_iife_2: {
|
|||||||
|
|
||||||
negate_iife_2_side_effects: {
|
negate_iife_2_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
@@ -60,7 +58,6 @@ negate_iife_3_evaluate: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
negate_iife: true,
|
negate_iife: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -103,7 +100,6 @@ negate_iife_3_off_evaluate: {
|
|||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
inline: true,
|
|
||||||
negate_iife: false,
|
negate_iife: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -83,18 +83,18 @@ new_with_unary_prefix: {
|
|||||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||||
}
|
}
|
||||||
|
|
||||||
dot_parenthesis_1: {
|
new_with_assignement_expression: {
|
||||||
input: {
|
options = {
|
||||||
console.log(new (Math.random().constructor) instanceof Number);
|
evaluate: true
|
||||||
}
|
}
|
||||||
expect_exact: "console.log(new(Math.random().constructor)instanceof Number);"
|
|
||||||
expect_stdout: "true"
|
|
||||||
}
|
|
||||||
|
|
||||||
dot_parenthesis_2: {
|
|
||||||
input: {
|
input: {
|
||||||
console.log(typeof new function(){Math.random()}.constructor);
|
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]);
|
||||||
}
|
}
|
||||||
expect_exact: "console.log(typeof new function(){Math.random()}.constructor);"
|
|
||||||
expect_stdout: "function"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
eval_let_6: {
|
|
||||||
input: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect_stdout: ""
|
|
||||||
node_version: ">=6"
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_let_4: {
|
|
||||||
input: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect_stdout: SyntaxError("Block-scoped declarations (let, const, function, class) not yet supported outside strict mode")
|
|
||||||
node_version: "4"
|
|
||||||
}
|
|
||||||
|
|
||||||
eval_let_0: {
|
|
||||||
input: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
eval("let a;");
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
expect_stdout: SyntaxError("Unexpected identifier")
|
|
||||||
node_version: "<=0.12"
|
|
||||||
}
|
|
||||||
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}){}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
keep_properties: {
|
keep_properties: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
properties: false
|
||||||
properties: false,
|
};
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
}
|
}
|
||||||
@@ -13,12 +12,9 @@ keep_properties: {
|
|||||||
|
|
||||||
dot_properties: {
|
dot_properties: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
properties: true,
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
ie8: true,
|
ie8: true,
|
||||||
}
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -39,12 +35,9 @@ dot_properties: {
|
|||||||
|
|
||||||
dot_properties_es5: {
|
dot_properties_es5: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
properties: true,
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
ie8: false,
|
ie8: false,
|
||||||
}
|
};
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a["if"] = "if";
|
a["if"] = "if";
|
||||||
@@ -64,8 +57,8 @@ dot_properties_es5: {
|
|||||||
sub_properties: {
|
sub_properties: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
properties: true,
|
properties: true
|
||||||
}
|
};
|
||||||
input: {
|
input: {
|
||||||
a[0] = 0;
|
a[0] = 0;
|
||||||
a["0"] = 1;
|
a["0"] = 1;
|
||||||
@@ -84,18 +77,18 @@ sub_properties: {
|
|||||||
a[3.14] = 3;
|
a[3.14] = 3;
|
||||||
a.if = 4;
|
a.if = 4;
|
||||||
a["foo bar"] = 5;
|
a["foo bar"] = 5;
|
||||||
a.NaN = 6;
|
a[NaN] = 6;
|
||||||
a.null = 7;
|
a[null] = 7;
|
||||||
a[void 0] = 8;
|
a[void 0] = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
evaluate_array_length: {
|
evaluate_array_length: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
properties: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
evaluate: true
|
||||||
|
};
|
||||||
input: {
|
input: {
|
||||||
a = [1, 2, 3].length;
|
a = [1, 2, 3].length;
|
||||||
a = [1, 2, 3].join()["len" + "gth"];
|
a = [1, 2, 3].join()["len" + "gth"];
|
||||||
@@ -112,10 +105,10 @@ evaluate_array_length: {
|
|||||||
|
|
||||||
evaluate_string_length: {
|
evaluate_string_length: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
properties: true,
|
||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
evaluate: true
|
||||||
|
};
|
||||||
input: {
|
input: {
|
||||||
a = "foo".length;
|
a = "foo".length;
|
||||||
a = ("foo" + "bar")["len" + "gth"];
|
a = ("foo" + "bar")["len" + "gth"];
|
||||||
@@ -131,11 +124,9 @@ evaluate_string_length: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_properties: {
|
mangle_properties: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
keep_quoted: false
|
||||||
keep_quoted: false,
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
@@ -146,21 +137,19 @@ mangle_properties: {
|
|||||||
expect: {
|
expect: {
|
||||||
a["a"] = "bar";
|
a["a"] = "bar";
|
||||||
a.b = "red";
|
a.b = "red";
|
||||||
x = {o: 10};
|
x = {c: 10};
|
||||||
a.r(x.o, a.a);
|
a.d(x.c, a.a);
|
||||||
a['r']({b: "blue", a: "baz"});
|
a['d']({b: "blue", a: "baz"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_unquoted_properties: {
|
mangle_unquoted_properties: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
properties: false
|
||||||
properties: false,
|
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
builtins: true,
|
||||||
keep_quoted: true,
|
keep_quoted: true
|
||||||
},
|
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -189,26 +178,24 @@ mangle_unquoted_properties: {
|
|||||||
function f1() {
|
function f1() {
|
||||||
a["foo"] = "bar";
|
a["foo"] = "bar";
|
||||||
a.color = "red";
|
a.color = "red";
|
||||||
a.r = 2;
|
a.b = 2;
|
||||||
x = {"bar": 10, b: 7};
|
x = {"bar": 10, c: 7};
|
||||||
a.b = 9;
|
a.c = 9;
|
||||||
}
|
}
|
||||||
function f2() {
|
function f2() {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
a['color'] = "red";
|
a['color'] = "red";
|
||||||
x = {bar: 10, b: 7};
|
x = {bar: 10, c: 7};
|
||||||
a.b = 9;
|
a.c = 9;
|
||||||
a.r = 3;
|
a.b = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug: {
|
mangle_debug: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
debug: ""
|
||||||
debug: "",
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -220,11 +207,9 @@ mangle_debug: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_true: {
|
mangle_debug_true: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
debug: true
|
||||||
debug: true,
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -236,11 +221,9 @@ mangle_debug_true: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mangle_debug_suffix: {
|
mangle_debug_suffix: {
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
debug: "XYZ"
|
||||||
debug: "XYZ",
|
};
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
a.foo = "bar";
|
a.foo = "bar";
|
||||||
x = { baz: "ban" };
|
x = { baz: "ban" };
|
||||||
@@ -253,15 +236,13 @@ mangle_debug_suffix: {
|
|||||||
|
|
||||||
mangle_debug_suffix_keep_quoted: {
|
mangle_debug_suffix_keep_quoted: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
properties: false
|
||||||
properties: false,
|
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle_props = {
|
||||||
properties: {
|
builtins: true,
|
||||||
debug: "XYZ",
|
keep_quoted: true,
|
||||||
keep_quoted: true,
|
debug: "XYZ",
|
||||||
reserved: [],
|
reserved: []
|
||||||
},
|
|
||||||
}
|
}
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: false,
|
beautify: false,
|
||||||
@@ -576,481 +557,3 @@ native_prototype: {
|
|||||||
"".indexOf.call(e, "bar");
|
"".indexOf.call(e, "bar");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accessor_boolean: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get true() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set false(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b.true, b.false = 2, b.true);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get true(){return a},set false(c){a=c}};console.log(b.true,b.false=2,b.true);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_get_set: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get set() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set get(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b.set, b.get = 2, b.set);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get set(){return a},set get(c){a=c}};console.log(b.set,b.get=2,b.set);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_null_undefined: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get null() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set undefined(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b.null, b.undefined = 2, b.null);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get null(){return a},set undefined(c){a=c}};console.log(b.null,b.undefined=2,b.null);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_number: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get 42() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set 42(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b[42], b[42] = 2, b[42]);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get 42(){return a},set 42(c){a=c}};console.log(b[42],b[42]=2,b[42]);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_string: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get "a-b"() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set "a-b"(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b["a-b"], b["a-b"] = 2, b["a-b"]);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get"a-b"(){return a},set"a-b"(c){a=c}};console.log(b["a-b"],b["a-b"]=2,b["a-b"]);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_this: {
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
var b = {
|
|
||||||
get this() {
|
|
||||||
return a;
|
|
||||||
},
|
|
||||||
set this(c) {
|
|
||||||
a = c;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(b.this, b.this = 2, b.this);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a=1;var b={get this(){return a},set this(c){a=c}};console.log(b.this,b.this=2,b.this);'
|
|
||||||
expect_stdout: "1 2 2"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2208_1: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
p: function() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(42);
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2208_2: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
a: 42,
|
|
||||||
p: function() {
|
|
||||||
return this.a;
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log({
|
|
||||||
a: 42,
|
|
||||||
p: function() {
|
|
||||||
return this.a;
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2208_3: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
a = 42;
|
|
||||||
console.log({
|
|
||||||
p: function() {
|
|
||||||
return function() {
|
|
||||||
return this.a;
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
a = 42;
|
|
||||||
console.log(function() {
|
|
||||||
return this.a;
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2208_4: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function foo() {}
|
|
||||||
console.log({
|
|
||||||
a: foo(),
|
|
||||||
p: function() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function foo() {}
|
|
||||||
console.log((foo(), function() {
|
|
||||||
return 42;
|
|
||||||
})());
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2208_5: {
|
|
||||||
options = {
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
p: "FAIL",
|
|
||||||
p: function() {
|
|
||||||
return 42;
|
|
||||||
}
|
|
||||||
}.p());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(42);
|
|
||||||
}
|
|
||||||
expect_stdout: "42"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2256: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
properties: {
|
|
||||||
keep_quoted: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
({ "keep": 1 });
|
|
||||||
g.keep = g.change;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
g.keep = g.g;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs_prop_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(++{
|
|
||||||
a: 1
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(++{
|
|
||||||
a: 1
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect_stdout: "2"
|
|
||||||
}
|
|
||||||
|
|
||||||
lhs_prop_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
[1][0] = 42;
|
|
||||||
(function(a) {
|
|
||||||
a.b = "g";
|
|
||||||
})("abc");
|
|
||||||
(function(a) {
|
|
||||||
a[2] = "g";
|
|
||||||
})("def");
|
|
||||||
(function(a) {
|
|
||||||
a[""] = "g";
|
|
||||||
})("ghi");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
[1][0] = 42;
|
|
||||||
"abc".b = "g";
|
|
||||||
"def"[2] = "g";
|
|
||||||
"ghi"[""] = "g";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
literal_duplicate_key_side_effects: {
|
|
||||||
options = {
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
a: "FAIL",
|
|
||||||
a: console.log ? "PASS" : "FAIL"
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(console.log ? "PASS" : "FAIL");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
prop_side_effects_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
properties: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var C = 1;
|
|
||||||
console.log(C);
|
|
||||||
var obj = {
|
|
||||||
bar: function() {
|
|
||||||
return C + C;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(obj.bar());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1);
|
|
||||||
var obj = {
|
|
||||||
bar: function() {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(obj.bar());
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
prop_side_effects_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
properties: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var C = 1;
|
|
||||||
console.log(C);
|
|
||||||
var obj = {
|
|
||||||
"": function() {
|
|
||||||
return C + C;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.log(obj[""]());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(1);
|
|
||||||
console.log(2);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_1: {
|
|
||||||
options = {
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
a: "FAIL",
|
|
||||||
get a() {
|
|
||||||
return "PASS";
|
|
||||||
}
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log({
|
|
||||||
a: "FAIL",
|
|
||||||
get a() {
|
|
||||||
return "PASS";
|
|
||||||
}
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
node_version: ">=4"
|
|
||||||
}
|
|
||||||
|
|
||||||
accessor_2: {
|
|
||||||
options = {
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log({
|
|
||||||
get a() {
|
|
||||||
return "PASS";
|
|
||||||
},
|
|
||||||
set a(v) {},
|
|
||||||
a: "FAIL"
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log({
|
|
||||||
get a() {
|
|
||||||
return "PASS";
|
|
||||||
},
|
|
||||||
set a(v) {},
|
|
||||||
a: "FAIL"
|
|
||||||
}.a);
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
array_hole: {
|
|
||||||
options = {
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
console.log(
|
|
||||||
[ 1, 2, , 3][1],
|
|
||||||
[ 1, 2, , 3][2],
|
|
||||||
[ 1, 2, , 3][3]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log(2, void 0, 3);
|
|
||||||
}
|
|
||||||
expect_stdout: "2 undefined 3"
|
|
||||||
}
|
|
||||||
|
|
||||||
new_this: {
|
|
||||||
options = {
|
|
||||||
properties: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
new {
|
|
||||||
f: function(a) {
|
|
||||||
this.a = a;
|
|
||||||
}
|
|
||||||
}.f(42);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
new function(a) {
|
|
||||||
this.a = a;
|
|
||||||
}(42);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2513: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
properties: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
!function(Infinity, NaN, undefined) {
|
|
||||||
console.log("a"[1/0], "b"["Infinity"]);
|
|
||||||
console.log("c"[0/0], "d"["NaN"]);
|
|
||||||
console.log("e"[void 0], "f"["undefined"]);
|
|
||||||
}(0, 0, 0);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
!function(Infinity, NaN, undefined) {
|
|
||||||
console.log("a"[1/0], "b"[1/0]);
|
|
||||||
console.log("c".NaN, "d".NaN);
|
|
||||||
console.log("e"[void 0], "f"[void 0]);
|
|
||||||
}(0, 0, 0);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"undefined undefined",
|
|
||||||
"undefined undefined",
|
|
||||||
"undefined undefined",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
strict: {
|
strict: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_funcs: false,
|
|
||||||
reduce_vars: false,
|
reduce_vars: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -31,7 +30,6 @@ strict: {
|
|||||||
strict_reduce_vars: {
|
strict_reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -60,7 +58,6 @@ strict_reduce_vars: {
|
|||||||
unsafe: {
|
unsafe: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
reduce_funcs: false,
|
|
||||||
reduce_vars: false,
|
reduce_vars: false,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -87,7 +84,6 @@ unsafe: {
|
|||||||
unsafe_reduce_vars: {
|
unsafe_reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: true,
|
pure_getters: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -182,432 +178,3 @@ impure_getter_2: {
|
|||||||
}
|
}
|
||||||
expect: {}
|
expect: {}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2110_1: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
function f() {}
|
|
||||||
function g() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
f.g = g;
|
|
||||||
return f.g();
|
|
||||||
}
|
|
||||||
console.log(typeof f());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
function f() {}
|
|
||||||
return f.g = function() {
|
|
||||||
return this;
|
|
||||||
}, f.g();
|
|
||||||
}
|
|
||||||
console.log(typeof f());
|
|
||||||
}
|
|
||||||
expect_stdout: "function"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2110_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
function f() {}
|
|
||||||
function g() {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
f.g = g;
|
|
||||||
return f.g();
|
|
||||||
}
|
|
||||||
console.log(typeof f());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function f() {
|
|
||||||
function f() {}
|
|
||||||
f.g = function() {
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
return f.g();
|
|
||||||
}
|
|
||||||
console.log(typeof f());
|
|
||||||
}
|
|
||||||
expect_stdout: "function"
|
|
||||||
}
|
|
||||||
|
|
||||||
set_immutable_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
1..foo += "";
|
|
||||||
if (1..foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
set_immutable_2: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
set_immutable_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
1..foo += "";
|
|
||||||
if (1..foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
set_immutable_4: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"use strict";
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("FAIL");
|
|
||||||
else console.log("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"use strict";
|
|
||||||
var a = 1;
|
|
||||||
a.foo += "", a.foo ? console.log("FAIL") : console.log("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: true
|
|
||||||
}
|
|
||||||
|
|
||||||
set_mutable_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
!function a() {
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("PASS");
|
|
||||||
else console.log("FAIL");
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
!function a() {
|
|
||||||
if (a.foo += "") console.log("PASS");
|
|
||||||
else console.log("FAIL");
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
set_mutable_2: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
!function a() {
|
|
||||||
a.foo += "";
|
|
||||||
if (a.foo) console.log("PASS");
|
|
||||||
else console.log("FAIL");
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
!function a() {
|
|
||||||
(a.foo += "") ? console.log("PASS") : console.log("FAIL");
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_1: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
if (x().y().z) {
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function x() {
|
|
||||||
return console.log(1), {
|
|
||||||
y: function() {
|
|
||||||
return console.log(2), {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++,
|
|
||||||
x().y().z && console.log(3);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_2: {
|
|
||||||
options = {
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
if (x().y().z) {
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function x() {
|
|
||||||
return console.log(1), {
|
|
||||||
y: function() {
|
|
||||||
return console.log(2), {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++,
|
|
||||||
x().y().z && console.log(3);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: "strict",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
if (x().y().z) {
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
x().y().z && console.log(3);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_4: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
conditionals: true,
|
|
||||||
pure_getters: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
if (x().y().z) {
|
|
||||||
console.log(3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function x() {
|
|
||||||
console.log(1);
|
|
||||||
return {
|
|
||||||
y: function() {
|
|
||||||
console.log(2);
|
|
||||||
return {
|
|
||||||
z: 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
x().y().z++;
|
|
||||||
x().y().z && console.log(3);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_5: {
|
|
||||||
options = {
|
|
||||||
pure_getters: "strict",
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
x().y++;
|
|
||||||
x().y;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
x().y++;
|
|
||||||
x().y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313_6: {
|
|
||||||
options = {
|
|
||||||
pure_getters: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
x().y++;
|
|
||||||
x().y;
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
x().y++;
|
|
||||||
x();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,536 +0,0 @@
|
|||||||
mangle_catch: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){a="PASS"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_ie8: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){a="PASS"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_var: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
var a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="FAIL";try{throw 1}catch(o){var a="PASS"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_var_ie8: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
var a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="FAIL";try{throw 1}catch(args){var a="PASS"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_ie8_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_var_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
var a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_var_ie8_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (args) {
|
|
||||||
var a = "PASS";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_1: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "PASS";
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_1_ie8: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "PASS";
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var a="PASS";try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_1_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "PASS";
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_1_ie8_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = "PASS";
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'var o="PASS";try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_2: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
|
||||||
expect_stdout: "undefined"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_2_ie8: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'try{throw"FAIL1"}catch(a){var a="FAIL2"}console.log(a);'
|
|
||||||
expect_stdout: "undefined"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_2_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
|
||||||
expect_stdout: "undefined"
|
|
||||||
}
|
|
||||||
|
|
||||||
mangle_catch_redef_2_ie8_toplevel: {
|
|
||||||
rename = true
|
|
||||||
options = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
toplevel: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
try {
|
|
||||||
throw "FAIL1";
|
|
||||||
} catch (a) {
|
|
||||||
var a = "FAIL2";
|
|
||||||
}
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
|
||||||
expect_stdout: "undefined"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2120_1: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (t) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (t) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2120_2: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
function_iife_catch: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f(n) {
|
|
||||||
!function() {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (n) {
|
|
||||||
var a = 1;
|
|
||||||
console.log(n, a);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
|
||||||
expect_stdout: "0 1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function_iife_catch_ie8: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f(n) {
|
|
||||||
!function() {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (n) {
|
|
||||||
var a = 1;
|
|
||||||
console.log(n, a);
|
|
||||||
}
|
|
||||||
}();
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
|
||||||
expect_stdout: "0 1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function_catch_catch: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = 0;
|
|
||||||
function f() {
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 2;
|
|
||||||
} catch (o) {
|
|
||||||
var o = 3;
|
|
||||||
console.log(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(o);
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
|
||||||
expect_stdout: [
|
|
||||||
"3",
|
|
||||||
"undefined",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
function_catch_catch_ie8: {
|
|
||||||
rename = true
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var o = 0;
|
|
||||||
function f() {
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 2;
|
|
||||||
} catch (o) {
|
|
||||||
var o = 3;
|
|
||||||
console.log(o);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(o);
|
|
||||||
}
|
|
||||||
f();
|
|
||||||
}
|
|
||||||
expect_exact: "var o=0;function f(){try{throw 1}catch(c){try{throw 2}catch(o){var o=3;console.log(o)}}console.log(o)}f();"
|
|
||||||
expect_stdout: [
|
|
||||||
"3",
|
|
||||||
"undefined",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
console_log: {
|
|
||||||
input: {
|
|
||||||
console.log("%% %s");
|
|
||||||
console.log("%% %s", "%s");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
console.log("%% %s");
|
|
||||||
console.log("%% %s", "%s");
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"%% %s",
|
|
||||||
"% %s",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -187,7 +187,6 @@ dont_screw_try_catch_undefined: {
|
|||||||
reduce_vars: {
|
reduce_vars: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
ie8: true,
|
ie8: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -256,139 +255,3 @@ issue_1586_2: {
|
|||||||
}
|
}
|
||||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2120_1: {
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (t) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (t) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2120_2: {
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"aaaaaaaa";
|
|
||||||
var a = 1, b = "FAIL";
|
|
||||||
try {
|
|
||||||
throw 1;
|
|
||||||
} catch (c) {
|
|
||||||
try {
|
|
||||||
throw 0;
|
|
||||||
} catch (a) {
|
|
||||||
if (c) b = "PASS";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(b);
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2254_1: {
|
|
||||||
mangle = {
|
|
||||||
ie8: false,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"eeeeee";
|
|
||||||
try {
|
|
||||||
console.log(f("PASS"));
|
|
||||||
} catch (e) {}
|
|
||||||
function f(s) {
|
|
||||||
try {
|
|
||||||
throw "FAIL";
|
|
||||||
} catch (e) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"eeeeee";
|
|
||||||
try {
|
|
||||||
console.log(f("PASS"));
|
|
||||||
} catch (e) {}
|
|
||||||
function f(e) {
|
|
||||||
try {
|
|
||||||
throw "FAIL";
|
|
||||||
} catch (t) {
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2254_2: {
|
|
||||||
mangle = {
|
|
||||||
ie8: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
"eeeeee";
|
|
||||||
try {
|
|
||||||
console.log(f("PASS"));
|
|
||||||
} catch (e) {}
|
|
||||||
function f(s) {
|
|
||||||
try {
|
|
||||||
throw "FAIL";
|
|
||||||
} catch (e) {
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
"eeeeee";
|
|
||||||
try {
|
|
||||||
console.log(f("PASS"));
|
|
||||||
} catch (e) {}
|
|
||||||
function f(t) {
|
|
||||||
try {
|
|
||||||
throw "FAIL";
|
|
||||||
} catch (e) {
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -176,11 +176,6 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
// 5
|
|
||||||
x = function() {
|
|
||||||
foo in bar;
|
|
||||||
};
|
|
||||||
for (y = 5; false;);
|
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
// 1
|
// 1
|
||||||
@@ -193,10 +188,6 @@ for_sequences: {
|
|||||||
// 4
|
// 4
|
||||||
x = (foo in bar);
|
x = (foo in bar);
|
||||||
for (y = 5; false;);
|
for (y = 5; false;);
|
||||||
// 5
|
|
||||||
for (x = function() {
|
|
||||||
foo in bar;
|
|
||||||
}, y = 5; false;);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,12 +243,13 @@ negate_iife_for: {
|
|||||||
input: {
|
input: {
|
||||||
(function() {})();
|
(function() {})();
|
||||||
for (i = 0; i < 5; i++) console.log(i);
|
for (i = 0; i < 5; i++) console.log(i);
|
||||||
|
|
||||||
(function() {})();
|
(function() {})();
|
||||||
for (; i < 10; i++) console.log(i);
|
for (; i < 5; i++) console.log(i);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
|
for (!function() {}(), i = 0; i < 5; i++) console.log(i);
|
||||||
for (!function() {}(); i < 10; i++) console.log(i);
|
for (function() {}(); i < 5; i++) console.log(i);
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
@@ -719,63 +711,26 @@ issue_27: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2062: {
|
reassign_const: {
|
||||||
options = {
|
|
||||||
booleans: true,
|
|
||||||
cascade: true,
|
|
||||||
conditionals: true,
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 1;
|
|
||||||
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 1;
|
|
||||||
a || (a++, a--), a++, --a && a.var;
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2313: {
|
|
||||||
options = {
|
options = {
|
||||||
cascade: true,
|
cascade: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = 0, b = 0;
|
function f() {
|
||||||
var foo = {
|
const a = 1;
|
||||||
get c() {
|
a++;
|
||||||
a++;
|
return a;
|
||||||
return 42;
|
|
||||||
},
|
|
||||||
set c(c) {
|
|
||||||
b++;
|
|
||||||
},
|
|
||||||
d: function() {
|
|
||||||
this.c++;
|
|
||||||
if (this.c) console.log(a, b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foo.d();
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 0, b = 0;
|
function f() {
|
||||||
var foo = {
|
const a = 1;
|
||||||
get c() {
|
return a++, a;
|
||||||
return a++, 42;
|
|
||||||
},
|
|
||||||
set c(c) {
|
|
||||||
b++;
|
|
||||||
},
|
|
||||||
d: function() {
|
|
||||||
if (this.c++, this.c) console.log(a, b);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
foo.d();
|
console.log(f());
|
||||||
}
|
}
|
||||||
expect_stdout: "2 1"
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,12 +8,3 @@ octal_escape_sequence: {
|
|||||||
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
var border_check = "\x20\x30\x38\x30\x00\x30\xc0\x30";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1929: {
|
|
||||||
input: {
|
|
||||||
function f(s) {
|
|
||||||
return s.split(/[\\/]/);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
|
|
||||||
}
|
|
||||||
|
|||||||
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();"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -714,7 +714,6 @@ issue_1705_2: {
|
|||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -817,50 +816,3 @@ issue_1758: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "0 3"
|
expect_stdout: "0 3"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2535: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
dead_code: true,
|
|
||||||
switches: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
switch(w(), 42) {
|
|
||||||
case 13: x();
|
|
||||||
case 42: y();
|
|
||||||
default: z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
w(), 42;
|
|
||||||
42;
|
|
||||||
y();
|
|
||||||
z();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_1750: {
|
|
||||||
options = {
|
|
||||||
dead_code: true,
|
|
||||||
evaluate: true,
|
|
||||||
switches: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = 0, b = 1;
|
|
||||||
switch (true) {
|
|
||||||
case a, true:
|
|
||||||
default:
|
|
||||||
b = 2;
|
|
||||||
case true:
|
|
||||||
}
|
|
||||||
console.log(a, b);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = 0, b = 1;
|
|
||||||
true;
|
|
||||||
a, true;
|
|
||||||
b = 2;
|
|
||||||
console.log(a, b);
|
|
||||||
}
|
|
||||||
expect_stdout: "0 2"
|
|
||||||
}
|
|
||||||
|
|||||||
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`);"
|
||||||
|
}
|
||||||
@@ -45,9 +45,9 @@ condition_evaluate: {
|
|||||||
if (void 0 == null);
|
if (void 0 == null);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
while (0);
|
while (!1);
|
||||||
for (; 1;);
|
for (; !0;);
|
||||||
if (1);
|
if (!0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +68,6 @@ label_if_break: {
|
|||||||
conditionals: true,
|
conditionals: true,
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
side_effects: true,
|
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
L: if (true) {
|
L: if (true) {
|
||||||
|
|||||||
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(){})}){}"
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
typeof_evaluation: {
|
typeof_evaluation: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true
|
||||||
typeofs: true,
|
|
||||||
};
|
};
|
||||||
input: {
|
input: {
|
||||||
a = typeof 1;
|
a = typeof 1;
|
||||||
@@ -45,7 +44,7 @@ typeof_in_boolean_context: {
|
|||||||
function f2() { return g(), "Yes"; }
|
function f2() { return g(), "Yes"; }
|
||||||
foo();
|
foo();
|
||||||
console.log(1);
|
console.log(1);
|
||||||
var a = !(console.log(2), 1);
|
var a = !(console.log(2), !0);
|
||||||
foo();
|
foo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,83 +57,6 @@ issue_1668: {
|
|||||||
if (typeof bar);
|
if (typeof bar);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
if (1);
|
if (!0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof_defun_1: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
passes: 2,
|
|
||||||
reduce_vars: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
typeofs: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
function f() {
|
|
||||||
console.log("YES");
|
|
||||||
}
|
|
||||||
function g() {
|
|
||||||
h = 42;
|
|
||||||
console.log("NOPE");
|
|
||||||
}
|
|
||||||
function h() {
|
|
||||||
console.log("YUP");
|
|
||||||
}
|
|
||||||
g = 42;
|
|
||||||
"function" == typeof f && f();
|
|
||||||
"function" == typeof g && g();
|
|
||||||
"function" == typeof h && h();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
function g() {
|
|
||||||
h = 42;
|
|
||||||
console.log("NOPE");
|
|
||||||
}
|
|
||||||
function h() {
|
|
||||||
console.log("YUP");
|
|
||||||
}
|
|
||||||
g = 42;
|
|
||||||
console.log("YES");
|
|
||||||
"function" == typeof g && g();
|
|
||||||
h();
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"YES",
|
|
||||||
"YUP",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
typeof_defun_2: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
typeofs: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var f = function() {
|
|
||||||
console.log(x);
|
|
||||||
};
|
|
||||||
var x = 0;
|
|
||||||
x++ < 2 && typeof f == "function" && f();
|
|
||||||
x++ < 2 && typeof f == "function" && f();
|
|
||||||
x++ < 2 && typeof f == "function" && f();
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var f = function() {
|
|
||||||
console.log(x);
|
|
||||||
};
|
|
||||||
var x = 0;
|
|
||||||
x++ < 2 && f();
|
|
||||||
x++ < 2 && f();
|
|
||||||
x++ < 2 && f();
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"1",
|
|
||||||
"2",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -16,42 +16,105 @@ unicode_parse_variables: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2242_1: {
|
unicode_escaped_identifier: {
|
||||||
beautify = {
|
beautify = {ecma: 6}
|
||||||
ascii_only: false,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
var \u{61} = "foo";
|
||||||
|
var \u{10000} = "bar";
|
||||||
}
|
}
|
||||||
expect_exact: 'console.log("\\ud83d","\\ude00","\ud83d\ude00","\\ud83d@\\ude00");'
|
expect_exact: 'var a="foo";var \u{10000}="bar";';
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2242_2: {
|
unicode_identifier_ascii_only: {
|
||||||
beautify = {
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
ascii_only: true,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
console.log("\ud83d", "\ude00", "\ud83d\ude00", "\ud83d@\ude00");
|
var \u{0061} = "hi";
|
||||||
|
var bar = "h\u{0065}llo";
|
||||||
|
var \u{10000} = "testing \u{101111}";
|
||||||
}
|
}
|
||||||
expect_exact: 'console.log("\\ud83d","\\ude00","\\ud83d\\ude00","\\ud83d@\\ude00");'
|
expect_exact: 'var a="hi";var bar="hello";var \\u{10000}="testing \\u{101111}";'
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2242_3: {
|
unicode_string_literals: {
|
||||||
options = {
|
beautify = {ascii_only: true, ecma: 6}
|
||||||
evaluate: false,
|
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
var a = "6 length unicode character: \u{101111}";
|
||||||
}
|
}
|
||||||
expect_exact: 'console.log("\\ud83d"+"\\ude00","\\ud83d"+"@"+"\\ude00");'
|
expect_exact: 'var a="6 length unicode character: \\u{101111}";'
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2242_4: {
|
// Don't escape identifiers below es6 (or in this case double escaped in expect_exact)
|
||||||
options = {
|
unicode_output_es5_surrogates: {
|
||||||
evaluate: true,
|
beautify = {ascii_only: true, ecma: 5}
|
||||||
}
|
|
||||||
input: {
|
input: {
|
||||||
console.log("\ud83d" + "\ude00", "\ud83d" + "@" + "\ude00");
|
var \u{10000} = "6 length unicode character: \u{10FFFF}";
|
||||||
}
|
}
|
||||||
expect_exact: 'console.log("\ud83d\ude00","\\ud83d@\\ude00");'
|
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"]()}'
|
||||||
|
}
|
||||||
@@ -8,7 +8,6 @@ exports["defaults"] = defaults;
|
|||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
|
||||||
exports["string_template"] = string_template;
|
exports["string_template"] = string_template;
|
||||||
exports["tokenizer"] = tokenizer;
|
exports["tokenizer"] = tokenizer;
|
||||||
exports["is_identifier"] = is_identifier;
|
exports["is_identifier"] = is_identifier;
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
var fs = require("fs");
|
|
||||||
var path = require("path");
|
|
||||||
|
|
||||||
try {
|
|
||||||
fs.mkdirSync("./tmp");
|
|
||||||
} catch (e) {
|
|
||||||
if (e.code != "EEXIST") throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
function local(url) {
|
|
||||||
return path.join("./tmp", encodeURIComponent(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
function read(url) {
|
|
||||||
return fs.createReadStream(local(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(url, callback) {
|
|
||||||
var result = read(url);
|
|
||||||
result.on("error", function(e) {
|
|
||||||
if (e.code != "ENOENT") return callback(e);
|
|
||||||
require(url.slice(0, url.indexOf(":"))).get(url, function(res) {
|
|
||||||
if (res.statusCode !== 200) return callback(res);
|
|
||||||
res.pipe(fs.createWriteStream(local(url)).on("close", function() {
|
|
||||||
callback(null, read(url));
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
}).on("open", function() {
|
|
||||||
callback(null, result);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
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;
|
||||||
|
}
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
var a, b = [1, 2];
|
|
||||||
for (1, 2, a in b) {
|
|
||||||
console.log(a, b[a]);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
var c = [1, 2];
|
|
||||||
for (var a, b in c) {
|
|
||||||
console.log(a, c[a]);
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
console.log(x);
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{"version": 3,"sources": ["index.js"],"mappings": ";"}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
function foo() {
|
|
||||||
return function() {
|
|
||||||
console.log("PASS");
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
var f = foo();
|
|
||||||
f();
|
|
||||||
})();
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user