Compare commits
325 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a6e58109e | ||
|
|
5ac6ec5496 | ||
|
|
eb22f0101e | ||
|
|
e4bff315eb | ||
|
|
001f6f9719 | ||
|
|
e0b302d651 | ||
|
|
fa2511f71c | ||
|
|
edf1bf1106 | ||
|
|
88dfc49683 | ||
|
|
9dec612cd5 | ||
|
|
02d966d914 | ||
|
|
5b5f6e329c | ||
|
|
4e4a2f8ed3 | ||
|
|
32bd65a87f | ||
|
|
318206d41d | ||
|
|
535212c69e | ||
|
|
1d42e9ad55 | ||
|
|
78f354beb8 | ||
|
|
e012f046bc | ||
|
|
f63b7b079d | ||
|
|
d530f9332c | ||
|
|
10bc86ba10 | ||
|
|
15b608f74c | ||
|
|
7c52af0dec | ||
|
|
cd97237c59 | ||
|
|
965e9767e5 | ||
|
|
41a7000745 | ||
|
|
9cdc1ef6c2 | ||
|
|
4db81065ee | ||
|
|
4653e8aec0 | ||
|
|
ac002b6338 | ||
|
|
9eea3a673a | ||
|
|
d6d2f5ced2 | ||
|
|
887e086890 | ||
|
|
8602d1ba17 | ||
|
|
dd90135944 | ||
|
|
612701a706 | ||
|
|
503532cf77 | ||
|
|
6c0e522922 | ||
|
|
9d37276986 | ||
|
|
5a4cd09938 | ||
|
|
c32fe26b8d | ||
|
|
2c3c4ec323 | ||
|
|
f451a7ad79 | ||
|
|
07953b36b0 | ||
|
|
387c69b194 | ||
|
|
a9d9af53e9 | ||
|
|
8a07f1202c | ||
|
|
41b65af6e2 | ||
|
|
884842cd6c | ||
|
|
8076d66ae5 | ||
|
|
64e3ceec3b | ||
|
|
672cdfa57a | ||
|
|
e39f33e41b | ||
|
|
6667440aaf | ||
|
|
ab5c7e6863 | ||
|
|
08c386f363 | ||
|
|
937a672879 | ||
|
|
513995f57d | ||
|
|
db6fd6db3e | ||
|
|
da930affd2 | ||
|
|
996836b67e | ||
|
|
fc7678c115 | ||
|
|
b371dc2d1e | ||
|
|
56e9454f1f | ||
|
|
d67daa8314 | ||
|
|
f0120e90b6 | ||
|
|
ec4558be29 | ||
|
|
685ab357cc | ||
|
|
5792f30175 | ||
|
|
24443b6764 | ||
|
|
154edf0427 | ||
|
|
4778cf88e2 | ||
|
|
38bd4f65d0 | ||
|
|
0b808f6428 | ||
|
|
b2bc2e1173 | ||
|
|
80787ff7ef | ||
|
|
b92a89f325 | ||
|
|
902292f776 | ||
|
|
3dcf098468 | ||
|
|
d89f0965aa | ||
|
|
c8d98f4787 | ||
|
|
0207b46d70 | ||
|
|
aa2a9fbedb | ||
|
|
3596b4feda | ||
|
|
51deeff72e | ||
|
|
4c227cc6bd | ||
|
|
2426657daa | ||
|
|
e1b03d0235 | ||
|
|
f1b3e9df1e | ||
|
|
fcc87edb71 | ||
|
|
8b464331ba | ||
|
|
9f57920566 | ||
|
|
933ca9ddd8 | ||
|
|
74e36e4456 | ||
|
|
4382bfe848 | ||
|
|
b6f250f5c9 | ||
|
|
5d69545299 | ||
|
|
139fad0c05 | ||
|
|
99946a3993 | ||
|
|
053cb27fe3 | ||
|
|
25017978e7 | ||
|
|
f749863cb2 | ||
|
|
123f9cf987 | ||
|
|
a758b40e3f | ||
|
|
44e5e99aae | ||
|
|
be53c4838b | ||
|
|
0c7b016fa7 | ||
|
|
00665766da | ||
|
|
88b4283200 | ||
|
|
d2bd0d1c1c | ||
|
|
25441d44f6 | ||
|
|
a025392a30 | ||
|
|
ad5f5ef2a3 | ||
|
|
40e669eacb | ||
|
|
ad3a331ca3 | ||
|
|
3c9e1693d5 | ||
|
|
8bc03dc6c4 | ||
|
|
2152f00de2 | ||
|
|
94aae05d45 | ||
|
|
0dbf2b1d3c | ||
|
|
59b23b8c13 | ||
|
|
5979b195fe | ||
|
|
a1cff23377 | ||
|
|
c82fc1ef71 | ||
|
|
740f93f5a9 | ||
|
|
d4caa97b88 | ||
|
|
c2ca7b7659 | ||
|
|
59edda6ca5 | ||
|
|
1668bc33c3 | ||
|
|
01f1e3fef8 | ||
|
|
27aa85f84b | ||
|
|
33c9c48318 | ||
|
|
63f16e4616 | ||
|
|
cb6dd34b98 | ||
|
|
27727e6926 | ||
|
|
a968ddc78c | ||
|
|
f70462aeb2 | ||
|
|
3aa92c76cc | ||
|
|
fc6a66836a | ||
|
|
31167da1a9 | ||
|
|
7db2ada880 | ||
|
|
e31bbe329a | ||
|
|
8946c87011 | ||
|
|
a9ef659bcb | ||
|
|
35c2149dbd | ||
|
|
89a35f9fcd | ||
|
|
1a4e99dc2d | ||
|
|
cb870f6fd6 | ||
|
|
a0c0c294c5 | ||
|
|
fbdb7eeda3 | ||
|
|
1bc0fccc8c | ||
|
|
20252c6483 | ||
|
|
e396912ea2 | ||
|
|
5ebfa78f56 | ||
|
|
950609f578 | ||
|
|
4a44d95f09 | ||
|
|
36718948be | ||
|
|
21bd4c4a9d | ||
|
|
998c9792da | ||
|
|
ccd77d70db | ||
|
|
d75a946707 | ||
|
|
696a20f10d | ||
|
|
224c91b6c1 | ||
|
|
8065e27a7d | ||
|
|
584e253f33 | ||
|
|
fb5e08e4ec | ||
|
|
e3d328f741 | ||
|
|
8922f08fbf | ||
|
|
15a4074d1a | ||
|
|
c624b43739 | ||
|
|
a8e040b133 | ||
|
|
5e30f3a48b | ||
|
|
46570a4eb6 | ||
|
|
01b84074d7 | ||
|
|
7aba2dc5f2 | ||
|
|
12a6728c4e | ||
|
|
042c228c7b | ||
|
|
e2b00814a8 | ||
|
|
104d385ba9 | ||
|
|
fdbbef2991 | ||
|
|
f8edf05c3c | ||
|
|
a9d0ddea9d | ||
|
|
313e4974a4 | ||
|
|
dd3b81dec6 | ||
|
|
d5afe16bc8 | ||
|
|
212ce4608e | ||
|
|
fbc5ecf75a | ||
|
|
a7d06167a0 | ||
|
|
9686379884 | ||
|
|
82e8ebd77d | ||
|
|
0b50880b4f | ||
|
|
316245ee12 | ||
|
|
63b92ead4e | ||
|
|
a14555a39e | ||
|
|
6d0bb58d68 | ||
|
|
33c163f648 | ||
|
|
b6c72c84d4 | ||
|
|
327e94a759 | ||
|
|
6fb7de7787 | ||
|
|
d338e45033 | ||
|
|
b106cd9476 | ||
|
|
9a91a7a4dc | ||
|
|
fa30960b8b | ||
|
|
8ceb4b0492 | ||
|
|
aad5d6e122 | ||
|
|
77552d9e69 | ||
|
|
93105f1a6d | ||
|
|
d7eb80b050 | ||
|
|
0a5a1f3687 | ||
|
|
e7d6dd2ea2 | ||
|
|
28943bcebb | ||
|
|
18f00457f6 | ||
|
|
e4a91a89e0 | ||
|
|
3693bde2dd | ||
|
|
67438f3ff9 | ||
|
|
371d25944d | ||
|
|
5c863b74d7 | ||
|
|
6de708af37 | ||
|
|
b9b2a4f7f8 | ||
|
|
b46c7944c6 | ||
|
|
866cd4a975 | ||
|
|
e24b255350 | ||
|
|
efed55f42d | ||
|
|
8c2b76eff9 | ||
|
|
b636e97e3b | ||
|
|
35d7f316ef | ||
|
|
43807c26fb | ||
|
|
774feeadb8 | ||
|
|
d96c59f9e6 | ||
|
|
dfd6418878 | ||
|
|
87e8aca245 | ||
|
|
14e1311bdf | ||
|
|
ff3c2ed7a2 | ||
|
|
f8602aca96 | ||
|
|
9a58270b70 | ||
|
|
f639a30bd2 | ||
|
|
082013c20f | ||
|
|
c7d2837184 | ||
|
|
caaa753861 | ||
|
|
4b949f6686 | ||
|
|
e9d9d5a9d2 | ||
|
|
f473b4db38 | ||
|
|
b0df5d7b55 | ||
|
|
be8c75bae1 | ||
|
|
58bea676ac | ||
|
|
9aab1f3661 | ||
|
|
10a1523ee6 | ||
|
|
d46eb69320 | ||
|
|
3a3666a94e | ||
|
|
2f568b9357 | ||
|
|
c94624f36c | ||
|
|
dec359ce58 | ||
|
|
1a054e869e | ||
|
|
7889192cae | ||
|
|
f7841bc8b8 | ||
|
|
aa6eb0d5be | ||
|
|
87a7426598 | ||
|
|
8d0422b6f3 | ||
|
|
e7ce1051fe | ||
|
|
80d5f23fee | ||
|
|
d51caaf358 | ||
|
|
835d130ccf | ||
|
|
e1013bd56d | ||
|
|
13d41778b3 | ||
|
|
bab416465f | ||
|
|
29a1e71705 | ||
|
|
7b2eb4b5ff | ||
|
|
343bf6d7a5 | ||
|
|
ba42cbad3f | ||
|
|
86406e71ec | ||
|
|
9e927ecc9a | ||
|
|
509896a410 | ||
|
|
7fe7c39a01 | ||
|
|
2c5e23506b | ||
|
|
07f35ea2c9 | ||
|
|
57a9519c3d | ||
|
|
9e4c4c995c | ||
|
|
d11c82f8ca | ||
|
|
bc27966a19 | ||
|
|
8f39491e96 | ||
|
|
065c50ebde | ||
|
|
d2e7c4af20 | ||
|
|
033d8d9405 | ||
|
|
b0799105c2 | ||
|
|
860aa9531b | ||
|
|
2547542873 | ||
|
|
3f8f0e246e | ||
|
|
12227ebbb0 | ||
|
|
1b4bd7082b | ||
|
|
0b6c185818 | ||
|
|
bfd0ac7f4b | ||
|
|
1a8f2ecc65 | ||
|
|
dc9e1ff0b1 | ||
|
|
ea10498902 | ||
|
|
69636dad69 | ||
|
|
3ee1b0d00d | ||
|
|
1e3ca4c6f7 | ||
|
|
839f4361f4 | ||
|
|
ae5c3ee8a1 | ||
|
|
77f7ae5ba2 | ||
|
|
2d0f8bcff5 | ||
|
|
f97e107c09 | ||
|
|
e9932e1314 | ||
|
|
eaa84d32df | ||
|
|
6e4aa0326f | ||
|
|
f9a4b36dd1 | ||
|
|
3acb5a329e | ||
|
|
6d94242318 | ||
|
|
bca83cb9df | ||
|
|
a841d45bc3 | ||
|
|
eb93d92357 | ||
|
|
a0250ec923 | ||
|
|
25801627be | ||
|
|
32ae994f88 | ||
|
|
03aec89f60 | ||
|
|
faf0190546 | ||
|
|
c8b0f685ee | ||
|
|
87b99162fb | ||
|
|
940887f20f | ||
|
|
0b2573c3fa | ||
|
|
157521066f | ||
|
|
f766babf5e | ||
|
|
436a29367c | ||
|
|
55418fd460 |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -50,7 +50,7 @@ jobs:
|
||||
OPTIONS: ${{ matrix.options }}
|
||||
SCRIPT: ${{ matrix.script }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Perform uglify, build & test
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -7,22 +7,18 @@ jobs:
|
||||
test:
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', '14', latest ]
|
||||
node: [ '0.10', '0.12', '4', '6', '8', '10', '12', '14', '16', latest ]
|
||||
os: [ ubuntu-latest, windows-latest ]
|
||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||
exclude:
|
||||
- node: '0.8'
|
||||
script: release/benchmark
|
||||
- node: '0.8'
|
||||
script: release/jetstream
|
||||
name: ${{ matrix.node }} ${{ matrix.os }} ${{ matrix.script }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
TYPE: ${{ matrix.script }}
|
||||
UGLIFY_GITHUB_LAG: 10000
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/cache@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: tmp
|
||||
key: tmp ${{ matrix.script }}
|
||||
|
||||
8
.github/workflows/ufuzz.yml
vendored
8
.github/workflows/ufuzz.yml
vendored
@@ -17,13 +17,13 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- node: latest
|
||||
- node: '16'
|
||||
os: macos-latest
|
||||
- node: '8'
|
||||
- node: '12'
|
||||
os: ubuntu-latest
|
||||
- node: '8'
|
||||
os: ubuntu-latest
|
||||
- node: '8'
|
||||
- node: '12'
|
||||
os: windows-latest
|
||||
- node: '8'
|
||||
os: windows-latest
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
env:
|
||||
NODE: ${{ matrix.node }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Perform fuzzing
|
||||
shell: bash
|
||||
run: |
|
||||
|
||||
155
README.md
155
README.md
@@ -54,8 +54,6 @@ a double dash to prevent input files being used as option arguments:
|
||||
modules and Userscripts that may
|
||||
be anonymous function wrapped (IIFE)
|
||||
by the .user.js engine `caller`.
|
||||
`expression` Parse a single expression, rather than
|
||||
a program (for parsing JSON).
|
||||
`spidermonkey` Assume input files are SpiderMonkey
|
||||
AST format (as JSON).
|
||||
-c, --compress [options] Enable compressor/specify compressor options:
|
||||
@@ -111,12 +109,16 @@ a double dash to prevent input files being used as option arguments:
|
||||
-d, --define <expr>[=value] Global definitions.
|
||||
-e, --enclose [arg[:value]] Embed everything in a big function, with configurable
|
||||
argument(s) & value(s).
|
||||
--expression Parse a single expression, rather than a program
|
||||
(for parsing JSON).
|
||||
--ie Support non-standard Internet Explorer.
|
||||
Equivalent to setting `ie: true` in `minify()`
|
||||
for `compress`, `mangle` and `output` options.
|
||||
By default UglifyJS will not try to be IE-proof.
|
||||
--keep-fargs Do not mangle/drop function arguments.
|
||||
--keep-fnames Do not mangle/drop function names. Useful for
|
||||
code relying on Function.prototype.name.
|
||||
--module Process input as ES module (implies --toplevel)
|
||||
--name-cache <file> File to hold mangled name mappings.
|
||||
--self Build UglifyJS as a library (implies --wrap UglifyJS)
|
||||
--source-map [options] Enable source map/specify source map options:
|
||||
@@ -145,7 +147,7 @@ a double dash to prevent input files being used as option arguments:
|
||||
--warn Print warning messages.
|
||||
--webkit Support non-standard Safari/Webkit.
|
||||
Equivalent to setting `webkit: true` in `minify()`
|
||||
for `mangle` and `output` options.
|
||||
for `compress`, `mangle` and `output` options.
|
||||
By default UglifyJS will not try to be Safari-proof.
|
||||
--wrap <name> Embed everything in a big function, making the
|
||||
“exports” and “global” variables available. You
|
||||
@@ -325,7 +327,7 @@ unquoted style (`o.foo`). Example:
|
||||
// stuff.js
|
||||
var o = {
|
||||
"foo": 1,
|
||||
bar: 3
|
||||
bar: 3,
|
||||
};
|
||||
o.foo += o.bar;
|
||||
console.log(o.foo);
|
||||
@@ -337,6 +339,16 @@ $ uglifyjs stuff.js --mangle-props keep_quoted -c -m
|
||||
var o={foo:1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
If the minified output will be processed again by UglifyJS, consider specifying
|
||||
`keep_quoted_props` so the same property names are preserved:
|
||||
|
||||
```bash
|
||||
$ uglifyjs stuff.js --mangle-props keep_quoted -c -m -O keep_quoted_props
|
||||
```
|
||||
```javascript
|
||||
var o={"foo":1,o:3};o.foo+=o.o,console.log(o.foo);
|
||||
```
|
||||
|
||||
### Debugging property name mangling
|
||||
|
||||
You can also pass `--mangle-props debug` in order to mangle property names
|
||||
@@ -502,8 +514,13 @@ if (result.error) throw result.error;
|
||||
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||
Pass an object to specify custom [compress options](#compress-options).
|
||||
|
||||
- `expression` (default: `false`) — parse as a single expression, e.g. JSON.
|
||||
|
||||
- `ie` (default: `false`) — enable workarounds for Internet Explorer bugs.
|
||||
|
||||
- `keep_fargs` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||
of function arguments.
|
||||
|
||||
- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||
of function names. Useful for code relying on `Function.prototype.name`.
|
||||
|
||||
@@ -513,6 +530,10 @@ if (result.error) throw result.error;
|
||||
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
|
||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`,
|
||||
alongside with `toplevel` enabled.
|
||||
|
||||
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||
used `nameCache` object if you wish to cache mangled variable and
|
||||
property names across multiple invocations of `minify()`. Note: this is
|
||||
@@ -624,7 +645,11 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||
|
||||
- `html5_comments` (default: `true`)
|
||||
- `html5_comments` (default: `true`) — process HTML comment as workaround for
|
||||
browsers which do not recognise `<script>` tags
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` and support for top-level `await`.
|
||||
|
||||
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||
|
||||
@@ -707,7 +732,8 @@ to be `false` and all symbol names will be omitted.
|
||||
- `1` — inline simple functions
|
||||
- `2` — inline functions with arguments
|
||||
- `3` — inline functions with arguments and variables
|
||||
- `true` — same as `3`
|
||||
- `4` — inline functions with arguments, variables and statements
|
||||
- `true` — same as `4`
|
||||
|
||||
- `join_vars` (default: `true`) — join consecutive `var` statements
|
||||
|
||||
@@ -723,6 +749,9 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `merge_vars` (default: `true`) — combine and reuse variables.
|
||||
|
||||
- `module` (default: `false`) — set to `true` if you wish to process input as
|
||||
ES module, i.e. implicit `"use strict";` alongside with `toplevel` enabled.
|
||||
|
||||
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
|
||||
where the return value is discarded, to avoid the parens that the
|
||||
code generator would insert.
|
||||
@@ -799,8 +828,9 @@ to be `false` and all symbol names will be omitted.
|
||||
|
||||
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||
|
||||
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
||||
none of the operands can be (coerced to) `NaN`.
|
||||
- `unsafe_comps` (default: `false`) — assume operands cannot be (coerced to) `NaN`
|
||||
in numeric comparisons, e.g. `a <= b`. In addition, expressions involving `in`
|
||||
or `instanceof` would never throw.
|
||||
|
||||
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||
when both `args` and `code` are string literals.
|
||||
@@ -867,6 +897,9 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
||||
- `debug` (default: `false`) — Mangle names with the original name still present.
|
||||
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
||||
|
||||
- `keep_fargs` (default: `false`) — Use `true` to prevent mangling of function
|
||||
arguments.
|
||||
|
||||
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
|
||||
|
||||
- `regex` (default: `null`) — Pass a RegExp literal to only mangle property
|
||||
@@ -907,11 +940,16 @@ can pass additional arguments that control the code output:
|
||||
}
|
||||
```
|
||||
|
||||
- `extendscript` (default: `false`) — enable workarounds for Adobe ExtendScript
|
||||
bugs
|
||||
|
||||
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
|
||||
|
||||
- `indent_level` (default: `4`)
|
||||
- `indent_level` (default: `4`) — indent by specified number of spaces or the
|
||||
exact whitespace sequence supplied, e.g. `"\t"`.
|
||||
|
||||
- `indent_start` (default: `0`) — prefix all lines by that many spaces
|
||||
- `indent_start` (default: `0`) — prefix all lines by whitespace sequence
|
||||
specified in the same format as `indent_level`.
|
||||
|
||||
- `inline_script` (default: `true`) — escape HTML comments and the slash in
|
||||
occurrences of `</script>` in strings
|
||||
@@ -1199,6 +1237,17 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
- Object properties can be added, removed and modified (not prevented with
|
||||
`Object.defineProperty()`, `Object.defineProperties()`, `Object.freeze()`,
|
||||
`Object.preventExtensions()` or `Object.seal()`).
|
||||
- If array destructuring is present, index-like properties in `Array.prototype`
|
||||
have not been overridden:
|
||||
```javascript
|
||||
Object.prototype[0] = 42;
|
||||
var [ a ] = [];
|
||||
var { 0: b } = {};
|
||||
// 42 undefined
|
||||
console.log([][0], a);
|
||||
// 42 42
|
||||
console.log({}[0], b);
|
||||
```
|
||||
- Earlier versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
({
|
||||
@@ -1310,10 +1359,8 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
var await;
|
||||
async function f() {
|
||||
class A {
|
||||
static p = await;
|
||||
}
|
||||
class A {
|
||||
static p = await;
|
||||
}
|
||||
// SyntaxError: Unexpected reserved word
|
||||
```
|
||||
@@ -1325,7 +1372,7 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// SyntaxError: The left-hand side of a for-of loop may not be 'async'.
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
console.log({
|
||||
@@ -1334,9 +1381,15 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
return "FAIL";
|
||||
},
|
||||
[42]: "PASS",
|
||||
}[42], {
|
||||
...console,
|
||||
get 42() {
|
||||
return "FAIL";
|
||||
},
|
||||
42: "PASS",
|
||||
}[42]);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
// Expected: "PASS PASS"
|
||||
// Actual: "PASS FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Earlier versions of JavaScript will throw `TypeError` with the following:
|
||||
@@ -1352,3 +1405,71 @@ To allow for better optimizations, the compiler makes various assumptions:
|
||||
// TypeError: const 'a' has already been declared
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
try {
|
||||
class A {
|
||||
static 42;
|
||||
static get 42() {}
|
||||
}
|
||||
console.log("PASS");
|
||||
} catch (e) {
|
||||
console.log("FAIL");
|
||||
}
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Some versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
(async function(a) {
|
||||
(function() {
|
||||
var b = await => console.log("PASS");
|
||||
b();
|
||||
})();
|
||||
})().catch(console.error);
|
||||
// Expected: "PASS"
|
||||
// Actual: SyntaxError: Unexpected reserved word
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of Chrome and Node.js will give incorrect results with the
|
||||
following:
|
||||
```javascript
|
||||
try {
|
||||
f();
|
||||
function f() {
|
||||
throw 42;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(typeof f, e);
|
||||
}
|
||||
// Expected: "function 42"
|
||||
// Actual: "undefined 42"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||
```javascript
|
||||
"use strict";
|
||||
console.log(function f() {
|
||||
return f = "PASS";
|
||||
}());
|
||||
// Expected: "PASS"
|
||||
// Actual: TypeError: invalid assignment to const 'f'
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(true ? "PASS" : false ? "FAIL" : null);
|
||||
// Expected: "PASS"
|
||||
// Actual: "FAIL"
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
- Adobe ExtendScript will give incorrect results with the following:
|
||||
```javascript
|
||||
alert(42 ? null ? "FAIL" : "PASS" : "FAIL");
|
||||
// Expected: "PASS"
|
||||
// Actual: SyntaxError: Expected: :
|
||||
```
|
||||
UglifyJS may modify the input which in turn may suppress those errors.
|
||||
|
||||
86
bin/uglifyjs
86
bin/uglifyjs
@@ -10,7 +10,9 @@ var info = require("../package.json");
|
||||
var path = require("path");
|
||||
var UglifyJS = require("../tools/node");
|
||||
|
||||
var skip_keys = [ "cname", "fixed", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||
var skip_keys = [ "cname", "fixed", "in_arg", "inlined", "length_read", "parent_scope", "redef", "scope", "unused" ];
|
||||
var truthy_keys = [ "optional", "pure", "terminal", "uses_arguments", "uses_eval", "uses_with" ];
|
||||
|
||||
var files = {};
|
||||
var options = {};
|
||||
var short_forms = {
|
||||
@@ -70,6 +72,7 @@ function process_option(name, no_value) {
|
||||
} else {
|
||||
if (padding.length < name.length) padding = Array(name.length + 1).join(" ");
|
||||
toplevels.push([ {
|
||||
keep_fargs: "keep-fargs",
|
||||
keep_fnames: "keep-fnames",
|
||||
nameCache: "name-cache",
|
||||
}[name] || name, option ]);
|
||||
@@ -101,8 +104,11 @@ function process_option(name, no_value) {
|
||||
" --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).",
|
||||
" --expression Parse a single expression, rather than a program.",
|
||||
" --ie Support non-standard Internet Explorer.",
|
||||
" --keep-fargs Do not mangle/drop function arguments.",
|
||||
" --keep-fnames Do not mangle/drop function names. Useful for code relying on Function.prototype.name.",
|
||||
" --module Process input as ES module (implies --toplevel)",
|
||||
" --name-cache <file> File to hold mangled name mappings.",
|
||||
" --rename Force symbol expansion.",
|
||||
" --no-rename Disable symbol expansion.",
|
||||
@@ -146,8 +152,10 @@ function process_option(name, no_value) {
|
||||
options[name] = read_value();
|
||||
break;
|
||||
case "annotations":
|
||||
case "expression":
|
||||
case "ie":
|
||||
case "ie8":
|
||||
case "module":
|
||||
case "timings":
|
||||
case "toplevel":
|
||||
case "v8":
|
||||
@@ -158,6 +166,9 @@ function process_option(name, no_value) {
|
||||
case "no-annotations":
|
||||
options.annotations = false;
|
||||
break;
|
||||
case "keep-fargs":
|
||||
options.keep_fargs = true;
|
||||
break;
|
||||
case "keep-fnames":
|
||||
options.keep_fnames = true;
|
||||
break;
|
||||
@@ -267,6 +278,8 @@ if (specified["self"]) {
|
||||
if (paths.length) UglifyJS.AST_Node.warn("Ignoring input files since --self was passed");
|
||||
if (!options.wrap) options.wrap = "UglifyJS";
|
||||
paths = UglifyJS.FILES;
|
||||
} else if (paths.length) {
|
||||
paths = simple_glob(paths);
|
||||
}
|
||||
if (specified["in-situ"]) {
|
||||
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
|
||||
@@ -281,7 +294,7 @@ if (specified["in-situ"]) {
|
||||
run();
|
||||
});
|
||||
} else if (paths.length) {
|
||||
simple_glob(paths).forEach(function(name) {
|
||||
paths.forEach(function(name) {
|
||||
files[convert_path(name)] = read_file(name);
|
||||
});
|
||||
run();
|
||||
@@ -430,7 +443,7 @@ function run() {
|
||||
case "thedef":
|
||||
return symdef(value);
|
||||
}
|
||||
if (skip_key(key)) return;
|
||||
if (skip_property(key, value)) return;
|
||||
if (value instanceof UglifyJS.AST_Token) return;
|
||||
if (value instanceof UglifyJS.Dictionary) return;
|
||||
if (value instanceof UglifyJS.AST_Node) {
|
||||
@@ -480,33 +493,42 @@ function fatal(message) {
|
||||
|
||||
// A file glob function that only supports "*" and "?" wildcards in the basename.
|
||||
// Example: "foo/bar/*baz??.*.js"
|
||||
// Argument `glob` may be a string or an array of strings.
|
||||
// Argument `paths` must be an array of strings.
|
||||
// Returns an array of strings. Garbage in, garbage out.
|
||||
function simple_glob(glob) {
|
||||
if (Array.isArray(glob)) {
|
||||
return [].concat.apply([], glob.map(simple_glob));
|
||||
}
|
||||
if (glob.match(/\*|\?/)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir);
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.sort().filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) return results;
|
||||
function simple_glob(paths) {
|
||||
return paths.reduce(function(paths, glob) {
|
||||
if (/\*|\?/.test(glob)) {
|
||||
var dir = path.dirname(glob);
|
||||
try {
|
||||
var entries = fs.readdirSync(dir).filter(function(name) {
|
||||
try {
|
||||
return fs.statSync(path.join(dir, name)).isFile();
|
||||
} catch (ex) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
} catch (ex) {}
|
||||
if (entries) {
|
||||
var pattern = "^" + path.basename(glob)
|
||||
.replace(/[.+^$[\]\\(){}]/g, "\\$&")
|
||||
.replace(/\*/g, "[^/\\\\]*")
|
||||
.replace(/\?/g, "[^/\\\\]") + "$";
|
||||
var mod = process.platform === "win32" ? "i" : "";
|
||||
var rx = new RegExp(pattern, mod);
|
||||
var results = entries.filter(function(name) {
|
||||
return rx.test(name);
|
||||
}).sort().map(function(name) {
|
||||
return path.join(dir, name);
|
||||
});
|
||||
if (results.length) {
|
||||
[].push.apply(paths, results);
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return [ glob ];
|
||||
paths.push(glob);
|
||||
return paths;
|
||||
}, []);
|
||||
}
|
||||
|
||||
function read_file(path, default_value) {
|
||||
@@ -519,7 +541,7 @@ function read_file(path, default_value) {
|
||||
}
|
||||
|
||||
function parse_js(value, options, flag) {
|
||||
if (!options || typeof options != "object") options = {};
|
||||
if (!options || typeof options != "object") options = Object.create(null);
|
||||
if (typeof value == "string") try {
|
||||
UglifyJS.parse(value, {
|
||||
expression: true
|
||||
@@ -559,8 +581,10 @@ function parse_js(value, options, flag) {
|
||||
return options;
|
||||
}
|
||||
|
||||
function skip_key(key) {
|
||||
return skip_keys.indexOf(key) >= 0;
|
||||
function skip_property(key, value) {
|
||||
return skip_keys.indexOf(key) >= 0
|
||||
// only skip truthy_keys if their value is falsy
|
||||
|| truthy_keys.indexOf(key) >= 0 && !value;
|
||||
}
|
||||
|
||||
function symdef(def) {
|
||||
|
||||
464
lib/ast.js
464
lib/ast.js
@@ -50,6 +50,8 @@ function DEFNODE(type, props, methods, base) {
|
||||
if (base && base.PROPS) props = props.concat(base.PROPS);
|
||||
var code = [
|
||||
"return function AST_", type, "(props){",
|
||||
// not essential, but speeds up compress by a few percent
|
||||
"this._bits=0;",
|
||||
"if(props){",
|
||||
];
|
||||
props.forEach(function(prop) {
|
||||
@@ -107,6 +109,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
start: "[AST_Token] The first token of this node",
|
||||
end: "[AST_Token] The last token of this node"
|
||||
},
|
||||
equals: function(node) {
|
||||
return this.TYPE == node.TYPE && this._equals(node);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
visitor.visit(this);
|
||||
},
|
||||
@@ -123,18 +128,63 @@ var AST_Node = DEFNODE("Node", "start end", {
|
||||
var marker = {};
|
||||
this.walk(new TreeWalker(function(node) {
|
||||
if (node.validate_visited === marker) {
|
||||
throw new Error(string_template("cannot reuse {type} from [{file}:{line},{col}]", {
|
||||
type: "AST_" + node.TYPE,
|
||||
file: node.start.file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
}));
|
||||
throw new Error(string_template("cannot reuse AST_{TYPE} from [{start}]", node));
|
||||
}
|
||||
node.validate_visited = marker;
|
||||
}));
|
||||
},
|
||||
}, null);
|
||||
|
||||
DEF_BITPROPS(AST_Node, [
|
||||
// AST_Node
|
||||
"_optimized",
|
||||
"_squeezed",
|
||||
// AST_Call
|
||||
"call_only",
|
||||
// AST_Lambda
|
||||
"collapse_scanning",
|
||||
// AST_SymbolRef
|
||||
"defined",
|
||||
"evaluating",
|
||||
"falsy",
|
||||
// AST_SymbolRef
|
||||
"in_arg",
|
||||
// AST_Return
|
||||
"in_bool",
|
||||
// AST_SymbolRef
|
||||
"is_undefined",
|
||||
// AST_LambdaExpression
|
||||
// AST_LambdaDefinition
|
||||
"inlined",
|
||||
// AST_Lambda
|
||||
"length_read",
|
||||
// AST_Yield
|
||||
"nested",
|
||||
// AST_Lambda
|
||||
"new",
|
||||
// AST_Call
|
||||
// AST_PropAccess
|
||||
"optional",
|
||||
// AST_ClassProperty
|
||||
"private",
|
||||
// AST_Call
|
||||
"pure",
|
||||
// AST_Assign
|
||||
"redundant",
|
||||
// AST_Node
|
||||
"single_use",
|
||||
// AST_ClassProperty
|
||||
"static",
|
||||
// AST_Call
|
||||
// AST_PropAccess
|
||||
"terminal",
|
||||
"truthy",
|
||||
// AST_Scope
|
||||
"uses_eval",
|
||||
// AST_Scope
|
||||
"uses_with",
|
||||
]);
|
||||
|
||||
(AST_Node.log_function = function(fn, verbose) {
|
||||
if (typeof fn != "function") {
|
||||
AST_Node.info = AST_Node.warn = noop;
|
||||
@@ -182,6 +232,24 @@ AST_Node.disable_validation = function() {
|
||||
while (restore = restore_transforms.pop()) restore();
|
||||
};
|
||||
|
||||
function all_equals(k, l) {
|
||||
return k.length == l.length && all(k, function(m, i) {
|
||||
return m.equals(l[i]);
|
||||
});
|
||||
}
|
||||
|
||||
function list_equals(s, t) {
|
||||
return s.length == t.length && all(s, function(u, i) {
|
||||
return u == t[i];
|
||||
});
|
||||
}
|
||||
|
||||
function prop_equals(u, v) {
|
||||
if (u === v) return true;
|
||||
if (u == null) return v == null;
|
||||
return u instanceof AST_Node && v instanceof AST_Node && u.equals(v);
|
||||
}
|
||||
|
||||
/* -----[ statements ]----- */
|
||||
|
||||
var AST_Statement = DEFNODE("Statement", null, {
|
||||
@@ -193,6 +261,7 @@ var AST_Statement = DEFNODE("Statement", null, {
|
||||
|
||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||
$documentation: "Represents a debugger statement",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
@@ -201,6 +270,9 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
quote: "[string?] the original quote character",
|
||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.value == node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
@@ -211,7 +283,8 @@ var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, {
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)"
|
||||
$documentation: "The empty statement (empty block or simply a semicolon)",
|
||||
_equals: return_true,
|
||||
}, AST_Statement);
|
||||
|
||||
function is_statement(node) {
|
||||
@@ -242,6 +315,9 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -253,7 +329,7 @@ var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_scope variables", {
|
||||
var AST_BlockScope = DEFNODE("BlockScope", "_var_names enclosed functions make_def parent_scope variables", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
$propdoc: {
|
||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||
@@ -293,6 +369,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Statement*] an array of statements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -327,6 +406,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_Label] a label definition"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.label.equals(node.label)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -368,6 +451,10 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||
$propdoc: {
|
||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||
must_be_expression(this, "condition");
|
||||
@@ -382,7 +469,7 @@ var AST_Do = DEFNODE("Do", null, {
|
||||
node.body.walk(visitor);
|
||||
node.condition.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_While = DEFNODE("While", null, {
|
||||
@@ -393,7 +480,7 @@ var AST_While = DEFNODE("While", null, {
|
||||
node.condition.walk(visitor);
|
||||
node.body.walk(visitor);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, AST_DWLoop);
|
||||
|
||||
var AST_For = DEFNODE("For", "init condition step", {
|
||||
@@ -403,6 +490,12 @@ var AST_For = DEFNODE("For", "init condition step", {
|
||||
condition: "[AST_Node?] the `for` termination clause, or null if empty",
|
||||
step: "[AST_Node?] the `for` update clause, or null if empty"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.init, node.init)
|
||||
&& prop_equals(this.condition, node.condition)
|
||||
&& prop_equals(this.step, node.step)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -430,6 +523,11 @@ var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
||||
init: "[AST_Node] the assignment target during iteration",
|
||||
object: "[AST_Node] the object to iterate over"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.init.equals(node.init)
|
||||
&& this.object.equals(node.object)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -470,6 +568,10 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `with` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -484,8 +586,8 @@ var AST_With = DEFNODE("With", "expression", {
|
||||
|
||||
/* -----[ scope and functions ]----- */
|
||||
|
||||
var AST_Scope = DEFNODE("Scope", "uses_eval uses_with", {
|
||||
$documentation: "Base class for all statements introducing a lexical scope",
|
||||
var AST_Scope = DEFNODE("Scope", "fn_defs may_call_this uses_eval uses_with", {
|
||||
$documentation: "Base class for all statements introducing a lambda scope",
|
||||
$propdoc: {
|
||||
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
||||
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
||||
@@ -543,13 +645,17 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||
}
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
||||
var AST_ClassInitBlock = DEFNODE("ClassInitBlock", null, {
|
||||
$documentation: "Value for `class` static initialization blocks",
|
||||
}, AST_Scope);
|
||||
|
||||
var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest safe_ids uses_arguments", {
|
||||
$documentation: "Base class for functions",
|
||||
$propdoc: {
|
||||
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
||||
length_read: "[boolean/S] whether length property of this function is accessed",
|
||||
rest: "[(AST_Destructured|AST_SymbolFunarg)?] rest parameter, or null if absent",
|
||||
uses_arguments: "[boolean/S] whether this function accesses the arguments array",
|
||||
uses_arguments: "[boolean|number/S] whether this function accesses the arguments array",
|
||||
},
|
||||
each_argname: function(visit) {
|
||||
var tw = new TreeWalker(function(node) {
|
||||
@@ -568,6 +674,13 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
||||
});
|
||||
if (this.rest) this.rest.walk(tw);
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.value, node.value)
|
||||
&& all_equals(this.argnames, node.argnames)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -778,6 +891,14 @@ var AST_Class = DEFNODE("Class", "extends name properties", {
|
||||
extends: "[AST_Node?] the super class, or null if not specified",
|
||||
properties: "[AST_ClassProperty*] array of class properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.name, node.name)
|
||||
&& prop_equals(this.extends, node.extends)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
resolve: function(def_class) {
|
||||
return def_class ? this : this.parent_scope.resolve();
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -822,11 +943,17 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||
var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
$documentation: "Base class for `class` properties",
|
||||
$propdoc: {
|
||||
key: "[string|AST_Node] property name (AST_Node for computed property)",
|
||||
key: "[string|AST_Node?] property name (AST_Node for computed property, null for initialization block)",
|
||||
private: "[boolean] whether this is a private property",
|
||||
static: "[boolean] whether this is a static property",
|
||||
value: "[AST_Node?] property value (AST_Accessor for getters/setters, AST_LambdaExpression for methods, null if not specified for fields)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.private == !node.private
|
||||
&& !this.static == !node.static
|
||||
&& prop_equals(this.key, node.key)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -836,7 +963,9 @@ var AST_ClassProperty = DEFNODE("ClassProperty", "key private static value", {
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty");
|
||||
if (typeof this.key != "string") {
|
||||
if (this instanceof AST_ClassInit) {
|
||||
if (this.key != null) throw new Error("key must be null");
|
||||
} else if (typeof this.key != "string") {
|
||||
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
||||
must_be_expression(this, "key");
|
||||
}
|
||||
@@ -876,6 +1005,17 @@ var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
var AST_ClassInit = DEFNODE("ClassInit", null, {
|
||||
$documentation: "A `class` static initialization block",
|
||||
_validate: function() {
|
||||
if (!this.static) throw new Error("static must be true");
|
||||
if (!(this.value instanceof AST_ClassInitBlock)) throw new Error("value must be AST_ClassInitBlock");
|
||||
},
|
||||
initialize: function() {
|
||||
this.static = true;
|
||||
},
|
||||
}, AST_ClassProperty);
|
||||
|
||||
/* -----[ JUMPS ]----- */
|
||||
|
||||
var AST_Jump = DEFNODE("Jump", null, {
|
||||
@@ -890,6 +1030,9 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
||||
$propdoc: {
|
||||
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -920,6 +1063,9 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
||||
$propdoc: {
|
||||
label: "[AST_LabelRef?] the label, or null if none",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.label, node.label);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -950,6 +1096,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
||||
condition: "[AST_Node] the `if` condition",
|
||||
alternative: "[AST_Statement?] the `else` part, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body)
|
||||
&& this.condition.equals(node.condition)
|
||||
&& prop_equals(this.alternative, node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -973,6 +1124,10 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `switch` “discriminant”"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1004,6 +1159,10 @@ var AST_Case = DEFNODE("Case", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] the `case` expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1024,6 +1183,11 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
|
||||
bcatch: "[AST_Catch?] the catch block, or null if not present",
|
||||
bfinally: "[AST_Finally?] the finally block, or null if not present"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.body, node.body)
|
||||
&& prop_equals(this.bcatch, node.bcatch)
|
||||
&& prop_equals(this.bfinally, node.bfinally);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1047,6 +1211,10 @@ var AST_Catch = DEFNODE("Catch", "argname", {
|
||||
$propdoc: {
|
||||
argname: "[(AST_Destructured|AST_SymbolCatch)?] symbol for the exception, or null if not present",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.argname, node.argname)
|
||||
&& all_equals(this.body, node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1072,6 +1240,9 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
||||
$propdoc: {
|
||||
definitions: "[AST_VarDef*] array of variable definitions"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.definitions, node.definitions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1128,6 +1299,10 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolVar] name of the variable",
|
||||
value: "[AST_Node?] initializer, or null of there's no initializer",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& prop_equals(this.value, node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1147,6 +1322,9 @@ var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1167,6 +1345,9 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
$propdoc: {
|
||||
body: "[AST_Node] the default export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.body.equals(node.body);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1180,29 +1361,29 @@ var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path", {
|
||||
$documentation: "An `export ... from '...'` statement",
|
||||
$propdoc: {
|
||||
aliases: "[string*] array of aliases to export",
|
||||
keys: "[string*] array of keys to import",
|
||||
path: "[string] the path to import module",
|
||||
quote: "[string?] the original quote character",
|
||||
aliases: "[AST_String*] array of aliases to export",
|
||||
keys: "[AST_String*] array of keys to import",
|
||||
path: "[AST_String] the path to import module",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& all_equals(this.aliases, node.aliases)
|
||||
&& all_equals(this.keys, node.keys);
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.aliases.length != this.keys.length) {
|
||||
throw new Error("aliases:key length mismatch: " + this.aliases.length + " != " + this.keys.length);
|
||||
}
|
||||
this.aliases.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("aliases must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("aliases must contain AST_String");
|
||||
});
|
||||
this.keys.forEach(function(name) {
|
||||
if (typeof name != "string") throw new Error("keys must contain string");
|
||||
if (!(name instanceof AST_String)) throw new Error("keys must contain AST_String");
|
||||
});
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1211,6 +1392,9 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1226,14 +1410,20 @@ var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
var AST_Import = DEFNODE("Import", "all default path properties", {
|
||||
$documentation: "An `import` statement",
|
||||
$propdoc: {
|
||||
all: "[AST_SymbolImport?] the imported namespace, or null if not specified",
|
||||
default: "[AST_SymbolImport?] the alias for default `export`, or null if not specified",
|
||||
path: "[string] the path to import module",
|
||||
path: "[AST_String] the path to import module",
|
||||
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||
quote: "[string?] the original quote character",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.path.equals(node.path)
|
||||
&& prop_equals(this.all, node.all)
|
||||
&& prop_equals(this.default, node.default)
|
||||
&& !this.properties == !node.properties
|
||||
&& (!this.properties || all_equals(this.properties, node.properties));
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1252,16 +1442,12 @@ var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||
}
|
||||
if (this.default != null) {
|
||||
if (!(this.default instanceof AST_SymbolImport)) throw new Error("default must be AST_SymbolImport");
|
||||
if (this.default.key !== "") throw new Error("invalid default key: " + this.default.key);
|
||||
if (this.default.key.value !== "") throw new Error("invalid default key: " + this.default.key.value);
|
||||
}
|
||||
if (typeof this.path != "string") throw new Error("path must be string");
|
||||
if (!(this.path instanceof AST_String)) throw new Error("path must be AST_String");
|
||||
if (this.properties != null) this.properties.forEach(function(node) {
|
||||
if (!(node instanceof AST_SymbolImport)) throw new Error("properties must contain AST_SymbolImport");
|
||||
});
|
||||
if (this.quote != null) {
|
||||
if (typeof this.quote != "string") throw new Error("quote must be string");
|
||||
if (!/^["']$/.test(this.quote)) throw new Error("invalid quote: " + this.quote);
|
||||
}
|
||||
},
|
||||
}, AST_Statement);
|
||||
|
||||
@@ -1271,6 +1457,10 @@ var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
||||
name: "[AST_Destructured|AST_SymbolDeclaration] name of the variable",
|
||||
value: "[AST_Node] value to assign if variable is `undefined`",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name.equals(node.name)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1295,9 +1485,14 @@ var AST_Call = DEFNODE("Call", "args expression optional pure terminal", {
|
||||
args: "[AST_Node*] array of arguments",
|
||||
expression: "[AST_Node] expression to invoke as function",
|
||||
optional: "[boolean] whether the expression is optional chaining",
|
||||
pure: "[string/S] marker for side-effect-free call expression",
|
||||
pure: "[boolean/S] marker for side-effect-free call expression",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& this.expression.equals(node.expression)
|
||||
&& all_equals(this.args, node.args);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1324,7 +1519,10 @@ var AST_New = DEFNODE("New", null, {
|
||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||
$documentation: "A sequence expression (comma-separated expressions)",
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] array of expressions (at least two)"
|
||||
expressions: "[AST_Node*] array of expressions (at least two)",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1353,6 +1551,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
||||
terminal: "[boolean] whether the chain has ended",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.optional == !node.optional
|
||||
&& prop_equals(this.property, node.property)
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
get_property: function() {
|
||||
var p = this.property;
|
||||
if (p instanceof AST_Constant) return p.value;
|
||||
@@ -1365,8 +1568,11 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression optional property termina
|
||||
},
|
||||
});
|
||||
|
||||
var AST_Dot = DEFNODE("Dot", null, {
|
||||
var AST_Dot = DEFNODE("Dot", "quoted", {
|
||||
$documentation: "A dotted property access expression",
|
||||
$propdoc: {
|
||||
quoted: "[boolean] whether property is transformed from a quoted string",
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1397,6 +1603,9 @@ var AST_Spread = DEFNODE("Spread", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression to be expanded",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1412,7 +1621,11 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
||||
$documentation: "Base class for unary expressions",
|
||||
$propdoc: {
|
||||
operator: "[string] the operator",
|
||||
expression: "[AST_Node] expression that this unary operator applies to"
|
||||
expression: "[AST_Node] expression that this unary operator applies to",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1442,6 +1655,11 @@ var AST_Binary = DEFNODE("Binary", "operator left right", {
|
||||
operator: "[string] the operator",
|
||||
right: "[AST_Node] right-hand side expression"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.operator == node.operator
|
||||
&& this.left.equals(node.left)
|
||||
&& this.right.equals(node.right);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1463,6 +1681,11 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
|
||||
consequent: "[AST_Node]",
|
||||
alternative: "[AST_Node]"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.condition.equals(node.condition)
|
||||
&& this.consequent.equals(node.consequent)
|
||||
&& this.alternative.equals(node.alternative);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1489,6 +1712,12 @@ var AST_Assign = DEFNODE("Assign", null, {
|
||||
throw new Error("left must be assignable: " + node.TYPE);
|
||||
}
|
||||
});
|
||||
} else if (!(this.left instanceof AST_Infinity
|
||||
|| this.left instanceof AST_NaN
|
||||
|| this.left instanceof AST_PropAccess && !this.left.optional
|
||||
|| this.left instanceof AST_SymbolRef
|
||||
|| this.left instanceof AST_Undefined)) {
|
||||
throw new Error("left must be assignable");
|
||||
}
|
||||
},
|
||||
}, AST_Binary);
|
||||
@@ -1498,6 +1727,9 @@ var AST_Await = DEFNODE("Await", "expression", {
|
||||
$propdoc: {
|
||||
expression: "[AST_Node] expression with Promise to resolve on",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.expression.equals(node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1515,6 +1747,10 @@ var AST_Yield = DEFNODE("Yield", "expression nested", {
|
||||
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||
nested: "[boolean] whether to iterate over expression as generator",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return !this.nested == !node.nested
|
||||
&& prop_equals(this.expression, node.expression);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1537,6 +1773,9 @@ var AST_Array = DEFNODE("Array", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[AST_Node*] array of elements"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1579,6 +1818,10 @@ var AST_DestructuredArray = DEFNODE("DestructuredArray", "elements", {
|
||||
$propdoc: {
|
||||
elements: "[(AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)*] array of elements",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.elements, node.elements);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1596,6 +1839,10 @@ var AST_DestructuredKeyVal = DEFNODE("DestructuredKeyVal", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_DefaultValue|AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef] property value",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1617,6 +1864,10 @@ var AST_DestructuredObject = DEFNODE("DestructuredObject", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[AST_DestructuredKeyVal*] array of properties",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.rest, node.rest)
|
||||
&& all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1638,6 +1889,9 @@ var AST_Object = DEFNODE("Object", "properties", {
|
||||
$propdoc: {
|
||||
properties: "[(AST_ObjectProperty|AST_Spread)*] array of properties"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return all_equals(this.properties, node.properties);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1661,6 +1915,10 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
||||
key: "[string|AST_Node] property name. For computed property this is an AST_Node.",
|
||||
value: "[AST_Node] property value. For getters and setters this is an AST_Accessor.",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.key, node.key)
|
||||
&& this.value.equals(node.value);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
visitor.visit(node, function() {
|
||||
@@ -1715,6 +1973,9 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
||||
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
|
||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.thedef ? this.thedef === node.thedef : this.name == node.name;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Symbol") throw new Error("should not instantiate AST_Symbol");
|
||||
if (typeof this.name != "string") throw new Error("name must be string");
|
||||
@@ -1732,10 +1993,14 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
||||
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||
$documentation: "Symbol defined by an `import` statement",
|
||||
$propdoc: {
|
||||
key: "[string] the original `export` name",
|
||||
key: "[AST_String] the original `export` name",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.key.equals(node.key);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.key != "string") throw new Error("key must be string");
|
||||
if (!(this.key instanceof AST_String)) throw new Error("key must be AST_String");
|
||||
},
|
||||
}, AST_SymbolConst);
|
||||
|
||||
@@ -1747,7 +2012,7 @@ var AST_SymbolVar = DEFNODE("SymbolVar", null, {
|
||||
$documentation: "Symbol defining a variable",
|
||||
}, AST_SymbolDeclaration);
|
||||
|
||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, {
|
||||
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", "unused", {
|
||||
$documentation: "Symbol naming a function argument",
|
||||
}, AST_SymbolVar);
|
||||
|
||||
@@ -1779,7 +2044,7 @@ var AST_Label = DEFNODE("Label", "references", {
|
||||
initialize: function() {
|
||||
this.references = [];
|
||||
this.thedef = this;
|
||||
}
|
||||
},
|
||||
}, AST_Symbol);
|
||||
|
||||
var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
@@ -1789,10 +2054,14 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
||||
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||
$documentation: "Reference in an `export` statement",
|
||||
$propdoc: {
|
||||
alias: "[string] the `export` alias",
|
||||
alias: "[AST_String] the `export` alias",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return this.name == node.name
|
||||
&& this.alias.equals(node.alias);
|
||||
},
|
||||
_validate: function() {
|
||||
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||
if (!(this.alias instanceof AST_String)) throw new Error("alias must be AST_String");
|
||||
},
|
||||
}, AST_SymbolRef);
|
||||
|
||||
@@ -1802,6 +2071,7 @@ var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||
|
||||
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||
$documentation: "Base class for `super` & `this`",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||
},
|
||||
@@ -1836,7 +2106,12 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
$propdoc: {
|
||||
expressions: "[AST_Node*] the placeholder expressions",
|
||||
strings: "[string*] the raw text segments",
|
||||
tag: "[AST_Node] tag function, or null if absent",
|
||||
tag: "[AST_Node?] tag function, or null if absent",
|
||||
},
|
||||
_equals: function(node) {
|
||||
return prop_equals(this.tag, node.tag)
|
||||
&& list_equals(this.strings, node.strings)
|
||||
&& all_equals(this.expressions, node.expressions);
|
||||
},
|
||||
walk: function(visitor) {
|
||||
var node = this;
|
||||
@@ -1861,6 +2136,9 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||
|
||||
var AST_Constant = DEFNODE("Constant", null, {
|
||||
$documentation: "Base class for all constants",
|
||||
_equals: function(node) {
|
||||
return this.value === node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||
},
|
||||
@@ -1909,6 +2187,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
$propdoc: {
|
||||
value: "[RegExp] the actual regexp"
|
||||
},
|
||||
_equals: function(node) {
|
||||
return "" + this.value == "" + node.value;
|
||||
},
|
||||
_validate: function() {
|
||||
if (!(this.value instanceof RegExp)) throw new Error("value must be RegExp");
|
||||
},
|
||||
@@ -1916,6 +2197,7 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
||||
|
||||
var AST_Atom = DEFNODE("Atom", null, {
|
||||
$documentation: "Base class for atoms",
|
||||
_equals: return_true,
|
||||
_validate: function() {
|
||||
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||
},
|
||||
@@ -1923,27 +2205,27 @@ var AST_Atom = DEFNODE("Atom", null, {
|
||||
|
||||
var AST_Null = DEFNODE("Null", null, {
|
||||
$documentation: "The `null` atom",
|
||||
value: null
|
||||
value: null,
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_NaN = DEFNODE("NaN", null, {
|
||||
$documentation: "The impossible value",
|
||||
value: 0/0
|
||||
value: 0/0,
|
||||
}, AST_Atom);
|
||||
|
||||
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, {
|
||||
$documentation: "The `Infinity` value",
|
||||
value: 1/0
|
||||
value: 1/0,
|
||||
}, AST_Atom);
|
||||
|
||||
var AST_Boolean = DEFNODE("Boolean", null, {
|
||||
@@ -1955,12 +2237,12 @@ var AST_Boolean = DEFNODE("Boolean", null, {
|
||||
|
||||
var AST_False = DEFNODE("False", null, {
|
||||
$documentation: "The `false` atom",
|
||||
value: false
|
||||
value: false,
|
||||
}, AST_Boolean);
|
||||
|
||||
var AST_True = DEFNODE("True", null, {
|
||||
$documentation: "The `true` atom",
|
||||
value: true
|
||||
value: true,
|
||||
}, AST_Boolean);
|
||||
|
||||
/* -----[ TreeWalker ]----- */
|
||||
@@ -1981,16 +2263,21 @@ TreeWalker.prototype = {
|
||||
return this.stack[this.stack.length - 2 - (n || 0)];
|
||||
},
|
||||
push: function(node) {
|
||||
if (node instanceof AST_Lambda) {
|
||||
var value;
|
||||
if (node instanceof AST_Class) {
|
||||
this.directives = Object.create(this.directives);
|
||||
value = "use strict";
|
||||
} else if (node instanceof AST_Directive) {
|
||||
value = node.value;
|
||||
} else if (node instanceof AST_Lambda) {
|
||||
this.directives = Object.create(this.directives);
|
||||
} else if (node instanceof AST_Directive && !this.directives[node.value]) {
|
||||
this.directives[node.value] = node;
|
||||
}
|
||||
if (value && !this.directives[value]) this.directives[value] = node;
|
||||
this.stack.push(node);
|
||||
},
|
||||
pop: function() {
|
||||
var node = this.stack.pop();
|
||||
if (node instanceof AST_Lambda) {
|
||||
if (node instanceof AST_Class || node instanceof AST_Lambda) {
|
||||
this.directives = Object.getPrototypeOf(this.directives);
|
||||
}
|
||||
},
|
||||
@@ -1999,7 +2286,7 @@ TreeWalker.prototype = {
|
||||
},
|
||||
find_parent: function(type) {
|
||||
var stack = this.stack;
|
||||
for (var i = stack.length; --i >= 0;) {
|
||||
for (var i = stack.length - 1; --i >= 0;) {
|
||||
var x = stack[i];
|
||||
if (x instanceof type) return x;
|
||||
}
|
||||
@@ -2030,33 +2317,40 @@ TreeWalker.prototype = {
|
||||
}
|
||||
},
|
||||
in_boolean_context: function() {
|
||||
var self = this.self();
|
||||
for (var i = 0, p; p = this.parent(i); i++) {
|
||||
if (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_Return && p.in_bool
|
||||
|| p instanceof AST_Sequence && p.tail_node() !== self
|
||||
|| p instanceof AST_SimpleStatement
|
||||
|| 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 if (p instanceof AST_Return) {
|
||||
for (var call, fn = p; call = this.parent(++i); fn = call) {
|
||||
if (call.TYPE == "Call") {
|
||||
if (!(fn instanceof AST_Lambda) || fn.name) return false;
|
||||
} else if (fn instanceof AST_Lambda) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (var drop = true, level = 0, parent, self = this.self(); parent = this.parent(level++); self = parent) {
|
||||
if (parent instanceof AST_Binary) switch (parent.operator) {
|
||||
case "&&":
|
||||
case "||":
|
||||
if (parent.left === self) drop = false;
|
||||
continue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (parent instanceof AST_Conditional) {
|
||||
if (parent.condition === self) return true;
|
||||
continue;
|
||||
}
|
||||
if (parent instanceof AST_DWLoop) return parent.condition === self;
|
||||
if (parent instanceof AST_For) return parent.condition === self;
|
||||
if (parent instanceof AST_If) return parent.condition === self;
|
||||
if (parent instanceof AST_Return) {
|
||||
if (parent.in_bool) return true;
|
||||
while (parent = this.parent(level++)) {
|
||||
if (parent instanceof AST_Lambda) {
|
||||
if (parent.name) return false;
|
||||
parent = this.parent(level++);
|
||||
if (parent.TYPE != "Call") return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parent instanceof AST_Sequence) {
|
||||
if (parent.tail_node() === self) continue;
|
||||
return drop ? "d" : true;
|
||||
}
|
||||
if (parent instanceof AST_SimpleStatement) return drop ? "d" : true;
|
||||
if (parent instanceof AST_UnaryPrefix) return parent.operator == "!";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
6080
lib/compress.js
6080
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@ function read_source_map(name, toplevel) {
|
||||
var match = /^# ([^\s=]+)=(\S+)\s*$/.exec(comment.value);
|
||||
if (!match) break;
|
||||
if (match[1] == "sourceMappingURL") {
|
||||
match = /^data:application\/json(;.*?)?;base64,(\S+)$/.exec(match[2]);
|
||||
match = /^data:application\/json(;.*?)?;base64,([^,]+)$/.exec(match[2]);
|
||||
if (!match) break;
|
||||
return to_ascii(match[2]);
|
||||
}
|
||||
@@ -76,17 +76,20 @@ function minify(files, options) {
|
||||
annotations: undefined,
|
||||
compress: {},
|
||||
enclose: false,
|
||||
expression: false,
|
||||
ie: false,
|
||||
ie8: false,
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
mangle: {},
|
||||
module: false,
|
||||
nameCache: null,
|
||||
output: {},
|
||||
parse: {},
|
||||
rename: undefined,
|
||||
sourceMap: false,
|
||||
timings: false,
|
||||
toplevel: false,
|
||||
toplevel: !!(options && options["module"]),
|
||||
v8: false,
|
||||
validate: false,
|
||||
warnings: false,
|
||||
@@ -95,20 +98,23 @@ function minify(files, options) {
|
||||
}, true);
|
||||
if (options.validate) AST_Node.enable_validation();
|
||||
var timings = options.timings && { start: Date.now() };
|
||||
if (options.rename === undefined) options.rename = options.compress && options.mangle;
|
||||
if (options.annotations !== undefined) set_shorthand("annotations", options, [ "compress", "output" ]);
|
||||
if (options.expression) set_shorthand("expression", options, [ "compress", "parse" ]);
|
||||
if (options.ie8) options.ie = options.ie || options.ie8;
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output" ]);
|
||||
if (options.ie) set_shorthand("ie", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
if (options.keep_fargs) set_shorthand("keep_fargs", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.module) set_shorthand("module", options, [ "compress", "parse" ]);
|
||||
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle", "rename" ]);
|
||||
if (options.v8) set_shorthand("v8", options, [ "mangle", "output", "rename" ]);
|
||||
if (options.webkit) set_shorthand("webkit", options, [ "compress", "mangle", "output", "rename" ]);
|
||||
var quoted_props;
|
||||
if (options.mangle) {
|
||||
options.mangle = defaults(options.mangle, {
|
||||
cache: options.nameCache && (options.nameCache.vars || {}),
|
||||
eval: false,
|
||||
ie: false,
|
||||
keep_fargs: false,
|
||||
keep_fnames: false,
|
||||
properties: false,
|
||||
reserved: [],
|
||||
@@ -132,6 +138,7 @@ function minify(files, options) {
|
||||
init_cache(options.mangle.cache);
|
||||
init_cache(options.mangle.properties.cache);
|
||||
}
|
||||
if (options.rename === undefined) options.rename = options.compress && options.mangle;
|
||||
if (options.sourceMap) {
|
||||
options.sourceMap = defaults(options.sourceMap, {
|
||||
content: null,
|
||||
@@ -148,13 +155,11 @@ function minify(files, options) {
|
||||
}, options.warnings == "verbose");
|
||||
if (timings) timings.parse = Date.now();
|
||||
var toplevel;
|
||||
if (files instanceof AST_Toplevel) {
|
||||
options.parse = options.parse || {};
|
||||
if (files instanceof AST_Node) {
|
||||
toplevel = files;
|
||||
} else {
|
||||
if (typeof files == "string") {
|
||||
files = [ files ];
|
||||
}
|
||||
options.parse = options.parse || {};
|
||||
if (typeof files == "string") files = [ files ];
|
||||
options.parse.toplevel = null;
|
||||
var source_map_content = options.sourceMap && options.sourceMap.content;
|
||||
if (typeof source_map_content == "string" && source_map_content != "inline") {
|
||||
@@ -166,17 +171,14 @@ function minify(files, options) {
|
||||
options.parse.toplevel = toplevel = parse(files[name], options.parse);
|
||||
if (source_map_content == "inline") {
|
||||
var inlined_content = read_source_map(name, toplevel);
|
||||
if (inlined_content) {
|
||||
options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
}
|
||||
if (inlined_content) options.sourceMap.orig[name] = parse_source_map(inlined_content);
|
||||
} else if (source_map_content) {
|
||||
options.sourceMap.orig[name] = source_map_content;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (quoted_props) {
|
||||
reserve_quoted_keys(toplevel, quoted_props);
|
||||
}
|
||||
if (options.parse.expression) toplevel = toplevel.wrap_expression();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
[ "enclose", "wrap" ].forEach(function(action) {
|
||||
var option = options[action];
|
||||
if (!option) return;
|
||||
@@ -187,8 +189,8 @@ function minify(files, options) {
|
||||
if (options.validate) toplevel.validate_ast();
|
||||
if (timings) timings.rename = Date.now();
|
||||
if (options.rename) {
|
||||
toplevel.figure_out_scope(options.mangle);
|
||||
toplevel.expand_names(options.mangle);
|
||||
toplevel.figure_out_scope(options.rename);
|
||||
toplevel.expand_names(options.rename);
|
||||
}
|
||||
if (timings) timings.compress = Date.now();
|
||||
if (options.compress) {
|
||||
@@ -203,7 +205,9 @@ function minify(files, options) {
|
||||
toplevel.mangle_names(options.mangle);
|
||||
}
|
||||
if (timings) timings.properties = Date.now();
|
||||
if (quoted_props) reserve_quoted_keys(toplevel, quoted_props);
|
||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||
if (options.parse.expression) toplevel = toplevel.unwrap_expression();
|
||||
if (timings) timings.output = Date.now();
|
||||
var result = {};
|
||||
var output = defaults(options.output, {
|
||||
|
||||
@@ -192,6 +192,19 @@
|
||||
value: from_moz(M.value),
|
||||
});
|
||||
},
|
||||
StaticBlock: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ClassInit({
|
||||
start: start,
|
||||
end: end,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
end: end,
|
||||
body: normalize_directives(M.body.map(from_moz)),
|
||||
}),
|
||||
});
|
||||
},
|
||||
ForOfStatement: function(M) {
|
||||
return new (M.await ? AST_ForAwaitOf : AST_ForOf)({
|
||||
start: my_start_token(M),
|
||||
@@ -303,13 +316,22 @@
|
||||
});
|
||||
},
|
||||
ExportAllDeclaration: function(M) {
|
||||
var alias = M.exported ? read_name(M.exported) : "*";
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: M.source.value,
|
||||
start: start,
|
||||
end: end,
|
||||
aliases: [ M.exported ? from_moz_alias(M.exported) : new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
keys: [ new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
}) ],
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ExportDefaultDeclaration: function(M) {
|
||||
@@ -346,15 +368,15 @@
|
||||
if (M.source) {
|
||||
var aliases = [], keys = [];
|
||||
M.specifiers.forEach(function(prop) {
|
||||
aliases.push(read_name(prop.exported));
|
||||
keys.push(read_name(prop.local));
|
||||
aliases.push(from_moz_alias(prop.exported));
|
||||
keys.push(from_moz_alias(prop.local));
|
||||
});
|
||||
return new AST_ExportForeign({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
aliases: aliases,
|
||||
keys: keys,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
}
|
||||
return new AST_ExportReferences({
|
||||
@@ -362,38 +384,48 @@
|
||||
end: my_end_token(M),
|
||||
properties: M.specifiers.map(function(prop) {
|
||||
var sym = new AST_SymbolExport(from_moz(prop.local));
|
||||
sym.alias = read_name(prop.exported);
|
||||
sym.alias = from_moz_alias(prop.exported);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
},
|
||||
ImportDeclaration: function(M) {
|
||||
var start = my_start_token(M);
|
||||
var end = my_end_token(M);
|
||||
var all = null, def = null, props = null;
|
||||
M.specifiers.forEach(function(prop) {
|
||||
var sym = new AST_SymbolImport(from_moz(prop.local));
|
||||
switch (prop.type) {
|
||||
case "ImportDefaultSpecifier":
|
||||
def = sym;
|
||||
def.key = "";
|
||||
def.key = new AST_String({
|
||||
start: start,
|
||||
value: "",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
case "ImportNamespaceSpecifier":
|
||||
all = sym;
|
||||
all.key = "*";
|
||||
all.key = new AST_String({
|
||||
start: start,
|
||||
value: "*",
|
||||
end: end,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
sym.key = prop.imported.name || syn.name;
|
||||
sym.key = from_moz_alias(prop.imported);
|
||||
if (!props) props = [];
|
||||
props.push(sym);
|
||||
break;
|
||||
}
|
||||
});
|
||||
return new AST_Import({
|
||||
start: my_start_token(M),
|
||||
end: my_end_token(M),
|
||||
start: start,
|
||||
end: end,
|
||||
all: all,
|
||||
default: def,
|
||||
properties: props,
|
||||
path: M.source.value,
|
||||
path: from_moz(M.source),
|
||||
});
|
||||
},
|
||||
ImportExpression: function(M) {
|
||||
@@ -714,6 +746,10 @@
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_ClassInit, function To_Moz_StaticBlock(M) {
|
||||
return to_moz_scope("StaticBlock", M.value);
|
||||
});
|
||||
|
||||
function To_Moz_ForOfStatement(is_await) {
|
||||
return function(M) {
|
||||
return {
|
||||
@@ -780,38 +816,26 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_ExportForeign, function To_Moz_ExportAllDeclaration_ExportNamedDeclaration(M) {
|
||||
if (M.keys[0] == "*") return {
|
||||
if (M.keys[0].value == "*") return {
|
||||
type: "ExportAllDeclaration",
|
||||
exported: M.aliases[0] == "*" ? null : {
|
||||
type: "Identifier",
|
||||
name: M.aliases[0],
|
||||
},
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
exported: M.aliases[0].value == "*" ? null : to_moz_alias(M.aliases[0]),
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
var specifiers = [];
|
||||
for (var i = 0; i < M.aliases.length; i++) {
|
||||
specifiers.push({
|
||||
specifiers.push(set_moz_loc({
|
||||
start: M.keys[i].start,
|
||||
end: M.aliases[i].end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: M.aliases[i],
|
||||
},
|
||||
local: {
|
||||
type: "Identifier",
|
||||
name: M.keys[i],
|
||||
},
|
||||
});
|
||||
local: to_moz_alias(M.keys[i]),
|
||||
exported: to_moz_alias(M.aliases[i]),
|
||||
}));
|
||||
}
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -819,44 +843,41 @@
|
||||
return {
|
||||
type: "ExportNamedDeclaration",
|
||||
specifiers: M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.start,
|
||||
end: prop.alias.end,
|
||||
}, {
|
||||
type: "ExportSpecifier",
|
||||
local: to_moz(prop),
|
||||
exported: {
|
||||
type: "Identifier",
|
||||
name: prop.alias,
|
||||
},
|
||||
};
|
||||
exported: to_moz_alias(prop.alias),
|
||||
});
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
def_to_moz(AST_Import, function To_Moz_ImportDeclaration(M) {
|
||||
var specifiers = M.properties ? M.properties.map(function(prop) {
|
||||
return {
|
||||
return set_moz_loc({
|
||||
start: prop.key.start,
|
||||
end: prop.end,
|
||||
}, {
|
||||
type: "ImportSpecifier",
|
||||
local: to_moz(prop),
|
||||
imported: {
|
||||
type: "Identifier",
|
||||
name: prop.key,
|
||||
},
|
||||
};
|
||||
imported: to_moz_alias(prop.key),
|
||||
});
|
||||
}) : [];
|
||||
if (M.all) specifiers.unshift({
|
||||
if (M.all) specifiers.unshift(set_moz_loc(M.all, {
|
||||
type: "ImportNamespaceSpecifier",
|
||||
local: to_moz(M.all),
|
||||
});
|
||||
if (M.default) specifiers.unshift({
|
||||
}));
|
||||
if (M.default) specifiers.unshift(set_moz_loc(M.default, {
|
||||
type: "ImportDefaultSpecifier",
|
||||
local: to_moz(M.default),
|
||||
});
|
||||
}));
|
||||
return {
|
||||
type: "ImportDeclaration",
|
||||
specifiers: specifiers,
|
||||
source: {
|
||||
type: "Literal",
|
||||
value: M.path,
|
||||
},
|
||||
source: to_moz(M.path),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1005,7 +1026,7 @@
|
||||
});
|
||||
|
||||
def_to_moz(AST_RegExp, function To_Moz_RegExpLiteral(M) {
|
||||
var flags = M.value.toString().match(/[gimuy]*$/)[0];
|
||||
var flags = M.value.toString().match(/\/([gimuy]*)$/)[1];
|
||||
var value = "/" + M.value.raw_source + "/" + flags;
|
||||
return {
|
||||
type: "Literal",
|
||||
@@ -1013,8 +1034,8 @@
|
||||
raw: value,
|
||||
regex: {
|
||||
pattern: M.value.raw_source,
|
||||
flags: flags
|
||||
}
|
||||
flags: flags,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1203,6 +1224,14 @@
|
||||
return node;
|
||||
}
|
||||
|
||||
function from_moz_alias(moz) {
|
||||
return new AST_String({
|
||||
start: my_start_token(moz),
|
||||
value: read_name(moz),
|
||||
end: my_end_token(moz),
|
||||
});
|
||||
}
|
||||
|
||||
AST_Node.from_mozilla_ast = function(node) {
|
||||
var save_stack = FROM_MOZ_STACK;
|
||||
FROM_MOZ_STACK = [];
|
||||
@@ -1254,6 +1283,13 @@
|
||||
return node != null ? node.to_mozilla_ast() : null;
|
||||
}
|
||||
|
||||
function to_moz_alias(alias) {
|
||||
return is_identifier_string(alias.value) ? set_moz_loc(alias, {
|
||||
type: "Identifier",
|
||||
name: alias.value,
|
||||
}) : to_moz(alias);
|
||||
}
|
||||
|
||||
function to_moz_block(node) {
|
||||
return {
|
||||
type: "BlockStatement",
|
||||
|
||||
263
lib/output.js
263
lib/output.js
@@ -55,6 +55,7 @@ function OutputStream(options) {
|
||||
beautify : false,
|
||||
braces : false,
|
||||
comments : false,
|
||||
extendscript : false,
|
||||
galio : false,
|
||||
ie : false,
|
||||
indent_level : 4,
|
||||
@@ -101,10 +102,18 @@ function OutputStream(options) {
|
||||
}
|
||||
}
|
||||
|
||||
function make_indent(value) {
|
||||
if (typeof value == "number") return new Array(value + 1).join(" ");
|
||||
if (!value) return "";
|
||||
if (!/^\s*$/.test(value)) throw new Error("unsupported indentation: " + JSON.stringify("" + value));
|
||||
return value;
|
||||
}
|
||||
|
||||
var current_col = 0;
|
||||
var current_line = 1;
|
||||
var current_pos = 0;
|
||||
var indentation = options.indent_start;
|
||||
var current_indent = make_indent(options.indent_start);
|
||||
var full_indent = make_indent(options.indent_level);
|
||||
var half_indent = full_indent.length + 1 >> 1;
|
||||
var last;
|
||||
var line_end = 0;
|
||||
var line_fixed = true;
|
||||
@@ -115,17 +124,17 @@ function OutputStream(options) {
|
||||
var might_need_semicolon;
|
||||
var need_newline_indented = false;
|
||||
var need_space = false;
|
||||
var newline_insert = -1;
|
||||
var output;
|
||||
var stack;
|
||||
var OUTPUT;
|
||||
var stored = "";
|
||||
|
||||
function reset() {
|
||||
last = "";
|
||||
might_need_space = false;
|
||||
might_need_semicolon = false;
|
||||
stack = [];
|
||||
var str = OUTPUT;
|
||||
OUTPUT = "";
|
||||
var str = output;
|
||||
output = "";
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -227,32 +236,39 @@ function OutputStream(options) {
|
||||
} : noop;
|
||||
|
||||
function insert_newlines(count) {
|
||||
var index = OUTPUT.lastIndexOf("\n");
|
||||
if (line_end < index) line_end = index;
|
||||
var left = OUTPUT.slice(0, line_end);
|
||||
var right = OUTPUT.slice(line_end);
|
||||
adjust_mappings(count, right.length - current_col);
|
||||
stored += output.slice(0, line_end);
|
||||
output = output.slice(line_end);
|
||||
var new_col = output.length;
|
||||
adjust_mappings(count, new_col - current_col);
|
||||
current_line += count;
|
||||
current_pos += count;
|
||||
current_col = right.length;
|
||||
OUTPUT = left;
|
||||
while (count--) OUTPUT += "\n";
|
||||
OUTPUT += right;
|
||||
current_col = new_col;
|
||||
while (count--) stored += "\n";
|
||||
}
|
||||
|
||||
var fix_line = options.max_line_len ? function() {
|
||||
var fix_line = options.max_line_len ? function(flush) {
|
||||
if (line_fixed) {
|
||||
if (current_col > options.max_line_len) {
|
||||
AST_Node.warn("Output exceeds {max_line_len} characters", options);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (current_col > options.max_line_len) insert_newlines(1);
|
||||
line_fixed = true;
|
||||
flush_mappings();
|
||||
if (current_col > options.max_line_len) {
|
||||
insert_newlines(1);
|
||||
line_fixed = true;
|
||||
}
|
||||
if (line_fixed || flush) flush_mappings();
|
||||
} : noop;
|
||||
|
||||
var requireSemicolonChars = makePredicate("( [ + * / - , .");
|
||||
var require_semicolon = makePredicate("( [ + * / - , .");
|
||||
|
||||
function require_space(prev, ch, str) {
|
||||
return is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| last == "--" && ch == ">"
|
||||
|| last == "!" && str == "--"
|
||||
|| prev == "/" && (str == "in" || str == "instanceof");
|
||||
}
|
||||
|
||||
var print = options.beautify
|
||||
|| options.comments
|
||||
@@ -276,45 +292,39 @@ function OutputStream(options) {
|
||||
space();
|
||||
}
|
||||
}
|
||||
newline_insert = -1;
|
||||
var prev = last.slice(-1);
|
||||
if (might_need_semicolon) {
|
||||
might_need_semicolon = false;
|
||||
|
||||
if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
|
||||
if (options.semicolons || requireSemicolonChars[ch]) {
|
||||
OUTPUT += ";";
|
||||
if (prev == ":" && ch == "}" || prev != ";" && (!ch || ";}".indexOf(ch) < 0)) {
|
||||
var need_semicolon = require_semicolon[ch];
|
||||
if (need_semicolon || options.semicolons) {
|
||||
output += ";";
|
||||
current_col++;
|
||||
current_pos++;
|
||||
if (!line_fixed) {
|
||||
fix_line();
|
||||
if (line_fixed && !need_semicolon && output == ";") {
|
||||
output = "";
|
||||
current_col = 0;
|
||||
}
|
||||
}
|
||||
if (line_end == output.length - 1) line_end++;
|
||||
} else {
|
||||
fix_line();
|
||||
OUTPUT += "\n";
|
||||
current_pos++;
|
||||
output += "\n";
|
||||
current_line++;
|
||||
current_col = 0;
|
||||
|
||||
if (/^\s+$/.test(str)) {
|
||||
// reset the semicolon flag, since we didn't print one
|
||||
// now and might still have to later
|
||||
might_need_semicolon = true;
|
||||
}
|
||||
// reset the semicolon flag, since we didn't print one
|
||||
// now and might still have to later
|
||||
if (/^\s+$/.test(str)) might_need_semicolon = true;
|
||||
}
|
||||
|
||||
if (!options.beautify)
|
||||
might_need_space = false;
|
||||
if (!options.beautify) might_need_space = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
OUTPUT += " ";
|
||||
if (require_space(prev, ch, str)) {
|
||||
output += " ";
|
||||
current_col++;
|
||||
current_pos++;
|
||||
}
|
||||
if (prev != "<" || str != "!") might_need_space = false;
|
||||
}
|
||||
@@ -324,14 +334,13 @@ function OutputStream(options) {
|
||||
token: mapping_token,
|
||||
name: mapping_name,
|
||||
line: current_line,
|
||||
col: current_col
|
||||
col: current_col,
|
||||
});
|
||||
mapping_token = false;
|
||||
if (line_fixed) flush_mappings();
|
||||
}
|
||||
|
||||
OUTPUT += str;
|
||||
current_pos += str.length;
|
||||
output += str;
|
||||
var a = str.split(/\r?\n/), n = a.length - 1;
|
||||
current_line += n;
|
||||
current_col += a[0].length;
|
||||
@@ -346,22 +355,15 @@ function OutputStream(options) {
|
||||
if (might_need_semicolon) {
|
||||
might_need_semicolon = false;
|
||||
if (prev == ":" && ch == "}" || (!ch || ";}".indexOf(ch) < 0) && prev != ";") {
|
||||
OUTPUT += ";";
|
||||
output += ";";
|
||||
might_need_space = false;
|
||||
}
|
||||
}
|
||||
if (might_need_space) {
|
||||
if (is_identifier_char(prev) && (is_identifier_char(ch) || ch == "\\")
|
||||
|| (ch == "/" && ch == prev)
|
||||
|| ((ch == "+" || ch == "-") && ch == last)
|
||||
|| str == "--" && last == "!"
|
||||
|| str == "in" && prev == "/"
|
||||
|| last == "--" && ch == ">") {
|
||||
OUTPUT += " ";
|
||||
}
|
||||
if (require_space(prev, ch, str)) output += " ";
|
||||
if (prev != "<" || str != "!") might_need_space = false;
|
||||
}
|
||||
OUTPUT += str;
|
||||
output += str;
|
||||
last = str;
|
||||
};
|
||||
|
||||
@@ -373,30 +375,25 @@ function OutputStream(options) {
|
||||
|
||||
var indent = options.beautify ? function(half) {
|
||||
if (need_newline_indented) print("\n");
|
||||
print(repeat_string(" ", half ? indentation - (options.indent_level >> 1) : indentation));
|
||||
print(half ? current_indent.slice(0, -half_indent) : current_indent);
|
||||
} : noop;
|
||||
|
||||
var with_indent = options.beautify ? function(cont) {
|
||||
var save_indentation = indentation;
|
||||
indentation += options.indent_level;
|
||||
var save_indentation = current_indent;
|
||||
current_indent += full_indent;
|
||||
cont();
|
||||
indentation = save_indentation;
|
||||
current_indent = save_indentation;
|
||||
} : function(cont) { cont() };
|
||||
|
||||
var may_add_newline = options.max_line_len || options.preserve_line ? function() {
|
||||
fix_line();
|
||||
line_end = OUTPUT.length;
|
||||
line_end = output.length;
|
||||
line_fixed = false;
|
||||
} : noop;
|
||||
|
||||
var newline = options.beautify ? function() {
|
||||
if (newline_insert < 0) return print("\n");
|
||||
if (OUTPUT[newline_insert] != "\n") {
|
||||
OUTPUT = OUTPUT.slice(0, newline_insert) + "\n" + OUTPUT.slice(newline_insert);
|
||||
current_pos++;
|
||||
current_line++;
|
||||
}
|
||||
newline_insert++;
|
||||
print("\n");
|
||||
line_end = output.length;
|
||||
} : may_add_newline;
|
||||
|
||||
var semicolon = options.beautify ? function() {
|
||||
@@ -410,10 +407,11 @@ function OutputStream(options) {
|
||||
print(";");
|
||||
}
|
||||
|
||||
function with_block(cont) {
|
||||
function with_block(cont, end) {
|
||||
print("{");
|
||||
newline();
|
||||
with_indent(cont);
|
||||
add_mapping(end);
|
||||
indent();
|
||||
print("}");
|
||||
}
|
||||
@@ -452,13 +450,12 @@ function OutputStream(options) {
|
||||
} : noop;
|
||||
|
||||
function get() {
|
||||
if (!line_fixed) fix_line();
|
||||
return OUTPUT;
|
||||
if (!line_fixed) fix_line(true);
|
||||
return stored + output;
|
||||
}
|
||||
|
||||
function has_nlb() {
|
||||
var index = OUTPUT.lastIndexOf("\n");
|
||||
return /^ *$/.test(OUTPUT.slice(index + 1));
|
||||
return /(^|\n) *$/.test(output);
|
||||
}
|
||||
|
||||
function pad_comment(token, force) {
|
||||
@@ -515,15 +512,13 @@ function OutputStream(options) {
|
||||
scan.walk(tw);
|
||||
}
|
||||
|
||||
if (current_pos == 0) {
|
||||
if (current_line == 1 && current_col == 0) {
|
||||
if (comments.length > 0 && options.shebang && comments[0].type == "comment5") {
|
||||
print("#!" + comments.shift().value + "\n");
|
||||
indent();
|
||||
}
|
||||
var preamble = options.preamble;
|
||||
if (preamble) {
|
||||
print(preamble.replace(/\r\n?|[\n\u2028\u2029]|\s*$/g, "\n"));
|
||||
}
|
||||
if (preamble) print(preamble.replace(/\r\n?|\u2028|\u2029|(^|\S)\s*$/g, "$1\n"));
|
||||
}
|
||||
|
||||
comments = comments.filter(comment_filter, node);
|
||||
@@ -561,20 +556,18 @@ function OutputStream(options) {
|
||||
return !/comment[134]/.test(c.type);
|
||||
}))) return;
|
||||
comments._dumped = self;
|
||||
var insert = OUTPUT.length;
|
||||
comments.filter(comment_filter, node).forEach(function(comment, index) {
|
||||
pad_comment(comment, index || !tail);
|
||||
print_comment(comment);
|
||||
});
|
||||
if (OUTPUT.length > insert) newline_insert = insert;
|
||||
}
|
||||
|
||||
return {
|
||||
get : get,
|
||||
reset : reset,
|
||||
indent : indent,
|
||||
should_break : options.width ? function() {
|
||||
return current_col - indentation >= options.width;
|
||||
should_break : options.beautify && options.width ? function() {
|
||||
return current_col >= options.width;
|
||||
} : return_false,
|
||||
has_parens : function() { return last.slice(-1) == "(" },
|
||||
newline : newline,
|
||||
@@ -708,6 +701,7 @@ function OutputStream(options) {
|
||||
if (p instanceof AST_Class) return true;
|
||||
// (x++)[y]
|
||||
// (typeof x).y
|
||||
// https://github.com/mishoo/UglifyJS/issues/115
|
||||
if (p instanceof AST_PropAccess) return p.expression === this;
|
||||
// (~x)`foo`
|
||||
if (p instanceof AST_Template) return p.tag === this;
|
||||
@@ -883,7 +877,9 @@ function OutputStream(options) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
});
|
||||
PARENS(AST_Conditional, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
return needs_parens_assign_cond(this, output)
|
||||
// https://github.com/mishoo/UglifyJS/issues/1144
|
||||
|| output.option("extendscript") && output.parent() instanceof AST_Conditional;
|
||||
});
|
||||
PARENS(AST_Yield, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
@@ -962,7 +958,7 @@ function OutputStream(options) {
|
||||
if (self.body.length > 0) {
|
||||
output.with_block(function() {
|
||||
display_body(self.body, false, output, allow_directives);
|
||||
});
|
||||
}, self.end);
|
||||
} else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_BlockStatement, function(output) {
|
||||
@@ -1070,6 +1066,14 @@ function OutputStream(options) {
|
||||
}
|
||||
output.semicolon();
|
||||
});
|
||||
function print_alias(alias, output) {
|
||||
var value = alias.value;
|
||||
if (value == "*" || is_identifier_string(value)) {
|
||||
output.print_name(value);
|
||||
} else {
|
||||
output.print_string(value, alias.quote);
|
||||
}
|
||||
}
|
||||
DEFPRINT(AST_ExportForeign, function(output) {
|
||||
var self = this;
|
||||
output.print("export");
|
||||
@@ -1077,7 +1081,7 @@ function OutputStream(options) {
|
||||
var len = self.keys.length;
|
||||
if (len == 0) {
|
||||
print_braced_empty(self, output);
|
||||
} else if (self.keys[0] == "*") {
|
||||
} else if (self.keys[0].value == "*") {
|
||||
print_entry(0);
|
||||
} else output.with_block(function() {
|
||||
output.indent();
|
||||
@@ -1089,22 +1093,22 @@ function OutputStream(options) {
|
||||
print_entry(i);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
output.space();
|
||||
output.print("from");
|
||||
output.space();
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
|
||||
function print_entry(index) {
|
||||
var alias = self.aliases[index];
|
||||
var key = self.keys[index];
|
||||
output.print_name(key);
|
||||
if (alias != key) {
|
||||
print_alias(key, output);
|
||||
if (alias.value != key.value) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1133,7 +1137,7 @@ function OutputStream(options) {
|
||||
output.print("from");
|
||||
output.space();
|
||||
}
|
||||
output.print_string(self.path, self.quote);
|
||||
self.path.print(output);
|
||||
output.semicolon();
|
||||
});
|
||||
|
||||
@@ -1152,8 +1156,9 @@ function OutputStream(options) {
|
||||
});
|
||||
}
|
||||
function print_arrow(self, output) {
|
||||
if (self.argnames.length == 1 && self.argnames[0] instanceof AST_SymbolFunarg && !self.rest) {
|
||||
self.argnames[0].print(output);
|
||||
var argname = self.argnames.length == 1 && !self.rest && self.argnames[0];
|
||||
if (argname instanceof AST_SymbolFunarg && argname.name != "yield") {
|
||||
argname.print(output);
|
||||
} else {
|
||||
print_funargs(self, output);
|
||||
}
|
||||
@@ -1262,6 +1267,11 @@ function OutputStream(options) {
|
||||
}
|
||||
print_method(self, output);
|
||||
});
|
||||
DEFPRINT(AST_ClassInit, function(output) {
|
||||
output.print("static");
|
||||
output.space();
|
||||
print_braced(this.value, output);
|
||||
});
|
||||
|
||||
/* -----[ jumps ]----- */
|
||||
function print_jump(kind, prop) {
|
||||
@@ -1347,7 +1357,7 @@ function OutputStream(options) {
|
||||
if (i < last && branch.body.length > 0)
|
||||
output.newline();
|
||||
});
|
||||
});
|
||||
}, self.end);
|
||||
});
|
||||
function print_branch_body(self, output) {
|
||||
output.newline();
|
||||
@@ -1464,17 +1474,15 @@ function OutputStream(options) {
|
||||
parent = output.parent(level++);
|
||||
if (parent instanceof AST_Call && parent.expression === node) return;
|
||||
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
||||
output.print(typeof self.pure == "string" ? "/*" + self.pure + "*/" : "/*@__PURE__*/");
|
||||
output.print("/*@__PURE__*/");
|
||||
}
|
||||
function print_call_args(self, output) {
|
||||
if (self.expression instanceof AST_Call || self.expression instanceof AST_Lambda) {
|
||||
output.add_mapping(self.start);
|
||||
}
|
||||
output.with_parens(function() {
|
||||
self.args.forEach(function(expr, i) {
|
||||
if (i) output.comma();
|
||||
expr.print(output);
|
||||
});
|
||||
output.add_mapping(self.end);
|
||||
});
|
||||
}
|
||||
DEFPRINT(AST_Call, function(output) {
|
||||
@@ -1509,11 +1517,12 @@ function OutputStream(options) {
|
||||
var expr = self.expression;
|
||||
expr.print(output);
|
||||
var prop = self.property;
|
||||
if (output.option("ie") && RESERVED_WORDS[prop]) {
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
output.print("]");
|
||||
if (output.option("ie") && RESERVED_WORDS[prop] || self.quoted && output.option("keep_quoted_props")) {
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
output.add_mapping(self.end);
|
||||
output.print_string(prop);
|
||||
});
|
||||
} else {
|
||||
if (expr instanceof AST_Number && !/[ex.)]/i.test(output.last())) output.print(".");
|
||||
output.print(self.optional ? "?." : ".");
|
||||
@@ -1525,9 +1534,10 @@ function OutputStream(options) {
|
||||
DEFPRINT(AST_Sub, function(output) {
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.print(self.optional ? "?.[" : "[");
|
||||
self.property.print(output);
|
||||
output.print("]");
|
||||
if (self.optional) output.print("?.");
|
||||
output.with_square(function() {
|
||||
self.property.print(output);
|
||||
});
|
||||
});
|
||||
DEFPRINT(AST_Spread, function(output) {
|
||||
output.print("...");
|
||||
@@ -1546,8 +1556,10 @@ function OutputStream(options) {
|
||||
exp.print(output);
|
||||
});
|
||||
DEFPRINT(AST_UnaryPostfix, function(output) {
|
||||
this.expression.print(output);
|
||||
output.print(this.operator);
|
||||
var self = this;
|
||||
self.expression.print(output);
|
||||
output.add_mapping(self.end);
|
||||
output.print(self.operator);
|
||||
});
|
||||
DEFPRINT(AST_Binary, function(output) {
|
||||
var self = this;
|
||||
@@ -1640,7 +1652,8 @@ function OutputStream(options) {
|
||||
value.print(output);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||
var props = this.properties, len = props.length, rest = this.rest;
|
||||
var self = this;
|
||||
var props = self.properties, len = props.length, rest = self.rest;
|
||||
if (len || rest) output.with_block(function() {
|
||||
props.forEach(function(prop, i) {
|
||||
if (i) {
|
||||
@@ -1660,8 +1673,8 @@ function OutputStream(options) {
|
||||
rest.print(output);
|
||||
}
|
||||
output.newline();
|
||||
});
|
||||
else print_braced_empty(this, output);
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
});
|
||||
function print_properties(self, output, no_comma) {
|
||||
var props = self.properties;
|
||||
@@ -1675,7 +1688,7 @@ function OutputStream(options) {
|
||||
prop.print(output);
|
||||
});
|
||||
output.newline();
|
||||
});
|
||||
}, self.end);
|
||||
else print_braced_empty(self, output);
|
||||
}
|
||||
DEFPRINT(AST_Object, function(output) {
|
||||
@@ -1737,19 +1750,19 @@ function OutputStream(options) {
|
||||
var name = get_symbol_name(self);
|
||||
output.print_name(name);
|
||||
var alias = self.alias;
|
||||
if (alias != name) {
|
||||
if (alias.value != name) {
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
output.print_name(alias);
|
||||
print_alias(alias, output);
|
||||
}
|
||||
});
|
||||
DEFPRINT(AST_SymbolImport, function(output) {
|
||||
var self = this;
|
||||
var name = get_symbol_name(self);
|
||||
var key = self.key;
|
||||
if (key && key != name) {
|
||||
output.print_name(key);
|
||||
if (key.value && key.value != name) {
|
||||
print_alias(key, output);
|
||||
output.space();
|
||||
output.print("as");
|
||||
output.space();
|
||||
@@ -1819,9 +1832,6 @@ function OutputStream(options) {
|
||||
case "\u2029": return "\\u2029";
|
||||
}
|
||||
}));
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === this)
|
||||
output.print(" ");
|
||||
});
|
||||
|
||||
function force_statement(stat, output) {
|
||||
@@ -1869,8 +1879,8 @@ function OutputStream(options) {
|
||||
len = match[0].length;
|
||||
digits = str.slice(len);
|
||||
candidates.push(digits + "e-" + (digits.length + len - 1));
|
||||
} else if (match = /0+$/.exec(str)) {
|
||||
len = match[0].length;
|
||||
} else if (match = /[^0]0+$/.exec(str)) {
|
||||
len = match[0].length - 1;
|
||||
candidates.push(str.slice(0, -len) + "e" + len);
|
||||
} else if (match = /^(\d)\.(\d+)e(-?\d+)$/.exec(str)) {
|
||||
candidates.push(match[1] + match[2] + "e" + (match[3] - match[2].length));
|
||||
@@ -1888,7 +1898,7 @@ function OutputStream(options) {
|
||||
output.indent();
|
||||
stmt.print(output);
|
||||
output.newline();
|
||||
});
|
||||
}, stmt.end);
|
||||
}
|
||||
|
||||
/* -----[ source map generators ]----- */
|
||||
@@ -1911,22 +1921,27 @@ function OutputStream(options) {
|
||||
// or if we should add even more.
|
||||
DEFMAP([
|
||||
AST_Array,
|
||||
AST_Await,
|
||||
AST_BlockStatement,
|
||||
AST_Catch,
|
||||
AST_Constant,
|
||||
AST_Debugger,
|
||||
AST_Definitions,
|
||||
AST_Destructured,
|
||||
AST_Directive,
|
||||
AST_Finally,
|
||||
AST_Jump,
|
||||
AST_Lambda,
|
||||
AST_New,
|
||||
AST_Object,
|
||||
AST_Spread,
|
||||
AST_StatementWithBody,
|
||||
AST_Symbol,
|
||||
AST_Switch,
|
||||
AST_SwitchBranch,
|
||||
AST_Try,
|
||||
AST_UnaryPrefix,
|
||||
AST_Yield,
|
||||
], function(output) {
|
||||
output.add_mapping(this.start);
|
||||
});
|
||||
|
||||
214
lib/parse.js
214
lib/parse.js
@@ -44,10 +44,10 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof let new return switch throw try typeof var void while with";
|
||||
var KEYWORDS = "break case catch class const continue debugger default delete do else extends finally for function if in instanceof new return switch throw try typeof var void while with";
|
||||
var KEYWORDS_ATOM = "false null true";
|
||||
var RESERVED_WORDS = [
|
||||
"abstract async await boolean byte char double enum export final float goto implements import int interface long native package private protected public short static super synchronized this throws transient volatile yield",
|
||||
"abstract async await boolean byte char double enum export final float goto implements import int interface let long native package private protected public short static super synchronized this throws transient volatile yield",
|
||||
KEYWORDS_ATOM,
|
||||
KEYWORDS,
|
||||
].join(" ");
|
||||
@@ -237,15 +237,14 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
newline_before : false,
|
||||
regex_allowed : false,
|
||||
comments_before : [],
|
||||
directives : {},
|
||||
directive_stack : [],
|
||||
directives : Object.create(null),
|
||||
read_template : with_eof_error("Unterminated template literal", function(strings) {
|
||||
var s = "";
|
||||
for (;;) {
|
||||
var ch = next(true, true);
|
||||
var ch = read();
|
||||
switch (ch) {
|
||||
case "\\":
|
||||
ch += next(true, true);
|
||||
ch += read();
|
||||
break;
|
||||
case "`":
|
||||
strings.push(s);
|
||||
@@ -260,6 +259,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
}
|
||||
s += ch;
|
||||
}
|
||||
|
||||
function read() {
|
||||
var ch = next(true, true);
|
||||
return ch == "\r" ? "\n" : ch;
|
||||
}
|
||||
}),
|
||||
};
|
||||
var prev_was_dot = false;
|
||||
@@ -548,16 +552,8 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
|
||||
function handle_dot() {
|
||||
next();
|
||||
var ch = peek();
|
||||
if (ch == ".") {
|
||||
var op = ".";
|
||||
do {
|
||||
op += ".";
|
||||
next();
|
||||
} while (peek() == ".");
|
||||
return token("operator", op);
|
||||
}
|
||||
return is_digit(ch.charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
if (looking_at("..")) return token("operator", "." + next() + next());
|
||||
return is_digit(peek().charCodeAt(0)) ? read_num(".") : token("punc", ".");
|
||||
}
|
||||
|
||||
function read_word() {
|
||||
@@ -630,24 +626,19 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
||||
};
|
||||
|
||||
next_token.add_directive = function(directive) {
|
||||
S.directive_stack[S.directive_stack.length - 1].push(directive);
|
||||
if (S.directives[directive]) S.directives[directive]++;
|
||||
else S.directives[directive] = 1;
|
||||
S.directives[directive] = true;
|
||||
}
|
||||
|
||||
next_token.push_directives_stack = function() {
|
||||
S.directive_stack.push([]);
|
||||
S.directives = Object.create(S.directives);
|
||||
}
|
||||
|
||||
next_token.pop_directives_stack = function() {
|
||||
var directives = S.directive_stack.pop();
|
||||
for (var i = directives.length; --i >= 0;) {
|
||||
S.directives[directives[i]]--;
|
||||
}
|
||||
S.directives = Object.getPrototypeOf(S.directives);
|
||||
}
|
||||
|
||||
next_token.has_directive = function(directive) {
|
||||
return S.directives[directive] > 0;
|
||||
return !!S.directives[directive];
|
||||
}
|
||||
|
||||
return next_token;
|
||||
@@ -694,6 +685,7 @@ function parse($TEXT, options) {
|
||||
expression : false,
|
||||
filename : null,
|
||||
html5_comments : true,
|
||||
module : false,
|
||||
shebang : true,
|
||||
strict : false,
|
||||
toplevel : null,
|
||||
@@ -815,7 +807,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
|
||||
var statement = embed_tokens(function() {
|
||||
var statement = embed_tokens(function(toplevel) {
|
||||
handle_regexp();
|
||||
switch (S.token.type) {
|
||||
case "string":
|
||||
@@ -854,14 +846,23 @@ function parse($TEXT, options) {
|
||||
if (S.in_async) return simple_statement();
|
||||
break;
|
||||
case "export":
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return export_();
|
||||
case "import":
|
||||
var token = peek();
|
||||
if (!(token.type == "punc" && /^[(.]$/.test(token.value))) {
|
||||
if (token.type == "punc" && /^[(.]$/.test(token.value)) break;
|
||||
if (!toplevel && options.module !== "") unexpected();
|
||||
next();
|
||||
return import_();
|
||||
case "let":
|
||||
if (is_vardefs()) {
|
||||
next();
|
||||
return import_();
|
||||
var node = let_();
|
||||
semicolon();
|
||||
return node;
|
||||
}
|
||||
break;
|
||||
case "yield":
|
||||
if (S.in_generator) return simple_statement();
|
||||
break;
|
||||
@@ -947,12 +948,6 @@ function parse($TEXT, options) {
|
||||
next();
|
||||
return if_();
|
||||
|
||||
case "let":
|
||||
next();
|
||||
var node = let_();
|
||||
semicolon();
|
||||
return node;
|
||||
|
||||
case "return":
|
||||
if (S.in_function == 0 && !options.bare_returns)
|
||||
croak("'return' outside of function");
|
||||
@@ -1061,13 +1056,13 @@ function parse($TEXT, options) {
|
||||
return stat;
|
||||
}
|
||||
|
||||
function has_modifier(name) {
|
||||
function has_modifier(name, no_nlb) {
|
||||
if (!is("name", name)) return;
|
||||
var token = peek();
|
||||
if (!token) return;
|
||||
if (is_token(token, "operator", "=")) return;
|
||||
if (token.type == "punc" && /^[(;}]$/.test(token.value)) return;
|
||||
if (has_newline_before(token)) return;
|
||||
if (no_nlb && has_newline_before(token)) return;
|
||||
return next();
|
||||
}
|
||||
|
||||
@@ -1097,7 +1092,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
var start = S.token;
|
||||
var fixed = !!has_modifier("static");
|
||||
var async = has_modifier("async");
|
||||
var async = has_modifier("async", true);
|
||||
if (is("operator", "*")) {
|
||||
next();
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
@@ -1116,6 +1111,18 @@ function parse($TEXT, options) {
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
if (fixed && is("punc", "{")) {
|
||||
props.push(new AST_ClassInit({
|
||||
start: start,
|
||||
value: new AST_ClassInitBlock({
|
||||
start: start,
|
||||
body: block_(),
|
||||
end: prev(),
|
||||
}),
|
||||
end: prev(),
|
||||
}));
|
||||
continue;
|
||||
}
|
||||
var internal = is("name") && /^#/.test(S.token.value);
|
||||
var key = as_property_key();
|
||||
if (is("punc", "(")) {
|
||||
@@ -1186,19 +1193,19 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function for_() {
|
||||
var await = is("name", "await") && next();
|
||||
var await_token = is("name", "await") && next();
|
||||
expect("(");
|
||||
var init = null;
|
||||
if (await || !is("punc", ";")) {
|
||||
if (await_token || !is("punc", ";")) {
|
||||
init = is("keyword", "const")
|
||||
? (next(), const_(true))
|
||||
: is("keyword", "let")
|
||||
: is("name", "let") && is_vardefs()
|
||||
? (next(), let_(true))
|
||||
: is("keyword", "var")
|
||||
? (next(), var_(true))
|
||||
: expression(true);
|
||||
var ctor;
|
||||
if (await) {
|
||||
if (await_token) {
|
||||
expect_token("name", "of");
|
||||
ctor = AST_ForAwaitOf;
|
||||
} else if (is("operator", "in")) {
|
||||
@@ -1308,6 +1315,11 @@ function parse($TEXT, options) {
|
||||
}
|
||||
if (node instanceof AST_SymbolFunarg) return node;
|
||||
if (node instanceof AST_SymbolRef) return new AST_SymbolFunarg(node);
|
||||
if (node instanceof AST_Yield) return new AST_SymbolFunarg({
|
||||
start: node.start,
|
||||
name: "yield",
|
||||
end: node.end,
|
||||
});
|
||||
token_error(node.start, "Invalid arrow parameter");
|
||||
}
|
||||
|
||||
@@ -1327,11 +1339,11 @@ function parse($TEXT, options) {
|
||||
var loop = S.in_loop;
|
||||
var labels = S.labels;
|
||||
++S.in_function;
|
||||
S.in_directives = true;
|
||||
S.input.push_directives_stack();
|
||||
S.in_loop = 0;
|
||||
S.labels = [];
|
||||
if (is("punc", "{")) {
|
||||
S.in_directives = true;
|
||||
body = block_();
|
||||
value = null;
|
||||
} else {
|
||||
@@ -1399,7 +1411,7 @@ function parse($TEXT, options) {
|
||||
name: name,
|
||||
argnames: argnames,
|
||||
rest: argnames.rest || null,
|
||||
body: body
|
||||
body: body,
|
||||
});
|
||||
if (is_strict) {
|
||||
if (name) strict_verify_symbol(name);
|
||||
@@ -1422,28 +1434,41 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function is_alias() {
|
||||
return is("name") || is_identifier_string(S.token.value);
|
||||
return is("name") || is("string") || is_identifier_string(S.token.value);
|
||||
}
|
||||
|
||||
function make_string(token) {
|
||||
return new AST_String({
|
||||
start: token,
|
||||
quote: token.quote,
|
||||
value: token.value,
|
||||
end: token,
|
||||
});
|
||||
}
|
||||
|
||||
function as_path() {
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return make_string(path);
|
||||
}
|
||||
|
||||
function export_() {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
var alias = key;
|
||||
next();
|
||||
var alias = "*";
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
alias = S.token.value;
|
||||
alias = S.token;
|
||||
next();
|
||||
}
|
||||
expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: [ alias ],
|
||||
keys: [ "*" ],
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: [ make_string(alias) ],
|
||||
keys: [ make_string(key) ],
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
if (is("punc", "{")) {
|
||||
@@ -1457,26 +1482,20 @@ function parse($TEXT, options) {
|
||||
if (is("name", "as")) {
|
||||
next();
|
||||
if (!is_alias()) expect_token("name");
|
||||
aliases.push(S.token.value);
|
||||
aliases.push(S.token);
|
||||
next();
|
||||
} else {
|
||||
aliases.push(key.value);
|
||||
aliases.push(key);
|
||||
}
|
||||
if (!is("punc", "}")) expect(",");
|
||||
}
|
||||
expect("}");
|
||||
if (is("name", "from")) {
|
||||
next();
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_ExportForeign({
|
||||
aliases: aliases,
|
||||
keys: keys.map(function(token) {
|
||||
return token.value;
|
||||
}),
|
||||
path: path.value,
|
||||
quote: path.quote,
|
||||
aliases: aliases.map(make_string),
|
||||
keys: keys.map(make_string),
|
||||
path: as_path(),
|
||||
});
|
||||
}
|
||||
semicolon();
|
||||
@@ -1484,7 +1503,7 @@ function parse($TEXT, options) {
|
||||
properties: keys.map(function(token, index) {
|
||||
if (!is_token(token, "name")) token_error(token, "Name expected");
|
||||
var sym = _make_symbol(AST_SymbolExport, token);
|
||||
sym.alias = aliases[index];
|
||||
sym.alias = make_string(aliases[index]);
|
||||
return sym;
|
||||
}),
|
||||
});
|
||||
@@ -1535,12 +1554,18 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
var export_decl = embed_tokens(function() {
|
||||
if (is("name", "async")) {
|
||||
if (is("name")) switch (S.token.value) {
|
||||
case "async":
|
||||
next();
|
||||
expect_token("keyword", "function");
|
||||
if (!is("operator", "*")) return function_(AST_AsyncDefun);
|
||||
next();
|
||||
return function_(AST_AsyncGeneratorDefun);
|
||||
case "let":
|
||||
next();
|
||||
var node = let_();
|
||||
semicolon();
|
||||
return node;
|
||||
} else if (is("keyword")) switch (S.token.value) {
|
||||
case "class":
|
||||
next();
|
||||
@@ -1555,11 +1580,6 @@ function parse($TEXT, options) {
|
||||
if (!is("operator", "*")) return function_(AST_Defun);
|
||||
next();
|
||||
return function_(AST_GeneratorDefun);
|
||||
case "let":
|
||||
next();
|
||||
var node = let_();
|
||||
semicolon();
|
||||
return node;
|
||||
case "var":
|
||||
next();
|
||||
var node = var_();
|
||||
@@ -1573,26 +1593,42 @@ function parse($TEXT, options) {
|
||||
var all = null;
|
||||
var def = as_symbol(AST_SymbolImport, true);
|
||||
var props = null;
|
||||
if (def ? (def.key = "", is("punc", ",") && next()) : !is("string")) {
|
||||
var cont;
|
||||
if (def) {
|
||||
def.key = new AST_String({
|
||||
start: def.start,
|
||||
value: "",
|
||||
end: def.end,
|
||||
});
|
||||
if (cont = is("punc", ",")) next();
|
||||
} else {
|
||||
cont = !is("string");
|
||||
}
|
||||
if (cont) {
|
||||
if (is("operator", "*")) {
|
||||
var key = S.token;
|
||||
next();
|
||||
expect_token("name", "as");
|
||||
all = as_symbol(AST_SymbolImport);
|
||||
all.key = "*";
|
||||
all.key = make_string(key);
|
||||
} else {
|
||||
expect("{");
|
||||
props = [];
|
||||
while (is_alias()) {
|
||||
var alias;
|
||||
if (is_token(peek(), "name", "as")) {
|
||||
var key = S.token.value;
|
||||
var key = S.token;
|
||||
next();
|
||||
next();
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = key;
|
||||
alias.key = make_string(key);
|
||||
} else {
|
||||
alias = as_symbol(AST_SymbolImport);
|
||||
alias.key = alias.name;
|
||||
alias.key = new AST_String({
|
||||
start: alias.start,
|
||||
value: alias.name,
|
||||
end: alias.end,
|
||||
});
|
||||
}
|
||||
props.push(alias);
|
||||
if (!is("punc", "}")) expect(",");
|
||||
@@ -1601,15 +1637,11 @@ function parse($TEXT, options) {
|
||||
}
|
||||
}
|
||||
if (all || def || props) expect_token("name", "from");
|
||||
var path = S.token;
|
||||
expect_token("string");
|
||||
semicolon();
|
||||
return new AST_Import({
|
||||
all: all,
|
||||
default: def,
|
||||
path: path.value,
|
||||
path: as_path(),
|
||||
properties: props,
|
||||
quote: path.quote,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1720,6 +1752,11 @@ function parse($TEXT, options) {
|
||||
return a;
|
||||
}
|
||||
|
||||
function is_vardefs() {
|
||||
var token = peek();
|
||||
return is_token(token, "name") || is_token(token, "punc", "[") || is_token(token, "punc", "{");
|
||||
}
|
||||
|
||||
var const_ = function(no_in) {
|
||||
return new AST_Const({
|
||||
start : prev(),
|
||||
@@ -1782,7 +1819,7 @@ function parse($TEXT, options) {
|
||||
ret = new AST_BigInt({ value: value });
|
||||
break;
|
||||
case "string":
|
||||
ret = new AST_String({ value : value, quote : tok.quote });
|
||||
ret = new AST_String({ value: value, quote: tok.quote });
|
||||
break;
|
||||
case "regexp":
|
||||
ret = new AST_RegExp({ value: value });
|
||||
@@ -2130,7 +2167,7 @@ function parse($TEXT, options) {
|
||||
}
|
||||
|
||||
function strict_verify_symbol(sym) {
|
||||
if (sym.name == "arguments" || sym.name == "eval")
|
||||
if (sym.name == "arguments" || sym.name == "eval" || sym.name == "let")
|
||||
token_error(sym.start, "Unexpected " + sym.name + " in strict mode");
|
||||
}
|
||||
|
||||
@@ -2297,9 +2334,8 @@ function parse($TEXT, options) {
|
||||
var comments = start.comments_before;
|
||||
var i = HOP(start, "comments_before_length") ? start.comments_before_length : comments.length;
|
||||
while (--i >= 0) {
|
||||
var match = /[@#]__PURE__/.exec(comments[i].value);
|
||||
if (match) {
|
||||
expr.pure = match[0];
|
||||
if (/[@#]__PURE__/.test(comments[i].value)) {
|
||||
expr.pure = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2532,9 +2568,13 @@ function parse($TEXT, options) {
|
||||
return function() {
|
||||
var start = S.token;
|
||||
var body = [];
|
||||
if (options.module) {
|
||||
S.in_async = true;
|
||||
S.input.add_directive("use strict");
|
||||
}
|
||||
S.input.push_directives_stack();
|
||||
while (!is("eof"))
|
||||
body.push(statement());
|
||||
body.push(statement(true));
|
||||
S.input.pop_directives_stack();
|
||||
var end = prev() || start;
|
||||
var toplevel = options.toplevel;
|
||||
|
||||
@@ -43,10 +43,11 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
var builtins = function() {
|
||||
var names = [];
|
||||
// NaN will be included due to Number.NaN
|
||||
function get_builtins() {
|
||||
var names = new Dictionary();
|
||||
// constants
|
||||
[
|
||||
"NaN",
|
||||
"null",
|
||||
"true",
|
||||
"false",
|
||||
@@ -54,35 +55,79 @@ var builtins = function() {
|
||||
"-Infinity",
|
||||
"undefined",
|
||||
].forEach(add);
|
||||
// global functions
|
||||
[
|
||||
Array,
|
||||
Boolean,
|
||||
Date,
|
||||
Error,
|
||||
Function,
|
||||
Math,
|
||||
Number,
|
||||
Object,
|
||||
RegExp,
|
||||
String,
|
||||
].forEach(function(ctor) {
|
||||
"encodeURI",
|
||||
"encodeURIComponent",
|
||||
"escape",
|
||||
"eval",
|
||||
"decodeURI",
|
||||
"decodeURIComponent",
|
||||
"isFinite",
|
||||
"isNaN",
|
||||
"parseFloat",
|
||||
"parseInt",
|
||||
"unescape",
|
||||
].forEach(add);
|
||||
// global constructors & objects
|
||||
var global = Function("return this")();
|
||||
[
|
||||
"Array",
|
||||
"ArrayBuffer",
|
||||
"Atomics",
|
||||
"BigInt",
|
||||
"Boolean",
|
||||
"console",
|
||||
"DataView",
|
||||
"Date",
|
||||
"Error",
|
||||
"Function",
|
||||
"Int8Array",
|
||||
"Intl",
|
||||
"JSON",
|
||||
"Map",
|
||||
"Math",
|
||||
"Number",
|
||||
"Object",
|
||||
"Promise",
|
||||
"Proxy",
|
||||
"Reflect",
|
||||
"RegExp",
|
||||
"Set",
|
||||
"String",
|
||||
"Symbol",
|
||||
"WebAssembly",
|
||||
].forEach(function(name) {
|
||||
add(name);
|
||||
var ctor = global[name];
|
||||
if (!ctor) return;
|
||||
Object.getOwnPropertyNames(ctor).map(add);
|
||||
if (ctor.prototype) {
|
||||
if (typeof ctor != "function") return;
|
||||
if (ctor.__proto__) Object.getOwnPropertyNames(ctor.__proto__).map(add);
|
||||
if (ctor.prototype) Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
try {
|
||||
Object.getOwnPropertyNames(new ctor()).map(add);
|
||||
Object.getOwnPropertyNames(ctor.prototype).map(add);
|
||||
} catch (e) {
|
||||
try {
|
||||
Object.getOwnPropertyNames(ctor()).map(add);
|
||||
} catch (e) {}
|
||||
}
|
||||
});
|
||||
return makePredicate(names);
|
||||
return (get_builtins = function() {
|
||||
return names.clone();
|
||||
})();
|
||||
|
||||
function add(name) {
|
||||
names.push(name);
|
||||
names.set(name, true);
|
||||
}
|
||||
}();
|
||||
}
|
||||
|
||||
function reserve_quoted_keys(ast, reserved) {
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_ClassProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Dot) {
|
||||
if (node.quoted) add(node.property);
|
||||
} else if (node instanceof AST_ObjectProperty) {
|
||||
if (node.start && node.start.quote) add(node.key);
|
||||
} else if (node instanceof AST_Sub) {
|
||||
@@ -116,9 +161,9 @@ function mangle_properties(ast, options) {
|
||||
reserved: null,
|
||||
}, true);
|
||||
|
||||
var reserved = Object.create(options.builtins ? null : builtins);
|
||||
var reserved = options.builtins ? new Dictionary() : get_builtins();
|
||||
if (Array.isArray(options.reserved)) options.reserved.forEach(function(name) {
|
||||
reserved[name] = true;
|
||||
reserved.set(name, true);
|
||||
});
|
||||
|
||||
var cname = -1;
|
||||
@@ -126,7 +171,7 @@ function mangle_properties(ast, options) {
|
||||
if (options.cache) {
|
||||
cache = options.cache.props;
|
||||
cache.each(function(name) {
|
||||
reserved[name] = true;
|
||||
reserved.set(name, true);
|
||||
});
|
||||
} else {
|
||||
cache = new Dictionary();
|
||||
@@ -141,8 +186,8 @@ function mangle_properties(ast, options) {
|
||||
var debug_suffix;
|
||||
if (debug) debug_suffix = options.debug === true ? "" : options.debug;
|
||||
|
||||
var names_to_mangle = Object.create(null);
|
||||
var unmangleable = Object.create(reserved);
|
||||
var names_to_mangle = new Dictionary();
|
||||
var unmangleable = reserved.clone();
|
||||
|
||||
// step 1: find candidates to mangle
|
||||
ast.walk(new TreeWalker(function(node) {
|
||||
@@ -211,20 +256,26 @@ function mangle_properties(ast, options) {
|
||||
// only function declarations after this line
|
||||
|
||||
function can_mangle(name) {
|
||||
if (unmangleable[name]) return false;
|
||||
if (unmangleable.has(name)) return false;
|
||||
if (/^-?[0-9]+(\.[0-9]+)?(e[+-][0-9]+)?$/.test(name)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
function should_mangle(name) {
|
||||
if (reserved[name]) return false;
|
||||
if (regex && !regex.test(name)) return false;
|
||||
return cache.has(name) || names_to_mangle[name];
|
||||
if (reserved.has(name)) {
|
||||
AST_Node.info("Preserving reserved property {this}", name);
|
||||
return false;
|
||||
}
|
||||
if (regex && !regex.test(name)) {
|
||||
AST_Node.info("Preserving excluded property {this}", name);
|
||||
return false;
|
||||
}
|
||||
return cache.has(name) || names_to_mangle.has(name);
|
||||
}
|
||||
|
||||
function add(name) {
|
||||
if (can_mangle(name)) names_to_mangle[name] = true;
|
||||
if (!should_mangle(name)) unmangleable[name] = true;
|
||||
if (can_mangle(name)) names_to_mangle.set(name, true);
|
||||
if (!should_mangle(name)) unmangleable.set(name, true);
|
||||
}
|
||||
|
||||
function mangle(name) {
|
||||
@@ -243,6 +294,10 @@ function mangle_properties(ast, options) {
|
||||
if (/^#/.test(name)) mangled = "#" + mangled;
|
||||
cache.set(name, mangled);
|
||||
}
|
||||
AST_Node.info("Mapping property {name} to {mangled}", {
|
||||
mangled: mangled,
|
||||
name: name,
|
||||
});
|
||||
return mangled;
|
||||
}
|
||||
|
||||
|
||||
189
lib/scope.js
189
lib/scope.js
@@ -44,9 +44,9 @@
|
||||
"use strict";
|
||||
|
||||
function SymbolDef(id, scope, orig, init) {
|
||||
this._bits = 0;
|
||||
this.defun = undefined;
|
||||
this.eliminated = 0;
|
||||
this.exported = false;
|
||||
this.global = false;
|
||||
this.id = id;
|
||||
this.init = init;
|
||||
this.mangled_name = null;
|
||||
@@ -54,8 +54,8 @@ function SymbolDef(id, scope, orig, init) {
|
||||
this.orig = [ orig ];
|
||||
this.references = [];
|
||||
this.replaced = 0;
|
||||
this.safe_ids = undefined;
|
||||
this.scope = scope;
|
||||
this.undeclared = false;
|
||||
}
|
||||
|
||||
SymbolDef.prototype = {
|
||||
@@ -64,19 +64,20 @@ SymbolDef.prototype = {
|
||||
this.references.forEach(fn);
|
||||
},
|
||||
mangle: function(options) {
|
||||
var cache = options.cache && options.cache.props;
|
||||
if (this.global && cache && cache.has(this.name)) {
|
||||
if (this.mangled_name) return;
|
||||
var cache = this.global && options.cache && options.cache.props;
|
||||
if (cache && cache.has(this.name)) {
|
||||
this.mangled_name = cache.get(this.name);
|
||||
} else if (!this.mangled_name && !this.unmangleable(options)) {
|
||||
} else if (this.unmangleable(options)) {
|
||||
names_in_use(this.scope, options).set(this.name, true);
|
||||
} else {
|
||||
var def = this.redefined();
|
||||
if (def) {
|
||||
this.mangled_name = def.mangled_name || def.name;
|
||||
} else {
|
||||
this.mangled_name = next_mangled_name(this, options);
|
||||
}
|
||||
if (this.global && cache) {
|
||||
cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
if (cache) cache.set(this.name, this.mangled_name);
|
||||
}
|
||||
},
|
||||
redefined: function() {
|
||||
@@ -92,18 +93,35 @@ SymbolDef.prototype = {
|
||||
if (def && def !== self) return def.redefined() || def;
|
||||
},
|
||||
unmangleable: function(options) {
|
||||
return this.global && !options.toplevel
|
||||
|| this.exported
|
||||
|| this.undeclared
|
||||
|| !options.eval && this.scope.pinned()
|
||||
|| options.keep_fnames
|
||||
&& (this.orig[0] instanceof AST_SymbolClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefClass
|
||||
|| this.orig[0] instanceof AST_SymbolDefun
|
||||
|| this.orig[0] instanceof AST_SymbolLambda);
|
||||
if (this.exported) return true;
|
||||
if (this.undeclared) return true;
|
||||
if (!options.eval && this.scope.pinned()) return true;
|
||||
if (options.keep_fargs && is_funarg(this)) return true;
|
||||
if (options.keep_fnames) {
|
||||
var sym = this.orig[0];
|
||||
if (sym instanceof AST_SymbolClass) return true;
|
||||
if (sym instanceof AST_SymbolDefClass) return true;
|
||||
if (sym instanceof AST_SymbolDefun) return true;
|
||||
if (sym instanceof AST_SymbolLambda) return true;
|
||||
}
|
||||
if (!options.toplevel && this.global) return true;
|
||||
return false;
|
||||
},
|
||||
};
|
||||
|
||||
DEF_BITPROPS(SymbolDef, [
|
||||
"const_redefs",
|
||||
"cross_loop",
|
||||
"direct_access",
|
||||
"exported",
|
||||
"global",
|
||||
"undeclared",
|
||||
]);
|
||||
|
||||
function is_funarg(def) {
|
||||
return def.orig[0] instanceof AST_SymbolFunarg || def.orig[1] instanceof AST_SymbolFunarg;
|
||||
}
|
||||
|
||||
var unary_side_effects = makePredicate("delete ++ --");
|
||||
|
||||
function is_lhs(node, parent) {
|
||||
@@ -205,20 +223,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
} else if (node instanceof AST_SymbolDefun) {
|
||||
var def = defun.def_function(node, tw.parent());
|
||||
if (exported) def.exported = true;
|
||||
entangle(defun, scope);
|
||||
} else if (node instanceof AST_SymbolFunarg) {
|
||||
defun.def_variable(node);
|
||||
entangle(defun, scope);
|
||||
} else if (node instanceof AST_SymbolLambda) {
|
||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||
if (options.ie) def.defun = defun.parent_scope.resolve();
|
||||
if (options.ie && node.name != "arguments") def.defun = defun.parent_scope.resolve();
|
||||
} else if (node instanceof AST_SymbolLet) {
|
||||
var def = scope.def_variable(node);
|
||||
if (exported) def.exported = true;
|
||||
} else if (node instanceof AST_SymbolVar) {
|
||||
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
|
||||
if (exported) def.exported = true;
|
||||
entangle(defun, scope);
|
||||
}
|
||||
|
||||
function walk_scope(descend) {
|
||||
@@ -231,16 +246,6 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
scope = save_scope;
|
||||
defun = save_defun;
|
||||
}
|
||||
|
||||
function entangle(defun, scope) {
|
||||
if (defun === scope) return;
|
||||
node.mark_enclosed(options);
|
||||
var def = scope.find_variable(node.name);
|
||||
if (node.thedef === def) return;
|
||||
node.thedef = def;
|
||||
def.orig.push(node);
|
||||
node.mark_enclosed(options);
|
||||
}
|
||||
});
|
||||
self.make_def = function(orig, init) {
|
||||
return new SymbolDef(++next_def_id, this, orig, init);
|
||||
@@ -261,6 +266,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
}
|
||||
if (node instanceof AST_Lambda) {
|
||||
in_arg.push(node);
|
||||
if (node.name) node.name.walk(tw);
|
||||
node.argnames.forEach(function(argname) {
|
||||
argname.walk(tw);
|
||||
});
|
||||
@@ -280,13 +286,23 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// ensure mangling works if `catch` reuses a scope variable
|
||||
var redef = def.redefined();
|
||||
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, redef);
|
||||
if (!push_uniq(s.enclosed, redef)) break;
|
||||
if (s === redef.scope) break;
|
||||
}
|
||||
} else if (node instanceof AST_SymbolConst) {
|
||||
// ensure compression works if `const` reuses a scope variable
|
||||
var redef = def.redefined();
|
||||
if (redef) redef.const_redefs = true;
|
||||
} else if (def.scope !== node.scope && (node instanceof AST_SymbolDefun
|
||||
|| node instanceof AST_SymbolFunarg
|
||||
|| node instanceof AST_SymbolVar)) {
|
||||
node.mark_enclosed(options);
|
||||
var redef = node.scope.find_variable(node.name);
|
||||
if (node.thedef !== redef) {
|
||||
node.thedef = redef;
|
||||
redef.orig.push(node);
|
||||
node.mark_enclosed(options);
|
||||
}
|
||||
}
|
||||
if (node.name != "arguments") return true;
|
||||
var parent = node instanceof AST_SymbolVar && tw.parent();
|
||||
@@ -353,8 +369,9 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
// pass 3: fix up any scoping issue with IE8
|
||||
if (options.ie) self.walk(new TreeWalker(function(node) {
|
||||
if (node instanceof AST_SymbolCatch) {
|
||||
var scope = node.thedef.defun;
|
||||
if (scope.name instanceof AST_SymbolLambda && scope.name.name == node.name) {
|
||||
var def = node.thedef;
|
||||
var scope = def.defun;
|
||||
if (def.name != "arguments" && scope.name instanceof AST_SymbolLambda && scope.name.name == def.name) {
|
||||
scope = scope.parent_scope.resolve();
|
||||
}
|
||||
redefine(node, scope);
|
||||
@@ -363,7 +380,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
||||
if (node instanceof AST_SymbolLambda) {
|
||||
var def = node.thedef;
|
||||
if (!redefine(node, node.scope.parent_scope.resolve())) {
|
||||
delete def.defun;
|
||||
def.defun = undefined;
|
||||
} else if (typeof node.thedef.init !== "undefined") {
|
||||
node.thedef.init = false;
|
||||
} else if (def.init) {
|
||||
@@ -454,6 +471,7 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
this.uses_arguments = false;
|
||||
this.def_variable(new AST_SymbolFunarg({
|
||||
name: "arguments",
|
||||
scope: this,
|
||||
start: this.start,
|
||||
end: this.end,
|
||||
}));
|
||||
@@ -463,11 +481,14 @@ AST_Lambda.DEFMETHOD("init_vars", function(parent_scope) {
|
||||
AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
||||
var def = this.definition();
|
||||
for (var s = this.scope; s; s = s.parent_scope) {
|
||||
push_uniq(s.enclosed, def);
|
||||
if (!push_uniq(s.enclosed, def)) break;
|
||||
if (!options) {
|
||||
delete s._var_names;
|
||||
} else if (options.keep_fnames) {
|
||||
s.functions.each(function(d) {
|
||||
s._var_names = undefined;
|
||||
} else {
|
||||
if (options.keep_fargs && s instanceof AST_Lambda) s.each_argname(function(arg) {
|
||||
push_uniq(def.scope.enclosed, arg.definition());
|
||||
});
|
||||
if (options.keep_fnames) s.functions.each(function(d) {
|
||||
push_uniq(def.scope.enclosed, d);
|
||||
});
|
||||
}
|
||||
@@ -510,12 +531,12 @@ function names_in_use(scope, options) {
|
||||
if (!names) {
|
||||
scope.cname = -1;
|
||||
scope.cname_holes = [];
|
||||
scope.names_in_use = names = Object.create(null);
|
||||
scope.names_in_use = names = new Dictionary();
|
||||
var cache = options.cache && options.cache.props;
|
||||
scope.enclosed.forEach(function(def) {
|
||||
if (def.unmangleable(options)) names[def.name] = true;
|
||||
if (def.unmangleable(options)) names.set(def.name, true);
|
||||
if (def.global && cache && cache.has(def.name)) {
|
||||
names[cache.get(def.name)] = true;
|
||||
names.set(cache.get(def.name), true);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -526,34 +547,33 @@ function next_mangled_name(def, options) {
|
||||
var scope = def.scope;
|
||||
var in_use = names_in_use(scope, options);
|
||||
var holes = scope.cname_holes;
|
||||
var names = Object.create(null);
|
||||
var names = new Dictionary();
|
||||
var scopes = [ scope ];
|
||||
def.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;
|
||||
if (member(scope, scopes)) break;
|
||||
names_in_use(scope, options).each(function(marker, name) {
|
||||
names.set(name, marker);
|
||||
});
|
||||
scopes.push(scope);
|
||||
} while (scope = scope.parent_scope);
|
||||
});
|
||||
var name;
|
||||
for (var i = 0; i < holes.length; i++) {
|
||||
name = base54(holes[i]);
|
||||
if (names[name]) continue;
|
||||
if (names.has(name)) continue;
|
||||
holes.splice(i, 1);
|
||||
in_use[name] = true;
|
||||
in_use.set(name, true);
|
||||
return name;
|
||||
}
|
||||
while (true) {
|
||||
name = base54(++scope.cname);
|
||||
if (in_use[name] || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||
if (!names[name]) break;
|
||||
if (in_use.has(name) || RESERVED_WORDS[name] || options.reserved.has[name]) continue;
|
||||
if (!names.has(name)) break;
|
||||
holes.push(scope.cname);
|
||||
}
|
||||
in_use[name] = true;
|
||||
in_use.set(name, true);
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -573,6 +593,7 @@ function _default_mangler_options(options) {
|
||||
options = defaults(options, {
|
||||
eval : false,
|
||||
ie : false,
|
||||
keep_fargs : false,
|
||||
keep_fnames : false,
|
||||
reserved : [],
|
||||
toplevel : false,
|
||||
@@ -580,38 +601,32 @@ function _default_mangler_options(options) {
|
||||
webkit : false,
|
||||
});
|
||||
if (!Array.isArray(options.reserved)) options.reserved = [];
|
||||
// Never mangle arguments
|
||||
// Never mangle `arguments`
|
||||
push_uniq(options.reserved, "arguments");
|
||||
options.reserved.has = makePredicate(options.reserved);
|
||||
return options;
|
||||
}
|
||||
|
||||
// We only need to mangle declaration nodes. Special logic wired into the code
|
||||
// generator will display the mangled name if it is present (and for
|
||||
// `AST_SymbolRef`s it will use the mangled name of the `AST_SymbolDeclaration`
|
||||
// that it points to).
|
||||
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;
|
||||
|
||||
if (options.cache && options.cache.props) {
|
||||
var mangled_names = names_in_use(this, options);
|
||||
options.cache.props.each(function(mangled_name) {
|
||||
mangled_names[mangled_name] = true;
|
||||
mangled_names.set(mangled_name, true);
|
||||
});
|
||||
}
|
||||
|
||||
var cutoff = 36;
|
||||
var lname = -1;
|
||||
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();
|
||||
if (!options.v8 || !in_label(tw)) lname = save_nesting;
|
||||
return true;
|
||||
}
|
||||
var save_nesting;
|
||||
if (node instanceof AST_BlockScope) {
|
||||
// `lname` is incremented when we get to the `AST_Label`
|
||||
if (node instanceof AST_LabeledStatement) save_nesting = lname;
|
||||
if (options.webkit && node instanceof AST_IterationStatement && node.init instanceof AST_Let) {
|
||||
node.init.definitions.forEach(function(defn) {
|
||||
defn.name.match_symbol(function(sym) {
|
||||
@@ -627,9 +642,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
});
|
||||
}, true);
|
||||
}
|
||||
node.to_mangle = [];
|
||||
var to_mangle = node.to_mangle = [];
|
||||
node.variables.each(function(def) {
|
||||
if (!defer_redef(def)) node.to_mangle.push(def);
|
||||
if (!defer_redef(def)) to_mangle.push(def);
|
||||
});
|
||||
descend();
|
||||
if (options.cache && node instanceof AST_Toplevel) {
|
||||
@@ -640,7 +655,24 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
sym.scope = node;
|
||||
sym.reference(options);
|
||||
}
|
||||
node.to_mangle.forEach(mangle);
|
||||
if (to_mangle.length > cutoff) {
|
||||
var indices = to_mangle.map(function(def, index) {
|
||||
return index;
|
||||
}).sort(function(i, j) {
|
||||
return to_mangle[j].references.length - to_mangle[i].references.length || i - j;
|
||||
});
|
||||
to_mangle = indices.slice(0, cutoff).sort(function(i, j) {
|
||||
return i - j;
|
||||
}).map(function(index) {
|
||||
return to_mangle[index];
|
||||
}).concat(indices.slice(cutoff).sort(function(i, j) {
|
||||
return i - j;
|
||||
}).map(function(index) {
|
||||
return to_mangle[index];
|
||||
}));
|
||||
}
|
||||
to_mangle.forEach(mangle);
|
||||
if (node instanceof AST_LabeledStatement && !(options.v8 && in_label(tw))) lname = save_nesting;
|
||||
return true;
|
||||
}
|
||||
if (node instanceof AST_Label) {
|
||||
@@ -673,7 +705,12 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
|
||||
}
|
||||
redefined.push(def);
|
||||
def.references.forEach(reference);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) reference(sym);
|
||||
if (sym instanceof AST_SymbolCatch || sym instanceof AST_SymbolConst) {
|
||||
reference(sym);
|
||||
def.redefined = function() {
|
||||
return redef;
|
||||
};
|
||||
}
|
||||
return true;
|
||||
|
||||
function reference(sym) {
|
||||
|
||||
@@ -77,21 +77,23 @@ function vlq_encode(num) {
|
||||
}
|
||||
|
||||
function create_array_map() {
|
||||
var map = Object.create(null);
|
||||
var map = new Dictionary();
|
||||
var array = [];
|
||||
array.index = function(name) {
|
||||
if (!HOP(map, name)) {
|
||||
map[name] = array.length;
|
||||
var index = map.get(name);
|
||||
if (!(index >= 0)) {
|
||||
index = array.length;
|
||||
array.push(name);
|
||||
map.set(name, index);
|
||||
}
|
||||
return map[name];
|
||||
return index;
|
||||
};
|
||||
return array;
|
||||
}
|
||||
|
||||
function SourceMap(options) {
|
||||
var sources = create_array_map();
|
||||
var sources_content = options.includeSources && Object.create(null);
|
||||
var sources_content = options.includeSources && new Dictionary();
|
||||
var names = create_array_map();
|
||||
var mappings = "";
|
||||
if (options.orig) Object.keys(options.orig).forEach(function(name) {
|
||||
@@ -110,7 +112,7 @@ function SourceMap(options) {
|
||||
if (!sources_content || !map.sourcesContent) return;
|
||||
for (var i = 0; i < map.sources.length; i++) {
|
||||
var content = map.sourcesContent[i];
|
||||
if (content) sources_content[map.sources[i]] = content;
|
||||
if (content) sources_content.set(map.sources[i], content);
|
||||
}
|
||||
});
|
||||
var prev_source;
|
||||
@@ -144,8 +146,8 @@ function SourceMap(options) {
|
||||
add(source, gen_line, gen_col, orig_line, orig_col, name);
|
||||
} : add,
|
||||
setSourceContent: sources_content ? function(source, content) {
|
||||
if (!(source in sources_content)) {
|
||||
sources_content[source] = content;
|
||||
if (!sources_content.has(source)) {
|
||||
sources_content.set(source, content);
|
||||
}
|
||||
} : noop,
|
||||
toString: function() {
|
||||
@@ -155,7 +157,7 @@ function SourceMap(options) {
|
||||
sourceRoot: options.root || undefined,
|
||||
sources: sources,
|
||||
sourcesContent: sources_content ? sources.map(function(source) {
|
||||
return sources_content[source] || null;
|
||||
return sources_content.get(source) || null;
|
||||
}) : undefined,
|
||||
names: names,
|
||||
mappings: mappings,
|
||||
|
||||
108
lib/utils.js
108
lib/utils.js
@@ -55,14 +55,6 @@ function find_if(func, array) {
|
||||
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;
|
||||
return i & 1 ? d + str : d;
|
||||
}
|
||||
|
||||
function configure_error_stack(fn) {
|
||||
Object.defineProperty(fn.prototype, "stack", {
|
||||
get: function() {
|
||||
@@ -96,15 +88,6 @@ function defaults(args, defs, croak) {
|
||||
return defs;
|
||||
}
|
||||
|
||||
function merge(obj, ext) {
|
||||
var count = 0;
|
||||
for (var i in ext) if (HOP(ext, i)) {
|
||||
obj[i] = ext[i];
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
function noop() {}
|
||||
function return_false() { return false; }
|
||||
function return_true() { return true; }
|
||||
@@ -143,9 +126,11 @@ function push_uniq(array, el) {
|
||||
}
|
||||
|
||||
function string_template(text, props) {
|
||||
return text.replace(/\{([^}]+)\}/g, function(str, p) {
|
||||
var value = props[p];
|
||||
return value instanceof AST_Node ? value.print_to_string() : value;
|
||||
return text.replace(/\{([^{}]+)\}/g, function(str, p) {
|
||||
var value = p == "this" ? props : props[p];
|
||||
if (value instanceof AST_Node) return value.print_to_string();
|
||||
if (value instanceof AST_Token) return value.file + ":" + value.line + "," + value.col;
|
||||
return value;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -171,63 +156,80 @@ function all(array, predicate) {
|
||||
}
|
||||
|
||||
function Dictionary() {
|
||||
this._values = Object.create(null);
|
||||
this._size = 0;
|
||||
this.values = Object.create(null);
|
||||
}
|
||||
Dictionary.prototype = {
|
||||
set: function(key, val) {
|
||||
if (!this.has(key)) ++this._size;
|
||||
this._values["$" + key] = val;
|
||||
if (key == "__proto__") {
|
||||
this.proto_value = val;
|
||||
} else {
|
||||
this.values[key] = val;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
add: function(key, val) {
|
||||
if (this.has(key)) {
|
||||
this.get(key).push(val);
|
||||
var list = this.get(key);
|
||||
if (list) {
|
||||
list.push(val);
|
||||
} else {
|
||||
this.set(key, [ val ]);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
get: function(key) { return this._values["$" + key] },
|
||||
get: function(key) {
|
||||
return key == "__proto__" ? this.proto_value : this.values[key];
|
||||
},
|
||||
del: function(key) {
|
||||
if (this.has(key)) {
|
||||
--this._size;
|
||||
delete this._values["$" + key];
|
||||
if (key == "__proto__") {
|
||||
delete this.proto_value;
|
||||
} else {
|
||||
delete this.values[key];
|
||||
}
|
||||
return this;
|
||||
},
|
||||
has: function(key) { return ("$" + key) in this._values },
|
||||
has: function(key) {
|
||||
return key == "__proto__" ? "proto_value" in this : key in this.values;
|
||||
},
|
||||
all: function(predicate) {
|
||||
for (var i in this._values)
|
||||
if (!predicate(this._values[i], i.substr(1)))
|
||||
return false;
|
||||
for (var i in this.values)
|
||||
if (!predicate(this.values[i], i)) return false;
|
||||
if ("proto_value" in this && !predicate(this.proto_value, "__proto__")) return false;
|
||||
return true;
|
||||
},
|
||||
each: function(f) {
|
||||
for (var i in this._values)
|
||||
f(this._values[i], i.substr(1));
|
||||
for (var i in this.values)
|
||||
f(this.values[i], i);
|
||||
if ("proto_value" in this) f(this.proto_value, "__proto__");
|
||||
},
|
||||
size: function() {
|
||||
return this._size;
|
||||
return Object.keys(this.values).length + ("proto_value" in this);
|
||||
},
|
||||
map: function(f) {
|
||||
var ret = [];
|
||||
for (var i in this._values)
|
||||
ret.push(f(this._values[i], i.substr(1)));
|
||||
for (var i in this.values)
|
||||
ret.push(f(this.values[i], i));
|
||||
if ("proto_value" in this) ret.push(f(this.proto_value, "__proto__"));
|
||||
return ret;
|
||||
},
|
||||
clone: function() {
|
||||
var ret = new Dictionary();
|
||||
for (var i in this._values)
|
||||
ret._values[i] = this._values[i];
|
||||
ret._size = this._size;
|
||||
this.each(function(value, i) {
|
||||
ret.set(i, value);
|
||||
});
|
||||
return ret;
|
||||
},
|
||||
toObject: function() { return this._values }
|
||||
toObject: function() {
|
||||
var obj = {};
|
||||
this.each(function(value, i) {
|
||||
obj["$" + i] = value;
|
||||
});
|
||||
return obj;
|
||||
},
|
||||
};
|
||||
Dictionary.fromObject = function(obj) {
|
||||
var dict = new Dictionary();
|
||||
dict._size = merge(dict._values, obj);
|
||||
for (var i in obj)
|
||||
if (HOP(obj, i)) dict.set(i.slice(1), obj[i]);
|
||||
return dict;
|
||||
};
|
||||
|
||||
@@ -265,3 +267,21 @@ function first_in_statement(stack, arrow, export_default) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function DEF_BITPROPS(ctor, props) {
|
||||
if (props.length > 31) throw new Error("Too many properties: " + props.length + "\n" + props.join(", "));
|
||||
props.forEach(function(name, pos) {
|
||||
var mask = 1 << pos;
|
||||
Object.defineProperty(ctor.prototype, name, {
|
||||
get: function() {
|
||||
return !!(this._bits & mask);
|
||||
},
|
||||
set: function(val) {
|
||||
if (val)
|
||||
this._bits |= mask;
|
||||
else
|
||||
this._bits &= ~mask;
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||
"license": "BSD-2-Clause",
|
||||
"version": "3.14.2",
|
||||
"version": "3.17.1",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
},
|
||||
@@ -23,7 +23,7 @@
|
||||
"LICENSE"
|
||||
],
|
||||
"devDependencies": {
|
||||
"acorn": "~8.2.1",
|
||||
"acorn": "~8.7.1",
|
||||
"semver": "~6.3.0"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -17,6 +17,7 @@ var urls = [
|
||||
"https://unpkg.com/mathjs@6.2.3/dist/math.js",
|
||||
"https://unpkg.com/react@15.3.2/dist/react.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/d3/6.7.0/d3.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/antd/4.18.7/antd.js",
|
||||
"https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js",
|
||||
"https://cdnjs.cloudflare.com/ajax/libs/ember.js/2.12.2/ember.prod.js",
|
||||
|
||||
@@ -60,8 +60,9 @@ function log() {
|
||||
console.log("%s", tmpl.apply(null, arguments));
|
||||
}
|
||||
|
||||
function make_code(ast, options) {
|
||||
function make_code(ast, options, expression) {
|
||||
var stream = U.OutputStream(options);
|
||||
if (expression) ast = ast.clone(true).unwrap_expression();
|
||||
ast.print(stream);
|
||||
return stream.get();
|
||||
}
|
||||
@@ -69,9 +70,7 @@ function make_code(ast, options) {
|
||||
function parse_test(file) {
|
||||
var script = fs.readFileSync(file, "utf8");
|
||||
try {
|
||||
var ast = U.parse(script, {
|
||||
filename: file
|
||||
});
|
||||
var ast = U.parse(script, { filename: file, module: "" });
|
||||
} catch (e) {
|
||||
console.error("Caught error while parsing tests in " + file);
|
||||
console.error(e);
|
||||
@@ -98,14 +97,14 @@ function parse_test(file) {
|
||||
file: file,
|
||||
line: node.start.line,
|
||||
col: node.start.col,
|
||||
code: make_code(node, { beautify: false })
|
||||
code: make_code(node, { beautify: false }),
|
||||
}));
|
||||
}
|
||||
|
||||
function read_string(stat) {
|
||||
if (stat.TYPE == "SimpleStatement") {
|
||||
var body = stat.body;
|
||||
switch(body.TYPE) {
|
||||
switch (body.TYPE) {
|
||||
case "String":
|
||||
return body.value;
|
||||
case "Array":
|
||||
@@ -142,7 +141,7 @@ function parse_test(file) {
|
||||
].indexOf(label.name) >= 0, tmpl("Unsupported label {name} [{line},{col}]", {
|
||||
name: label.name,
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
var stat = node.body;
|
||||
if (label.name == "expect_exact" || label.name == "node_version") {
|
||||
@@ -155,12 +154,12 @@ function parse_test(file) {
|
||||
var ctor = global[body.expression.name];
|
||||
assert.ok(ctor === Error || ctor.prototype instanceof Error, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
test[label.name] = ctor.apply(null, body.args.map(function(node) {
|
||||
assert.ok(node instanceof U.AST_Constant, tmpl("Unsupported expect_stdout format [{line},{col}]", {
|
||||
line: label.start.line,
|
||||
col: label.start.col
|
||||
col: label.start.col,
|
||||
}));
|
||||
return node.value;
|
||||
}));
|
||||
@@ -180,16 +179,23 @@ function parse_test(file) {
|
||||
|
||||
// Try to reminify original input with standard options
|
||||
// to see if it matches expect_stdout.
|
||||
function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
function reminify(expression, orig_options, input_code, input_formatted, stdout) {
|
||||
for (var i = 0; i < minify_options.length; i++) {
|
||||
var options = JSON.parse(minify_options[i]);
|
||||
if (options.compress) [
|
||||
if (expression) {
|
||||
if (!options.parse || typeof options.parse != "object") options.parse = {};
|
||||
options.parse.expression = true;
|
||||
if (options.compress == null) options.compress = {};
|
||||
if (options.compress) {
|
||||
if (typeof options.compress != "object") options.compress = {};
|
||||
options.compress.expression = true;
|
||||
}
|
||||
}
|
||||
[
|
||||
"keep_fargs",
|
||||
"keep_fnames",
|
||||
].forEach(function(name) {
|
||||
if (name in orig_options) {
|
||||
options.compress[name] = orig_options[name];
|
||||
}
|
||||
if (name in orig_options) options[name] = orig_options[name];
|
||||
});
|
||||
var options_formatted = JSON.stringify(options, null, 4);
|
||||
options.validate = true;
|
||||
@@ -214,7 +220,7 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
} else {
|
||||
var toplevel = sandbox.has_toplevel(options);
|
||||
var expected = stdout[toplevel ? 1 : 0];
|
||||
var actual = sandbox.run_code(result.code, toplevel);
|
||||
var actual = run_code(expression, result.code, toplevel);
|
||||
if (typeof expected != "string" && typeof actual != "string" && expected.name == actual.name) {
|
||||
actual = expected;
|
||||
}
|
||||
@@ -249,18 +255,23 @@ function reminify(orig_options, input_code, input_formatted, stdout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function run_code(expression, code, toplevel) {
|
||||
return sandbox.run_code(expression ? "console.log(" + code + ");" : code, toplevel);
|
||||
}
|
||||
|
||||
function test_case(test) {
|
||||
log(" Running test [{name}]", { name: test.name });
|
||||
U.AST_Node.enable_validation();
|
||||
var output_options = test.beautify || {};
|
||||
var expect;
|
||||
if (test.expect) {
|
||||
expect = make_code(to_toplevel(test.expect, test.mangle), output_options);
|
||||
expect = to_toplevel(test.expect, test.mangle, test.expression);
|
||||
expect = make_code(expect, output_options, test.expression);
|
||||
} else {
|
||||
expect = test.expect_exact;
|
||||
}
|
||||
var input = to_toplevel(test.input, test.mangle);
|
||||
var input_code = make_code(input);
|
||||
var input = to_toplevel(test.input, test.mangle, test.expression);
|
||||
var input_code = make_code(input, {}, test.expression);
|
||||
var input_formatted = make_code(test.input, {
|
||||
annotations: true,
|
||||
beautify: true,
|
||||
@@ -270,7 +281,7 @@ function test_case(test) {
|
||||
});
|
||||
try {
|
||||
input.validate_ast();
|
||||
U.parse(input_code);
|
||||
U.parse(input_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Cannot parse input",
|
||||
@@ -296,8 +307,9 @@ function test_case(test) {
|
||||
warnings_emitted.push(text);
|
||||
}, /"INFO: /.test(expected_warnings));
|
||||
}
|
||||
var quoted_props;
|
||||
if (test.mangle && test.mangle.properties && test.mangle.properties.keep_quoted) {
|
||||
var quoted_props = test.mangle.properties.reserved;
|
||||
quoted_props = test.mangle.properties.reserved;
|
||||
if (!Array.isArray(quoted_props)) quoted_props = [];
|
||||
test.mangle.properties.reserved = quoted_props;
|
||||
U.reserve_quoted_keys(input, quoted_props);
|
||||
@@ -312,9 +324,10 @@ function test_case(test) {
|
||||
if (test.mangle) {
|
||||
output.compute_char_frequency(test.mangle);
|
||||
output.mangle_names(test.mangle);
|
||||
if (quoted_props) U.reserve_quoted_keys(input, quoted_props);
|
||||
if (test.mangle.properties) U.mangle_properties(output, test.mangle.properties);
|
||||
}
|
||||
var output_code = make_code(output, output_options);
|
||||
var output_code = make_code(output, output_options, test.expression);
|
||||
U.AST_Node.log_function();
|
||||
if (expect != output_code) {
|
||||
log([
|
||||
@@ -337,7 +350,7 @@ function test_case(test) {
|
||||
// expect == output
|
||||
try {
|
||||
output.validate_ast();
|
||||
U.parse(output_code);
|
||||
U.parse(output_code, { expression: test.expression });
|
||||
} catch (ex) {
|
||||
log([
|
||||
"!!! Test matched expected result but cannot parse output",
|
||||
@@ -381,7 +394,7 @@ function test_case(test) {
|
||||
}
|
||||
}
|
||||
if (test.expect_stdout && (!test.node_version || semver.satisfies(process.version, test.node_version))) {
|
||||
var stdout = [ sandbox.run_code(input_code), sandbox.run_code(input_code, true) ];
|
||||
var stdout = [ run_code(test.expression, input_code), run_code(test.expression, input_code, true) ];
|
||||
var toplevel = sandbox.has_toplevel({
|
||||
compress: test.options,
|
||||
mangle: test.mangle
|
||||
@@ -410,7 +423,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
actual = sandbox.run_code(output_code, toplevel);
|
||||
actual = run_code(test.expression, output_code, toplevel);
|
||||
if (!sandbox.same_stdout(test.expect_stdout, actual)) {
|
||||
log([
|
||||
"!!! failed",
|
||||
@@ -431,7 +444,7 @@ function test_case(test) {
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (!reminify(test.options, input_code, input_formatted, stdout)) {
|
||||
if (!reminify(test.expression, test.options, input_code, input_formatted, stdout)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -442,20 +455,30 @@ function tmpl() {
|
||||
return U.string_template.apply(null, arguments);
|
||||
}
|
||||
|
||||
function to_toplevel(input, mangle_options) {
|
||||
function to_toplevel(input, mangle_options, expression) {
|
||||
if (!(input instanceof U.AST_BlockStatement)) throw new Error("Unsupported input syntax");
|
||||
var directive = true;
|
||||
var offset = input.start.line;
|
||||
var tokens = [];
|
||||
var toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
input.walk(new U.TreeWalker(function(node) {
|
||||
if (U.push_uniq(tokens, node.start)) node.start.line -= offset;
|
||||
if (!directive || node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
} else {
|
||||
if (U.push_uniq(tokens, node.end)) node.end.line -= offset;
|
||||
}));
|
||||
var toplevel;
|
||||
if (!expression) {
|
||||
var directive = true;
|
||||
toplevel = new U.AST_Toplevel(input.transform(new U.TreeTransformer(function(node) {
|
||||
if (!directive) return node;
|
||||
if (node === input) return;
|
||||
if (node instanceof U.AST_SimpleStatement && node.body instanceof U.AST_String) {
|
||||
return new U.AST_Directive(node.body);
|
||||
}
|
||||
directive = false;
|
||||
}
|
||||
})));
|
||||
})));
|
||||
} else if (input.body.length == 1) {
|
||||
toplevel = input.body[0].wrap_expression();
|
||||
} else {
|
||||
throw new Error("Invalid expression");
|
||||
}
|
||||
toplevel.figure_out_scope(mangle_options);
|
||||
return toplevel;
|
||||
}
|
||||
|
||||
@@ -442,9 +442,9 @@ compress_annotations_disabled_output_annotations_enabled: {
|
||||
}
|
||||
expect_exact: [
|
||||
"/*@__PURE__*/a(3),",
|
||||
"/*#__PURE__*/b(5),",
|
||||
"/*@__PURE__*/b(5),",
|
||||
"c(side_effect),",
|
||||
"/*#__PURE__*/d(effect());",
|
||||
"/*@__PURE__*/d(effect());",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -363,6 +363,28 @@ negate: {
|
||||
}
|
||||
|
||||
inline_this: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var p = "PASS";
|
||||
console.log({
|
||||
p: "FAIL",
|
||||
q: (() => this.p)(),
|
||||
}.q);
|
||||
}
|
||||
expect: {
|
||||
var p = "PASS";
|
||||
console.log({
|
||||
p: "FAIL",
|
||||
q: this.p,
|
||||
}.q);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dont_inline_this: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
@@ -486,7 +508,7 @@ drop_value: {
|
||||
((a, b) => a + b)(console.log(42));
|
||||
}
|
||||
expect: {
|
||||
((a, b) => {})(console.log(42));
|
||||
void console.log(42);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=4"
|
||||
@@ -646,6 +668,28 @@ single_use_recursive: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_iife_within_arrow: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => console.log(function(a) {
|
||||
return Math.ceil(a);
|
||||
}(Math.random()));
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
return console.log((a = Math.random(), Math.ceil(a)));
|
||||
var a;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "1"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4388: {
|
||||
options = {
|
||||
inline: true,
|
||||
@@ -884,3 +928,334 @@ issue_4772: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5251: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(() => {
|
||||
while (console.log(arguments))
|
||||
var arguments = "FAIL";
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(() => {
|
||||
while (console.log(arguments))
|
||||
var arguments = "FAIL";
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5342_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var a in 0) {
|
||||
(() => {
|
||||
while (1);
|
||||
})(new function(NaN) {
|
||||
a.p;
|
||||
}());
|
||||
}
|
||||
console.log(function() {
|
||||
return b;
|
||||
try {
|
||||
b;
|
||||
} catch (e) {
|
||||
var b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
for (var a in 0) {
|
||||
(function(NaN) {
|
||||
a.p;
|
||||
})();
|
||||
while (1);
|
||||
}
|
||||
console.log(b);
|
||||
var b;
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5342_2: {
|
||||
rename = true
|
||||
options = {
|
||||
dead_code: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
for (var a in 0) {
|
||||
(() => {
|
||||
while (1);
|
||||
})(new function(NaN) {
|
||||
a.p;
|
||||
}());
|
||||
}
|
||||
console.log(function() {
|
||||
return b;
|
||||
try {
|
||||
b;
|
||||
} catch (e) {
|
||||
var b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
for (var a in 0) {
|
||||
a.p;
|
||||
while (1);
|
||||
}
|
||||
console.log(c);
|
||||
var c;
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5356: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log((a => a++)(console));
|
||||
}
|
||||
expect: {
|
||||
console.log((a => +a)(console));
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5414_1: {
|
||||
options = {
|
||||
arrows: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(() => {
|
||||
(() => {
|
||||
if (!console)
|
||||
var arguments = 42;
|
||||
while (console.log(arguments));
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(() => {
|
||||
if (!console)
|
||||
var arguments = 42;
|
||||
while (console.log(arguments));
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5414_2: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
(() => {
|
||||
(() => {
|
||||
if (!console)
|
||||
var arguments = 42;
|
||||
while (console.log(arguments));
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(() => {
|
||||
if (!console)
|
||||
var arguments = 42;
|
||||
while (console.log(arguments));
|
||||
})();
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
while ((() => {
|
||||
console;
|
||||
var a = function g(arguments) {
|
||||
console.log(arguments);
|
||||
}();
|
||||
})());
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
console;
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
loops: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
while ((() => {
|
||||
console;
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})());
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
{
|
||||
console;
|
||||
var arguments = void 0;
|
||||
for (; console.log(arguments););
|
||||
return;
|
||||
}
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
console.log(arguments);
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
arguments = void 0,
|
||||
console.log(arguments);
|
||||
var arguments;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5416_4: {
|
||||
options = {
|
||||
arrows: true,
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var f = () => {
|
||||
(() => {
|
||||
var a = function g(arguments) {
|
||||
while (console.log(arguments));
|
||||
}();
|
||||
})();
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
var f = () => {
|
||||
var arguments = void 0;
|
||||
while (console.log(arguments));
|
||||
return;
|
||||
};
|
||||
f();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5495: {
|
||||
input: {
|
||||
console.log((() => {
|
||||
"use strict";
|
||||
return function() {
|
||||
return this;
|
||||
}();
|
||||
})());
|
||||
}
|
||||
expect_exact: 'console.log((()=>{"use strict";return function(){return this}()})());'
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5653: {
|
||||
options = {
|
||||
arrows: true,
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log((a => {
|
||||
a = { p: console };
|
||||
return a++;
|
||||
})());
|
||||
}
|
||||
expect: {
|
||||
console.log((a => {
|
||||
return console, +{};
|
||||
})());
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ logical_assignments: {
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
logical_collapse_vars: {
|
||||
logical_collapse_vars_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
@@ -509,6 +509,46 @@ logical_collapse_vars: {
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
logical_collapse_vars_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b ||= (a = "FAIL", {});
|
||||
return b;
|
||||
})(console).log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
return b ||= (a = "FAIL", {});
|
||||
})(console).log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
logical_collapse_vars_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 6;
|
||||
a *= 7;
|
||||
a ??= "FAIL";
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 6;
|
||||
a = a * 7 ?? "FAIL";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
logical_reduce_vars: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -550,6 +590,24 @@ logical_side_effects: {
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
evaluate_lazy_assignment: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
console.log(a &&= "PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
issue_4815_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -615,8 +673,7 @@ issue_4827_1: {
|
||||
c &&= b = a, console.log(b);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
var a = A, b = "PASS", c;
|
||||
var a = A = "FAIL", b = "PASS", c;
|
||||
c &&= b = a, console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,7 @@ arithmetic: {
|
||||
}
|
||||
expect_exact: "console.log((1n+0x2n)*(0o3n- -4n)>>5n-6n);"
|
||||
expect_stdout: "42n"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
minus_dot: {
|
||||
@@ -13,7 +13,7 @@ minus_dot: {
|
||||
}
|
||||
expect_exact: "console.log(typeof-42n.toString(),typeof(-42n).toString());"
|
||||
expect_stdout: "number string"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
@@ -28,7 +28,7 @@ evaluate: {
|
||||
console.log(0xdeadbeefn.toString(16));
|
||||
}
|
||||
expect_stdout: "deadbeef"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
Number: {
|
||||
@@ -42,7 +42,7 @@ Number: {
|
||||
console.log(+("" + -0xfeed_dead_beef_badn));
|
||||
}
|
||||
expect_stdout: "-1148098955808013200"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
issue_4590: {
|
||||
@@ -58,7 +58,7 @@ issue_4590: {
|
||||
0n || console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
issue_4801: {
|
||||
@@ -88,5 +88,5 @@ issue_4801: {
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
@@ -427,6 +427,44 @@ negated_if: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
concat_truthy: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo") + (console.log("bar"), "baz") || console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo") + (console.log("bar"), "baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: + in boolean context always true [test/compress/booleans.js:1,8]",
|
||||
"WARN: Condition left of || always true [test/compress/booleans.js:1,8]",
|
||||
]
|
||||
}
|
||||
|
||||
process_returns: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return 42;
|
||||
})() && console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
return 42;
|
||||
})() && console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3465_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
@@ -697,3 +735,54 @@ issue_5041_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5228: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return !function() {
|
||||
do {
|
||||
return null;
|
||||
} while (console);
|
||||
}();
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
do {
|
||||
return !0;
|
||||
} while (console);
|
||||
return !0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_5469: {
|
||||
options = {
|
||||
assignments: true,
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f(a) {
|
||||
a && 42[a = A && null];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(a) {
|
||||
a && A,
|
||||
0;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -346,9 +346,7 @@ collapse_vars_if: {
|
||||
return "x" != "Bar" + x / 4 ? g9 : g5;
|
||||
}
|
||||
function f3(x) {
|
||||
if (x)
|
||||
return 1;
|
||||
return 2;
|
||||
return x ? 1 : 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1912,6 +1910,42 @@ collapse_vars_regexp: {
|
||||
]
|
||||
}
|
||||
|
||||
collapse_arg_sequence: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(a) {
|
||||
a("foo");
|
||||
})((console.log("bar"), console.log));
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
(0, console.log)("foo");
|
||||
})(console.log("bar"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
}
|
||||
|
||||
collapse_for_init: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
for (var a = (Math, console), b = a.log("PASS"); b;);
|
||||
}
|
||||
expect: {
|
||||
Math;
|
||||
for (var a, b = console.log("PASS"); b;);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_1537: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -2545,7 +2579,7 @@ side_effects_property: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
undeclared: {
|
||||
undeclared_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
@@ -2560,8 +2594,68 @@ undeclared: {
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
return (b = y) + x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
undeclared_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var a;
|
||||
a = x;
|
||||
b = y;
|
||||
return b + x;
|
||||
return a + b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
return x + (b = y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
undeclared_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var a;
|
||||
a = x;
|
||||
b = y;
|
||||
return b + a();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
return (b = y) + x();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
undeclared_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(x, y) {
|
||||
var a;
|
||||
a = x;
|
||||
b = y;
|
||||
return a() + b;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f(x, y) {
|
||||
b = y;
|
||||
return x() + b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2667,6 +2761,24 @@ chained_4: {
|
||||
expect_stdout: "foo undefined"
|
||||
}
|
||||
|
||||
chained_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
var a = (console, console.log(a));
|
||||
a && ++a;
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
console;
|
||||
var a;
|
||||
(a = console.log(a)) && ++a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
boolean_binary_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -2906,6 +3018,127 @@ compound_assignment_2: {
|
||||
expect_stdout: "4"
|
||||
}
|
||||
|
||||
compound_assignment_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
a += (console.log("PASS"), 2);
|
||||
a.p;
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
(a += (console.log("PASS"), 2)).p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
compound_assignment_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
var a = "";
|
||||
a += (a = "FAIL", A);
|
||||
a.p;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "";
|
||||
(a += (a = "FAIL", A = "PASS")).p;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
compound_assignment_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0, b;
|
||||
a += 42;
|
||||
b && (a *= null);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b;
|
||||
a += 42;
|
||||
b && (a *= null);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
compound_assignment_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
a ^= 6;
|
||||
a *= a + 1;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = (a ^= 6) * (a + 1);
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
compound_assignment_7: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FA";
|
||||
a = a + "I";
|
||||
a = a + "L";
|
||||
if (console)
|
||||
a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "FA";
|
||||
a = a + "I" + "L";
|
||||
if (console)
|
||||
a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
compound_assignment_8: {
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2;
|
||||
a = 3 * a;
|
||||
a = 7 * a;
|
||||
console || (a = "FAIL");
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 2;
|
||||
a = a * 3 * 7;
|
||||
console || (a = "FAIL");
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_2187_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -3030,10 +3263,10 @@ issue_2203_2: {
|
||||
a: "FAIL",
|
||||
b: function() {
|
||||
return function(c) {
|
||||
return (String, (Object, function() {
|
||||
return (Object, function() {
|
||||
return this;
|
||||
}())).a;
|
||||
}();
|
||||
}()).a;
|
||||
}(String);
|
||||
}
|
||||
}.b());
|
||||
}
|
||||
@@ -3731,6 +3964,7 @@ issue_2437_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 2,
|
||||
@@ -3763,17 +3997,17 @@ issue_2437_1: {
|
||||
console.log(foo());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
if (xhrDesc) {
|
||||
var result = !!(req = new XMLHttpRequest()).onreadystatechange;
|
||||
return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
|
||||
result;
|
||||
}
|
||||
var req = new XMLHttpRequest(), detectFunc = function(){};
|
||||
return req.onreadystatechange = detectFunc,
|
||||
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc,
|
||||
req.onreadystatechange = null, result;
|
||||
}());
|
||||
var req, detectFunc, result;
|
||||
console.log((
|
||||
xhrDesc ? (result = !!(req = new XMLHttpRequest).onreadystatechange,
|
||||
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc||{})
|
||||
) : (
|
||||
(req = new XMLHttpRequest).onreadystatechange = detectFunc = function(){},
|
||||
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc,
|
||||
req.onreadystatechange = null
|
||||
),
|
||||
result
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3783,6 +4017,7 @@ issue_2437_2: {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
negate_iife: true,
|
||||
passes: 3,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
@@ -3813,15 +4048,15 @@ issue_2437_2: {
|
||||
foo();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
if (xhrDesc)
|
||||
return (req = new XMLHttpRequest()).onreadystatechange,
|
||||
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {});
|
||||
var req = new XMLHttpRequest();
|
||||
req.onreadystatechange = function(){},
|
||||
var req;
|
||||
xhrDesc ? (
|
||||
(req = new XMLHttpRequest).onreadystatechange,
|
||||
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {})
|
||||
) : (
|
||||
(req = new XMLHttpRequest).onreadystatechange = function(){},
|
||||
req[SYMBOL_FAKE_ONREADYSTATECHANGE_1],
|
||||
req.onreadystatechange = null;
|
||||
}();
|
||||
req.onreadystatechange = null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6443,7 +6678,8 @@ assign_undeclared: {
|
||||
console.log(typeof B);
|
||||
}
|
||||
expect: {
|
||||
B = new (console.log(42), function() {})();
|
||||
console.log(42);
|
||||
B = new function() {}();
|
||||
console.log(typeof B);
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -8156,9 +8392,9 @@ issue_3884_1: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = 100, b = 1;
|
||||
b <<= ++a;
|
||||
console.log(a, b);
|
||||
var a = 100;
|
||||
++a;
|
||||
console.log(a, 32);
|
||||
}
|
||||
expect_stdout: "101 32"
|
||||
}
|
||||
@@ -8778,6 +9014,27 @@ collapse_and_assign: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_and_assign_property: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function f() {
|
||||
f && (f.p = "PASS");
|
||||
return f.p;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f() {
|
||||
return f.p = f ? "PASS" : f.p;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
collapse_or_assign: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -8795,7 +9052,7 @@ collapse_or_assign: {
|
||||
var a = {
|
||||
p: "PASS",
|
||||
};
|
||||
log(a = !a.q ? a.p : a);
|
||||
log(a = a.q ? a: a.p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -9064,12 +9321,11 @@ issue_4874: {
|
||||
})(a = 42);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
null;
|
||||
(function(b) {
|
||||
for (var c in a && a[console.log("PASS")])
|
||||
for (var c in 42, 42[console.log("PASS")])
|
||||
console;
|
||||
})(a = 42);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -9139,9 +9395,7 @@ issue_4908: {
|
||||
console.log(d[1]);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b;
|
||||
console || a++;
|
||||
var c = a, d = [ (d = a) && d, d += 42 ];
|
||||
var a = 0, b, c = (console || a++, a), d = [ (d = a) && d, d += 42 ];
|
||||
console.log(d[1]);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
@@ -9253,13 +9507,13 @@ issue_4920_2: {
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
var o;
|
||||
var a = "PASS", b;
|
||||
({
|
||||
get PASS() {
|
||||
a = "FAIL";
|
||||
},
|
||||
};
|
||||
var a = "PASS", b;
|
||||
o[b = a];
|
||||
})[b = a];
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -9283,16 +9537,47 @@ issue_4920_3: {
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var o = {
|
||||
var o;
|
||||
var a = "PASS", b;
|
||||
({
|
||||
get PASS() {
|
||||
a = "FAIL";
|
||||
},
|
||||
})[b = a];
|
||||
log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4920_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = {
|
||||
get [(a = "FAIL 1", "PASS")]() {
|
||||
a = "FAIL 2";
|
||||
},
|
||||
};
|
||||
var a = "PASS", b;
|
||||
o[b = a];
|
||||
log(b);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var o = {
|
||||
get [(a = "FAIL 1", "PASS")]() {
|
||||
a = "FAIL 2";
|
||||
},
|
||||
};
|
||||
var a = "PASS", b;
|
||||
o[b = a];
|
||||
log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4935: {
|
||||
@@ -9343,9 +9628,8 @@ inline_throw: {
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
return function() {
|
||||
throw a;
|
||||
}();
|
||||
throw a;
|
||||
return;
|
||||
})("PASS");
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
@@ -9482,3 +9766,358 @@ issue_5112_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5182: {
|
||||
options = {
|
||||
arrows: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
passes: 4,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var con = console;
|
||||
global.log = con.log;
|
||||
var jump = function(x) {
|
||||
console.log("JUMP:", x * 10);
|
||||
return x + x;
|
||||
};
|
||||
var jump2 = jump;
|
||||
var run = function(x) {
|
||||
console.log("RUN:", x * -10);
|
||||
return x * x;
|
||||
};
|
||||
var run2 = run;
|
||||
var bar = (x, y) => {
|
||||
console.log("BAR:", x + y);
|
||||
return x - y;
|
||||
};
|
||||
var bar2 = bar;
|
||||
var obj = {
|
||||
foo: bar2,
|
||||
go: run2,
|
||||
not_used: jump2,
|
||||
};
|
||||
console.log(obj.foo(1, 2), global.log("PASS"));
|
||||
}
|
||||
expect: {
|
||||
var con = console;
|
||||
global.log = con.log,
|
||||
console.log((console.log("BAR:", 3), -1), global.log("PASS"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"BAR: 3",
|
||||
"PASS",
|
||||
"-1 undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5273: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "10", b = 1;
|
||||
function f(c, d) {
|
||||
return d;
|
||||
}
|
||||
f((b += a, b *= a), f);
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a = "10", b = 1;
|
||||
function f(c, d) {
|
||||
return d;
|
||||
}
|
||||
b = 1100,
|
||||
f,
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "1100"
|
||||
}
|
||||
|
||||
issue_5276: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = A = "PASS";
|
||||
a.p += null;
|
||||
a.p -= 42;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = A = "PASS";
|
||||
a.p = a.p + null - 42;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5277: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
var a = function() {
|
||||
a += null;
|
||||
a -= 42;
|
||||
};
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5309_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
if (console)
|
||||
var a = (console.log("PASS"), b), b = a;
|
||||
else
|
||||
console.log("FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
console ? (console.log("PASS"), b = b) : console.log("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5309_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b;
|
||||
console ? (a = (console.log("PASS"), b), b = a) : console.log("FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
console ? (console.log("PASS"), b = b) : console.log("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5394: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
throw A.p = (console.log("FAIL"), []), !1;
|
||||
} catch (e) {
|
||||
console.log(typeof e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
throw !(A.p = (console.log("FAIL"), []));
|
||||
} catch (e) {
|
||||
console.log(typeof e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_5396: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b;
|
||||
function f() {}
|
||||
b = 0;
|
||||
new function g(c) {
|
||||
var d = a && g(e), e = ++d, i = [ 42 ];
|
||||
for (var j in i)
|
||||
console.log("PASS"),
|
||||
i;
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
function f() {}
|
||||
b = 0;
|
||||
(function g(c) {
|
||||
a && g();
|
||||
for (var j in [ 42 ])
|
||||
console.log("PASS");
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5568: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
var a = (A = "PASS", !1);
|
||||
for (var b in a);
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
for (var b in !(A = "PASS"));
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console;
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 42 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = { foo: 6 }, b;
|
||||
for (var k in a) {
|
||||
b = a[k];
|
||||
log(k || b, b *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5643: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect: {
|
||||
var a = 3, b;
|
||||
a *= 7;
|
||||
b = !!this;
|
||||
console || console.log(b);
|
||||
console.log(a * ++b);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
@@ -40,6 +40,22 @@ unsafe_comps: {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe_in_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe_comps: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
42 in a;
|
||||
f() instanceof "foo";
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
dont_change_in_or_instanceof_expressions: {
|
||||
input: {
|
||||
1 in 1;
|
||||
@@ -489,7 +505,36 @@ issue_3413: {
|
||||
}
|
||||
expect: {
|
||||
var b;
|
||||
void 0 !== ("" < b || void 0) || console.log("PASS");
|
||||
void 0 === ("" < b || void 0) && console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
nullish_assign: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
void 0 !== (a = "PASS".split("")) && null !== a && console.log(a.join("-"));
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
null != (a = "PASS".split("")) && console.log(a.join("-"));
|
||||
}
|
||||
expect_stdout: "P-A-S-S"
|
||||
}
|
||||
|
||||
nullish_chain: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
A || B || void 0 === a || null === a || C;
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
A || B || null == a || C;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -289,3 +289,18 @@ issue_3689: {
|
||||
}
|
||||
expect_stdout: "00"
|
||||
}
|
||||
|
||||
issue_5145: {
|
||||
options = {
|
||||
strings: true,
|
||||
}
|
||||
input: {
|
||||
var a = [];
|
||||
console.log("" + a + ((a[0] = 4) + "2"));
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
console.log("" + a + (a[0] = 4) + "2");
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -142,6 +142,80 @@ if_dead_branch: {
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
const b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
const b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -220,6 +294,32 @@ merge_vars_3: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
merge_vars_4: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
{
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
const a = 0;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
{
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
const a = 0;
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
use_before_init_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -553,6 +653,37 @@ dead_block_after_return: {
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
const b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -571,8 +702,7 @@ do_if_continue_1: {
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
if (console) {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
@@ -602,8 +732,7 @@ do_if_continue_2: {
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
if (console) {
|
||||
console.log("PASS");
|
||||
{
|
||||
const a = 0;
|
||||
@@ -838,12 +967,10 @@ issue_4202: {
|
||||
expect: {
|
||||
{
|
||||
const o = {};
|
||||
(function() {
|
||||
function f() {
|
||||
o.p = 42;
|
||||
}
|
||||
f(f);
|
||||
})();
|
||||
function f() {
|
||||
o.p = 42;
|
||||
}
|
||||
f(f);
|
||||
console.log(o.p++);
|
||||
}
|
||||
}
|
||||
@@ -1219,9 +1346,9 @@ issue_4248: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4261: {
|
||||
issue_4261_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
inline: 3,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -1259,6 +1386,43 @@ issue_4261: {
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_4261_2: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
{
|
||||
const a = 42;
|
||||
(function() {
|
||||
function f() {
|
||||
console.log(a);
|
||||
}
|
||||
function g() {
|
||||
while (f());
|
||||
}
|
||||
(function() {
|
||||
while (g());
|
||||
})();
|
||||
})();
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
{
|
||||
const a = 42;
|
||||
function g() {
|
||||
while (void console.log(a));
|
||||
}
|
||||
while (g());
|
||||
}
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_4274_1: {
|
||||
options = {
|
||||
loops: true,
|
||||
@@ -1457,6 +1621,7 @@ issue_4689: {
|
||||
|
||||
issue_4691: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
toplevel: true,
|
||||
}
|
||||
@@ -1692,3 +1857,350 @@ issue_4965_2: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5254: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
do {
|
||||
(function() {
|
||||
const a = console.log;
|
||||
a && a("foo");
|
||||
})();
|
||||
} while (console.log("bar"));
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
const a = console.log;
|
||||
a && a("foo");
|
||||
} while (console.log("bar"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5260: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "foo", o;
|
||||
while (console.log("bar"));
|
||||
o = {
|
||||
baz: function(b) {
|
||||
console.log(a, b);
|
||||
},
|
||||
};
|
||||
for (const a in o)
|
||||
o[a](a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "foo", o;
|
||||
while (console.log("bar"));
|
||||
o = {
|
||||
baz: function(b) {
|
||||
console.log(a, b);
|
||||
},
|
||||
};
|
||||
for (const a in o)
|
||||
o[a](a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5319: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function(a, c) {
|
||||
var b = a, c = b;
|
||||
{
|
||||
const a = c;
|
||||
console.log(c());
|
||||
}
|
||||
})(function() {
|
||||
return "PASS";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
(function(a, c) {
|
||||
var b = a, c;
|
||||
{
|
||||
const a = c = b;
|
||||
console.log(c());
|
||||
}
|
||||
})(function() {
|
||||
return "PASS";
|
||||
});
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5338: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
const a = a;
|
||||
}
|
||||
expect: {
|
||||
const a = a;
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5476: {
|
||||
mangle = {
|
||||
keep_fargs: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(n) {
|
||||
const a = 42;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(n) {
|
||||
const o = 42;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
(function f() {
|
||||
a;
|
||||
})();
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
try {} catch (a) {
|
||||
void a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_5580_1: {
|
||||
mangle = {}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function(a, b, c) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (e) {
|
||||
return function() {
|
||||
var d = e, i, j;
|
||||
{
|
||||
const e = j;
|
||||
}
|
||||
return a;
|
||||
}();
|
||||
} finally {
|
||||
const e = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(r, n, t) {
|
||||
try {
|
||||
FAIL;
|
||||
} catch (o) {
|
||||
return function() {
|
||||
var n = o, t, c;
|
||||
{
|
||||
const o = c;
|
||||
}
|
||||
return r;
|
||||
}();
|
||||
} finally {
|
||||
const c = 42;
|
||||
}
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5580_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
return function() {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
}();
|
||||
} finally {
|
||||
const e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
{
|
||||
const e = "FAIL 1";
|
||||
}
|
||||
return;
|
||||
} finally {
|
||||
var e = "FAIL 2";
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
const a = 42;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5656: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
b++;
|
||||
{
|
||||
const a = b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = a;
|
||||
{
|
||||
const a = ++b;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_5660: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
a;
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
try {
|
||||
var b;
|
||||
return b;
|
||||
} catch (e) {
|
||||
var a = "FAIL";
|
||||
const b = null;
|
||||
return a;
|
||||
}
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1485,8 +1485,6 @@ self_assignments_5: {
|
||||
}
|
||||
expect: {
|
||||
var i = 0, l = [ "FAIL", "PASS" ];
|
||||
l[0];
|
||||
l[0];
|
||||
l[0] = l[1];
|
||||
console.log(l[0], 2);
|
||||
}
|
||||
@@ -1669,3 +1667,66 @@ issue_5106_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
(function(a) {
|
||||
var b = 1;
|
||||
(function f() {
|
||||
try {
|
||||
b-- && f();
|
||||
} catch (c) {}
|
||||
console.log(a);
|
||||
a = 42 in (a = "bar");
|
||||
})();
|
||||
})("foo");
|
||||
} catch (e) {}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5641: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
if (a || b) {
|
||||
var b = "PASS", c = b && console.log(b);
|
||||
} else
|
||||
var d = a || b;
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
var b, c, d;
|
||||
(a || b) && (b = "PASS") && console.log(b);
|
||||
}
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -220,7 +220,7 @@ funarg_side_effects_2: {
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
node_version: ">=6.9.2"
|
||||
}
|
||||
|
||||
funarg_side_effects_3: {
|
||||
@@ -254,7 +254,7 @@ funarg_side_effects_3: {
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
node_version: ">=6.9.2"
|
||||
}
|
||||
|
||||
funarg_unused_1: {
|
||||
@@ -395,7 +395,8 @@ funarg_unused_6_keep_fargs: {
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var {} = (console, 42);
|
||||
console;
|
||||
var {} = 42;
|
||||
})();
|
||||
console.log(typeof a);
|
||||
}
|
||||
@@ -471,6 +472,93 @@ funarg_collapse_vars_3: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(b);
|
||||
})(a, console);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b, { log: c }) {
|
||||
c(a);
|
||||
})(0, console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_5: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
try {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
} catch (e) {}
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_collapse_vars_6: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = "FAIL";
|
||||
B = "PASS";
|
||||
function f() {
|
||||
console.log(function({}, a) {
|
||||
return a;
|
||||
}(null, A = B));
|
||||
}
|
||||
try {
|
||||
f();
|
||||
} catch (e) {
|
||||
console.log(A);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
funarg_reduce_vars_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
@@ -691,7 +779,7 @@ funarg_inline: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
process_boolean_returns: {
|
||||
process_returns: {
|
||||
options = {
|
||||
booleans: true,
|
||||
}
|
||||
@@ -705,9 +793,7 @@ process_boolean_returns: {
|
||||
expect: {
|
||||
console.log(function({ length }) {
|
||||
return length ? "FAIL" : "PASS";
|
||||
}(function() {
|
||||
return 42;
|
||||
}));
|
||||
}(function() {}));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -1129,7 +1215,7 @@ drop_unused_2: {
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect:{
|
||||
expect: {
|
||||
(function(a) {
|
||||
console.log("PASS");
|
||||
})();
|
||||
@@ -1220,7 +1306,7 @@ keep_reference: {
|
||||
}
|
||||
expect: {
|
||||
var a = [ {}, 42 ];
|
||||
var [ b ] = a;
|
||||
var b = a[0];
|
||||
console.log(a[0] === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -1566,6 +1652,8 @@ fn_name_unused: {
|
||||
hoist_vars: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
@@ -1573,14 +1661,82 @@ hoist_vars: {
|
||||
console.log(a, b);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var [ b ] = [ 42 ];
|
||||
var a = "PASS", b = [ 42 ][0];
|
||||
console.log(a, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
singleton_1: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ a ] = "P", b, o = {};
|
||||
[ { 1: o.p } ] = [ "FAIL" ];
|
||||
({ foo: [ o.q ] } = { foo: "S" });
|
||||
[ b = "S" ] = [];
|
||||
console.log(a + o.p + o.q + b);
|
||||
}
|
||||
expect: {
|
||||
var b, a = "P"[0], o = {};
|
||||
o.p = [ "FAIL"["1"] ][0];
|
||||
o.q = { foo: "S"[0] }["foo"];
|
||||
[ b = "S" ] = [];
|
||||
console.log(a + o.p + o.q + b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
singleton_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ a ] = "P", b, o = {};
|
||||
[ { 1: o.p } ] = [ "FAIL" ];
|
||||
({ foo: [ o.q ] } = { foo: "S" });
|
||||
[ b = "S" ] = [];
|
||||
console.log(a + o.p + o.q + b);
|
||||
}
|
||||
expect: {
|
||||
var b, a = "P", o = {};
|
||||
o.p = "A";
|
||||
o.q = "S";
|
||||
[ b = "S" ] = [];
|
||||
console.log(a + o.p + o.q + b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
singleton_side_effects: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
[ 42[console.log("foo")] ] = [ console.log("bar") ];
|
||||
}
|
||||
expect: {
|
||||
[ 42[console.log("foo")] ] = [ console.log("bar") ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_4280: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -1747,8 +1903,8 @@ issue_4288: {
|
||||
console.log(typeof b);
|
||||
}()]: a,
|
||||
}) {
|
||||
var b = a;
|
||||
b++;
|
||||
var a = a;
|
||||
a++;
|
||||
}
|
||||
f(0);
|
||||
}
|
||||
@@ -1775,10 +1931,10 @@ issue_4294: {
|
||||
expect: {
|
||||
A = "PASS";
|
||||
(function() {
|
||||
var b = function({
|
||||
[b]: {},
|
||||
var a = function({
|
||||
[a]: {},
|
||||
}) {}({
|
||||
[b]: 0,
|
||||
[a]: 0,
|
||||
});
|
||||
var b = A;
|
||||
console.log(b);
|
||||
@@ -1921,17 +2077,16 @@ issue_4312: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
b = "PASS",
|
||||
c = "FAIL",
|
||||
[
|
||||
{
|
||||
[a = b]: d,
|
||||
[c = b]: d,
|
||||
},
|
||||
] = [ c && c ],
|
||||
void 0;
|
||||
var b, c, d;
|
||||
console.log(a);
|
||||
console.log(c);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
@@ -2000,7 +2155,7 @@ issue_4319: {
|
||||
|
||||
issue_4321: {
|
||||
options = {
|
||||
inline: true,
|
||||
inline: 3,
|
||||
keep_fargs: false,
|
||||
}
|
||||
input: {
|
||||
@@ -2127,7 +2282,7 @@ issue_4372_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ a ] = [ "PASS", "FAIL" ];
|
||||
[ a ] = a = [ "PASS", "FAIL" ];
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -2952,6 +3107,7 @@ issue_5074_method_pure_getters: {
|
||||
issue_5085_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
@@ -2964,8 +3120,7 @@ issue_5085_1: {
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
var b = [ 42 ][0];
|
||||
b;
|
||||
42;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -2975,6 +3130,7 @@ issue_5085_1: {
|
||||
issue_5085_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
@@ -2991,7 +3147,7 @@ issue_5085_2: {
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
(function(b) {
|
||||
b = [ 42 ][0];
|
||||
0;
|
||||
})();
|
||||
console.log(a);
|
||||
}
|
||||
@@ -3125,3 +3281,591 @@ issue_5114_3: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5153_array_assign: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
var a = function*() {
|
||||
yield b;
|
||||
}(), b;
|
||||
[ b ] = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = function*() {
|
||||
yield b;
|
||||
}(), b;
|
||||
[ b ] = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5153_array_var: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
var a = function*() {
|
||||
yield b;
|
||||
}(), [ b ] = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = function*() {
|
||||
yield b;
|
||||
}(), [ b ] = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5153_object_assign: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
var a = {
|
||||
get p() {
|
||||
return b;
|
||||
},
|
||||
}, b;
|
||||
({
|
||||
p: b
|
||||
} = b = a);
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
get p() {
|
||||
return b;
|
||||
},
|
||||
}, b;
|
||||
({
|
||||
p: b
|
||||
} = b = a);
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5153_object_var: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
var a = {
|
||||
get p() {
|
||||
return b;
|
||||
},
|
||||
}, {
|
||||
p: b
|
||||
} = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
get p() {
|
||||
return b;
|
||||
},
|
||||
}, {
|
||||
p: b
|
||||
} = b = a;
|
||||
console.log(a === b ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5168: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
(function a({
|
||||
[console.log(typeof function() {
|
||||
++a;
|
||||
return a;
|
||||
}())]: b,
|
||||
}) {
|
||||
var a;
|
||||
})({});
|
||||
}
|
||||
expect: {
|
||||
(function a({
|
||||
[console.log(typeof function() {
|
||||
++a;
|
||||
return a;
|
||||
}())]: b,
|
||||
}) {
|
||||
var a;
|
||||
})({});
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5189_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
[ a.p ] = a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ a.p ] = a = "PASS";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5189_2: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 42;
|
||||
({ p: a.q } = a = "PASS");
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
({ p: a.q } = a = "PASS");
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5222: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
do {
|
||||
(function() {
|
||||
var a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
})();
|
||||
} while (console.log("PASS"));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
do {
|
||||
a = void 0,
|
||||
a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
} while (console.log("PASS"));
|
||||
var a;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5288_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
while (function([]) {}([ function f() {
|
||||
if (console)
|
||||
return console.log("PASS");
|
||||
else {
|
||||
let a = 0;
|
||||
}
|
||||
}() ]));
|
||||
}
|
||||
expect: {
|
||||
while (function() {
|
||||
if (console)
|
||||
console.log("PASS");
|
||||
}(), void 0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5288_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
while (function([]) {}([ function f() {
|
||||
if (console)
|
||||
return console.log("PASS");
|
||||
else {
|
||||
let a = 0;
|
||||
}
|
||||
}() ]));
|
||||
}
|
||||
expect: {
|
||||
while (console && console.log("PASS"), void 0);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5314_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
A = this;
|
||||
new function() {
|
||||
(function({
|
||||
[console.log(this === A ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
A = this;
|
||||
(function() {
|
||||
(function({
|
||||
[console.log(this === A ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5314_2: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
A = this;
|
||||
new function() {
|
||||
(({
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: a,
|
||||
}) => {})(42);
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
A = this;
|
||||
new function() {
|
||||
[ {
|
||||
[console.log(this === A ? "FAIL" : "PASS")]: [][0],
|
||||
} ] = [ 42 ];
|
||||
}();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5370: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments({}) {
|
||||
return arguments;
|
||||
try {} catch (e) {
|
||||
var arguments;
|
||||
}
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments({}) {
|
||||
return arguments;
|
||||
var arguments;
|
||||
}(42));
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5405_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var [ a ] = [ {} ];
|
||||
console.log(a === a ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var [ a ] = [ {} ];
|
||||
console.log(true ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5405_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var { p: a } = { p: [] };
|
||||
console.log(a === a ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var { p: a } = { p: [] };
|
||||
console.log(true ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5423: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a, b;
|
||||
function f({
|
||||
[function() {
|
||||
if (++a)
|
||||
return 42;
|
||||
}()]: c
|
||||
}) {}
|
||||
f(b = f);
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect: {
|
||||
var a, b;
|
||||
function f({
|
||||
[function() {
|
||||
if (++a)
|
||||
return 42;
|
||||
}()]: c
|
||||
}) {}
|
||||
f(b = f);
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5454: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var a = 42, a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
return "PASS";
|
||||
}
|
||||
console.log(f());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
a = 42, a = {
|
||||
p: [ a ] = [],
|
||||
};
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5485: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
}
|
||||
input: {
|
||||
(function f({
|
||||
p: f,
|
||||
[console.log(void 0 === f ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
}
|
||||
expect: {
|
||||
(function f({
|
||||
p: f,
|
||||
[console.log(void 0 === f ? "PASS" : "FAIL")]: a,
|
||||
}) {})(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f([ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})([]);
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5573: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = "FAIL";
|
||||
(function([ { [log(a)]: b } ]) {
|
||||
A = 42;
|
||||
})((a = "PASS", [ {} ]));
|
||||
log(a, A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS 42",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5651: {
|
||||
options = {
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments({}) {
|
||||
try {} catch (arguments) {
|
||||
var arguments;
|
||||
}
|
||||
return arguments[0];
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -129,3 +129,47 @@ valid_after_invalid_2: {
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5368_1: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
"foo"
|
||||
}
|
||||
expect_exact: '"foo"'
|
||||
expect_stdout: "foo"
|
||||
}
|
||||
|
||||
issue_5368_2: {
|
||||
expression = true
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
"foo";
|
||||
})()
|
||||
}
|
||||
expect_exact: "function(){}()"
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5368_3: {
|
||||
options = {
|
||||
directives: true,
|
||||
expression: true,
|
||||
}
|
||||
input: {
|
||||
"foo";
|
||||
(function() {
|
||||
"bar";
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function() {})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -409,6 +409,15 @@ drop_toplevel_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_array: {
|
||||
@@ -442,6 +451,15 @@ drop_toplevel_retain_array: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_retain_regex: {
|
||||
@@ -471,6 +489,15 @@ drop_toplevel_retain_regex: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_all_retain: {
|
||||
@@ -501,6 +528,15 @@ drop_toplevel_all_retain: {
|
||||
a = 2;
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
"INFO: Dropping unused function g [test/compress/drop-unused.js:8,17]",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_funcs_retain: {
|
||||
@@ -532,6 +568,12 @@ drop_toplevel_funcs_retain: {
|
||||
function g() {}
|
||||
console.log(b = 3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"WARN: Dropping unused function h [test/compress/drop-unused.js:9,17]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_vars_retain: {
|
||||
@@ -564,6 +606,13 @@ drop_toplevel_vars_retain: {
|
||||
function h() {}
|
||||
console.log(3);
|
||||
}
|
||||
expect_stdout: "3"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable a",
|
||||
"INFO: Retaining variable f",
|
||||
"INFO: Dropping unused variable b [test/compress/drop-unused.js:1,15]",
|
||||
"INFO: Dropping unused variable c [test/compress/drop-unused.js:1,22]",
|
||||
]
|
||||
}
|
||||
|
||||
drop_toplevel_keep_assign: {
|
||||
@@ -671,6 +720,76 @@ iife: {
|
||||
}
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
booleans: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
console.log(!1, (Math, !1));
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_1: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "false false"
|
||||
}
|
||||
|
||||
keep_instanceof_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
var f = Object;
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
keep_instanceof_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect: {
|
||||
f = Object;
|
||||
function f() {}
|
||||
console.log({} instanceof f, Math instanceof f);
|
||||
}
|
||||
expect_stdout: "true true"
|
||||
}
|
||||
|
||||
issue_1539: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -1233,8 +1352,11 @@ issue_2105_2: {
|
||||
issue_2105_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
join_vars: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
sequences: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -1258,12 +1380,12 @@ issue_2105_3: {
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
!void void {
|
||||
({
|
||||
prop: function() {
|
||||
console.log;
|
||||
void console.log("PASS");
|
||||
}
|
||||
}.prop();
|
||||
console.log,
|
||||
console.log("PASS");
|
||||
},
|
||||
}).prop();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -1728,7 +1850,8 @@ issue_2768: {
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
var c = (d = a, void (d && (a = "PASS")));
|
||||
d = a;
|
||||
var c = void (d && (a = "PASS"));
|
||||
var d;
|
||||
console.log(a, typeof c);
|
||||
}
|
||||
@@ -1755,7 +1878,7 @@ issue_2846: {
|
||||
var c = function(a, b) {
|
||||
a = 0;
|
||||
b && b(a);
|
||||
return a++;
|
||||
return +a;
|
||||
}();
|
||||
console.log(c);
|
||||
}
|
||||
@@ -1765,7 +1888,7 @@ issue_2846: {
|
||||
issue_805_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
@@ -1798,7 +1921,7 @@ issue_805_1: {
|
||||
issue_805_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
@@ -2382,7 +2505,8 @@ issue_3664: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
|
||||
a = (a = [ b && console.log("FAIL") ]).p = 0;
|
||||
var a, b = 0;
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
@@ -2551,10 +2675,9 @@ issue_3899: {
|
||||
console.log(typeof a);
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
console.log(typeof function() {
|
||||
return 2;
|
||||
}
|
||||
console.log(typeof a);
|
||||
});
|
||||
}
|
||||
expect_stdout: "function"
|
||||
}
|
||||
@@ -2652,7 +2775,7 @@ issue_3956: {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
@@ -2783,7 +2906,7 @@ issue_3986: {
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
issue_4017: {
|
||||
issue_4017_1: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
@@ -2801,7 +2924,31 @@ issue_4017: {
|
||||
var a = 0;
|
||||
console.log(function() {
|
||||
c &= 0;
|
||||
var c;
|
||||
var c = a++ + (A = a);
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4017_2: {
|
||||
options = {
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
console.log(function f() {
|
||||
var b = c &= 0;
|
||||
var c = a++ + (A = a);
|
||||
var d = c && c[f];
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
console.log(function() {
|
||||
0;
|
||||
a++,
|
||||
A = a;
|
||||
}());
|
||||
@@ -2829,14 +2976,12 @@ issue_4025: {
|
||||
console.log(a, b, d);
|
||||
}
|
||||
expect: {
|
||||
var c = 0;
|
||||
try {
|
||||
console.log(c);
|
||||
console.log(0);
|
||||
} finally {
|
||||
var d = c + 1;
|
||||
c = 0;
|
||||
0;
|
||||
}
|
||||
console.log(1, 1, d);
|
||||
console.log(1, 1, 1);
|
||||
}
|
||||
expect_stdout: [
|
||||
"0",
|
||||
@@ -2916,7 +3061,7 @@ issue_4133: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var b = 1;
|
||||
var a = 1;
|
||||
console.log(0);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
@@ -3062,7 +3207,7 @@ issue_4184: {
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_4235: {
|
||||
issue_4235_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
@@ -3081,13 +3226,37 @@ issue_4235: {
|
||||
}
|
||||
expect: {
|
||||
void function() {
|
||||
var f;
|
||||
console.log(f);
|
||||
var f = console.log(f);
|
||||
}();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4235_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
{
|
||||
const f = 0;
|
||||
}
|
||||
(function f() {
|
||||
var f = console.log(f);
|
||||
})();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
console.log(void 0);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4404: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
@@ -3220,7 +3389,7 @@ issue_4558_1: {
|
||||
expect: {
|
||||
var a = 0;
|
||||
var b = c >>>= a;
|
||||
var c;
|
||||
var c = 0;
|
||||
b && a++,
|
||||
console.log(a);
|
||||
}
|
||||
@@ -3306,6 +3475,7 @@ issue_4806_1: {
|
||||
issue_4806_2: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -3492,3 +3662,155 @@ issue_5079: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5224: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
try {
|
||||
var b = function() {
|
||||
var a = "FAIL 1";
|
||||
null && a;
|
||||
a = console.log(a);
|
||||
}(new function(c, d) {
|
||||
console.log(d);
|
||||
a;
|
||||
}("FAIL 2", Infinity));
|
||||
} finally {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function f() {
|
||||
try {
|
||||
(function() {
|
||||
var a = "FAIL 1";
|
||||
null;
|
||||
console.log(a);
|
||||
})(function() {
|
||||
console.log(1 / 0);
|
||||
a;
|
||||
}());
|
||||
} finally {
|
||||
return f;
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: "Infinity"
|
||||
}
|
||||
|
||||
issue_5271: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
do {
|
||||
var a = b = 0 ^ f, b = b;
|
||||
} while (console.log(42 - b));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function f() {
|
||||
do {
|
||||
var b;
|
||||
b = 0 ^ f;
|
||||
} while (console.log(42 - b));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5533_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5533_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ call_args: {
|
||||
expect: {
|
||||
var a = 1;
|
||||
console.log(1);
|
||||
+(1, 1);
|
||||
1, 1;
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -769,7 +769,7 @@ call_args_drop_param: {
|
||||
}
|
||||
expect: {
|
||||
console.log(1);
|
||||
+(b, 1);
|
||||
b, 1;
|
||||
}
|
||||
expect_stdout: true
|
||||
}
|
||||
@@ -888,6 +888,39 @@ unsafe_charAt_noop: {
|
||||
expect_stdout: "f n"
|
||||
}
|
||||
|
||||
chained_side_effects: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo") || (console.log("bar"), "baz") || console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo") || (console.log("bar"), "baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1,8]",
|
||||
]
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_1649: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -2752,8 +2785,7 @@ issue_3944: {
|
||||
}
|
||||
expect: {
|
||||
void function f() {
|
||||
while (a = 0 == (a = void 0), console.log(a), void 0);
|
||||
var a;
|
||||
while (0 == void 0, console.log(false), void 0);
|
||||
f;
|
||||
}();
|
||||
}
|
||||
@@ -3203,7 +3235,7 @@ issue_4552: {
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_4886: {
|
||||
issue_4886_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
@@ -3222,3 +3254,165 @@ issue_4886: {
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_4886_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo" in {
|
||||
"foo": null,
|
||||
__proto__: 42,
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("foo" in {
|
||||
"foo": null,
|
||||
__proto__: 42,
|
||||
});
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_5354: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return +a.toExponential(1);
|
||||
}
|
||||
function g(b) {
|
||||
return 0 + b.toFixed(2);
|
||||
}
|
||||
function h(c) {
|
||||
return 1 * c.toPrecision(3);
|
||||
}
|
||||
console.log(typeof f(45), typeof g(67), typeof h(89));
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return +a.toExponential(1);
|
||||
}
|
||||
function g(b) {
|
||||
return 0 + b.toFixed(2);
|
||||
}
|
||||
function h(c) {
|
||||
return +c.toPrecision(3);
|
||||
}
|
||||
console.log(typeof f(45), typeof g(67), typeof h(89));
|
||||
}
|
||||
expect_stdout: "number string number"
|
||||
}
|
||||
|
||||
issue_5356: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return a++;
|
||||
var a = a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(+a);
|
||||
var a;
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5362_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = -console;
|
||||
console.log(delete +a);
|
||||
}
|
||||
expect: {
|
||||
var a = -console;
|
||||
console.log((+a, true));
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_5362_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unsafe: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = -console;
|
||||
console.log(delete +a);
|
||||
}
|
||||
expect: {
|
||||
console.log(true);
|
||||
}
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
issue_5380: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function f(b) {
|
||||
return function g() {
|
||||
for (b in { PASS: 42 });
|
||||
}(), b;
|
||||
}("FAIL");
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = function f(b) {
|
||||
return function g() {
|
||||
for (b in { PASS: 42 });
|
||||
}(), b;
|
||||
}("FAIL");
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5558: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 99, b = 0;
|
||||
a++;
|
||||
b++;
|
||||
b += a;
|
||||
b *= a;
|
||||
b += a;
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 99, b = 0;
|
||||
b++,
|
||||
b = (b += ++a) * a + a,
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "100"
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ assignment_2: {
|
||||
}
|
||||
expect_exact: "var a=8n;a**=a;console.log(a);"
|
||||
expect_stdout: "16777216n"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.4.0"
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
@@ -99,8 +99,8 @@ issue_4664: {
|
||||
expect: {
|
||||
(function f() {
|
||||
new function(a) {
|
||||
console.log(typeof f, a, typeof this);
|
||||
}((A = 0, 2 ** 30));
|
||||
console.log(typeof f, 2 ** 30, typeof this);
|
||||
}(A = 0);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "function 1073741824 object"
|
||||
|
||||
@@ -109,6 +109,17 @@ foreign: {
|
||||
expect_exact: 'export*from"foo";export{}from"bar";export*as a from"baz";export{default}from"moo";export{b,c as case,default as delete,d}from"moz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
export * as "42" from 'foo';
|
||||
export { '42', "delete" as 'foo' } from "bar";
|
||||
}
|
||||
expect_exact: "export*as\"42\"from'foo';export{'42',delete as foo}from\"bar\";"
|
||||
}
|
||||
|
||||
same_quotes: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
@@ -417,6 +428,46 @@ hoist_funs: {
|
||||
expect_exact: "export function f(){}export default async function*g(){}"
|
||||
}
|
||||
|
||||
instanceof_default_class: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default class A {
|
||||
f(a) {
|
||||
return a instanceof A;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
instanceof_default_function: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
export default function f() {
|
||||
if (!(this instanceof f))
|
||||
throw new Error("must instantiate");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue_4742_join_vars_1: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
@@ -496,3 +547,36 @@ issue_4766: {
|
||||
export var a = "bar";
|
||||
}
|
||||
}
|
||||
|
||||
issue_5444: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
export var a = (console, console);
|
||||
}
|
||||
expect: {
|
||||
console;
|
||||
export var a = console;
|
||||
}
|
||||
}
|
||||
|
||||
issue_5628: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
export default function f() {
|
||||
for (a in 42);
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -217,7 +217,8 @@ name_collision_1: {
|
||||
var obj_foo = 1;
|
||||
var obj_bar = 2;
|
||||
function f() {
|
||||
var obj_foo$0 = 3,
|
||||
var obj,
|
||||
obj_foo$0 = 3,
|
||||
obj_bar = 4,
|
||||
obj_b_r = 5,
|
||||
obj_b_r$0 = 6,
|
||||
@@ -249,7 +250,8 @@ name_collision_2: {
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5), o__$0, o__$1);
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
var o,
|
||||
o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
@@ -283,7 +285,8 @@ name_collision_3: {
|
||||
console.log(o.p === o.p, o["+"](4), o["-"](5));
|
||||
}
|
||||
expect: {
|
||||
var o_p = 1,
|
||||
var o,
|
||||
o_p = 1,
|
||||
o__ = function(x) {
|
||||
return x;
|
||||
},
|
||||
@@ -315,7 +318,7 @@ name_collision_4: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var o_p$0 = 0, o_q = "PASS";
|
||||
var o, o_p$0 = 0, o_q = "PASS";
|
||||
return function(o_p) {
|
||||
if (!o_p$0) return o_p;
|
||||
}(o_q);
|
||||
@@ -459,6 +462,11 @@ issue_2473_1: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_2: {
|
||||
@@ -481,6 +489,11 @@ issue_2473_2: {
|
||||
var x = {};
|
||||
var y = [];
|
||||
}
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable x",
|
||||
"INFO: Retaining variable y",
|
||||
"WARN: Dropping unused variable z [test/compress/hoist_props.js:3,12]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_3: {
|
||||
@@ -506,6 +519,9 @@ issue_2473_3: {
|
||||
console.log(o.a, o.b);
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Retaining variable o",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2473_4: {
|
||||
@@ -532,6 +548,9 @@ issue_2473_4: {
|
||||
})();
|
||||
}
|
||||
expect_stdout: "1 2"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable o [test/compress/hoist_props.js:2,16]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_2508_1: {
|
||||
@@ -768,7 +787,7 @@ issue_3046: {
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
do {
|
||||
var b_c = a++;
|
||||
var b, b_c = a++;
|
||||
} while (b_c && a);
|
||||
return a;
|
||||
}(0));
|
||||
@@ -931,7 +950,7 @@ issue_3411: {
|
||||
expect: {
|
||||
var c = 1;
|
||||
!function f() {
|
||||
var o_p = --c && f();
|
||||
var o, o_p = --c && f();
|
||||
+{} || console.log("PASS");
|
||||
}();
|
||||
}
|
||||
@@ -1042,9 +1061,7 @@ issue_3945_1: {
|
||||
expect: {
|
||||
function f() {
|
||||
o.p;
|
||||
var o = {
|
||||
q: 0,
|
||||
};
|
||||
var o, o_q = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1063,9 +1080,7 @@ issue_3945_2: {
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof o);
|
||||
var o = {
|
||||
p: 0,
|
||||
};
|
||||
var o, o_p = 0;
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
@@ -1134,10 +1149,94 @@ issue_4985: {
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
var a_p = 42;
|
||||
var a, a_p = 42;
|
||||
console.log(function() {
|
||||
({});
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_5182: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
merge_vars: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = console;
|
||||
log = o.log;
|
||||
o = {
|
||||
p: function(a) {
|
||||
console.log(a ? "PASS" : "FAIL");
|
||||
return a;
|
||||
},
|
||||
};
|
||||
log(o.p(42));
|
||||
}
|
||||
expect: {
|
||||
var o = console;
|
||||
log = o.log;
|
||||
o = function(a) {
|
||||
console.log(a ? "PASS" : "FAIL");
|
||||
return a;
|
||||
};
|
||||
log(o(42));
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"42",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5441: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
(function() {
|
||||
a = { p: this };
|
||||
})();
|
||||
return typeof a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
(function() {
|
||||
a_p = this;
|
||||
})();
|
||||
var a_p;
|
||||
return typeof {};
|
||||
}());
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
issue_5498: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
__proto__: 42,
|
||||
};
|
||||
while (console.log(typeof o.__proto__));
|
||||
}
|
||||
expect_stdout: "object"
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@ statements: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -25,6 +27,8 @@ statements_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -48,6 +52,8 @@ sequences: {
|
||||
options = {
|
||||
hoist_funs: false,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -71,6 +77,8 @@ sequences_funs: {
|
||||
options = {
|
||||
hoist_funs: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
@@ -108,7 +116,8 @@ catch_var: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
a = "PASS";
|
||||
var a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -118,6 +127,8 @@ issue_2295: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function foo(o) {
|
||||
@@ -135,10 +146,11 @@ issue_2295: {
|
||||
}
|
||||
}
|
||||
|
||||
issue_4487: {
|
||||
issue_4487_1: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -150,16 +162,66 @@ issue_4487: {
|
||||
};
|
||||
var b = a();
|
||||
}
|
||||
expect: {
|
||||
var a = function f() {
|
||||
var f = console.log(typeof f);
|
||||
};
|
||||
a();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4487_2: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function f() {
|
||||
var f = console.log(typeof f);
|
||||
};
|
||||
var b = a();
|
||||
}
|
||||
expect: {
|
||||
function a() {
|
||||
var f;
|
||||
console.log(typeof f);
|
||||
var f = console.log(typeof f);
|
||||
}
|
||||
a();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4487_3: {
|
||||
options = {
|
||||
functions: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fnames: true,
|
||||
passes: 3,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function f() {
|
||||
var f = console.log(typeof f);
|
||||
};
|
||||
var b = a();
|
||||
}
|
||||
expect: {
|
||||
(function a() {
|
||||
console.log(typeof void 0);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4489: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -176,8 +238,7 @@ issue_4489: {
|
||||
console.log(k);
|
||||
}
|
||||
expect: {
|
||||
!(A = 0);
|
||||
for (var k in true);
|
||||
for (var k in !(A = 0));
|
||||
console.log(k);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -201,9 +262,7 @@ issue_4517: {
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
var a = 2;
|
||||
A = a;
|
||||
return A + typeof !1;
|
||||
return (A = 2) + typeof !1;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "2boolean"
|
||||
@@ -214,6 +273,7 @@ issue_4736: {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -233,8 +293,8 @@ issue_4736: {
|
||||
expect: {
|
||||
(function() {
|
||||
(function() {
|
||||
0,
|
||||
console.log(1073741824);
|
||||
0;
|
||||
console.log(1 << 30);
|
||||
})();
|
||||
})();
|
||||
}
|
||||
@@ -245,24 +305,25 @@ issue_4839: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = function(a, b) {
|
||||
var log = console.log, o = function(a, b) {
|
||||
return b && b;
|
||||
}("foo");
|
||||
for (var k in o)
|
||||
throw "FAIL";
|
||||
console.log("PASS");
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var k, o = void 0;
|
||||
for (k in o)
|
||||
var k, log = console.log;
|
||||
for (k in void 0)
|
||||
throw "FAIL";
|
||||
console.log("PASS");
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -271,6 +332,7 @@ issue_4859: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
keep_infinity: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
@@ -288,8 +350,7 @@ issue_4859: {
|
||||
}
|
||||
expect: {
|
||||
(function f(a) {
|
||||
var d = 1 / 0, d = Infinity;
|
||||
console.log(d);
|
||||
console.log(2 + 1 / 0);
|
||||
return f;
|
||||
})();
|
||||
}
|
||||
@@ -361,9 +422,9 @@ issue_4893_2: {
|
||||
expect: {
|
||||
try{
|
||||
(function() {
|
||||
var b;
|
||||
b = null;
|
||||
b.p += 42;
|
||||
var a;
|
||||
a = null;
|
||||
a.p += 42;
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
@@ -395,3 +456,348 @@ issue_4898: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5187_1: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 42;
|
||||
do {
|
||||
var b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a, b;
|
||||
a = 42;
|
||||
do {
|
||||
b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5187_2: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a = 42;
|
||||
do {
|
||||
var b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var b, a = 42;
|
||||
do {
|
||||
b = { 0: a++ };
|
||||
} while (console.log(b[b ^= 0]));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5195: {
|
||||
options = {
|
||||
hoist_props: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f() {
|
||||
var a;
|
||||
do {
|
||||
var b = { p: a };
|
||||
} while (console.log(b += ""));
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
var a, b;
|
||||
do {
|
||||
b = { p: a };
|
||||
} while (console.log(b += ""));
|
||||
})();
|
||||
}
|
||||
expect_stdout: "[object Object]"
|
||||
}
|
||||
|
||||
issue_5378: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 2;
|
||||
while (a--)
|
||||
(function() {
|
||||
var b;
|
||||
var c;
|
||||
while (console.log(b));
|
||||
--b;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = 2;
|
||||
while (a--) {
|
||||
b = void 0;
|
||||
var b, c;
|
||||
while (console.log(b));
|
||||
--b;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5411_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
b++;
|
||||
b = a;
|
||||
var b = b, c = c && c[b];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var a, b, c;
|
||||
b++;
|
||||
b = a = "PASS";
|
||||
c = c && c[b];
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5411_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
b++;
|
||||
b = a;
|
||||
var b = b, c = c && c[b];
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b, c;
|
||||
b++;
|
||||
b = "PASS",
|
||||
c;
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5411_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = console;
|
||||
a++;
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = console;
|
||||
a = A = ++a;
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5411_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = console;
|
||||
a++;
|
||||
var a = A = a;
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
var a = console;
|
||||
a = A = ++a;
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5626: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
return console.log(arguments[0]), 42;
|
||||
}("PASS") ? null : "foo";
|
||||
for (var b in a)
|
||||
FAIL;
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
console.log(arguments[0]);
|
||||
}("PASS"));
|
||||
for (var b in null)
|
||||
FAIL;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5638_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 42 ];
|
||||
console || FAIL(a);
|
||||
console.log(a++);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
a = "FAIL";
|
||||
a = [ 6 ];
|
||||
console || FAIL(a);
|
||||
console.log(a *= 7);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_5638_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 42 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 42 }) {
|
||||
v = o[k];
|
||||
log(k || v, v++);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
issue_5638_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
hoist_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var o = { foo: 6 };
|
||||
for (var k in o) {
|
||||
var v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var log, o, k, v;
|
||||
log = console.log;
|
||||
for (k in o = { foo: 6 }) {
|
||||
v = o[k];
|
||||
log(k || v, v *= 7);
|
||||
}
|
||||
}
|
||||
expect_stdout: "foo 42"
|
||||
}
|
||||
|
||||
@@ -2631,13 +2631,14 @@ issue_3999: {
|
||||
]
|
||||
}
|
||||
|
||||
issue_4001: {
|
||||
issue_4001_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: false,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -2660,7 +2661,42 @@ issue_4001: {
|
||||
return a;
|
||||
}
|
||||
var a;
|
||||
console.log((a = 42, void f()[42], void function a() {}));
|
||||
console.log((a = 42, f()[42], void f, void function a() {}));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_4001_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
ie: true,
|
||||
inline: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
function f() {
|
||||
return a;
|
||||
var b;
|
||||
}
|
||||
var c = f();
|
||||
(function g() {
|
||||
c[42];
|
||||
f;
|
||||
})();
|
||||
(function a() {});
|
||||
}(42));
|
||||
}
|
||||
expect: {
|
||||
function f() {
|
||||
return a;
|
||||
}
|
||||
var a;
|
||||
console.log((a = 42, void f()[42]));
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
@@ -3109,9 +3145,9 @@ issue_5081_call: {
|
||||
}));
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
function f(a) {
|
||||
// IE5-10: TypeError: Function expected
|
||||
return b(b = "A") + (b += "SS");
|
||||
return a(a = "A") + (a += "SS");
|
||||
}
|
||||
console.log(f(function() {
|
||||
return "P";
|
||||
@@ -3161,8 +3197,8 @@ issue_5081_property_access: {
|
||||
console.log(f({ A: "P" }));
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
return b[b = "A"] + (b += "SS");
|
||||
function f(a) {
|
||||
return a[a = "A"] + (a += "SS");
|
||||
}
|
||||
// IE9-11: undefinedASS
|
||||
console.log(f({ A: "P" }));
|
||||
@@ -3192,3 +3228,249 @@ issue_5081_property_access_ie: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5269_1: {
|
||||
options = {
|
||||
ie: false,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
do {
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
})();
|
||||
} while (!console);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
} while (!console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5269_1_ie: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
do {
|
||||
(function() {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
})();
|
||||
} while (!console);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
try {
|
||||
throw "PASS";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
} while (!console);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5269_2: {
|
||||
options = {
|
||||
ie: false,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
(function() {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
var e = "FAIL 1";
|
||||
}
|
||||
e = "FAIL 2";
|
||||
console;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
e = void 0;
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
var e = "FAIL 1";
|
||||
}
|
||||
e = "FAIL 2";
|
||||
console;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5269_2_ie: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
for (var i = 0; i < 2; i++)
|
||||
(function() {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
var e = "FAIL 1";
|
||||
}
|
||||
e = "FAIL 2";
|
||||
console;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
e = void 0;
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
var e = "FAIL 1";
|
||||
}
|
||||
e = "FAIL 2";
|
||||
console;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5269_3: {
|
||||
options = {
|
||||
ie: false,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
e = "foo";
|
||||
for (var i = 0; i < 2; i++)
|
||||
(function() {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
e = "FAIL";
|
||||
}
|
||||
e = "bar";
|
||||
console;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
e = "foo";
|
||||
for (var i = 0; i < 2; i++) {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
e = "FAIL";
|
||||
}
|
||||
e = "bar";
|
||||
console;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5269_3_ie: {
|
||||
options = {
|
||||
ie: true,
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
e = "foo";
|
||||
for (var i = 0; i < 2; i++)
|
||||
(function() {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
e = "FAIL";
|
||||
}
|
||||
e = "bar";
|
||||
console;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
e = "foo";
|
||||
for (var i = 0; i < 2; i++) {
|
||||
console.log(e);
|
||||
try {
|
||||
console;
|
||||
} catch (e) {
|
||||
e = "FAIL";
|
||||
}
|
||||
e = "bar";
|
||||
console;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5350: {
|
||||
options = {
|
||||
ie: false,
|
||||
properties: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof f, [ 42, function f() {} ][0]);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof f, 42);
|
||||
}
|
||||
expect_stdout: "undefined 42"
|
||||
}
|
||||
|
||||
issue_5350_ie: {
|
||||
options = {
|
||||
ie: true,
|
||||
properties: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof f, [ 42, function f() {} ][0]);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof f, (function f() {}, 42));
|
||||
}
|
||||
expect_stdout: "undefined 42"
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -40,6 +40,17 @@ default_keys: {
|
||||
expect_exact: 'import foo,{bar}from"baz";'
|
||||
}
|
||||
|
||||
non_identifiers: {
|
||||
beautify = {
|
||||
quote_style: 3,
|
||||
}
|
||||
input: {
|
||||
import { '42' as foo } from "bar";
|
||||
import { "foo" as bar } from 'baz';
|
||||
}
|
||||
expect_exact: "import{'42'as foo}from\"bar\";import{foo as bar}from'baz';"
|
||||
}
|
||||
|
||||
dynamic: {
|
||||
input: {
|
||||
(async a => await import(a))("foo").then(bar);
|
||||
@@ -106,6 +117,22 @@ drop_unused: {
|
||||
}
|
||||
}
|
||||
|
||||
drop_side_effect_free: {
|
||||
options = {
|
||||
imports: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
import foo from "bar";
|
||||
var a = foo;
|
||||
}
|
||||
expect: {
|
||||
import "bar";
|
||||
}
|
||||
}
|
||||
|
||||
mangle: {
|
||||
rename = false
|
||||
mangle = {
|
||||
@@ -211,3 +238,33 @@ issue_4708_2: {
|
||||
import a from "foo";
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_1: {
|
||||
input: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
expect: {
|
||||
if (console)
|
||||
import("foo");
|
||||
else
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
|
||||
pr_5550_2: {
|
||||
input: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: {
|
||||
import("foo");
|
||||
import.meta.url.replace(/bar/g, console.log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100
test/compress/indentation.js
Normal file
100
test/compress/indentation.js
Normal file
@@ -0,0 +1,100 @@
|
||||
numeric: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
indent_start: 1,
|
||||
indent_level: 3,
|
||||
}
|
||||
input: {
|
||||
switch (42) {
|
||||
case null:
|
||||
console.log("FAIL");
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_exact: [
|
||||
" switch (42) {",
|
||||
" case null:",
|
||||
' console.log("FAIL");',
|
||||
" }",
|
||||
"",
|
||||
' console.log("PASS");',
|
||||
]
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
spaces: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
indent_start: " ",
|
||||
indent_level: " ",
|
||||
}
|
||||
input: {
|
||||
switch (42) {
|
||||
case null:
|
||||
console.log("FAIL");
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_exact: [
|
||||
" switch (42) {",
|
||||
" case null:",
|
||||
' console.log("FAIL");',
|
||||
" }",
|
||||
"",
|
||||
' console.log("PASS");',
|
||||
]
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
tabs: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
indent_start: "\t",
|
||||
indent_level: "\t",
|
||||
}
|
||||
input: {
|
||||
switch (42) {
|
||||
case null:
|
||||
console.log("FAIL");
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_exact: [
|
||||
"\tswitch (42) {",
|
||||
"\tcase null:",
|
||||
'\t\tconsole.log("FAIL");',
|
||||
"\t}",
|
||||
"",
|
||||
'\tconsole.log("PASS");',
|
||||
]
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
mixed: {
|
||||
beautify = {
|
||||
beautify: true,
|
||||
indent_start: "\n",
|
||||
indent_level: " \t",
|
||||
}
|
||||
input: {
|
||||
switch (42) {
|
||||
case null:
|
||||
console.log("FAIL");
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_exact: [
|
||||
"",
|
||||
"switch (42) {",
|
||||
"",
|
||||
" case null:",
|
||||
"",
|
||||
' \tconsole.log("FAIL");',
|
||||
"",
|
||||
"}",
|
||||
"",
|
||||
"",
|
||||
'console.log("PASS");',
|
||||
]
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -4,22 +4,21 @@ multiple_functions: {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
(function() {
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
(function() {
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( !window );
|
||||
if (!window);
|
||||
function f() {}
|
||||
function g() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,18 +28,17 @@ single_function: {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
(function() {
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( !window );
|
||||
(function() {
|
||||
if (!window);
|
||||
function f() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,28 +48,26 @@ deeply_nested: {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
(function() {
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
function f() {}
|
||||
function g() {}
|
||||
if ( !document ) {
|
||||
if (!document)
|
||||
return;
|
||||
}
|
||||
function h() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
(function() {
|
||||
// NOTE: other compression steps will reduce this
|
||||
// down to just `window`.
|
||||
if ( window )
|
||||
if ( !document );
|
||||
if (!window);
|
||||
else if (!document);
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
} )();
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,18 +77,18 @@ not_hoisted_when_already_nested: {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
( function() {
|
||||
if ( !window ) {
|
||||
(function() {
|
||||
if (!window)
|
||||
return;
|
||||
}
|
||||
if ( foo ) function f() {}
|
||||
} )();
|
||||
if (foo) function f() {}
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
( function() {
|
||||
if ( window )
|
||||
if ( foo ) function f() {}
|
||||
} )();
|
||||
(function() {
|
||||
if (!window);
|
||||
else if (foo)
|
||||
function f() {}
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -104,15 +100,19 @@ defun_if_return: {
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
if (!window)
|
||||
return;
|
||||
else
|
||||
function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
if (!window);
|
||||
else
|
||||
function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
@@ -126,8 +126,10 @@ defun_hoist_funs: {
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (!window) return;
|
||||
else function g() {}
|
||||
if (!window)
|
||||
return;
|
||||
else
|
||||
function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
@@ -136,7 +138,7 @@ defun_hoist_funs: {
|
||||
function f() {}
|
||||
function g() {}
|
||||
function h() {}
|
||||
if (window);
|
||||
if (!window);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,15 +151,18 @@ defun_else_if_return: {
|
||||
input: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
else return;
|
||||
if (window)
|
||||
function g() {}
|
||||
else
|
||||
return;
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function e() {
|
||||
function f() {}
|
||||
if (window) function g() {}
|
||||
if (window)
|
||||
function g() {}
|
||||
function h() {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ conditional_false_stray_else_in_loop: {
|
||||
console.log(i);
|
||||
}
|
||||
}
|
||||
expect_exact: "for(var i=1;i<=4;++i)if(!(i<=2))console.log(i);"
|
||||
expect_stdout: true
|
||||
expect_exact: "for(var i=1;i<=4;++i)if(i<=2);else console.log(i);"
|
||||
expect_stdout: [
|
||||
"3",
|
||||
"4",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -356,6 +356,7 @@ mangle_catch_redef_3: {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
// prints "FAIL" if inlined on Node.js v4-
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
@@ -366,7 +367,8 @@ mangle_catch_redef_3: {
|
||||
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: true
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_toplevel: {
|
||||
@@ -379,6 +381,7 @@ mangle_catch_redef_3_toplevel: {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
// prints "FAIL" if inlined on Node.js v4-
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
@@ -389,7 +392,8 @@ mangle_catch_redef_3_toplevel: {
|
||||
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: true
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8: {
|
||||
@@ -402,6 +406,7 @@ mangle_catch_redef_3_ie8: {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
// prints "FAIL" if inlined on Node.js v4-
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
@@ -412,7 +417,8 @@ mangle_catch_redef_3_ie8: {
|
||||
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: true
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
mangle_catch_redef_3_ie8_toplevel: {
|
||||
@@ -425,6 +431,7 @@ mangle_catch_redef_3_ie8_toplevel: {
|
||||
try {
|
||||
throw 0;
|
||||
} catch (o) {
|
||||
// prints "FAIL" if inlined on Node.js v4-
|
||||
(function() {
|
||||
function f() {
|
||||
o = "FAIL";
|
||||
@@ -435,5 +442,6 @@ mangle_catch_redef_3_ie8_toplevel: {
|
||||
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: true
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -53,6 +53,14 @@ mangle_props: {
|
||||
);
|
||||
}
|
||||
expect_stdout: "1 1 1 2 2 2 3 3 3 4 4 4 5 5"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property undefined",
|
||||
"INFO: Preserving reserved property NaN",
|
||||
"INFO: Preserving reserved property Infinity",
|
||||
"INFO: Preserving reserved property -Infinity",
|
||||
"INFO: Preserving reserved property null",
|
||||
"INFO: Preserving reserved property log",
|
||||
]
|
||||
}
|
||||
|
||||
numeric_literal: {
|
||||
@@ -106,11 +114,18 @@ numeric_literal: {
|
||||
"4 5 4 4",
|
||||
"8 7 8",
|
||||
]
|
||||
expect_warnings: [
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property 0x25 to o",
|
||||
"INFO: Mapping property 1E42 to b",
|
||||
]
|
||||
}
|
||||
|
||||
identifier: {
|
||||
mangle = {
|
||||
properties: true,
|
||||
properties: {
|
||||
builtins: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var obj = {
|
||||
@@ -209,37 +224,37 @@ identifier: {
|
||||
B: 28,
|
||||
C: 29,
|
||||
D: 30,
|
||||
F: 31,
|
||||
G: 32,
|
||||
false: 33,
|
||||
null: 34,
|
||||
true: 35,
|
||||
H: 36,
|
||||
I: 37,
|
||||
J: 38,
|
||||
K: 39,
|
||||
L: 40,
|
||||
M: 41,
|
||||
N: 42,
|
||||
O: 43,
|
||||
P: 44,
|
||||
Q: 45,
|
||||
R: 46,
|
||||
S: 47,
|
||||
T: 48,
|
||||
U: 49,
|
||||
V: 50,
|
||||
W: 51,
|
||||
X: 52,
|
||||
Y: 53,
|
||||
Z: 54,
|
||||
$: 55,
|
||||
_: 56,
|
||||
ee: 57,
|
||||
te: 58,
|
||||
ne: 59,
|
||||
ae: 60,
|
||||
ie: 61,
|
||||
E: 31,
|
||||
F: 32,
|
||||
G: 33,
|
||||
H: 34,
|
||||
I: 35,
|
||||
J: 36,
|
||||
K: 37,
|
||||
L: 38,
|
||||
M: 39,
|
||||
N: 40,
|
||||
O: 41,
|
||||
P: 42,
|
||||
Q: 43,
|
||||
R: 44,
|
||||
S: 45,
|
||||
T: 46,
|
||||
U: 47,
|
||||
V: 48,
|
||||
W: 49,
|
||||
X: 50,
|
||||
Y: 51,
|
||||
Z: 52,
|
||||
$: 53,
|
||||
_: 54,
|
||||
ee: 55,
|
||||
te: 56,
|
||||
ne: 57,
|
||||
ae: 58,
|
||||
ie: 59,
|
||||
oe: 60,
|
||||
re: 61,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,6 +108,7 @@ safe_undefined: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -123,6 +124,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -203,6 +205,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -215,11 +218,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: 'void console.log("test");'
|
||||
expect_exact: 'void console.log("test")'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
inline: true,
|
||||
@@ -232,7 +236,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(void console.log("test"))()()();'
|
||||
expect_exact: '(void console.log("test"))()()()'
|
||||
}
|
||||
|
||||
negate_iife_issue_1073: {
|
||||
|
||||
195
test/compress/issue-5614.js
Normal file
195
test/compress/issue-5614.js
Normal file
@@ -0,0 +1,195 @@
|
||||
record_update: {
|
||||
options = {
|
||||
loops: true,
|
||||
passes: 3,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var value = { a: 42, b: "PASS" };
|
||||
var unused = _Utils_update(value, { b: "FAIL" });
|
||||
function _Utils_update(oldRecord, updatedFields) {
|
||||
var newRecord = {};
|
||||
for (var key in oldRecord)
|
||||
newRecord[key] = oldRecord[key];
|
||||
for (var key in updatedFields)
|
||||
newRecord[key] = updatedFields[key];
|
||||
return newRecord;
|
||||
}
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
currying: {
|
||||
options = {
|
||||
inline: true,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function F(arity, fun, wrapper) {
|
||||
wrapper.a = arity;
|
||||
wrapper.f = fun;
|
||||
return wrapper;
|
||||
}
|
||||
function F2(fun) {
|
||||
return F(2, fun, function(a) {
|
||||
return function(b) {
|
||||
return fun(a, b);
|
||||
};
|
||||
});
|
||||
}
|
||||
function _Utils_eq(x, y) {
|
||||
var pair, stack = [], isEqual = _Utils_eqHelp(x, y, 0, stack);
|
||||
while (isEqual && (pair = stack.pop()))
|
||||
isEqual = _Utils_eqHelp(pair.a, pair.b, 0, stack);
|
||||
return isEqual;
|
||||
}
|
||||
var _Utils_equal = F2(_Utils_eq);
|
||||
}
|
||||
expect: {}
|
||||
}
|
||||
|
||||
conditional_property_write: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
var o = {};
|
||||
if (a)
|
||||
o.p = console.log("foo");
|
||||
else
|
||||
o.q = console.log("bar");
|
||||
o.r = console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
if (a)
|
||||
console.log("foo");
|
||||
else
|
||||
console.log("bar");
|
||||
console.log("baz");
|
||||
}
|
||||
f(42);
|
||||
f(null);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_1: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS", b = "FAIL";
|
||||
(b = a).toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = "FAIL";
|
||||
(b = "PASS").toString();
|
||||
console.log(b);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = null + 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = "PASS";
|
||||
if (false) {
|
||||
a = 0;
|
||||
a();
|
||||
}
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
(a = a || "PASS").toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
(a = (0, "PASS")).toString();
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instance_write: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
return a;
|
||||
}
|
||||
function g() {
|
||||
var o = {};
|
||||
var b = new f(o);
|
||||
if (console)
|
||||
b.p = "PASS";
|
||||
return o;
|
||||
}
|
||||
console.log(g().p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -68,6 +68,7 @@ drop_console_2: {
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
side_effects: true,
|
||||
@@ -106,6 +107,7 @@ wrongly_optimized: {
|
||||
}
|
||||
|
||||
negate_iife_1: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -119,6 +121,7 @@ negate_iife_1: {
|
||||
}
|
||||
|
||||
negate_iife_3: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -133,6 +136,7 @@ negate_iife_3: {
|
||||
}
|
||||
|
||||
negate_iife_3_off: {
|
||||
expression = true
|
||||
options = {
|
||||
conditionals: true,
|
||||
expression: true,
|
||||
@@ -215,6 +219,7 @@ negate_iife_5_off: {
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_true: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -226,11 +231,12 @@ issue_1254_negate_iife_true: {
|
||||
};
|
||||
})()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
issue_1254_negate_iife_nested: {
|
||||
expression = true
|
||||
options = {
|
||||
expression: true,
|
||||
negate_iife: true,
|
||||
@@ -242,7 +248,7 @@ issue_1254_negate_iife_nested: {
|
||||
};
|
||||
})()()()()();
|
||||
}
|
||||
expect_exact: '(function(){return function(){console.log("test")}})()()()()();'
|
||||
expect_exact: 'function(){return function(){console.log("test")}}()()()()()'
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -317,7 +323,35 @@ iife: {
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), typeof function g() {}();
|
||||
x = 42,
|
||||
function a() {}(),
|
||||
!function b() {}(),
|
||||
~function c() {}(),
|
||||
+function d() {}(),
|
||||
-function e() {}(),
|
||||
void function f() {}(),
|
||||
typeof function g() {}();
|
||||
}
|
||||
}
|
||||
|
||||
iife_drop_side_effect_free: {
|
||||
options = {
|
||||
expression: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
!function b() {}();
|
||||
~function c() {}();
|
||||
+function d() {}();
|
||||
-function e() {}();
|
||||
void function f() {}();
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42,
|
||||
typeof void 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,11 @@ dont_reuse_prop: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property asd to b",
|
||||
]
|
||||
}
|
||||
|
||||
unmangleable_props_should_always_be_reserved: {
|
||||
@@ -42,4 +47,9 @@ unmangleable_props_should_always_be_reserved: {
|
||||
console.log(obj.a);
|
||||
}
|
||||
expect_stdout: "123"
|
||||
expect_warnings: [
|
||||
"INFO: Preserving excluded property a",
|
||||
"INFO: Preserving reserved property log",
|
||||
"INFO: Mapping property asd to b",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
dont_mangle_arguments: {
|
||||
mangle = {
|
||||
};
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
@@ -21,12 +19,13 @@ dont_mangle_arguments: {
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
mangle = {}
|
||||
input: {
|
||||
(function(){
|
||||
var arguments = arguments, not_arguments = 9;
|
||||
console.log(not_arguments, arguments);
|
||||
})(5,6,7);
|
||||
})(5, 6, 7);
|
||||
}
|
||||
expect_exact: "(function(){var arguments=arguments,o=9;console.log(o,arguments)})(5,6,7);"
|
||||
expect_exact: "(function(){var arguments,o=9;console.log(o,arguments)})(5,6,7);"
|
||||
expect_stdout: true
|
||||
}
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
keep_var_for_in: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var foo = 5;
|
||||
for (var i in obj)
|
||||
return foo;
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(obj){
|
||||
(function(obj) {
|
||||
var i, foo = 5;
|
||||
for (i in obj)
|
||||
return foo;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
issue979_reported: {
|
||||
reported: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
@@ -17,29 +17,26 @@ issue979_reported: {
|
||||
}
|
||||
input: {
|
||||
function f1() {
|
||||
if (a == 1 || b == 2) {
|
||||
if (a == 1 || b == 2)
|
||||
foo();
|
||||
}
|
||||
}
|
||||
function f2() {
|
||||
if (!(a == 1 || b == 2)) {
|
||||
}
|
||||
else {
|
||||
if (!(a == 1 || b == 2));
|
||||
else
|
||||
foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f1() {
|
||||
1!=a&&2!=b||foo();
|
||||
1 != a && 2 != b || foo();
|
||||
}
|
||||
function f2() {
|
||||
1!=a&&2!=b||foo();
|
||||
1 != a && 2 != b || foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
issue979_test_negated_is_best: {
|
||||
test_negated_is_best: {
|
||||
options = {
|
||||
booleans: true,
|
||||
comparisons: true,
|
||||
@@ -58,53 +55,47 @@ issue979_test_negated_is_best: {
|
||||
}
|
||||
input: {
|
||||
function f3() {
|
||||
if (a == 1 | b == 2) {
|
||||
if (a == 1 | b == 2)
|
||||
foo();
|
||||
}
|
||||
}
|
||||
function f4() {
|
||||
if (!(a == 1 | b == 2)) {
|
||||
}
|
||||
else {
|
||||
if (!(a == 1 | b == 2));
|
||||
else
|
||||
foo();
|
||||
}
|
||||
}
|
||||
function f5() {
|
||||
if (a == 1 && b == 2) {
|
||||
if (a == 1 && b == 2)
|
||||
foo();
|
||||
}
|
||||
}
|
||||
function f6() {
|
||||
if (!(a == 1 && b == 2)) {
|
||||
}
|
||||
else {
|
||||
if (!(a == 1 && b == 2));
|
||||
else
|
||||
foo();
|
||||
}
|
||||
}
|
||||
function f7() {
|
||||
if (a == 1 || b == 2) {
|
||||
if (a == 1 || b == 2)
|
||||
foo();
|
||||
}
|
||||
else {
|
||||
else
|
||||
return bar();
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
function f3() {
|
||||
1==a|2==b&&foo();
|
||||
1 == a | 2 == b && foo();
|
||||
}
|
||||
function f4() {
|
||||
1==a|2==b&&foo();
|
||||
1 == a | 2 == b && foo();
|
||||
}
|
||||
function f5() {
|
||||
1==a&&2==b&&foo();
|
||||
1 == a && 2 == b && foo();
|
||||
}
|
||||
function f6() {
|
||||
1!=a||2!=b||foo();
|
||||
1 == a && 2 == b && foo();
|
||||
}
|
||||
function f7() {
|
||||
if(1!=a&&2!=b)return bar();foo()
|
||||
if (1 != a && 2 != b)
|
||||
return bar();
|
||||
foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,6 +489,160 @@ join_object_assignments_regex: {
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
chained_assignments: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = a = {};
|
||||
b.p = "PASS";
|
||||
console.log(a.p);
|
||||
}
|
||||
expect: {
|
||||
var a, b = a = {
|
||||
p: "PASS",
|
||||
};
|
||||
console.log(a.p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
folded_assignments_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = {};
|
||||
a[a.PASS = 42] = "PASS";
|
||||
console.log(a[42], a.PASS);
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
PASS: 42,
|
||||
42: "PASS",
|
||||
};
|
||||
console.log(a[42], a.PASS);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
}
|
||||
|
||||
folded_assignments_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = {};
|
||||
a[42] = "FAIL";
|
||||
a[a.PASS = 42] = "PASS";
|
||||
console.log(a[42], a.PASS);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = {
|
||||
42: "FAIL",
|
||||
PASS: 42,
|
||||
};
|
||||
a[42] = "PASS";
|
||||
console.log(a[42], a.PASS);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
}
|
||||
|
||||
inlined_assignments: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(a = {}).p = "PASS";
|
||||
console.log(a.p);
|
||||
}
|
||||
expect: {
|
||||
var a = {
|
||||
p: "PASS",
|
||||
};
|
||||
console.log(a.p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inilne_for: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
for (; console.log("PASS"););
|
||||
};
|
||||
a();
|
||||
}
|
||||
expect: {
|
||||
for (; console.log("PASS"););
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
inilne_var: {
|
||||
options = {
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
var a = function() {
|
||||
var b = A;
|
||||
for (b in console.log(b));
|
||||
};
|
||||
a();
|
||||
}
|
||||
expect: {
|
||||
A = "PASS";
|
||||
var b = A;
|
||||
for (b in console.log(b));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
typescript_enum: {
|
||||
rename = true
|
||||
options = {
|
||||
assignments: true,
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
hoist_props: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
passes: 4,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var Enum;
|
||||
(function (Enum) {
|
||||
Enum[Enum.PASS = 42] = "PASS";
|
||||
})(Enum || (Enum = {}));
|
||||
console.log(Enum[42], Enum.PASS);
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS", 42);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
}
|
||||
|
||||
issue_2816: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
@@ -990,7 +1144,7 @@ conditional_assignments_3: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3856: {
|
||||
issue_3856_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
@@ -1015,9 +1169,46 @@ issue_3856: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
var a, b;
|
||||
if (a) return a, 1;
|
||||
for (a = 0; !console;);
|
||||
return 0;
|
||||
if (a) a;
|
||||
else {
|
||||
a = 0;
|
||||
for (; !console;);
|
||||
}
|
||||
})();
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
issue_3856_2: {
|
||||
options = {
|
||||
booleans: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
join_vars: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
var a;
|
||||
if (!a) {
|
||||
a = 0;
|
||||
for (var b; !console;);
|
||||
return 0;
|
||||
}
|
||||
if (a) return 1;
|
||||
})();
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
(function() {
|
||||
var a, b;
|
||||
if (!a)
|
||||
for (a = 0; !console;);
|
||||
})();
|
||||
}());
|
||||
}
|
||||
@@ -1172,10 +1363,7 @@ assign_sequence_var: {
|
||||
console.log(a, b, c);
|
||||
}
|
||||
expect: {
|
||||
var a = 0, b = 1;
|
||||
console.log(a),
|
||||
a++;
|
||||
var b = 2, c = 3;
|
||||
var a = 0, b = 1, c = (console.log(a), a++, b = 2, 3);
|
||||
console.log(a, b, c);
|
||||
}
|
||||
expect_stdout: [
|
||||
@@ -1183,3 +1371,26 @@ assign_sequence_var: {
|
||||
"1 2 3",
|
||||
]
|
||||
}
|
||||
|
||||
issue_5175: {
|
||||
options = {
|
||||
join_vars: true,
|
||||
}
|
||||
input: {
|
||||
function log(f) {
|
||||
console.log(f(), A.p);
|
||||
}
|
||||
log(function() {
|
||||
return (A = {}).p = "PASS";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
function log(f) {
|
||||
console.log(f(), A.p);
|
||||
}
|
||||
log(function() {
|
||||
return (A = {}).p = "PASS";
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS PASS"
|
||||
}
|
||||
|
||||
@@ -181,10 +181,10 @@ issue_2203_2: {
|
||||
a: "FAIL",
|
||||
b: function() {
|
||||
return function() {
|
||||
return (String, (Object, function() {
|
||||
return (Object, function() {
|
||||
return this;
|
||||
}())).a;
|
||||
}();
|
||||
}()).a;
|
||||
}(String);
|
||||
}
|
||||
}.b());
|
||||
}
|
||||
@@ -925,6 +925,28 @@ duplicate_lambda_defun_name_2: {
|
||||
expect_stdout: "0"
|
||||
}
|
||||
|
||||
function_argument_mangle: {
|
||||
mangle = {
|
||||
keep_fargs: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
A = "PASS";
|
||||
var a = A;
|
||||
(function(o) {
|
||||
console.log(a);
|
||||
})("FAIL");
|
||||
}
|
||||
expect: {
|
||||
A = "PASS";
|
||||
var n = A;
|
||||
(function(o) {
|
||||
console.log(n);
|
||||
})("FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
function_name_mangle: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
@@ -1217,6 +1239,7 @@ issues_3267_1: {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
|
||||
@@ -83,8 +83,9 @@ labels_5: {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
// should keep the break-s in the following
|
||||
// should keep `break`s below
|
||||
input: {
|
||||
while (foo) {
|
||||
if (bar) break;
|
||||
@@ -100,8 +101,8 @@ labels_5: {
|
||||
if (bar) break;
|
||||
console.log("foo");
|
||||
}
|
||||
out: while (foo) {
|
||||
if (bar) break out;
|
||||
while (foo) {
|
||||
if (bar) break;
|
||||
console.log("foo");
|
||||
}
|
||||
}
|
||||
@@ -110,6 +111,7 @@ labels_5: {
|
||||
labels_6: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: break out;
|
||||
@@ -189,23 +191,75 @@ labels_10: {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
y();
|
||||
out: while (42) {
|
||||
console.log("PASS");
|
||||
break out;
|
||||
z();
|
||||
k();
|
||||
console.log("FAIL");
|
||||
}
|
||||
};
|
||||
expect: {
|
||||
out: while (foo) {
|
||||
x();
|
||||
y();
|
||||
break out;
|
||||
while (42) {
|
||||
console.log("PASS");
|
||||
break;
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_11: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
L: if (console.log("PASS"))
|
||||
break L;
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
labels_12: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
if (console.log("foo"))
|
||||
break L;
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
break L;
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
if (!console.log("foo"))
|
||||
throw "bar";
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
if (console.log("baz"))
|
||||
break L;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
}
|
||||
|
||||
issue_4466_1: {
|
||||
@@ -327,3 +381,53 @@ issue_4466_2_toplevel_v8: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5522: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function() {
|
||||
L: try {
|
||||
return "FAIL";
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
return "PASS";
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5524: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
L: try {
|
||||
FAIL;
|
||||
} finally {
|
||||
break L;
|
||||
}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
retain_block: {
|
||||
retain_block_1: {
|
||||
options = {}
|
||||
input: {
|
||||
"use strict";
|
||||
@@ -20,6 +20,94 @@ retain_block: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_block_2: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
var a;
|
||||
let a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
var a;
|
||||
let a;
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_block_2_mangle: {
|
||||
rename = true
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
var a;
|
||||
let a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
var t;
|
||||
let t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retain_block_3: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
let a;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
let a;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_block_3_mangle: {
|
||||
rename = true
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
{
|
||||
let a;
|
||||
var a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
{
|
||||
let t;
|
||||
var t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retain_assignment: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
@@ -102,6 +190,96 @@ if_dead_branch: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
let b = "bar";
|
||||
while (console.log("baz"));
|
||||
console.log(b);
|
||||
} else {
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
retain_tail_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
var b = "foo";
|
||||
if (a) {
|
||||
while (console.log("bar"));
|
||||
console.log(b);
|
||||
} else {
|
||||
let b = "baz";
|
||||
while (console.log("moo"));
|
||||
console.log(b);
|
||||
}
|
||||
}
|
||||
f();
|
||||
f(42);
|
||||
}
|
||||
expect_stdout: [
|
||||
"moo",
|
||||
"baz",
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
merge_vars_1: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
@@ -182,8 +360,8 @@ merge_vars_3: {
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
}
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
var b = 1;
|
||||
console.log(typeof b);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
@@ -192,6 +370,38 @@ merge_vars_3: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
merge_vars_4: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
{
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
let a = 0;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = 1;
|
||||
console.log(typeof a);
|
||||
{
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
let a = 0;
|
||||
}
|
||||
}
|
||||
expect_stdout: [
|
||||
"number",
|
||||
"object",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
use_before_init_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -772,6 +982,40 @@ if_return_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
if_return_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "PASS";
|
||||
function f(b) {
|
||||
if (console) {
|
||||
let b = a;
|
||||
return b;
|
||||
} else
|
||||
while (console.log("FAIL 1"));
|
||||
return b;
|
||||
}
|
||||
console.log(f("FAIL 2"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
do_if_continue_1: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -792,8 +1036,7 @@ do_if_continue_1: {
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
if (console) {
|
||||
console.log("PASS");
|
||||
{
|
||||
let a = 0;
|
||||
@@ -826,8 +1069,7 @@ do_if_continue_2: {
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
if (!console);
|
||||
else {
|
||||
if (console) {
|
||||
console.log("FAIL");
|
||||
{
|
||||
let a = 0;
|
||||
@@ -966,12 +1208,10 @@ issue_4202: {
|
||||
"use strict";
|
||||
{
|
||||
let o = {};
|
||||
(function() {
|
||||
function f() {
|
||||
o.p = 42;
|
||||
}
|
||||
f(f);
|
||||
})();
|
||||
function f() {
|
||||
o.p = 42;
|
||||
}
|
||||
f(f);
|
||||
console.log(o.p++);
|
||||
}
|
||||
}
|
||||
@@ -1488,48 +1728,6 @@ issue_4305_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753_toplevel: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let e = 0; e < 1; e++)
|
||||
console.log(e);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4438: {
|
||||
options = {
|
||||
if_return: true,
|
||||
@@ -1549,9 +1747,7 @@ issue_4438: {
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
if (!console)
|
||||
;
|
||||
else {
|
||||
if (console) {
|
||||
let a = console.log;
|
||||
a("PASS");
|
||||
}
|
||||
@@ -1639,6 +1835,7 @@ issue_4689: {
|
||||
|
||||
issue_4691: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
toplevel: true,
|
||||
}
|
||||
@@ -1747,3 +1944,229 @@ issue_4985: {
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5240: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f() {
|
||||
if (console) {
|
||||
let g = function() {
|
||||
e;
|
||||
}, e;
|
||||
(function() {
|
||||
if (console) {
|
||||
console.log(e);
|
||||
var e = "FAIL";
|
||||
}
|
||||
})(console.log(e));
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f() {
|
||||
if (console) {
|
||||
let g = function() {
|
||||
e;
|
||||
}, e;
|
||||
(function() {
|
||||
if (console) {
|
||||
console.log(e);
|
||||
var e = "FAIL";
|
||||
}
|
||||
})(console.log(e));
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"undefined",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5254: {
|
||||
options = {
|
||||
inline: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
do {
|
||||
(function() {
|
||||
let a = console.log;
|
||||
a && a("foo");
|
||||
})();
|
||||
} while (console.log("bar"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
do {
|
||||
let a = console.log;
|
||||
a && a("foo");
|
||||
} while (console.log("bar"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5260: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
var a = "foo", o;
|
||||
while (console.log("bar"));
|
||||
o = {
|
||||
baz: function(b) {
|
||||
console.log(a, b);
|
||||
},
|
||||
};
|
||||
for (let a in o)
|
||||
o[a](a);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var a = "foo", o;
|
||||
while (console.log("bar"));
|
||||
o = {
|
||||
baz: function(b) {
|
||||
console.log(a, b);
|
||||
},
|
||||
};
|
||||
for (let a in o)
|
||||
o[a](a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5319: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
(function(a, c) {
|
||||
var b = a, c = b;
|
||||
{
|
||||
let a = c;
|
||||
console.log(c());
|
||||
}
|
||||
})(function() {
|
||||
return "PASS";
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
(function(a, c) {
|
||||
var b = a, c;
|
||||
{
|
||||
let a = c = b;
|
||||
console.log(c());
|
||||
}
|
||||
})(function() {
|
||||
return "PASS";
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5338: {
|
||||
options = {
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let a = a;
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
a;
|
||||
let a;
|
||||
}
|
||||
expect_stdout: ReferenceError("a is not defined")
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5476: {
|
||||
mangle = {
|
||||
keep_fargs: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(function(n) {
|
||||
let a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(function(n) {
|
||||
let o;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5591: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
function f(a) {
|
||||
switch (console.log("foo")) {
|
||||
case console.log("bar"):
|
||||
if (console.log("baz"))
|
||||
return;
|
||||
else {
|
||||
let a;
|
||||
return;
|
||||
}
|
||||
case null:
|
||||
FAIL;
|
||||
}
|
||||
}
|
||||
f();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -37,6 +37,51 @@ just_enough: {
|
||||
expect_warnings: []
|
||||
}
|
||||
|
||||
drop_semicolon: {
|
||||
beautify = {
|
||||
max_line_len: 5,
|
||||
semicolons: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(a || 42);
|
||||
}
|
||||
expect_exact: [
|
||||
"var a",
|
||||
"console.log(",
|
||||
"a||42",
|
||||
");",
|
||||
]
|
||||
expect_stdout: "42"
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 5 characters",
|
||||
]
|
||||
}
|
||||
|
||||
template_newline: {
|
||||
beautify = {
|
||||
max_line_len: 2,
|
||||
}
|
||||
input: {
|
||||
console.log(`foo
|
||||
bar`);
|
||||
}
|
||||
expect_exact: [
|
||||
"console.log(",
|
||||
"`foo",
|
||||
"bar`",
|
||||
");",
|
||||
]
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Output exceeds 2 characters",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_304: {
|
||||
beautify = {
|
||||
max_line_len: 10,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -122,13 +122,41 @@ negate_iife_4: {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
(function(){ return t })() ? console.log(true) : console.log(false);
|
||||
(function(){
|
||||
(function() {
|
||||
return t;
|
||||
})() ? console.log(true) : console.log(false);
|
||||
(function() {
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? console.log(false) : console.log(true), function(){
|
||||
!function() {
|
||||
return t;
|
||||
}() ? console.log(false) : console.log(true), !function() {
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_4_drop_side_effect_free: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
return t;
|
||||
})() ? console.log(true) : console.log(false);
|
||||
(function() {
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
return t;
|
||||
}() ? console.log(false) : console.log(true), function() {
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -176,17 +204,49 @@ negate_iife_5: {
|
||||
sequences: true,
|
||||
}
|
||||
input: {
|
||||
if ((function(){ return t })()) {
|
||||
if (function() {
|
||||
return t;
|
||||
}()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function(){
|
||||
(function() {
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function(){ return t }() ? bar(false) : foo(true), function(){
|
||||
!function() {
|
||||
return t;
|
||||
}() ? bar(false) : foo(true), !function() {
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
}
|
||||
|
||||
negate_iife_5_drop_side_effect_free: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
if (function() {
|
||||
return t;
|
||||
}()) {
|
||||
foo(true);
|
||||
} else {
|
||||
bar(false);
|
||||
}
|
||||
(function() {
|
||||
console.log("something");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
!function() {
|
||||
return t;
|
||||
}() ? bar(false) : foo(true), function() {
|
||||
console.log("something");
|
||||
}();
|
||||
}
|
||||
@@ -389,6 +449,7 @@ issue_1288_side_effects: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
negate_iife: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
@@ -409,10 +470,10 @@ issue_1288_side_effects: {
|
||||
})(0);
|
||||
}
|
||||
expect: {
|
||||
w;
|
||||
w,
|
||||
x || function() {
|
||||
x = {};
|
||||
}();
|
||||
}(),
|
||||
y;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,6 +262,30 @@ de_morgan_2e: {
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
inline_binary_nullish: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
while (console.log("foo"));
|
||||
})() ?? (function() {
|
||||
while (console.log("bar"));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
if (null == function() {
|
||||
while (console.log("foo"));
|
||||
}())
|
||||
while (console.log("bar"));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_4679: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
@@ -280,3 +304,43 @@ issue_4679: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5266: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
[
|
||||
42,
|
||||
null,
|
||||
false,
|
||||
void 0,
|
||||
"FAIL",
|
||||
].forEach(function (a) {
|
||||
a ?? function() {
|
||||
while (console.log(a));
|
||||
}();
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
[
|
||||
42,
|
||||
null,
|
||||
false,
|
||||
void 0,
|
||||
"FAIL",
|
||||
].forEach(function (a) {
|
||||
if (null == a) {
|
||||
while (console.log(a));
|
||||
return;
|
||||
} else
|
||||
return;
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"null",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
@@ -842,9 +842,9 @@ unary_binary_parentheses: {
|
||||
v.forEach(function(x) {
|
||||
v.forEach(function(y) {
|
||||
console.log(
|
||||
+x*y,
|
||||
+x/y,
|
||||
+x%y,
|
||||
x*y,
|
||||
x/y,
|
||||
x%y,
|
||||
-x*y,
|
||||
-x/y,
|
||||
-x%y
|
||||
@@ -1397,7 +1397,7 @@ issue_3695: {
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
console.log(+(a * (a[0] = false)));
|
||||
console.log(a * (a[0] = false));
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
@@ -521,3 +521,25 @@ issue_4415: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5213: {
|
||||
options = {
|
||||
objects: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
console.log({
|
||||
p: a = "PASS",
|
||||
0: a,
|
||||
p: null,
|
||||
}[0]);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
console.log({
|
||||
p: (a = "PASS", null),
|
||||
0: a,
|
||||
}[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -361,7 +361,9 @@ issue_4906: {
|
||||
} while (console.log("PASS"));
|
||||
}
|
||||
expect: {
|
||||
do {} while (console.log("PASS"));
|
||||
do {
|
||||
var a = a?.[42];
|
||||
} while (console.log("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
@@ -434,7 +436,7 @@ issue_5039: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
(function f() {});
|
||||
var a = a?.[function f() {}];
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -455,14 +457,163 @@ issue_5091: {
|
||||
console.log(f("FAIL 1") || "PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
var b = b.p;
|
||||
function f(a) {
|
||||
var a = a.p;
|
||||
var c;
|
||||
b?.[c = "FAIL 2"];
|
||||
return b || c;
|
||||
a?.[c = "FAIL 2"];
|
||||
return a || c;
|
||||
}
|
||||
console.log(f("FAIL 1") || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5292_dot: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
o?.p;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
o?.p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5292_dot_pure_getters: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
o?.p;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
issue_5292_dot_pure_getters_strict: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
o?.p;
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
}
|
||||
};
|
||||
o?.p;
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5292_sub: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
o?.[console.log("bar"), "p"];
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
o?.[console.log("bar"), "p"];
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
issue_5292_sub_pure_getters: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
o?.[console.log("bar"), "p"];
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
console.log("bar");
|
||||
}
|
||||
}
|
||||
|
||||
issue_5292_sub_pure_getters_strict: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
o?.[console.log("bar"), "p"];
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
get p() {
|
||||
console.log("foo");
|
||||
}
|
||||
};
|
||||
o?.[console.log("bar"), "p"];
|
||||
}
|
||||
expect_stdout: [
|
||||
"bar",
|
||||
"foo",
|
||||
]
|
||||
node_version: ">=14"
|
||||
}
|
||||
|
||||
@@ -97,10 +97,10 @@ return_5: {
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(tags,slug){",
|
||||
"var ref",
|
||||
"var ref;",
|
||||
"",
|
||||
"",
|
||||
";return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
|
||||
"return null!=(ref=_.find(tags,{slug:slug}))?ref.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
@@ -146,10 +146,10 @@ return_7: {
|
||||
}
|
||||
expect_exact: [
|
||||
"_is_selected=function(e,l){",
|
||||
"var n",
|
||||
"var n;",
|
||||
"",
|
||||
"",
|
||||
";return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
|
||||
"return null!=(n=_.find(e,{slug:l}))?n.selected:void 0};",
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
@@ -206,6 +206,7 @@ mangle_unquoted_properties: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
@@ -305,6 +306,7 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
builtins: true,
|
||||
debug: "XYZ",
|
||||
keep_quoted: true,
|
||||
reserved: [],
|
||||
@@ -351,6 +353,68 @@ mangle_debug_suffix_keep_quoted: {
|
||||
}
|
||||
}
|
||||
|
||||
keep_substituted_property: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
mangle = {
|
||||
properties: {
|
||||
keep_quoted: true,
|
||||
},
|
||||
}
|
||||
input: {
|
||||
var o = { p: [] };
|
||||
function f(b) {
|
||||
return o[b];
|
||||
}
|
||||
function g() {
|
||||
var a = "p";
|
||||
return o[a] === f(a);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var o = { p: [] };
|
||||
function f(n) {
|
||||
return o[n];
|
||||
}
|
||||
function g() {
|
||||
var n = "p";
|
||||
return o.p === f(n);
|
||||
}
|
||||
console.log(g() ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
keep_substituted_property_quotes: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
properties: true,
|
||||
reduce_vars: true,
|
||||
}
|
||||
beautify = {
|
||||
keep_quoted_props: true,
|
||||
}
|
||||
input: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o[a];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect: {
|
||||
function f(o) {
|
||||
var a = "p";
|
||||
return o["p"];
|
||||
}
|
||||
console.log(f({ p: "PASS" }));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
first_256_chars_as_properties: {
|
||||
beautify = {
|
||||
ascii_only: true,
|
||||
@@ -897,12 +961,15 @@ issue_2256: {
|
||||
},
|
||||
}
|
||||
input: {
|
||||
({ "keep": 1 });
|
||||
g.keep = g.change;
|
||||
({ "keep": 42 });
|
||||
global.keep = global.change;
|
||||
console.log(keep);
|
||||
}
|
||||
expect: {
|
||||
g.keep = g.g;
|
||||
global.keep = global.l;
|
||||
console.log(keep);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
}
|
||||
|
||||
lhs_prop_1: {
|
||||
@@ -1510,3 +1577,71 @@ issue_5093_quote_style: {
|
||||
expect_exact: 'console.log({a:true,\'42\':"PASS","null":[]}[6*7]);'
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
object_methods: {
|
||||
options = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
({
|
||||
p() {
|
||||
console.log("FAIL 1");
|
||||
},
|
||||
*q() {
|
||||
console.log("FAIL 2");
|
||||
},
|
||||
async r() {
|
||||
console.log("FAIL 3");
|
||||
},
|
||||
async *s() {
|
||||
console.log("PASS");
|
||||
},
|
||||
}).s().next();
|
||||
}
|
||||
expect: {
|
||||
[
|
||||
() => {
|
||||
console.log("FAIL 1");
|
||||
},
|
||||
function*() {
|
||||
console.log("FAIL 2");
|
||||
},
|
||||
async () => {
|
||||
console.log("FAIL 3");
|
||||
},
|
||||
async function*() {
|
||||
console.log("PASS");
|
||||
},
|
||||
][3]().next();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5177: {
|
||||
options = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var o = { a: "PASS" };
|
||||
o.p = {
|
||||
q() {
|
||||
return this.a;
|
||||
},
|
||||
}.q;
|
||||
console.log(o.p());
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
var o = { a: "PASS" };
|
||||
o.p = {
|
||||
q() {
|
||||
return this.a;
|
||||
},
|
||||
}.q;
|
||||
console.log(o.p());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ relational: {
|
||||
"bar" >= "bar";
|
||||
}
|
||||
expect: {
|
||||
bar();
|
||||
0 instanceof bar();
|
||||
bar();
|
||||
bar(), bar();
|
||||
bar();
|
||||
|
||||
@@ -1289,6 +1289,7 @@ issue_2878: {
|
||||
collapse_vars: true,
|
||||
pure_getters: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var c = 0;
|
||||
@@ -1363,9 +1364,8 @@ issue_3490_1: {
|
||||
}
|
||||
expect: {
|
||||
var b = 42, c = "FAIL";
|
||||
if (function() {
|
||||
var a;
|
||||
}(), c = "PASS", b) while ("" == typeof d);
|
||||
var a;
|
||||
if (c = "PASS", b) while ("" == typeof d);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1540,10 +1540,12 @@ this_toString: {
|
||||
issue_4803: {
|
||||
options = {
|
||||
hoist_vars: true,
|
||||
join_vars: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
@@ -1640,6 +1642,26 @@ nested_property_assignments_3: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
nested_property_assignments_4: {
|
||||
options = {
|
||||
pure_getters: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var n, o = { p: { q: { r: "PASS" } } };
|
||||
(n = o.p).r = n.q.r;
|
||||
console.log(o.p.r);
|
||||
}
|
||||
expect: {
|
||||
var n, o = { p: { q: { r: "PASS" } } };
|
||||
(n = o.p).r = n.q.r;
|
||||
console.log(o.p.r);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_4939: {
|
||||
options = {
|
||||
pure_getters: "strict",
|
||||
|
||||
@@ -6,6 +6,7 @@ reduce_vars: {
|
||||
C: 0,
|
||||
},
|
||||
inline: true,
|
||||
passes: 2,
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
@@ -41,10 +42,8 @@ reduce_vars: {
|
||||
}
|
||||
expect: {
|
||||
var A = 1;
|
||||
(function() {
|
||||
console.log(-3);
|
||||
console.log(A - 5);
|
||||
})();
|
||||
console.log(-3);
|
||||
console.log(A - 5);
|
||||
(function f1() {
|
||||
var a = 2;
|
||||
console.log(a - 5);
|
||||
@@ -905,7 +904,7 @@ use_before_var: {
|
||||
}
|
||||
expect: {
|
||||
function f(){
|
||||
console.log(void 0);
|
||||
console.log(t);
|
||||
var t = 1;
|
||||
}
|
||||
}
|
||||
@@ -981,7 +980,7 @@ inner_var_for_1: {
|
||||
expect: {
|
||||
function f() {
|
||||
var a = 1;
|
||||
x(1, void 0, d);
|
||||
x(1, b, d);
|
||||
for (var b = 2, c = 3; x(1, 2, 3, d); x(1, 2, 3, d)) {
|
||||
var d = 4, e = 5;
|
||||
x(1, 2, 3, d, e);
|
||||
@@ -2489,7 +2488,7 @@ side_effects_assign: {
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = typeof void (a && a.in);
|
||||
var a = "undefined";
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
@@ -2531,7 +2530,8 @@ pure_getters_2: {
|
||||
var a = a && a.b;
|
||||
}
|
||||
expect: {
|
||||
var a = a && a.b;
|
||||
var a;
|
||||
a && a.b;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5425,7 +5425,7 @@ issue_2774: {
|
||||
get a() {
|
||||
var b;
|
||||
(b = true) && b.c;
|
||||
b = void 0;
|
||||
void 0;
|
||||
}
|
||||
}.a);
|
||||
}
|
||||
@@ -6671,6 +6671,7 @@ issues_3267_1: {
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
negate_iife: true,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
@@ -6688,7 +6689,7 @@ issues_3267_1: {
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
!function(i) {
|
||||
!function(x) {
|
||||
if (Object())
|
||||
return console.log("PASS");
|
||||
throw "FAIL";
|
||||
@@ -6705,6 +6706,7 @@ issues_3267_2: {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
keep_fargs: false,
|
||||
negate_iife: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
sequences: true,
|
||||
@@ -7320,6 +7322,64 @@ local_assignment_loop: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
local_assignment_modified: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
(a = a || {}).p = 42;
|
||||
console.log(a.p);
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
(a = {}).p = 42;
|
||||
console.log(a.p);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
local_declaration: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
a || console.log(a = "PASS");
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
local_definition_modified: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = a || {};
|
||||
a.p = 42;
|
||||
console.log(a.p);
|
||||
}
|
||||
expect: {
|
||||
var a = {};
|
||||
a.p = 42;
|
||||
console.log(a.p);
|
||||
}
|
||||
expect_stdout: "42"
|
||||
}
|
||||
|
||||
issue_3957_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -7435,6 +7495,7 @@ issue_4030: {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
@@ -7772,3 +7833,97 @@ issue_5055_2: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5324: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = 0;
|
||||
do {
|
||||
var a, b = A;
|
||||
for (a in b)
|
||||
var c = b;
|
||||
} while (function() {
|
||||
var d;
|
||||
console.log(d *= A);
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
A = 0;
|
||||
do {
|
||||
var a, b = A;
|
||||
for (a in b);
|
||||
} while (b = void 0, void console.log(b *= A));
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
}
|
||||
|
||||
issue_5434: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var b = "FAIL";
|
||||
f && f();
|
||||
a = b;
|
||||
var f = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
}
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
for (var i = 0; i < 2; i++) {
|
||||
var b = "FAIL";
|
||||
f && f();
|
||||
a = b;
|
||||
var f = function() {
|
||||
b = "PASS";
|
||||
};
|
||||
}
|
||||
return a;
|
||||
}());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5623: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
evaluate: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b = a;
|
||||
a = b;
|
||||
}
|
||||
f && f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 0;
|
||||
function f() {
|
||||
var b;
|
||||
a = a;
|
||||
}
|
||||
f((a++ && a).toString());
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: "1"
|
||||
}
|
||||
|
||||
@@ -50,6 +50,22 @@ regexp_properties: {
|
||||
expect_stdout: "abc true false 0 false"
|
||||
}
|
||||
|
||||
instanceof_1: {
|
||||
input: {
|
||||
console.log(/foo/ instanceof RegExp);
|
||||
}
|
||||
expect_exact: "console.log(/foo/ instanceof RegExp);"
|
||||
expect_stdout: "true"
|
||||
}
|
||||
|
||||
instanceof_2: {
|
||||
input: {
|
||||
console.log(42 + /foo/ instanceof Object);
|
||||
}
|
||||
expect_exact: "console.log(42+/foo/ instanceof Object);"
|
||||
expect_stdout: "false"
|
||||
}
|
||||
|
||||
issue_3434_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
@@ -51,7 +51,7 @@ arrow_destructured_object_1: {
|
||||
}
|
||||
expect_exact: "var f=({...a})=>a,o=f({PASS:42});for(var k in o)console.log(k,o[k]);"
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
arrow_destructured_object_2: {
|
||||
@@ -62,7 +62,7 @@ arrow_destructured_object_2: {
|
||||
}
|
||||
expect_exact: "var f=({FAIL:a,...b})=>b,o=f({PASS:42,FAIL:null});for(var k in o)console.log(k,o[k]);"
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
arrow_destructured_object_3: {
|
||||
@@ -79,7 +79,7 @@ arrow_destructured_object_3: {
|
||||
"2 S",
|
||||
"3 S",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
funarg_1: {
|
||||
@@ -131,7 +131,7 @@ destructured_object_1: {
|
||||
}
|
||||
expect_exact: 'var{...a}=["FAIL","PASS",42];console.log(a[1],a[2]);'
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
destructured_object_2: {
|
||||
@@ -141,7 +141,7 @@ destructured_object_2: {
|
||||
}
|
||||
expect_exact: 'var{0:a,...b}=["FAIL","PASS",42];console.log(b[1],b[2]);'
|
||||
expect_stdout: "PASS 42"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
drop_fargs: {
|
||||
@@ -231,7 +231,7 @@ reduce_destructured_object: {
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
retain_destructured_array: {
|
||||
@@ -270,7 +270,7 @@ retain_destructured_object_1: {
|
||||
"1 PASS",
|
||||
"2 42",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
retain_destructured_object_2: {
|
||||
@@ -292,7 +292,7 @@ retain_destructured_object_2: {
|
||||
"bar PASS",
|
||||
"baz 42",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
retain_funarg_destructured_array_1: {
|
||||
@@ -344,11 +344,12 @@ retain_funarg_destructured_object_1: {
|
||||
console.log((({ ...a }) => a)([ "PASS" ])[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
retain_funarg_destructured_object_2: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
@@ -359,10 +360,10 @@ retain_funarg_destructured_object_2: {
|
||||
expect: {
|
||||
console.log(function({ p: a, ... b }) {
|
||||
return b;
|
||||
}({ p: "FAIL" }).p || "PASS");
|
||||
}({}).p || "PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
drop_unused_call_args_1: {
|
||||
@@ -436,9 +437,9 @@ merge_funarg: {
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
(function(...b) {
|
||||
var b = b.length;
|
||||
console.log(b);
|
||||
(function(...a) {
|
||||
var a = a.length;
|
||||
console.log(a);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "0"
|
||||
@@ -456,9 +457,9 @@ merge_funarg_destructured_array: {
|
||||
})([]);
|
||||
}
|
||||
expect: {
|
||||
(function([ ...b ]) {
|
||||
var b = b.length;
|
||||
console.log(b);
|
||||
(function([ ...a ]) {
|
||||
var a = a.length;
|
||||
console.log(a);
|
||||
})([]);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
@@ -476,13 +477,13 @@ merge_funarg_destructured_object: {
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect: {
|
||||
(function({ ...b }) {
|
||||
var b = b[0];
|
||||
console.log(b);
|
||||
(function({ ...a }) {
|
||||
var a = a[0];
|
||||
console.log(a);
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_arguments: {
|
||||
@@ -647,7 +648,7 @@ drop_new_function: {
|
||||
}
|
||||
expect: {
|
||||
void ([ ... {
|
||||
[console.log("PASS")]: [].e,
|
||||
[console.log("PASS")]: [][0],
|
||||
}] = []);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -866,9 +867,9 @@ issue_4575: {
|
||||
}
|
||||
expect: {
|
||||
(function(a) {
|
||||
(function a(...d) {
|
||||
(function(d) {
|
||||
console.log(d.length);
|
||||
})();
|
||||
})([]);
|
||||
})();
|
||||
}
|
||||
expect_stdout: "0"
|
||||
@@ -992,7 +993,7 @@ issue_5089_1: {
|
||||
console.log(o.p);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5089_2: {
|
||||
@@ -1019,7 +1020,7 @@ issue_5089_2: {
|
||||
console.log(o.p);
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5100_1: {
|
||||
@@ -1044,17 +1045,19 @@ issue_5100_1: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ {
|
||||
({
|
||||
p: {},
|
||||
...a
|
||||
} ] = [ {
|
||||
p: [ a = 42["q"] ],
|
||||
} = [ {
|
||||
p: {
|
||||
q: a,
|
||||
} = 42,
|
||||
r: "PASS",
|
||||
} ];
|
||||
} ][0]);
|
||||
console.log(a.r);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5100_2: {
|
||||
@@ -1077,20 +1080,23 @@ issue_5100_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
[ {
|
||||
({
|
||||
p: {},
|
||||
...a
|
||||
} ] = [ {
|
||||
p: [ console.log("PASS"), a = 42["q"] ],
|
||||
} ];
|
||||
} = [ {
|
||||
p: (console.log("PASS"), {
|
||||
q: a,
|
||||
} = 42),
|
||||
} ][0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=10"
|
||||
node_version: ">=10.22.0"
|
||||
}
|
||||
|
||||
issue_5108: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
unsafe: true,
|
||||
@@ -1102,9 +1108,518 @@ issue_5108: {
|
||||
}([ "PASS", "FAIL" ]));
|
||||
}
|
||||
expect: {
|
||||
console.log(function([]) {
|
||||
return "PASS";
|
||||
}([ "PASS", "FAIL" ]));
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5128_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return function f(...[ a ]) {
|
||||
return a;
|
||||
}("PASS");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(...[ a ]) {
|
||||
return a;
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5128_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
keep_fnames: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function() {
|
||||
return function f(...[ a ]) {
|
||||
return a;
|
||||
}("PASS");
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function f(...[ a ]) {
|
||||
return a;
|
||||
}("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5165_1: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function([ ...a ]) {
|
||||
switch (a) {
|
||||
case a:
|
||||
return "PASS";
|
||||
}
|
||||
}([]));
|
||||
}
|
||||
expect: {
|
||||
console.log(function([ ...a ]) {
|
||||
return "PASS";
|
||||
}([]));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5165_2: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
dead_code: true,
|
||||
evaluate: true,
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
side_effects: true,
|
||||
switches: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(...a) {
|
||||
switch (a) {
|
||||
case a:
|
||||
return "PASS";
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_1: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function([ , ...a ]) {
|
||||
return this && a;
|
||||
}([ , function(){} ])[0]);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function() {
|
||||
return this && [ function(){} ];
|
||||
}()[0]);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_2: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
reduce_vars: true,
|
||||
rests: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
A = [ , "PASS", "FAIL" ];
|
||||
var [ , ...a ] = [ ... A ];
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect: {
|
||||
A = [ , "PASS", "FAIL" ];
|
||||
var [ , ...a ] = [ ... A ];
|
||||
console.log(a[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5246_3: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function f(...[ [ a ] ]) {
|
||||
console.log(a);
|
||||
})([ "PASS" ]);
|
||||
}
|
||||
expect: {
|
||||
(function(...[ a ]) {
|
||||
console.log(a);
|
||||
})([ "PASS" ][0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5360: {
|
||||
options = {
|
||||
keep_fargs: false,
|
||||
pure_getters: "strict",
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(function({ p: {}, ...b }) {
|
||||
return b.q;
|
||||
}({
|
||||
p: ~a && ([ a ] = []),
|
||||
q: "PASS",
|
||||
}));
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log(function({ p: {}, ...b }) {
|
||||
return b.q;
|
||||
}({
|
||||
p: ~a && ([ a ] = []),
|
||||
q: "PASS",
|
||||
}));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5370: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
ie: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function arguments(...a) {
|
||||
return arguments;
|
||||
try {} catch (e) {
|
||||
var arguments;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
console.log(function arguments(...a) {
|
||||
return arguments;
|
||||
var arguments;
|
||||
}());
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5391: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
keep_fargs: false,
|
||||
objects: true,
|
||||
pure_getters: "strict",
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a, b = function f({
|
||||
p: {},
|
||||
...c
|
||||
}) {
|
||||
while (c.q);
|
||||
}({
|
||||
p: {
|
||||
r: a++,
|
||||
r: 0,
|
||||
}
|
||||
});
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
(function({
|
||||
p: {},
|
||||
...c
|
||||
}) {
|
||||
while (c.q);
|
||||
})({
|
||||
p: 0,
|
||||
});
|
||||
console.log(NaN);
|
||||
}
|
||||
expect_stdout: "NaN"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5533_1_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_1_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...b) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_keep_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: true,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5533_2_drop_fargs: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
inline: true,
|
||||
join_vars: true,
|
||||
keep_fargs: false,
|
||||
loops: true,
|
||||
side_effects: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
var a;
|
||||
for (; 1;)
|
||||
a = function() {
|
||||
(function f(...[ b ]) {
|
||||
b;
|
||||
throw "PASS";
|
||||
})();
|
||||
}();
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
try {
|
||||
(function() {
|
||||
for (;;)
|
||||
throw "PASS";
|
||||
})();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f, b = log();
|
||||
function f(...[ c = a = "PASS" ]) {}
|
||||
f((a = "FAIL", b));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_2: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
var a = f;
|
||||
function f(...{ [a = "PASS"]: b }) {}
|
||||
f((a = "FAIL", 42));
|
||||
log(a);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_3: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...[ c = a.pop() ]) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5552_4: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect: {
|
||||
var a = [ "FAIL", "PASS" ];
|
||||
console.log(function(b, ...{ [a.pop()]: c }) {
|
||||
return b;
|
||||
}(a.pop()));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
|
||||
@@ -201,3 +201,20 @@ issue_4811_2: {
|
||||
expect_stdout: "PASS [object global] true"
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5197: {
|
||||
rename = true
|
||||
input: {
|
||||
function f(async) {
|
||||
async(")=>{}");
|
||||
}
|
||||
console.log("" + this.__proto__);
|
||||
}
|
||||
expect: {
|
||||
function f(a) {
|
||||
a(")=>{}");
|
||||
}
|
||||
console.log("" + this.__proto__);
|
||||
}
|
||||
expect_stdout: "[object global]"
|
||||
}
|
||||
|
||||
@@ -289,8 +289,34 @@ iife: {
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42, function a() {}(), function b() {}(), function c() {}(),
|
||||
function d() {}(), function e() {}(), function f() {}(), function g() {}();
|
||||
x = 42,
|
||||
function a() {}(),
|
||||
!function b() {}(),
|
||||
~function c() {}(),
|
||||
+function d() {}(),
|
||||
-function e() {}(),
|
||||
void function f() {}(),
|
||||
typeof function g() {}();
|
||||
}
|
||||
}
|
||||
|
||||
iife_drop_side_effect_free: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
x = 42;
|
||||
(function a() {})();
|
||||
!function b() {}();
|
||||
~function c() {}();
|
||||
+function d() {}();
|
||||
-function e() {}();
|
||||
void function f() {}();
|
||||
typeof function g() {}();
|
||||
}
|
||||
expect: {
|
||||
x = 42;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -774,7 +800,7 @@ side_effects_cascade_3: {
|
||||
}
|
||||
expect: {
|
||||
function f(a, b) {
|
||||
(b += a) || (b = a) || (b -= a, b ^= a),
|
||||
(b += a) || (b = a) || (b = b - a ^ a),
|
||||
a--;
|
||||
}
|
||||
}
|
||||
@@ -910,9 +936,7 @@ hoist_decl: {
|
||||
var d;
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
w();
|
||||
var b = x(), c, d;
|
||||
var a, b = (w(), x()), c, d;
|
||||
for (y(); 0;) z();
|
||||
}
|
||||
}
|
||||
@@ -1047,11 +1071,102 @@ call: {
|
||||
b.c = function() {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
},
|
||||
a,
|
||||
b(),
|
||||
a,
|
||||
b.c(),
|
||||
(a, b.c)(),
|
||||
a,
|
||||
b["c"](),
|
||||
(a, b["c"])(),
|
||||
a,
|
||||
function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
a,
|
||||
new b(),
|
||||
a,
|
||||
new b.c(),
|
||||
a,
|
||||
new b.c(),
|
||||
a,
|
||||
new b["c"](),
|
||||
a,
|
||||
new b["c"](),
|
||||
a,
|
||||
new function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
console.log((a, typeof b.c)),
|
||||
console.log((a, typeof b["c"]));
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
"bar",
|
||||
"baz",
|
||||
"true",
|
||||
"foo",
|
||||
"baz",
|
||||
"baz",
|
||||
"baz",
|
||||
"baz",
|
||||
"false",
|
||||
"function",
|
||||
"function",
|
||||
]
|
||||
}
|
||||
|
||||
call_drop_side_effect_free: {
|
||||
options = {
|
||||
sequences: true,
|
||||
side_effects: 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, b.c)();
|
||||
(a, b)["c"]();
|
||||
(a, b["c"])();
|
||||
(a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
new (a, b)();
|
||||
new (a, b).c();
|
||||
new (a, b.c)();
|
||||
new (a, b)["c"]();
|
||||
new (a, b["c"])();
|
||||
new (a, function() {
|
||||
console.log(this === a);
|
||||
})();
|
||||
console.log(typeof (a, b).c);
|
||||
console.log(typeof (a, b)["c"]);
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
return this;
|
||||
}();
|
||||
function b() {
|
||||
console.log("foo");
|
||||
}
|
||||
b.c = function() {
|
||||
console.log(this === b ? "bar" : "baz");
|
||||
},
|
||||
b(),
|
||||
b.c(),
|
||||
(0, b.c)(),
|
||||
b["c"](),
|
||||
(0, b["c"])(),
|
||||
function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
@@ -1063,8 +1178,8 @@ call: {
|
||||
new function() {
|
||||
console.log(this === a);
|
||||
}(),
|
||||
console.log((a, typeof b.c)),
|
||||
console.log((a, typeof b["c"]));
|
||||
console.log(typeof b.c),
|
||||
console.log(typeof b["c"]);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
@@ -1099,6 +1214,26 @@ missing_link: {
|
||||
expect: {
|
||||
var a = 100;
|
||||
a,
|
||||
a++ + (0, 1),
|
||||
console.log(a);
|
||||
}
|
||||
}
|
||||
|
||||
missing_link_drop_side_effect_free: {
|
||||
options = {
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
var a = 100;
|
||||
a;
|
||||
a++ + (0 ? 2 : 1);
|
||||
console.log(a);
|
||||
}
|
||||
expect: {
|
||||
var a = 100;
|
||||
a++,
|
||||
console.log(a);
|
||||
}
|
||||
@@ -1162,10 +1297,8 @@ issue_3490_1: {
|
||||
}
|
||||
expect: {
|
||||
var b = 42, c = "FAIL";
|
||||
if (function() {
|
||||
var a;
|
||||
a && a.p;
|
||||
}(), c = "PASS", b) while ("" == typeof d);
|
||||
var a;
|
||||
if (a && a.p, c = "PASS", b) while ("" == typeof d);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
@@ -1195,9 +1328,8 @@ issue_3490_2: {
|
||||
}
|
||||
expect: {
|
||||
var b = 42, c = "FAIL";
|
||||
for (function() {
|
||||
var a;
|
||||
}(), c = "PASS", b; "" == typeof d;);
|
||||
var a;
|
||||
for (c = "PASS"; "" == typeof d;);
|
||||
console.log(c, b);
|
||||
}
|
||||
expect_stdout: "PASS 42"
|
||||
|
||||
@@ -318,6 +318,32 @@ unsafe_string_replace: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
unsafe_Object_call: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
unsafe: true,
|
||||
}
|
||||
input: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
Object(o.f)(42);
|
||||
}
|
||||
expect: {
|
||||
var o = {
|
||||
f: function(a) {
|
||||
console.log(a ? this.p : "FAIL 1");
|
||||
},
|
||||
p: "FAIL 2",
|
||||
}, p = "PASS";
|
||||
(0, o.f)(42);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_value: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -617,7 +643,7 @@ issue_4730_2: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
!console.log("PASS") || a && a[a.p];
|
||||
console.log("PASS") && a && a[a.p];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
@@ -645,3 +671,56 @@ issue_4751: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
42 instanceof function() {};
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
drop_instanceof_reference: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
}
|
||||
input: {
|
||||
function f() {}
|
||||
42 instanceof f;
|
||||
console.log("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f() {}
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
retain_instanceof: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
try {
|
||||
42 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
try {
|
||||
0 instanceof "foo";
|
||||
} catch (e) {
|
||||
console.log("PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -1,3 +1,12 @@
|
||||
decimal: {
|
||||
input: {
|
||||
console.log({... 0.42});
|
||||
}
|
||||
expect_exact: "console.log({....42});"
|
||||
expect_stdout: "{}"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
collapse_vars_1: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
@@ -147,7 +156,7 @@ dont_inline: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
do_inline: {
|
||||
do_inline_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
spreads: true,
|
||||
@@ -164,6 +173,46 @@ do_inline: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
do_inline_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
(function() {
|
||||
console.log("PASS");
|
||||
})(..."");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
[] = [ ..."" ],
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
do_inline_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
(function() {
|
||||
while (console.log("PASS"));
|
||||
})(..."");
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var [] = [ ..."" ];
|
||||
while (console.log("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
drop_empty_call_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -201,7 +250,29 @@ drop_empty_call_2: {
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
convert_hole: {
|
||||
convert_hole_array: {
|
||||
options = {
|
||||
spreads: true,
|
||||
}
|
||||
input: {
|
||||
[ ...[ "PASS", , 42 ] ].forEach(function(a) {
|
||||
console.log(a);
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
[ "PASS", void 0, 42 ].forEach(function(a) {
|
||||
console.log(a);
|
||||
});
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"undefined",
|
||||
"42",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
convert_hole_call: {
|
||||
options = {
|
||||
spreads: true,
|
||||
}
|
||||
@@ -341,7 +412,7 @@ convert_setter: {
|
||||
console.log(k, o[k]);
|
||||
}
|
||||
expect_stdout: "PASS undefined"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_getter_1: {
|
||||
@@ -370,7 +441,7 @@ keep_getter_1: {
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_getter_2: {
|
||||
@@ -399,7 +470,7 @@ keep_getter_2: {
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_getter_3: {
|
||||
@@ -429,7 +500,7 @@ keep_getter_3: {
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_getter_4: {
|
||||
@@ -460,7 +531,7 @@ keep_getter_4: {
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
keep_accessor: {
|
||||
@@ -508,7 +579,7 @@ keep_accessor: {
|
||||
"q undefined",
|
||||
"r null",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
object_key_order_1: {
|
||||
@@ -538,7 +609,7 @@ object_key_order_1: {
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
node_version: ">=8 <=10"
|
||||
node_version: ">=8.3.0 <=10"
|
||||
}
|
||||
|
||||
object_key_order_2: {
|
||||
@@ -568,7 +639,7 @@ object_key_order_2: {
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
object_key_order_3: {
|
||||
@@ -598,7 +669,7 @@ object_key_order_3: {
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
object_key_order_4: {
|
||||
@@ -628,7 +699,7 @@ object_key_order_4: {
|
||||
"a 3",
|
||||
"b 2",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
object_spread_array: {
|
||||
@@ -654,7 +725,7 @@ object_spread_array: {
|
||||
"0 foo",
|
||||
"1 bar",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
object_spread_string: {
|
||||
@@ -681,7 +752,7 @@ object_spread_string: {
|
||||
"1 o",
|
||||
"2 o",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
unused_var_side_effects: {
|
||||
@@ -711,7 +782,7 @@ unused_var_side_effects: {
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
unsafe_join_1: {
|
||||
@@ -793,7 +864,7 @@ issue_4329: {
|
||||
}[0]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4331: {
|
||||
@@ -871,7 +942,7 @@ issue_4345: {
|
||||
}[42]);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4361: {
|
||||
@@ -901,7 +972,7 @@ issue_4361: {
|
||||
"foo",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4363: {
|
||||
@@ -922,7 +993,7 @@ issue_4363: {
|
||||
});
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4556: {
|
||||
@@ -994,7 +1065,7 @@ issue_4849: {
|
||||
}()));
|
||||
}
|
||||
expect_stdout: "object"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4882_1: {
|
||||
@@ -1026,7 +1097,7 @@ issue_4882_1: {
|
||||
"PASS",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4882_2: {
|
||||
@@ -1052,7 +1123,7 @@ issue_4882_2: {
|
||||
"42",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_4882_3: {
|
||||
@@ -1082,7 +1153,7 @@ issue_4882_3: {
|
||||
"PASS",
|
||||
"42",
|
||||
]
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5006: {
|
||||
@@ -1104,3 +1175,81 @@ issue_5006: {
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5382: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
({
|
||||
f() {
|
||||
({ ...this });
|
||||
},
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
}).f();
|
||||
}
|
||||
expect: {
|
||||
({
|
||||
f() {
|
||||
({ ...this });
|
||||
},
|
||||
get p() {
|
||||
console.log("PASS");
|
||||
},
|
||||
}).f();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=8.3.0"
|
||||
}
|
||||
|
||||
issue_5602: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
conditionals: true,
|
||||
evaluate: true,
|
||||
if_return: true,
|
||||
inline: true,
|
||||
passes: 2,
|
||||
sequences: true,
|
||||
spreads: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
(function() {
|
||||
try {
|
||||
var b = function(c) {
|
||||
if (c)
|
||||
return FAIL;
|
||||
var d = 42;
|
||||
}(...[ null, A = 0 ]);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})();
|
||||
console.log(A);
|
||||
}
|
||||
expect: {
|
||||
(function() {
|
||||
try {
|
||||
var b = void (A = 0);
|
||||
} catch (e) {
|
||||
b();
|
||||
}
|
||||
})(),
|
||||
console.log(A);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
expect_warnings: [
|
||||
"INFO: Dropping unused variable d [test/compress/spreads.js:6,24]",
|
||||
"INFO: Collapsing c [test/compress/spreads.js:4,24]",
|
||||
"INFO: Dropping unused variable c [test/compress/spreads.js:3,33]",
|
||||
"INFO: pass 0: last_count: Infinity, count: 27",
|
||||
"WARN: Condition always false [test/compress/spreads.js:4,20]",
|
||||
"INFO: Collapsing null [test/compress/spreads.js:7,23]",
|
||||
"INFO: Collapsing 0 [test/compress/spreads.js:3,24]",
|
||||
"INFO: pass 1: last_count: 27, count: 22",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -1608,3 +1608,83 @@ issue_5012: {
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_1: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (false) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_5543_2: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
switches: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
switch (a) {
|
||||
default:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("PASS"):
|
||||
}
|
||||
break;
|
||||
case null:
|
||||
switch (42) {
|
||||
case a:
|
||||
case console.log("FAIL"):
|
||||
}
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
@@ -131,6 +131,105 @@ malformed_escape: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
booleans: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log(`$${a}${a}` ? "PASS" : "FAIL");
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("$" + a + a ? "PASS" : "FAIL");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escape_placeholder_1: {
|
||||
options = {
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`\${\n`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`\${
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"${",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escape_placeholder_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`\n${"${"}\n`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`
|
||||
\${
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"${",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escape_placeholder_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`\n$${"{"}\n`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`
|
||||
\${
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"${",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escape_placeholder_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`\n${"$"}${"{"}\n`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`
|
||||
\${
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"",
|
||||
"${",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
evaluate: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
@@ -174,7 +273,7 @@ partial_evaluate: {
|
||||
console.log(`${6 * 7} foo ${console ? `PA` + "SS" : `FA` + `IL`}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`42 foo ${console ? "PASS" : "FAIL"}`);
|
||||
console.log("42 foo " + (console ? "PASS" : "FAIL"));
|
||||
}
|
||||
expect_stdout: "42 foo PASS"
|
||||
node_version: ">=4"
|
||||
@@ -204,7 +303,7 @@ malformed_evaluate_2: {
|
||||
console.log(`\u0${0}b${5}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`\u0${0}b5`);
|
||||
console.log(`\u00b` + 5);
|
||||
}
|
||||
expect_stdout: true
|
||||
node_version: ">=4"
|
||||
@@ -238,7 +337,7 @@ malformed_evaluate_4: {
|
||||
console.log("\\u00b5");
|
||||
}
|
||||
expect_stdout: "\\u00b5"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.10.0"
|
||||
}
|
||||
|
||||
unsafe_evaluate: {
|
||||
@@ -254,7 +353,7 @@ unsafe_evaluate: {
|
||||
console.log("\\uFo");
|
||||
}
|
||||
expect_stdout: "\\uFo"
|
||||
node_version: ">=8"
|
||||
node_version: ">=8.10.0"
|
||||
}
|
||||
|
||||
side_effects_1: {
|
||||
@@ -357,13 +456,14 @@ issue_4604: {
|
||||
issue_4606: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`${typeof A} ${"\r"} ${"\\"} ${"`"}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`${typeof A} \r \\ \``);
|
||||
console.log(typeof A + " \r \\ `");
|
||||
}
|
||||
expect_stdout: "undefined \r \\ `"
|
||||
node_version: ">=4"
|
||||
@@ -434,3 +534,238 @@ issue_4931: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`PASS ${typeof A}`);
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS " + typeof A);
|
||||
}
|
||||
expect_stdout: "PASS undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`PASS
|
||||
${typeof A}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`PASS
|
||||
` + typeof A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_3: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`PASS\n${typeof A}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`PASS
|
||||
` + typeof A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_4: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`PASS
|
||||
|
||||
${typeof A}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`PASS
|
||||
|
||||
` + typeof A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_5: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`PASS\n\n${typeof A}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`PASS
|
||||
|
||||
` + typeof A);
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_6: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`${typeof A} ${typeof B} PASS`);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof A + ` ${typeof B} PASS`);
|
||||
}
|
||||
expect_stdout: "undefined undefined PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_7: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`${typeof A} ${typeof B} ${typeof C} PASS`);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof A + ` ${typeof B} ${typeof C} PASS`);
|
||||
}
|
||||
expect_stdout: "undefined undefined undefined PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5125_8: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`${typeof A}${typeof B}${typeof C} PASS`);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof A + typeof B + typeof C + " PASS");
|
||||
}
|
||||
expect_stdout: "undefinedundefinedundefined PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5136: {
|
||||
options = {
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
console.log(`${A = []}${A[0] = 42}`);
|
||||
}
|
||||
expect: {
|
||||
console.log(`` + (A = []) + (A[0] = 42));
|
||||
}
|
||||
expect_stdout: "42"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5145_1: {
|
||||
options = {
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
var a = [];
|
||||
console.log(`${a}${a[0] = 42}
|
||||
`);
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
console.log(`${a}${a[0] = 42}
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5145_2: {
|
||||
options = {
|
||||
strings: true,
|
||||
templates: true,
|
||||
}
|
||||
input: {
|
||||
var a = [];
|
||||
console.log(`${a}${a}${a[0] = 42}
|
||||
`);
|
||||
}
|
||||
expect: {
|
||||
var a = [];
|
||||
console.log("" + a + a + (a[0] = 42) + `
|
||||
`);
|
||||
}
|
||||
expect_stdout: [
|
||||
"42",
|
||||
"",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5199: {
|
||||
options = {
|
||||
collapse_vars: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var a = function() {
|
||||
console.log(typeof b);
|
||||
}``;
|
||||
{
|
||||
const b = a;
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var a = function() {
|
||||
console.log(typeof b);
|
||||
}``;
|
||||
{
|
||||
const b = a;
|
||||
}
|
||||
}
|
||||
expect_stdout: "undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -127,7 +127,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ typeof_defined_1: {
|
||||
}
|
||||
expect: {
|
||||
"undefined" == typeof A && A;
|
||||
"undefined" != typeof A || A;
|
||||
"undefined" == typeof A && A;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,7 +324,7 @@ typeof_defined_2: {
|
||||
}
|
||||
expect: {
|
||||
"function" != typeof A && A;
|
||||
"function" == typeof A || A;
|
||||
"function" != typeof A && A;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,16 +355,19 @@ typeof_defined_3: {
|
||||
"undefined" == typeof A && "undefined" == typeof B && (A, B);
|
||||
"undefined" == typeof A && "undefined" != typeof B && A;
|
||||
"undefined" != typeof A && "undefined" == typeof B && B;
|
||||
// dropped
|
||||
"undefined" == typeof A && "undefined" == typeof B || (A, B);
|
||||
"undefined" == typeof A && "undefined" != typeof B || (A, B);
|
||||
"undefined" != typeof A && "undefined" == typeof B || (A, B);
|
||||
"undefined" != typeof A && "undefined" != typeof B || (A, B);
|
||||
"undefined" == typeof A || "undefined" == typeof B && B;
|
||||
"undefined" != typeof A || "undefined" == typeof B && (A, B);
|
||||
"undefined" != typeof A || "undefined" != typeof B && A;
|
||||
"undefined" == typeof A || "undefined" != typeof B || B;
|
||||
"undefined" != typeof A || "undefined" == typeof B || A;
|
||||
"undefined" != typeof A || "undefined" != typeof B || (A, B);
|
||||
"undefined" != typeof A && "undefined" == typeof B && B;
|
||||
// dropped
|
||||
"undefined" == typeof A && "undefined" == typeof B && (A, B);
|
||||
"undefined" == typeof A && "undefined" != typeof B && A;
|
||||
// dropped
|
||||
"undefined" != typeof A && "undefined" == typeof B && B;
|
||||
"undefined" == typeof A && "undefined" != typeof B && A;
|
||||
"undefined" == typeof A && "undefined" == typeof B && (A, B);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,6 +395,7 @@ typeof_defined_4: {
|
||||
"object" != typeof A || "object" != typeof B || (A, B);
|
||||
}
|
||||
expect: {
|
||||
// dropped
|
||||
"object" == typeof A && "object" != typeof B && B;
|
||||
"object" != typeof A && "object" == typeof B && A;
|
||||
"object" != typeof A && "object" != typeof B && (A, B);
|
||||
@@ -399,12 +403,14 @@ typeof_defined_4: {
|
||||
"object" == typeof A && "object" != typeof B || (A, B);
|
||||
"object" != typeof A && "object" == typeof B || (A, B);
|
||||
"object" != typeof A && "object" != typeof B || (A, B);
|
||||
"object" == typeof A || "object" == typeof B && A;
|
||||
"object" == typeof A || "object" != typeof B && (A, B);
|
||||
"object" != typeof A || "object" != typeof B && B;
|
||||
"object" == typeof A || "object" == typeof B || (A, B);
|
||||
"object" == typeof A || "object" != typeof B || A;
|
||||
"object" != typeof A || "object" == typeof B || B;
|
||||
"object" != typeof A && "object" == typeof B && A;
|
||||
"object" != typeof A && "object" != typeof B && (A, B);
|
||||
// dropped
|
||||
"object" == typeof A && "object" != typeof B && B;
|
||||
"object" != typeof A && "object" != typeof B && (A, B);
|
||||
"object" != typeof A && "object" == typeof B && A;
|
||||
"object" == typeof A && "object" != typeof B && B;
|
||||
// dropped
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,6 +442,245 @@ emberjs_global: {
|
||||
expect_stdout: Error("PASS")
|
||||
}
|
||||
|
||||
reassign: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A = void 0;
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A = void 0;
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_call: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
function f() {
|
||||
A = void 0;
|
||||
}
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
f();
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
function f() {
|
||||
A = void 0;
|
||||
}
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
f();
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_conditional: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A &&= void 0;
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A &&= void 0;
|
||||
while (console.log(void 0 === A ? "PASS" : "FAIL 2"));
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=15"
|
||||
}
|
||||
|
||||
reassign_do: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
if_return: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
(function() {
|
||||
if ("undefined" == typeof A)
|
||||
return;
|
||||
var a = A, i = 2;
|
||||
do {
|
||||
console.log(void 0 === A, void 0 === a);
|
||||
A = void 0;
|
||||
} while (--i);
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
(function() {
|
||||
if ("undefined" != typeof A) {
|
||||
var a = A, i = 2;
|
||||
do {
|
||||
console.log(void 0 === A, (a, false));
|
||||
A = void 0;
|
||||
} while (--i);
|
||||
}
|
||||
})();
|
||||
}
|
||||
expect_stdout: [
|
||||
"false false",
|
||||
"true false",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_for: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
if (A = console, "undefined" != typeof A)
|
||||
for (var a = A, i = 0; i < 2; i++)
|
||||
console.log(void 0 === A, void 0 === a),
|
||||
A = void 0;
|
||||
}
|
||||
expect: {
|
||||
if (A = console, "undefined" != typeof A)
|
||||
for (var a = A, i = 0; i < 2; i++)
|
||||
console.log(void 0 === A, (a, false)),
|
||||
A = void 0;
|
||||
}
|
||||
expect_stdout: [
|
||||
"false false",
|
||||
"true false",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_for_in: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
reduce_vars: true,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
(A = console) && "undefined" != typeof A && function(a) {
|
||||
for (var k in [ a = A, 42 ]) {
|
||||
console.log(void 0 === A, void 0 === a);
|
||||
A = void 0;
|
||||
}
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
(A = console) && "undefined" != typeof A && function(a) {
|
||||
for (var k in [ a = A, 42 ]) {
|
||||
console.log(void 0 === A, (a, false));
|
||||
A = void 0;
|
||||
}
|
||||
}();
|
||||
}
|
||||
expect_stdout: [
|
||||
"false false",
|
||||
"true false",
|
||||
]
|
||||
}
|
||||
|
||||
reassign_iife: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else (function() {
|
||||
A = void 0;
|
||||
})(console.log(void 0 === A ? "FAIL 2" : "PASS"));
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
"undefined" == typeof A ? console.log("FAIL 1") : function() {
|
||||
A = void 0;
|
||||
}(console.log((A, false) ? "FAIL 2" : "PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
reassign_property: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
conditionals: true,
|
||||
passes: 2,
|
||||
typeofs: true,
|
||||
}
|
||||
input: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A.p = void 0;
|
||||
console.log(void 0 === A ? "FAIL 2" : "PASS");
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
A = console;
|
||||
if ("undefined" == typeof A)
|
||||
console.log("FAIL 1");
|
||||
else {
|
||||
A.p = void 0;
|
||||
console.log((A, false) ? "FAIL 2" : "PASS");
|
||||
}
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
issue_3817: {
|
||||
options = {
|
||||
comparisons: true,
|
||||
|
||||
@@ -67,7 +67,8 @@ unicode_escaped_identifier_2: {
|
||||
}
|
||||
expect_exact: 'var a="foo";var \u{10000}="bar";console.log(a,\u{10000});'
|
||||
expect_stdout: "foo bar"
|
||||
node_version: ">=4"
|
||||
// non-BMP support is platform-dependent on Node.js v4
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
unicode_identifier_ascii_only: {
|
||||
@@ -200,7 +201,8 @@ surrogate_pair: {
|
||||
}
|
||||
expect_exact: 'var \ud87e\udc00={"\ud87e\udc01":"\udbc0\udc00"};\ud87e\udc00.\ud87e\udc02="\udbc0\udc01";console.log(typeof \ud87e\udc00,\ud87e\udc00.\ud87e\udc01,\ud87e\udc00["\ud87e\udc02"]);'
|
||||
expect_stdout: "object \udbc0\udc00 \udbc0\udc01"
|
||||
node_version: ">=4"
|
||||
// non-BMP support is platform-dependent on Node.js v4
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
surrogate_pair_ascii: {
|
||||
@@ -216,5 +218,6 @@ surrogate_pair_ascii: {
|
||||
}
|
||||
expect_exact: 'var \\u{2f800}={"\\ud87e\\udc01":"\\udbc0\\udc00"};\\u{2f800}.\\u{2f802}="\\udbc0\\udc01";console.log(typeof \\u{2f800},\\u{2f800}.\\u{2f801},\\u{2f800}["\\ud87e\\udc02"]);'
|
||||
expect_stdout: "object \udbc0\udc00 \udbc0\udc01"
|
||||
node_version: ">=4"
|
||||
// non-BMP support is platform-dependent on Node.js v4
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ reduce_merge_const: {
|
||||
console.log(b);
|
||||
}
|
||||
expect: {
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
b = typeof b;
|
||||
console.log(b);
|
||||
var a = console;
|
||||
console.log(typeof a);
|
||||
a = typeof a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
@@ -41,10 +41,10 @@ reduce_merge_let: {
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var b = console;
|
||||
console.log(typeof b);
|
||||
b = typeof b;
|
||||
console.log(b);
|
||||
var a = console;
|
||||
console.log(typeof a);
|
||||
a = typeof a;
|
||||
console.log(a);
|
||||
}
|
||||
expect_stdout: [
|
||||
"object",
|
||||
@@ -111,7 +111,7 @@ hoist_props_const: {
|
||||
}
|
||||
}
|
||||
expect: {
|
||||
var o_p = "PASS";
|
||||
var o, o_p = "PASS";
|
||||
console.log(o_p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -136,7 +136,7 @@ hoist_props_let: {
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var o_p = "PASS";
|
||||
var o, o_p = "PASS";
|
||||
console.log(o_p);
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
@@ -194,6 +194,43 @@ scope_adjustment_let: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
escaped_const: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
const log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
escaped_let: {
|
||||
options = {
|
||||
reduce_vars: true,
|
||||
toplevel: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
var log = console.log;
|
||||
log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4191_const: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -613,3 +650,35 @@ issue_4954: {
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5516: {
|
||||
options = {
|
||||
reduce_funcs: true,
|
||||
reduce_vars: true,
|
||||
unused: true,
|
||||
varify: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
let a;
|
||||
}
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
console.log(typeof function() {
|
||||
{
|
||||
const a = function() {};
|
||||
return a;
|
||||
}
|
||||
}());
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -107,3 +107,209 @@ function_name_mangle_ie8: {
|
||||
expect_exact: "(function(){console.log(typeof function n(o){})})();"
|
||||
expect_stdout: "function"
|
||||
}
|
||||
|
||||
issue_1753: {
|
||||
mangle = {
|
||||
toplevel: false,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_1753_toplevel: {
|
||||
mangle = {
|
||||
toplevel: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let i = 0; i < 1; i++)
|
||||
console.log(i);
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
let l = null;
|
||||
for (let e = 0; e < 1; e++)
|
||||
console.log(e);
|
||||
}
|
||||
expect_stdout: "0"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_await: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_await_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
async function f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS");
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=8"
|
||||
}
|
||||
|
||||
issue_5032_yield: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var a = log(a), c = a;
|
||||
log(a);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_yield_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5480: {
|
||||
mangle = {
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
"use strict";
|
||||
L: for (let a in console.log("PASS"));
|
||||
}
|
||||
expect: {
|
||||
"use strict";
|
||||
o: for (let o in console.log("PASS"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ pause_resume: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
arrow_yield: {
|
||||
arrow_yield_1: {
|
||||
input: {
|
||||
yield = "PASS";
|
||||
console.log(function*() {
|
||||
@@ -108,6 +108,18 @@ arrow_yield: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
arrow_yield_2: {
|
||||
input: {
|
||||
console.log(typeof function *() {
|
||||
// Syntax error on Node.js v6+
|
||||
return (yield) => {};
|
||||
}().next().value);
|
||||
}
|
||||
expect_exact: "console.log(typeof function*(){return(yield)=>{}}().next().value);"
|
||||
expect_stdout: "function"
|
||||
node_version: "4"
|
||||
}
|
||||
|
||||
for_of: {
|
||||
input: {
|
||||
function* f() {
|
||||
@@ -737,7 +749,7 @@ lift_sequence: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_nested_yield: {
|
||||
inline_nested: {
|
||||
options = {
|
||||
inline: true,
|
||||
sequences: true,
|
||||
@@ -772,6 +784,118 @@ inline_nested_yield: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
inline_nested_async: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo");
|
||||
var a = async function*() {
|
||||
console.log(await(yield* async function*() {
|
||||
yield {
|
||||
then: r => r("bar"),
|
||||
};
|
||||
return "baz";
|
||||
}()));
|
||||
}();
|
||||
console.log("moo");
|
||||
a.next().then(function f(b) {
|
||||
console.log(b.value);
|
||||
b.done || a.next().then(f);
|
||||
});
|
||||
console.log("moz");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo");
|
||||
var a = async function*() {
|
||||
console.log((yield {
|
||||
then: r => r("bar"),
|
||||
}, await "baz"));
|
||||
}();
|
||||
console.log("moo"),
|
||||
a.next().then(function f(b) {
|
||||
console.log(b.value),
|
||||
b.done || a.next().then(f);
|
||||
}),
|
||||
console.log("moz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"moo",
|
||||
"moz",
|
||||
"bar",
|
||||
"baz",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
inline_nested_block: {
|
||||
options = {
|
||||
if_return: true,
|
||||
inline: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a = function*() {
|
||||
yield* function*() {
|
||||
for (var a of [ "foo", "bar" ])
|
||||
yield a;
|
||||
return "FAIL";
|
||||
}();
|
||||
}(), b;
|
||||
do {
|
||||
b = a.next();
|
||||
console.log(b.value);
|
||||
} while (!b.done);
|
||||
}
|
||||
expect: {
|
||||
var a = function*() {
|
||||
for (var a of [ "foo", "bar" ])
|
||||
yield a;
|
||||
"FAIL";
|
||||
}(), b;
|
||||
do {
|
||||
b = a.next();
|
||||
console.log(b.value);
|
||||
} while (!b.done);
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"undefined",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
dont_inline_nested: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
var yield = "PASS";
|
||||
(function*() {
|
||||
(function() {
|
||||
console.log(yield);
|
||||
})();
|
||||
})().next();
|
||||
}
|
||||
expect: {
|
||||
var yield = "PASS";
|
||||
(function*() {
|
||||
(function() {
|
||||
console.log(yield);
|
||||
})();
|
||||
})().next();
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
drop_body: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -783,7 +907,7 @@ drop_body: {
|
||||
})([ console.log("baz") ]);
|
||||
}
|
||||
expect: {
|
||||
[ [ , [].e = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
[ [ , [][0] = console.log("foo") ] ] = [ [ console.log("baz") ] ];
|
||||
}
|
||||
expect_stdout: [
|
||||
"baz",
|
||||
@@ -810,6 +934,21 @@ drop_unused_call: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
instanceof_lambda: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
console.log(42 instanceof function*() {});
|
||||
}
|
||||
expect: {
|
||||
console.log(false);
|
||||
}
|
||||
expect_stdout: "false"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_4454_1: {
|
||||
rename = false
|
||||
options = {
|
||||
@@ -852,8 +991,8 @@ issue_4454_2: {
|
||||
f("PASS");
|
||||
}
|
||||
expect: {
|
||||
function f(b) {
|
||||
(function*(c = console.log(b)) {})();
|
||||
function f(a) {
|
||||
(function*(c = console.log(a)) {})();
|
||||
var b = 42..toString();
|
||||
console.log(b);
|
||||
}
|
||||
@@ -958,7 +1097,7 @@ issue_4639_1: {
|
||||
}().next().value());
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
node_version: ">=4 <7 || >=8.7.0"
|
||||
}
|
||||
|
||||
issue_4639_2: {
|
||||
@@ -1044,6 +1183,35 @@ issue_4641_2: {
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4641_3: {
|
||||
options = {
|
||||
if_return: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof async function*() {
|
||||
try {
|
||||
return void "FAIL";
|
||||
} finally {
|
||||
console.log("PASS");
|
||||
}
|
||||
}().next().then);
|
||||
}
|
||||
expect_stdout: [
|
||||
"function",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_4769_1: {
|
||||
options = {
|
||||
side_effects: true,
|
||||
@@ -1143,80 +1311,6 @@ issue_5019_2: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_normal: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: false,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(c) {
|
||||
var b = log(c), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5032_webkit: {
|
||||
options = {
|
||||
merge_vars: true,
|
||||
webkit: true,
|
||||
}
|
||||
input: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect: {
|
||||
function log(value) {
|
||||
console.log(value);
|
||||
return value;
|
||||
}
|
||||
function *f(a) {
|
||||
var b = log(a), c = b;
|
||||
log(b);
|
||||
log(c);
|
||||
}
|
||||
f("PASS").next();
|
||||
}
|
||||
expect_stdout: [
|
||||
"PASS",
|
||||
"PASS",
|
||||
"PASS",
|
||||
]
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5034: {
|
||||
options = {
|
||||
functions: true,
|
||||
@@ -1247,12 +1341,13 @@ issue_5034: {
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5076: {
|
||||
issue_5076_1: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
passes: 2,
|
||||
keep_fargs: false,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
@@ -1269,9 +1364,408 @@ issue_5076: {
|
||||
}
|
||||
expect: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
console.log("PASS"),
|
||||
a = 42["a"];
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5076_2: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
hoist_vars: true,
|
||||
keep_fargs: false,
|
||||
passes: 2,
|
||||
pure_getters: "strict",
|
||||
sequences: true,
|
||||
side_effects: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a;
|
||||
console.log("PASS");
|
||||
var b = function*({
|
||||
p: {},
|
||||
}) {}({
|
||||
p: { a } = 42,
|
||||
});
|
||||
}
|
||||
expect: {
|
||||
console.log("PASS");
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
issue_5177: {
|
||||
options = {
|
||||
properties: true,
|
||||
}
|
||||
input: {
|
||||
console.log(typeof function*() {
|
||||
return {
|
||||
p(yield) {},
|
||||
}.p;
|
||||
}().next().value);
|
||||
}
|
||||
expect: {
|
||||
console.log(typeof function*() {
|
||||
return {
|
||||
p(yield) {},
|
||||
}.p;
|
||||
}().next().value);
|
||||
}
|
||||
expect_stdout: "function"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5385_1: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
(function() {
|
||||
try {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
return console.log("bar");
|
||||
}
|
||||
console.log("baz");
|
||||
})();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
(function() {
|
||||
try {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
return console.log("bar");
|
||||
}
|
||||
console.log("baz");
|
||||
})();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_2: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
return console.log("foo");
|
||||
} finally {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_3: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return function() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
}();
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
throw console.log("foo");
|
||||
} catch (e) {
|
||||
return console.log("bar");
|
||||
}
|
||||
return void 0;
|
||||
})().next();
|
||||
console.log("moo");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5385_4: {
|
||||
options = {
|
||||
awaits: true,
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
return async function() {
|
||||
try {
|
||||
return {
|
||||
then(resolve) {
|
||||
resolve(console.log("FAIL"));
|
||||
},
|
||||
};
|
||||
} finally {
|
||||
return "PASS";
|
||||
}
|
||||
}();
|
||||
})().next().then(o => console.log(o.value, o.done));
|
||||
}
|
||||
expect_stdout: "PASS true"
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5425: {
|
||||
options = {
|
||||
assignments: true,
|
||||
ie: true,
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
yields: true,
|
||||
}
|
||||
input: {
|
||||
var a = "FAIL";
|
||||
var b = function* f() {}(a ? a = "PASS" : 42);
|
||||
console.log(a, typeof f);
|
||||
}
|
||||
expect: {
|
||||
var a = "FAIL";
|
||||
(function* f() {})(a && (a = "PASS"));
|
||||
console.log(a, typeof f);
|
||||
}
|
||||
expect_stdout: "PASS undefined"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5456: {
|
||||
options = {
|
||||
inline: true,
|
||||
merge_vars: true,
|
||||
}
|
||||
input: {
|
||||
var a = true;
|
||||
(function() {
|
||||
(function(b, c) {
|
||||
var d = function*() {
|
||||
c = null;
|
||||
}();
|
||||
var e = function() {
|
||||
if (c)
|
||||
console.log(typeof d);
|
||||
while (b);
|
||||
}();
|
||||
})(function(i) {
|
||||
return console.log("foo") && i;
|
||||
}(a));
|
||||
})();
|
||||
}
|
||||
expect: {
|
||||
var a = true;
|
||||
(function() {
|
||||
b = (i = a, console.log("foo") && i),
|
||||
d = function*() {
|
||||
c = null;
|
||||
}(),
|
||||
e = function() {
|
||||
if (c) console.log(typeof d);
|
||||
while (b);
|
||||
}(),
|
||||
void 0;
|
||||
var b, c, d, e;
|
||||
var i;
|
||||
})();
|
||||
}
|
||||
expect_stdout: "foo"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5506: {
|
||||
options = {
|
||||
dead_code: true,
|
||||
}
|
||||
input: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect: {
|
||||
console.log(function(a) {
|
||||
var b = function*() {
|
||||
a = null in (a = "PASS");
|
||||
}();
|
||||
try {
|
||||
b.next();
|
||||
} catch (e) {
|
||||
return a;
|
||||
}
|
||||
}("FAIL"));
|
||||
}
|
||||
expect_stdout: "PASS"
|
||||
node_version: ">=4"
|
||||
}
|
||||
|
||||
issue_5526: {
|
||||
options = {
|
||||
inline: true,
|
||||
side_effects: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
return function() {
|
||||
while (console.log("foo"));
|
||||
}();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
return void 0;
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"baz",
|
||||
"bar",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5576: {
|
||||
options = {
|
||||
inline: true,
|
||||
}
|
||||
input: {
|
||||
(async function*() {
|
||||
try {
|
||||
(function() {
|
||||
while (console.log("foo"));
|
||||
})();
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect: {
|
||||
(async function*() {
|
||||
try {
|
||||
while (console.log("foo"));
|
||||
} finally {
|
||||
console.log("bar");
|
||||
}
|
||||
})().next();
|
||||
console.log("baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
]
|
||||
node_version: ">=10"
|
||||
}
|
||||
|
||||
issue_5663: {
|
||||
options = {
|
||||
toplevel: true,
|
||||
unused: true,
|
||||
}
|
||||
input: {
|
||||
var [ , a ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect: {
|
||||
var [ , , ] = function*() {
|
||||
console.log("foo");
|
||||
yield console.log("bar");
|
||||
console.log("baz");
|
||||
yield console.log("moo");
|
||||
console.log("moz");
|
||||
yield FAIL;
|
||||
}();
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
"baz",
|
||||
"moo",
|
||||
]
|
||||
node_version: ">=6"
|
||||
}
|
||||
|
||||
@@ -38,4 +38,4 @@ var _require = require("bar"), foo = _require.foo;
|
||||
var _require2 = require("world"), hello = _require2.hello;
|
||||
|
||||
foo.x.apply(foo, _toConsumableArray(foo.y(hello.z)));
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxRQUFmQyxNLFNBQUFBOztBLGdCQUNTRCxRQUFRLFVBQWpCRSxRLFVBQUFBOztBQUVQRCxJQUFJRSxFQUFKQyxNQUFBSCxLQUFHSSxtQkFBTUosSUFBSUssRUFBRUosTUFBTUsifQ==
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImNvbnN0IHtmb299ID0gcmVxdWlyZShcImJhclwiKTtcbmNvbnN0IHtoZWxsb30gPSByZXF1aXJlKFwid29ybGRcIik7XG5cbmZvby54KC4uLmZvby55KGhlbGxvLnopKTtcbiJdLCJuYW1lcyI6WyJyZXF1aXJlIiwiZm9vIiwiaGVsbG8iLCJ4IiwiYXBwbHkiLCJfdG9Db25zdW1hYmxlQXJyYXkiLCJ5IiwieiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7ZUFBY0EsUUFBUSxLQUFELEdBQWRDLE0sU0FBQUE7O0EsZ0JBQ1NELFFBQVEsT0FBRCxHQUFoQkUsUSxVQUFBQTs7QUFFUEQsSUFBSUUsRUFBSkMsTUFBQUgsS0FBR0ksbUJBQU1KLElBQUlLLEVBQUVKLE1BQU1LLENBQVosQ0FBTixDQUFBIn0=
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
function test(a){
|
||||
"aaaaaaaaaaaaaaaa"
|
||||
;a(err,data),a(err,
|
||||
"aaaaaaaaaaaaaaaa";
|
||||
a(err,data),a(err,
|
||||
data)}
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsS0FBS0M7O0NBRVZBLEVBQVNDLElBQUtDLE1BQ2RGLEVBQVNDO0FBQUtDIn0=
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIjAiXSwibmFtZXMiOlsidGVzdCIsImNhbGxiYWNrIiwiZXJyIiwiZGF0YSJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0E7SEFBS0MsR0FDVjtBQUNBQTtoQkFBU0MsSUFBS0MsSUFBSSxFQUNsQkYsRUFBU0MsSUFBS0MsSUFBSSxDQUN0QiJ9
|
||||
@@ -1,2 +1,2 @@
|
||||
console.log(3);
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSJ9
|
||||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIl0sInNvdXJjZXNDb250ZW50IjpbImNsYXNzIEZvbyB7IGNvbnN0cnVjdG9yKCl7Y29uc29sZS5sb2coMSsyKTt9IH0gbmV3IEZvbygpO1xuIl0sIm5hbWVzIjpbImNvbnNvbGUiLCJsb2ciXSwibWFwcGluZ3MiOiJBQUEwQkEsUUFBUUMsSUFBSSxDQUFHIn0=
|
||||
|
||||
1
test/input/module/expect.js
Normal file
1
test/input/module/expect.js
Normal file
@@ -0,0 +1 @@
|
||||
function n(){return this||arguments[0]+arguments[1]}function o(){return this||arguments[0]+arguments[1]}console.log(n(n(1,3),5)),console.log(o(o(2,4),6));
|
||||
13
test/input/module/input.js
Normal file
13
test/input/module/input.js
Normal file
@@ -0,0 +1,13 @@
|
||||
console.log(function() {
|
||||
function sum(...params) {
|
||||
return this || arguments[0] + arguments[1];
|
||||
}
|
||||
return sum(sum(1, 3), 5);
|
||||
}());
|
||||
console.log(function() {
|
||||
"use strict";
|
||||
function sum(...params) {
|
||||
return this || arguments[0] + arguments[1];
|
||||
}
|
||||
return sum(sum(2, 4), 6);
|
||||
}());
|
||||
@@ -1,7 +1,5 @@
|
||||
// (beautified)
|
||||
console.log(function() {
|
||||
return 1 + .1 + .1;
|
||||
}());
|
||||
console.log(1 + .1 + .1);
|
||||
// output: 1.2000000000000002
|
||||
//
|
||||
// minify: 1.2
|
||||
|
||||
17
test/input/reduce/export_default.js
Normal file
17
test/input/reduce/export_default.js
Normal file
@@ -0,0 +1,17 @@
|
||||
var unused;
|
||||
export default class {
|
||||
____11111() {
|
||||
a, b, c, d, e;
|
||||
f, g, h, i, j;
|
||||
k, l, m, n, o;
|
||||
p, q, r, s, t;
|
||||
u, v, w, x, y, z;
|
||||
A, B, C, D, E;
|
||||
F, G, H, I, J;
|
||||
K, L, M, N, O;
|
||||
P, Q, R, S, T;
|
||||
U, V, W, X, Y, Z;
|
||||
$, _;
|
||||
unused;
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ if (typeof phantom == "undefined") {
|
||||
var cmd = process.platform == "win32" ? "npm.cmd" : "npm";
|
||||
|
||||
function npm(args, done) {
|
||||
args.push("--loglevel=error");
|
||||
child_process.spawn(cmd, args, { stdio: [ "ignore", 1, 2 ] }).on("exit", done);
|
||||
}
|
||||
|
||||
@@ -69,11 +70,15 @@ if (typeof phantom == "undefined") {
|
||||
npm([
|
||||
"install",
|
||||
"graceful-fs@4.2.6",
|
||||
"is-my-json-valid@2.20.5",
|
||||
"phantomjs-prebuilt@2.1.14",
|
||||
"--no-audit",
|
||||
"--no-fund",
|
||||
"--no-optional",
|
||||
"--no-save",
|
||||
"--no-strict-ssl",
|
||||
"--no-update-notifier",
|
||||
"--production",
|
||||
], function(code) {
|
||||
if (code) {
|
||||
console.log("npm install failed with code", code);
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
var fs = require("fs");
|
||||
|
||||
var config = {
|
||||
limit: 10000,
|
||||
timeout: function(limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
this.limit = limit + lag;
|
||||
},
|
||||
};
|
||||
var lag = +process.env["UGLIFY_GITHUB_LAG"] || 0;
|
||||
var tasks = [];
|
||||
var titles = [];
|
||||
config.timeout(10000);
|
||||
describe = function(title, fn) {
|
||||
config = Object.create(config);
|
||||
titles.push(title);
|
||||
@@ -21,10 +22,11 @@ it = function(title, fn) {
|
||||
fn.titles.push(title);
|
||||
tasks.push(fn);
|
||||
};
|
||||
|
||||
fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
}).forEach(function(file) {
|
||||
(function(arg) {
|
||||
return arg ? [ arg ] : fs.readdirSync("test/mocha").filter(function(file) {
|
||||
return /\.js$/.test(file);
|
||||
});
|
||||
})(process.argv[2]).forEach(function(file) {
|
||||
require("./mocha/" + file);
|
||||
});
|
||||
|
||||
@@ -66,12 +68,13 @@ process.nextTick(function run() {
|
||||
if (task.length) {
|
||||
task.timeout = function(limit) {
|
||||
clearTimeout(timer);
|
||||
limit += lag;
|
||||
task.limit = limit;
|
||||
timer = setTimeout(function() {
|
||||
raise(new Error("Timed out: exceeds " + limit + "ms"));
|
||||
}, limit);
|
||||
};
|
||||
task.timeout(task.limit);
|
||||
task.timeout(task.limit - lag);
|
||||
process.on("uncaughtException", raise);
|
||||
task.call(task, done);
|
||||
} else {
|
||||
|
||||
@@ -7,7 +7,7 @@ describe("async", function() {
|
||||
"function await() {}",
|
||||
"function(await) {}",
|
||||
"function() { await; }",
|
||||
"function() { await:{} }",
|
||||
"function() { await: {} }",
|
||||
"function() { var await; }",
|
||||
"function() { function await() {} }",
|
||||
"function() { try {} catch (await) {} }",
|
||||
|
||||
@@ -2,6 +2,7 @@ var assert = require("assert");
|
||||
var exec = require("child_process").exec;
|
||||
var fs = require("fs");
|
||||
var run_code = require("../sandbox").run_code;
|
||||
var semver = require("semver");
|
||||
var to_ascii = require("../node").to_ascii;
|
||||
|
||||
function read(path) {
|
||||
@@ -12,10 +13,13 @@ describe("bin/uglifyjs", function() {
|
||||
var uglifyjscmd = '"' + process.argv[0] + '" bin/uglifyjs';
|
||||
it("Should produce a functional build when using --self", function(done) {
|
||||
this.timeout(30000);
|
||||
var command = uglifyjscmd + ' --self -cm --wrap WrappedUglifyJS';
|
||||
exec(command, {
|
||||
maxBuffer: 1048576
|
||||
}, function(err, stdout) {
|
||||
var command = [
|
||||
uglifyjscmd,
|
||||
"--self",
|
||||
semver.satisfies(process.version, "<=0.12") ? "-mc hoist_funs" : "-mc",
|
||||
"--wrap WrappedUglifyJS",
|
||||
].join(" ");
|
||||
exec(command, { maxBuffer: 1048576 }, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
eval(stdout);
|
||||
assert.strictEqual(typeof WrappedUglifyJS, "object");
|
||||
@@ -49,6 +53,23 @@ describe("bin/uglifyjs", function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --expression", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
"--expression",
|
||||
"--compress",
|
||||
"--mangle",
|
||||
].join(" "), function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function(n){for(;n(););return 42}(A)\n");
|
||||
done();
|
||||
}).stdin.end([
|
||||
"function(x) {",
|
||||
" while (x()) {}",
|
||||
" return 42;",
|
||||
"}(A)",
|
||||
].join("\n"));
|
||||
});
|
||||
it("Should work with --source-map names=true", function(done) {
|
||||
exec([
|
||||
uglifyjscmd,
|
||||
@@ -65,7 +86,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, [ "obj", "p", "a", "q", "b" ]);
|
||||
@@ -93,7 +114,7 @@ describe("bin/uglifyjs", function() {
|
||||
" q: b",
|
||||
"};",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,",
|
||||
].join("\n")
|
||||
].join("\n");
|
||||
assert.strictEqual(stdout.slice(0, expected.length), expected);
|
||||
var map = JSON.parse(to_ascii(stdout.slice(expected.length).trim()));
|
||||
assert.deepEqual(map.names, []);
|
||||
@@ -122,7 +143,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -184,6 +205,30 @@ describe("bin/uglifyjs", function() {
|
||||
child.stdin.end(read("test/input/issue-3040/input.js"));
|
||||
}, 1000);
|
||||
});
|
||||
it("Should work with --keep-fargs (mangle only)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fargs (mangle & compress)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fargs -m -c';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){return x(function(a){return a*a})}}function g(op){return op(1)+op(2)}console.log(5==f(g)());\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with keep_fargs under mangler options", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js -m keep_fargs=true';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(x){return function(){function n(a){return a*a}return x(n)}}function g(op){return op(1)+op(2)}console.log(f(g)()==5);\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle only)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m';
|
||||
exec(command, function(err, stdout) {
|
||||
@@ -193,10 +238,10 @@ describe("bin/uglifyjs", function() {
|
||||
});
|
||||
});
|
||||
it("Should work with --keep-fnames (mangle & compress)", function(done) {
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c unused=false';
|
||||
var command = uglifyjscmd + ' test/input/issue-1431/sample.js --keep-fnames -m -c';
|
||||
exec(command, function(err, stdout) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, "function f(r){return function(){function n(n){return n*n}return r(n)}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
||||
assert.strictEqual(stdout, "function f(n){return function(){return n(function n(r){return r*r})}}function g(n){return n(1)+n(2)}console.log(5==f(g)());\n");
|
||||
done();
|
||||
});
|
||||
});
|
||||
@@ -285,7 +330,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxJQUdYLE9BQU9DLElBTEQifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMTMyMy9zYW1wbGUuanMiXSwibmFtZXMiOlsiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFJQSxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -305,7 +350,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
"var Foo=function Foo(){console.log(1+2)};new Foo;var bar=function(){function foo(bar){return bar}return foo}();",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxJQUFPLElBQUlGLElDQW5ELElBQUlHLElBQU0sV0FDTixTQUFTQyxJQUFLRCxLQUNWLE9BQU9BLElBR1gsT0FBT0MsSUFMRCJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0ZGluIiwidGVzdC9pbnB1dC9pc3N1ZS0xMzIzL3NhbXBsZS5qcyJdLCJuYW1lcyI6WyJGb28iLCJjb25zb2xlIiwibG9nIiwiYmFyIiwiZm9vIl0sIm1hcHBpbmdzIjoiQUFBQSxJQUFNQSxJQUFJLFNBQUVBLE1BQWNDLFFBQVFDLElBQUksRUFBRSxDQUFDLENBQUUsRUFBSSxJQUFJRixJQ0FuRCxJQUFJRyxJQUFNLFdBQ04sU0FBU0MsSUFBS0QsS0FDVixPQUFPQSxHQUNYLENBRUEsT0FBT0MsR0FDVixFQUFFIn0=",
|
||||
"",
|
||||
].join("\n"));
|
||||
var stderrLines = stderr.split("\n");
|
||||
@@ -746,7 +791,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'"use strict";var foo=function foo(x){return"foo "+x};console.log(foo("bar"));',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxHQUN4QkMsUUFBUUMsSUFBSUgsSUFBSSJ9",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluZGV4LmpzIl0sIm5hbWVzIjpbImZvbyIsIngiLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiYUFBQSxJQUFJQSxJQUFNLFNBQU5BLElBQU1DLEdBQUEsTUFBSyxPQUFTQSxDQUFkLEVBQ1ZDLFFBQVFDLElBQUlILElBQUksS0FBSixDQUFaIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -769,7 +814,7 @@ describe("bin/uglifyjs", function() {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, [
|
||||
'function foo(){return function(){console.log("PASS")}}foo()();',
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIiwiZiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsTUFDTCxPQUFPLFdBQ0hDLFFBQVFDLElBQUksU0FLUkYsS0FDUkcifQ==",
|
||||
"//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QvaW5wdXQvaXNzdWUtMjMxMC9pbnB1dC5qcyJdLCJuYW1lcyI6WyJmb28iLCJjb25zb2xlIiwibG9nIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxNQUNMLE9BQU8sV0FDSEMsUUFBUUMsSUFBSSxNQUFNLENBQ3RCLENBQ0osQ0FHWUYsSUFBSSxFQUNWIn0=",
|
||||
""
|
||||
].join("\n"));
|
||||
done();
|
||||
@@ -900,6 +945,14 @@ describe("bin/uglifyjs", function() {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should work with --module", function(done) {
|
||||
var command = uglifyjscmd + " test/input/module/input.js --module -mc";
|
||||
exec(command, function(err, stdout, stderr) {
|
||||
if (err) throw err;
|
||||
assert.strictEqual(stdout, read("test/input/module/expect.js"));
|
||||
done();
|
||||
});
|
||||
});
|
||||
it("Should compress swarm of unused variables with reasonable performance", function(done) {
|
||||
var code = [
|
||||
"console.log(function() {",
|
||||
|
||||
@@ -191,7 +191,7 @@ describe("comments", function() {
|
||||
});
|
||||
|
||||
it("Should correctly preserve new lines around comments", function() {
|
||||
var tests = [
|
||||
[
|
||||
[
|
||||
"// foo",
|
||||
"// bar",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
var acorn = require("acorn");
|
||||
var assert = require("assert");
|
||||
var UglifyJS = require("../node");
|
||||
|
||||
@@ -25,6 +26,7 @@ describe("export", function() {
|
||||
"export { * };",
|
||||
"export { * as A };",
|
||||
"export { 42 as A };",
|
||||
"export { 'A' as B };",
|
||||
"export { A as B-C };",
|
||||
"export { default as A };",
|
||||
].forEach(function(code) {
|
||||
@@ -51,8 +53,11 @@ describe("export", function() {
|
||||
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||
[
|
||||
"export from 'path';",
|
||||
"export A from 'path';",
|
||||
"export * from `path`;",
|
||||
"export 'A' from 'path';",
|
||||
"export A as B from 'path';",
|
||||
"export 'A' as B from 'path';",
|
||||
"export default from 'path';",
|
||||
"export { A }, B from 'path';",
|
||||
"export * as A, B from 'path';",
|
||||
@@ -68,4 +73,109 @@ describe("export", function() {
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should reject `export` statement not under top-level scope", function() {
|
||||
[
|
||||
"{ export {}; }",
|
||||
"if (0) export var A;",
|
||||
"function f() { export default 42; }",
|
||||
].forEach(function(code) {
|
||||
assert.throws(function() {
|
||||
UglifyJS.parse(code);
|
||||
}, function(e) {
|
||||
return e instanceof UglifyJS.JS_Parse_Error;
|
||||
}, code);
|
||||
});
|
||||
});
|
||||
it("Should compare `export` statements correctly", function() {
|
||||
var stats = {
|
||||
Declaration: [
|
||||
"export let A;",
|
||||
"export const A = 42;",
|
||||
"export var { A, B: [] } = C;",
|
||||
"export function A() { return B(A); }",
|
||||
"export async function* A({}, ...[]) { return B(A); }",
|
||||
],
|
||||
Default: [
|
||||
"export default 42;",
|
||||
"export default A => A(B);",
|
||||
"export default class A extends B {}",
|
||||
"export default (class A extends B {});",
|
||||
"export default class A { static C = 42; }",
|
||||
"export default class A extends B { static C = 42; }",
|
||||
],
|
||||
Foreign: [
|
||||
"export * from 'path';",
|
||||
"export {} from 'path';",
|
||||
"export * as A from 'path';",
|
||||
"export { default } from 'path';",
|
||||
"export { A, B as C } from 'path';",
|
||||
"export { A, default as C } from 'path';",
|
||||
],
|
||||
References: [
|
||||
"export {};",
|
||||
"export { A };",
|
||||
"export { A as B };",
|
||||
"export { A, B as C };",
|
||||
"export { A as default };",
|
||||
],
|
||||
};
|
||||
for (var k in stats) stats[k].forEach(function(c, i) {
|
||||
var s = UglifyJS.parse(c);
|
||||
assert.ok(s instanceof UglifyJS.AST_Toplevel, c);
|
||||
assert.strictEqual(s.body.length, 1, c);
|
||||
assert.strictEqual(s.body[0].TYPE, "Export" + k, c);
|
||||
for (var l in stats) stats[l].forEach(function(d, j) {
|
||||
var t = UglifyJS.parse(d);
|
||||
assert.ok(t instanceof UglifyJS.AST_Toplevel, d);
|
||||
assert.strictEqual(t.body.length, 1, d);
|
||||
assert.strictEqual(t.body[0].TYPE, "Export" + l, d);
|
||||
assert.strictEqual(s.equals(t), k === l && i === j, c + "\n" + d);
|
||||
});
|
||||
});
|
||||
});
|
||||
it("Should interoperate with ESTree correctly", function() {
|
||||
[
|
||||
"export var A = 42;",
|
||||
"export default (class A {});",
|
||||
"var A; export { A as '42' };",
|
||||
"export { '42' } from 'path';",
|
||||
"export * as '42' from 'path';",
|
||||
].forEach(function(code) {
|
||||
var ast = UglifyJS.parse(code);
|
||||
try {
|
||||
var spidermonkey = ast.to_mozilla_ast();
|
||||
} catch (ex) {
|
||||
assert.fail("[to_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast2 = UglifyJS.AST_Node.from_mozilla_ast(spidermonkey);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_mozilla_ast] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast2.print_to_string(), ast.print_to_string(), [
|
||||
"spidermonkey:",
|
||||
ast.print_to_string(),
|
||||
ast2.print_to_string(),
|
||||
].join("\n"));
|
||||
try {
|
||||
var acorn_est = acorn.parse(code, {
|
||||
ecmaVersion: "latest",
|
||||
locations: true,
|
||||
sourceType: "module",
|
||||
});
|
||||
} catch (ex) {
|
||||
assert.fail("[acorn.parse] " + ex.stack);
|
||||
}
|
||||
try {
|
||||
var ast3 = UglifyJS.AST_Node.from_mozilla_ast(acorn_est);
|
||||
} catch (ex) {
|
||||
assert.fail("[from_acorn] " + ex.stack);
|
||||
}
|
||||
assert.strictEqual(ast3.print_to_string(), ast.print_to_string(), [
|
||||
"acorn:",
|
||||
ast.print_to_string(),
|
||||
ast3.print_to_string(),
|
||||
].join("\n"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user