Compare commits
298 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fa43768ce0 | ||
|
|
a74e600fa0 | ||
|
|
4b21526310 | ||
|
|
a7a7b1daed | ||
|
|
7436977aa5 | ||
|
|
e3c565b46f | ||
|
|
54b0b49b68 | ||
|
|
65648d84a5 | ||
|
|
fd788590f6 | ||
|
|
143f9054da | ||
|
|
f2286c33f1 | ||
|
|
b9615f7a62 | ||
|
|
c520e99eda | ||
|
|
615ae37ca3 | ||
|
|
7aa7f21872 | ||
|
|
4430a436eb | ||
|
|
9707ccdc9f | ||
|
|
cb8f3a2a31 | ||
|
|
8b3259e0c2 | ||
|
|
b66f47b8dd | ||
|
|
8d2e6f333e | ||
|
|
b3ef5e514d | ||
|
|
627f5fb41e | ||
|
|
d90777b724 | ||
|
|
e49297e5eb | ||
|
|
ebd82b3fb6 | ||
|
|
d074aa6e27 | ||
|
|
b052f62710 | ||
|
|
d4ac84b255 | ||
|
|
e250396d7e | ||
|
|
c6fa39b482 | ||
|
|
9aae4f2424 | ||
|
|
008c236137 | ||
|
|
b1c0664066 | ||
|
|
ea999b0e92 | ||
|
|
ce7e220de4 | ||
|
|
2bdaca10ae | ||
|
|
aa0029204e | ||
|
|
f352bcec3a | ||
|
|
08514030f4 | ||
|
|
694ca5d045 | ||
|
|
57fb58b263 | ||
|
|
18c1c9b38a | ||
|
|
5c1ae3662d | ||
|
|
cfebeb2f63 | ||
|
|
fc78423f1d | ||
|
|
2a5277b391 | ||
|
|
d47547dc71 | ||
|
|
304db15a20 | ||
|
|
7cf72b8d66 | ||
|
|
cea685f8d9 | ||
|
|
8d4b5344f4 | ||
|
|
34a0ab6f2c | ||
|
|
bcebacbb9e | ||
|
|
018a5a750a | ||
|
|
b468103f26 | ||
|
|
66c126ffde | ||
|
|
fdee083465 | ||
|
|
5ffc17d4aa | ||
|
|
6aa750010f | ||
|
|
76df77c08c | ||
|
|
957d5537a8 | ||
|
|
88c8f4e363 | ||
|
|
ab36b9b10a | ||
|
|
28330913d8 | ||
|
|
766a4147d4 | ||
|
|
915c7e234d | ||
|
|
e54ddcbb8a | ||
|
|
9e19e63551 | ||
|
|
bce7ee5f6a | ||
|
|
b39043f3ab | ||
|
|
caf96acb08 | ||
|
|
c76749084b | ||
|
|
5843494ee2 | ||
|
|
efa21ae3e6 | ||
|
|
24d9633a35 | ||
|
|
7963b96681 | ||
|
|
8c62d854ce | ||
|
|
69931574e1 | ||
|
|
b5af8a1914 | ||
|
|
c14d09ba84 | ||
|
|
4fc39d8dad | ||
|
|
0b7c70f726 | ||
|
|
f72d3029dd | ||
|
|
1a0d6edc81 | ||
|
|
7b59b2f5b2 | ||
|
|
7bc7704edf | ||
|
|
14e712ee80 | ||
|
|
f83adcc995 | ||
|
|
df8a99439a | ||
|
|
6b91d12ec3 | ||
|
|
f37b91879f | ||
|
|
d835c72c80 | ||
|
|
c4cebb4b01 | ||
|
|
d51a00a450 | ||
|
|
fc0f168a0c | ||
|
|
a0ca595c2c | ||
|
|
1a314e9f60 | ||
|
|
6fcbd5e217 | ||
|
|
22cea023d1 | ||
|
|
70d4477e05 | ||
|
|
838f837379 | ||
|
|
82a8b6f612 | ||
|
|
69fc7ca8da | ||
|
|
0a79496e0a | ||
|
|
9e87edfc2e | ||
|
|
27211cf2d5 | ||
|
|
b5ce199711 | ||
|
|
c71ed91e63 | ||
|
|
f7545d0f1c | ||
|
|
59eecb6bf5 | ||
|
|
d83c6490ab | ||
|
|
7362f57966 | ||
|
|
eaa2c1f6af | ||
|
|
6a916523d4 | ||
|
|
ba7069d52b | ||
|
|
4dd7d0e39b | ||
|
|
90199d0a96 | ||
|
|
b82fd0ad41 | ||
|
|
183da16896 | ||
|
|
87857b0f1b | ||
|
|
e5f6a88233 | ||
|
|
8d0b00317e | ||
|
|
db49daf365 | ||
|
|
923deeff35 | ||
|
|
0b62a28b47 | ||
|
|
44116c6d2b | ||
|
|
b5bab254ce | ||
|
|
81603ecd15 | ||
|
|
e67553fa55 | ||
|
|
fcf542f262 | ||
|
|
8adfc29f91 | ||
|
|
02f47e1713 | ||
|
|
07f64d4050 | ||
|
|
6982a0554c | ||
|
|
fa3250199a | ||
|
|
06b9894c19 | ||
|
|
9f9db504d7 | ||
|
|
82ae95c334 | ||
|
|
9a5e2052c4 | ||
|
|
b1410be443 | ||
|
|
12985d86c2 | ||
|
|
49bfc6b555 | ||
|
|
d1c6bb8c7c | ||
|
|
5c169615a8 | ||
|
|
73d77f4f64 | ||
|
|
ccf0e2ef4f | ||
|
|
20ca0f5906 | ||
|
|
b29d435bb5 | ||
|
|
90585e29c2 | ||
|
|
d8fc281915 | ||
|
|
188c39e8d5 | ||
|
|
5429234138 | ||
|
|
b9f72a4a81 | ||
|
|
fc6ebd04a5 | ||
|
|
7e00a12741 | ||
|
|
10b3752b1e | ||
|
|
fe51a91395 | ||
|
|
951d87ca94 | ||
|
|
798fc21530 | ||
|
|
a75a046abb | ||
|
|
38f2b4579f | ||
|
|
56e2a369d0 | ||
|
|
0daa199fa8 | ||
|
|
73e98dcda4 | ||
|
|
36bca6934d | ||
|
|
ace5811691 | ||
|
|
ba7bad0dbd | ||
|
|
b8b2ac5230 | ||
|
|
ea2359381b | ||
|
|
52de64cf16 | ||
|
|
455790202a | ||
|
|
f40f5eb228 | ||
|
|
604caa09e7 | ||
|
|
29a71d3aae | ||
|
|
39a907bde3 | ||
|
|
70474310f3 | ||
|
|
b5f0f4f3a1 | ||
|
|
2905fd625a | ||
|
|
4facd94029 | ||
|
|
4b5993ff15 | ||
|
|
2351a672ea | ||
|
|
4a528c469c | ||
|
|
82d1ef0242 | ||
|
|
7fdd2082a6 | ||
|
|
e529f54e90 | ||
|
|
d626e9bf19 | ||
|
|
a2a9459684 | ||
|
|
a3dfeea144 | ||
|
|
d316fb139d | ||
|
|
83d8aa8b12 | ||
|
|
4f1c12b6fd | ||
|
|
d8e0e34354 | ||
|
|
0c4f315c02 | ||
|
|
0809699bdc | ||
|
|
2088e1c19d | ||
|
|
bf1d47180c | ||
|
|
0cfbd79aa1 | ||
|
|
d66d86f20b | ||
|
|
905325d3e2 | ||
|
|
dea0cc0662 | ||
|
|
d69d8007d6 | ||
|
|
c0b8f2a16d | ||
|
|
cb0257dbbf | ||
|
|
9637f51b68 | ||
|
|
3026bd8975 | ||
|
|
78a44d5ab0 | ||
|
|
7e13c0db40 | ||
|
|
e6a2e9e4d0 | ||
|
|
e773f03927 | ||
|
|
b16380d669 | ||
|
|
334b07a3db | ||
|
|
3cc1527f00 | ||
|
|
525a61fb55 | ||
|
|
c3a002ff97 | ||
|
|
fad6766a90 | ||
|
|
aa664dea0a | ||
|
|
102f994b9d | ||
|
|
2a4c68be4f | ||
|
|
541e6011af | ||
|
|
6fa3fbeae8 | ||
|
|
4eb4cb656c | ||
|
|
193612ac67 | ||
|
|
95cfce68ea | ||
|
|
ec4202590d | ||
|
|
5e2cd07d6f | ||
|
|
06166df999 | ||
|
|
e2dc9cf091 | ||
|
|
069df27bf1 | ||
|
|
3e7873217c | ||
|
|
e21bab7ce6 | ||
|
|
ac9a168fba | ||
|
|
81b64549ce | ||
|
|
082e004b87 | ||
|
|
983e69128b | ||
|
|
b335912e86 | ||
|
|
cc07f3b806 | ||
|
|
07e4b64f3a | ||
|
|
d3ce2bc9e7 | ||
|
|
cff3bf4914 | ||
|
|
79cfac77bd | ||
|
|
224c14d49d | ||
|
|
7857354d85 | ||
|
|
b4aef753e7 | ||
|
|
424173d311 | ||
|
|
ec7cd1dcf7 | ||
|
|
7def684730 | ||
|
|
10f961c27b | ||
|
|
b483678ca7 | ||
|
|
cbbe6fad60 | ||
|
|
f96929c031 | ||
|
|
2b6657e967 | ||
|
|
7c0c92943f | ||
|
|
62a66dfff4 | ||
|
|
2cab348341 | ||
|
|
460218a3f8 | ||
|
|
e49416e4aa | ||
|
|
d4d7d99b70 | ||
|
|
6a696d0a7b | ||
|
|
1c9e13f47d | ||
|
|
b757450cd8 | ||
|
|
23ec484806 | ||
|
|
f1e1bb419a | ||
|
|
6a0af85c8b | ||
|
|
09269be974 | ||
|
|
bf832cde16 | ||
|
|
2972d58dbb | ||
|
|
2e22d38a02 | ||
|
|
ce27bcd69a | ||
|
|
9336cc8247 | ||
|
|
9809567dfc | ||
|
|
1ee8be8d91 | ||
|
|
8430c2f9f8 | ||
|
|
659c8a7632 | ||
|
|
3564b4f20d | ||
|
|
3505a3604a | ||
|
|
9b1bc6c014 | ||
|
|
9f23185f2b | ||
|
|
b82feb9302 | ||
|
|
7f2a591c7e | ||
|
|
afbcebddf6 | ||
|
|
484e484571 | ||
|
|
6f3f21233f | ||
|
|
a6873a3859 | ||
|
|
7a6d452b54 | ||
|
|
9b58b54e2d | ||
|
|
c598a12af9 | ||
|
|
cfe3a98ce5 | ||
|
|
14778e049b | ||
|
|
446fb0198b | ||
|
|
7d3cddf9d6 | ||
|
|
6dead95eb3 | ||
|
|
cc931b3ad8 | ||
|
|
d838b4b52e | ||
|
|
2f3bddbaca | ||
|
|
673b071637 | ||
|
|
da82fa59a7 | ||
|
|
333792352e |
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
@@ -2,10 +2,6 @@
|
||||
|
||||
<!-- Note: sub-optimal but correct code is not a bug -->
|
||||
|
||||
**ES5 or ES6+ input?**
|
||||
|
||||
<!-- Note: for ES6 see: https://github.com/mishoo/UglifyJS2/tree/harmony#harmony -->
|
||||
|
||||
**Uglify version (`uglifyjs -V`)**
|
||||
|
||||
**JavaScript input**
|
||||
@@ -24,6 +20,6 @@
|
||||
**JavaScript output or error produced.**
|
||||
|
||||
<!--
|
||||
Note: `uglify-js` only supports ES5.
|
||||
Those wishing to minify ES6 should use `uglify-es`.
|
||||
Note: `uglify-js` only supports JavaScript.
|
||||
Those wishing to minify ES6+ should transpile first.
|
||||
-->
|
||||
|
||||
43
.travis.yml
43
.travis.yml
@@ -1,14 +1,35 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
||||
- "0.12"
|
||||
- "4"
|
||||
- "6"
|
||||
- "8"
|
||||
env:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- libstdc++-4.9-dev
|
||||
cache:
|
||||
directories: tmp
|
||||
language: generic
|
||||
matrix:
|
||||
fast_finish: true
|
||||
sudo: false
|
||||
cache:
|
||||
directories: tmp
|
||||
env:
|
||||
global:
|
||||
- UGLIFYJS_TEST_ALL=1
|
||||
matrix:
|
||||
- NODEJS_VER=node/0.10
|
||||
- NODEJS_VER=node/0.12
|
||||
- NODEJS_VER=node/4
|
||||
- NODEJS_VER=node/6
|
||||
- NODEJS_VER=node/8
|
||||
- NODEJS_VER=node/10
|
||||
- NODEJS_VER=node/latest
|
||||
before_install:
|
||||
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||
- . ~/.nvs/nvs.sh
|
||||
- nvs --version
|
||||
install:
|
||||
- nvs add $NODEJS_VER
|
||||
- nvs use $NODEJS_VER
|
||||
- node --version
|
||||
- npm --version --no-update-notifier
|
||||
- npm install --no-optional --no-save --no-update-notifier
|
||||
script:
|
||||
- npm test --no-update-notifier
|
||||
|
||||
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@@ -0,0 +1,61 @@
|
||||
Contributing
|
||||
============
|
||||
|
||||
## Documentation
|
||||
|
||||
Every new feature and API change should be accompanied by a README additon.
|
||||
|
||||
## Testing
|
||||
|
||||
All features and bugs should have tests that verify the fix. You can run all
|
||||
tests using `npm test`.
|
||||
|
||||
The most common type of test are tests that verify input and output of the
|
||||
Uglify transforms. These tests exist in `test/compress`. New tests can be added
|
||||
either to an existing file or in a new file `issue-xxx.js`.
|
||||
|
||||
Tests that cannot be expressed as a simple AST can be found in `test/mocha`.
|
||||
|
||||
## Code style
|
||||
|
||||
- File encoding must be `UTF-8`.
|
||||
- `LF` is always used as a line ending.
|
||||
- Statements end with semicolons.
|
||||
- Indentation uses 4 spaces, switch `case` 2 spaces.
|
||||
- Identifiers use `snake_case`.
|
||||
- Strings use double quotes (`"`).
|
||||
- Use a trailing comma for multiline array and object literals to minimize diffs.
|
||||
- The Uglify code only uses ES5, even in the `harmony` branch.
|
||||
- Line length should be at most 80 cols, except when it is easier to read a
|
||||
longer line.
|
||||
- If both sides of a comparison are of the same type, `==` and `!=` are used.
|
||||
- Multiline conditions place `&&` and `||` first on the line.
|
||||
|
||||
**Example feature**
|
||||
|
||||
```js
|
||||
OPT(AST_Debugger, function(self, compressor) {
|
||||
if (compressor.option("drop_debugger"))
|
||||
return make_node(AST_EmptyStatement, self);
|
||||
return self;
|
||||
});
|
||||
```
|
||||
|
||||
**Example test case**
|
||||
|
||||
```js
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
}
|
||||
expect: {
|
||||
if (foo);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
UglifyJS is released under the BSD license:
|
||||
|
||||
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
Copyright 2012-2018 (c) Mihai Bazon <mihai.bazon@gmail.com>
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
|
||||
96
README.md
96
README.md
@@ -6,9 +6,8 @@ UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
||||
#### 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)**.
|
||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS2/tree/v2.x)**.
|
||||
- `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).
|
||||
- `uglify-js` only supports JavaScript (ECMAScript 5).
|
||||
- To minify ECMAScript 2015 or above, transpile using tools like [Babel](https://babeljs.io/).
|
||||
|
||||
Install
|
||||
-------
|
||||
@@ -70,7 +69,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
`debug` Add debug prefix and suffix.
|
||||
`domprops` Mangle property names that overlaps
|
||||
with DOM properties.
|
||||
`keep_quoted` Only mangle unquoted properies.
|
||||
`keep_quoted` Only mangle unquoted properties.
|
||||
`regex` Only mangle matched property names.
|
||||
`reserved` List of names that should not be mangled.
|
||||
-b, --beautify [options] Beautify output/specify output options:
|
||||
@@ -105,6 +104,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
sequences.
|
||||
--config-file <file> Read `minify()` options from JSON file.
|
||||
-d, --define <expr>[=value] Global definitions.
|
||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||
argument(s) & value(s).
|
||||
--ie8 Support non-standard Internet Explorer 8.
|
||||
Equivalent to setting `ie8: true` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
@@ -119,7 +120,8 @@ a double dash to prevent input files being used as option arguments:
|
||||
JS that was generated from some other original
|
||||
code. Specify "inline" if the source map is
|
||||
included within the sources.
|
||||
`filename` Name and/or location of the output source.
|
||||
`filename` Filename and/or location of the output source
|
||||
(sets `file` attribute in source map).
|
||||
`includeSources` Pass this flag if you want to include
|
||||
the content of source files in the
|
||||
source map as sourcesContent property.
|
||||
@@ -150,7 +152,9 @@ debugging your compressed JavaScript. To get a source map, pass
|
||||
|
||||
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. The value of
|
||||
`filename` is only used to set `file` attribute (see [the spec][sm-spec])
|
||||
in source map file.
|
||||
|
||||
- `--source-map "root='<URL>'"` to pass the URL where the original files can be found.
|
||||
|
||||
@@ -598,6 +602,11 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
## Compress options
|
||||
|
||||
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
||||
parameter name whenever possible.
|
||||
|
||||
- `assignments` (default: `true`) -- apply optimizations to assignment expressions.
|
||||
|
||||
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
||||
for example `!!a ? b : c → a ? b : c`
|
||||
|
||||
@@ -605,14 +614,16 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
side effects permitting.
|
||||
|
||||
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
||||
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.
|
||||
e.g. `!(a <= b) → a > b`, 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
|
||||
expressions
|
||||
|
||||
- `dead_code` (default: `true`) -- remove unreachable code
|
||||
|
||||
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
||||
|
||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
||||
`console.*` functions. If you wish to drop a specific function call
|
||||
such as `console.info` and/or retain side effects from function arguments
|
||||
@@ -640,7 +651,13 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
||||
|
||||
- `inline` (default: `true`) -- embed simple functions
|
||||
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
||||
- `false` -- same as `0`
|
||||
- `0` -- disabled inlining
|
||||
- `1` -- inline simple functions
|
||||
- `2` -- inline functions with arguments
|
||||
- `3` -- inline functions with arguments and variables
|
||||
- `true` -- same as `3`
|
||||
|
||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
||||
|
||||
@@ -649,7 +666,7 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `keep_fnames` (default: `false`) -- Pass `true` to prevent the
|
||||
compressor from discarding function names. Useful for code relying on
|
||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle).
|
||||
`Function.prototype.name`. See also: the `keep_fnames` [mangle option](#mangle-options).
|
||||
|
||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||
@@ -677,7 +694,8 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
pass `pure_funcs: [ 'Math.floor' ]` to let it know that this
|
||||
function won't produce any side effect, in which case the whole
|
||||
statement would get discarded. The current implementation adds some
|
||||
overhead (compression will be slower).
|
||||
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||
are also under `mangle.reserved` to avoid mangling.
|
||||
|
||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
||||
this, UglifyJS will assume that object property access
|
||||
@@ -724,14 +742,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
|
||||
- `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_comps` (default: `false`) -- compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
|
||||
- `unsafe_Func` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
|
||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
||||
@@ -743,6 +757,10 @@ If you're using the `X-SourceMap` header instead, you can just omit `sourceMap.u
|
||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
||||
`RegExp` values the same way as if they are constants.
|
||||
|
||||
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
||||
variable named `undefined` in scope (variable name will be mangled, typically
|
||||
reduced to a single character)
|
||||
|
||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||
|
||||
@@ -816,7 +834,7 @@ can pass additional arguments that control the code output:
|
||||
when you want to generate minified code, in order to specify additional
|
||||
arguments, so you can use `-b beautify=false` to override it.
|
||||
|
||||
- `bracketize` (default `false`) -- always insert brackets in `if`, `for`,
|
||||
- `braces` (default `false`) -- always insert braces in `if`, `for`,
|
||||
`do`, `while` or `with` statements, even if their body is a single
|
||||
statement.
|
||||
|
||||
@@ -828,8 +846,8 @@ can pass additional arguments that control the code output:
|
||||
|
||||
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
||||
|
||||
- `inline_script` (default `false`) -- escape the slash in occurrences of
|
||||
`</script` in strings
|
||||
- `inline_script` (default `true`) -- escape HTML comments and 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.
|
||||
@@ -841,8 +859,8 @@ can pass additional arguments that control the code output:
|
||||
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`.
|
||||
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
|
||||
a best effort basis.
|
||||
|
||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
||||
objects
|
||||
@@ -916,9 +934,6 @@ when this flag is on:
|
||||
- `new Object()` → `{}`
|
||||
- `String(exp)` or `exp.toString()` → `"" + exp`
|
||||
- `new Object/RegExp/Function/Error/Array (...)` → we discard the `new`
|
||||
- `void 0` → `undefined` (if there is a variable named "undefined" in
|
||||
scope; we do it because the variable name will be mangled, typically
|
||||
reduced to a single character)
|
||||
|
||||
### Conditional compilation
|
||||
|
||||
@@ -1035,8 +1050,9 @@ var result = UglifyJS.minify(ast, {
|
||||
### 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.
|
||||
[`TreeWalker`](https://github.com/mishoo/UglifyJS2/blob/master/lib/ast.js) and
|
||||
[`TreeTransformer`](https://github.com/mishoo/UglifyJS2/blob/master/lib/transform.js)
|
||||
respectively.
|
||||
|
||||
### ESTree / SpiderMonkey AST
|
||||
|
||||
@@ -1095,3 +1111,27 @@ To enable fast minify mode with the API use:
|
||||
```js
|
||||
UglifyJS.minify(code, { compress: false, mangle: true });
|
||||
```
|
||||
|
||||
#### Source maps and debugging
|
||||
|
||||
Various `compress` transforms that simplify, rearrange, inline and remove code
|
||||
are known to have an adverse effect on debugging with source maps. This is
|
||||
expected as code is optimized and mappings are often simply not possible as
|
||||
some code no longer exists. For highest fidelity in source map debugging
|
||||
disable the Uglify `compress` option and just use `mangle`.
|
||||
|
||||
### Compiler assumptions
|
||||
|
||||
To allow for better optimizations, the compiler makes various assumptions:
|
||||
|
||||
- `.toString()` and `.valueOf()` don't have side effects, and for built-in
|
||||
objects they have not been overridden.
|
||||
- `undefined`, `NaN` and `Infinity` have not been externally redefined.
|
||||
- `arguments.callee`, `arguments.caller` and `Function.prototype.caller` are not used.
|
||||
- The code doesn't expect the contents of `Function.prototype.toString()` or
|
||||
`Error.prototype.stack` to be anything in particular.
|
||||
- Getting and setting properties on a plain object does not cause other side effects
|
||||
(using `.watch()` or `Proxy`).
|
||||
- Object properties can be added, removed and modified (not prevented with
|
||||
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||
`Object.preventExtensions()` or `Object.seal()`).
|
||||
|
||||
40
appveyor.yml
40
appveyor.yml
@@ -1,24 +1,26 @@
|
||||
environment:
|
||||
UGLIFYJS_TEST_ALL: 1
|
||||
matrix:
|
||||
- nodejs_version: "0.10"
|
||||
- nodejs_version: "0.12"
|
||||
- nodejs_version: "4.0"
|
||||
- nodejs_version: "6.0"
|
||||
|
||||
- NODEJS_VER: node/0.10
|
||||
- NODEJS_VER: node/0.12
|
||||
- NODEJS_VER: node/4
|
||||
- NODEJS_VER: node/6
|
||||
- NODEJS_VER: node/8
|
||||
- NODEJS_VER: node/10
|
||||
- NODEJS_VER: node/latest
|
||||
install:
|
||||
- git clone --branch v1.4.2 --depth 1 https://github.com/jasongin/nvs.git %LOCALAPPDATA%\nvs
|
||||
- set PATH=%LOCALAPPDATA%\nvs;%PATH%
|
||||
- nvs --version
|
||||
- nvs add %NODEJS_VER%
|
||||
- nvs use %NODEJS_VER%
|
||||
- node --version
|
||||
- npm --version --no-update-notifier
|
||||
- npm install --no-optional --no-save --no-update-notifier
|
||||
build: off
|
||||
cache:
|
||||
- tmp
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
platform:
|
||||
- x86
|
||||
- x64
|
||||
|
||||
install:
|
||||
- ps: Install-Product node $env:nodejs_version $env:platform
|
||||
- npm install
|
||||
|
||||
test_script:
|
||||
- node --version
|
||||
- npm --version
|
||||
- npm test
|
||||
|
||||
build: off
|
||||
- npm test --no-update-notifier
|
||||
|
||||
80
bin/uglifyjs
80
bin/uglifyjs
@@ -3,11 +3,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// workaround for tty output truncation upon process.exit()
|
||||
[process.stdout, process.stderr].forEach(function(stream){
|
||||
if (stream._handle && stream._handle.setBlocking)
|
||||
stream._handle.setBlocking(true);
|
||||
});
|
||||
require("../tools/exit");
|
||||
|
||||
var fs = require("fs");
|
||||
var info = require("../package.json");
|
||||
@@ -15,7 +11,7 @@ var path = require("path");
|
||||
var program = require("commander");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
var skip_keys = [ "cname", "enclosed", "inlined", "parent_scope", "scope", "thedef", "uses_eval", "uses_with" ];
|
||||
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||
var files = {};
|
||||
var options = {
|
||||
compress: false,
|
||||
@@ -44,13 +40,15 @@ program.option("-o, --output <file>", "Output file (default STDOUT).");
|
||||
program.option("--comments [filter]", "Preserve copyright comments in the output.");
|
||||
program.option("--config-file <file>", "Read minify() options from JSON file.");
|
||||
program.option("-d, --define <expr>[=value]", "Global definitions.", parse_js("define"));
|
||||
program.option("-e, --enclose [arg[,...][:value[,...]]]", "Embed everything in a big function, with configurable argument(s) & value(s).");
|
||||
program.option("--ie8", "Support non-standard Internet Explorer 8.");
|
||||
program.option("--keep-fnames", "Do not mangle/drop function names. Useful for code relying on Function.prototype.name.");
|
||||
program.option("--name-cache <file>", "File to hold mangled name mappings.");
|
||||
program.option("--rename", "Force symbol expansion.");
|
||||
program.option("--no-rename", "Disable symbol expansion.");
|
||||
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("--timings", "Display operations run time on STDERR.")
|
||||
program.option("--source-map [options]", "Enable source map/specify source map options.", parse_js());
|
||||
program.option("--timings", "Display operations run time on STDERR.");
|
||||
program.option("--toplevel", "Compress and/or mangle variables in toplevel scope.");
|
||||
program.option("--verbose", "Print diagnostic messages.");
|
||||
program.option("--warn", "Print warning messages.");
|
||||
@@ -58,21 +56,25 @@ program.option("--wrap <name>", "Embed everything as a function with “exports
|
||||
program.arguments("[files...]").parseArgv(process.argv);
|
||||
if (program.configFile) {
|
||||
options = JSON.parse(read_file(program.configFile));
|
||||
if (options.mangle && options.mangle.properties && options.mangle.properties.regex) {
|
||||
options.mangle.properties.regex = UglifyJS.parse(options.mangle.properties.regex, {
|
||||
expression: true
|
||||
}).getValue();
|
||||
}
|
||||
}
|
||||
if (!program.output && program.sourceMap && program.sourceMap.url != "inline") {
|
||||
fatal("ERROR: cannot write source map to STDOUT");
|
||||
}
|
||||
[
|
||||
"compress",
|
||||
"enclose",
|
||||
"ie8",
|
||||
"mangle",
|
||||
"rename",
|
||||
"sourceMap",
|
||||
"toplevel",
|
||||
"wrap"
|
||||
].forEach(function(name) {
|
||||
if (name in program) {
|
||||
if (name == "rename" && program[name]) return;
|
||||
options[name] = program[name];
|
||||
}
|
||||
});
|
||||
@@ -103,7 +105,7 @@ if (program.mangleProps) {
|
||||
if (typeof program.mangleProps != "object") program.mangleProps = {};
|
||||
if (!Array.isArray(program.mangleProps.reserved)) program.mangleProps.reserved = [];
|
||||
require("../tools/domprops").forEach(function(name) {
|
||||
UglifyJS._push_uniq(program.mangleProps.reserved, name);
|
||||
UglifyJS.push_uniq(program.mangleProps.reserved, name);
|
||||
});
|
||||
}
|
||||
if (typeof options.mangle != "object") options.mangle = {};
|
||||
@@ -125,6 +127,11 @@ if (program.parse) {
|
||||
fatal("ERROR: inline source map only works with built-in parser");
|
||||
}
|
||||
}
|
||||
if (~program.rawArgs.indexOf("--rename")) {
|
||||
options.rename = true;
|
||||
} else if (!program.rename) {
|
||||
options.rename = false;
|
||||
}
|
||||
var convert_path = function(name) {
|
||||
return name;
|
||||
};
|
||||
@@ -176,6 +183,11 @@ function run() {
|
||||
UglifyJS.AST_Node.warn_function = function(msg) {
|
||||
print_error("WARN: " + msg);
|
||||
};
|
||||
var content = program.sourceMap && program.sourceMap.content;
|
||||
if (content && content != "inline") {
|
||||
print_error("INFO: Using input source map: " + content);
|
||||
options.sourceMap.content = read_file(content, content);
|
||||
}
|
||||
if (program.timings) options.timings = true;
|
||||
try {
|
||||
if (program.parse) {
|
||||
@@ -227,7 +239,20 @@ function run() {
|
||||
}
|
||||
fatal(ex);
|
||||
} else if (program.output == "ast") {
|
||||
if (!options.compress && !options.mangle) {
|
||||
result.ast.figure_out_scope({});
|
||||
}
|
||||
print(JSON.stringify(result.ast, function(key, value) {
|
||||
if (value) switch (key) {
|
||||
case "thedef":
|
||||
return symdef(value);
|
||||
case "enclosed":
|
||||
return value.length ? value.map(symdef) : undefined;
|
||||
case "variables":
|
||||
case "functions":
|
||||
case "globals":
|
||||
return value.size() ? value.map(symdef) : undefined;
|
||||
}
|
||||
if (skip_key(key)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
@@ -317,17 +342,9 @@ function parse_js(flag) {
|
||||
return function(value, options) {
|
||||
options = options || {};
|
||||
try {
|
||||
UglifyJS.minify(value, {
|
||||
parse: {
|
||||
expression: true
|
||||
},
|
||||
compress: false,
|
||||
mangle: false,
|
||||
output: {
|
||||
ast: true,
|
||||
code: false
|
||||
}
|
||||
}).ast.walk(new UglifyJS.TreeWalker(function(node) {
|
||||
UglifyJS.parse(value, {
|
||||
expression: true
|
||||
}).walk(new UglifyJS.TreeWalker(function(node) {
|
||||
if (node instanceof UglifyJS.AST_Assign) {
|
||||
var name = node.left.print_to_string();
|
||||
var value = node.right;
|
||||
@@ -364,23 +381,16 @@ function parse_js(flag) {
|
||||
}
|
||||
}
|
||||
|
||||
function parse_source_map() {
|
||||
var parse = parse_js();
|
||||
return function(value, options) {
|
||||
var hasContent = options && "content" in options;
|
||||
var settings = parse(value, options);
|
||||
if (!hasContent && settings.content && settings.content != "inline") {
|
||||
print_error("INFO: Using input source map: " + settings.content);
|
||||
settings.content = read_file(settings.content, settings.content);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
}
|
||||
|
||||
function symdef(def) {
|
||||
var ret = (1e6 + def.id) + " " + def.name;
|
||||
if (def.mangled_name) ret += " " + def.mangled_name;
|
||||
return ret;
|
||||
}
|
||||
|
||||
function format_object(obj) {
|
||||
var lines = [];
|
||||
var padding = "";
|
||||
|
||||
209
lib/ast.js
209
lib/ast.js
@@ -44,21 +44,21 @@
|
||||
"use strict";
|
||||
|
||||
function DEFNODE(type, props, methods, base) {
|
||||
if (arguments.length < 4) base = AST_Node;
|
||||
if (!props) props = [];
|
||||
else props = props.split(/\s+/);
|
||||
if (typeof base === "undefined") base = AST_Node;
|
||||
props = props ? props.split(/\s+/) : [];
|
||||
var self_props = props;
|
||||
if (base && base.PROPS)
|
||||
props = props.concat(base.PROPS);
|
||||
var code = "return function AST_" + type + "(props){ if (props) { ";
|
||||
for (var i = props.length; --i >= 0;) {
|
||||
code += "this." + props[i] + " = props." + props[i] + ";";
|
||||
}
|
||||
if (base && base.PROPS) props = props.concat(base.PROPS);
|
||||
var code = [
|
||||
"return function AST_", type, "(props){",
|
||||
"if(props){",
|
||||
];
|
||||
props.forEach(function(prop) {
|
||||
code.push("this.", prop, "=props.", prop, ";");
|
||||
});
|
||||
var proto = base && new base;
|
||||
if (proto && proto.initialize || (methods && methods.initialize))
|
||||
code += "this.initialize();";
|
||||
code += "}}";
|
||||
var ctor = new Function(code)();
|
||||
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
||||
code.push("}}");
|
||||
var ctor = new Function(code.join(""))();
|
||||
if (proto) {
|
||||
ctor.prototype = proto;
|
||||
ctor.BASE = base;
|
||||
@@ -71,11 +71,11 @@ function DEFNODE(type, props, methods, base) {
|
||||
if (type) {
|
||||
ctor.prototype.TYPE = ctor.TYPE = type;
|
||||
}
|
||||
if (methods) for (i in methods) if (HOP(methods, i)) {
|
||||
if (/^\$/.test(i)) {
|
||||
ctor[i.substr(1)] = methods[i];
|
||||
if (methods) for (var name in methods) if (HOP(methods, name)) {
|
||||
if (/^\$/.test(name)) {
|
||||
ctor[name.substr(1)] = methods[name];
|
||||
} else {
|
||||
ctor.prototype[i] = methods[i];
|
||||
ctor.prototype[name] = methods[name];
|
||||
}
|
||||
}
|
||||
ctor.DEFMETHOD = function(name, method) {
|
||||
@@ -85,7 +85,7 @@ function DEFNODE(type, props, methods, base) {
|
||||
exports["AST_" + type] = ctor;
|
||||
}
|
||||
return ctor;
|
||||
};
|
||||
}
|
||||
|
||||
var AST_Token = DEFNODE("Token", "type value line col pos endline endcol endpos nlb comments_before comments_after file raw", {
|
||||
}, null);
|
||||
@@ -118,10 +118,8 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
}
|
||||
}, null);
|
||||
|
||||
AST_Node.warn_function = null;
|
||||
AST_Node.warn = function(txt, props) {
|
||||
if (AST_Node.warn_function)
|
||||
AST_Node.warn_function(string_template(txt, props));
|
||||
if (AST_Node.warn_function) AST_Node.warn_function(string_template(txt, props));
|
||||
};
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
@@ -148,7 +146,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -158,19 +156,18 @@ function walk_body(node, visitor) {
|
||||
var body = node.body;
|
||||
if (body instanceof AST_Statement) {
|
||||
body._walk(visitor);
|
||||
}
|
||||
else for (var i = 0, len = body.length; i < len; i++) {
|
||||
body[i]._walk(visitor);
|
||||
}
|
||||
};
|
||||
} else body.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
}
|
||||
|
||||
var AST_Block = DEFNODE("Block", "body", {
|
||||
$documentation: "A body of statements (usually bracketed)",
|
||||
$documentation: "A body of statements (usually braced)",
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
@@ -197,7 +194,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.label._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -208,8 +205,7 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
var label = node.label;
|
||||
var def = this.label;
|
||||
node.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl
|
||||
&& node.label && node.label.thedef === def) {
|
||||
if (node instanceof AST_LoopControl && node.label && node.label.thedef === def) {
|
||||
node.label.thedef = label;
|
||||
label.references.push(node);
|
||||
}
|
||||
@@ -233,7 +229,7 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
var AST_Do = DEFNODE("Do", null, {
|
||||
$documentation: "A `do` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.body._walk(visitor);
|
||||
this.condition._walk(visitor);
|
||||
});
|
||||
@@ -243,7 +239,7 @@ var AST_Do = DEFNODE("Do", null, {
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
$documentation: "A `while` statement",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -258,7 +254,7 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
if (this.init) this.init._walk(visitor);
|
||||
if (this.condition) this.condition._walk(visitor);
|
||||
if (this.step) this.step._walk(visitor);
|
||||
@@ -267,15 +263,14 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
}
|
||||
}, AST_IterationStatement);
|
||||
|
||||
var AST_ForIn = DEFNODE("ForIn", "init name object", {
|
||||
var AST_ForIn = DEFNODE("ForIn", "init object", {
|
||||
$documentation: "A `for ... in` statement",
|
||||
$propdoc: {
|
||||
init: "[AST_Node] the `for/in` initialization code",
|
||||
name: "[AST_SymbolRef?] the loop variable, only if `init` is AST_Var",
|
||||
object: "[AST_Node] the object that we're looping through"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.init._walk(visitor);
|
||||
this.object._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
@@ -289,7 +284,7 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
});
|
||||
@@ -309,6 +304,16 @@ 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",
|
||||
cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
|
||||
},
|
||||
clone: function(deep) {
|
||||
var node = this._clone(deep);
|
||||
if (this.variables) node.variables = this.variables.clone();
|
||||
if (this.functions) node.functions = this.functions.clone();
|
||||
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
||||
return node;
|
||||
},
|
||||
pinned: function() {
|
||||
return this.uses_eval || this.uses_with;
|
||||
}
|
||||
}, AST_Block);
|
||||
|
||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
@@ -320,12 +325,29 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
var body = this.body;
|
||||
var wrapped_tl = "(function(exports){'$ORIG';})(typeof " + name + "=='undefined'?(" + name + "={}):" + name + ");";
|
||||
wrapped_tl = parse(wrapped_tl);
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
|
||||
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
return wrapped_tl;
|
||||
},
|
||||
wrap_enclose: function(args_values) {
|
||||
if (typeof args_values != "string") args_values = "";
|
||||
var index = args_values.indexOf(":");
|
||||
if (index < 0) index = args_values.length;
|
||||
var body = this.body;
|
||||
return parse([
|
||||
"(function(",
|
||||
args_values.slice(0, index),
|
||||
'){"$ORIG"})(',
|
||||
args_values.slice(index + 1),
|
||||
")"
|
||||
].join("")).transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Directive && node.value == "$ORIG") {
|
||||
return MAP.splice(body);
|
||||
}
|
||||
}));
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
@@ -337,12 +359,11 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
|
||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
if (this.name) this.name._walk(visitor);
|
||||
var argnames = this.argnames;
|
||||
for (var i = 0, len = argnames.length; i < len; i++) {
|
||||
argnames[i]._walk(visitor);
|
||||
}
|
||||
this.argnames.forEach(function(argname) {
|
||||
argname._walk(visitor);
|
||||
});
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
}
|
||||
@@ -372,7 +393,7 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, this.value && function(){
|
||||
return visitor._visit(this, this.value && function() {
|
||||
this.value._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -392,7 +413,7 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, this.label && function(){
|
||||
return visitor._visit(this, this.label && function() {
|
||||
this.label._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -415,7 +436,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.body._walk(visitor);
|
||||
if (this.alternative) this.alternative._walk(visitor);
|
||||
@@ -431,7 +452,7 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -452,7 +473,7 @@ var AST_Case = DEFNODE("Case", "expression", {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -468,7 +489,7 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
walk_body(this, visitor);
|
||||
if (this.bcatch) this.bcatch._walk(visitor);
|
||||
if (this.bfinally) this.bfinally._walk(visitor);
|
||||
@@ -482,7 +503,7 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
argname: "[AST_SymbolCatch] symbol for the exception"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.argname._walk(visitor);
|
||||
walk_body(this, visitor);
|
||||
});
|
||||
@@ -501,11 +522,10 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var definitions = this.definitions;
|
||||
for (var i = 0, len = definitions.length; i < len; i++) {
|
||||
definitions[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.definitions.forEach(function(defn) {
|
||||
defn._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, AST_Statement);
|
||||
@@ -521,7 +541,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.name._walk(visitor);
|
||||
if (this.value) this.value._walk(visitor);
|
||||
});
|
||||
@@ -537,12 +557,11 @@ var AST_Call = DEFNODE("Call", "expression args", {
|
||||
args: "[AST_Node*] array of arguments"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var args = this.args;
|
||||
for (var i = 0, len = args.length; i < len; i++) {
|
||||
args[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.args.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -557,7 +576,7 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expressions.forEach(function(node) {
|
||||
node._walk(visitor);
|
||||
});
|
||||
@@ -576,7 +595,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
$documentation: "A dotted property access expression",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -585,7 +604,7 @@ var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Sub = DEFNODE("Sub", null, {
|
||||
$documentation: "Index-style property access, i.e. `a[\"foo\"]`",
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
this.property._walk(visitor);
|
||||
});
|
||||
@@ -599,7 +618,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.expression._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -621,7 +640,7 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.left._walk(visitor);
|
||||
this.right._walk(visitor);
|
||||
});
|
||||
@@ -636,7 +655,7 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.condition._walk(visitor);
|
||||
this.consequent._walk(visitor);
|
||||
this.alternative._walk(visitor);
|
||||
@@ -656,11 +675,10 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var elements = this.elements;
|
||||
for (var i = 0, len = elements.length; i < len; i++) {
|
||||
elements[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.elements.forEach(function(element) {
|
||||
element._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -671,11 +689,10 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
properties: "[AST_ObjectProperty*] array of properties"
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
var properties = this.properties;
|
||||
for (var i = 0, len = properties.length; i < len; i++) {
|
||||
properties[i]._walk(visitor);
|
||||
}
|
||||
return visitor._visit(this, function() {
|
||||
this.properties.forEach(function(prop) {
|
||||
prop._walk(visitor);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -683,11 +700,11 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
$documentation: "Base class for literal object properties",
|
||||
$propdoc: {
|
||||
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.",
|
||||
value: "[AST_Node] property value. For setters and getters this is an AST_Accessor."
|
||||
key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor."
|
||||
},
|
||||
_walk: function(visitor) {
|
||||
return visitor._visit(this, function(){
|
||||
return visitor._visit(this, function() {
|
||||
this.value._walk(visitor);
|
||||
});
|
||||
}
|
||||
@@ -814,12 +831,12 @@ var AST_NaN = DEFNODE("NaN", null, {
|
||||
|
||||
var AST_Undefined = DEFNODE("Undefined", null, {
|
||||
$documentation: "The `undefined` value",
|
||||
value: (function(){}())
|
||||
value: function(){}()
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_Hole = DEFNODE("Hole", null, {
|
||||
$documentation: "A hole in an array",
|
||||
value: (function(){}())
|
||||
value: function(){}()
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_Infinity = DEFNODE("Infinity", null, {
|
||||
@@ -847,11 +864,11 @@ function TreeWalker(callback) {
|
||||
this.visit = callback;
|
||||
this.stack = [];
|
||||
this.directives = Object.create(null);
|
||||
};
|
||||
}
|
||||
TreeWalker.prototype = {
|
||||
_visit: function(node, descend) {
|
||||
this.push(node);
|
||||
var ret = this.visit(node, descend ? function(){
|
||||
var ret = this.visit(node, descend ? function() {
|
||||
descend.call(node);
|
||||
} : noop);
|
||||
if (!ret && descend) {
|
||||
@@ -910,5 +927,25 @@ TreeWalker.prototype = {
|
||||
|| node instanceof AST_Break && x instanceof AST_Switch)
|
||||
return x;
|
||||
}
|
||||
},
|
||||
in_boolean_context: function() {
|
||||
var self = this.self();
|
||||
for (var i = 0, p; p = this.parent(i); i++) {
|
||||
if (p instanceof AST_SimpleStatement
|
||||
|| p instanceof AST_Conditional && p.condition === self
|
||||
|| p instanceof AST_DWLoop && p.condition === self
|
||||
|| p instanceof AST_For && p.condition === self
|
||||
|| p instanceof AST_If && p.condition === self
|
||||
|| p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) {
|
||||
return true;
|
||||
}
|
||||
if (p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||")
|
||||
|| p instanceof AST_Conditional
|
||||
|| p.tail_node() === self) {
|
||||
self = p;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
4360
lib/compress.js
4360
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -7,15 +7,23 @@ var to_base64 = typeof btoa == "undefined" ? function(str) {
|
||||
return new Buffer(str).toString("base64");
|
||||
} : btoa;
|
||||
|
||||
function read_source_map(code) {
|
||||
function read_source_map(name, code) {
|
||||
var match = /\n\/\/# sourceMappingURL=data:application\/json(;.*?)?;base64,(.*)/.exec(code);
|
||||
if (!match) {
|
||||
AST_Node.warn("inline source map not found");
|
||||
AST_Node.warn("inline source map not found: " + name);
|
||||
return null;
|
||||
}
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
|
||||
function parse_source_map(content) {
|
||||
try {
|
||||
return JSON.parse(content);
|
||||
} catch (ex) {
|
||||
throw new Error("invalid input source map: " + content);
|
||||
}
|
||||
}
|
||||
|
||||
function set_shorthand(name, options, keys) {
|
||||
if (options[name]) {
|
||||
keys.forEach(function(key) {
|
||||
@@ -29,7 +37,6 @@ 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)) {
|
||||
@@ -39,7 +46,6 @@ function init_cache(cache) {
|
||||
|
||||
function to_json(cache) {
|
||||
return {
|
||||
cname: cache.cname,
|
||||
props: cache.props.toObject()
|
||||
};
|
||||
}
|
||||
@@ -49,6 +55,7 @@ function minify(files, options) {
|
||||
try {
|
||||
options = defaults(options, {
|
||||
compress: {},
|
||||
enclose: false,
|
||||
ie8: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
@@ -115,7 +122,7 @@ function minify(files, options) {
|
||||
};
|
||||
}
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
var source_maps, toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
@@ -124,13 +131,23 @@ function minify(files, options) {
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
source_map_content = parse_source_map(source_map_content);
|
||||
}
|
||||
source_maps = source_map_content && Object.create(null);
|
||||
for (var name in files) if (HOP(files, name)) {
|
||||
options.parse.filename = name;
|
||||
options.parse.toplevel = parse(files[name], options.parse);
|
||||
if (options.sourceMap && options.sourceMap.content == "inline") {
|
||||
if (Object.keys(files).length > 1)
|
||||
throw new Error("inline source map only works with singular input");
|
||||
options.sourceMap.content = read_source_map(files[name]);
|
||||
if (source_maps) {
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, files[name]);
|
||||
if (inlined_content) {
|
||||
source_maps[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
} else {
|
||||
source_maps[name] = source_map_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
toplevel = options.parse.toplevel;
|
||||
@@ -141,6 +158,9 @@ function minify(files, options) {
|
||||
if (options.wrap) {
|
||||
toplevel = toplevel.wrap_commonjs(options.wrap);
|
||||
}
|
||||
if (options.enclose) {
|
||||
toplevel = toplevel.wrap_enclose(options.enclose);
|
||||
}
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
@@ -152,7 +172,6 @@ function minify(files, options) {
|
||||
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
||||
if (timings) timings.mangle = Date.now();
|
||||
if (options.mangle) {
|
||||
base54.reset();
|
||||
toplevel.compute_char_frequency(options.mangle);
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
@@ -167,12 +186,9 @@ function minify(files, options) {
|
||||
}
|
||||
if (!HOP(options.output, "code") || options.output.code) {
|
||||
if (options.sourceMap) {
|
||||
if (typeof options.sourceMap.content == "string") {
|
||||
options.sourceMap.content = JSON.parse(options.sourceMap.content);
|
||||
}
|
||||
options.output.source_map = SourceMap({
|
||||
file: options.sourceMap.filename,
|
||||
orig: options.sourceMap.content,
|
||||
orig: source_maps,
|
||||
root: options.sourceMap.root
|
||||
});
|
||||
if (options.sourceMap.includeSources) {
|
||||
@@ -181,6 +197,8 @@ function minify(files, options) {
|
||||
} else for (var name in files) if (HOP(files, name)) {
|
||||
options.output.source_map.get().setSourceContent(name, files[name]);
|
||||
}
|
||||
} else {
|
||||
options.output.source_map.get()._sourcesContents = null;
|
||||
}
|
||||
}
|
||||
delete options.output.ast;
|
||||
|
||||
@@ -43,11 +43,9 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
(function(){
|
||||
|
||||
var normalize_directives = function(body) {
|
||||
(function() {
|
||||
function normalize_directives(body) {
|
||||
var in_directive = true;
|
||||
|
||||
for (var i = 0; i < body.length; i++) {
|
||||
if (in_directive && body[i] instanceof AST_Statement && body[i].body instanceof AST_String) {
|
||||
body[i] = new AST_Directive({
|
||||
@@ -59,9 +57,8 @@
|
||||
in_directive = false;
|
||||
}
|
||||
}
|
||||
|
||||
return body;
|
||||
};
|
||||
}
|
||||
|
||||
var MOZ_TO_ME = {
|
||||
Program: function(M) {
|
||||
@@ -129,7 +126,7 @@
|
||||
return new AST_Array({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
elements : M.elements.map(function(elem){
|
||||
elements : M.elements.map(function(elem) {
|
||||
return elem === null ? new AST_Hole() : from_moz(elem);
|
||||
})
|
||||
});
|
||||
@@ -138,7 +135,7 @@
|
||||
return new AST_Object({
|
||||
start : my_start_token(M),
|
||||
end : my_end_token(M),
|
||||
properties : M.properties.map(function(prop){
|
||||
properties : M.properties.map(function(prop) {
|
||||
prop.type = "Property";
|
||||
return from_moz(prop)
|
||||
})
|
||||
@@ -180,6 +177,17 @@
|
||||
end : my_end_token(M)
|
||||
};
|
||||
if (val === null) return new AST_Null(args);
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags);
|
||||
args.value.raw_source = rx.pattern;
|
||||
return new AST_RegExp(args);
|
||||
} else if (rx) {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
switch (typeof val) {
|
||||
case "string":
|
||||
args.value = val;
|
||||
@@ -189,16 +197,6 @@
|
||||
return new AST_Number(args);
|
||||
case "boolean":
|
||||
return new (val ? AST_True : AST_False)(args);
|
||||
default:
|
||||
var rx = M.regex;
|
||||
if (rx && rx.pattern) {
|
||||
// RegExpLiteral as per ESTree AST spec
|
||||
args.value = new RegExp(rx.pattern, rx.flags).toString();
|
||||
} else {
|
||||
// support legacy RegExp
|
||||
args.value = M.regex && M.raw ? M.raw : val;
|
||||
}
|
||||
return new AST_RegExp(args);
|
||||
}
|
||||
},
|
||||
Identifier: function(M) {
|
||||
@@ -410,14 +408,15 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||
var value = M.value;
|
||||
var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
||||
var value = "/" + M.value.raw_source + "/" + flags;
|
||||
return {
|
||||
type: "Literal",
|
||||
value: value,
|
||||
raw: value.toString(),
|
||||
raw: value,
|
||||
regex: {
|
||||
pattern: value.source,
|
||||
flags: value.toString().match(/[gimuy]*$/)[0]
|
||||
pattern: M.value.raw_source,
|
||||
flags: flags
|
||||
}
|
||||
};
|
||||
});
|
||||
@@ -478,7 +477,7 @@
|
||||
endpos : range ? range[0] : moznode.start,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function my_end_token(moznode) {
|
||||
var loc = moznode.loc, end = loc && loc.end;
|
||||
@@ -493,7 +492,7 @@
|
||||
endpos : range ? range[1] : moznode.end,
|
||||
raw : raw_token(moznode),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function map(moztype, mytype, propmap) {
|
||||
var moz_to_me = "function From_Moz_" + moztype + "(M){\n";
|
||||
@@ -505,7 +504,7 @@
|
||||
me_to_moz += "return {\n" +
|
||||
"type: " + JSON.stringify(moztype);
|
||||
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop){
|
||||
if (propmap) propmap.split(/\s*,\s*/).forEach(function(prop) {
|
||||
var m = /([a-z0-9$_]+)(=|@|>|%)([a-z0-9$_]+)/i.exec(prop);
|
||||
if (!m) throw new Error("Can't understand property map: " + prop);
|
||||
var moz = m[1], how = m[2], my = m[3];
|
||||
@@ -548,7 +547,7 @@
|
||||
);
|
||||
MOZ_TO_ME[moztype] = moz_to_me;
|
||||
def_to_moz(mytype, me_to_moz);
|
||||
};
|
||||
}
|
||||
|
||||
var FROM_MOZ_STACK = null;
|
||||
|
||||
@@ -557,13 +556,28 @@
|
||||
var ret = node != null ? MOZ_TO_ME[node.type](node) : null;
|
||||
FROM_MOZ_STACK.pop();
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node){
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
var ast = from_moz(node);
|
||||
FROM_MOZ_STACK = save_stack;
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LabelRef) {
|
||||
for (var level = 0, parent; parent = this.parent(level); level++) {
|
||||
if (parent instanceof AST_Scope) break;
|
||||
if (parent instanceof AST_LabeledStatement && parent.label.name == node.name) {
|
||||
node.thedef = parent.label;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!node.thedef) {
|
||||
var s = node.start;
|
||||
js_error("Undefined label " + node.name, s.file, s.line, s.col, s.pos);
|
||||
}
|
||||
}
|
||||
}));
|
||||
return ast;
|
||||
};
|
||||
|
||||
@@ -583,24 +597,24 @@
|
||||
}
|
||||
}
|
||||
return moznode;
|
||||
};
|
||||
}
|
||||
|
||||
function def_to_moz(mytype, handler) {
|
||||
mytype.DEFMETHOD("to_mozilla_ast", function() {
|
||||
return set_moz_loc(this, handler(this));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz(node) {
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
body: node.body.map(to_moz)
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function to_moz_scope(type, node) {
|
||||
var body = node.body.map(to_moz);
|
||||
@@ -611,5 +625,5 @@
|
||||
type: type,
|
||||
body: body
|
||||
};
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
765
lib/output.js
765
lib/output.js
File diff suppressed because it is too large
Load Diff
311
lib/parse.js
311
lib/parse.js
@@ -130,7 +130,7 @@ function is_letter(code) {
|
||||
return (code >= 97 && code <= 122)
|
||||
|| (code >= 65 && code <= 90)
|
||||
|| (code >= 0xaa && UNICODE.letter.test(String.fromCharCode(code)));
|
||||
};
|
||||
}
|
||||
|
||||
function is_surrogate_pair_head(code) {
|
||||
if (typeof code == "string")
|
||||
@@ -146,11 +146,11 @@ function is_surrogate_pair_tail(code) {
|
||||
|
||||
function is_digit(code) {
|
||||
return code >= 48 && code <= 57;
|
||||
};
|
||||
}
|
||||
|
||||
function is_alphanumeric_char(code) {
|
||||
return is_digit(code) || is_letter(code);
|
||||
};
|
||||
}
|
||||
|
||||
function is_unicode_digit(code) {
|
||||
return UNICODE.digit.test(String.fromCharCode(code));
|
||||
@@ -158,19 +158,19 @@ function is_unicode_digit(code) {
|
||||
|
||||
function is_unicode_combining_mark(ch) {
|
||||
return UNICODE.non_spacing_mark.test(ch) || UNICODE.space_combining_mark.test(ch);
|
||||
};
|
||||
}
|
||||
|
||||
function is_unicode_connector_punctuation(ch) {
|
||||
return UNICODE.connector_punctuation.test(ch);
|
||||
};
|
||||
}
|
||||
|
||||
function is_identifier(name) {
|
||||
return !RESERVED_WORDS(name) && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
||||
};
|
||||
return !RESERVED_WORDS[name] && /^[a-z_$][a-z0-9_$]*$/i.test(name);
|
||||
}
|
||||
|
||||
function is_identifier_start(code) {
|
||||
return code == 36 || code == 95 || is_letter(code);
|
||||
};
|
||||
}
|
||||
|
||||
function is_identifier_char(ch) {
|
||||
var code = ch.charCodeAt(0);
|
||||
@@ -182,11 +182,11 @@ function is_identifier_char(ch) {
|
||||
|| is_unicode_connector_punctuation(ch)
|
||||
|| is_unicode_digit(code)
|
||||
;
|
||||
};
|
||||
}
|
||||
|
||||
function is_identifier_string(str){
|
||||
function is_identifier_string(str) {
|
||||
return /^[a-z_$][a-z0-9_$]*$/i.test(str);
|
||||
};
|
||||
}
|
||||
|
||||
function parse_js_number(num) {
|
||||
if (RE_HEX_NUMBER.test(num)) {
|
||||
@@ -197,7 +197,7 @@ function parse_js_number(num) {
|
||||
var val = parseFloat(num);
|
||||
if (val == num) return val;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function JS_Parse_Error(message, filename, line, col, pos) {
|
||||
this.message = message;
|
||||
@@ -205,7 +205,7 @@ function JS_Parse_Error(message, filename, line, col, pos) {
|
||||
this.line = line;
|
||||
this.col = col;
|
||||
this.pos = pos;
|
||||
};
|
||||
}
|
||||
JS_Parse_Error.prototype = Object.create(Error.prototype);
|
||||
JS_Parse_Error.prototype.constructor = JS_Parse_Error;
|
||||
JS_Parse_Error.prototype.name = "SyntaxError";
|
||||
@@ -213,11 +213,11 @@ configure_error_stack(JS_Parse_Error);
|
||||
|
||||
function js_error(message, filename, line, col, pos) {
|
||||
throw new JS_Parse_Error(message, filename, line, col, pos);
|
||||
};
|
||||
}
|
||||
|
||||
function is_token(token, type, val) {
|
||||
return token.type == type && (val == null || token.value == val);
|
||||
};
|
||||
}
|
||||
|
||||
var EX_EOF = {};
|
||||
|
||||
@@ -239,13 +239,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
directive_stack : []
|
||||
};
|
||||
|
||||
function peek() { return S.text.charAt(S.pos); };
|
||||
function peek() {
|
||||
return S.text.charAt(S.pos);
|
||||
}
|
||||
|
||||
function next(signal_eof, in_string) {
|
||||
var ch = S.text.charAt(S.pos++);
|
||||
if (signal_eof && !ch)
|
||||
throw EX_EOF;
|
||||
if (NEWLINE_CHARS(ch)) {
|
||||
if (NEWLINE_CHARS[ch]) {
|
||||
S.newline_before = S.newline_before || !in_string;
|
||||
++S.line;
|
||||
S.col = 0;
|
||||
@@ -258,43 +260,43 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
++S.col;
|
||||
}
|
||||
return ch;
|
||||
};
|
||||
}
|
||||
|
||||
function forward(i) {
|
||||
while (i-- > 0) next();
|
||||
};
|
||||
}
|
||||
|
||||
function looking_at(str) {
|
||||
return S.text.substr(S.pos, str.length) == str;
|
||||
};
|
||||
}
|
||||
|
||||
function find_eol() {
|
||||
var text = S.text;
|
||||
for (var i = S.pos, n = S.text.length; i < n; ++i) {
|
||||
var ch = text[i];
|
||||
if (NEWLINE_CHARS(ch))
|
||||
if (NEWLINE_CHARS[ch])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
}
|
||||
|
||||
function find(what, signal_eof) {
|
||||
var pos = S.text.indexOf(what, S.pos);
|
||||
if (signal_eof && pos == -1) throw EX_EOF;
|
||||
return pos;
|
||||
};
|
||||
}
|
||||
|
||||
function start_token() {
|
||||
S.tokline = S.line;
|
||||
S.tokcol = S.col;
|
||||
S.tokpos = S.pos;
|
||||
};
|
||||
}
|
||||
|
||||
var prev_was_dot = false;
|
||||
function token(type, value, is_comment) {
|
||||
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX(value)) ||
|
||||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION(value)) ||
|
||||
(type == "punc" && PUNC_BEFORE_EXPRESSION(value)));
|
||||
S.regex_allowed = ((type == "operator" && !UNARY_POSTFIX[value]) ||
|
||||
(type == "keyword" && KEYWORDS_BEFORE_EXPRESSION[value]) ||
|
||||
(type == "punc" && PUNC_BEFORE_EXPRESSION[value]));
|
||||
if (type == "punc" && value == ".") {
|
||||
prev_was_dot = true;
|
||||
} else if (!is_comment) {
|
||||
@@ -321,27 +323,27 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
S.newline_before = false;
|
||||
return new AST_Token(ret);
|
||||
};
|
||||
}
|
||||
|
||||
function skip_whitespace() {
|
||||
while (WHITESPACE_CHARS(peek()))
|
||||
while (WHITESPACE_CHARS[peek()])
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
function read_while(pred) {
|
||||
var ret = "", ch, i = 0;
|
||||
while ((ch = peek()) && pred(ch, i++))
|
||||
ret += next();
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
function parse_error(err) {
|
||||
js_error(err, filename, S.tokline, S.tokcol, S.tokpos);
|
||||
};
|
||||
}
|
||||
|
||||
function read_num(prefix) {
|
||||
var has_e = false, after_e = false, has_x = false, has_dot = prefix == ".";
|
||||
var num = read_while(function(ch, i){
|
||||
var num = read_while(function(ch, i) {
|
||||
var code = ch.charCodeAt(0);
|
||||
switch (code) {
|
||||
case 120: case 88: // xX
|
||||
@@ -367,7 +369,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
} else {
|
||||
parse_error("Invalid syntax: " + num);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function read_escaped_char(in_string) {
|
||||
var ch = next(true, in_string);
|
||||
@@ -390,7 +392,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
if (ch >= "0" && ch <= "7")
|
||||
return read_octal_escape_sequence(ch);
|
||||
return ch;
|
||||
};
|
||||
}
|
||||
|
||||
function read_octal_escape_sequence(ch) {
|
||||
// Read
|
||||
@@ -417,14 +419,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
num = (num << 4) | digit;
|
||||
}
|
||||
return num;
|
||||
};
|
||||
}
|
||||
|
||||
var read_string = with_eof_error("Unterminated string constant", function(quote_char){
|
||||
var read_string = with_eof_error("Unterminated string constant", function(quote_char) {
|
||||
var quote = next(), ret = "";
|
||||
for (;;) {
|
||||
var ch = next(true, true);
|
||||
if (ch == "\\") ch = read_escaped_char(true);
|
||||
else if (NEWLINE_CHARS(ch)) parse_error("Unterminated string constant");
|
||||
else if (NEWLINE_CHARS[ch]) parse_error("Unterminated string constant");
|
||||
else if (ch == quote) break;
|
||||
ret += ch;
|
||||
}
|
||||
@@ -447,9 +449,9 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
S.comments_before.push(token(type, ret, true));
|
||||
S.regex_allowed = regex_allowed;
|
||||
return next_token;
|
||||
};
|
||||
}
|
||||
|
||||
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function(){
|
||||
var skip_multiline_comment = with_eof_error("Unterminated multiline comment", function() {
|
||||
var regex_allowed = S.regex_allowed;
|
||||
var i = find("*/", true);
|
||||
var text = S.text.substring(S.pos, i).replace(/\r\n|\r|\u2028|\u2029/g, '\n');
|
||||
@@ -476,16 +478,16 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
backslash = false;
|
||||
}
|
||||
}
|
||||
if (KEYWORDS(name) && escaped) {
|
||||
if (KEYWORDS[name] && escaped) {
|
||||
hex = name.charCodeAt(0).toString(16).toUpperCase();
|
||||
name = "\\u" + "0000".substr(hex.length) + hex + name.slice(1);
|
||||
}
|
||||
return name;
|
||||
};
|
||||
}
|
||||
|
||||
var read_regexp = with_eof_error("Unterminated regular expression", function(source) {
|
||||
var prev_backslash = false, ch, in_class = false;
|
||||
while ((ch = next(true))) if (NEWLINE_CHARS(ch)) {
|
||||
while ((ch = next(true))) if (NEWLINE_CHARS[ch]) {
|
||||
parse_error("Unexpected line terminator");
|
||||
} else if (prev_backslash) {
|
||||
source += "\\" + ch;
|
||||
@@ -517,15 +519,15 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
function grow(op) {
|
||||
if (!peek()) return op;
|
||||
var bigger = op + peek();
|
||||
if (OPERATORS(bigger)) {
|
||||
if (OPERATORS[bigger]) {
|
||||
next();
|
||||
return grow(bigger);
|
||||
} else {
|
||||
return op;
|
||||
}
|
||||
};
|
||||
}
|
||||
return token("operator", grow(prefix || next()));
|
||||
};
|
||||
}
|
||||
|
||||
function handle_slash() {
|
||||
next();
|
||||
@@ -538,23 +540,23 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
return skip_multiline_comment();
|
||||
}
|
||||
return S.regex_allowed ? read_regexp("") : read_operator("/");
|
||||
};
|
||||
}
|
||||
|
||||
function handle_dot() {
|
||||
next();
|
||||
return is_digit(peek().charCodeAt(0))
|
||||
? read_num(".")
|
||||
: token("punc", ".");
|
||||
};
|
||||
}
|
||||
|
||||
function read_word() {
|
||||
var word = read_name();
|
||||
if (prev_was_dot) return token("name", word);
|
||||
return KEYWORDS_ATOM(word) ? token("atom", word)
|
||||
: !KEYWORDS(word) ? token("name", word)
|
||||
: OPERATORS(word) ? token("operator", word)
|
||||
return KEYWORDS_ATOM[word] ? token("atom", word)
|
||||
: !KEYWORDS[word] ? token("name", word)
|
||||
: OPERATORS[word] ? token("operator", word)
|
||||
: token("keyword", word);
|
||||
};
|
||||
}
|
||||
|
||||
function with_eof_error(eof_error, cont) {
|
||||
return function(x) {
|
||||
@@ -565,7 +567,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
else throw ex;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function next_token(force_regexp) {
|
||||
if (force_regexp != null)
|
||||
@@ -603,13 +605,13 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
}
|
||||
if (is_digit(code)) return read_num();
|
||||
if (PUNC_CHARS(ch)) return token("punc", next());
|
||||
if (OPERATOR_CHARS(ch)) return read_operator();
|
||||
if (PUNC_CHARS[ch]) return token("punc", next());
|
||||
if (OPERATOR_CHARS[ch]) return read_operator();
|
||||
if (code == 92 || is_identifier_start(code)) return read_word();
|
||||
break;
|
||||
}
|
||||
parse_error("Unexpected character '" + ch + "'");
|
||||
};
|
||||
}
|
||||
|
||||
next_token.context = function(nc) {
|
||||
if (nc) S = nc;
|
||||
@@ -645,8 +647,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
|
||||
return next_token;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
/* -----[ Parser (constants) ]----- */
|
||||
|
||||
@@ -666,7 +667,7 @@ var UNARY_POSTFIX = makePredicate([ "--", "++" ]);
|
||||
|
||||
var ASSIGNMENT = makePredicate([ "=", "+=", "-=", "/=", "*=", "%=", ">>=", "<<=", ">>>=", "|=", "^=", "&=" ]);
|
||||
|
||||
var PRECEDENCE = (function(a, ret){
|
||||
var PRECEDENCE = function(a, ret) {
|
||||
for (var i = 0; i < a.length; ++i) {
|
||||
var b = a[i];
|
||||
for (var j = 0; j < b.length; ++j) {
|
||||
@@ -674,28 +675,24 @@ var PRECEDENCE = (function(a, ret){
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
})(
|
||||
[
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
],
|
||||
{}
|
||||
);
|
||||
}([
|
||||
["||"],
|
||||
["&&"],
|
||||
["|"],
|
||||
["^"],
|
||||
["&"],
|
||||
["==", "===", "!=", "!=="],
|
||||
["<", ">", "<=", ">=", "in", "instanceof"],
|
||||
[">>", "<<", ">>>"],
|
||||
["+", "-"],
|
||||
["*", "/", "%"]
|
||||
], {});
|
||||
|
||||
var ATOMIC_START_TOKEN = makePredicate([ "atom", "num", "string", "regexp", "name" ]);
|
||||
|
||||
/* -----[ Parser ]----- */
|
||||
|
||||
function parse($TEXT, options) {
|
||||
|
||||
options = defaults(options, {
|
||||
bare_returns : false,
|
||||
expression : false,
|
||||
@@ -724,9 +721,11 @@ function parse($TEXT, options) {
|
||||
|
||||
function is(type, value) {
|
||||
return is_token(S.token, type, value);
|
||||
};
|
||||
}
|
||||
|
||||
function peek() { return S.peeked || (S.peeked = S.input()); };
|
||||
function peek() {
|
||||
return S.peeked || (S.peeked = S.input());
|
||||
}
|
||||
|
||||
function next() {
|
||||
S.prev = S.token;
|
||||
@@ -740,11 +739,11 @@ function parse($TEXT, options) {
|
||||
S.token.type == "string" || is("punc", ";")
|
||||
);
|
||||
return S.token;
|
||||
};
|
||||
}
|
||||
|
||||
function prev() {
|
||||
return S.prev;
|
||||
};
|
||||
}
|
||||
|
||||
function croak(msg, line, col, pos) {
|
||||
var ctx = S.input.context();
|
||||
@@ -753,26 +752,32 @@ function parse($TEXT, options) {
|
||||
line != null ? line : ctx.tokline,
|
||||
col != null ? col : ctx.tokcol,
|
||||
pos != null ? pos : ctx.tokpos);
|
||||
};
|
||||
}
|
||||
|
||||
function token_error(token, msg) {
|
||||
croak(msg, token.line, token.col);
|
||||
};
|
||||
}
|
||||
|
||||
function token_to_string(type, value) {
|
||||
return type + (value === undefined ? "" : " «" + value + "»");
|
||||
}
|
||||
|
||||
function unexpected(token) {
|
||||
if (token == null)
|
||||
token = S.token;
|
||||
token_error(token, "Unexpected token: " + token.type + " (" + token.value + ")");
|
||||
};
|
||||
token_error(token, "Unexpected token: " + token_to_string(token.type, token.value));
|
||||
}
|
||||
|
||||
function expect_token(type, val) {
|
||||
if (is(type, val)) {
|
||||
return next();
|
||||
}
|
||||
token_error(S.token, "Unexpected token " + S.token.type + " «" + S.token.value + "»" + ", expected " + type + " «" + val + "»");
|
||||
};
|
||||
token_error(S.token, "Unexpected token: " + token_to_string(S.token.type, S.token.value) + ", expected: " + token_to_string(type, val));
|
||||
}
|
||||
|
||||
function expect(punc) { return expect_token("punc", punc); };
|
||||
function expect(punc) {
|
||||
return expect_token("punc", punc);
|
||||
}
|
||||
|
||||
function has_newline_before(token) {
|
||||
return token.nlb || !all(token.comments_before, function(comment) {
|
||||
@@ -783,39 +788,39 @@ function parse($TEXT, options) {
|
||||
function can_insert_semicolon() {
|
||||
return !options.strict
|
||||
&& (is("eof") || is("punc", "}") || has_newline_before(S.token));
|
||||
};
|
||||
}
|
||||
|
||||
function semicolon(optional) {
|
||||
if (is("punc", ";")) next();
|
||||
else if (!optional && !can_insert_semicolon()) unexpected();
|
||||
};
|
||||
else if (!optional && !can_insert_semicolon()) expect_token("punc", ";");
|
||||
}
|
||||
|
||||
function parenthesised() {
|
||||
expect("(");
|
||||
var exp = expression(true);
|
||||
expect(")");
|
||||
return exp;
|
||||
};
|
||||
}
|
||||
|
||||
function embed_tokens(parser) {
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var expr = parser();
|
||||
var expr = parser.apply(null, arguments);
|
||||
var end = prev();
|
||||
expr.start = start;
|
||||
expr.end = end;
|
||||
return expr;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function handle_regexp() {
|
||||
if (is("operator", "/") || is("operator", "/=")) {
|
||||
S.peeked = null;
|
||||
S.token = S.input(S.token.value.substr(1)); // force regexp
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(strict_defun) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
@@ -901,6 +906,9 @@ function parse($TEXT, options) {
|
||||
return for_();
|
||||
|
||||
case "function":
|
||||
if (!strict_defun && S.input.has_directive("use strict")) {
|
||||
croak("In strict mode code, functions can only be declared at top level or immediately within another function.");
|
||||
}
|
||||
next();
|
||||
return function_(AST_Defun);
|
||||
|
||||
@@ -966,7 +974,9 @@ function parse($TEXT, options) {
|
||||
|
||||
function labeled_statement() {
|
||||
var label = as_symbol(AST_Label);
|
||||
if (find_if(function(l){ return l.name == label.name }, S.labels)) {
|
||||
if (!all(S.labels, function(l) {
|
||||
return l.name != label.name;
|
||||
})) {
|
||||
// ECMA-262, 12.12: An ECMAScript program is considered
|
||||
// syntactically incorrect if it contains a
|
||||
// LabelledStatement that is enclosed by a
|
||||
@@ -981,7 +991,7 @@ function parse($TEXT, options) {
|
||||
// check for `continue` that refers to this label.
|
||||
// those should be reported as syntax errors.
|
||||
// https://github.com/mishoo/UglifyJS2/issues/287
|
||||
label.references.forEach(function(ref){
|
||||
label.references.forEach(function(ref) {
|
||||
if (ref instanceof AST_Continue) {
|
||||
ref = ref.label.start;
|
||||
croak("Continue label `" + label.name + "` refers to non-IterationStatement.",
|
||||
@@ -990,11 +1000,11 @@ function parse($TEXT, options) {
|
||||
});
|
||||
}
|
||||
return new AST_LabeledStatement({ body: stat, label: label });
|
||||
};
|
||||
}
|
||||
|
||||
function simple_statement(tmp) {
|
||||
return new AST_SimpleStatement({ body: (tmp = expression(true), semicolon(), tmp) });
|
||||
};
|
||||
}
|
||||
|
||||
function break_cont(type) {
|
||||
var label = null, ldef;
|
||||
@@ -1002,18 +1012,17 @@ function parse($TEXT, options) {
|
||||
label = as_symbol(AST_LabelRef, true);
|
||||
}
|
||||
if (label != null) {
|
||||
ldef = find_if(function(l){ return l.name == label.name }, S.labels);
|
||||
if (!ldef)
|
||||
croak("Undefined label " + label.name);
|
||||
ldef = find_if(function(l) {
|
||||
return l.name == label.name;
|
||||
}, S.labels);
|
||||
if (!ldef) croak("Undefined label " + label.name);
|
||||
label.thedef = ldef;
|
||||
}
|
||||
else if (S.in_loop == 0)
|
||||
croak(type.TYPE + " not inside a loop or switch");
|
||||
} else if (S.in_loop == 0) croak(type.TYPE + " not inside a loop or switch");
|
||||
semicolon();
|
||||
var stat = new type({ label: label });
|
||||
if (ldef) ldef.references.push(stat);
|
||||
return stat;
|
||||
};
|
||||
}
|
||||
|
||||
function for_() {
|
||||
expect("(");
|
||||
@@ -1034,7 +1043,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
return regular_for(init);
|
||||
};
|
||||
}
|
||||
|
||||
function regular_for(init) {
|
||||
expect(";");
|
||||
@@ -1048,25 +1057,23 @@ function parse($TEXT, options) {
|
||||
step : step,
|
||||
body : in_loop(statement)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function for_in(init) {
|
||||
var lhs = init instanceof AST_Var ? init.definitions[0].name : null;
|
||||
var obj = expression(true);
|
||||
expect(")");
|
||||
return new AST_ForIn({
|
||||
init : init,
|
||||
name : lhs,
|
||||
object : obj,
|
||||
body : in_loop(statement)
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
var function_ = function(ctor) {
|
||||
var in_statement = ctor === AST_Defun;
|
||||
var name = is("name") ? as_symbol(in_statement ? AST_SymbolDefun : AST_SymbolLambda) : null;
|
||||
if (in_statement && !name)
|
||||
unexpected();
|
||||
expect_token("name");
|
||||
if (name && ctor !== AST_Accessor && !(name instanceof AST_SymbolDeclaration))
|
||||
unexpected(prev());
|
||||
expect("(");
|
||||
@@ -1083,7 +1090,7 @@ function parse($TEXT, options) {
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
var body = block_();
|
||||
var body = block_(true);
|
||||
if (S.input.has_directive("use strict")) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
argnames.forEach(strict_verify_symbol);
|
||||
@@ -1110,24 +1117,24 @@ function parse($TEXT, options) {
|
||||
body : body,
|
||||
alternative : belse
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function block_() {
|
||||
function block_(strict_defun) {
|
||||
expect("{");
|
||||
var a = [];
|
||||
while (!is("punc", "}")) {
|
||||
if (is("eof")) unexpected();
|
||||
a.push(statement());
|
||||
if (is("eof")) expect_token("punc", "}");
|
||||
a.push(statement(strict_defun));
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
function switch_body_() {
|
||||
expect("{");
|
||||
var a = [], cur = null, branch = null, tmp;
|
||||
while (!is("punc", "}")) {
|
||||
if (is("eof")) unexpected();
|
||||
if (is("eof")) expect_token("punc", "}");
|
||||
if (is("keyword", "case")) {
|
||||
if (branch) branch.end = prev();
|
||||
cur = [];
|
||||
@@ -1138,8 +1145,7 @@ function parse($TEXT, options) {
|
||||
});
|
||||
a.push(branch);
|
||||
expect(":");
|
||||
}
|
||||
else if (is("keyword", "default")) {
|
||||
} else if (is("keyword", "default")) {
|
||||
if (branch) branch.end = prev();
|
||||
cur = [];
|
||||
branch = new AST_Default({
|
||||
@@ -1147,8 +1153,7 @@ function parse($TEXT, options) {
|
||||
body : cur
|
||||
});
|
||||
a.push(branch);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!cur) unexpected();
|
||||
cur.push(statement());
|
||||
}
|
||||
@@ -1156,7 +1161,7 @@ function parse($TEXT, options) {
|
||||
if (branch) branch.end = prev();
|
||||
next();
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
function try_() {
|
||||
var body = block_(), bcatch = null, bfinally = null;
|
||||
@@ -1189,7 +1194,7 @@ function parse($TEXT, options) {
|
||||
bcatch : bcatch,
|
||||
bfinally : bfinally
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function vardefs(no_in) {
|
||||
var a = [];
|
||||
@@ -1205,7 +1210,7 @@ function parse($TEXT, options) {
|
||||
next();
|
||||
}
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
var var_ = function(no_in) {
|
||||
return new AST_Var({
|
||||
@@ -1225,12 +1230,14 @@ function parse($TEXT, options) {
|
||||
} else {
|
||||
args = [];
|
||||
}
|
||||
return subscripts(new AST_New({
|
||||
var call = new AST_New({
|
||||
start : start,
|
||||
expression : newexp,
|
||||
args : args,
|
||||
end : prev()
|
||||
}), allow_calls);
|
||||
});
|
||||
mark_pure(call);
|
||||
return subscripts(call, allow_calls);
|
||||
};
|
||||
|
||||
function as_atom_node() {
|
||||
@@ -1269,7 +1276,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
next();
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
var expr_atom = function(allow_calls) {
|
||||
if (is("operator", "new")) {
|
||||
@@ -1316,7 +1323,7 @@ function parse($TEXT, options) {
|
||||
func.end = prev();
|
||||
return subscripts(func, allow_calls);
|
||||
}
|
||||
if (ATOMIC_START_TOKEN(S.token.type)) {
|
||||
if (ATOMIC_START_TOKEN[S.token.type]) {
|
||||
return subscripts(as_atom_node(), allow_calls);
|
||||
}
|
||||
unexpected();
|
||||
@@ -1335,7 +1342,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
next();
|
||||
return a;
|
||||
};
|
||||
}
|
||||
|
||||
var array_ = embed_tokens(function() {
|
||||
expect("[");
|
||||
@@ -1362,7 +1369,7 @@ function parse($TEXT, options) {
|
||||
if (type == "name" && !is("punc", ":")) {
|
||||
var key = new AST_SymbolAccessor({
|
||||
start: S.token,
|
||||
name: as_property_name(),
|
||||
name: "" + as_property_name(),
|
||||
end: prev()
|
||||
});
|
||||
if (name == "get") {
|
||||
@@ -1388,7 +1395,7 @@ function parse($TEXT, options) {
|
||||
a.push(new AST_ObjectKeyVal({
|
||||
start : start,
|
||||
quote : start.quote,
|
||||
key : name,
|
||||
key : "" + name,
|
||||
value : expression(false),
|
||||
end : prev()
|
||||
}));
|
||||
@@ -1401,7 +1408,7 @@ function parse($TEXT, options) {
|
||||
var tmp = S.token;
|
||||
switch (tmp.type) {
|
||||
case "operator":
|
||||
if (!KEYWORDS(tmp.value)) unexpected();
|
||||
if (!KEYWORDS[tmp.value]) unexpected();
|
||||
case "num":
|
||||
case "string":
|
||||
case "name":
|
||||
@@ -1412,14 +1419,14 @@ function parse($TEXT, options) {
|
||||
default:
|
||||
unexpected();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function as_name() {
|
||||
var tmp = S.token;
|
||||
if (tmp.type != "name") unexpected();
|
||||
if (!is("name")) expect_token("name");
|
||||
var name = S.token.value;
|
||||
next();
|
||||
return tmp.value;
|
||||
};
|
||||
return name;
|
||||
}
|
||||
|
||||
function _make_symbol(type) {
|
||||
var name = S.token.value;
|
||||
@@ -1428,7 +1435,7 @@ function parse($TEXT, options) {
|
||||
start : S.token,
|
||||
end : S.token
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function strict_verify_symbol(sym) {
|
||||
if (sym.name == "arguments" || sym.name == "eval")
|
||||
@@ -1446,7 +1453,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
next();
|
||||
return sym;
|
||||
};
|
||||
}
|
||||
|
||||
function mark_pure(call) {
|
||||
var start = call.start;
|
||||
@@ -1499,7 +1506,7 @@ function parse($TEXT, options) {
|
||||
|
||||
var maybe_unary = function(allow_calls) {
|
||||
var start = S.token;
|
||||
if (is("operator") && UNARY_PREFIX(start.value)) {
|
||||
if (is("operator") && UNARY_PREFIX[start.value]) {
|
||||
next();
|
||||
handle_regexp();
|
||||
var ex = make_unary(AST_UnaryPrefix, start, maybe_unary(allow_calls));
|
||||
@@ -1508,7 +1515,7 @@ function parse($TEXT, options) {
|
||||
return ex;
|
||||
}
|
||||
var val = expr_atom(allow_calls);
|
||||
while (is("operator") && UNARY_POSTFIX(S.token.value) && !has_newline_before(S.token)) {
|
||||
while (is("operator") && UNARY_POSTFIX[S.token.value] && !has_newline_before(S.token)) {
|
||||
val = make_unary(AST_UnaryPostfix, S.token, val);
|
||||
val.start = start;
|
||||
val.end = S.token;
|
||||
@@ -1531,7 +1538,7 @@ function parse($TEXT, options) {
|
||||
break;
|
||||
}
|
||||
return new ctor({ operator: op, expression: expr });
|
||||
};
|
||||
}
|
||||
|
||||
var expr_op = function(left, min_prec, no_in) {
|
||||
var op = is("operator") ? S.token.value : null;
|
||||
@@ -1553,7 +1560,7 @@ function parse($TEXT, options) {
|
||||
|
||||
function expr_ops(no_in) {
|
||||
return expr_op(maybe_unary(true), 0, no_in);
|
||||
};
|
||||
}
|
||||
|
||||
var maybe_conditional = function(no_in) {
|
||||
var start = S.token;
|
||||
@@ -1575,12 +1582,12 @@ function parse($TEXT, options) {
|
||||
|
||||
function is_assignable(expr) {
|
||||
return expr instanceof AST_PropAccess || expr instanceof AST_SymbolRef;
|
||||
};
|
||||
}
|
||||
|
||||
var maybe_assign = function(no_in) {
|
||||
var start = S.token;
|
||||
var left = maybe_conditional(no_in), val = S.token.value;
|
||||
if (is("operator") && ASSIGNMENT(val)) {
|
||||
if (is("operator") && ASSIGNMENT[val]) {
|
||||
if (is_assignable(left)) {
|
||||
next();
|
||||
return new AST_Assign({
|
||||
@@ -1617,18 +1624,19 @@ function parse($TEXT, options) {
|
||||
var ret = cont();
|
||||
--S.in_loop;
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
if (options.expression) {
|
||||
handle_regexp();
|
||||
return expression(true);
|
||||
}
|
||||
|
||||
return (function(){
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev();
|
||||
var toplevel = options.toplevel;
|
||||
@@ -1639,6 +1647,5 @@ function parse($TEXT, options) {
|
||||
toplevel = new AST_Toplevel({ start: start, body: body, end: end });
|
||||
}
|
||||
return toplevel;
|
||||
})();
|
||||
|
||||
};
|
||||
}();
|
||||
}
|
||||
|
||||
@@ -53,25 +53,30 @@ function find_builtins(reserved) {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
[ Object, Array, Function, Number,
|
||||
String, Boolean, Error, Math,
|
||||
Date, RegExp
|
||||
].forEach(function(ctor){
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
}
|
||||
});
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -79,6 +84,10 @@ function reserve_quoted_keys(ast, reserved) {
|
||||
addStrings(node.property, add);
|
||||
}
|
||||
}));
|
||||
|
||||
function add(name) {
|
||||
push_uniq(reserved, name);
|
||||
}
|
||||
}
|
||||
|
||||
function addStrings(node, add) {
|
||||
@@ -110,12 +119,15 @@ function mangle_properties(ast, options) {
|
||||
if (!Array.isArray(reserved)) reserved = [];
|
||||
if (!options.builtins) find_builtins(reserved);
|
||||
|
||||
var cache = options.cache;
|
||||
if (cache == null) {
|
||||
cache = {
|
||||
cname: -1,
|
||||
props: new Dictionary()
|
||||
};
|
||||
var cname = -1;
|
||||
var cache;
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
cache.each(function(mangled_name) {
|
||||
push_uniq(reserved, mangled_name);
|
||||
});
|
||||
} else {
|
||||
cache = new Dictionary();
|
||||
}
|
||||
|
||||
var regex = options.regex;
|
||||
@@ -124,45 +136,43 @@ function mangle_properties(ast, options) {
|
||||
// note debug may be enabled as an empty string, which is falsey. Also treat passing 'true'
|
||||
// the same as passing an empty string.
|
||||
var debug = options.debug !== false;
|
||||
var debug_name_suffix;
|
||||
if (debug) {
|
||||
debug_name_suffix = (options.debug === true ? "" : options.debug);
|
||||
}
|
||||
var debug_suffix;
|
||||
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
|
||||
|
||||
var names_to_mangle = [];
|
||||
var unmangleable = [];
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node){
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ObjectKeyVal) {
|
||||
add(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter, since KeyVal is handled above
|
||||
add(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
} else if (node instanceof AST_Dot) {
|
||||
add(node.property);
|
||||
}
|
||||
else if (node instanceof AST_Sub) {
|
||||
} else if (node instanceof AST_Sub) {
|
||||
addStrings(node.property, add);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
addStrings(node.args[1], add);
|
||||
}
|
||||
}));
|
||||
|
||||
// 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) {
|
||||
node.key = mangle(node.key);
|
||||
}
|
||||
else if (node instanceof AST_ObjectProperty) {
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
// setter or getter
|
||||
node.key.name = mangle(node.key.name);
|
||||
}
|
||||
else if (node instanceof AST_Dot) {
|
||||
} else if (node instanceof AST_Dot) {
|
||||
node.property = mangle(node.property);
|
||||
}
|
||||
else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
} else if (!options.keep_quoted && node instanceof AST_Sub) {
|
||||
node.property = mangleStrings(node.property);
|
||||
} else if (node instanceof AST_Call
|
||||
&& node.expression.print_to_string() == "Object.defineProperty") {
|
||||
node.args[1] = mangleStrings(node.args[1]);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -171,9 +181,7 @@ function mangle_properties(ast, options) {
|
||||
function can_mangle(name) {
|
||||
if (unmangleable.indexOf(name) >= 0) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
if (options.only_cache) {
|
||||
return cache.props.has(name);
|
||||
}
|
||||
if (options.only_cache) return cache.has(name);
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
@@ -181,57 +189,42 @@ function mangle_properties(ast, options) {
|
||||
function should_mangle(name) {
|
||||
if (regex && !regex.test(name)) return false;
|
||||
if (reserved.indexOf(name) >= 0) return false;
|
||||
return cache.props.has(name)
|
||||
|| names_to_mangle.indexOf(name) >= 0;
|
||||
return cache.has(name) || names_to_mangle.indexOf(name) >= 0;
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
if (can_mangle(name))
|
||||
push_uniq(names_to_mangle, name);
|
||||
|
||||
if (!should_mangle(name)) {
|
||||
push_uniq(unmangleable, name);
|
||||
}
|
||||
if (can_mangle(name)) push_uniq(names_to_mangle, name);
|
||||
if (!should_mangle(name)) push_uniq(unmangleable, name);
|
||||
}
|
||||
|
||||
function mangle(name) {
|
||||
if (!should_mangle(name)) {
|
||||
return name;
|
||||
}
|
||||
|
||||
var mangled = cache.props.get(name);
|
||||
var mangled = cache.get(name);
|
||||
if (!mangled) {
|
||||
if (debug) {
|
||||
// debug mode: use a prefix and suffix to preserve readability, e.g. o.foo -> o._$foo$NNN_.
|
||||
var debug_mangled = "_$" + name + "$" + debug_name_suffix + "_";
|
||||
|
||||
if (can_mangle(debug_mangled)) {
|
||||
mangled = debug_mangled;
|
||||
}
|
||||
var debug_mangled = "_$" + name + "$" + debug_suffix + "_";
|
||||
if (can_mangle(debug_mangled)) mangled = debug_mangled;
|
||||
}
|
||||
|
||||
// either debug mode is off, or it is on and we could not use the mangled name
|
||||
if (!mangled) {
|
||||
do {
|
||||
mangled = base54(++cache.cname);
|
||||
} while (!can_mangle(mangled));
|
||||
}
|
||||
|
||||
cache.props.set(name, mangled);
|
||||
if (!mangled) do {
|
||||
mangled = base54(++cname);
|
||||
} while (!can_mangle(mangled));
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
return mangled;
|
||||
}
|
||||
|
||||
function mangleStrings(node) {
|
||||
return node.transform(new TreeTransformer(function(node){
|
||||
return node.transform(new TreeTransformer(function(node) {
|
||||
if (node instanceof AST_Sequence) {
|
||||
var last = node.expressions.length - 1;
|
||||
node.expressions[last] = mangleStrings(node.expressions[last]);
|
||||
}
|
||||
else if (node instanceof AST_String) {
|
||||
} else if (node instanceof AST_String) {
|
||||
node.value = mangle(node.value);
|
||||
}
|
||||
else if (node instanceof AST_Conditional) {
|
||||
} else if (node instanceof AST_Conditional) {
|
||||
node.consequent = mangleStrings(node.consequent);
|
||||
node.alternative = mangleStrings(node.alternative);
|
||||
}
|
||||
|
||||
415
lib/scope.js
415
lib/scope.js
@@ -43,9 +43,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(scope, orig) {
|
||||
function SymbolDef(scope, orig, init) {
|
||||
this.name = orig.name;
|
||||
this.orig = [ orig ];
|
||||
this.init = init;
|
||||
this.eliminated = 0;
|
||||
this.scope = scope;
|
||||
this.references = [];
|
||||
@@ -54,7 +55,7 @@ function SymbolDef(scope, orig) {
|
||||
this.mangled_name = null;
|
||||
this.undeclared = false;
|
||||
this.id = SymbolDef.next_id++;
|
||||
};
|
||||
}
|
||||
|
||||
SymbolDef.next_id = 1;
|
||||
|
||||
@@ -62,28 +63,24 @@ SymbolDef.prototype = {
|
||||
unmangleable: function(options) {
|
||||
if (!options) options = {};
|
||||
|
||||
return (this.global && !options.toplevel)
|
||||
return this.global && !options.toplevel
|
||||
|| this.undeclared
|
||||
|| (!options.eval && (this.scope.uses_eval || this.scope.uses_with))
|
||||
|| (options.keep_fnames
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
||||
|| this.orig[0] instanceof AST_SymbolDefun));
|
||||
|| this.orig[0] instanceof AST_SymbolDefun);
|
||||
},
|
||||
mangle: function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
if (this.global && cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
}
|
||||
else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var s = this.scope;
|
||||
var sym = this.orig[0];
|
||||
if (options.ie8 && sym instanceof AST_SymbolLambda)
|
||||
s = s.parent_scope;
|
||||
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
var def;
|
||||
if (def = this.redefined()) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else
|
||||
this.mangled_name = s.next_mangled(options, this);
|
||||
} else {
|
||||
this.mangled_name = next_mangled_name(this.scope, options, this);
|
||||
}
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
@@ -94,7 +91,7 @@ SymbolDef.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
options = defaults(options, {
|
||||
cache: null,
|
||||
ie8: false,
|
||||
@@ -103,9 +100,8 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
// pass 1: setup scope chaining and handle definitions
|
||||
var self = this;
|
||||
var scope = self.parent_scope = null;
|
||||
var labels = new Dictionary();
|
||||
var defun = null;
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_Catch) {
|
||||
var save_scope = scope;
|
||||
scope = new AST_Scope(node);
|
||||
@@ -118,28 +114,14 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
node.init_scope_vars(scope);
|
||||
var save_scope = scope;
|
||||
var save_defun = defun;
|
||||
var save_labels = labels;
|
||||
defun = scope = node;
|
||||
labels = new Dictionary();
|
||||
descend();
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
labels = save_labels;
|
||||
return true; // don't descend again in TreeWalker
|
||||
}
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
var l = node.label;
|
||||
if (labels.has(l.name)) {
|
||||
throw new Error(string_template("Label {name} defined twice", l));
|
||||
}
|
||||
labels.set(l.name, l);
|
||||
descend();
|
||||
labels.del(l.name);
|
||||
return true; // no descend again
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_With) {
|
||||
for (var s = scope; s; s = s.parent_scope)
|
||||
s.uses_with = true;
|
||||
for (var s = scope; s; s = s.parent_scope) s.uses_with = true;
|
||||
return;
|
||||
}
|
||||
if (node instanceof AST_Symbol) {
|
||||
@@ -149,48 +131,34 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
node.thedef = node;
|
||||
node.references = [];
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
defun.def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolDefun) {
|
||||
// Careful here, the scope where this should be defined is
|
||||
// the parent scope. The reason is that we enter a new
|
||||
// scope when we encounter the AST_Defun node (which is
|
||||
// instanceof AST_Scope) but we get to the symbol a bit
|
||||
// later.
|
||||
(node.scope = defun.parent_scope).def_function(node);
|
||||
}
|
||||
else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node);
|
||||
if (node instanceof AST_SymbolDefun) {
|
||||
// This should be defined in the parent scope, as we encounter the
|
||||
// AST_Defun node before getting to its AST_Symbol.
|
||||
(node.scope = defun.parent_scope.resolve()).def_function(node, defun);
|
||||
} else if (node instanceof AST_SymbolLambda) {
|
||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
||||
} else if (node instanceof AST_SymbolVar) {
|
||||
defun.def_variable(node, node.TYPE == "SymbolVar" ? null : undefined);
|
||||
if (defun !== scope) {
|
||||
node.mark_enclosed(options);
|
||||
var def = scope.find_variable(node);
|
||||
if (node.thedef !== def) {
|
||||
node.thedef = def;
|
||||
node.reference(options);
|
||||
}
|
||||
node.reference(options);
|
||||
}
|
||||
}
|
||||
else if (node instanceof AST_SymbolCatch) {
|
||||
} else if (node instanceof AST_SymbolCatch) {
|
||||
scope.def_variable(node).defun = defun;
|
||||
}
|
||||
else if (node instanceof AST_LabelRef) {
|
||||
var sym = labels.get(node.name);
|
||||
if (!sym) throw new Error(string_template("Undefined label {name} [{line},{col}]", {
|
||||
name: node.name,
|
||||
line: node.start.line,
|
||||
col: node.start.col
|
||||
}));
|
||||
node.thedef = sym;
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 2: find back references and eval
|
||||
self.globals = new Dictionary();
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
if (node instanceof AST_LoopControl && node.label) {
|
||||
node.label.thedef.references.push(node);
|
||||
var tw = new TreeWalker(function(node) {
|
||||
if (node instanceof AST_LoopControl) {
|
||||
if (node.label) node.label.thedef.references.push(node);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolRef) {
|
||||
@@ -211,43 +179,43 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
|
||||
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) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var def = node.definition().redefined();
|
||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
self.walk(tw);
|
||||
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie8) {
|
||||
self.walk(new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var name = node.name;
|
||||
var refs = node.thedef.references;
|
||||
var scope = node.thedef.defun;
|
||||
var def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||
refs.forEach(function(ref) {
|
||||
ref.thedef = def;
|
||||
ref.reference(options);
|
||||
});
|
||||
node.thedef = def;
|
||||
node.reference(options);
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
}
|
||||
if (options.ie8) self.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
redefine(node, node.thedef.defun);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
var def = node.thedef;
|
||||
redefine(node, node.scope.parent_scope);
|
||||
node.thedef.init = def.init;
|
||||
return true;
|
||||
}
|
||||
}));
|
||||
|
||||
if (options.cache) {
|
||||
this.cname = options.cache.cname;
|
||||
function redefine(node, scope) {
|
||||
var name = node.name;
|
||||
var old_def = node.thedef;
|
||||
var new_def = scope.find_variable(name) || self.globals.get(name) || scope.def_variable(node);
|
||||
old_def.orig.concat(old_def.references).forEach(function(node) {
|
||||
node.thedef = new_def;
|
||||
node.reference(options);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
||||
var globals = this.globals, name = node.name;
|
||||
if (globals.has(name)) {
|
||||
return globals.get(name);
|
||||
@@ -260,7 +228,7 @@ AST_Toplevel.DEFMETHOD("def_global", function(node){
|
||||
}
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
|
||||
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
||||
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope)
|
||||
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
||||
@@ -270,7 +238,7 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope){
|
||||
this.cname = -1; // the current index for mangling functions/variables
|
||||
});
|
||||
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
AST_Lambda.DEFMETHOD("init_scope_vars", function() {
|
||||
AST_Scope.prototype.init_scope_vars.apply(this, arguments);
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
@@ -282,8 +250,7 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function(){
|
||||
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
var s = this.scope;
|
||||
while (s) {
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
@@ -291,7 +258,6 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
});
|
||||
}
|
||||
if (s === def.scope) break;
|
||||
s = s.parent_scope;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -300,71 +266,91 @@ AST_Symbol.DEFMETHOD("reference", function(options) {
|
||||
this.mark_enclosed(options);
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name){
|
||||
AST_Scope.DEFMETHOD("find_variable", function(name) {
|
||||
if (name instanceof AST_Symbol) name = name.name;
|
||||
return this.variables.get(name)
|
||||
|| (this.parent_scope && this.parent_scope.find_variable(name));
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol){
|
||||
var def = this.def_variable(symbol);
|
||||
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
|
||||
var def = this.def_variable(symbol, init);
|
||||
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
||||
this.functions.set(symbol.name, def);
|
||||
return def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol){
|
||||
var def;
|
||||
if (!this.variables.has(symbol.name)) {
|
||||
def = new SymbolDef(this, symbol);
|
||||
AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
|
||||
var def = this.variables.get(symbol.name);
|
||||
if (def) {
|
||||
def.orig.push(symbol);
|
||||
if (def.init && (def.scope !== symbol.scope || def.init instanceof AST_Function)) {
|
||||
def.init = init;
|
||||
}
|
||||
} else {
|
||||
def = new SymbolDef(this, symbol, init);
|
||||
this.variables.set(symbol.name, def);
|
||||
def.global = !this.parent_scope;
|
||||
} else {
|
||||
def = this.variables.get(symbol.name);
|
||||
def.orig.push(symbol);
|
||||
}
|
||||
return symbol.thedef = def;
|
||||
});
|
||||
|
||||
AST_Scope.DEFMETHOD("next_mangled", function(options){
|
||||
var ext = this.enclosed;
|
||||
out: while (true) {
|
||||
var m = base54(++this.cname);
|
||||
if (!is_identifier(m)) continue; // skip over "do"
|
||||
|
||||
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not
|
||||
// shadow a name reserved from mangling.
|
||||
if (member(m, options.reserved)) continue;
|
||||
|
||||
// we must ensure that the mangled name does not shadow a name
|
||||
// from some parent scope that is referenced in this or in
|
||||
// inner scopes.
|
||||
for (var i = ext.length; --i >= 0;) {
|
||||
var sym = ext[i];
|
||||
var name = sym.mangled_name || (sym.unmangleable(options) && sym.name);
|
||||
if (m == name) continue out;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
AST_Lambda.DEFMETHOD("resolve", return_this);
|
||||
AST_Scope.DEFMETHOD("resolve", function() {
|
||||
return this.parent_scope;
|
||||
});
|
||||
AST_Toplevel.DEFMETHOD("resolve", return_this);
|
||||
|
||||
AST_Function.DEFMETHOD("next_mangled", function(options, def){
|
||||
// #179, #326
|
||||
// in Safari strict mode, something like (function x(x){...}) is a syntax error;
|
||||
// a function expression's argument cannot shadow the function expression's name
|
||||
|
||||
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition();
|
||||
|
||||
// the function's mangled_name is null when keep_fnames is true
|
||||
var tricky_name = tricky_def ? tricky_def.mangled_name || tricky_def.name : null;
|
||||
function names_in_use(scope, options) {
|
||||
var names = scope.names_in_use;
|
||||
if (!names) {
|
||||
scope.names_in_use = names = Object.create(scope.mangled_names || null);
|
||||
scope.cname_holes = [];
|
||||
var cache = options.cache && options.cache.props;
|
||||
scope.enclosed.forEach(function(def) {
|
||||
if (def.unmangleable(options)) names[def.name] = true;
|
||||
if (def.global && cache && cache.has(def.name)) {
|
||||
names[cache.get(def.name)] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
function next_mangled_name(scope, options, def) {
|
||||
var in_use = names_in_use(scope, options);
|
||||
var holes = scope.cname_holes;
|
||||
var names = Object.create(null);
|
||||
var scopes = [ scope ];
|
||||
def.references.forEach(function(sym) {
|
||||
var scope = sym.scope;
|
||||
do {
|
||||
if (scopes.indexOf(scope) < 0) {
|
||||
for (var name in names_in_use(scope, options)) {
|
||||
names[name] = true;
|
||||
}
|
||||
scopes.push(scope);
|
||||
} else break;
|
||||
} while (scope = scope.parent_scope);
|
||||
});
|
||||
var name;
|
||||
for (var i = 0, len = holes.length; i < len; i++) {
|
||||
name = base54(holes[i]);
|
||||
if (names[name]) continue;
|
||||
holes.splice(i, 1);
|
||||
scope.names_in_use[name] = true;
|
||||
return name;
|
||||
}
|
||||
while (true) {
|
||||
var name = AST_Lambda.prototype.next_mangled.call(this, options, def);
|
||||
if (!tricky_name || tricky_name != name)
|
||||
return name;
|
||||
name = base54(++scope.cname);
|
||||
if (in_use[name] || !is_identifier(name) || options.reserved.has[name]) continue;
|
||||
if (!names[name]) break;
|
||||
holes.push(scope.cname);
|
||||
}
|
||||
});
|
||||
scope.names_in_use[name] = true;
|
||||
return name;
|
||||
}
|
||||
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
AST_Symbol.DEFMETHOD("unmangleable", function(options) {
|
||||
var def = this.definition();
|
||||
return !def || def.unmangleable(options);
|
||||
});
|
||||
@@ -372,20 +358,19 @@ AST_Symbol.DEFMETHOD("unmangleable", function(options){
|
||||
// labels are always mangleable
|
||||
AST_Label.DEFMETHOD("unmangleable", return_false);
|
||||
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function(){
|
||||
return this.definition().references.length == 0
|
||||
&& !(this.scope.uses_eval || this.scope.uses_with);
|
||||
AST_Symbol.DEFMETHOD("unreferenced", function() {
|
||||
return !this.definition().references.length && !this.scope.pinned();
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("definition", function(){
|
||||
AST_Symbol.DEFMETHOD("definition", function() {
|
||||
return this.thedef;
|
||||
});
|
||||
|
||||
AST_Symbol.DEFMETHOD("global", function(){
|
||||
AST_Symbol.DEFMETHOD("global", function() {
|
||||
return this.definition().global;
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||
function _default_mangler_options(options) {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
ie8 : false,
|
||||
@@ -396,113 +381,128 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options) {
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
// Never mangle arguments
|
||||
push_uniq(options.reserved, "arguments");
|
||||
options.reserved.has = makePredicate(options.reserved);
|
||||
return options;
|
||||
});
|
||||
}
|
||||
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
|
||||
// We only need to mangle declaration nodes. Special logic wired
|
||||
// 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
|
||||
// the AST_SymbolDeclaration that it points to).
|
||||
var lname = -1;
|
||||
var to_mangle = [];
|
||||
|
||||
if (options.cache) {
|
||||
this.globals.each(collect);
|
||||
if (options.cache && options.cache.props) {
|
||||
var mangled_names = this.mangled_names = Object.create(null);
|
||||
options.cache.props.each(function(mangled_name) {
|
||||
mangled_names[mangled_name] = true;
|
||||
});
|
||||
}
|
||||
|
||||
var tw = new TreeWalker(function(node, descend){
|
||||
var redefined = [];
|
||||
var tw = new TreeWalker(function(node, descend) {
|
||||
if (node instanceof AST_LabeledStatement) {
|
||||
// lname is incremented when we get to the AST_Label
|
||||
var save_nesting = lname;
|
||||
descend();
|
||||
lname = save_nesting;
|
||||
return true; // don't descend again in TreeWalker
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Scope) {
|
||||
node.variables.each(collect);
|
||||
return;
|
||||
descend();
|
||||
if (options.cache && node instanceof AST_Toplevel) {
|
||||
node.globals.each(mangle);
|
||||
}
|
||||
node.variables.each(mangle);
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
var name;
|
||||
do name = base54(++lname); while (!is_identifier(name));
|
||||
do {
|
||||
name = base54(++lname);
|
||||
} while (!is_identifier(name));
|
||||
node.mangled_name = name;
|
||||
return true;
|
||||
}
|
||||
if (!options.ie8 && node instanceof AST_SymbolCatch) {
|
||||
to_mangle.push(node.definition());
|
||||
return;
|
||||
if (!options.ie8 && node instanceof AST_Catch) {
|
||||
var def = node.argname.definition();
|
||||
var redef = def.redefined();
|
||||
if (redef) {
|
||||
redefined.push(def);
|
||||
reference(node.argname);
|
||||
def.references.forEach(reference);
|
||||
}
|
||||
descend();
|
||||
if (!redef) mangle(def);
|
||||
return true;
|
||||
}
|
||||
|
||||
function reference(sym) {
|
||||
sym.thedef = redef;
|
||||
sym.reference(options);
|
||||
sym.thedef = def;
|
||||
}
|
||||
});
|
||||
this.walk(tw);
|
||||
to_mangle.forEach(function(def){ def.mangle(options) });
|
||||
redefined.forEach(mangle);
|
||||
|
||||
if (options.cache) {
|
||||
options.cache.cname = this.cname;
|
||||
}
|
||||
|
||||
function collect(symbol) {
|
||||
if (!member(symbol.name, options.reserved)) {
|
||||
to_mangle.push(symbol);
|
||||
}
|
||||
function mangle(def) {
|
||||
if (options.reserved.has[def.name]) return;
|
||||
def.mangle(options);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("find_unique_prefix", function(options) {
|
||||
var letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_";
|
||||
AST_Toplevel.DEFMETHOD("find_colliding_names", function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
var prefixes = Object.create(null);
|
||||
options.reserved.forEach(add_prefix);
|
||||
var avoid = Object.create(null);
|
||||
options.reserved.forEach(to_avoid);
|
||||
this.globals.each(add_def);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(add_def);
|
||||
if (node instanceof AST_SymbolCatch) add_def(node.definition());
|
||||
}));
|
||||
var prefix, i = 0;
|
||||
do {
|
||||
prefix = create_name(i++);
|
||||
} while (prefixes[prefix]);
|
||||
return prefix;
|
||||
return avoid;
|
||||
|
||||
function add_prefix(name) {
|
||||
if (/[0-9]$/.test(name)) {
|
||||
prefixes[name.replace(/[0-9]+$/, "")] = true;
|
||||
}
|
||||
function to_avoid(name) {
|
||||
avoid[name] = true;
|
||||
}
|
||||
|
||||
function add_def(def) {
|
||||
var name = def.name;
|
||||
if (def.global && cache && cache.has(name)) name = cache.get(name);
|
||||
else if (!def.unmangleable(options)) return;
|
||||
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;
|
||||
to_avoid(name);
|
||||
}
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("expand_names", function(options) {
|
||||
options = this._default_mangler_options(options);
|
||||
var prefix = this.find_unique_prefix(options);
|
||||
base54.reset();
|
||||
base54.sort();
|
||||
options = _default_mangler_options(options);
|
||||
var avoid = this.find_colliding_names(options);
|
||||
var cname = 0;
|
||||
this.globals.each(rename);
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_Scope) node.variables.each(rename);
|
||||
if (node instanceof AST_SymbolCatch) rename(node.definition());
|
||||
}));
|
||||
|
||||
function next_name() {
|
||||
var name;
|
||||
do {
|
||||
name = base54(cname++);
|
||||
} while (avoid[name] || !is_identifier(name));
|
||||
return name;
|
||||
}
|
||||
|
||||
function rename(def) {
|
||||
if (def.global || def.unmangleable(options)) return;
|
||||
if (member(def.name, options.reserved)) return;
|
||||
if (def.global && options.cache) return;
|
||||
if (def.unmangleable(options)) return;
|
||||
if (options.reserved.has[def.name]) return;
|
||||
var d = def.redefined();
|
||||
def.name = d ? d.name : prefix + def.id;
|
||||
def.name = d ? d.name : next_name();
|
||||
def.orig.forEach(function(sym) {
|
||||
sym.name = def.name;
|
||||
});
|
||||
@@ -517,8 +517,9 @@ AST_Sequence.DEFMETHOD("tail_node", function() {
|
||||
return this.expressions[this.expressions.length - 1];
|
||||
});
|
||||
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
options = this._default_mangler_options(options);
|
||||
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
||||
options = _default_mangler_options(options);
|
||||
base54.reset();
|
||||
try {
|
||||
AST_Node.prototype.print = function(stream, force_parens) {
|
||||
this._print(stream, force_parens);
|
||||
@@ -551,17 +552,21 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
|
||||
});
|
||||
|
||||
var base54 = (function() {
|
||||
var leading = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_".split("");
|
||||
var digits = "0123456789".split("");
|
||||
var freq = Object.create(null);
|
||||
function init(chars) {
|
||||
var array = [];
|
||||
for (var i = 0, len = chars.length; i < len; i++) {
|
||||
var ch = chars[i];
|
||||
array.push(ch);
|
||||
freq[ch] = -1e-2 * i;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
var digits = init("0123456789");
|
||||
var leading = init("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_");
|
||||
var chars, frequency;
|
||||
function reset() {
|
||||
frequency = Object.create(null);
|
||||
leading.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
digits.forEach(function(ch) {
|
||||
frequency[ch] = 0;
|
||||
});
|
||||
frequency = Object.create(freq);
|
||||
}
|
||||
base54.consider = function(str, delta) {
|
||||
for (var i = str.length; --i >= 0;) {
|
||||
@@ -572,7 +577,7 @@ var base54 = (function() {
|
||||
return frequency[b] - frequency[a];
|
||||
}
|
||||
base54.sort = function() {
|
||||
chars = mergeSort(leading, compare).concat(mergeSort(digits, compare));
|
||||
chars = leading.sort(compare).concat(digits.sort(compare));
|
||||
};
|
||||
base54.reset = reset;
|
||||
reset();
|
||||
@@ -586,6 +591,6 @@ var base54 = (function() {
|
||||
base = 64;
|
||||
} while (num > 0);
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
return base54;
|
||||
})();
|
||||
|
||||
@@ -46,52 +46,59 @@
|
||||
// a small wrapper around fitzgen's source-map library
|
||||
function SourceMap(options) {
|
||||
options = defaults(options, {
|
||||
file : null,
|
||||
root : null,
|
||||
orig : null,
|
||||
|
||||
orig_line_diff : 0,
|
||||
dest_line_diff : 0,
|
||||
});
|
||||
file: null,
|
||||
root: null,
|
||||
orig: null,
|
||||
orig_line_diff: 0,
|
||||
dest_line_diff: 0,
|
||||
}, true);
|
||||
var generator = new MOZ_SourceMap.SourceMapGenerator({
|
||||
file : options.file,
|
||||
sourceRoot : options.root
|
||||
file: options.file,
|
||||
sourceRoot: options.root
|
||||
});
|
||||
var orig_map = options.orig && new MOZ_SourceMap.SourceMapConsumer(options.orig);
|
||||
|
||||
if (orig_map && Array.isArray(options.orig.sources)) {
|
||||
orig_map._sources.toArray().forEach(function(source) {
|
||||
var sourceContent = orig_map.sourceContentFor(source, true);
|
||||
if (sourceContent) {
|
||||
generator.setSourceContent(source, sourceContent);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function add(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
if (orig_map) {
|
||||
var info = orig_map.originalPositionFor({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
var maps = options.orig && Object.create(null);
|
||||
if (maps) for (var source in options.orig) {
|
||||
var map = new MOZ_SourceMap.SourceMapConsumer(options.orig[source]);
|
||||
if (Array.isArray(options.orig[source].sources)) {
|
||||
map._sources.toArray().forEach(function(source) {
|
||||
var sourceContent = map.sourceContentFor(source, true);
|
||||
if (sourceContent) generator.setSourceContent(source, sourceContent);
|
||||
});
|
||||
if (info.source === null) {
|
||||
return;
|
||||
}
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
generated : { line: gen_line + options.dest_line_diff, column: gen_col },
|
||||
original : { line: orig_line + options.orig_line_diff, column: orig_col },
|
||||
source : source,
|
||||
name : name
|
||||
});
|
||||
};
|
||||
maps[source] = map;
|
||||
}
|
||||
return {
|
||||
add : add,
|
||||
get : function() { return generator },
|
||||
toString : function() { return JSON.stringify(generator.toJSON()); }
|
||||
add: function(source, gen_line, gen_col, orig_line, orig_col, name) {
|
||||
var map = maps && maps[source];
|
||||
if (map) {
|
||||
var info = map.originalPositionFor({
|
||||
line: orig_line,
|
||||
column: orig_col
|
||||
});
|
||||
if (info.source === null) return;
|
||||
source = info.source;
|
||||
orig_line = info.line;
|
||||
orig_col = info.column;
|
||||
name = info.name || name;
|
||||
}
|
||||
generator.addMapping({
|
||||
name: name,
|
||||
source: source,
|
||||
generated: {
|
||||
line: gen_line + options.dest_line_diff,
|
||||
column: gen_col
|
||||
},
|
||||
original: {
|
||||
line: orig_line + options.orig_line_diff,
|
||||
column: orig_col
|
||||
}
|
||||
});
|
||||
},
|
||||
get: function() {
|
||||
return generator;
|
||||
},
|
||||
toString: function() {
|
||||
return JSON.stringify(generator.toJSON());
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
133
lib/transform.js
133
lib/transform.js
@@ -43,8 +43,6 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
// Tree transformer helpers.
|
||||
|
||||
function TreeTransformer(before, after) {
|
||||
TreeWalker.call(this);
|
||||
this.before = before;
|
||||
@@ -52,163 +50,136 @@ function TreeTransformer(before, after) {
|
||||
}
|
||||
TreeTransformer.prototype = new TreeWalker;
|
||||
|
||||
(function(undefined){
|
||||
|
||||
function _(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list){
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (x === undefined) {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
if (tw.after) {
|
||||
y = tw.after(x, in_list);
|
||||
if (y !== undefined) x = y;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return x;
|
||||
});
|
||||
};
|
||||
|
||||
(function(DEF) {
|
||||
function do_list(list, tw) {
|
||||
return MAP(list, function(node){
|
||||
return MAP(list, function(node) {
|
||||
return node.transform(tw, true);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
_(AST_Node, noop);
|
||||
|
||||
_(AST_LabeledStatement, function(self, tw){
|
||||
DEF(AST_Node, noop);
|
||||
DEF(AST_LabeledStatement, function(self, tw) {
|
||||
self.label = self.label.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_SimpleStatement, function(self, tw){
|
||||
DEF(AST_SimpleStatement, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Block, function(self, tw){
|
||||
DEF(AST_Block, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_DWLoop, function(self, tw){
|
||||
DEF(AST_Do, function(self, tw) {
|
||||
self.body = self.body.transform(tw);
|
||||
self.condition = self.condition.transform(tw);
|
||||
});
|
||||
DEF(AST_While, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_For, function(self, tw){
|
||||
DEF(AST_For, function(self, tw) {
|
||||
if (self.init) self.init = self.init.transform(tw);
|
||||
if (self.condition) self.condition = self.condition.transform(tw);
|
||||
if (self.step) self.step = self.step.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_ForIn, function(self, tw){
|
||||
DEF(AST_ForIn, function(self, tw) {
|
||||
self.init = self.init.transform(tw);
|
||||
self.object = self.object.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_With, function(self, tw){
|
||||
DEF(AST_With, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Exit, function(self, tw){
|
||||
DEF(AST_Exit, function(self, tw) {
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_LoopControl, function(self, tw){
|
||||
DEF(AST_LoopControl, function(self, tw) {
|
||||
if (self.label) self.label = self.label.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_If, function(self, tw){
|
||||
DEF(AST_If, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.body = self.body.transform(tw);
|
||||
if (self.alternative) self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Switch, function(self, tw){
|
||||
DEF(AST_Switch, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Case, function(self, tw){
|
||||
DEF(AST_Case, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Try, function(self, tw){
|
||||
DEF(AST_Try, function(self, tw) {
|
||||
self.body = do_list(self.body, tw);
|
||||
if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
|
||||
if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Catch, function(self, tw){
|
||||
DEF(AST_Catch, function(self, tw) {
|
||||
self.argname = self.argname.transform(tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Definitions, function(self, tw){
|
||||
DEF(AST_Definitions, function(self, tw) {
|
||||
self.definitions = do_list(self.definitions, tw);
|
||||
});
|
||||
|
||||
_(AST_VarDef, function(self, tw){
|
||||
DEF(AST_VarDef, function(self, tw) {
|
||||
self.name = self.name.transform(tw);
|
||||
if (self.value) self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Lambda, function(self, tw){
|
||||
DEF(AST_Lambda, function(self, tw) {
|
||||
if (self.name) self.name = self.name.transform(tw);
|
||||
self.argnames = do_list(self.argnames, tw);
|
||||
self.body = do_list(self.body, tw);
|
||||
});
|
||||
|
||||
_(AST_Call, function(self, tw){
|
||||
DEF(AST_Call, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.args = do_list(self.args, tw);
|
||||
});
|
||||
|
||||
_(AST_Sequence, function(self, tw){
|
||||
DEF(AST_Sequence, function(self, tw) {
|
||||
self.expressions = do_list(self.expressions, tw);
|
||||
});
|
||||
|
||||
_(AST_Dot, function(self, tw){
|
||||
DEF(AST_Dot, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Sub, function(self, tw){
|
||||
DEF(AST_Sub, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
self.property = self.property.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Unary, function(self, tw){
|
||||
DEF(AST_Unary, function(self, tw) {
|
||||
self.expression = self.expression.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Binary, function(self, tw){
|
||||
DEF(AST_Binary, function(self, tw) {
|
||||
self.left = self.left.transform(tw);
|
||||
self.right = self.right.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Conditional, function(self, tw){
|
||||
DEF(AST_Conditional, function(self, tw) {
|
||||
self.condition = self.condition.transform(tw);
|
||||
self.consequent = self.consequent.transform(tw);
|
||||
self.alternative = self.alternative.transform(tw);
|
||||
});
|
||||
|
||||
_(AST_Array, function(self, tw){
|
||||
DEF(AST_Array, function(self, tw) {
|
||||
self.elements = do_list(self.elements, tw);
|
||||
});
|
||||
|
||||
_(AST_Object, function(self, tw){
|
||||
DEF(AST_Object, function(self, tw) {
|
||||
self.properties = do_list(self.properties, tw);
|
||||
});
|
||||
|
||||
_(AST_ObjectProperty, function(self, tw){
|
||||
DEF(AST_ObjectProperty, function(self, tw) {
|
||||
self.value = self.value.transform(tw);
|
||||
});
|
||||
|
||||
})();
|
||||
})(function(node, descend) {
|
||||
node.DEFMETHOD("transform", function(tw, in_list) {
|
||||
var x, y;
|
||||
tw.push(this);
|
||||
if (tw.before) x = tw.before(this, descend, in_list);
|
||||
if (typeof x === "undefined") {
|
||||
x = this;
|
||||
descend(x, tw);
|
||||
if (tw.after) {
|
||||
y = tw.after(x, in_list);
|
||||
if (typeof y !== "undefined") x = y;
|
||||
}
|
||||
}
|
||||
tw.pop();
|
||||
return x;
|
||||
});
|
||||
});
|
||||
|
||||
180
lib/utils.js
180
lib/utils.js
@@ -45,27 +45,23 @@
|
||||
|
||||
function characters(str) {
|
||||
return str.split("");
|
||||
};
|
||||
}
|
||||
|
||||
function member(name, array) {
|
||||
return array.indexOf(name) >= 0;
|
||||
};
|
||||
}
|
||||
|
||||
function find_if(func, array) {
|
||||
for (var i = 0, n = array.length; i < n; ++i) {
|
||||
if (func(array[i]))
|
||||
return array[i];
|
||||
}
|
||||
};
|
||||
for (var i = array.length; --i >= 0;) if (func(array[i])) return array[i];
|
||||
}
|
||||
|
||||
function repeat_string(str, i) {
|
||||
if (i <= 0) return "";
|
||||
if (i == 1) return str;
|
||||
var d = repeat_string(str, i >> 1);
|
||||
d += d;
|
||||
if (i & 1) d += str;
|
||||
return d;
|
||||
};
|
||||
return i & 1 ? d + str : d;
|
||||
}
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
@@ -84,27 +80,23 @@ function configure_error_stack(fn) {
|
||||
function DefaultsError(msg, defs) {
|
||||
this.message = msg;
|
||||
this.defs = defs;
|
||||
};
|
||||
}
|
||||
DefaultsError.prototype = Object.create(Error.prototype);
|
||||
DefaultsError.prototype.constructor = DefaultsError;
|
||||
DefaultsError.prototype.name = "DefaultsError";
|
||||
configure_error_stack(DefaultsError);
|
||||
|
||||
DefaultsError.croak = function(msg, defs) {
|
||||
throw new DefaultsError(msg, defs);
|
||||
};
|
||||
|
||||
function defaults(args, defs, croak) {
|
||||
if (args === true)
|
||||
args = {};
|
||||
if (args === true) args = {};
|
||||
var ret = args || {};
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i))
|
||||
DefaultsError.croak("`" + i + "` is not a supported option", defs);
|
||||
if (croak) for (var i in ret) if (HOP(ret, i) && !HOP(defs, i)) {
|
||||
throw new DefaultsError("`" + i + "` is not a supported option", defs);
|
||||
}
|
||||
for (var i in defs) if (HOP(defs, i)) {
|
||||
ret[i] = (args && HOP(args, i)) ? args[i] : defs[i];
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
function merge(obj, ext) {
|
||||
var count = 0;
|
||||
@@ -113,7 +105,7 @@ function merge(obj, ext) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
};
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
@@ -121,7 +113,7 @@ function return_true() { return true; }
|
||||
function return_this() { return this; }
|
||||
function return_null() { return null; }
|
||||
|
||||
var MAP = (function(){
|
||||
var MAP = (function() {
|
||||
function MAP(a, f, backwards) {
|
||||
var ret = [], top = [], i;
|
||||
function doit() {
|
||||
@@ -144,8 +136,8 @@ var MAP = (function(){
|
||||
}
|
||||
}
|
||||
return is_last;
|
||||
};
|
||||
if (a instanceof Array) {
|
||||
}
|
||||
if (Array.isArray(a)) {
|
||||
if (backwards) {
|
||||
for (i = a.length; --i >= 0;) if (doit()) break;
|
||||
ret.reverse();
|
||||
@@ -158,115 +150,52 @@ var MAP = (function(){
|
||||
for (i in a) if (HOP(a, i)) if (doit()) break;
|
||||
}
|
||||
return top.concat(ret);
|
||||
};
|
||||
}
|
||||
MAP.at_top = function(val) { return new AtTop(val) };
|
||||
MAP.splice = function(val) { return new Splice(val) };
|
||||
MAP.last = function(val) { return new Last(val) };
|
||||
var skip = MAP.skip = {};
|
||||
function AtTop(val) { this.v = val };
|
||||
function Splice(val) { this.v = val };
|
||||
function Last(val) { this.v = val };
|
||||
function AtTop(val) { this.v = val }
|
||||
function Splice(val) { this.v = val }
|
||||
function Last(val) { this.v = val }
|
||||
return MAP;
|
||||
})();
|
||||
|
||||
function push_uniq(array, el) {
|
||||
if (array.indexOf(el) < 0)
|
||||
array.push(el);
|
||||
};
|
||||
if (array.indexOf(el) < 0) return array.push(el);
|
||||
}
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p){
|
||||
return text.replace(/\{(.+?)\}/g, function(str, p) {
|
||||
return props && props[p];
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function remove(array, el) {
|
||||
for (var i = array.length; --i >= 0;) {
|
||||
if (array[i] === el) array.splice(i, 1);
|
||||
}
|
||||
};
|
||||
var index = array.indexOf(el);
|
||||
if (index >= 0) array.splice(index, 1);
|
||||
}
|
||||
|
||||
function mergeSort(array, cmp) {
|
||||
if (array.length < 2) return array.slice();
|
||||
function merge(a, b) {
|
||||
var r = [], ai = 0, bi = 0, i = 0;
|
||||
while (ai < a.length && bi < b.length) {
|
||||
cmp(a[ai], b[bi]) <= 0
|
||||
? r[i++] = a[ai++]
|
||||
: r[i++] = b[bi++];
|
||||
}
|
||||
if (ai < a.length) r.push.apply(r, a.slice(ai));
|
||||
if (bi < b.length) r.push.apply(r, b.slice(bi));
|
||||
return r;
|
||||
};
|
||||
function _ms(a) {
|
||||
if (a.length <= 1)
|
||||
return a;
|
||||
var m = Math.floor(a.length / 2), left = a.slice(0, m), right = a.slice(m);
|
||||
left = _ms(left);
|
||||
right = _ms(right);
|
||||
return merge(left, right);
|
||||
};
|
||||
return _ms(array);
|
||||
};
|
||||
|
||||
// this function is taken from Acorn [1], written by Marijn Haverbeke
|
||||
// [1] https://github.com/marijnh/acorn
|
||||
function makePredicate(words) {
|
||||
if (!(words instanceof Array)) words = words.split(" ");
|
||||
var f = "", cats = [];
|
||||
out: for (var i = 0; i < words.length; ++i) {
|
||||
for (var j = 0; j < cats.length; ++j)
|
||||
if (cats[j][0].length == words[i].length) {
|
||||
cats[j].push(words[i]);
|
||||
continue out;
|
||||
}
|
||||
cats.push([words[i]]);
|
||||
}
|
||||
function quote(word) {
|
||||
return JSON.stringify(word).replace(/[\u2028\u2029]/g, function(s) {
|
||||
switch (s) {
|
||||
case "\u2028": return "\\u2028";
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
return s;
|
||||
});
|
||||
}
|
||||
function compareTo(arr) {
|
||||
if (arr.length == 1) return f += "return str === " + quote(arr[0]) + ";";
|
||||
f += "switch(str){";
|
||||
for (var i = 0; i < arr.length; ++i) f += "case " + quote(arr[i]) + ":";
|
||||
f += "return true}return false;";
|
||||
}
|
||||
// When there are more than three length categories, an outer
|
||||
// switch first dispatches on the lengths, to save on comparisons.
|
||||
if (cats.length > 3) {
|
||||
cats.sort(function(a, b) {return b.length - a.length;});
|
||||
f += "switch(str.length){";
|
||||
for (var i = 0; i < cats.length; ++i) {
|
||||
var cat = cats[i];
|
||||
f += "case " + cat[0].length + ":";
|
||||
compareTo(cat);
|
||||
}
|
||||
f += "}";
|
||||
// Otherwise, simply generate a flat `switch` statement.
|
||||
} else {
|
||||
compareTo(words);
|
||||
}
|
||||
return new Function("str", f);
|
||||
};
|
||||
if (!Array.isArray(words)) words = words.split(" ");
|
||||
var map = Object.create(null);
|
||||
words.forEach(function(word) {
|
||||
map[word] = true;
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
function all(array, predicate) {
|
||||
for (var i = array.length; --i >= 0;)
|
||||
if (!predicate(array[i]))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
function Dictionary() {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
};
|
||||
}
|
||||
Dictionary.prototype = {
|
||||
set: function(key, val) {
|
||||
if (!this.has(key)) ++this._size;
|
||||
@@ -303,6 +232,13 @@ Dictionary.prototype = {
|
||||
ret.push(f(this._values[i], i.substr(1)));
|
||||
return ret;
|
||||
},
|
||||
clone: function() {
|
||||
var ret = new Dictionary();
|
||||
for (var i in this._values)
|
||||
ret._values[i] = this._values[i];
|
||||
ret._size = this._size;
|
||||
return ret;
|
||||
},
|
||||
toObject: function() { return this._values }
|
||||
};
|
||||
Dictionary.fromObject = function(obj) {
|
||||
@@ -320,20 +256,22 @@ function HOP(obj, prop) {
|
||||
// a statement.
|
||||
function first_in_statement(stack) {
|
||||
var node = stack.parent(-1);
|
||||
for (var i = 0, p; p = stack.parent(i); i++) {
|
||||
if (p instanceof AST_Statement && p.body === node)
|
||||
return true;
|
||||
if ((p instanceof AST_Sequence && p.expressions[0] === node) ||
|
||||
(p.TYPE == "Call" && p.expression === node ) ||
|
||||
(p instanceof AST_Dot && p.expression === node ) ||
|
||||
(p instanceof AST_Sub && p.expression === node ) ||
|
||||
(p instanceof AST_Conditional && p.condition === node ) ||
|
||||
(p instanceof AST_Binary && p.left === node ) ||
|
||||
(p instanceof AST_UnaryPostfix && p.expression === node ))
|
||||
{
|
||||
node = p;
|
||||
} else {
|
||||
return false;
|
||||
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||
if (p.TYPE == "Call") {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Binary) {
|
||||
if (p.left === node) continue;
|
||||
} else if (p instanceof AST_Conditional) {
|
||||
if (p.condition === node) continue;
|
||||
} else if (p instanceof AST_PropAccess) {
|
||||
if (p.expression === node) continue;
|
||||
} else if (p instanceof AST_Sequence) {
|
||||
if (p.expressions[0] === node) continue;
|
||||
} else if (p instanceof AST_Statement) {
|
||||
return p.body === node;
|
||||
} else if (p instanceof AST_UnaryPostfix) {
|
||||
if (p.expression === node) continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
44
package.json
44
package.json
@@ -1,23 +1,17 @@
|
||||
{
|
||||
"name": "uglify-js",
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"homepage": "http://lisperator.net/uglifyjs",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.3.4",
|
||||
"version": "3.5.3",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
"maintainers": [
|
||||
"Alex Lam <alexlamsl@gmail.com>",
|
||||
"Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mishoo/UglifyJS2.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mishoo/UglifyJS2/issues"
|
||||
},
|
||||
"repository": "mishoo/UglifyJS2",
|
||||
"main": "tools/node.js",
|
||||
"bin": {
|
||||
"uglifyjs": "bin/uglifyjs"
|
||||
@@ -29,16 +23,38 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"dependencies": {
|
||||
"commander": "~2.12.1",
|
||||
"commander": "~2.19.0",
|
||||
"source-map": "~0.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "~5.2.1",
|
||||
"mocha": "~3.5.1",
|
||||
"semver": "~5.4.1"
|
||||
"acorn": "~6.1.1",
|
||||
"semver": "~5.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/run-tests.js"
|
||||
},
|
||||
"keywords": ["uglify", "uglify-js", "minify", "minifier", "es5"]
|
||||
"keywords": [
|
||||
"cli",
|
||||
"compress",
|
||||
"compressor",
|
||||
"ecma",
|
||||
"ecmascript",
|
||||
"es",
|
||||
"es5",
|
||||
"javascript",
|
||||
"js",
|
||||
"jsmin",
|
||||
"min",
|
||||
"minification",
|
||||
"minifier",
|
||||
"minify",
|
||||
"optimize",
|
||||
"optimizer",
|
||||
"pack",
|
||||
"packer",
|
||||
"parse",
|
||||
"parser",
|
||||
"uglifier",
|
||||
"uglify"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ var remaining = 2 * urls.length;
|
||||
function done() {
|
||||
if (!--remaining) {
|
||||
var failures = [];
|
||||
var sum = { input: 0, output: 0, gzip: 0 };
|
||||
urls.forEach(function(url) {
|
||||
var info = results[url];
|
||||
console.log();
|
||||
@@ -40,6 +41,9 @@ function done() {
|
||||
if (info.code) {
|
||||
failures.push(url);
|
||||
}
|
||||
sum.input += info.input;
|
||||
sum.output += info.output;
|
||||
sum.gzip += info.gzip;
|
||||
});
|
||||
if (failures.length) {
|
||||
console.error("Benchmark failed:");
|
||||
@@ -47,6 +51,13 @@ function done() {
|
||||
console.error(url);
|
||||
});
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log();
|
||||
console.log("Subtotal");
|
||||
console.log();
|
||||
console.log("Original:", sum.input, "bytes");
|
||||
console.log("Uglified:", sum.output, "bytes");
|
||||
console.log("GZipped: ", sum.gzip, "bytes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
578
test/compress/arguments.js
Normal file
578
test/compress/arguments.js
Normal file
@@ -0,0 +1,578 @@
|
||||
replace_index: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
var arguments = [];
|
||||
console.log(arguments[0]);
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(arguments) {
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
(function() {
|
||||
var arguments;
|
||||
console.log(arguments[1], arguments[1], arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
"a a undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
replace_index_keep_fargs_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(arguments[1], arguments["1"], arguments["foo"]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(argument_0, argument_1) {
|
||||
console.log(argument_1, argument_1, arguments.foo);
|
||||
})("bar", 42);
|
||||
(function(a, b) {
|
||||
console.log(b, b, arguments.foo);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42 42 undefined",
|
||||
"42 42 undefined",
|
||||
]
|
||||
}
|
||||
|
||||
modified: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
(function(a, b) {
|
||||
var c = a;
|
||||
var d = b;
|
||||
var a = "foo";
|
||||
b++;
|
||||
a = "moo";
|
||||
b *= 2;
|
||||
console.log(a, b, c, d, a, b);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "moo 86 bar 42 moo 86"
|
||||
}
|
||||
|
||||
modified_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a, b) {
|
||||
var c = arguments[0];
|
||||
var d = arguments[1];
|
||||
var a = "foo";
|
||||
b++;
|
||||
arguments[0] = "moo";
|
||||
arguments[1] *= 2;
|
||||
console.log(a, b, c, d, arguments[0], arguments[1]);
|
||||
})("bar", 42);
|
||||
}
|
||||
expect_stdout: "foo 43 bar 42 moo 84"
|
||||
}
|
||||
|
||||
duplicate_argname: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], arguments[1], arguments[2]);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a, b, a) {
|
||||
console.log(a, b, arguments[0], b, a);
|
||||
})("foo", 42, "bar");
|
||||
}
|
||||
expect_stdout: "bar 42 foo 42 bar"
|
||||
}
|
||||
|
||||
issue_3273: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
console.log(a, a);
|
||||
a++;
|
||||
console.log(a, a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 1",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_local_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
"use strict";
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict: {
|
||||
options = {
|
||||
arguments: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3273_global_strict_reduce_vars: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
console.log(arguments[0], a);
|
||||
arguments[0]++;
|
||||
console.log(arguments[0], a);
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0 0",
|
||||
"1 0",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3282_1: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_1_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return function() {
|
||||
(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2: {
|
||||
options = {
|
||||
arguments: true,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_3282_2_passes: {
|
||||
options = {
|
||||
arguments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f();
|
||||
})(function() {
|
||||
return (function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
})(function() {
|
||||
'use strict';
|
||||
function e() {
|
||||
return arguments[0];
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
return function(t) {
|
||||
return function() {
|
||||
t();
|
||||
};
|
||||
}(function() {
|
||||
"use strict";
|
||||
function e(argument_0) {
|
||||
return argument_0;
|
||||
}
|
||||
e();
|
||||
e();
|
||||
})();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -15,9 +15,9 @@ holes_and_undefined: {
|
||||
|
||||
constant_join: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "foo", "bar", "baz" ].join("");
|
||||
var a1 = [ "foo", "bar", "baz" ].join();
|
||||
@@ -64,9 +64,9 @@ constant_join: {
|
||||
|
||||
constant_join_2: {
|
||||
options = {
|
||||
unsafe : true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "foo", "bar", boo(), "baz", "x", "y" ].join("");
|
||||
var b = [ "foo", "bar", boo(), "baz", "x", "y" ].join("-");
|
||||
@@ -93,9 +93,9 @@ constant_join_2: {
|
||||
|
||||
constant_join_3: {
|
||||
options = {
|
||||
unsafe: true,
|
||||
evaluate: true,
|
||||
};
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ null ].join();
|
||||
var b = [ , ].join();
|
||||
@@ -133,7 +133,7 @@ for_loop: {
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function f0() {
|
||||
var a = [1, 2, 3];
|
||||
@@ -239,3 +239,113 @@ index_length: {
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
}
|
||||
|
||||
constructor_bad: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
new Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(NaN);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL1");
|
||||
} catch (ex) {
|
||||
try {
|
||||
Array(3.14);
|
||||
console.log("FAIL2");
|
||||
} catch (ex) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:13,12]",
|
||||
"WARN: Invalid array length: 3.14 [test/compress/arrays.js:17,16]",
|
||||
]
|
||||
}
|
||||
|
||||
constructor_good: {
|
||||
options = {
|
||||
unsafe: true
|
||||
}
|
||||
input: {
|
||||
console.log(Array());
|
||||
console.log(Array(0));
|
||||
console.log(Array(1));
|
||||
console.log(Array(6));
|
||||
console.log(Array(7));
|
||||
console.log(Array(1, 2));
|
||||
console.log(Array(false));
|
||||
console.log(Array("foo"));
|
||||
console.log(Array(Array));
|
||||
console.log(new Array());
|
||||
console.log(new Array(0));
|
||||
console.log(new Array(1));
|
||||
console.log(new Array(6));
|
||||
console.log(new Array(7));
|
||||
console.log(new Array(1, 2));
|
||||
console.log(new Array(false));
|
||||
console.log(new Array("foo"));
|
||||
console.log(new Array(Array));
|
||||
}
|
||||
expect: {
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
console.log([]);
|
||||
console.log([]);
|
||||
console.log([,]);
|
||||
console.log([,,,,,,]);
|
||||
console.log(Array(7));
|
||||
console.log([ 1, 2 ]);
|
||||
console.log([ false ]);
|
||||
console.log([ "foo" ]);
|
||||
console.log(Array(Array));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
asm_mixed: {
|
||||
options = {
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
drop_debugger : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
side_effects : true,
|
||||
negate_iife : true
|
||||
};
|
||||
assignments: true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// adapted from http://asmjs.org/spec/latest/
|
||||
function asm_GeometricMean(stdlib, foreign, buffer) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
op_equals_left_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -60,6 +61,7 @@ op_equals_left_local_var: {
|
||||
|
||||
op_equals_right_local_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -123,6 +125,7 @@ op_equals_right_local_var: {
|
||||
}
|
||||
op_equals_left_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -179,6 +182,7 @@ op_equals_left_global_var: {
|
||||
|
||||
op_equals_right_global_var: {
|
||||
options = {
|
||||
assignments: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
@@ -236,3 +240,52 @@ op_equals_right_global_var: {
|
||||
x = g() & x;
|
||||
}
|
||||
}
|
||||
|
||||
increment_decrement_1: {
|
||||
options = {
|
||||
assignments: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
increment_decrement_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
a = a + 1;
|
||||
a = a - 1;
|
||||
a += 1;
|
||||
a -= 1;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a){
|
||||
++a;
|
||||
--a;
|
||||
++a;
|
||||
--a;
|
||||
return a;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,114 +0,0 @@
|
||||
keep_comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: false
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
keep_comparisons_with_unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe_comps: true
|
||||
}
|
||||
input: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1 = {
|
||||
valueOf: function() {triggeredFirst();}
|
||||
}
|
||||
var obj2 = {
|
||||
valueOf: function() {triggeredSecond();}
|
||||
}
|
||||
var result1 = obj2 >= obj1;
|
||||
var result2 = obj2 > obj1;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
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"
|
||||
}
|
||||
347
test/compress/comparisons.js
Normal file
347
test/compress/comparisons.js
Normal file
@@ -0,0 +1,347 @@
|
||||
comparisons: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj1 >= obj2;
|
||||
var result4 = obj1 > obj2;
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
var result1 = obj1 <= obj2;
|
||||
var result2 = obj1 < obj2;
|
||||
var result3 = obj2 <= obj1;
|
||||
var result4 = obj2 < obj1;
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_comps: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var obj1, obj2;
|
||||
obj1 <= obj2 ? f1() : g1();
|
||||
obj1 < obj2 ? f2() : g2();
|
||||
obj1 >= obj2 ? f3() : g3();
|
||||
obj1 > obj2 ? f4() : g4();
|
||||
}
|
||||
expect: {
|
||||
var obj1, obj2;
|
||||
obj2 < obj1 ? g1() : f1();
|
||||
obj1 < obj2 ? f2() : g2();
|
||||
obj1 < obj2 ? g3() : f3();
|
||||
obj2 < obj1 ? f4() : g4();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
null instanceof null;
|
||||
}
|
||||
expect: {
|
||||
1 in 1;
|
||||
null in null;
|
||||
1 instanceof 1;
|
||||
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"
|
||||
}
|
||||
|
||||
issue_2857_1: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a) {
|
||||
a === undefined || a === null;
|
||||
a === undefined || a !== null;
|
||||
a !== undefined || a === null;
|
||||
a !== undefined || a !== null;
|
||||
a === undefined && a === null;
|
||||
a === undefined && a !== null;
|
||||
a !== undefined && a === null;
|
||||
a !== undefined && a !== null;
|
||||
}
|
||||
function f2(a) {
|
||||
a === null || a === undefined;
|
||||
a === null || a !== undefined;
|
||||
a !== null || a === undefined;
|
||||
a !== null || a !== undefined;
|
||||
a === null && a === undefined;
|
||||
a === null && a !== undefined;
|
||||
a !== null && a === undefined;
|
||||
a !== null && a !== undefined;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1(a) {
|
||||
null == a;
|
||||
void 0 === a || null !== a;
|
||||
void 0 !== a || null === a;
|
||||
void 0 !== a || null !== a;
|
||||
void 0 === a && null === a;
|
||||
void 0 === a && null !== a;
|
||||
void 0 !== a && null === a;
|
||||
null != a;
|
||||
}
|
||||
function f2(a) {
|
||||
null == a;
|
||||
null === a || void 0 !== a;
|
||||
null !== a || void 0 === a;
|
||||
null !== a || void 0 !== a;
|
||||
null === a && void 0 === a;
|
||||
null === a && void 0 !== a;
|
||||
null !== a && void 0 === a;
|
||||
null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_2: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null || p;
|
||||
a === undefined || a !== null || p;
|
||||
a !== undefined || a === null || p;
|
||||
a !== undefined || a !== null || p;
|
||||
a === undefined && a === null || p;
|
||||
a === undefined && a !== null || p;
|
||||
a !== undefined && a === null || p;
|
||||
a !== undefined && a !== null || p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
null == a || p;
|
||||
void 0 === a || null !== a || p;
|
||||
void 0 !== a || null === a || p;
|
||||
void 0 !== a || null !== a || p;
|
||||
void 0 === a && null === a || p;
|
||||
void 0 === a && null !== a || p;
|
||||
void 0 !== a && null === a || p;
|
||||
null != a || p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_3: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
a === undefined || a === null && p;
|
||||
a === undefined || a !== null && p;
|
||||
a !== undefined || a === null && p;
|
||||
a !== undefined || a !== null && p;
|
||||
a === undefined && a === null && p;
|
||||
a === undefined && a !== null && p;
|
||||
a !== undefined && a === null && p;
|
||||
a !== undefined && a !== null && p;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
void 0 === a || null === a && p;
|
||||
void 0 === a || null !== a && p;
|
||||
void 0 !== a || null === a && p;
|
||||
void 0 !== a || null !== a && p;
|
||||
void 0 === a && null === a && p;
|
||||
void 0 === a && null !== a && p;
|
||||
void 0 !== a && null === a && p;
|
||||
null != a && p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_4: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p || a === undefined || a === null;
|
||||
p || a === undefined || a !== null;
|
||||
p || a !== undefined || a === null;
|
||||
p || a !== undefined || a !== null;
|
||||
p || a === undefined && a === null;
|
||||
p || a === undefined && a !== null;
|
||||
p || a !== undefined && a === null;
|
||||
p || a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p || null == a;
|
||||
p || void 0 === a || null !== a;
|
||||
p || void 0 !== a || null === a;
|
||||
p || void 0 !== a || null !== a;
|
||||
p || void 0 === a && null === a;
|
||||
p || void 0 === a && null !== a;
|
||||
p || void 0 !== a && null === a;
|
||||
p || null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_5: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, p) {
|
||||
p && a === undefined || a === null;
|
||||
p && a === undefined || a !== null;
|
||||
p && a !== undefined || a === null;
|
||||
p && a !== undefined || a !== null;
|
||||
p && a === undefined && a === null;
|
||||
p && a === undefined && a !== null;
|
||||
p && a !== undefined && a === null;
|
||||
p && a !== undefined && a !== null;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, p) {
|
||||
p && void 0 === a || null === a;
|
||||
p && void 0 === a || null !== a;
|
||||
p && void 0 !== a || null === a;
|
||||
p && void 0 !== a || null !== a;
|
||||
p && void 0 === a && null === a;
|
||||
p && void 0 === a && null !== a;
|
||||
p && void 0 !== a && null === a;
|
||||
p && null != a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_2857_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (({}).b === undefined || {}.b === null)
|
||||
return a.b !== undefined && a.b !== null;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (null == {}.b)
|
||||
return void 0 !== a.b && null !== a.b;
|
||||
}
|
||||
console.log(f({
|
||||
a: [ null ],
|
||||
get b() {
|
||||
return this.a.shift();
|
||||
}
|
||||
}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(/foo/.test("bar") === [].isPrototypeOf({}));
|
||||
}
|
||||
expect: {
|
||||
console.log(/foo/.test("bar") == [].isPrototypeOf({}));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_number_unsafe: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(Math.acos(42) !== "foo".charCodeAt(4));
|
||||
}
|
||||
expect: {
|
||||
console.log(Math.acos(42) != "foo".charCodeAt(4));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
is_boolean_var: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] === c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
for (var i = 0, c = !b; i < a.length; i++)
|
||||
if (!a[i] == c)
|
||||
return i;
|
||||
}([ false, true ], 42));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
concat_1: {
|
||||
options = {
|
||||
evaluate: true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a = "foo" + "bar" + x() + "moo" + "foo" + y() + "x" + "y" + "z" + q();
|
||||
var b = "foo" + 1 + x() + 2 + "boo";
|
||||
@@ -26,7 +26,7 @@ concat_1: {
|
||||
}
|
||||
|
||||
concat_2: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + (2 + 3),
|
||||
@@ -55,7 +55,7 @@ concat_2: {
|
||||
}
|
||||
|
||||
concat_3: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + 2 + (3 + 4 + 5),
|
||||
@@ -84,7 +84,7 @@ concat_3: {
|
||||
}
|
||||
|
||||
concat_4: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
1 + "2" + (3 + 4 + 5),
|
||||
@@ -113,7 +113,7 @@ concat_4: {
|
||||
}
|
||||
|
||||
concat_5: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
"1" + 2 + (3 + 4 + 5),
|
||||
@@ -142,7 +142,7 @@ concat_5: {
|
||||
}
|
||||
|
||||
concat_6: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log(
|
||||
"1" + "2" + (3 + 4 + 5),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ifs_1: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo) bar();
|
||||
if (!foo); else bar();
|
||||
@@ -18,8 +18,8 @@ ifs_1: {
|
||||
|
||||
ifs_2: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo) {
|
||||
x();
|
||||
@@ -47,12 +47,12 @@ ifs_2: {
|
||||
|
||||
ifs_3_should_warn: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
side_effects : true,
|
||||
};
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var x, y;
|
||||
if (x && !(x + "1") && y) { // 1
|
||||
@@ -78,8 +78,8 @@ ifs_3_should_warn: {
|
||||
|
||||
ifs_4: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (foo && bar) {
|
||||
x(foo)[10].bar.baz = something();
|
||||
@@ -95,10 +95,10 @@ ifs_4: {
|
||||
|
||||
ifs_5: {
|
||||
options = {
|
||||
if_return: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
};
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
if (foo) return;
|
||||
@@ -132,9 +132,9 @@ ifs_5: {
|
||||
|
||||
ifs_6: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
comparisons: true
|
||||
};
|
||||
}
|
||||
input: {
|
||||
var x, y;
|
||||
if (!foo && !bar && !baz && !boo) {
|
||||
@@ -163,8 +163,8 @@ ifs_6: {
|
||||
|
||||
cond_1: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function foo(do_something, some_condition) {
|
||||
if (some_condition) {
|
||||
@@ -189,8 +189,8 @@ cond_1: {
|
||||
|
||||
cond_2: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x, FooBar, some_condition) {
|
||||
if (some_condition) {
|
||||
@@ -209,8 +209,8 @@ cond_2: {
|
||||
|
||||
cond_3: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var FooBar;
|
||||
if (some_condition()) {
|
||||
@@ -227,8 +227,8 @@ cond_3: {
|
||||
|
||||
cond_4: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var do_something;
|
||||
if (some_condition()) {
|
||||
@@ -251,8 +251,8 @@ cond_4: {
|
||||
|
||||
cond_5: {
|
||||
options = {
|
||||
conditionals: true
|
||||
};
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
if (some_condition()) {
|
||||
if (some_other_condition()) {
|
||||
@@ -279,9 +279,9 @@ cond_5: {
|
||||
cond_7: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
var x, y, z, a, b;
|
||||
// compress these
|
||||
@@ -332,7 +332,7 @@ cond_7: {
|
||||
x = 'foo';
|
||||
x = 'foo';
|
||||
x = (condition(), 20);
|
||||
x = z ? 'fuji' : (condition(), 'fuji');
|
||||
x = (z || condition(), 'fuji');
|
||||
x = (condition(), 'foobar');
|
||||
x = y ? a : b;
|
||||
x = y ? 'foo' : 'fo';
|
||||
@@ -342,8 +342,8 @@ cond_7: {
|
||||
cond_7_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var x;
|
||||
// access to global should be assumed to have side effects
|
||||
@@ -361,10 +361,10 @@ cond_7_1: {
|
||||
|
||||
cond_8: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : false
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -445,10 +445,10 @@ cond_8: {
|
||||
|
||||
cond_8b: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -528,10 +528,10 @@ cond_8b: {
|
||||
|
||||
cond_8c: {
|
||||
options = {
|
||||
booleans: false,
|
||||
conditionals: true,
|
||||
evaluate : false,
|
||||
booleans : false
|
||||
};
|
||||
evaluate: false,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
// compress these
|
||||
@@ -647,9 +647,21 @@ cond_9: {
|
||||
|
||||
ternary_boolean_consequent: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? true : x; }
|
||||
@@ -675,9 +687,21 @@ ternary_boolean_consequent: {
|
||||
|
||||
ternary_boolean_alternative: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:true, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() { return a == b ? x : true; }
|
||||
@@ -703,10 +727,11 @@ ternary_boolean_alternative: {
|
||||
|
||||
trivial_boolean_ternary_expressions : {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true
|
||||
};
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
f('foo' in m ? true : false);
|
||||
f('foo' in m ? false : true);
|
||||
@@ -777,11 +802,11 @@ trivial_boolean_ternary_expressions : {
|
||||
|
||||
issue_1154: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function f1(x) { return x ? -1 : -1; }
|
||||
function f2(x) { return x ? +2 : +2; }
|
||||
@@ -817,7 +842,7 @@ issue_1154: {
|
||||
no_evaluate: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate : false,
|
||||
evaluate: false,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1203,3 +1228,191 @@ issue_2560: {
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if (x()) {
|
||||
var a;
|
||||
y();
|
||||
} else {
|
||||
z();
|
||||
var b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
x() ? y() : z();
|
||||
}
|
||||
}
|
||||
|
||||
to_and_or: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x ? y || z : z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var values = [
|
||||
0,
|
||||
null,
|
||||
true,
|
||||
"foo",
|
||||
false,
|
||||
-1 / 0,
|
||||
void 0,
|
||||
];
|
||||
values.forEach(function(x) {
|
||||
values.forEach(function(y) {
|
||||
values.forEach(function(z) {
|
||||
console.log(x && y || z);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
cond_seq_assign_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
t = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
t = a ? (t = "foo", "bar") : (console.log(t), 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var t;
|
||||
if (a) {
|
||||
t = "foo";
|
||||
a = "bar";
|
||||
} else {
|
||||
console.log(t);
|
||||
t = 42;
|
||||
}
|
||||
console.log(t);
|
||||
}
|
||||
f(f);
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var t;
|
||||
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
|
||||
console.log(t);
|
||||
}
|
||||
f(f),
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
cond_seq_assign_3: {
|
||||
options = {
|
||||
assignments: true,
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
if (this)
|
||||
c = 1 + c, c = c + 1;
|
||||
else
|
||||
c = 1 + c, c = c + 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
this, c = 1 + c, c += 1;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_3271: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
if (a) {
|
||||
b[i++] = 4,
|
||||
b[i++] = 1;
|
||||
} else {
|
||||
b[i++] = 3,
|
||||
b[i++] = 2,
|
||||
b[i++] = 1;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var i = 0, b = [];
|
||||
a ? b[i++] = 4 : (b[i++] = 3, b[i++] = 2),
|
||||
b[i++] = 1;
|
||||
return b;
|
||||
}
|
||||
console.log(f(0).pop(), f(1).pop());
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
dead_code_1: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
a();
|
||||
@@ -25,8 +25,8 @@ dead_code_1: {
|
||||
|
||||
dead_code_2_should_warn: {
|
||||
options = {
|
||||
dead_code: true
|
||||
};
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
g();
|
||||
@@ -62,55 +62,15 @@ dead_code_2_should_warn: {
|
||||
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: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
};
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
console.log("unreachable");
|
||||
@@ -137,42 +97,6 @@ dead_code_constant_boolean_should_warn_more: {
|
||||
node_version: "<=4"
|
||||
}
|
||||
|
||||
dead_code_constant_boolean_should_warn_more_strict: {
|
||||
options = {
|
||||
dead_code : true,
|
||||
loops : true,
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
evaluate : true,
|
||||
side_effects : true,
|
||||
};
|
||||
input: {
|
||||
"use strict";
|
||||
while (!((foo && bar) || (x + "0"))) {
|
||||
console.log("unreachable");
|
||||
var foo;
|
||||
function bar() {}
|
||||
}
|
||||
for (var x = 10, y; x && (y || x) && (!typeof x); ++x) {
|
||||
asdf();
|
||||
foo();
|
||||
var moo;
|
||||
}
|
||||
bar();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var foo;
|
||||
// nothing for the while
|
||||
// as for the for, it should keep:
|
||||
var moo;
|
||||
var x = 10, y;
|
||||
bar();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
try_catch_finally: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
@@ -881,3 +805,140 @@ issue_2692: {
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2701: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: false,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a = function() {
|
||||
return function() {
|
||||
return a;
|
||||
};
|
||||
}();
|
||||
}
|
||||
console.log(typeof f()());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2749: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2, c = "PASS";
|
||||
while (a--)
|
||||
(function() {
|
||||
return b ? c = "FAIL" : b = 1;
|
||||
try {
|
||||
} catch (b) {
|
||||
var b;
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var a = 2, c = "PASS";
|
||||
while (a--)
|
||||
b = void 0, b ? c = "FAIL" : b = 1;
|
||||
var b;
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_builtin: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
(!w).constructor(x);
|
||||
Math.abs(y);
|
||||
[ 1, 2, z ].valueOf();
|
||||
}
|
||||
expect: {
|
||||
w, x;
|
||||
y;
|
||||
z;
|
||||
}
|
||||
}
|
||||
|
||||
issue_2860_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return a ^= 1;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
return 1 ^ a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2860_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
return a ^= 1;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2929: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return null.p = a = 1;
|
||||
} catch (e) {
|
||||
return a ? "PASS" : "FAIL";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return null.p = a = 1;
|
||||
} catch (e) {
|
||||
return a ? "PASS" : "FAIL";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
keep_debugger: {
|
||||
options = {
|
||||
drop_debugger: false
|
||||
};
|
||||
drop_debugger: false,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
}
|
||||
@@ -12,8 +12,8 @@ keep_debugger: {
|
||||
|
||||
drop_debugger: {
|
||||
options = {
|
||||
drop_debugger: true
|
||||
};
|
||||
drop_debugger: true,
|
||||
}
|
||||
input: {
|
||||
debugger;
|
||||
if (foo) debugger;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
drop_console_1: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
@@ -11,7 +11,9 @@ drop_console_1: {
|
||||
}
|
||||
|
||||
drop_console_2: {
|
||||
options = { drop_console: true };
|
||||
options = {
|
||||
drop_console: true,
|
||||
}
|
||||
input: {
|
||||
console.log('foo');
|
||||
console.log.apply(console, arguments);
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
unused_funarg_1: {
|
||||
options = { unused: true, keep_fargs: false };
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c, d, e) {
|
||||
return a + b;
|
||||
@@ -13,7 +16,10 @@ unused_funarg_1: {
|
||||
}
|
||||
|
||||
unused_funarg_2: {
|
||||
options = { unused: true, keep_fargs: false };
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b, c, d, e) {
|
||||
return a + c;
|
||||
@@ -27,7 +33,9 @@ unused_funarg_2: {
|
||||
}
|
||||
|
||||
unused_nested_function: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
function g() {
|
||||
@@ -44,7 +52,9 @@ unused_nested_function: {
|
||||
}
|
||||
|
||||
unused_circular_references_1: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
// circular reference
|
||||
@@ -65,7 +75,9 @@ unused_circular_references_1: {
|
||||
}
|
||||
|
||||
unused_circular_references_2: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var foo = 1, bar = baz, baz = foo + bar, qwe = moo();
|
||||
@@ -81,7 +93,9 @@ unused_circular_references_2: {
|
||||
}
|
||||
|
||||
unused_circular_references_3: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var g = function() { return h() };
|
||||
@@ -97,7 +111,9 @@ unused_circular_references_3: {
|
||||
}
|
||||
|
||||
unused_keep_setter_arg: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var x = {
|
||||
_foo: null,
|
||||
@@ -121,7 +137,9 @@ unused_keep_setter_arg: {
|
||||
}
|
||||
|
||||
unused_var_in_catch: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
try {
|
||||
@@ -141,7 +159,9 @@ unused_var_in_catch: {
|
||||
}
|
||||
|
||||
used_var_in_catch: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
try {
|
||||
@@ -165,7 +185,11 @@ used_var_in_catch: {
|
||||
}
|
||||
|
||||
keep_fnames: {
|
||||
options = { unused: true, keep_fnames: true, unsafe: true };
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
return function bar(baz) {};
|
||||
@@ -367,7 +391,7 @@ drop_toplevel_vars_fargs: {
|
||||
drop_toplevel_all: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = 1, c = g;
|
||||
@@ -418,7 +442,11 @@ drop_toplevel_retain: {
|
||||
|
||||
drop_toplevel_retain_array: {
|
||||
options = {
|
||||
top_retain: [ "f", "a", "o" ],
|
||||
top_retain: [
|
||||
"f",
|
||||
"a",
|
||||
"o"
|
||||
],
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -476,8 +504,8 @@ drop_toplevel_retain_regex: {
|
||||
|
||||
drop_toplevel_all_retain: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
top_retain: "f,a,o",
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -506,8 +534,8 @@ drop_toplevel_all_retain: {
|
||||
|
||||
drop_toplevel_funcs_retain: {
|
||||
options = {
|
||||
toplevel: "funcs",
|
||||
top_retain: "f,a,o",
|
||||
toplevel: "funcs",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -537,8 +565,8 @@ drop_toplevel_funcs_retain: {
|
||||
|
||||
drop_toplevel_vars_retain: {
|
||||
options = {
|
||||
toplevel: "vars",
|
||||
top_retain: "f,a,o",
|
||||
toplevel: "vars",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1377,9 +1405,9 @@ issue_2516_1: {
|
||||
issue_2516_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
passes: 2,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1522,3 +1550,458 @@ issue_2665: {
|
||||
}
|
||||
expect_stdout: "-1"
|
||||
}
|
||||
|
||||
double_assign_1: {
|
||||
options = {
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
function f2() {
|
||||
var a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f3() {
|
||||
a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
function f4(a) {
|
||||
a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f5(a) {
|
||||
var a = {};
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f6(a) {
|
||||
a = {};
|
||||
var a = [];
|
||||
return a;
|
||||
}
|
||||
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
return [];
|
||||
}
|
||||
function f2() {
|
||||
var a;
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f3() {
|
||||
return [];
|
||||
}
|
||||
function f4(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f5(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
function f6(a) {
|
||||
a = [];
|
||||
return a;
|
||||
}
|
||||
console.log(f1(), f2(), f3(), f4(), f5(), f6());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
double_assign_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = {}, console.log(a);
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
void 0, a = {}, console.log(a);
|
||||
var a;
|
||||
}
|
||||
}
|
||||
|
||||
double_assign_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = { a: a }, console.log(a);
|
||||
var a;
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
a = void 0, a = { a: a }, console.log(a);
|
||||
var a;
|
||||
}
|
||||
}
|
||||
|
||||
cascade_drop_assign: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = a = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
chained_3: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a, b) {
|
||||
var c = a, c = b;
|
||||
b++;
|
||||
return c;
|
||||
}(1, 2));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a, b) {
|
||||
var c = b;
|
||||
b++;
|
||||
return c;
|
||||
}(0, 2));
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
issue_2768: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL", c = 1;
|
||||
var c = function(b) {
|
||||
var d = b = a;
|
||||
var e = --b + (d && (a = "PASS"));
|
||||
}();
|
||||
console.log(a, typeof c);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
var c = (d = a, 0, void (d && (a = "PASS")));
|
||||
var d;
|
||||
console.log(a, typeof c);
|
||||
}
|
||||
expect_stdout: "PASS undefined"
|
||||
}
|
||||
|
||||
issue_2846: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
var a = 0;
|
||||
b && b(a);
|
||||
return a++;
|
||||
}
|
||||
var c = f();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = function(a, b) {
|
||||
a = 0;
|
||||
b && b(a);
|
||||
return a++;
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
var unused = function() {};
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_805_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
function unused() {}
|
||||
unused.prototype[a()] = 42;
|
||||
(unused.prototype.bar = function() {
|
||||
console.log("bar");
|
||||
})();
|
||||
return unused;
|
||||
})(function() {
|
||||
console.log("foo");
|
||||
return "foo";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("foo"),
|
||||
console.log("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2995: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b;
|
||||
a.b = b = function() {};
|
||||
b.c = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b.c);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b;
|
||||
a.b = b = function() {};
|
||||
b.c = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b.c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3146_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f("g()");
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
function g(b) {
|
||||
if (!b) b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(f) {
|
||||
f("g()");
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
function g(b) {
|
||||
if (!b) b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3146_2: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(f) {
|
||||
f("g()");
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
function g(b) {
|
||||
if (!b) b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(f) {
|
||||
f("g()");
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
function g(b) {
|
||||
if (!b) b = "PASS";
|
||||
console.log(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3146_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var g = "PASS";
|
||||
(function(f) {
|
||||
var g = "FAIL";
|
||||
f("console.log(g)", g[g]);
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var g = "PASS";
|
||||
(function(f) {
|
||||
var g = "FAIL";
|
||||
f("console.log(g)", g[g]);
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3146_4: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var g = "PASS";
|
||||
(function(f) {
|
||||
var g = "FAIL";
|
||||
f("console.log(g)", g[g]);
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
var g = "PASS";
|
||||
(function(f) {
|
||||
var g = "FAIL";
|
||||
f("console.log(g)", g[g]);
|
||||
})(function(a) {
|
||||
eval(a);
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3192: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
console.log(a = "foo", arguments[0]);
|
||||
})("bar");
|
||||
(function(a) {
|
||||
"use strict";
|
||||
console.log(a = "foo", arguments[0]);
|
||||
})("bar");
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
console.log(a = "foo", arguments[0]);
|
||||
})("bar");
|
||||
(function(a) {
|
||||
"use strict";
|
||||
console.log("foo", arguments[0]);
|
||||
})("bar");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo foo",
|
||||
"foo bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3233: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function b() {
|
||||
b.c = "PASS";
|
||||
};
|
||||
a();
|
||||
console.log(a.c);
|
||||
}
|
||||
expect: {
|
||||
var a = function b() {
|
||||
b.c = "PASS";
|
||||
};
|
||||
a();
|
||||
console.log(a.c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -186,7 +186,9 @@ unary_prefix: {
|
||||
}
|
||||
|
||||
negative_zero: {
|
||||
options = { evaluate: true }
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
-"",
|
||||
@@ -207,7 +209,9 @@ negative_zero: {
|
||||
}
|
||||
|
||||
positive_zero: {
|
||||
options = { evaluate: true }
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
+"",
|
||||
@@ -229,8 +233,8 @@ positive_zero: {
|
||||
|
||||
unsafe_constant: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -421,8 +425,8 @@ prop_function: {
|
||||
|
||||
unsafe_integer_key: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -449,8 +453,8 @@ unsafe_integer_key: {
|
||||
|
||||
unsafe_integer_key_complex: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -477,8 +481,8 @@ unsafe_integer_key_complex: {
|
||||
|
||||
unsafe_float_key: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -505,8 +509,8 @@ unsafe_float_key: {
|
||||
|
||||
unsafe_float_key_complex: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -533,8 +537,8 @@ unsafe_float_key_complex: {
|
||||
|
||||
unsafe_array: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -569,8 +573,8 @@ unsafe_array: {
|
||||
|
||||
unsafe_string: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -597,8 +601,8 @@ unsafe_string: {
|
||||
|
||||
unsafe_array_bad_index: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -619,8 +623,8 @@ unsafe_array_bad_index: {
|
||||
|
||||
unsafe_string_bad_index: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -745,7 +749,7 @@ in_boolean_context: {
|
||||
!b("foo"),
|
||||
!b([1, 2]),
|
||||
!b(/foo/),
|
||||
![1, foo()],
|
||||
(foo(), !1),
|
||||
(foo(), !1)
|
||||
);
|
||||
}
|
||||
@@ -754,8 +758,8 @@ in_boolean_context: {
|
||||
|
||||
unsafe_charAt: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -782,8 +786,8 @@ unsafe_charAt: {
|
||||
|
||||
unsafe_charAt_bad_index: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -804,8 +808,8 @@ unsafe_charAt_bad_index: {
|
||||
|
||||
unsafe_charAt_noop: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
unsafe : true
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(
|
||||
@@ -1120,14 +1124,14 @@ issue_2207_1: {
|
||||
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));
|
||||
console.log(Math.pow(Math.PI, Math.E - Math.LN10).toFixed(15));
|
||||
}
|
||||
expect: {
|
||||
console.log("A");
|
||||
console.log(7);
|
||||
console.log(Math.cos(1.2345));
|
||||
console.log(1.2543732512566947);
|
||||
console.log(1.6093984514472044);
|
||||
console.log("1.609398451447204");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -1194,6 +1198,9 @@ issue_2231_1: {
|
||||
console.log(Object.keys(void 0));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Error evaluating Object.keys(void 0) [test/compress/evaluate.js:1,20]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2231_2: {
|
||||
@@ -1208,6 +1215,23 @@ issue_2231_2: {
|
||||
console.log(Object.getOwnPropertyNames(null));
|
||||
}
|
||||
expect_stdout: true
|
||||
expect_warnings: [
|
||||
"WARN: Error evaluating Object.getOwnPropertyNames(null) [test/compress/evaluate.js:1,20]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2231_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(Object.keys({ foo: "bar" })[0]);
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
self_comparison_1: {
|
||||
@@ -1221,12 +1245,12 @@ self_comparison_1: {
|
||||
}
|
||||
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);
|
||||
console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n);
|
||||
}
|
||||
expect: {
|
||||
console.log(false, false, true, true, "number");
|
||||
console.log("number", false, false, true, true);
|
||||
}
|
||||
expect_stdout: "false false true true 'number'"
|
||||
expect_stdout: "number false false true true"
|
||||
}
|
||||
|
||||
self_comparison_2: {
|
||||
@@ -1241,12 +1265,12 @@ self_comparison_2: {
|
||||
}
|
||||
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);
|
||||
console.log(typeof o.n, o.n == o.n, o.n === o.n, o.n != o.n, o.n !== o.n);
|
||||
}
|
||||
expect: {
|
||||
console.log(false, false, true, true, "number");
|
||||
console.log("number", false, false, true, true);
|
||||
}
|
||||
expect_stdout: "false false true true 'number'"
|
||||
expect_stdout: "number false false true true"
|
||||
}
|
||||
|
||||
issue_2535_1: {
|
||||
@@ -1330,13 +1354,336 @@ issue_2535_3: {
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:1,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:2,20]",
|
||||
"WARN: Dropping side-effect-free && [test/compress/evaluate.js:3,20]",
|
||||
"WARN: Condition left of && always false [test/compress/evaluate.js:3,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:4,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:5,20]",
|
||||
"WARN: Dropping side-effect-free || [test/compress/evaluate.js:6,20]",
|
||||
"WARN: Condition left of || always true [test/compress/evaluate.js:6,20]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2822: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log([ function() {}, "PASS", "FAIL" ][1]);
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
string_case: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log("İ".toLowerCase().charCodeAt(0));
|
||||
console.log("I".toLowerCase().charCodeAt(0));
|
||||
console.log("Ş".toLowerCase().charCodeAt(0));
|
||||
console.log("Ğ".toLowerCase().charCodeAt(0));
|
||||
console.log("Ü".toLowerCase().charCodeAt(0));
|
||||
console.log("Ö".toLowerCase().charCodeAt(0));
|
||||
console.log("Ç".toLowerCase().charCodeAt(0));
|
||||
console.log("i".toUpperCase().charCodeAt(0));
|
||||
console.log("ı".toUpperCase().charCodeAt(0));
|
||||
console.log("ş".toUpperCase().charCodeAt(0));
|
||||
console.log("ğ".toUpperCase().charCodeAt(0));
|
||||
console.log("ü".toUpperCase().charCodeAt(0));
|
||||
console.log("ö".toUpperCase().charCodeAt(0));
|
||||
console.log("ç".toUpperCase().charCodeAt(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(105);
|
||||
console.log(105);
|
||||
console.log(351);
|
||||
console.log(287);
|
||||
console.log(252);
|
||||
console.log(246);
|
||||
console.log(231);
|
||||
console.log(73);
|
||||
console.log(73);
|
||||
console.log(350);
|
||||
console.log(286);
|
||||
console.log(220);
|
||||
console.log(214);
|
||||
console.log(199);
|
||||
}
|
||||
expect_stdout: [
|
||||
"105",
|
||||
"105",
|
||||
"351",
|
||||
"287",
|
||||
"252",
|
||||
"246",
|
||||
"231",
|
||||
"73",
|
||||
"73",
|
||||
"350",
|
||||
"286",
|
||||
"220",
|
||||
"214",
|
||||
"199",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2916_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
(function(a, b) {
|
||||
(function(d) {
|
||||
d[0] = 1;
|
||||
})(b);
|
||||
a == b && (c = "FAIL");
|
||||
})("", []);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
(function(a, b) {
|
||||
(function(d) {
|
||||
d[0] = 1;
|
||||
})(b);
|
||||
a == b && (c = "FAIL");
|
||||
})("", []);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2916_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function(b) {
|
||||
(function(d) {
|
||||
d[0] = 1;
|
||||
})(b);
|
||||
+b && (c = "PASS");
|
||||
})([]);
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function(b) {
|
||||
b[0] = 1;
|
||||
+b && (c = "PASS");
|
||||
})([]);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2919: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log([ function() {} ].toString());
|
||||
}
|
||||
expect: {
|
||||
console.log("function(){}");
|
||||
}
|
||||
}
|
||||
|
||||
issue_2926_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
(function f(a) {
|
||||
console.log(f.name.length, f.length);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function f(a) {
|
||||
console.log(1, 1);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 1"
|
||||
}
|
||||
|
||||
issue_2926_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {}.valueOf());
|
||||
}
|
||||
expect: {
|
||||
console.log("function");
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2968_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
(function(a, b) {
|
||||
a <<= 0;
|
||||
a && (a[(c = "PASS", 0 >>> (b += 1))] = 0);
|
||||
})(42, -42);
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
b = -(a = 42),
|
||||
void ((a <<= 0) && (a[(c = "PASS", 0 >>> (b += 1))] = 0));
|
||||
var a, b;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2968_2: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
(function(a, b) {
|
||||
a <<= 0;
|
||||
a && (a[(c = "PASS", 0 >>> (b += 1))] = 0);
|
||||
})(42, -42);
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
a = 42,
|
||||
((a <<= 0) && (a[(c = "PASS", 0)] = 0));
|
||||
var a;
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
truthy_conditionals: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
if (a = {}) x();
|
||||
(b = /foo/) && y();
|
||||
(c = function() {}) || z();
|
||||
}
|
||||
expect: {
|
||||
a = {}, x();
|
||||
b = /foo/, y();
|
||||
c = function() {};
|
||||
}
|
||||
}
|
||||
|
||||
truthy_loops: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
while ([]) x();
|
||||
do {
|
||||
y();
|
||||
} while(a = {});
|
||||
}
|
||||
expect: {
|
||||
for (;;) {
|
||||
[];
|
||||
x();
|
||||
}
|
||||
for (;;) {
|
||||
y();
|
||||
a = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_increment: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
if (console)
|
||||
return ++a;
|
||||
}(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
if (console)
|
||||
return 1;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
try_increment: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return ++a;
|
||||
} catch (e) {}
|
||||
}(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
try {
|
||||
return 1;
|
||||
} catch (e) {}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ must_replace: {
|
||||
options = {
|
||||
global_defs: {
|
||||
D: "foo bar",
|
||||
}
|
||||
},
|
||||
}
|
||||
input: {
|
||||
console.log(D);
|
||||
@@ -141,9 +141,8 @@ mixed: {
|
||||
console.log(CONFIG);
|
||||
}
|
||||
expect_warnings: [
|
||||
'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:130,8]',
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:4,22]",
|
||||
"WARN: global_defs CONFIG.VALUE redefined [test/compress/global_defs.js:7,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -197,3 +196,23 @@ issue_2167: {
|
||||
doWork();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3217: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
global_defs: {
|
||||
"@o": "{fn:function(){var a=42;console.log(a)}}",
|
||||
},
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
o.fn();
|
||||
}
|
||||
expect: {
|
||||
console.log(42);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
issue_2377_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -33,8 +33,8 @@ issue_2377_1: {
|
||||
issue_2377_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
@@ -64,8 +64,8 @@ issue_2377_2: {
|
||||
issue_2377_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
passes: 4,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
@@ -239,14 +239,14 @@ name_collision_2: {
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
"-": 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);
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
@@ -273,14 +273,14 @@ name_collision_3: {
|
||||
input: {
|
||||
var o = {
|
||||
p: 1,
|
||||
0: function(x) {
|
||||
"+": function(x) {
|
||||
return x;
|
||||
},
|
||||
1: function(x) {
|
||||
"-": function(x) {
|
||||
return x + 1;
|
||||
}
|
||||
}, o__$0 = 2, o__$1 = 3;
|
||||
console.log(o.p === o.p, o[0](4), o[1](5));
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
@@ -416,7 +416,10 @@ issue_2473_1: {
|
||||
options = {
|
||||
hoist_props: false,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -435,7 +438,10 @@ issue_2473_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
top_retain: [ "x", "y" ],
|
||||
top_retain: [
|
||||
"x",
|
||||
"y"
|
||||
],
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -664,3 +670,195 @@ issue_2519: {
|
||||
}
|
||||
expect_stdout: "5.5"
|
||||
}
|
||||
|
||||
undefined_key: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 4,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, o = {};
|
||||
o[a] = 1;
|
||||
o.b = 2;
|
||||
console.log(o[a] + o.b);
|
||||
}
|
||||
expect: {
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
}
|
||||
|
||||
issue_3021: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 1, b = 2;
|
||||
(function() {
|
||||
b = a;
|
||||
if (a++ + b--)
|
||||
return 1;
|
||||
return;
|
||||
var b = {};
|
||||
})();
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
issue_3046: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b = {
|
||||
c: a++
|
||||
};
|
||||
} while (b.c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b_c = a++;
|
||||
} while (b_c && a);
|
||||
return a;
|
||||
}(0));
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_2_toplevel: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
obj = {};
|
||||
obj.one = 1;
|
||||
obj.two = 2;
|
||||
console.log(obj.one);
|
||||
var obj;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_3071_3: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
(function(a, b) {
|
||||
(function f(o) {
|
||||
var n = 2;
|
||||
while (--b + (o = {
|
||||
p: c++,
|
||||
}) && --n > 0);
|
||||
})();
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "2"
|
||||
}
|
||||
|
||||
971
test/compress/ie8.js
Normal file
971
test/compress/ie8.js
Normal file
@@ -0,0 +1,971 @@
|
||||
do_screw: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\v");'
|
||||
}
|
||||
|
||||
dont_screw: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\x0B");'
|
||||
}
|
||||
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(void 0,1/0);"
|
||||
}
|
||||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(undefined,Infinity);"
|
||||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
good = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
good = function(n){
|
||||
return function(t){
|
||||
try{
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
bad = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
bad = function(t){
|
||||
return function(n){
|
||||
try{
|
||||
t()
|
||||
} catch(t) {
|
||||
n(t)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
do_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(o){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (o) {
|
||||
console.log("caught: "+o)
|
||||
}
|
||||
console.log("undefined is " + void 0);
|
||||
return void 0===o
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(n){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (undefined) {
|
||||
console.log("caught: " + undefined)
|
||||
}
|
||||
console.log("undefined is " + undefined);
|
||||
return n === undefined
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
ie8: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
try {
|
||||
x();
|
||||
} catch (a) {
|
||||
y();
|
||||
}
|
||||
alert(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var t;
|
||||
try {
|
||||
x();
|
||||
} catch (t) {
|
||||
y();
|
||||
}
|
||||
alert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.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(t) {
|
||||
try {
|
||||
throw "FAIL";
|
||||
} catch (e) {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
}
|
||||
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"
|
||||
}
|
||||
|
||||
issue_24_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
console.log(typeof function f(){} === typeof a ? "FAIL" : "PASS");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(o) {
|
||||
console.log(typeof function o(){} === typeof o ? "FAIL" : "PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_24_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
console.log(typeof function f(){} === typeof a ? "FAIL" : "PASS");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(o) {
|
||||
console.log(typeof function n(){} === typeof o ? "FAIL" : "PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2976_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
var a;
|
||||
return a === f ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function n() {
|
||||
var o;
|
||||
return o === n ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2976_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
var a;
|
||||
return a === f ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {
|
||||
var n;
|
||||
return n === f ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2976_3: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
var a;
|
||||
return a === f ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function o() {
|
||||
var n;
|
||||
return n === o ? "FAIL" : "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3035: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
try {
|
||||
throw 1;
|
||||
} catch (b) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
b && (c = "PASS");
|
||||
}
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function(o) {
|
||||
try {
|
||||
throw 1;
|
||||
} catch (t) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
t && (c = "PASS");
|
||||
}
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3035_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function(a) {
|
||||
try {
|
||||
throw 1;
|
||||
} catch (b) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (a) {
|
||||
b && (c = "PASS");
|
||||
}
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function(t) {
|
||||
try {
|
||||
throw 1;
|
||||
} catch (o) {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (t) {
|
||||
o && (c = "PASS");
|
||||
}
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3197_1: {
|
||||
options = {
|
||||
ie8: false,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
var window = {};
|
||||
!function() {
|
||||
function Foo() {
|
||||
console.log(this instanceof Foo);
|
||||
}
|
||||
window.Foo = Foo;
|
||||
}();
|
||||
new window.Foo();
|
||||
}
|
||||
expect: {
|
||||
var window = {};
|
||||
window.Foo = function o() {
|
||||
console.log(this instanceof o);
|
||||
};
|
||||
new window.Foo();
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3197_1_ie8: {
|
||||
options = {
|
||||
ie8: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
var window = {};
|
||||
!function() {
|
||||
function Foo() {
|
||||
console.log(this instanceof Foo);
|
||||
}
|
||||
window.Foo = Foo;
|
||||
}();
|
||||
new window.Foo();
|
||||
}
|
||||
expect: {
|
||||
var window = {};
|
||||
window.Foo = function Foo() {
|
||||
console.log(this instanceof Foo);
|
||||
};
|
||||
new window.Foo();
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3197_2: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
var f = function f() {
|
||||
console.log(this instanceof f);
|
||||
};
|
||||
new f(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(n) {
|
||||
var o = function n() {
|
||||
console.log(this instanceof n);
|
||||
};
|
||||
new o(n);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3197_2_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
var f = function f() {
|
||||
console.log(this instanceof f);
|
||||
};
|
||||
new f(a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(n) {
|
||||
var o = function o() {
|
||||
console.log(this instanceof o);
|
||||
};
|
||||
new o(n);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3206_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
ie8: false,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var foo = function bar() {};
|
||||
var baz = function moo() {};
|
||||
return "function" == typeof bar;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
return "function" == typeof bar;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3206_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
ie8: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var foo = function bar() {};
|
||||
var baz = function moo() {};
|
||||
return "function" == typeof bar;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
(function bar() {});
|
||||
return "function" == typeof bar;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3215_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function foo() {
|
||||
var bar = function bar(name) {
|
||||
return "PASS";
|
||||
};
|
||||
try {
|
||||
"moo";
|
||||
} catch (e) {
|
||||
bar = function bar(name) {
|
||||
return "FAIL";
|
||||
};
|
||||
}
|
||||
return bar;
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
console.log(function n() {
|
||||
var o = function n(o) {
|
||||
return "PASS";
|
||||
};
|
||||
try {
|
||||
"moo";
|
||||
} catch (n) {
|
||||
o = function n(o) {
|
||||
return "FAIL";
|
||||
};
|
||||
}
|
||||
return o;
|
||||
}()());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3215_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function foo() {
|
||||
var bar = function bar(name) {
|
||||
return "PASS";
|
||||
};
|
||||
try {
|
||||
"moo";
|
||||
} catch (e) {
|
||||
bar = function bar(name) {
|
||||
return "FAIL";
|
||||
};
|
||||
}
|
||||
return bar;
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
console.log(function foo() {
|
||||
var o = function o(n) {
|
||||
return "PASS";
|
||||
};
|
||||
try {
|
||||
"moo";
|
||||
} catch (n) {
|
||||
o = function o(n) {
|
||||
return "FAIL";
|
||||
};
|
||||
}
|
||||
return o;
|
||||
}()());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3215_3: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function foo() {
|
||||
var bar = function bar(name) {
|
||||
return "FAIL";
|
||||
};
|
||||
try {
|
||||
moo;
|
||||
} catch (e) {
|
||||
bar = function bar(name) {
|
||||
return "PASS";
|
||||
};
|
||||
}
|
||||
return bar;
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
console.log(function n() {
|
||||
var o = function n(o) {
|
||||
return "FAIL";
|
||||
};
|
||||
try {
|
||||
moo;
|
||||
} catch (n) {
|
||||
o = function n(o) {
|
||||
return "PASS";
|
||||
};
|
||||
}
|
||||
return o;
|
||||
}()());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3215_4: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function foo() {
|
||||
var bar = function bar(name) {
|
||||
return "FAIL";
|
||||
};
|
||||
try {
|
||||
moo;
|
||||
} catch (e) {
|
||||
bar = function bar(name) {
|
||||
return "PASS";
|
||||
};
|
||||
}
|
||||
return bar;
|
||||
}()());
|
||||
}
|
||||
expect: {
|
||||
console.log(function foo() {
|
||||
var o = function o(n) {
|
||||
return "FAIL";
|
||||
};
|
||||
try {
|
||||
moo;
|
||||
} catch (n) {
|
||||
o = function o(n) {
|
||||
return "PASS";
|
||||
};
|
||||
}
|
||||
return o;
|
||||
}()());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3355_1: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
(function f() {
|
||||
var f;
|
||||
})();
|
||||
(function g() {
|
||||
})();
|
||||
console.log(typeof f === typeof g);
|
||||
}
|
||||
expect: {
|
||||
(function o() {
|
||||
var o;
|
||||
})();
|
||||
(function o() {
|
||||
})();
|
||||
console.log(typeof f === typeof g);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3355_2: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
(function f() {
|
||||
var f;
|
||||
})();
|
||||
(function g() {
|
||||
})();
|
||||
console.log(typeof f === typeof g);
|
||||
}
|
||||
expect: {
|
||||
(function f() {
|
||||
var f;
|
||||
})();
|
||||
(function g() {
|
||||
})();
|
||||
console.log(typeof f === typeof g);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_3355_3: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
!function(a) {
|
||||
"aaaaaaaaaa";
|
||||
a();
|
||||
var b = function c() {
|
||||
var c = 42;
|
||||
console.log("FAIL");
|
||||
};
|
||||
}(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
!function(a) {
|
||||
"aaaaaaaaaa";
|
||||
a();
|
||||
var o = function a() {
|
||||
var a = 42;
|
||||
console.log("FAIL");
|
||||
};
|
||||
}(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3355_4: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
!function(a) {
|
||||
"aaaaaaaaaa";
|
||||
a();
|
||||
var b = function c() {
|
||||
var c = 42;
|
||||
console.log("FAIL");
|
||||
};
|
||||
}(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
!function(a) {
|
||||
"aaaaaaaaaa";
|
||||
a();
|
||||
var o = function n() {
|
||||
var n = 42;
|
||||
console.log("FAIL");
|
||||
};
|
||||
}(function() {
|
||||
console.log("PASS");
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
if_return_1: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -24,15 +24,15 @@ if_return_1: {
|
||||
|
||||
if_return_2: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -49,15 +49,15 @@ if_return_2: {
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -75,15 +75,15 @@ if_return_3: {
|
||||
|
||||
if_return_4: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
@@ -100,15 +100,15 @@ if_return_4: {
|
||||
|
||||
if_return_5: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -126,15 +126,15 @@ if_return_5: {
|
||||
|
||||
if_return_6: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -150,15 +150,15 @@ if_return_6: {
|
||||
|
||||
if_return_7: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x) {
|
||||
@@ -176,10 +176,10 @@ if_return_7: {
|
||||
|
||||
if_return_8: {
|
||||
options = {
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
side_effects : true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(e) {
|
||||
@@ -220,15 +220,15 @@ if_return_8: {
|
||||
|
||||
issue_1089: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -243,7 +243,7 @@ issue_1089: {
|
||||
expect: {
|
||||
function x() {
|
||||
var f = document.getElementById("fname");
|
||||
if (f.files[0].size > 12345)
|
||||
if (12345 < f.files[0].size)
|
||||
return alert("alert"), f.focus(), !1;
|
||||
}
|
||||
}
|
||||
@@ -251,9 +251,9 @@ issue_1089: {
|
||||
|
||||
issue_1437: {
|
||||
options = {
|
||||
if_return : true,
|
||||
sequences : true,
|
||||
conditionals : false
|
||||
conditionals: false,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -281,9 +281,9 @@ issue_1437: {
|
||||
|
||||
issue_1437_conditionals: {
|
||||
options = {
|
||||
conditionals : true,
|
||||
if_return : true,
|
||||
sequences : true
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function x() {
|
||||
@@ -326,3 +326,221 @@ issue_512: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_var_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
return;
|
||||
var b;
|
||||
}
|
||||
function g() {
|
||||
var a;
|
||||
if (u()) {
|
||||
var b;
|
||||
return v();
|
||||
var c;
|
||||
}
|
||||
var d;
|
||||
if (w()) {
|
||||
var e;
|
||||
return x();
|
||||
var f;
|
||||
} else {
|
||||
var g;
|
||||
y();
|
||||
var h;
|
||||
}
|
||||
var i;
|
||||
z();
|
||||
var j;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var a, b;
|
||||
}
|
||||
function g() {
|
||||
var a, b, c, d, e, f, g, h, i, j;
|
||||
return u() ? v() : w() ? x() : (y(), z(), void 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_if_return_return: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b)
|
||||
return b;
|
||||
return;
|
||||
}
|
||||
g();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
if (a)
|
||||
return b || void 0;
|
||||
g();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if_body_return_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (0 + a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
if_body_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 == a) {
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var c = "PASS";
|
||||
function f(a, b) {
|
||||
if (1 != a) return true;
|
||||
if (b) throw new Error(c);
|
||||
return 42;
|
||||
}
|
||||
console.log(f(0, 0));
|
||||
console.log(f(0, 1));
|
||||
console.log(f(1, 0));
|
||||
try {
|
||||
f(1, 1);
|
||||
console.log("FAIL");
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"true",
|
||||
"true",
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
non_hoisted_function_after_return: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -27,19 +36,30 @@ non_hoisted_function_after_return: {
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Dropping unreachable code [test/compress/issue-1034.js:11,16]',
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:14,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:17,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:18,21]"
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:11,21]"
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
warnings: "verbose",
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -65,28 +85,37 @@ non_hoisted_function_after_return_2a: {
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:48,16]",
|
||||
"WARN: Dropping 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 function nope [test/compress/issue-1034.js:55,21]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:4,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:4,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:11,21]",
|
||||
"WARN: pass 0: last_count: Infinity, count: 37",
|
||||
"WARN: Dropping 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 unused variable b [test/compress/issue-1034.js:51,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:53,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:7,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:9,16]",
|
||||
"WARN: pass 1: last_count: 37, count: 18",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(x) {
|
||||
@@ -110,20 +139,28 @@ non_hoisted_function_after_return_2b: {
|
||||
}
|
||||
}
|
||||
expect_warnings: [
|
||||
// duplicate warnings no longer emitted
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:97,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:97,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:99,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:99,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:103,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:6,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:12,12]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -153,19 +190,30 @@ non_hoisted_function_after_return_strict: {
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:11,12]",
|
||||
"WARN: Dropping unused function UnusedFunction [test/compress/issue-1034.js:12,21]",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2a_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false, passes: 2, warnings: "verbose"
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
warnings: "verbose",
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -196,28 +244,37 @@ non_hoisted_function_after_return_2a_strict: {
|
||||
}
|
||||
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: Dropping unreachable code [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:5,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:8,16]",
|
||||
"WARN: Dropping unused variable a [test/compress/issue-1034.js:5,20]",
|
||||
"WARN: Dropping unused function nope [test/compress/issue-1034.js:12,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: Dropping unreachable code [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:10,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
"WARN: Dropping unused variable b [test/compress/issue-1034.js:8,20]",
|
||||
"WARN: Dropping unused variable c [test/compress/issue-1034.js:10,16]",
|
||||
"WARN: pass 1: last_count: 48, count: 29",
|
||||
]
|
||||
}
|
||||
|
||||
non_hoisted_function_after_return_2b_strict: {
|
||||
options = {
|
||||
hoist_funs: false, dead_code: true, conditionals: true, comparisons: true,
|
||||
evaluate: true, booleans: true, loops: true, unused: true, keep_fargs: true,
|
||||
if_return: true, join_vars: true, side_effects: true,
|
||||
collapse_vars: false
|
||||
booleans: true,
|
||||
collapse_vars: false,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: false,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -246,11 +303,10 @@ non_hoisted_function_after_return_2b_strict: {
|
||||
}
|
||||
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]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:7,16]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Declarations in unreachable code! [test/compress/issue-1034.js:9,12]",
|
||||
"WARN: Dropping unreachable code [test/compress/issue-1034.js:13,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ const_pragma: {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: {
|
||||
/** @const */ var goog = goog || {};
|
||||
@@ -19,7 +19,7 @@ not_const: {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: {
|
||||
var goog = goog || {};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
with_in_global_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = 42;
|
||||
@@ -18,7 +18,7 @@ with_in_global_scope: {
|
||||
}
|
||||
with_in_function_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -40,7 +40,7 @@ with_in_function_scope: {
|
||||
}
|
||||
compress_with_with_in_other_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo() {
|
||||
@@ -69,7 +69,7 @@ compress_with_with_in_other_scope: {
|
||||
}
|
||||
with_using_existing_variable_outside_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -99,7 +99,7 @@ with_using_existing_variable_outside_scope: {
|
||||
}
|
||||
check_drop_unused_in_peer_function: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function outer() {
|
||||
@@ -148,7 +148,7 @@ check_drop_unused_in_peer_function: {
|
||||
|
||||
Infinity_not_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -164,7 +164,7 @@ Infinity_not_in_with_scope: {
|
||||
|
||||
Infinity_in_with_scope: {
|
||||
options = {
|
||||
unused: true
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = { Infinity: 'oInfinity' };
|
||||
@@ -180,19 +180,19 @@ Infinity_in_with_scope: {
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
options = {
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: false,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
@@ -242,19 +242,19 @@ assorted_Infinity_NaN_undefined_in_with_scope: {
|
||||
|
||||
assorted_Infinity_NaN_undefined_in_with_scope_keep_infinity: {
|
||||
options = {
|
||||
unused: true,
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
conditionals: true,
|
||||
comparisons: true,
|
||||
booleans: true,
|
||||
hoist_funs: true,
|
||||
keep_fargs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
sequences: false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_infinity: true,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = console.log;
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
keep_name_of_getter: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: { a = { get foo () {} } }
|
||||
expect: { a = { get foo () {} } }
|
||||
}
|
||||
|
||||
keep_name_of_setter: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: { a = { set foo () {} } }
|
||||
expect: { a = { set foo () {} } }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mangle_keep_fnames_false: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : false,
|
||||
@@ -26,8 +26,8 @@ mangle_keep_fnames_false: {
|
||||
|
||||
mangle_keep_fnames_true: {
|
||||
options = {
|
||||
keep_fnames : true,
|
||||
keep_fargs : true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames : true,
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
pure_function_calls: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
negate_iife : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -48,28 +48,28 @@ pure_function_calls: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:16,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:29,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:29,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:27,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:37,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:38,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:25,31]",
|
||||
]
|
||||
}
|
||||
|
||||
pure_function_calls_toplevel: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
side_effects : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
negate_iife : true,
|
||||
toplevel : true,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
// pure top-level IIFE will be dropped
|
||||
@@ -110,17 +110,17 @@ pure_function_calls_toplevel: {
|
||||
a.b(), f.g();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:77,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:77,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:90,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:90,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:88,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:105,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:106,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:82,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:82,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:98,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:98,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:16,37]",
|
||||
"WARN: Dropping unused variable iife2 [test/compress/issue-1261.js:16,16]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:14,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:31,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:32,31]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,33]",
|
||||
"WARN: Dropping unused variable iife1 [test/compress/issue-1261.js:8,12]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:24,45]",
|
||||
"WARN: Dropping unused variable MyClass [test/compress/issue-1261.js:24,12]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -155,29 +155,29 @@ should_warn: {
|
||||
baz();
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:135,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:135,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:136,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:137,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:137,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:138,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:139,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:140,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:141,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:141,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:142,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:143,24]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:143,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:144,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:144,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,61]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Dropping side-effect-free statement [test/compress/issue-1261.js:1,23]",
|
||||
"WARN: Boolean || always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:2,23]",
|
||||
"WARN: Condition left of || always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:3,8]",
|
||||
"WARN: Boolean && always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:4,23]",
|
||||
"WARN: Condition left of && always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:5,8]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:6,23]",
|
||||
"WARN: + in boolean context always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:7,31]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:7,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:8,23]",
|
||||
"WARN: Condition always true [test/compress/issue-1261.js:9,8]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:9,24]",
|
||||
"WARN: Dropping __PURE__ call [test/compress/issue-1261.js:10,31]",
|
||||
"WARN: Condition always false [test/compress/issue-1261.js:10,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
string_plus_optimization: {
|
||||
options = {
|
||||
side_effects : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
dead_code : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
hoist_funs : true,
|
||||
};
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(anything) {
|
||||
function throwing_function() {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
tranformation_sort_order_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) == a }
|
||||
expect: { (a = parseInt('100')) == a }
|
||||
@@ -24,7 +24,7 @@ tranformation_sort_order_equal: {
|
||||
tranformation_sort_order_unequal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) != a }
|
||||
expect: { (a = parseInt('100')) != a }
|
||||
@@ -33,7 +33,7 @@ tranformation_sort_order_unequal: {
|
||||
tranformation_sort_order_lesser_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) <= a }
|
||||
expect: { (a = parseInt('100')) <= a }
|
||||
@@ -41,7 +41,7 @@ tranformation_sort_order_lesser_or_equal: {
|
||||
tranformation_sort_order_greater_or_equal: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
};
|
||||
}
|
||||
|
||||
input: { (a = parseInt('100')) >= a }
|
||||
expect: { (a = parseInt('100')) >= a }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
level_zero: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -29,7 +29,7 @@ level_zero: {
|
||||
|
||||
level_one: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -58,7 +58,7 @@ level_one: {
|
||||
|
||||
level_two: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
@@ -97,7 +97,7 @@ level_two: {
|
||||
|
||||
level_three: {
|
||||
options = {
|
||||
keep_fnames: true
|
||||
keep_fnames: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -4,7 +4,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
@@ -30,7 +30,7 @@ keep_fnames: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {
|
||||
keep_fnames: true
|
||||
|
||||
@@ -22,17 +22,17 @@ else_with_empty_statement: {
|
||||
|
||||
conditional_false_stray_else_in_loop: {
|
||||
options = {
|
||||
evaluate : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
loops : true,
|
||||
side_effects : true,
|
||||
dead_code : true,
|
||||
hoist_vars : true,
|
||||
join_vars : true,
|
||||
if_return : true,
|
||||
conditionals : false,
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: false,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 1; i <= 4; ++i) {
|
||||
|
||||
@@ -61,7 +61,7 @@ unsafe_undefined: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unsafe: true,
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
|
||||
@@ -104,7 +104,7 @@ mangle_catch_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ mangle_catch_var_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -345,3 +345,95 @@ mangle_catch_redef_2_ie8_toplevel: {
|
||||
expect_exact: 'try{throw"FAIL1"}catch(o){var o="FAIL2"}console.log(o);'
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_toplevel: {
|
||||
mangle = {
|
||||
ie8: false,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_ie8_3: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: false,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var o="PASS";try{throw 0}catch(o){(function(){function c(){o="FAIL"}c(),c()})()}console.log(o);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8_toplevel: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = "PASS";
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
}
|
||||
f(), f();
|
||||
})();
|
||||
}
|
||||
console.log(o);
|
||||
}
|
||||
expect_exact: 'var c="PASS";try{throw 0}catch(c){(function(){function o(){c="FAIL"}o(),o()})()}console.log(c);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ function_iife_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ function_iife_catch_ie8: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ function_catch_catch: {
|
||||
}
|
||||
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_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
|
||||
@@ -84,12 +84,12 @@ numeric_literal: {
|
||||
' 0: 0,',
|
||||
' "-0": 1,',
|
||||
' 42: 2,',
|
||||
' "42": 3,',
|
||||
' 42: 3,',
|
||||
' 37: 4,',
|
||||
' o: 5,',
|
||||
' 1e42: 6,',
|
||||
' b: 7,',
|
||||
' "1e+42": 8',
|
||||
' 1e42: 8',
|
||||
'};',
|
||||
'',
|
||||
'console.log(obj[-0], obj[-""], obj["-0"]);',
|
||||
|
||||
@@ -125,8 +125,8 @@ label_do: {
|
||||
|
||||
label_while: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
do_not_update_lhs: {
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
DEBUG++;
|
||||
@@ -16,7 +18,9 @@ do_not_update_lhs: {
|
||||
|
||||
do_update_rhs: {
|
||||
options = {
|
||||
global_defs: { DEBUG: 0 }
|
||||
global_defs: {
|
||||
DEBUG: 0,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
MY_DEBUG = DEBUG;
|
||||
@@ -35,7 +39,7 @@ mixed: {
|
||||
DEBUG: 0,
|
||||
ENV: 1,
|
||||
FOO: 2,
|
||||
}
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var ENV = 3;
|
||||
@@ -60,11 +64,11 @@ mixed: {
|
||||
x = 0;
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: global_defs ENV redefined [test/compress/issue-208.js:41,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:42,12]',
|
||||
'WARN: global_defs FOO redefined [test/compress/issue-208.js:44,10]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:45,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:46,8]',
|
||||
'WARN: global_defs DEBUG redefined [test/compress/issue-208.js:47,8]',
|
||||
"WARN: global_defs ENV redefined [test/compress/issue-208.js:1,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:2,12]",
|
||||
"WARN: global_defs FOO redefined [test/compress/issue-208.js:4,10]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:5,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:6,8]",
|
||||
"WARN: global_defs DEBUG redefined [test/compress/issue-208.js:7,8]",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
return_with_no_value_in_if_body: {
|
||||
options = { conditionals: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function foo(bar) {
|
||||
if (bar) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_267: {
|
||||
options = { comparisons: true };
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
x = a % b / b * c * 2;
|
||||
x = a % b * 2
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_269_1: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x),
|
||||
@@ -20,7 +22,9 @@ issue_269_1: {
|
||||
}
|
||||
|
||||
issue_269_dangers: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x, x),
|
||||
@@ -34,7 +38,9 @@ issue_269_dangers: {
|
||||
}
|
||||
|
||||
issue_269_in_scope: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var String, Number, Boolean;
|
||||
f(
|
||||
@@ -50,7 +56,9 @@ issue_269_in_scope: {
|
||||
}
|
||||
|
||||
strings_concat: {
|
||||
options = {unsafe: true};
|
||||
options = {
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
f(
|
||||
String(x + 'str'),
|
||||
@@ -64,3 +72,27 @@ strings_concat: {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
regexp: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
RegExp("foo");
|
||||
RegExp("bar", "ig");
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect: {
|
||||
/foo/;
|
||||
/bar/ig;
|
||||
RegExp(foo);
|
||||
RegExp("bar", ig);
|
||||
RegExp("should", "fail");
|
||||
}
|
||||
expect_warnings: [
|
||||
'WARN: Error converting RegExp("should","fail") [test/compress/issue-269.js:5,2]',
|
||||
]
|
||||
}
|
||||
|
||||
32
test/compress/issue-2719.js
Normal file
32
test/compress/issue-2719.js
Normal file
@@ -0,0 +1,32 @@
|
||||
warn: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
properties: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
return g();
|
||||
}
|
||||
function g() {
|
||||
return g["call" + "er"].arguments;
|
||||
}
|
||||
// 3
|
||||
console.log(f(1, 2, 3).length);
|
||||
}
|
||||
expect: {
|
||||
// TypeError: Cannot read property 'arguments' of null
|
||||
console.log(function g() {
|
||||
return g.caller.arguments;
|
||||
}().length);
|
||||
}
|
||||
expect_warnings: [
|
||||
"WARN: Function.prototype.caller not supported [test/compress/issue-2719.js:5,19]",
|
||||
"WARN: Function.prototype.arguments not supported [test/compress/issue-2719.js:5,19]",
|
||||
]
|
||||
}
|
||||
@@ -186,7 +186,7 @@ negate_iife_5_off: {
|
||||
inline: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -245,7 +245,7 @@ negate_iife_issue_1073: {
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
@@ -273,7 +273,7 @@ issue_1288_side_effects: {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
@@ -399,7 +399,7 @@ wrap_iife_in_expression: {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
foo = (function() {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
|
||||
37
test/compress/issue-2871.js
Normal file
37
test/compress/issue-2871.js
Normal file
@@ -0,0 +1,37 @@
|
||||
comparison_with_undefined: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
a == undefined;
|
||||
a != undefined;
|
||||
a === undefined;
|
||||
a !== undefined;
|
||||
|
||||
undefined == a;
|
||||
undefined != a;
|
||||
undefined === a;
|
||||
undefined !== a;
|
||||
|
||||
void 0 == a;
|
||||
void 0 != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
expect: {
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
|
||||
null == a;
|
||||
null != a;
|
||||
void 0 === a;
|
||||
void 0 !== a;
|
||||
}
|
||||
}
|
||||
21
test/compress/issue-2989.js
Normal file
21
test/compress/issue-2989.js
Normal file
@@ -0,0 +1,21 @@
|
||||
inline_script_off: {
|
||||
beautify = {
|
||||
inline_script: false,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("</sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
|
||||
inline_script_on: {
|
||||
beautify = {
|
||||
inline_script: true,
|
||||
}
|
||||
input: {
|
||||
console.log("</sCrIpT>");
|
||||
}
|
||||
expect_exact: 'console.log("<\\/sCrIpT>");'
|
||||
expect_stdout: "</sCrIpT>"
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
issue_44_valid_ast_1: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a(b) {
|
||||
for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
@@ -14,7 +16,9 @@ issue_44_valid_ast_1: {
|
||||
}
|
||||
|
||||
issue_44_valid_ast_2: {
|
||||
options = { unused: true };
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function a(b) {
|
||||
if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
keep_continue: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true
|
||||
};
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
while (a) {
|
||||
if (b) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
NaN_and_Infinity_must_have_parens: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
Infinity.toString();
|
||||
NaN.toString();
|
||||
@@ -11,7 +11,7 @@ NaN_and_Infinity_must_have_parens: {
|
||||
}
|
||||
|
||||
NaN_and_Infinity_should_not_be_replaced_when_they_are_redefined: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
var Infinity, NaN;
|
||||
Infinity.toString();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
issue_611: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true
|
||||
};
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
define(function() {
|
||||
function fn() {}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
evaluate: true
|
||||
};
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
function func() {
|
||||
foo();
|
||||
|
||||
@@ -28,12 +28,12 @@ cond_5: {
|
||||
|
||||
dead_code_const_annotation_regex: {
|
||||
options = {
|
||||
booleans : true,
|
||||
conditionals : true,
|
||||
dead_code : true,
|
||||
evaluate : true,
|
||||
expression : true,
|
||||
loops : true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var unused;
|
||||
@@ -82,8 +82,8 @@ drop_value: {
|
||||
|
||||
wrongly_optimized: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
expression: true,
|
||||
}
|
||||
@@ -195,7 +195,7 @@ negate_iife_5_off: {
|
||||
expression: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -248,7 +248,9 @@ issue_1254_negate_iife_nested: {
|
||||
conditional: {
|
||||
options = {
|
||||
expression: true,
|
||||
pure_funcs: [ "pure" ],
|
||||
pure_funcs: [
|
||||
"pure"
|
||||
],
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
negate_booleans_1: {
|
||||
options = {
|
||||
comparisons: true
|
||||
};
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var a = !a || !b || !c || !d || !e || !f;
|
||||
}
|
||||
@@ -12,8 +12,8 @@ negate_booleans_1: {
|
||||
|
||||
negate_booleans_2: {
|
||||
options = {
|
||||
comparisons: true
|
||||
};
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var match = !x && // should not touch this one
|
||||
(!z || c) &&
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
remove_redundant_sequence_items: {
|
||||
options = { side_effects: true };
|
||||
remove_sequence: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(0, 1, eval)();
|
||||
(0, 1, logThis)();
|
||||
(0, 1, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
eval();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
}
|
||||
}
|
||||
|
||||
remove_redundant_sequence_items: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(0, 1, eval)();
|
||||
(0, 1, logThis)();
|
||||
(0, 1, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
@@ -13,13 +33,17 @@ remove_redundant_sequence_items: {
|
||||
}
|
||||
|
||||
dont_remove_this_binding_sequence: {
|
||||
options = { side_effects: true };
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
(0, logThis)();
|
||||
(0, _decorators.logThis)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(0, eval)();
|
||||
logThis();
|
||||
(0, _decorators.logThis)();
|
||||
|
||||
@@ -2,25 +2,25 @@ dont_mangle_arguments: {
|
||||
mangle = {
|
||||
};
|
||||
options = {
|
||||
sequences : true,
|
||||
properties : true,
|
||||
dead_code : true,
|
||||
drop_debugger : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
evaluate : true,
|
||||
booleans : true,
|
||||
loops : true,
|
||||
unused : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
if_return : true,
|
||||
join_vars : true,
|
||||
side_effects : true,
|
||||
negate_iife : false
|
||||
};
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: false,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(){
|
||||
var arguments = arguments, not_arguments = 9;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
keep_var_for_in: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
unused: true
|
||||
};
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(obj){
|
||||
var foo = 5;
|
||||
|
||||
@@ -3,8 +3,9 @@ this_binding_conditionals: {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(1 && a)();
|
||||
(0 || a)();
|
||||
(0 || 1 && a)();
|
||||
@@ -26,6 +27,7 @@ this_binding_conditionals: {
|
||||
(1 ? eval : 0)();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a();
|
||||
a();
|
||||
a();
|
||||
@@ -53,13 +55,15 @@ this_binding_collapse_vars: {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var c = a; c();
|
||||
var d = a.b; d();
|
||||
var e = eval; e();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a();
|
||||
(0, a.b)();
|
||||
(0, eval)();
|
||||
@@ -68,32 +72,89 @@ this_binding_collapse_vars: {
|
||||
|
||||
this_binding_side_effects: {
|
||||
options = {
|
||||
side_effects : true
|
||||
};
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
"use strict";
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function(foo) {
|
||||
var eval = console;
|
||||
(0, foo)();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
eval("console.log(foo);");
|
||||
}());
|
||||
(function (foo) {
|
||||
(function(foo) {
|
||||
"use strict";
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)("console.log(foo);");
|
||||
}());
|
||||
(function(foo) {
|
||||
var eval = console;
|
||||
foo();
|
||||
(0, foo.bar)();
|
||||
(0, eval)('console.log(foo);');
|
||||
eval("console.log(foo);");
|
||||
}());
|
||||
}
|
||||
}
|
||||
|
||||
this_binding_sequences: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return eval("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
return eval("this");
|
||||
}()),
|
||||
console.log(typeof function() {
|
||||
"use strict";
|
||||
return (0, eval)("this");
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
"undefined",
|
||||
"object",
|
||||
"object",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
eval_collapse_vars: {
|
||||
options = {
|
||||
collapse_vars:true, sequences:false, properties:true, dead_code:true, conditionals:true,
|
||||
comparisons:true, evaluate:true, booleans:true, loops:true, unused:true, hoist_funs:true,
|
||||
keep_fargs:true, if_return:true, join_vars:true, side_effects:true
|
||||
};
|
||||
booleans: true,
|
||||
collapse_vars: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
var e = 7;
|
||||
@@ -46,7 +58,10 @@ eval_collapse_vars: {
|
||||
}
|
||||
|
||||
eval_unused: {
|
||||
options = { unused: true, keep_fargs: false };
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1(a, eval, c, d, e) {
|
||||
return a('c') + eval;
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
issue979_reported: {
|
||||
options = {
|
||||
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, side_effects:true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
@@ -30,9 +41,20 @@ issue979_reported: {
|
||||
|
||||
issue979_test_negated_is_best: {
|
||||
options = {
|
||||
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, side_effects:true
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
properties: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f3() {
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
labels_1: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: {
|
||||
if (foo) break out;
|
||||
@@ -13,7 +17,11 @@ labels_1: {
|
||||
}
|
||||
|
||||
labels_2: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: {
|
||||
if (foo) print("stuff");
|
||||
@@ -30,7 +38,11 @@ labels_2: {
|
||||
}
|
||||
|
||||
labels_3: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 5; ++i) {
|
||||
if (i < 3) continue;
|
||||
@@ -45,7 +57,11 @@ labels_3: {
|
||||
}
|
||||
|
||||
labels_4: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: for (var i = 0; i < 5; ++i) {
|
||||
if (i < 3) continue out;
|
||||
@@ -60,7 +76,11 @@ labels_4: {
|
||||
}
|
||||
|
||||
labels_5: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
// should keep the break-s in the following
|
||||
input: {
|
||||
while (foo) {
|
||||
@@ -92,7 +112,11 @@ labels_6: {
|
||||
}
|
||||
|
||||
labels_7: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
while (foo) {
|
||||
x();
|
||||
@@ -109,7 +133,11 @@ labels_7: {
|
||||
}
|
||||
|
||||
labels_8: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
while (foo) {
|
||||
x();
|
||||
@@ -127,7 +155,11 @@ labels_8: {
|
||||
}
|
||||
|
||||
labels_9: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
@@ -146,7 +178,11 @@ labels_9: {
|
||||
}
|
||||
|
||||
labels_10: {
|
||||
options = { if_return: true, conditionals: true, dead_code: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
while_becomes_for: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
while (foo()) bar();
|
||||
}
|
||||
@@ -9,7 +11,9 @@ while_becomes_for: {
|
||||
}
|
||||
|
||||
drop_if_break_1: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;;)
|
||||
if (foo()) break;
|
||||
@@ -20,7 +24,9 @@ drop_if_break_1: {
|
||||
}
|
||||
|
||||
drop_if_break_2: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();)
|
||||
if (foo()) break;
|
||||
@@ -31,7 +37,9 @@ drop_if_break_2: {
|
||||
}
|
||||
|
||||
drop_if_break_3: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) break;
|
||||
@@ -48,7 +56,10 @@ drop_if_break_3: {
|
||||
}
|
||||
|
||||
drop_if_break_4: {
|
||||
options = { loops: true, sequences: true };
|
||||
options = {
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
x();
|
||||
@@ -64,7 +75,9 @@ drop_if_break_4: {
|
||||
}
|
||||
|
||||
drop_if_else_break_1: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;;) if (foo()) bar(); else break;
|
||||
}
|
||||
@@ -74,7 +87,9 @@ drop_if_else_break_1: {
|
||||
}
|
||||
|
||||
drop_if_else_break_2: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) baz();
|
||||
@@ -87,7 +102,9 @@ drop_if_else_break_2: {
|
||||
}
|
||||
|
||||
drop_if_else_break_3: {
|
||||
options = { loops: true };
|
||||
options = {
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
if (foo()) baz();
|
||||
@@ -106,7 +123,10 @@ drop_if_else_break_3: {
|
||||
}
|
||||
|
||||
drop_if_else_break_4: {
|
||||
options = { loops: true, sequences: true };
|
||||
options = {
|
||||
loops: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
for (;bar();) {
|
||||
x();
|
||||
@@ -123,7 +143,9 @@ drop_if_else_break_4: {
|
||||
}
|
||||
|
||||
parse_do_while_with_semicolon: {
|
||||
options = { loops: false };
|
||||
options = {
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
x();
|
||||
@@ -135,7 +157,9 @@ parse_do_while_with_semicolon: {
|
||||
}
|
||||
|
||||
parse_do_while_without_semicolon: {
|
||||
options = { loops: false };
|
||||
options = {
|
||||
loops: false,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
x();
|
||||
@@ -153,7 +177,7 @@ evaluate: {
|
||||
loops: true,
|
||||
passes: 2,
|
||||
side_effects: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
while (true) {
|
||||
a();
|
||||
@@ -294,10 +318,10 @@ issue_186_beautify_ie8: {
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_bracketize: {
|
||||
issue_186_braces: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
@@ -314,10 +338,10 @@ issue_186_bracketize: {
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_bracketize_ie8: {
|
||||
issue_186_braces_ie8: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
@@ -334,10 +358,10 @@ issue_186_bracketize_ie8: {
|
||||
expect_exact: 'var x=3;if(foo()){do{do{alert(x)}while(--x)}while(x)}else{bar()}'
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize: {
|
||||
issue_186_beautify_braces: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
@@ -366,10 +390,10 @@ issue_186_beautify_bracketize: {
|
||||
]
|
||||
}
|
||||
|
||||
issue_186_beautify_bracketize_ie8: {
|
||||
issue_186_beautify_braces_ie8: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
bracketize: true,
|
||||
braces: true,
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
@@ -457,7 +481,7 @@ 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);
|
||||
@@ -492,3 +516,133 @@ dead_code_condition: {
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2740_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
for (; ; ) break;
|
||||
for (a(); ; ) break;
|
||||
for (; b(); ) break;
|
||||
for (c(); d(); ) break;
|
||||
for (; ; e()) break;
|
||||
for (f(); ; g()) break;
|
||||
for (; h(); i()) break;
|
||||
for (j(); k(); l()) break;
|
||||
}
|
||||
expect: {
|
||||
a();
|
||||
b();
|
||||
c();
|
||||
d();
|
||||
f();
|
||||
h();
|
||||
j();
|
||||
k();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2740_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: while (x()) {
|
||||
break L1;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2740_3: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L1;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
L1: for (var x = 0; x < 3; x++)
|
||||
for (var y = 0; y < 2; y++)
|
||||
break L1;
|
||||
console.log(x, y);
|
||||
}
|
||||
expect_stdout: "0 0"
|
||||
}
|
||||
|
||||
issue_2740_4: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L2;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
for (var x = 0; x < 3; x++) {
|
||||
var y = 0;
|
||||
y < 2;
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect_stdout: "3 0"
|
||||
}
|
||||
|
||||
issue_2740_5: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
loops: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
L1: for (var x = 0; x < 3; x++) {
|
||||
break L1;
|
||||
L2: for (var y = 0; y < 2; y++) {
|
||||
break L2;
|
||||
}
|
||||
}
|
||||
console.log(x, y);
|
||||
}
|
||||
expect: {
|
||||
var x = 0;
|
||||
x < 3;
|
||||
var y;
|
||||
console.log(x,y);
|
||||
}
|
||||
expect_stdout: "0 undefined"
|
||||
}
|
||||
|
||||
issue_2904: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
loops: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
do {
|
||||
console.log(a);
|
||||
} while (--a);
|
||||
}
|
||||
expect: {
|
||||
for (var a = 1; console.log(a), --a;);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -8,14 +8,14 @@ too_short: {
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{',
|
||||
'c:42,',
|
||||
'd:a(),',
|
||||
'e:"foo"}}',
|
||||
"function f(",
|
||||
"a){return{",
|
||||
"c:42,d:a(",
|
||||
'),e:"foo"}',
|
||||
"}",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 10 characters"
|
||||
"WARN: Output exceeds 10 characters",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,11 +29,25 @@ just_enough: {
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
'function f(a){',
|
||||
'return{c:42,',
|
||||
"function f(a){",
|
||||
"return{c:42,",
|
||||
'd:a(),e:"foo"}',
|
||||
'}',
|
||||
]
|
||||
expect_warnings: [
|
||||
"}",
|
||||
]
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
issue_304: {
|
||||
beautify = {
|
||||
max_line_len: 10,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b = 0, c = 0, d = 0, e = 0;
|
||||
}
|
||||
expect_exact: [
|
||||
"var a=0,",
|
||||
"b=0,c=0,",
|
||||
"d=0,e=0;",
|
||||
]
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
negate_iife_1: {
|
||||
options = {
|
||||
negate_iife: true
|
||||
};
|
||||
negate_iife: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
@@ -13,7 +13,7 @@ negate_iife_1: {
|
||||
negate_iife_1_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ stuff() })();
|
||||
}
|
||||
@@ -24,7 +24,7 @@ negate_iife_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ return {} })().x = 10;
|
||||
}
|
||||
@@ -45,9 +45,9 @@ negate_iife_2_side_effects: {
|
||||
|
||||
negate_iife_3: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
conditionals: true
|
||||
};
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
@@ -67,7 +67,7 @@ negate_iife_3_evaluate: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
true, console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -88,9 +88,9 @@ negate_iife_3_side_effects: {
|
||||
|
||||
negate_iife_3_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
};
|
||||
negate_iife: false,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
@@ -110,17 +110,17 @@ negate_iife_3_off_evaluate: {
|
||||
(function(){ return true })() ? console.log(true) : console.log(false);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
true, console.log(true);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
negate_iife_4: {
|
||||
options = {
|
||||
negate_iife: true,
|
||||
conditionals: true,
|
||||
sequences: true
|
||||
};
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
@@ -136,11 +136,11 @@ negate_iife_4: {
|
||||
|
||||
sequence_off: {
|
||||
options = {
|
||||
negate_iife: false,
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
negate_iife: false,
|
||||
passes: 2,
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
@@ -171,10 +171,10 @@ sequence_off: {
|
||||
|
||||
negate_iife_5: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -194,10 +194,10 @@ negate_iife_5: {
|
||||
|
||||
negate_iife_5_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
foo(true);
|
||||
@@ -217,10 +217,10 @@ negate_iife_5_off: {
|
||||
|
||||
negate_iife_nested: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
@@ -250,10 +250,10 @@ negate_iife_nested: {
|
||||
|
||||
negate_iife_nested_off: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: false,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
function Foo(f) {
|
||||
this.f = f;
|
||||
@@ -283,10 +283,10 @@ negate_iife_nested_off: {
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
conditionals: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
new (function(a) {
|
||||
return function Foo() {
|
||||
@@ -356,7 +356,7 @@ issue_1288: {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
side_effects: false,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
if (w) ;
|
||||
else {
|
||||
|
||||
@@ -36,7 +36,9 @@ new_statements_3: {
|
||||
}
|
||||
|
||||
new_with_rewritten_true_value: {
|
||||
options = { booleans: true }
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
new true;
|
||||
}
|
||||
|
||||
@@ -1,21 +1,49 @@
|
||||
hex_numbers_in_parentheses_for_prototype_functions: {
|
||||
input: {
|
||||
(-2);
|
||||
(-2).toFixed(0);
|
||||
|
||||
(2);
|
||||
(2).toFixed(0);
|
||||
|
||||
(0.2);
|
||||
(0.2).toFixed(0);
|
||||
|
||||
(0.00000002);
|
||||
(0.00000002).toFixed(0);
|
||||
|
||||
(1000000000000000128);
|
||||
(1000000000000000128).toFixed(0);
|
||||
beautify = {
|
||||
beautify: true,
|
||||
}
|
||||
expect_exact: "-2;(-2).toFixed(0);2;2..toFixed(0);.2;.2.toFixed(0);2e-8;2e-8.toFixed(0);0xde0b6b3a7640080;(0xde0b6b3a7640080).toFixed(0);"
|
||||
input: {
|
||||
function f() {
|
||||
(-2);
|
||||
(-2).toFixed(0);
|
||||
|
||||
(2);
|
||||
(2).toFixed(0);
|
||||
|
||||
(0.2);
|
||||
(0.2).toFixed(0);
|
||||
|
||||
(2.34e20);
|
||||
(2.34e20).toFixed(0);
|
||||
|
||||
(0.00000002);
|
||||
(0.00000002).toFixed(0);
|
||||
|
||||
(1000000000000000128);
|
||||
(1000000000000000128).toFixed(0);
|
||||
|
||||
(-1000000000000000128);
|
||||
(-1000000000000000128).toFixed(0);
|
||||
}
|
||||
}
|
||||
expect_exact: [
|
||||
"function f() {",
|
||||
" -2;",
|
||||
" (-2).toFixed(0);",
|
||||
" 2;",
|
||||
" 2..toFixed(0);",
|
||||
" .2;",
|
||||
" .2.toFixed(0);",
|
||||
" 234e18;",
|
||||
" 234e18.toFixed(0);",
|
||||
" 2e-8;",
|
||||
" 2e-8.toFixed(0);",
|
||||
" 0xde0b6b3a7640080;",
|
||||
" (0xde0b6b3a7640080).toFixed(0);",
|
||||
" -0xde0b6b3a7640080;",
|
||||
" (-0xde0b6b3a7640080).toFixed(0);",
|
||||
"}",
|
||||
]
|
||||
}
|
||||
|
||||
comparisons: {
|
||||
|
||||
181
test/compress/preserve_line.js
Normal file
181
test/compress/preserve_line.js
Normal file
@@ -0,0 +1,181 @@
|
||||
return_1: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f(){",
|
||||
"",
|
||||
"return 42!=f.toString()}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_2: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f() {",
|
||||
"",
|
||||
" return 42 != f.toString();",
|
||||
"}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_3: {
|
||||
options = {}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f(){",
|
||||
"",
|
||||
"return 42!=f.toString()}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_4: {
|
||||
options = {}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
return (
|
||||
f.toString() != 42
|
||||
);
|
||||
}());
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(function f() {",
|
||||
"",
|
||||
" return 42 != f.toString();",
|
||||
"}());",
|
||||
]
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
return_5: {
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(tags,slug){",
|
||||
"var ref",
|
||||
"",
|
||||
"",
|
||||
";return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
return_6: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected = function(tags, slug) {",
|
||||
" var ref;",
|
||||
"",
|
||||
"",
|
||||
" return null != (ref = _.find(tags, {",
|
||||
" slug: slug",
|
||||
" })) ? ref.selected : void 0;",
|
||||
"};",
|
||||
]
|
||||
}
|
||||
|
||||
return_7: {
|
||||
options = {}
|
||||
mangle = {}
|
||||
beautify = {
|
||||
beautify: false,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(e,l){",
|
||||
"var n",
|
||||
"",
|
||||
"",
|
||||
";return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
return_8: {
|
||||
options = {}
|
||||
mangle = {}
|
||||
beautify = {
|
||||
beautify: true,
|
||||
preserve_line: true,
|
||||
}
|
||||
input: {
|
||||
_is_selected = function(tags, slug) {
|
||||
var ref;
|
||||
return (ref = _.find(tags, {
|
||||
slug: slug
|
||||
})) != null ? ref.selected : void 0;
|
||||
};
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected = function(e, l) {",
|
||||
" var n;",
|
||||
"",
|
||||
"",
|
||||
" return null != (n = _.find(e, {",
|
||||
" slug: l",
|
||||
" })) ? n.selected : void 0;",
|
||||
"};",
|
||||
]
|
||||
}
|
||||
@@ -567,16 +567,41 @@ native_prototype: {
|
||||
}
|
||||
input: {
|
||||
Array.prototype.splice.apply(a, [1, 2, b, c]);
|
||||
Function.prototype.call.apply(console.log, console, [ "foo" ]);
|
||||
Number.prototype.toFixed.call(Math.PI, 2);
|
||||
Object.prototype.hasOwnProperty.call(d, "foo");
|
||||
RegExp.prototype.test.call(/foo/, "bar");
|
||||
String.prototype.indexOf.call(e, "bar");
|
||||
}
|
||||
expect: {
|
||||
[].splice.apply(a, [1, 2, b, c]);
|
||||
(function() {}).call.apply(console.log, console, [ "foo" ]);
|
||||
0..toFixed.call(Math.PI, 2);
|
||||
({}).hasOwnProperty.call(d, "foo");
|
||||
/t/.test.call(/foo/, "bar");
|
||||
"".indexOf.call(e, "bar");
|
||||
}
|
||||
}
|
||||
|
||||
native_prototype_lhs: {
|
||||
options = {
|
||||
unsafe_proto: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
Function.prototype.bar = "PASS";
|
||||
return function() {};
|
||||
}().bar);
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
Function.prototype.bar = "PASS";
|
||||
return function() {};
|
||||
}().bar);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
accessor_boolean: {
|
||||
input: {
|
||||
var a = 1;
|
||||
@@ -1094,3 +1119,746 @@ const_prop_assign_pure: {
|
||||
x();
|
||||
}
|
||||
}
|
||||
|
||||
join_object_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
};
|
||||
x.b = 2;
|
||||
x[3] = function() {
|
||||
console.log(x);
|
||||
},
|
||||
x["a"] = /foo/,
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var x = {
|
||||
a: 1,
|
||||
c: (console.log("c"), "C"),
|
||||
b: 2,
|
||||
3: function() {
|
||||
console.log(x);
|
||||
},
|
||||
a: /foo/,
|
||||
};
|
||||
x.bar = x;
|
||||
return x;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
join_object_assignments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
foo: 1,
|
||||
};
|
||||
o.bar = 2;
|
||||
o.baz = 3;
|
||||
console.log(o.foo, o.bar + o.bar, o.foo * o.bar * o.baz);
|
||||
}
|
||||
expect: {
|
||||
console.log(1, 4, 6);
|
||||
}
|
||||
expect_stdout: "1 4 6"
|
||||
}
|
||||
|
||||
join_object_assignments_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
a: "PASS",
|
||||
}, a = o.a;
|
||||
o.a = "FAIL";
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
a: "PASS",
|
||||
}, a = o.a;
|
||||
o.a = "FAIL";
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_4: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var o;
|
||||
console.log(o);
|
||||
o = {};
|
||||
o.a = "foo";
|
||||
console.log(o.b);
|
||||
o.b = "bar";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o;
|
||||
console.log(o),
|
||||
o = {
|
||||
a: "foo",
|
||||
},
|
||||
console.log(o.b),
|
||||
o.b = "bar",
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_return_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = "foo";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
};
|
||||
return o.q;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
join_object_assignments_return_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = /foo/,
|
||||
o.r = "bar";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: /foo/,
|
||||
r: "bar"
|
||||
};
|
||||
return o.r;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "bar"
|
||||
}
|
||||
|
||||
join_object_assignments_return_3: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
return o.q = "foo",
|
||||
o.p += "",
|
||||
console.log(o.q),
|
||||
o.p;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
};
|
||||
return o.p += "",
|
||||
console.log(o.q),
|
||||
o.p;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_for: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {
|
||||
p: 3
|
||||
};
|
||||
for (o.q = "foo"; console.log(o.q););
|
||||
return o.p;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
for (var o = {
|
||||
p: 3,
|
||||
q: "foo"
|
||||
}; console.log(o.q););
|
||||
return o.p;
|
||||
}());
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"3",
|
||||
]
|
||||
}
|
||||
|
||||
join_object_assignments_if: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {};
|
||||
if (o.a = "PASS") return o.a;
|
||||
}())
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = { a: "PASS" };
|
||||
if (o.a) return o.a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_forin: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var o = {};
|
||||
for (var a in o.a = "PASS", o)
|
||||
return o[a];
|
||||
}())
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o = { a: "PASS" };
|
||||
for (var a in o)
|
||||
return o[a];
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_object_assignments_negative: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[0] = 0;
|
||||
o[-0] = 1;
|
||||
o[-1] = 2;
|
||||
console.log(o[0], o[-0], o[-1]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
0: 0,
|
||||
0: 1,
|
||||
"-1": 2
|
||||
};
|
||||
console.log(o[0], o[-0], o[-1]);
|
||||
}
|
||||
expect_stdout: "1 1 2"
|
||||
}
|
||||
|
||||
join_object_assignments_NaN_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
join_object_assignments_NaN_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[NaN] = 1;
|
||||
o[0/0] = 2;
|
||||
console.log(o[NaN], o[NaN]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
NaN: 1,
|
||||
NaN: 2
|
||||
};
|
||||
console.log(o.NaN, o.NaN);
|
||||
}
|
||||
expect_stdout: "2 2"
|
||||
}
|
||||
|
||||
join_object_assignments_null_0: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_null_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[null] = 1;
|
||||
console.log(o[null]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
null: 1
|
||||
};
|
||||
console.log(o.null);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_void_0: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[void 0] = 1;
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
undefined: 1
|
||||
};
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_undefined_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[undefined] = 1;
|
||||
console.log(o[undefined]);
|
||||
}
|
||||
expect: {
|
||||
var o = {};
|
||||
o[void 0] = 1;
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_undefined_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[undefined] = 1;
|
||||
console.log(o[undefined]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
undefined : 1
|
||||
};
|
||||
console.log(o[void 0]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
join_object_assignments_Infinity: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[Infinity] = 1;
|
||||
o[1/0] = 2;
|
||||
o[-Infinity] = 3;
|
||||
o[-1/0] = 4;
|
||||
console.log(o[Infinity], o[1/0], o[-Infinity], o[-1/0]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
Infinity: 1,
|
||||
Infinity: 2,
|
||||
"-Infinity": 3,
|
||||
"-Infinity": 4
|
||||
};
|
||||
console.log(o[1/0], o[1/0], o[-1/0], o[-1/0]);
|
||||
}
|
||||
expect_stdout: "2 2 4 4"
|
||||
}
|
||||
|
||||
join_object_assignments_regex: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
o[/rx/] = 1;
|
||||
console.log(o[/rx/]);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
"/rx/": 1
|
||||
};
|
||||
console.log(o[/rx/]);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
issue_2816: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1
|
||||
};
|
||||
o.b = 2;
|
||||
o.a = 3;
|
||||
o.c = 4;
|
||||
console.log(o.a, o.b, o.c);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var o = {
|
||||
a: 1,
|
||||
b: 2
|
||||
};
|
||||
o.a = 3;
|
||||
o.c = 4;
|
||||
console.log(o.a, o.b, o.c);
|
||||
}
|
||||
expect_stdout: "3 2 4"
|
||||
}
|
||||
|
||||
issue_2893_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get a() {
|
||||
return "PASS";
|
||||
},
|
||||
};
|
||||
o.a = "FAIL";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get a() {
|
||||
return "PASS";
|
||||
},
|
||||
};
|
||||
o.a = "FAIL";
|
||||
console.log(o.a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2893_2: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
set a(v) {
|
||||
this.b = v;
|
||||
},
|
||||
b: "FAIL",
|
||||
};
|
||||
o.a = "PASS";
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
set a(v) {
|
||||
this.b = v;
|
||||
},
|
||||
b: "FAIL",
|
||||
};
|
||||
o.a = "PASS";
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_869_1: {
|
||||
mangle = {
|
||||
properties: {
|
||||
reserved: [ "get" ]
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: "FAIL" };
|
||||
Object.defineProperty(o, "p", {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
});
|
||||
console.log(o.p);
|
||||
}
|
||||
expect: {
|
||||
var o = { o: "FAIL" };
|
||||
Object.defineProperty(o, "o", {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
});
|
||||
console.log(o.o);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_869_2: {
|
||||
mangle = {
|
||||
properties: {
|
||||
reserved: [ "get" ]
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: "FAIL" };
|
||||
Object.defineProperties(o, {
|
||||
p: {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(o.p);
|
||||
}
|
||||
expect: {
|
||||
var o = { o: "FAIL" };
|
||||
Object.defineProperties(o, {
|
||||
o: {
|
||||
get: function() {
|
||||
return "PASS";
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(o.o);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this.p);
|
||||
}
|
||||
(function() {
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: f
|
||||
};
|
||||
o.f();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this.p);
|
||||
}
|
||||
({
|
||||
p: "PASS",
|
||||
f: f
|
||||
}).f();
|
||||
var o;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
var f = function() {
|
||||
console.log(this.p);
|
||||
};
|
||||
function g() {
|
||||
var o = {
|
||||
p: "PASS",
|
||||
f: f
|
||||
};
|
||||
o.f();
|
||||
}
|
||||
g();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
({
|
||||
p: "PASS",
|
||||
f: function() {
|
||||
console.log(this.p);
|
||||
}
|
||||
}).f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3188_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
inline: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this[0]);
|
||||
}
|
||||
(function() {
|
||||
var o = ["PASS", f];
|
||||
o[1]();
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(this[0]);
|
||||
}
|
||||
["PASS", f][1]();
|
||||
var o;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
join_expr: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
var a = 0;
|
||||
switch ((a = {}) && (a.b = 0)) {
|
||||
case 0:
|
||||
c = "PASS";
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect: {
|
||||
var c = "FAIL";
|
||||
(function() {
|
||||
var a = 0;
|
||||
switch (a = { b: 0 }, a.b) {
|
||||
case 0:
|
||||
c = "PASS";
|
||||
}
|
||||
})();
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -414,3 +414,269 @@ issue_2638: {
|
||||
"/* */(a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a();
|
||||
/*@__PURE__*/ (new b());
|
||||
new (/*@__PURE__*/ c)();
|
||||
(/*@__PURE__*/ new d());
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */c;",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a(1)(2)(3);
|
||||
/*@__PURE__*/ new (b(1))(2)(3);
|
||||
/*@__PURE__*/ new (c(1)(2))(3);
|
||||
/*@__PURE__*/ new (d(1)(2)(3));
|
||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||
(/*@__PURE__*/ new f(1))(2)(3);
|
||||
(/*@__PURE__*/ new g(1)(2))(3);
|
||||
(/*@__PURE__*/ new h(1)(2)(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */e(1)(2)(3);",
|
||||
"/* */new f(1)(2)(3);",
|
||||
"/* */new g(1)(2)(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_3: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||
}
|
||||
expect_exact: [
|
||||
"new/* */h.x(1).y(2).z(3);",
|
||||
"/* */new/* */i.x(1).y(2).z(3);",
|
||||
"/* */new j.x(1).y(2).z(3);",
|
||||
"/* */new k.x(1).y(2).z(3);",
|
||||
"/* */new l.x(1).y(2).z(3);",
|
||||
"/* */new m.x(1).y(2).z(3);",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2705_4: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(/*@__PURE__*/ new x(), y());
|
||||
(w(), /*@__PURE__*/ new x(), y());
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_5: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[ /*@__PURE__*/ new x() ];
|
||||
[ /*@__PURE__*/ new x(), y() ];
|
||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||
}
|
||||
expect: {
|
||||
y();
|
||||
w(), y();
|
||||
}
|
||||
}
|
||||
|
||||
issue_2705_6: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
beautify = {
|
||||
comments: "all",
|
||||
}
|
||||
input: {
|
||||
/*@__PURE__*/new (g() || h())(x(), y());
|
||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||
}
|
||||
expect_exact: [
|
||||
"/* */x(),y();",
|
||||
"/* */new(/* */a()||b())(c(),d());",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3065_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
pure_funcs: [ "pureFunc" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function modifyWrapper(a, f, wrapper) {
|
||||
wrapper.a = a;
|
||||
wrapper.f = f;
|
||||
return wrapper;
|
||||
}
|
||||
function pureFunc(fun) {
|
||||
return modifyWrapper(1, fun, function(a) {
|
||||
return fun(a);
|
||||
});
|
||||
}
|
||||
var unused = pureFunc(function(x) {
|
||||
return x;
|
||||
});
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3065_2: {
|
||||
rename = true
|
||||
options = {
|
||||
inline: true,
|
||||
pure_funcs: [ "pureFunc" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
reserved: [ "pureFunc" ],
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function modifyWrapper(a, f, wrapper) {
|
||||
wrapper.a = a;
|
||||
wrapper.f = f;
|
||||
return wrapper;
|
||||
}
|
||||
function pureFunc(fun) {
|
||||
return modifyWrapper(1, fun, function(a) {
|
||||
return fun(a);
|
||||
});
|
||||
}
|
||||
var unused = pureFunc(function(x) {
|
||||
return x;
|
||||
});
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
issue_3065_3: {
|
||||
options = {
|
||||
pure_funcs: [ "debug" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function debug(msg) {
|
||||
console.log(msg);
|
||||
}
|
||||
debug(function() {
|
||||
console.log("PASS");
|
||||
return "FAIL";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3065_4: {
|
||||
options = {
|
||||
pure_funcs: [ "debug" ],
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var debug = function(msg) {
|
||||
console.log(msg);
|
||||
};
|
||||
debug(function() {
|
||||
console.log("PASS");
|
||||
return "FAIL";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
issue_3325_1: {
|
||||
options = {
|
||||
pure_funcs: "cb",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_3325_2: {
|
||||
options = {
|
||||
pure_funcs: "xxxcbxxx",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect: {
|
||||
function cb() {
|
||||
console.log("PASS");
|
||||
}
|
||||
cb();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -187,10 +187,10 @@ issue_2110_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -348,6 +348,57 @@ set_immutable_4: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
1..foo += "";
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_immutable_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a.foo += "";
|
||||
if (a.foo) console.log("FAIL");
|
||||
else console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
1..foo ? console.log("FAIL") : console.log("PASS");
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
set_mutable_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -643,3 +694,470 @@ issue_2678: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2838: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
(a || b).c = "PASS";
|
||||
(function() {
|
||||
return f(a, b);
|
||||
}).prototype.foo = "bar";
|
||||
}
|
||||
var o = {};
|
||||
f(null, o);
|
||||
console.log(o.c);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(a || b).c = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(null, o);
|
||||
console.log(o.c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_1: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_2: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var Parser = function Parser() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function initialContext() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect: {
|
||||
var Parser = function() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_3: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var unused = a.a;
|
||||
a.b = "PASS";
|
||||
a.c;
|
||||
}
|
||||
var o = {};
|
||||
o.d;
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
a.b = "PASS";
|
||||
}
|
||||
var o = {};
|
||||
f(o);
|
||||
console.log(o.b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_2938_4: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var Parser = function Parser() {};
|
||||
var p = Parser.prototype;
|
||||
var unused = p.x;
|
||||
p.initialContext = function initialContext() {
|
||||
p.y;
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect: {
|
||||
var Parser = function() {};
|
||||
var p = Parser.prototype;
|
||||
p.initialContext = function() {
|
||||
console.log("PASS");
|
||||
};
|
||||
p.braceIsBlock = function() {};
|
||||
(new Parser).initialContext();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_vars_1_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
if (a.g() || b.p) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_1_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_1_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
for (;;) {
|
||||
var c = a.g();
|
||||
var d = b.p;
|
||||
if (c || d) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.b = g.a = function() {};
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_vars_2_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.a = function() {};
|
||||
g.b = g.a;
|
||||
return g;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
function g() {}
|
||||
g.b = g.a = function() {};
|
||||
return g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collapse_rhs_true: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_false: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: false,
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_strict: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
console.log((42..length = "PASS", "PASS"));
|
||||
console.log(("foo".length = "PASS", "PASS"));
|
||||
console.log((false.length = "PASS", "PASS"));
|
||||
console.log((function() {}.length = "PASS", "PASS"));
|
||||
console.log(({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS", "PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(42..length = "PASS");
|
||||
console.log("foo".length = "PASS");
|
||||
console.log(false.length = "PASS");
|
||||
console.log(function() {}.length = "PASS");
|
||||
console.log({
|
||||
get length() {
|
||||
return "FAIL";
|
||||
}
|
||||
}.length = "PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_rhs_setter: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
console.log(({
|
||||
set length(v) {
|
||||
throw "PASS";
|
||||
}
|
||||
}.length = "FAIL", "FAIL"));
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
console.log({
|
||||
set length(v) {
|
||||
throw "PASS";
|
||||
}
|
||||
}.length = "FAIL");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_rhs_call: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {};
|
||||
function f() {
|
||||
console.log("PASS");
|
||||
}
|
||||
o.f = f;
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
({}.f = function() {
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_rhs_lhs: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
}
|
||||
input: {
|
||||
function f(a, b) {
|
||||
a.b = b, b += 2;
|
||||
console.log(a.b, b);
|
||||
}
|
||||
f({}, 1);
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
a.b = b, b += 2;
|
||||
console.log(a.b, b);
|
||||
}
|
||||
f({}, 1);
|
||||
}
|
||||
expect_stdout: "1 3"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
37
test/compress/regexp.js
Normal file
37
test/compress/regexp.js
Normal file
@@ -0,0 +1,37 @@
|
||||
regexp_simple: {
|
||||
input: {
|
||||
/rx/ig
|
||||
}
|
||||
expect_exact: "/rx/gi;"
|
||||
}
|
||||
|
||||
regexp_slashes: {
|
||||
input: {
|
||||
/\\\/rx\/\\/ig
|
||||
}
|
||||
expect_exact: "/\\\\\\/rx\\/\\\\/gi;"
|
||||
}
|
||||
|
||||
regexp_1: {
|
||||
input: {
|
||||
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/ig)));
|
||||
}
|
||||
expect: {
|
||||
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/gi)));
|
||||
}
|
||||
expect_stdout: '["PASS","pass"]'
|
||||
}
|
||||
|
||||
regexp_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(JSON.stringify("COMPASS? Overpass.".match(new RegExp("([Sap]+)", "ig"))));
|
||||
}
|
||||
expect: {
|
||||
console.log(JSON.stringify("COMPASS? Overpass.".match(/([Sap]+)/gi)));
|
||||
}
|
||||
expect_stdout: '["PASS","pass"]'
|
||||
}
|
||||
@@ -109,7 +109,7 @@ mangle_catch_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(c){o="PASS"}console.log(o);'
|
||||
expect_exact: 'var c="FAIL";try{throw 1}catch(o){c="PASS"}console.log(c);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ mangle_catch_var_toplevel: {
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_exact: 'var o="FAIL";try{throw 1}catch(r){var o="PASS"}console.log(o);'
|
||||
expect_exact: 'var r="FAIL";try{throw 1}catch(o){var r="PASS"}console.log(r);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ function_iife_catch: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ function_iife_catch_ie8: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_exact: "function f(o){!function(){try{throw 0}catch(o){var c=1;console.log(o,c)}}()}f();"
|
||||
expect_exact: "function f(c){!function(){try{throw 0}catch(c){var o=1;console.log(c,o)}}()}f();"
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -499,7 +499,7 @@ function_catch_catch: {
|
||||
}
|
||||
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_exact: "var o=0;function f(){try{throw 1}catch(o){try{throw 2}catch(c){var c=3;console.log(c)}}console.log(c)}f();"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"undefined",
|
||||
@@ -534,3 +534,80 @@ function_catch_catch_ie8: {
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
function_do_catch_ie8: {
|
||||
rename = true
|
||||
options = {
|
||||
ie8: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1, b = 1, c = 0;
|
||||
function d(e) {
|
||||
var f, g, h, i;
|
||||
do {
|
||||
try {
|
||||
try {
|
||||
var j = function q(){}();
|
||||
} catch (r) {
|
||||
--a && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
|
||||
var k, l, m, n, o;
|
||||
--m;
|
||||
--n;
|
||||
--o;
|
||||
}
|
||||
try {
|
||||
i[1];
|
||||
} catch (s) {
|
||||
var p;
|
||||
switch (function t() {
|
||||
c++;
|
||||
}()) {
|
||||
case j + --p:
|
||||
}
|
||||
}
|
||||
} catch (u) {}
|
||||
} while (--i);
|
||||
b--;
|
||||
}
|
||||
d();
|
||||
console.log(b, c);
|
||||
}
|
||||
expect: {
|
||||
var t = 1, u = 1, y = 0;
|
||||
function c(c) {
|
||||
var d;
|
||||
do {
|
||||
try {
|
||||
try {
|
||||
var e = void 0;
|
||||
} catch (i) {
|
||||
--t && w("ddddddddeeeeeeegggggggggiiiiilllllllnnnnntuuuuuuuuyyyyyyy");
|
||||
0;
|
||||
0;
|
||||
0;
|
||||
}
|
||||
try {
|
||||
d[1];
|
||||
} catch (l) {
|
||||
var g;
|
||||
switch(function x() {
|
||||
y++;
|
||||
}()) {
|
||||
case e + --g:
|
||||
}
|
||||
}
|
||||
} catch (n) {}
|
||||
} while (--d);
|
||||
u--;
|
||||
}
|
||||
c();
|
||||
console.log(u, y);
|
||||
}
|
||||
expect_stdout: "0 1"
|
||||
}
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
return_undefined: {
|
||||
options = {
|
||||
sequences : false,
|
||||
if_return : true,
|
||||
evaluate : true,
|
||||
dead_code : true,
|
||||
conditionals : true,
|
||||
comparisons : true,
|
||||
booleans : true,
|
||||
unused : true,
|
||||
side_effects : true,
|
||||
properties : true,
|
||||
drop_debugger : true,
|
||||
loops : true,
|
||||
hoist_funs : true,
|
||||
keep_fargs : true,
|
||||
keep_fnames : false,
|
||||
hoist_vars : true,
|
||||
join_vars : true,
|
||||
negate_iife : true
|
||||
};
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
drop_debugger: true,
|
||||
evaluate: true,
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
keep_fnames: false,
|
||||
loops: true,
|
||||
negate_iife: true,
|
||||
properties: true,
|
||||
sequences: false,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f0() {
|
||||
}
|
||||
|
||||
@@ -1,394 +0,0 @@
|
||||
do_screw: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\v");'
|
||||
}
|
||||
|
||||
dont_screw: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
ascii_only: true,
|
||||
}
|
||||
input: {
|
||||
f("\v");
|
||||
}
|
||||
expect_exact: 'f("\\x0B");'
|
||||
}
|
||||
|
||||
do_screw_constants: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(void 0,1/0);"
|
||||
}
|
||||
|
||||
dont_screw_constants: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
f(undefined, Infinity);
|
||||
}
|
||||
expect_exact: "f(undefined,Infinity);"
|
||||
}
|
||||
|
||||
do_screw_try_catch: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
good = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
good = function(n){
|
||||
return function(t){
|
||||
try{
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
dont_screw_try_catch: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
bad = function(e){
|
||||
return function(error){
|
||||
try{
|
||||
e()
|
||||
} catch(e) {
|
||||
error(e)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
bad = function(n){
|
||||
return function(t){
|
||||
try{
|
||||
n()
|
||||
} catch(n) {
|
||||
t(n)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
do_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
beautify = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(o){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (o) {
|
||||
console.log("caught: "+o)
|
||||
}
|
||||
console.log("undefined is " + void 0);
|
||||
return void 0===o
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
dont_screw_try_catch_undefined: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
beautify = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function a(b){
|
||||
try {
|
||||
throw 'Stuff';
|
||||
} catch (undefined) {
|
||||
console.log('caught: ' + undefined);
|
||||
}
|
||||
console.log('undefined is ' + undefined);
|
||||
return b === undefined;
|
||||
};
|
||||
}
|
||||
expect: {
|
||||
function a(n){
|
||||
try{
|
||||
throw "Stuff"
|
||||
} catch (undefined) {
|
||||
console.log("caught: " + undefined)
|
||||
}
|
||||
console.log("undefined is " + undefined);
|
||||
return n === undefined
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
ie8: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
try {
|
||||
x();
|
||||
} catch (a) {
|
||||
y();
|
||||
}
|
||||
alert(a);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
var t;
|
||||
try {
|
||||
x();
|
||||
} catch (t) {
|
||||
y();
|
||||
}
|
||||
alert(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_1586_1: {
|
||||
options = {
|
||||
ie8: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_exact: "function f(){try{x()}catch(c){console.log(c.message)}}"
|
||||
}
|
||||
|
||||
issue_1586_2: {
|
||||
options = {
|
||||
ie8: false,
|
||||
}
|
||||
mangle = {
|
||||
ie8: false,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
x();
|
||||
} catch (err) {
|
||||
console.log(err.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"
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
make_sequences_1: {
|
||||
options = {
|
||||
sequences: true
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
foo();
|
||||
bar();
|
||||
@@ -14,8 +14,8 @@ make_sequences_1: {
|
||||
|
||||
make_sequences_2: {
|
||||
options = {
|
||||
sequences: true
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if (boo) {
|
||||
foo();
|
||||
@@ -35,8 +35,8 @@ make_sequences_2: {
|
||||
|
||||
make_sequences_3: {
|
||||
options = {
|
||||
sequences: true
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
foo();
|
||||
@@ -61,8 +61,8 @@ make_sequences_3: {
|
||||
|
||||
make_sequences_4: {
|
||||
options = {
|
||||
sequences: true
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
x = 5;
|
||||
if (y) z();
|
||||
@@ -90,7 +90,9 @@ make_sequences_4: {
|
||||
}
|
||||
|
||||
lift_sequences_1: {
|
||||
options = { sequences: true };
|
||||
options = {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var foo, x, y, bar;
|
||||
foo = !(x(), y(), bar());
|
||||
@@ -102,7 +104,10 @@ lift_sequences_1: {
|
||||
}
|
||||
|
||||
lift_sequences_2: {
|
||||
options = { sequences: true, evaluate: true };
|
||||
options = {
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var foo = 1, bar;
|
||||
foo.x = (foo = {}, 10);
|
||||
@@ -119,7 +124,10 @@ lift_sequences_2: {
|
||||
}
|
||||
|
||||
lift_sequences_3: {
|
||||
options = { sequences: true, conditionals: true };
|
||||
options = {
|
||||
conditionals: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var x, foo, bar, baz;
|
||||
x = (foo(), bar(), baz()) ? 10 : 20;
|
||||
@@ -131,7 +139,9 @@ lift_sequences_3: {
|
||||
}
|
||||
|
||||
lift_sequences_4: {
|
||||
options = { side_effects: true };
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var x, foo, bar, baz;
|
||||
x = (foo, bar, baz);
|
||||
@@ -160,7 +170,9 @@ lift_sequences_5: {
|
||||
}
|
||||
|
||||
for_sequences: {
|
||||
options = { sequences: true };
|
||||
options = {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
// 1
|
||||
foo();
|
||||
@@ -203,7 +215,7 @@ for_sequences: {
|
||||
limit_1: {
|
||||
options = {
|
||||
sequences: 3,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
a;
|
||||
b;
|
||||
@@ -228,7 +240,7 @@ limit_1: {
|
||||
limit_2: {
|
||||
options = {
|
||||
sequences: 3,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
a, b;
|
||||
c, d;
|
||||
@@ -246,9 +258,9 @@ limit_2: {
|
||||
|
||||
negate_iife_for: {
|
||||
options = {
|
||||
sequences: true,
|
||||
negate_iife: true,
|
||||
};
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function() {})();
|
||||
for (i = 0; i < 5; i++) console.log(i);
|
||||
@@ -265,7 +277,7 @@ negate_iife_for: {
|
||||
iife: {
|
||||
options = {
|
||||
sequences: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
@@ -288,7 +300,7 @@ unsafe_undefined: {
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
unsafe_undefined: true,
|
||||
}
|
||||
input: {
|
||||
function f(undefined) {
|
||||
@@ -668,8 +680,7 @@ side_effects_cascade_2: {
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
b = a,
|
||||
!a + (b += a) || (b += a),
|
||||
!(b = a) + (b += a) || (b += a),
|
||||
b = a;
|
||||
}
|
||||
}
|
||||
@@ -796,3 +807,160 @@ cascade_assignment_in_return: {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hoist_defun: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
x();
|
||||
function f() {}
|
||||
y();
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
x(), y();
|
||||
}
|
||||
}
|
||||
|
||||
hoist_decl: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
w();
|
||||
var b = x();
|
||||
y();
|
||||
for (var c; 0;) z();
|
||||
var d;
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
w();
|
||||
var b = x(), c, d;
|
||||
for (y(); 0;) z();
|
||||
}
|
||||
}
|
||||
|
||||
for_init_var: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
unused: false,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
var b = 42;
|
||||
for (var c = 5; c > 0;) c--;
|
||||
a = "FAIL";
|
||||
var a;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function() {
|
||||
for (var b = 42, c = 5, a; c > 0;) c--;
|
||||
a = "FAIL";
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
forin: {
|
||||
options = {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var o = [];
|
||||
o.push("PASS");
|
||||
for (var a in o)
|
||||
console.log(o[a]);
|
||||
}
|
||||
expect: {
|
||||
var o = [];
|
||||
for (var a in o.push("PASS"), o)
|
||||
console.log(o[a]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
call: {
|
||||
options = {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
return this;
|
||||
}();
|
||||
function b() {
|
||||
console.log("foo");
|
||||
}
|
||||
b.c = function() {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
};
|
||||
(a, b)();
|
||||
(a, b.c)();
|
||||
(a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
new (a, b)();
|
||||
new (a, b.c)();
|
||||
new (a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
return this;
|
||||
}();
|
||||
function b() {
|
||||
console.log("foo");
|
||||
}
|
||||
b.c = function() {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
},
|
||||
b(),
|
||||
(a, b.c)(),
|
||||
function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
new b(),
|
||||
new b.c(),
|
||||
new function() {
|
||||
console.log(this === a);
|
||||
}();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"true",
|
||||
"foo",
|
||||
"baz",
|
||||
"false",
|
||||
]
|
||||
}
|
||||
|
||||
missing_link: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100;
|
||||
a;
|
||||
a++ + (0 ? 2 : 1);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 100;
|
||||
a,
|
||||
a++,
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ issue_1929: {
|
||||
function f(s) {
|
||||
return s.split(/[\\/]/);
|
||||
}
|
||||
console.log(JSON.stringify(f("A/B\\C\\D/E\\F")));
|
||||
}
|
||||
expect_exact: "function f(s){return s.split(/[\\\\/]/)}"
|
||||
expect: {
|
||||
function f(s) {
|
||||
return s.split(/[\\/]/);
|
||||
}
|
||||
console.log(JSON.stringify(f("A/B\\C\\D/E\\F")));
|
||||
}
|
||||
expect_stdout: '["A","B","C","D","E","F"]'
|
||||
}
|
||||
|
||||
@@ -820,8 +820,8 @@ issue_1758: {
|
||||
|
||||
issue_2535: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
|
||||
@@ -59,7 +59,7 @@ if_else_empty: {
|
||||
if ({} ? a : b); else {}
|
||||
}
|
||||
expect: {
|
||||
!{} ? b : a;
|
||||
({}), a;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,6 +104,7 @@ if_return: {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f(w, x, y, z) {
|
||||
@@ -124,7 +125,7 @@ if_return: {
|
||||
if (w) {
|
||||
if (y) return;
|
||||
} else if (z) return;
|
||||
return x == y || (x && w(), y && z(), !0);
|
||||
return x == y || (x && w(), y && z()), !0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ typeof_evaluation: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
typeofs: true,
|
||||
};
|
||||
}
|
||||
input: {
|
||||
a = typeof 1;
|
||||
b = typeof 'test';
|
||||
@@ -27,11 +27,11 @@ typeof_evaluation: {
|
||||
|
||||
typeof_in_boolean_context: {
|
||||
options = {
|
||||
booleans : true,
|
||||
evaluate : true,
|
||||
conditionals : true,
|
||||
side_effects : true,
|
||||
};
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f1(x) { return typeof x ? "yes" : "no"; }
|
||||
function f2() { return typeof g()? "Yes" : "No"; }
|
||||
@@ -90,16 +90,10 @@ typeof_defun_1: {
|
||||
"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: [
|
||||
@@ -138,3 +132,166 @@ typeof_defun_2: {
|
||||
"2",
|
||||
]
|
||||
}
|
||||
|
||||
duplicate_defun_arg_name: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}
|
||||
console.log(typeof long_name, long_name());
|
||||
}
|
||||
expect: {
|
||||
function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}
|
||||
console.log(typeof long_name, long_name());
|
||||
}
|
||||
expect_stdout: "function undefined"
|
||||
}
|
||||
|
||||
duplicate_lambda_arg_name: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function long_name(long_name) {
|
||||
return typeof long_name;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2728_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function arguments() {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function arguments() {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_2728_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments() {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect: {
|
||||
function arguments() {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect_stdout: "function object"
|
||||
}
|
||||
|
||||
issue_2728_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function arguments() {
|
||||
}
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
function arguments() {
|
||||
}
|
||||
console.log("function");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2728_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments() {
|
||||
}
|
||||
console.log(typeof arguments);
|
||||
}
|
||||
expect: {
|
||||
function arguments() {
|
||||
}
|
||||
console.log("function");
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_2728_5: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(function arguments(arguments) {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function arguments(arguments) {
|
||||
console.log(typeof arguments);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_2728_6: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
function arguments(arguments) {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect: {
|
||||
function arguments(arguments) {
|
||||
return typeof arguments;
|
||||
}
|
||||
console.log(typeof arguments, arguments());
|
||||
}
|
||||
expect_stdout: "function undefined"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
unicode_parse_variables: {
|
||||
options = {};
|
||||
options = {}
|
||||
input: {
|
||||
var a = {};
|
||||
a.你好 = 456;
|
||||
|
||||
109
test/compress/webkit.js
Normal file
109
test/compress/webkit.js
Normal file
@@ -0,0 +1,109 @@
|
||||
lambda_call_dot_assign: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return {};
|
||||
}().a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){return{}}().a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_call_dot_assign_webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return {};
|
||||
}().a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){return{}}()).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_dot_assign: {
|
||||
beautify = {
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log(function(){1+1}.a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_dot_assign_webkit: {
|
||||
beautify = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
1 + 1;
|
||||
}.a = 1);
|
||||
}
|
||||
expect_exact: "console.log((function(){1+1}).a=1);"
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
lambda_name_mangle: {
|
||||
mangle = {}
|
||||
input: {
|
||||
console.log(typeof function foo(bar) {});
|
||||
}
|
||||
expect_exact: "console.log(typeof function o(n){});"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
lambda_name_mangle_ie8: {
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function foo(bar) {});
|
||||
}
|
||||
expect_exact: "console.log(typeof function n(o){});"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
function_name_mangle: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
(function() {
|
||||
function foo(bar) {}
|
||||
console.log(typeof foo);
|
||||
})();
|
||||
}
|
||||
expect_exact: "(function(){console.log(typeof function o(n){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
function_name_mangle_ie8: {
|
||||
options = {
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {
|
||||
ie8: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
function foo(bar) {}
|
||||
console.log(typeof foo);
|
||||
})();
|
||||
}
|
||||
expect_exact: "(function(){console.log(typeof function n(o){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
@@ -23,7 +23,7 @@ wrap_iife_in_expression: {
|
||||
wrap_iife: true,
|
||||
}
|
||||
input: {
|
||||
foo = (function () {
|
||||
foo = (function() {
|
||||
return bar();
|
||||
})();
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
exports["Compressor"] = Compressor;
|
||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||
exports["OutputStream"] = OutputStream;
|
||||
exports["SourceMap"] = SourceMap;
|
||||
exports["TreeWalker"] = TreeWalker;
|
||||
exports["base54"] = base54;
|
||||
exports["Compressor"] = Compressor;
|
||||
exports["defaults"] = defaults;
|
||||
exports["is_identifier"] = is_identifier;
|
||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||
exports["mangle_properties"] = mangle_properties;
|
||||
exports["minify"] = minify;
|
||||
exports["OutputStream"] = OutputStream;
|
||||
exports["parse"] = parse;
|
||||
exports["push_uniq"] = push_uniq;
|
||||
exports["reserve_quoted_keys"] = reserve_quoted_keys;
|
||||
exports["SourceMap"] = SourceMap;
|
||||
exports["string_template"] = string_template;
|
||||
exports["tokenizer"] = tokenizer;
|
||||
exports["is_identifier"] = is_identifier;
|
||||
exports["TreeTransformer"] = TreeTransformer;
|
||||
exports["TreeWalker"] = TreeWalker;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user