Compare commits
195 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b8570f16c | ||
|
|
bb225367cb | ||
|
|
bbca9de9cd | ||
|
|
ee9ceb79ca | ||
|
|
ac1f7d689b | ||
|
|
19d232badb | ||
|
|
d464be3f3f | ||
|
|
3094eaaa89 | ||
|
|
ce3c35fa8b | ||
|
|
5d9224deb8 | ||
|
|
45b6d23d36 | ||
|
|
f0de9a8b5d | ||
|
|
203f4b7ad9 | ||
|
|
4114431eec | ||
|
|
fb03561799 | ||
|
|
6ab26eef6c | ||
|
|
53b57ee57e | ||
|
|
16411dcb87 | ||
|
|
8bbfaacdae | ||
|
|
df980db4a8 | ||
|
|
8e4a19ffec | ||
|
|
d833e66d23 | ||
|
|
8aa650bcf9 | ||
|
|
d576495e5a | ||
|
|
a06e20304b | ||
|
|
4cccc01f3e | ||
|
|
97bd56b7e8 | ||
|
|
acf951a5bc | ||
|
|
324587f769 | ||
|
|
80efaa2f33 | ||
|
|
a1a212f639 | ||
|
|
a2b1b96752 | ||
|
|
c296a63fb3 | ||
|
|
10dd9d4eaf | ||
|
|
9b8deff64d | ||
|
|
f46209b7e5 | ||
|
|
bddb5a0102 | ||
|
|
3c161a6662 | ||
|
|
c58e174647 | ||
|
|
c53af3dfb1 | ||
|
|
f1f4a4dd82 | ||
|
|
ca49f6f41a | ||
|
|
8a82822654 | ||
|
|
ebe4e1ad28 | ||
|
|
a37ca558dd | ||
|
|
73a564343b | ||
|
|
4870747306 | ||
|
|
b179a2459f | ||
|
|
231c3d7c84 | ||
|
|
aed758ed5c | ||
|
|
0df028187d | ||
|
|
10fbf8e295 | ||
|
|
cf38b52afa | ||
|
|
e755d01a0b | ||
|
|
4084948d3b | ||
|
|
cea1fb5c58 | ||
|
|
1947a21824 | ||
|
|
6335b5fd8a | ||
|
|
daa8319b8a | ||
|
|
d5599604e8 | ||
|
|
072933f1d5 | ||
|
|
39df3a1680 | ||
|
|
03c5ecb2e3 | ||
|
|
40ef074cb3 | ||
|
|
78e3936cd4 | ||
|
|
e7be38b42a | ||
|
|
44394e61c9 | ||
|
|
f9055df44d | ||
|
|
51bdb7281b | ||
|
|
9c01511f84 | ||
|
|
9faee3b66a | ||
|
|
8ea1ced389 | ||
|
|
24619daf68 | ||
|
|
b89cc84c3a | ||
|
|
3016a78d85 | ||
|
|
2508481e33 | ||
|
|
48c46fa9a7 | ||
|
|
7da49b5709 | ||
|
|
d837a46ebd | ||
|
|
d4303b62cc | ||
|
|
7d595e2eac | ||
|
|
9fc0ff5953 | ||
|
|
997d09bb33 | ||
|
|
b244b4ec21 | ||
|
|
b872ffee01 | ||
|
|
9a9543013c | ||
|
|
b98ce6c84f | ||
|
|
7b43b6396f | ||
|
|
67f8fcb103 | ||
|
|
352a944868 | ||
|
|
77c9116c91 | ||
|
|
e821787095 | ||
|
|
aa6e33e208 | ||
|
|
176581d732 | ||
|
|
01aa078e9c | ||
|
|
149d75c092 | ||
|
|
2619bff3cf | ||
|
|
4fb54b066f | ||
|
|
e124ef57e3 | ||
|
|
73e6b2550b | ||
|
|
241113200e | ||
|
|
6f3ab09319 | ||
|
|
3b5d5014e0 | ||
|
|
c36c3cb470 | ||
|
|
24b73a95fa | ||
|
|
862b1b77b5 | ||
|
|
b4944a31a4 | ||
|
|
58362d5ec7 | ||
|
|
01fa430a3e | ||
|
|
f4ee0f651c | ||
|
|
077512d151 | ||
|
|
e4848a7f5a | ||
|
|
f52b0e7c31 | ||
|
|
31e7d25cad | ||
|
|
12babdfe20 | ||
|
|
397e48b97e | ||
|
|
c7520b4b97 | ||
|
|
ad903e9240 | ||
|
|
83c3838b07 | ||
|
|
fa09f87589 | ||
|
|
2db1a141ab | ||
|
|
dd30ed6a9b | ||
|
|
cb50a2d192 | ||
|
|
20be5209c0 | ||
|
|
2a49760032 | ||
|
|
04ed818f0a | ||
|
|
10ca578ee5 | ||
|
|
955411e065 | ||
|
|
adcafce048 | ||
|
|
b1e05fd48a | ||
|
|
23b51287aa | ||
|
|
74dee5c445 | ||
|
|
ee27d87a08 | ||
|
|
62887f2c66 | ||
|
|
68b2dadc58 | ||
|
|
bd73720061 | ||
|
|
ec0440f264 | ||
|
|
81254f67e4 | ||
|
|
c549ee89b9 | ||
|
|
7924a3ae8b | ||
|
|
13ad10a6b5 | ||
|
|
e6ebf827ce | ||
|
|
0a42457df6 | ||
|
|
ba4a771bbc | ||
|
|
ac26993b5a | ||
|
|
ea52339502 | ||
|
|
992952d8f6 | ||
|
|
6d7ab63a66 | ||
|
|
822b1da5d2 | ||
|
|
72805ea73a | ||
|
|
a5e6946f74 | ||
|
|
b8672b55b2 | ||
|
|
a5a958beda | ||
|
|
c885660347 | ||
|
|
d68d155f93 | ||
|
|
e535f19189 | ||
|
|
f9a2a9d78e | ||
|
|
960668ccdb | ||
|
|
55b59407e4 | ||
|
|
b726e364c1 | ||
|
|
bfe3a8b516 | ||
|
|
ae09773ba0 | ||
|
|
8d668c2963 | ||
|
|
5f60c1b830 | ||
|
|
10de27ca3d | ||
|
|
7b4fd858ba | ||
|
|
a7bcd4d613 | ||
|
|
6a2bda52f3 | ||
|
|
fa8aa204a0 | ||
|
|
76b27891c6 | ||
|
|
203ca2586a | ||
|
|
c21f096ab8 | ||
|
|
b7219ac489 | ||
|
|
a6bb66931b | ||
|
|
766742e1d3 | ||
|
|
94e8944f67 | ||
|
|
83197ffdb3 | ||
|
|
952765be66 | ||
|
|
083679bcad | ||
|
|
f5659f292b | ||
|
|
c6e287331d | ||
|
|
a98ec7e4df | ||
|
|
5ec82e5801 | ||
|
|
c76481341c | ||
|
|
5e6307974f | ||
|
|
228cdf8e7e | ||
|
|
14fedbf123 | ||
|
|
fcee32527b | ||
|
|
e13d1e9969 | ||
|
|
aedc1e7fc9 | ||
|
|
353f654038 | ||
|
|
357d861246 | ||
|
|
fd4caf7a9c | ||
|
|
c44b6399c3 | ||
|
|
522cceeccf |
58
.github/workflows/build.yml
vendored
Normal file
58
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
name: Build testing
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
jobs:
|
||||||
|
ufuzz:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
options:
|
||||||
|
- '-mb braces'
|
||||||
|
- '--ie8 -c'
|
||||||
|
- '-mc'
|
||||||
|
- '-p acorn --toplevel -mco spidermonkey'
|
||||||
|
- '--toplevel -mc passes=3,pure_getters,unsafe'
|
||||||
|
script:
|
||||||
|
- acorn.sh
|
||||||
|
- bootstrap.sh
|
||||||
|
- buble.sh
|
||||||
|
- butternut.sh
|
||||||
|
- mathjs.sh
|
||||||
|
- rollup-es.sh
|
||||||
|
- rollup-ts.sh
|
||||||
|
- sucrase.sh
|
||||||
|
- web-tooling-benchmark.sh
|
||||||
|
include:
|
||||||
|
- node: '14'
|
||||||
|
script: acorn.sh
|
||||||
|
- node: '14'
|
||||||
|
script: bootstrap.sh
|
||||||
|
- node: '14'
|
||||||
|
script: buble.sh
|
||||||
|
- node: '14'
|
||||||
|
script: butternut.sh
|
||||||
|
- node: '14'
|
||||||
|
script: mathjs.sh
|
||||||
|
- node: '8'
|
||||||
|
script: rollup-es.sh
|
||||||
|
- node: '14'
|
||||||
|
script: rollup-ts.sh
|
||||||
|
- node: '14'
|
||||||
|
script: sucrase.sh
|
||||||
|
- node: '14'
|
||||||
|
script: web-tooling-benchmark.sh
|
||||||
|
name: ${{ matrix.script }} ${{ matrix.options }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
NODE: ${{ matrix.node }}
|
||||||
|
OPTIONS: ${{ matrix.options }}
|
||||||
|
SCRIPT: ${{ matrix.script }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Perform uglify, build & test
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
. ./test/release/install.sh
|
||||||
|
./test/release/$SCRIPT $OPTIONS
|
||||||
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@@ -7,7 +7,7 @@ jobs:
|
|||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', latest ]
|
node: [ '0.8', '0.10', '0.12', '4', '6', '8', '10', '12', '14', latest ]
|
||||||
os: [ ubuntu-latest, windows-latest ]
|
os: [ ubuntu-latest, windows-latest ]
|
||||||
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
script: [ compress, mocha, release/benchmark, release/jetstream ]
|
||||||
exclude:
|
exclude:
|
||||||
@@ -29,20 +29,5 @@ jobs:
|
|||||||
- name: Perform tests
|
- name: Perform tests
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
. ./test/release/install.sh
|
||||||
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
|
||||||
cd ~/.nvs
|
|
||||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
|
||||||
cd -
|
|
||||||
done
|
|
||||||
. ~/.nvs/nvs.sh --version
|
|
||||||
nvs use $NODE
|
|
||||||
node --version
|
|
||||||
npm config set audit false
|
|
||||||
npm config set optional false
|
|
||||||
npm config set save false
|
|
||||||
npm config set strict-ssl false
|
|
||||||
npm config set update-notifier false
|
|
||||||
npm --version
|
|
||||||
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
|
||||||
node test/$TYPE
|
node test/$TYPE
|
||||||
|
|||||||
24
.github/workflows/ufuzz.yml
vendored
24
.github/workflows/ufuzz.yml
vendored
@@ -30,32 +30,10 @@ jobs:
|
|||||||
NODE: ${{ matrix.node }}
|
NODE: ${{ matrix.node }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: Install GNU Core Utilities
|
|
||||||
if: ${{ startsWith(matrix.os, 'macos') }}
|
|
||||||
env:
|
|
||||||
HOMEBREW_NO_INSTALL_CLEANUP: 1
|
|
||||||
shell: bash
|
|
||||||
run: |
|
|
||||||
brew install coreutils
|
|
||||||
- name: Perform fuzzing
|
- name: Perform fuzzing
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
. ./test/release/install.sh
|
||||||
while ! timeout 60 bash -c '. ~/.nvs/nvs.sh add $NODE && nvs use $NODE'; do
|
|
||||||
cd ~/.nvs
|
|
||||||
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
|
||||||
cd -
|
|
||||||
done
|
|
||||||
. ~/.nvs/nvs.sh --version
|
|
||||||
nvs use $NODE
|
|
||||||
node --version
|
|
||||||
npm config set audit false
|
|
||||||
npm config set optional false
|
|
||||||
npm config set save false
|
|
||||||
npm config set strict-ssl false
|
|
||||||
npm config set update-notifier false
|
|
||||||
npm --version
|
|
||||||
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
|
||||||
if [[ $CAUSE == "schedule" ]]; then
|
if [[ $CAUSE == "schedule" ]]; then
|
||||||
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
|
node test/ufuzz/job $BASE_URL $TOKEN $RUN_NUM
|
||||||
else
|
else
|
||||||
|
|||||||
311
README.md
311
README.md
@@ -4,12 +4,11 @@ UglifyJS 3
|
|||||||
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
UglifyJS is a JavaScript parser, minifier, compressor and beautifier toolkit.
|
||||||
|
|
||||||
#### Note:
|
#### Note:
|
||||||
- **`uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
|
- `uglify-js` supports JavaScript and most language features in ECMAScript.
|
||||||
that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
- For more exotic parts of ECMAScript, process your source file with transpilers
|
||||||
- **Documentation for UglifyJS `2.x` releases can be found [here](https://github.com/mishoo/UglifyJS/tree/v2.x)**.
|
like [Babel](https://babeljs.io/) before passing onto `uglify-js`.
|
||||||
- `uglify-js` supports ECMAScript 5 and some newer language features.
|
- `uglify-js@3` has a simplified [API](#api-reference) and [CLI](#command-line-usage)
|
||||||
- To minify ECMAScript 2015 or above, you may need to transpile using tools like
|
that is not backwards compatible with [`uglify-js@2`](https://github.com/mishoo/UglifyJS/tree/v2.x).
|
||||||
[Babel](https://babeljs.io/).
|
|
||||||
|
|
||||||
Install
|
Install
|
||||||
-------
|
-------
|
||||||
@@ -86,13 +85,16 @@ a double dash to prevent input files being used as option arguments:
|
|||||||
1 - single
|
1 - single
|
||||||
2 - double
|
2 - double
|
||||||
3 - original
|
3 - original
|
||||||
`wrap_iife` Wrap IIFEs in parenthesis. Note: you may
|
`wrap_iife` Wrap IIFEs in parentheses. Note: you may
|
||||||
want to disable `negate_iife` under
|
want to disable `negate_iife` under
|
||||||
compressor options.
|
compressor options.
|
||||||
-O, --output-opts [options] Specify output options (`beautify` disabled by default).
|
-O, --output-opts [options] Specify output options (`beautify` disabled by default).
|
||||||
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
-o, --output <file> Output file path (default STDOUT). Specify `ast` or
|
||||||
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
`spidermonkey` to write UglifyJS or SpiderMonkey AST
|
||||||
as JSON to STDOUT respectively.
|
as JSON to STDOUT respectively.
|
||||||
|
--annotations Process and preserve comment annotations.
|
||||||
|
(`/*@__PURE__*/` or `/*#__PURE__*/`)
|
||||||
|
--no-annotations Ignore and discard comment annotations.
|
||||||
--comments [filter] Preserve copyright comments in the output. By
|
--comments [filter] Preserve copyright comments in the output. By
|
||||||
default this works like Google Closure, keeping
|
default this works like Google Closure, keeping
|
||||||
JSDoc-style comments that contain "@license" or
|
JSDoc-style comments that contain "@license" or
|
||||||
@@ -222,10 +224,10 @@ Example:
|
|||||||
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
To enable the mangler you need to pass `--mangle` (`-m`). The following
|
||||||
(comma-separated) options are supported:
|
(comma-separated) options are supported:
|
||||||
|
|
||||||
- `eval` (default `false`) -- mangle names visible in scopes where `eval` or
|
- `eval` (default: `false`) — mangle names visible in scopes where `eval` or
|
||||||
`with` are used.
|
`with` are used.
|
||||||
|
|
||||||
- `reserved` (default: `[]`) -- when mangling is enabled but you want to
|
- `reserved` (default: `[]`) — when mangling is enabled but you want to
|
||||||
prevent certain names from being mangled, you can declare those names with
|
prevent certain names from being mangled, you can declare those names with
|
||||||
`--mangle reserved` — pass a comma-separated list of names. For example:
|
`--mangle reserved` — pass a comma-separated list of names. For example:
|
||||||
|
|
||||||
@@ -492,46 +494,51 @@ if (result.error) throw result.error;
|
|||||||
|
|
||||||
## Minify options
|
## Minify options
|
||||||
|
|
||||||
- `compress` (default `{}`) — pass `false` to skip compressing entirely.
|
- `annotations` — pass `false` to ignore all comment annotations and elide them
|
||||||
|
from output. Useful when, for instance, external tools incorrectly applied
|
||||||
|
`/*@__PURE__*/` or `/*#__PURE__*/`. Pass `true` to both compress and retain
|
||||||
|
comment annotations in output to allow for further processing downstream.
|
||||||
|
|
||||||
|
- `compress` (default: `{}`) — pass `false` to skip compressing entirely.
|
||||||
Pass an object to specify custom [compress options](#compress-options).
|
Pass an object to specify custom [compress options](#compress-options).
|
||||||
|
|
||||||
- `ie8` (default `false`) -- set to `true` to support IE8.
|
- `ie8` (default: `false`) — set to `true` to support IE8.
|
||||||
|
|
||||||
- `keep_fnames` (default: `false`) -- pass `true` to prevent discarding or mangling
|
- `keep_fnames` (default: `false`) — pass `true` to prevent discarding or mangling
|
||||||
of function names. Useful for code relying on `Function.prototype.name`.
|
of function names. Useful for code relying on `Function.prototype.name`.
|
||||||
|
|
||||||
- `mangle` (default `true`) — pass `false` to skip mangling names, or pass
|
- `mangle` (default: `true`) — pass `false` to skip mangling names, or pass
|
||||||
an object to specify [mangle options](#mangle-options) (see below).
|
an object to specify [mangle options](#mangle-options) (see below).
|
||||||
|
|
||||||
- `mangle.properties` (default `false`) — a subcategory of the mangle option.
|
- `mangle.properties` (default: `false`) — a subcategory of the mangle option.
|
||||||
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
Pass an object to specify custom [mangle property options](#mangle-properties-options).
|
||||||
|
|
||||||
- `nameCache` (default `null`) -- pass an empty object `{}` or a previously
|
- `nameCache` (default: `null`) — pass an empty object `{}` or a previously
|
||||||
used `nameCache` object if you wish to cache mangled variable and
|
used `nameCache` object if you wish to cache mangled variable and
|
||||||
property names across multiple invocations of `minify()`. Note: this is
|
property names across multiple invocations of `minify()`. Note: this is
|
||||||
a read/write property. `minify()` will read the name cache state of this
|
a read/write property. `minify()` will read the name cache state of this
|
||||||
object and update it during minification so that it may be
|
object and update it during minification so that it may be
|
||||||
reused or externally persisted by the user.
|
reused or externally persisted by the user.
|
||||||
|
|
||||||
- `output` (default `null`) — pass an object if you wish to specify
|
- `output` (default: `null`) — pass an object if you wish to specify
|
||||||
additional [output options](#output-options). The defaults are optimized
|
additional [output options](#output-options). The defaults are optimized
|
||||||
for best compression.
|
for best compression.
|
||||||
|
|
||||||
- `parse` (default `{}`) — pass an object if you wish to specify some
|
- `parse` (default: `{}`) — pass an object if you wish to specify some
|
||||||
additional [parse options](#parse-options).
|
additional [parse options](#parse-options).
|
||||||
|
|
||||||
- `sourceMap` (default `false`) -- pass an object if you wish to specify
|
- `sourceMap` (default: `false`) — pass an object if you wish to specify
|
||||||
[source map options](#source-map-options).
|
[source map options](#source-map-options).
|
||||||
|
|
||||||
- `toplevel` (default `false`) -- set to `true` if you wish to enable top level
|
- `toplevel` (default: `false`) — set to `true` if you wish to enable top level
|
||||||
variable and function name mangling and to drop unused variables and functions.
|
variable and function name mangling and to drop unused variables and functions.
|
||||||
|
|
||||||
- `v8` (default `false`) -- enable workarounds for Chrome & Node.js bugs.
|
- `v8` (default: `false`) — enable workarounds for Chrome & Node.js bugs.
|
||||||
|
|
||||||
- `warnings` (default `false`) — pass `true` to return compressor warnings
|
- `warnings` (default: `false`) — pass `true` to return compressor warnings
|
||||||
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
in `result.warnings`. Use the value `"verbose"` for more detailed warnings.
|
||||||
|
|
||||||
- `webkit` (default `false`) -- enable workarounds for Safari/WebKit bugs.
|
- `webkit` (default: `false`) — enable workarounds for Safari/WebKit bugs.
|
||||||
PhantomJS users should set this option to `true`.
|
PhantomJS users should set this option to `true`.
|
||||||
|
|
||||||
## Minify options structure
|
## Minify options structure
|
||||||
@@ -616,111 +623,121 @@ to be `false` and all symbol names will be omitted.
|
|||||||
|
|
||||||
## Parse options
|
## Parse options
|
||||||
|
|
||||||
- `bare_returns` (default `false`) -- support top level `return` statements
|
- `bare_returns` (default: `false`) — support top level `return` statements
|
||||||
|
|
||||||
- `html5_comments` (default `true`)
|
- `html5_comments` (default: `true`)
|
||||||
|
|
||||||
- `shebang` (default `true`) -- support `#!command` as the first line
|
- `shebang` (default: `true`) — support `#!command` as the first line
|
||||||
|
|
||||||
## Compress options
|
## Compress options
|
||||||
|
|
||||||
- `arguments` (default: `true`) -- replace `arguments[index]` with function
|
- `annotations` (default: `true`) — Pass `false` to disable potentially dropping
|
||||||
|
functions marked as "pure". A function call is marked as "pure" if a comment
|
||||||
|
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
||||||
|
example: `/*@__PURE__*/foo();`
|
||||||
|
|
||||||
|
- `arguments` (default: `true`) — replace `arguments[index]` with function
|
||||||
parameter name whenever possible.
|
parameter name whenever possible.
|
||||||
|
|
||||||
- `arrows` (default: `true`) -- apply optimizations to arrow functions
|
- `arrows` (default: `true`) — apply optimizations to arrow functions
|
||||||
|
|
||||||
- `assignments` (default: `true`) -- apply optimizations to assignment expressions
|
- `assignments` (default: `true`) — apply optimizations to assignment expressions
|
||||||
|
|
||||||
- `awaits` (default: `true`) -- apply optimizations to `await` expressions
|
- `awaits` (default: `true`) — apply optimizations to `await` expressions
|
||||||
|
|
||||||
- `booleans` (default: `true`) -- various optimizations for boolean context,
|
- `booleans` (default: `true`) — various optimizations for boolean context,
|
||||||
for example `!!a ? b : c → a ? b : c`
|
for example `!!a ? b : c → a ? b : c`
|
||||||
|
|
||||||
- `collapse_vars` (default: `true`) -- Collapse single-use non-constant variables,
|
- `collapse_vars` (default: `true`) — Collapse single-use non-constant variables,
|
||||||
side effects permitting.
|
side effects permitting.
|
||||||
|
|
||||||
- `comparisons` (default: `true`) -- apply certain optimizations to binary nodes,
|
- `comparisons` (default: `true`) — apply certain optimizations to binary nodes,
|
||||||
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
|
e.g. `!(a <= b) → a > b`, attempts to negate binary nodes, e.g.
|
||||||
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
`a = !b && !c && !d && !e → a=!(b||c||d||e)` etc.
|
||||||
|
|
||||||
- `conditionals` (default: `true`) -- apply optimizations for `if`-s and conditional
|
- `conditionals` (default: `true`) — apply optimizations for `if`-s and conditional
|
||||||
expressions
|
expressions
|
||||||
|
|
||||||
- `dead_code` (default: `true`) -- remove unreachable code
|
- `dead_code` (default: `true`) — remove unreachable code
|
||||||
|
|
||||||
- `default_values` (default: `true`) -- drop overshadowed default values
|
- `default_values` (default: `true`) — drop overshadowed default values
|
||||||
|
|
||||||
- `directives` (default: `true`) -- remove redundant or non-standard directives
|
- `directives` (default: `true`) — remove redundant or non-standard directives
|
||||||
|
|
||||||
- `drop_console` (default: `false`) -- Pass `true` to discard calls to
|
- `drop_console` (default: `false`) — Pass `true` to discard calls to
|
||||||
`console.*` functions. If you wish to drop a specific function call
|
`console.*` functions. If you wish to drop a specific function call
|
||||||
such as `console.info` and/or retain side effects from function arguments
|
such as `console.info` and/or retain side effects from function arguments
|
||||||
after dropping the function call then use `pure_funcs` instead.
|
after dropping the function call then use `pure_funcs` instead.
|
||||||
|
|
||||||
- `drop_debugger` (default: `true`) -- remove `debugger;` statements
|
- `drop_debugger` (default: `true`) — remove `debugger;` statements
|
||||||
|
|
||||||
- `evaluate` (default: `true`) -- Evaluate expression for shorter constant
|
- `evaluate` (default: `true`) — Evaluate expression for shorter constant
|
||||||
representation. Pass `"eager"` to always replace function calls whenever
|
representation. Pass `"eager"` to always replace function calls whenever
|
||||||
possible, or a positive integer to specify an upper bound for each individual
|
possible, or a positive integer to specify an upper bound for each individual
|
||||||
evaluation in number of characters.
|
evaluation in number of characters.
|
||||||
|
|
||||||
- `expression` (default: `false`) -- Pass `true` to preserve completion values
|
- `expression` (default: `false`) — Pass `true` to preserve completion values
|
||||||
from terminal statements without `return`, e.g. in bookmarklets.
|
from terminal statements without `return`, e.g. in bookmarklets.
|
||||||
|
|
||||||
- `functions` (default: `true`) -- convert declarations from `var`to `function`
|
- `functions` (default: `true`) — convert declarations from `var` to `function`
|
||||||
whenever possible.
|
whenever possible.
|
||||||
|
|
||||||
- `global_defs` (default: `{}`) -- see [conditional compilation](#conditional-compilation)
|
- `global_defs` (default: `{}`) — see [conditional compilation](#conditional-compilation)
|
||||||
|
|
||||||
- `hoist_funs` (default: `false`) -- hoist function declarations
|
- `hoist_exports` (default: `true`) — hoist `export` statements to facilitate
|
||||||
|
various `compress` and `mangle` optimizations.
|
||||||
|
|
||||||
- `hoist_props` (default: `true`) -- hoist properties from constant object and
|
- `hoist_funs` (default: `false`) — hoist function declarations
|
||||||
|
|
||||||
|
- `hoist_props` (default: `true`) — hoist properties from constant object and
|
||||||
array literals into regular variables subject to a set of constraints. For example:
|
array literals into regular variables subject to a set of constraints. For example:
|
||||||
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
|
`var o={p:1, q:2}; f(o.p, o.q);` is converted to `f(1, 2);`. Note: `hoist_props`
|
||||||
works best with `toplevel` and `mangle` enabled, alongside with `compress` option
|
works best with `toplevel` and `mangle` enabled, alongside with `compress` option
|
||||||
`passes` set to `2` or higher.
|
`passes` set to `2` or higher.
|
||||||
|
|
||||||
- `hoist_vars` (default: `false`) -- hoist `var` declarations (this is `false`
|
- `hoist_vars` (default: `false`) — hoist `var` declarations (this is `false`
|
||||||
by default because it seems to increase the size of the output in general)
|
by default because it seems to increase the size of the output in general)
|
||||||
|
|
||||||
- `if_return` (default: `true`) -- optimizations for if/return and if/continue
|
- `if_return` (default: `true`) — optimizations for if/return and if/continue
|
||||||
|
|
||||||
- `inline` (default: `true`) -- inline calls to function with simple/`return` statement:
|
- `imports` (default: `true`) — drop unreferenced import symbols when used with `unused`
|
||||||
- `false` -- same as `0`
|
|
||||||
- `0` -- disabled inlining
|
|
||||||
- `1` -- inline simple functions
|
|
||||||
- `2` -- inline functions with arguments
|
|
||||||
- `3` -- inline functions with arguments and variables
|
|
||||||
- `true` -- same as `3`
|
|
||||||
|
|
||||||
- `join_vars` (default: `true`) -- join consecutive `var` statements
|
- `inline` (default: `true`) — inline calls to function with simple/`return` statement:
|
||||||
|
- `false` — same as `0`
|
||||||
|
- `0` — disabled inlining
|
||||||
|
- `1` — inline simple functions
|
||||||
|
- `2` — inline functions with arguments
|
||||||
|
- `3` — inline functions with arguments and variables
|
||||||
|
- `true` — same as `3`
|
||||||
|
|
||||||
- `keep_fargs` (default: `false`) -- discard unused function arguments except
|
- `join_vars` (default: `true`) — join consecutive `var` statements
|
||||||
|
|
||||||
|
- `keep_fargs` (default: `false`) — discard unused function arguments except
|
||||||
when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
|
when unsafe to do so, e.g. code which relies on `Function.prototype.length`.
|
||||||
Pass `true` to always retain function arguments.
|
Pass `true` to always retain function arguments.
|
||||||
|
|
||||||
- `keep_infinity` (default: `false`) -- Pass `true` to prevent `Infinity` from
|
- `keep_infinity` (default: `false`) — Pass `true` to prevent `Infinity` from
|
||||||
being compressed into `1/0`, which may cause performance issues on Chrome.
|
being compressed into `1/0`, which may cause performance issues on Chrome.
|
||||||
|
|
||||||
- `loops` (default: `true`) -- optimizations for `do`, `while` and `for` loops
|
- `loops` (default: `true`) — optimizations for `do`, `while` and `for` loops
|
||||||
when we can statically determine the condition.
|
when we can statically determine the condition.
|
||||||
|
|
||||||
- `merge_vars` (default: `true`) -- combine and reuse variables.
|
- `merge_vars` (default: `true`) — combine and reuse variables.
|
||||||
|
|
||||||
- `negate_iife` (default: `true`) -- negate "Immediately-Called Function Expressions"
|
- `negate_iife` (default: `true`) — negate "Immediately-Called Function Expressions"
|
||||||
where the return value is discarded, to avoid the parens that the
|
where the return value is discarded, to avoid the parens that the
|
||||||
code generator would insert.
|
code generator would insert.
|
||||||
|
|
||||||
- `objects` (default: `true`) -- compact duplicate keys in object literals.
|
- `objects` (default: `true`) — compact duplicate keys in object literals.
|
||||||
|
|
||||||
- `passes` (default: `1`) -- The maximum number of times to run compress.
|
- `passes` (default: `1`) — The maximum number of times to run compress.
|
||||||
In some cases more than one pass leads to further compressed code. Keep in
|
In some cases more than one pass leads to further compressed code. Keep in
|
||||||
mind more passes will take more time.
|
mind more passes will take more time.
|
||||||
|
|
||||||
- `properties` (default: `true`) -- rewrite property access using the dot notation, for
|
- `properties` (default: `true`) — rewrite property access using the dot notation, for
|
||||||
example `foo["bar"] → foo.bar`
|
example `foo["bar"] → foo.bar`
|
||||||
|
|
||||||
- `pure_funcs` (default: `null`) -- You can pass an array of names and
|
- `pure_funcs` (default: `null`) — You can pass an array of names and
|
||||||
UglifyJS will assume that those functions do not produce side
|
UglifyJS will assume that those functions do not produce side
|
||||||
effects. DANGER: will not check if the name is redefined in scope.
|
effects. DANGER: will not check if the name is redefined in scope.
|
||||||
An example case here, for instance `var q = Math.floor(a/b)`. If
|
An example case here, for instance `var q = Math.floor(a/b)`. If
|
||||||
@@ -732,24 +749,24 @@ to be `false` and all symbol names will be omitted.
|
|||||||
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
overhead (compression will be slower). Make sure symbols under `pure_funcs`
|
||||||
are also under `mangle.reserved` to avoid mangling.
|
are also under `mangle.reserved` to avoid mangling.
|
||||||
|
|
||||||
- `pure_getters` (default: `"strict"`) -- If you pass `true` for
|
- `pure_getters` (default: `"strict"`) — If you pass `true` for
|
||||||
this, UglifyJS will assume that object property access
|
this, UglifyJS will assume that object property access
|
||||||
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
(e.g. `foo.bar` or `foo["bar"]`) doesn't have any side effects.
|
||||||
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
Specify `"strict"` to treat `foo.bar` as side-effect-free only when
|
||||||
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
`foo` is certain to not throw, i.e. not `null` or `undefined`.
|
||||||
|
|
||||||
- `reduce_funcs` (default: `true`) -- Allows single-use functions to be
|
- `reduce_funcs` (default: `true`) — Allows single-use functions to be
|
||||||
inlined as function expressions when permissible allowing further
|
inlined as function expressions when permissible allowing further
|
||||||
optimization. Enabled by default. Option depends on `reduce_vars`
|
optimization. Enabled by default. Option depends on `reduce_vars`
|
||||||
being enabled. Some code runs faster in the Chrome V8 engine if this
|
being enabled. Some code runs faster in the Chrome V8 engine if this
|
||||||
option is disabled. Does not negatively impact other major browsers.
|
option is disabled. Does not negatively impact other major browsers.
|
||||||
|
|
||||||
- `reduce_vars` (default: `true`) -- Improve optimization on variables assigned with and
|
- `reduce_vars` (default: `true`) — Improve optimization on variables assigned with and
|
||||||
used as constant values.
|
used as constant values.
|
||||||
|
|
||||||
- `rests` (default: `true`) -- apply optimizations to rest parameters
|
- `rests` (default: `true`) — apply optimizations to rest parameters
|
||||||
|
|
||||||
- `sequences` (default: `true`) -- join consecutive simple statements using the
|
- `sequences` (default: `true`) — join consecutive simple statements using the
|
||||||
comma operator. May be set to a positive integer to specify the maximum number
|
comma operator. May be set to a positive integer to specify the maximum number
|
||||||
of consecutive comma sequences that will be generated. If this option is set to
|
of consecutive comma sequences that will be generated. If this option is set to
|
||||||
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
`true` then the default `sequences` limit is `200`. Set option to `false` or `0`
|
||||||
@@ -758,68 +775,68 @@ to be `false` and all symbol names will be omitted.
|
|||||||
occasions the default sequences limit leads to very slow compress times in which
|
occasions the default sequences limit leads to very slow compress times in which
|
||||||
case a value of `20` or less is recommended.
|
case a value of `20` or less is recommended.
|
||||||
|
|
||||||
- `side_effects` (default: `true`) -- Pass `false` to disable potentially dropping
|
- `side_effects` (default: `true`) — drop extraneous code which does not affect
|
||||||
functions marked as "pure". A function call is marked as "pure" if a comment
|
outcome of runtime execution.
|
||||||
annotation `/*@__PURE__*/` or `/*#__PURE__*/` immediately precedes the call. For
|
|
||||||
example: `/*@__PURE__*/foo();`
|
|
||||||
|
|
||||||
- `spreads` (default: `true`) -- flatten spread expressions.
|
- `spreads` (default: `true`) — flatten spread expressions.
|
||||||
|
|
||||||
- `strings` (default: `true`) -- compact string concatenations.
|
- `strings` (default: `true`) — compact string concatenations.
|
||||||
|
|
||||||
- `switches` (default: `true`) -- de-duplicate and remove unreachable `switch` branches
|
- `switches` (default: `true`) — de-duplicate and remove unreachable `switch` branches
|
||||||
|
|
||||||
- `templates` (default: `true`) -- compact template literals by embedding expressions
|
- `templates` (default: `true`) — compact template literals by embedding expressions
|
||||||
and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
|
and/or converting to string literals, e.g. `` `foo ${42}` → "foo 42"``
|
||||||
|
|
||||||
- `top_retain` (default: `null`) -- prevent specific toplevel functions and
|
- `top_retain` (default: `null`) — prevent specific toplevel functions and
|
||||||
variables from `unused` removal (can be array, comma-separated, RegExp or
|
variables from `unused` removal (can be array, comma-separated, RegExp or
|
||||||
function. Implies `toplevel`)
|
function. Implies `toplevel`)
|
||||||
|
|
||||||
- `toplevel` (default: `false`) -- drop unreferenced functions (`"funcs"`) and/or
|
- `toplevel` (default: `false`) — drop unreferenced functions (`"funcs"`) and/or
|
||||||
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
variables (`"vars"`) in the top level scope (`false` by default, `true` to drop
|
||||||
both unreferenced functions and variables)
|
both unreferenced functions and variables)
|
||||||
|
|
||||||
- `typeofs` (default: `true`) -- Transforms `typeof foo == "undefined"` into
|
- `typeofs` (default: `true`) — Transforms `typeof foo == "undefined"` into
|
||||||
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
`foo === void 0`. Note: recommend to set this value to `false` for IE10 and
|
||||||
earlier versions due to known issues.
|
earlier versions due to known issues.
|
||||||
|
|
||||||
- `unsafe` (default: `false`) -- apply "unsafe" transformations (discussion below)
|
- `unsafe` (default: `false`) — apply "unsafe" transformations (discussion below)
|
||||||
|
|
||||||
- `unsafe_comps` (default: `false`) -- compress expressions like `a <= b` assuming
|
- `unsafe_comps` (default: `false`) — compress expressions like `a <= b` assuming
|
||||||
none of the operands can be (coerced to) `NaN`.
|
none of the operands can be (coerced to) `NaN`.
|
||||||
|
|
||||||
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
- `unsafe_Function` (default: `false`) — compress and mangle `Function(args, code)`
|
||||||
when both `args` and `code` are string literals.
|
when both `args` and `code` are string literals.
|
||||||
|
|
||||||
- `unsafe_math` (default: `false`) -- optimize numerical expressions like
|
- `unsafe_math` (default: `false`) — optimize numerical expressions like
|
||||||
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
`2 * x * 3` into `6 * x`, which may give imprecise floating point results.
|
||||||
|
|
||||||
- `unsafe_proto` (default: `false`) -- optimize expressions like
|
- `unsafe_proto` (default: `false`) — optimize expressions like
|
||||||
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
`Array.prototype.slice.call(a)` into `[].slice.call(a)`
|
||||||
|
|
||||||
- `unsafe_regexp` (default: `false`) -- enable substitutions of variables with
|
- `unsafe_regexp` (default: `false`) — enable substitutions of variables with
|
||||||
`RegExp` values the same way as if they are constants.
|
`RegExp` values the same way as if they are constants.
|
||||||
|
|
||||||
- `unsafe_undefined` (default: `false`) -- substitute `void 0` if there is a
|
- `unsafe_undefined` (default: `false`) — substitute `void 0` if there is a
|
||||||
variable named `undefined` in scope (variable name will be mangled, typically
|
variable named `undefined` in scope (variable name will be mangled, typically
|
||||||
reduced to a single character)
|
reduced to a single character)
|
||||||
|
|
||||||
- `unused` (default: `true`) -- drop unreferenced functions and variables (simple
|
- `unused` (default: `true`) — drop unreferenced functions and variables (simple
|
||||||
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
direct variable assignments do not count as references unless set to `"keep_assign"`)
|
||||||
|
|
||||||
- `varify` (default: `true`) -- convert block-scoped declaractions into `var`
|
- `varify` (default: `true`) — convert block-scoped declaractions into `var`
|
||||||
whenever safe to do so
|
whenever safe to do so
|
||||||
|
|
||||||
|
- `yields` (default: `true`) — apply optimizations to `yield` expressions
|
||||||
|
|
||||||
## Mangle options
|
## Mangle options
|
||||||
|
|
||||||
- `eval` (default `false`) -- Pass `true` to mangle names visible in scopes
|
- `eval` (default: `false`) — Pass `true` to mangle names visible in scopes
|
||||||
where `eval` or `with` are used.
|
where `eval` or `with` are used.
|
||||||
|
|
||||||
- `reserved` (default `[]`) -- Pass an array of identifiers that should be
|
- `reserved` (default: `[]`) — Pass an array of identifiers that should be
|
||||||
excluded from mangling. Example: `["foo", "bar"]`.
|
excluded from mangling. Example: `["foo", "bar"]`.
|
||||||
|
|
||||||
- `toplevel` (default `false`) -- Pass `true` to mangle names declared in the
|
- `toplevel` (default: `false`) — Pass `true` to mangle names declared in the
|
||||||
top level scope.
|
top level scope.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
@@ -846,18 +863,18 @@ UglifyJS.minify(code, { mangle: { toplevel: true } }).code;
|
|||||||
|
|
||||||
### Mangle properties options
|
### Mangle properties options
|
||||||
|
|
||||||
- `builtins` (default: `false`) -- Use `true` to allow the mangling of builtin
|
- `builtins` (default: `false`) — Use `true` to allow the mangling of builtin
|
||||||
DOM properties. Not recommended to override this setting.
|
DOM properties. Not recommended to override this setting.
|
||||||
|
|
||||||
- `debug` (default: `false`) -— Mangle names with the original name still present.
|
- `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.
|
Pass an empty string `""` to enable, or a non-empty string to set the debug suffix.
|
||||||
|
|
||||||
- `keep_quoted` (default: `false`) -— Only mangle unquoted property names.
|
- `keep_quoted` (default: `false`) — Only mangle unquoted property names.
|
||||||
|
|
||||||
- `regex` (default: `null`) -— Pass a RegExp literal to only mangle property
|
- `regex` (default: `null`) — Pass a RegExp literal to only mangle property
|
||||||
names matching the regular expression.
|
names matching the regular expression.
|
||||||
|
|
||||||
- `reserved` (default: `[]`) -- Do not mangle property names listed in the
|
- `reserved` (default: `[]`) — Do not mangle property names listed in the
|
||||||
`reserved` array.
|
`reserved` array.
|
||||||
|
|
||||||
## Output options
|
## Output options
|
||||||
@@ -866,19 +883,23 @@ The code generator tries to output shortest code possible by default. In
|
|||||||
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
case you want beautified output, pass `--beautify` (`-b`). Optionally you
|
||||||
can pass additional arguments that control the code output:
|
can pass additional arguments that control the code output:
|
||||||
|
|
||||||
- `ascii_only` (default `false`) -- escape Unicode characters in strings and
|
- `annotations` (default: `false`) — pass `true` to retain comment annotations
|
||||||
|
`/*@__PURE__*/` or `/*#__PURE__*/`, otherwise they will be discarded even if
|
||||||
|
`comments` is set.
|
||||||
|
|
||||||
|
- `ascii_only` (default: `false`) — escape Unicode characters in strings and
|
||||||
regexps (affects directives with non-ascii characters becoming invalid)
|
regexps (affects directives with non-ascii characters becoming invalid)
|
||||||
|
|
||||||
- `beautify` (default `true`) -- whether to actually beautify the output.
|
- `beautify` (default: `true`) — whether to actually beautify the output.
|
||||||
Passing `-b` will set this to true, but you might need to pass `-b` even
|
Passing `-b` will set this to true, but you might need to pass `-b` even
|
||||||
when you want to generate minified code, in order to specify additional
|
when you want to generate minified code, in order to specify additional
|
||||||
arguments, so you can use `-b beautify=false` to override it.
|
arguments, so you can use `-b beautify=false` to override it.
|
||||||
|
|
||||||
- `braces` (default `false`) -- always insert braces in `if`, `for`,
|
- `braces` (default: `false`) — always insert braces in `if`, `for`,
|
||||||
`do`, `while` or `with` statements, even if their body is a single
|
`do`, `while` or `with` statements, even if their body is a single
|
||||||
statement.
|
statement.
|
||||||
|
|
||||||
- `comments` (default `false`) -- pass `true` or `"all"` to preserve all
|
- `comments` (default: `false`) — pass `true` or `"all"` to preserve all
|
||||||
comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
|
comments, `"some"` to preserve multi-line comments that contain `@cc_on`,
|
||||||
`@license`, or `@preserve` (case-insensitive), a regular expression string
|
`@license`, or `@preserve` (case-insensitive), a regular expression string
|
||||||
(e.g. `/^!/`), or a function which returns `boolean`, e.g.
|
(e.g. `/^!/`), or a function which returns `boolean`, e.g.
|
||||||
@@ -888,53 +909,53 @@ can pass additional arguments that control the code output:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- `galio` (default `false`) -- enable workarounds for ANT Galio bugs
|
- `galio` (default: `false`) — enable workarounds for ANT Galio bugs
|
||||||
|
|
||||||
- `indent_level` (default `4`)
|
- `indent_level` (default: `4`)
|
||||||
|
|
||||||
- `indent_start` (default `0`) -- prefix all lines by that many spaces
|
- `indent_start` (default: `0`) — prefix all lines by that many spaces
|
||||||
|
|
||||||
- `inline_script` (default `true`) -- escape HTML comments and the slash in
|
- `inline_script` (default: `true`) — escape HTML comments and the slash in
|
||||||
occurrences of `</script>` in strings
|
occurrences of `</script>` in strings
|
||||||
|
|
||||||
- `keep_quoted_props` (default `false`) -- when turned on, prevents stripping
|
- `keep_quoted_props` (default: `false`) — when turned on, prevents stripping
|
||||||
quotes from property names in object literals.
|
quotes from property names in object literals.
|
||||||
|
|
||||||
- `max_line_len` (default `false`) -- maximum line length (for uglified code)
|
- `max_line_len` (default: `false`) — maximum line length (for uglified code)
|
||||||
|
|
||||||
- `preamble` (default `null`) -- when passed it must be a string and
|
- `preamble` (default: `null`) — when passed it must be a string and
|
||||||
it will be prepended to the output literally. The source map will
|
it will be prepended to the output literally. The source map will
|
||||||
adjust for this text. Can be used to insert a comment containing
|
adjust for this text. Can be used to insert a comment containing
|
||||||
licensing information, for example.
|
licensing information, for example.
|
||||||
|
|
||||||
- `preserve_line` (default `false`) -- pass `true` to retain line numbering on
|
- `preserve_line` (default: `false`) — pass `true` to retain line numbering on
|
||||||
a best effort basis.
|
a best effort basis.
|
||||||
|
|
||||||
- `quote_keys` (default `false`) -- pass `true` to quote all keys in literal
|
- `quote_keys` (default: `false`) — pass `true` to quote all keys in literal
|
||||||
objects
|
objects
|
||||||
|
|
||||||
- `quote_style` (default `0`) -- preferred quote style for strings (affects
|
- `quote_style` (default: `0`) — preferred quote style for strings (affects
|
||||||
quoted property names and directives as well):
|
quoted property names and directives as well):
|
||||||
- `0` -- prefers double quotes, switches to single quotes when there are
|
- `0` — prefers double quotes, switches to single quotes when there are
|
||||||
more double quotes in the string itself. `0` is best for gzip size.
|
more double quotes in the string itself. `0` is best for gzip size.
|
||||||
- `1` -- always use single quotes
|
- `1` — always use single quotes
|
||||||
- `2` -- always use double quotes
|
- `2` — always use double quotes
|
||||||
- `3` -- always use the original quotes
|
- `3` — always use the original quotes
|
||||||
|
|
||||||
- `semicolons` (default `true`) -- separate statements with semicolons. If
|
- `semicolons` (default: `true`) — separate statements with semicolons. If
|
||||||
you pass `false` then whenever possible we will use a newline instead of a
|
you pass `false` then whenever possible we will use a newline instead of a
|
||||||
semicolon, leading to more readable output of uglified code (size before
|
semicolon, leading to more readable output of uglified code (size before
|
||||||
gzip could be smaller; size after gzip insignificantly larger).
|
gzip could be smaller; size after gzip insignificantly larger).
|
||||||
|
|
||||||
- `shebang` (default `true`) -- preserve shebang `#!` in preamble (bash scripts)
|
- `shebang` (default: `true`) — preserve shebang `#!` in preamble (bash scripts)
|
||||||
|
|
||||||
- `width` (default `80`) -- only takes effect when beautification is on, this
|
- `width` (default: `80`) — only takes effect when beautification is on, this
|
||||||
specifies an (orientative) line width that the beautifier will try to
|
specifies an (orientative) line width that the beautifier will try to
|
||||||
obey. It refers to the width of the line text (excluding indentation).
|
obey. It refers to the width of the line text (excluding indentation).
|
||||||
It doesn't work very well currently, but it does make the code generated
|
It doesn't work very well currently, but it does make the code generated
|
||||||
by UglifyJS more readable.
|
by UglifyJS more readable.
|
||||||
|
|
||||||
- `wrap_iife` (default `false`) -- pass `true` to wrap immediately invoked
|
- `wrap_iife` (default: `false`) — pass `true` to wrap immediately invoked
|
||||||
function expressions. See
|
function expressions. See
|
||||||
[#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
|
[#640](https://github.com/mishoo/UglifyJS/issues/640) for more details.
|
||||||
|
|
||||||
@@ -1135,18 +1156,14 @@ in total it's a bit more than just using UglifyJS's own parser.
|
|||||||
It's not well known, but whitespace removal and symbol mangling accounts
|
It's not well known, but whitespace removal and symbol mangling accounts
|
||||||
for 95% of the size reduction in minified code for most JavaScript - not
|
for 95% of the size reduction in minified code for most JavaScript - not
|
||||||
elaborate code transforms. One can simply disable `compress` to speed up
|
elaborate code transforms. One can simply disable `compress` to speed up
|
||||||
Uglify builds by 3 to 4 times. In this fast `mangle`-only mode Uglify has
|
Uglify builds by 3 to 5 times.
|
||||||
comparable minify speeds and gzip sizes to
|
|
||||||
[`butternut`](https://www.npmjs.com/package/butternut):
|
|
||||||
|
|
||||||
| d3.js | minify size | gzip size | minify time (seconds) |
|
| d3.js | minify size | gzip size | minify time (seconds) |
|
||||||
| --- | ---: | ---: | ---: |
|
| --- | ---: | ---: | ---: |
|
||||||
| original | 451,131 | 108,733 | - |
|
| original | 511,371 | 119,932 | - |
|
||||||
| uglify-js@3.0.24 mangle=false, compress=false | 316,600 | 85,245 | 0.70 |
|
| uglify-js@3.13.0 mangle=false, compress=false | 363,988 | 95,695 | 0.56 |
|
||||||
| uglify-js@3.0.24 mangle=true, compress=false | 220,216 | 72,730 | 1.13 |
|
| uglify-js@3.13.0 mangle=true, compress=false | 253,305 | 81,281 | 0.99 |
|
||||||
| butternut@0.4.6 | 217,568 | 72,738 | 1.41 |
|
| uglify-js@3.13.0 mangle=true, compress=true | 244,436 | 79,854 | 5.30 |
|
||||||
| uglify-js@3.0.24 mangle=true, compress=true | 212,511 | 71,560 | 3.36 |
|
|
||||||
| babili@0.1.4 | 210,713 | 72,140 | 12.64 |
|
|
||||||
|
|
||||||
To enable fast minify mode from the CLI use:
|
To enable fast minify mode from the CLI use:
|
||||||
```
|
```
|
||||||
@@ -1270,3 +1287,43 @@ To allow for better optimizations, the compiler makes various assumptions:
|
|||||||
// SyntaxError: Invalid Unicode escape sequence
|
// SyntaxError: Invalid Unicode escape sequence
|
||||||
```
|
```
|
||||||
UglifyJS may modify the input which in turn may suppress those errors.
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Some versions of JavaScript will throw `SyntaxError` with the
|
||||||
|
following:
|
||||||
|
```javascript
|
||||||
|
try {} catch (e) {
|
||||||
|
for (var e of []);
|
||||||
|
}
|
||||||
|
// SyntaxError: Identifier 'e' has already been declared
|
||||||
|
```
|
||||||
|
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
|
||||||
|
console.log({
|
||||||
|
...{
|
||||||
|
set 42(v) {},
|
||||||
|
42: "PASS",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
// Expected: { '42': 'PASS' }
|
||||||
|
// Actual: { '42': undefined }
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
|
```javascript
|
||||||
|
var await;
|
||||||
|
async function f() {
|
||||||
|
class A {
|
||||||
|
static p = await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// SyntaxError: Unexpected reserved word
|
||||||
|
```
|
||||||
|
UglifyJS may modify the input which in turn may suppress those errors.
|
||||||
|
- Later versions of JavaScript will throw `SyntaxError` with the following:
|
||||||
|
```javascript
|
||||||
|
var async;
|
||||||
|
for (async of []);
|
||||||
|
// 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.
|
||||||
|
|||||||
103
bin/uglifyjs
103
bin/uglifyjs
@@ -10,7 +10,7 @@ var info = require("../package.json");
|
|||||||
var path = require("path");
|
var path = require("path");
|
||||||
var UglifyJS = require("../tools/node");
|
var UglifyJS = require("../tools/node");
|
||||||
|
|
||||||
var skip_keys = [ "cname", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
var skip_keys = [ "cname", "fixed", "inlined", "parent_scope", "scope", "uses_eval", "uses_with" ];
|
||||||
var files = {};
|
var files = {};
|
||||||
var options = {};
|
var options = {};
|
||||||
var short_forms = {
|
var short_forms = {
|
||||||
@@ -95,6 +95,8 @@ function process_option(name, no_value) {
|
|||||||
" -b, --beautify [options] Beautify output/specify output options.",
|
" -b, --beautify [options] Beautify output/specify output options.",
|
||||||
" -O, --output-opts <options> Output options (beautify disabled).",
|
" -O, --output-opts <options> Output options (beautify disabled).",
|
||||||
" -o, --output <file> Output file (default STDOUT).",
|
" -o, --output <file> Output file (default STDOUT).",
|
||||||
|
" --annotations Process and preserve comment annotations.",
|
||||||
|
" --no-annotations Ignore and discard comment annotations.",
|
||||||
" --comments [filter] Preserve copyright comments in the output.",
|
" --comments [filter] Preserve copyright comments in the output.",
|
||||||
" --config-file <file> Read minify() options from JSON file.",
|
" --config-file <file> Read minify() options from JSON file.",
|
||||||
" -d, --define <expr>[=value] Global definitions.",
|
" -d, --define <expr>[=value] Global definitions.",
|
||||||
@@ -113,6 +115,9 @@ function process_option(name, no_value) {
|
|||||||
" --warn Print warning messages.",
|
" --warn Print warning messages.",
|
||||||
" --webkit Support non-standard Safari/Webkit.",
|
" --webkit Support non-standard Safari/Webkit.",
|
||||||
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
|
" --wrap <name> Embed everything as a function with “exports” corresponding to “name” globally.",
|
||||||
|
"",
|
||||||
|
"(internal debug use only)",
|
||||||
|
" --in-situ Warning: replaces original source files with minified output.",
|
||||||
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
|
" --reduce-test Reduce a standalone test case (assumes cloned repository).",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
}
|
}
|
||||||
@@ -139,6 +144,7 @@ function process_option(name, no_value) {
|
|||||||
case "enclose":
|
case "enclose":
|
||||||
options[name] = read_value();
|
options[name] = read_value();
|
||||||
break;
|
break;
|
||||||
|
case "annotations":
|
||||||
case "ie8":
|
case "ie8":
|
||||||
case "timings":
|
case "timings":
|
||||||
case "toplevel":
|
case "toplevel":
|
||||||
@@ -146,6 +152,9 @@ function process_option(name, no_value) {
|
|||||||
case "webkit":
|
case "webkit":
|
||||||
options[name] = true;
|
options[name] = true;
|
||||||
break;
|
break;
|
||||||
|
case "no-annotations":
|
||||||
|
options.annotations = false;
|
||||||
|
break;
|
||||||
case "keep-fnames":
|
case "keep-fnames":
|
||||||
options.keep_fnames = true;
|
options.keep_fnames = true;
|
||||||
break;
|
break;
|
||||||
@@ -194,6 +203,7 @@ function process_option(name, no_value) {
|
|||||||
case "no-rename":
|
case "no-rename":
|
||||||
options.rename = false;
|
options.rename = false;
|
||||||
break;
|
break;
|
||||||
|
case "in-situ":
|
||||||
case "reduce-test":
|
case "reduce-test":
|
||||||
case "self":
|
case "self":
|
||||||
break;
|
break;
|
||||||
@@ -225,10 +235,11 @@ if (options.mangle && options.mangle.properties) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (output == "ast") options.output = {
|
if (/^ast|spidermonkey$/.test(output)) {
|
||||||
ast: true,
|
if (typeof options.output != "object") options.output = {};
|
||||||
code: false,
|
options.output.ast = true;
|
||||||
};
|
options.output.code = false;
|
||||||
|
}
|
||||||
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
|
if (options.parse && (options.parse.acorn || options.parse.spidermonkey)
|
||||||
&& options.sourceMap && options.sourceMap.content == "inline") {
|
&& options.sourceMap && options.sourceMap.content == "inline") {
|
||||||
fatal("inline source map only works with built-in parser");
|
fatal("inline source map only works with built-in parser");
|
||||||
@@ -254,15 +265,32 @@ if (specified["self"]) {
|
|||||||
if (!options.wrap) options.wrap = "UglifyJS";
|
if (!options.wrap) options.wrap = "UglifyJS";
|
||||||
paths = UglifyJS.FILES;
|
paths = UglifyJS.FILES;
|
||||||
}
|
}
|
||||||
if (paths.length) {
|
if (specified["in-situ"]) {
|
||||||
|
if (output && output != "spidermonkey" || specified["reduce-test"] || specified["self"]) {
|
||||||
|
fatal("incompatible options specified");
|
||||||
|
}
|
||||||
|
paths.forEach(function(name) {
|
||||||
|
print(name);
|
||||||
|
if (/^ast|spidermonkey$/.test(name)) fatal("invalid file name specified");
|
||||||
|
files = {};
|
||||||
|
files[convert_path(name)] = read_file(name);
|
||||||
|
output = name;
|
||||||
|
run();
|
||||||
|
});
|
||||||
|
} else if (paths.length) {
|
||||||
simple_glob(paths).forEach(function(name) {
|
simple_glob(paths).forEach(function(name) {
|
||||||
files[convert_path(name)] = read_file(name);
|
files[convert_path(name)] = read_file(name);
|
||||||
});
|
});
|
||||||
run();
|
run();
|
||||||
} else {
|
} else {
|
||||||
|
var timerId = process.stdin.isTTY && process.argv.length < 3 && setTimeout(function() {
|
||||||
|
print_error("Waiting for input... (use `--help` to print usage information)");
|
||||||
|
}, 1500);
|
||||||
var chunks = [];
|
var chunks = [];
|
||||||
process.stdin.setEncoding("utf8");
|
process.stdin.setEncoding("utf8");
|
||||||
process.stdin.on("data", function(chunk) {
|
process.stdin.once("data", function() {
|
||||||
|
clearTimeout(timerId);
|
||||||
|
}).on("data", function(chunk) {
|
||||||
chunks.push(chunk);
|
chunks.push(chunk);
|
||||||
}).on("end", function() {
|
}).on("end", function() {
|
||||||
files = { STDIN: chunks.join("") };
|
files = { STDIN: chunks.join("") };
|
||||||
@@ -286,13 +314,43 @@ function run() {
|
|||||||
try {
|
try {
|
||||||
if (options.parse) {
|
if (options.parse) {
|
||||||
if (options.parse.acorn) {
|
if (options.parse.acorn) {
|
||||||
|
var annotations = Object.create(null);
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
return require("acorn").parse(files[name], {
|
var content = files[name];
|
||||||
|
var list = annotations[name] = [];
|
||||||
|
var prev = -1;
|
||||||
|
return require("acorn").parse(content, {
|
||||||
|
allowHashBang: true,
|
||||||
|
ecmaVersion: "latest",
|
||||||
locations: true,
|
locations: true,
|
||||||
|
onComment: function(block, text, start, end) {
|
||||||
|
var match = /[@#]__PURE__/.exec(text);
|
||||||
|
if (!match) {
|
||||||
|
if (start != prev) return;
|
||||||
|
match = [ list[prev] ];
|
||||||
|
}
|
||||||
|
while (/\s/.test(content[end])) end++;
|
||||||
|
list[end] = match[0];
|
||||||
|
prev = end;
|
||||||
|
},
|
||||||
|
preserveParens: true,
|
||||||
program: toplevel,
|
program: toplevel,
|
||||||
sourceFile: name
|
sourceFile: name,
|
||||||
|
sourceType: "module",
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
files.walk(new UglifyJS.TreeWalker(function(node) {
|
||||||
|
if (!(node instanceof UglifyJS.AST_Call)) return;
|
||||||
|
var list = annotations[node.start.file];
|
||||||
|
var pure = list[node.start.pos];
|
||||||
|
if (!pure) {
|
||||||
|
var pos = node.start.parens;
|
||||||
|
if (pos) for (var i = 0; !pure && i < pos.length; i++) {
|
||||||
|
pure = list[pos[i]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pure) node.pure = pure;
|
||||||
|
}));
|
||||||
} else if (options.parse.spidermonkey) {
|
} else if (options.parse.spidermonkey) {
|
||||||
files = convert_ast(function(toplevel, name) {
|
files = convert_ast(function(toplevel, name) {
|
||||||
var obj = JSON.parse(files[name]);
|
var obj = JSON.parse(files[name]);
|
||||||
@@ -360,14 +418,14 @@ function run() {
|
|||||||
}
|
}
|
||||||
print(JSON.stringify(result.ast, function(key, value) {
|
print(JSON.stringify(result.ast, function(key, value) {
|
||||||
if (value) switch (key) {
|
if (value) switch (key) {
|
||||||
case "thedef":
|
|
||||||
return symdef(value);
|
|
||||||
case "enclosed":
|
case "enclosed":
|
||||||
return value.length ? value.map(symdef) : undefined;
|
return value.length ? value.map(symdef) : undefined;
|
||||||
case "variables":
|
|
||||||
case "functions":
|
case "functions":
|
||||||
case "globals":
|
case "globals":
|
||||||
|
case "variables":
|
||||||
return value.size() ? value.map(symdef) : undefined;
|
return value.size() ? value.map(symdef) : undefined;
|
||||||
|
case "thedef":
|
||||||
|
return symdef(value);
|
||||||
}
|
}
|
||||||
if (skip_key(key)) return;
|
if (skip_key(key)) return;
|
||||||
if (value instanceof UglifyJS.AST_Token) return;
|
if (value instanceof UglifyJS.AST_Token) return;
|
||||||
@@ -384,16 +442,19 @@ function run() {
|
|||||||
return value;
|
return value;
|
||||||
}, 2));
|
}, 2));
|
||||||
} else if (output == "spidermonkey") {
|
} else if (output == "spidermonkey") {
|
||||||
print(JSON.stringify(UglifyJS.minify(result.code, {
|
print(JSON.stringify(result.ast.to_mozilla_ast(), null, 2));
|
||||||
compress: false,
|
|
||||||
mangle: false,
|
|
||||||
output: {
|
|
||||||
ast: true,
|
|
||||||
code: false
|
|
||||||
},
|
|
||||||
}).ast.to_mozilla_ast(), null, 2));
|
|
||||||
} else if (output) {
|
} else if (output) {
|
||||||
fs.writeFileSync(output, result.code);
|
var code;
|
||||||
|
if (result.ast) {
|
||||||
|
var opts = {};
|
||||||
|
for (var name in options.output) {
|
||||||
|
if (!/^ast|code$/.test(name)) opts[name] = options.output[name];
|
||||||
|
}
|
||||||
|
code = UglifyJS.AST_Node.from_mozilla_ast(result.ast.to_mozilla_ast()).print_to_string(opts);
|
||||||
|
} else {
|
||||||
|
code = result.code;
|
||||||
|
}
|
||||||
|
fs.writeFileSync(output, code);
|
||||||
if (result.map) fs.writeFileSync(output + ".map", result.map);
|
if (result.map) fs.writeFileSync(output + ".map", result.map);
|
||||||
} else {
|
} else {
|
||||||
print(result.code);
|
print(result.code);
|
||||||
|
|||||||
569
lib/ast.js
569
lib/ast.js
@@ -55,9 +55,10 @@ function DEFNODE(type, props, methods, base) {
|
|||||||
props.forEach(function(prop) {
|
props.forEach(function(prop) {
|
||||||
code.push("this.", prop, "=props.", prop, ";");
|
code.push("this.", prop, "=props.", prop, ";");
|
||||||
});
|
});
|
||||||
|
code.push("}");
|
||||||
var proto = base && new base;
|
var proto = base && new base;
|
||||||
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
if (proto && proto.initialize || methods && methods.initialize) code.push("this.initialize();");
|
||||||
code.push("}}");
|
code.push("}");
|
||||||
var ctor = new Function(code.join(""))();
|
var ctor = new Function(code.join(""))();
|
||||||
if (proto) {
|
if (proto) {
|
||||||
ctor.prototype = proto;
|
ctor.prototype = proto;
|
||||||
@@ -113,7 +114,9 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
},
|
},
|
||||||
_validate: noop,
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Node") throw new Error("should not instantiate AST_Node");
|
||||||
|
},
|
||||||
validate: function() {
|
validate: function() {
|
||||||
var ctor = this.CTOR;
|
var ctor = this.CTOR;
|
||||||
do {
|
do {
|
||||||
@@ -137,7 +140,7 @@ var AST_Node = DEFNODE("Node", "start end", {
|
|||||||
}, null);
|
}, null);
|
||||||
|
|
||||||
(AST_Node.log_function = function(fn, verbose) {
|
(AST_Node.log_function = function(fn, verbose) {
|
||||||
if (!fn) {
|
if (typeof fn != "function") {
|
||||||
AST_Node.info = AST_Node.warn = noop;
|
AST_Node.info = AST_Node.warn = noop;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -187,19 +190,26 @@ AST_Node.disable_validation = function() {
|
|||||||
|
|
||||||
var AST_Statement = DEFNODE("Statement", null, {
|
var AST_Statement = DEFNODE("Statement", null, {
|
||||||
$documentation: "Base class of all statements",
|
$documentation: "Base class of all statements",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Statement") throw new Error("should not instantiate AST_Statement");
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_Debugger = DEFNODE("Debugger", null, {
|
var AST_Debugger = DEFNODE("Debugger", null, {
|
||||||
$documentation: "Represents a debugger statement",
|
$documentation: "Represents a debugger statement",
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Directive = DEFNODE("Directive", "value quote", {
|
var AST_Directive = DEFNODE("Directive", "quote value", {
|
||||||
$documentation: "Represents a directive, like \"use strict\";",
|
$documentation: "Represents a directive, like \"use strict\";",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
quote: "[string?] the original quote character",
|
||||||
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
|
||||||
quote: "[string] the original quote character"
|
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
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 (typeof this.value != "string") throw new Error("value must be string");
|
if (typeof this.value != "string") throw new Error("value must be string");
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -208,6 +218,12 @@ 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)"
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
|
function is_statement(node) {
|
||||||
|
return node instanceof AST_Statement
|
||||||
|
&& !(node instanceof AST_ClassExpression)
|
||||||
|
&& !(node instanceof AST_LambdaExpression);
|
||||||
|
}
|
||||||
|
|
||||||
function validate_expression(value, prop, multiple, allow_spread, allow_hole) {
|
function validate_expression(value, prop, multiple, allow_spread, allow_hole) {
|
||||||
multiple = multiple ? "contain" : "be";
|
multiple = multiple ? "contain" : "be";
|
||||||
if (!(value instanceof AST_Node)) throw new Error(prop + " must " + multiple + " AST_Node");
|
if (!(value instanceof AST_Node)) throw new Error(prop + " must " + multiple + " AST_Node");
|
||||||
@@ -215,9 +231,7 @@ function validate_expression(value, prop, multiple, allow_spread, allow_hole) {
|
|||||||
if (value instanceof AST_Destructured) throw new Error(prop + " cannot " + multiple + " AST_Destructured");
|
if (value instanceof AST_Destructured) throw new Error(prop + " cannot " + multiple + " AST_Destructured");
|
||||||
if (value instanceof AST_Hole && !allow_hole) throw new Error(prop + " cannot " + multiple + " AST_Hole");
|
if (value instanceof AST_Hole && !allow_hole) throw new Error(prop + " cannot " + multiple + " AST_Hole");
|
||||||
if (value instanceof AST_Spread && !allow_spread) throw new Error(prop + " cannot " + multiple + " AST_Spread");
|
if (value instanceof AST_Spread && !allow_spread) throw new Error(prop + " cannot " + multiple + " AST_Spread");
|
||||||
if (value instanceof AST_Statement && !is_function(value)) {
|
if (is_statement(value)) throw new Error(prop + " cannot " + multiple + " AST_Statement");
|
||||||
throw new Error(prop + " cannot " + multiple + " AST_Statement");
|
|
||||||
}
|
|
||||||
if (value instanceof AST_SymbolDeclaration) {
|
if (value instanceof AST_SymbolDeclaration) {
|
||||||
throw new Error(prop + " cannot " + multiple + " AST_SymbolDeclaration");
|
throw new Error(prop + " cannot " + multiple + " AST_SymbolDeclaration");
|
||||||
}
|
}
|
||||||
@@ -230,7 +244,7 @@ function must_be_expression(node, prop) {
|
|||||||
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", {
|
||||||
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
|
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)"
|
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -247,9 +261,9 @@ var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_s
|
|||||||
$documentation: "Base class for all statements introducing a lexical scope",
|
$documentation: "Base class for all statements introducing a lexical scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
|
||||||
functions: "[Object/S] like `variables`, but only lists function declarations",
|
functions: "[Dictionary/S] like `variables`, but only lists function declarations",
|
||||||
parent_scope: "[AST_Scope?/S] link to the parent scope",
|
parent_scope: "[AST_Scope?/S] link to the parent scope",
|
||||||
variables: "[Object/S] a map of name ---> SymbolDef for all variables/functions defined in this scope",
|
variables: "[Dictionary/S] a map of name ---> SymbolDef for all variables/functions defined in this scope",
|
||||||
},
|
},
|
||||||
clone: function(deep) {
|
clone: function(deep) {
|
||||||
var node = this._clone(deep);
|
var node = this._clone(deep);
|
||||||
@@ -265,6 +279,7 @@ var AST_BlockScope = DEFNODE("BlockScope", "enclosed functions make_def parent_s
|
|||||||
return this.parent_scope.resolve();
|
return this.parent_scope.resolve();
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "BlockScope") throw new Error("should not instantiate AST_BlockScope");
|
||||||
if (this.parent_scope == null) return;
|
if (this.parent_scope == null) return;
|
||||||
if (!(this.parent_scope instanceof AST_BlockScope)) throw new Error("parent_scope must be AST_BlockScope");
|
if (!(this.parent_scope instanceof AST_BlockScope)) throw new Error("parent_scope must be AST_BlockScope");
|
||||||
if (!(this.resolve() instanceof AST_Scope)) throw new Error("must be contained within AST_Scope");
|
if (!(this.resolve() instanceof AST_Scope)) throw new Error("must be contained within AST_Scope");
|
||||||
@@ -289,9 +304,9 @@ var AST_Block = DEFNODE("Block", "body", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Block") throw new Error("should not instantiate AST_Block");
|
||||||
this.body.forEach(function(node) {
|
this.body.forEach(function(node) {
|
||||||
if (!(node instanceof AST_Statement)) throw new Error("body must be AST_Statement[]");
|
if (!is_statement(node)) throw new Error("body must contain AST_Statement");
|
||||||
if (is_function(node)) throw new Error("body cannot contain AST_Function");
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
}, AST_BlockScope);
|
}, AST_BlockScope);
|
||||||
@@ -306,8 +321,8 @@ var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
|
|||||||
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.body instanceof AST_Statement)) throw new Error("body must be AST_Statement");
|
if (this.TYPE == "StatementWithBody") throw new Error("should not instantiate AST_StatementWithBody");
|
||||||
if (is_function(this.body)) throw new Error("body cannot be AST_Function");
|
if (!is_statement(this.body)) throw new Error("body must be AST_Statement");
|
||||||
},
|
},
|
||||||
}, AST_BlockScope);
|
}, AST_BlockScope);
|
||||||
|
|
||||||
@@ -346,7 +361,10 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
|
|||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
var AST_IterationStatement = DEFNODE("IterationStatement", null, {
|
var AST_IterationStatement = DEFNODE("IterationStatement", null, {
|
||||||
$documentation: "Internal class. All loops inherit from it."
|
$documentation: "Internal class. All loops inherit from it.",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "IterationStatement") throw new Error("should not instantiate AST_IterationStatement");
|
||||||
|
},
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
|
|
||||||
var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
||||||
@@ -355,6 +373,7 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
|
|||||||
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement"
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "DWLoop") throw new Error("should not instantiate AST_DWLoop");
|
||||||
must_be_expression(this, "condition");
|
must_be_expression(this, "condition");
|
||||||
},
|
},
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
@@ -400,8 +419,7 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.init != null) {
|
if (this.init != null) {
|
||||||
if (!(this.init instanceof AST_Node)) throw new Error("init must be AST_Node");
|
if (!(this.init instanceof AST_Node)) throw new Error("init must be AST_Node");
|
||||||
if (this.init instanceof AST_Statement
|
if (is_statement(this.init) && !(this.init instanceof AST_Definitions)) {
|
||||||
&& !(this.init instanceof AST_Definitions || is_function(this.init))) {
|
|
||||||
throw new Error("init cannot be AST_Statement");
|
throw new Error("init cannot be AST_Statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -410,11 +428,11 @@ var AST_For = DEFNODE("For", "init condition step", {
|
|||||||
},
|
},
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
|
|
||||||
var AST_ForIn = DEFNODE("ForIn", "init object", {
|
var AST_ForEnumeration = DEFNODE("ForEnumeration", "init object", {
|
||||||
$documentation: "A `for ... in` statement",
|
$documentation: "Base class for enumeration loops, i.e. `for ... in`, `for ... of` & `for await ... of`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
init: "[AST_Node] the `for/in` initialization code",
|
init: "[AST_Node] the assignment target during iteration",
|
||||||
object: "[AST_Node] the object that we're looping through"
|
object: "[AST_Node] the object to iterate over"
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -425,6 +443,7 @@ var AST_ForIn = DEFNODE("ForIn", "init object", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "ForEnumeration") throw new Error("should not instantiate AST_ForEnumeration");
|
||||||
if (this.init instanceof AST_Definitions) {
|
if (this.init instanceof AST_Definitions) {
|
||||||
if (this.init.definitions.length != 1) throw new Error("init must have single declaration");
|
if (this.init.definitions.length != 1) throw new Error("init must have single declaration");
|
||||||
} else {
|
} else {
|
||||||
@@ -438,6 +457,18 @@ var AST_ForIn = DEFNODE("ForIn", "init object", {
|
|||||||
},
|
},
|
||||||
}, AST_IterationStatement);
|
}, AST_IterationStatement);
|
||||||
|
|
||||||
|
var AST_ForIn = DEFNODE("ForIn", null, {
|
||||||
|
$documentation: "A `for ... in` statement",
|
||||||
|
}, AST_ForEnumeration);
|
||||||
|
|
||||||
|
var AST_ForOf = DEFNODE("ForOf", null, {
|
||||||
|
$documentation: "A `for ... of` statement",
|
||||||
|
}, AST_ForEnumeration);
|
||||||
|
|
||||||
|
var AST_ForAwaitOf = DEFNODE("ForAwaitOf", null, {
|
||||||
|
$documentation: "A `for await ... of` statement",
|
||||||
|
}, AST_ForOf);
|
||||||
|
|
||||||
var AST_With = DEFNODE("With", "expression", {
|
var AST_With = DEFNODE("With", "expression", {
|
||||||
$documentation: "A `with` statement",
|
$documentation: "A `with` statement",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
@@ -467,12 +498,15 @@ var AST_Scope = DEFNODE("Scope", "uses_eval uses_with", {
|
|||||||
return this.uses_eval || this.uses_with;
|
return this.uses_eval || this.uses_with;
|
||||||
},
|
},
|
||||||
resolve: return_this,
|
resolve: return_this,
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Scope") throw new Error("should not instantiate AST_Scope");
|
||||||
|
},
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
var AST_Toplevel = DEFNODE("Toplevel", "globals", {
|
||||||
$documentation: "The toplevel scope",
|
$documentation: "The toplevel scope",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
globals: "[Object/S] a map of name ---> SymbolDef for all undeclared names",
|
globals: "[Dictionary/S] a map of name ---> SymbolDef for all undeclared names",
|
||||||
},
|
},
|
||||||
wrap: function(name) {
|
wrap: function(name) {
|
||||||
var body = this.body;
|
var body = this.body;
|
||||||
@@ -517,8 +551,9 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
|||||||
$documentation: "Base class for functions",
|
$documentation: "Base class for functions",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
argnames: "[(AST_DefaultValue|AST_Destructured|AST_SymbolFunarg)*] array of function arguments and/or destructured literals",
|
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",
|
rest: "[(AST_Destructured|AST_SymbolFunarg)?] rest parameter, or null if absent",
|
||||||
uses_arguments: "[boolean/S] tells whether this function accesses the arguments array",
|
uses_arguments: "[boolean/S] whether this function accesses the arguments array",
|
||||||
},
|
},
|
||||||
each_argname: function(visit) {
|
each_argname: function(visit) {
|
||||||
var tw = new TreeWalker(function(node) {
|
var tw = new TreeWalker(function(node) {
|
||||||
@@ -549,6 +584,7 @@ var AST_Lambda = DEFNODE("Lambda", "argnames length_read rest uses_arguments", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Lambda") throw new Error("should not instantiate AST_Lambda");
|
||||||
this.argnames.forEach(function(node) {
|
this.argnames.forEach(function(node) {
|
||||||
validate_destructured(node, function(node) {
|
validate_destructured(node, function(node) {
|
||||||
if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]");
|
if (!(node instanceof AST_SymbolFunarg)) throw new Error("argnames must be AST_SymbolFunarg[]");
|
||||||
@@ -567,12 +603,33 @@ var AST_Accessor = DEFNODE("Accessor", null, {
|
|||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
|
var AST_LambdaExpression = DEFNODE("LambdaExpression", "inlined", {
|
||||||
|
$documentation: "Base class for function expressions",
|
||||||
|
$propdoc: {
|
||||||
|
inlined: "[boolean/S] whether this function has been inlined",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "LambdaExpression") throw new Error("should not instantiate AST_LambdaExpression");
|
||||||
|
},
|
||||||
|
}, AST_Lambda);
|
||||||
|
|
||||||
function is_arrow(node) {
|
function is_arrow(node) {
|
||||||
return node instanceof AST_AsyncArrow || node instanceof AST_Arrow;
|
return node instanceof AST_Arrow || node instanceof AST_AsyncArrow;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_function(node) {
|
function is_async(node) {
|
||||||
return is_arrow(node) || node instanceof AST_AsyncFunction || node instanceof AST_Function;
|
return node instanceof AST_AsyncArrow
|
||||||
|
|| node instanceof AST_AsyncDefun
|
||||||
|
|| node instanceof AST_AsyncFunction
|
||||||
|
|| node instanceof AST_AsyncGeneratorDefun
|
||||||
|
|| node instanceof AST_AsyncGeneratorFunction;
|
||||||
|
}
|
||||||
|
|
||||||
|
function is_generator(node) {
|
||||||
|
return node instanceof AST_AsyncGeneratorDefun
|
||||||
|
|| node instanceof AST_AsyncGeneratorFunction
|
||||||
|
|| node instanceof AST_GeneratorDefun
|
||||||
|
|| node instanceof AST_GeneratorFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
function walk_lambda(node, tw) {
|
function walk_lambda(node, tw) {
|
||||||
@@ -583,7 +640,7 @@ function walk_lambda(node, tw) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_Arrow = DEFNODE("Arrow", "inlined value", {
|
var AST_Arrow = DEFNODE("Arrow", "value", {
|
||||||
$documentation: "An arrow function expression",
|
$documentation: "An arrow function expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[AST_Node?] simple return expression, or null if using function body.",
|
value: "[AST_Node?] simple return expression, or null if using function body.",
|
||||||
@@ -610,13 +667,9 @@ var AST_Arrow = DEFNODE("Arrow", "inlined value", {
|
|||||||
if (this.body.length) throw new Error("body must be empty if value exists");
|
if (this.body.length) throw new Error("body must be empty if value exists");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
function is_async(node) {
|
var AST_AsyncArrow = DEFNODE("AsyncArrow", "value", {
|
||||||
return node instanceof AST_AsyncArrow || node instanceof AST_AsyncDefun || node instanceof AST_AsyncFunction;
|
|
||||||
}
|
|
||||||
|
|
||||||
var AST_AsyncArrow = DEFNODE("AsyncArrow", "inlined value", {
|
|
||||||
$documentation: "An asynchronous arrow function expression",
|
$documentation: "An asynchronous arrow function expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
value: "[AST_Node?] simple return expression, or null if using function body.",
|
value: "[AST_Node?] simple return expression, or null if using function body.",
|
||||||
@@ -643,60 +696,197 @@ var AST_AsyncArrow = DEFNODE("AsyncArrow", "inlined value", {
|
|||||||
if (this.body.length) throw new Error("body must be empty if value exists");
|
if (this.body.length) throw new Error("body must be empty if value exists");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
var AST_AsyncFunction = DEFNODE("AsyncFunction", "inlined name", {
|
var AST_AsyncFunction = DEFNODE("AsyncFunction", "name", {
|
||||||
$documentation: "An asynchronous function expression",
|
$documentation: "An asynchronous function expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolLambda?] the name of this function",
|
name: "[AST_SymbolLambda?] the name of this function, or null if not specified",
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.name != null) {
|
if (this.name != null) {
|
||||||
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
var AST_Function = DEFNODE("Function", "inlined name", {
|
var AST_AsyncGeneratorFunction = DEFNODE("AsyncGeneratorFunction", "name", {
|
||||||
|
$documentation: "An asynchronous generator function expression",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolLambda?] the name of this function, or null if not specified",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) {
|
||||||
|
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
|
var AST_Function = DEFNODE("Function", "name", {
|
||||||
$documentation: "A function expression",
|
$documentation: "A function expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolLambda?] the name of this function",
|
name: "[AST_SymbolLambda?] the name of this function, or null if not specified",
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.name != null) {
|
if (this.name != null) {
|
||||||
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
|
var AST_GeneratorFunction = DEFNODE("GeneratorFunction", "name", {
|
||||||
|
$documentation: "A generator function expression",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolLambda?] the name of this function, or null if not specified",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) {
|
||||||
|
if (!(this.name instanceof AST_SymbolLambda)) throw new Error("name must be AST_SymbolLambda");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_LambdaExpression);
|
||||||
|
|
||||||
|
var AST_LambdaDefinition = DEFNODE("LambdaDefinition", "inlined name", {
|
||||||
|
$documentation: "Base class for function definitions",
|
||||||
|
$propdoc: {
|
||||||
|
inlined: "[boolean/S] whether this function has been inlined",
|
||||||
|
name: "[AST_SymbolDefun] the name of this function",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "LambdaDefinition") throw new Error("should not instantiate AST_LambdaDefinition");
|
||||||
|
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
||||||
|
},
|
||||||
}, AST_Lambda);
|
}, AST_Lambda);
|
||||||
|
|
||||||
function is_defun(node) {
|
var AST_AsyncDefun = DEFNODE("AsyncDefun", null, {
|
||||||
return node instanceof AST_AsyncDefun || node instanceof AST_Defun;
|
|
||||||
}
|
|
||||||
|
|
||||||
var AST_AsyncDefun = DEFNODE("AsyncDefun", "inlined name", {
|
|
||||||
$documentation: "An asynchronous function definition",
|
$documentation: "An asynchronous function definition",
|
||||||
$propdoc: {
|
}, AST_LambdaDefinition);
|
||||||
name: "[AST_SymbolDefun] the name of this function",
|
|
||||||
},
|
|
||||||
_validate: function() {
|
|
||||||
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
|
||||||
},
|
|
||||||
}, AST_Lambda);
|
|
||||||
|
|
||||||
var AST_Defun = DEFNODE("Defun", "inlined name", {
|
var AST_AsyncGeneratorDefun = DEFNODE("AsyncGeneratorDefun", null, {
|
||||||
|
$documentation: "An asynchronous generator function definition",
|
||||||
|
}, AST_LambdaDefinition);
|
||||||
|
|
||||||
|
var AST_Defun = DEFNODE("Defun", null, {
|
||||||
$documentation: "A function definition",
|
$documentation: "A function definition",
|
||||||
|
}, AST_LambdaDefinition);
|
||||||
|
|
||||||
|
var AST_GeneratorDefun = DEFNODE("GeneratorDefun", null, {
|
||||||
|
$documentation: "A generator function definition",
|
||||||
|
}, AST_LambdaDefinition);
|
||||||
|
|
||||||
|
/* -----[ classes ]----- */
|
||||||
|
|
||||||
|
var AST_Class = DEFNODE("Class", "extends name properties", {
|
||||||
|
$documentation: "Base class for class literals",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
name: "[AST_SymbolDefun] the name of this function",
|
extends: "[AST_Node?] the super class, or null if not specified",
|
||||||
|
properties: "[AST_ClassProperty*] array of class properties",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
if (node.name) node.name.walk(visitor);
|
||||||
|
if (node.extends) node.extends.walk(visitor);
|
||||||
|
node.properties.forEach(function(prop) {
|
||||||
|
prop.walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (!(this.name instanceof AST_SymbolDefun)) throw new Error("name must be AST_SymbolDefun");
|
if (this.TYPE == "Class") throw new Error("should not instantiate AST_Class");
|
||||||
|
if (this.extends != null) must_be_expression(this, "extends");
|
||||||
|
this.properties.forEach(function(node) {
|
||||||
|
if (!(node instanceof AST_ClassProperty)) throw new Error("properties must contain AST_ClassProperty");
|
||||||
|
});
|
||||||
},
|
},
|
||||||
}, AST_Lambda);
|
}, AST_BlockScope);
|
||||||
|
|
||||||
|
var AST_DefClass = DEFNODE("DefClass", null, {
|
||||||
|
$documentation: "A class definition",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolDefClass] the name of this class",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.name instanceof AST_SymbolDefClass)) throw new Error("name must be AST_SymbolDefClass");
|
||||||
|
},
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
|
var AST_ClassExpression = DEFNODE("ClassExpression", null, {
|
||||||
|
$documentation: "A class expression",
|
||||||
|
$propdoc: {
|
||||||
|
name: "[AST_SymbolClass?] the name of this class, or null if not specified",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name != null) {
|
||||||
|
if (!(this.name instanceof AST_SymbolClass)) throw new Error("name must be AST_SymbolClass");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Class);
|
||||||
|
|
||||||
|
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)",
|
||||||
|
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)",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
if (node.key instanceof AST_Node) node.key.walk(visitor);
|
||||||
|
if (node.value) node.value.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "ClassProperty") throw new Error("should not instantiate AST_ClassProperty");
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
if(this.value != null) {
|
||||||
|
if (!(this.value instanceof AST_Node)) throw new Error("value must be AST_Node");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
var AST_ClassField = DEFNODE("ClassField", null, {
|
||||||
|
$documentation: "A `class` field",
|
||||||
|
_validate: function() {
|
||||||
|
if(this.value != null) must_be_expression(this, "value");
|
||||||
|
},
|
||||||
|
}, AST_ClassProperty);
|
||||||
|
|
||||||
|
var AST_ClassGetter = DEFNODE("ClassGetter", null, {
|
||||||
|
$documentation: "A `class` getter",
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor");
|
||||||
|
},
|
||||||
|
}, AST_ClassProperty);
|
||||||
|
|
||||||
|
var AST_ClassSetter = DEFNODE("ClassSetter", null, {
|
||||||
|
$documentation: "A `class` setter",
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.value instanceof AST_Accessor)) throw new Error("value must be AST_Accessor");
|
||||||
|
},
|
||||||
|
}, AST_ClassProperty);
|
||||||
|
|
||||||
|
var AST_ClassMethod = DEFNODE("ClassMethod", null, {
|
||||||
|
$documentation: "A `class` method",
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
|
||||||
|
if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
|
||||||
|
if (this.value.name != null) throw new Error("name of class method's lambda must be null");
|
||||||
|
},
|
||||||
|
}, AST_ClassProperty);
|
||||||
|
|
||||||
/* -----[ JUMPS ]----- */
|
/* -----[ JUMPS ]----- */
|
||||||
|
|
||||||
var AST_Jump = DEFNODE("Jump", null, {
|
var AST_Jump = DEFNODE("Jump", null, {
|
||||||
$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
|
$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Jump") throw new Error("should not instantiate AST_Jump");
|
||||||
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
|
|
||||||
var AST_Exit = DEFNODE("Exit", "value", {
|
var AST_Exit = DEFNODE("Exit", "value", {
|
||||||
@@ -709,7 +899,10 @@ var AST_Exit = DEFNODE("Exit", "value", {
|
|||||||
visitor.visit(node, function() {
|
visitor.visit(node, function() {
|
||||||
if (node.value) node.value.walk(visitor);
|
if (node.value) node.value.walk(visitor);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Exit") throw new Error("should not instantiate AST_Exit");
|
||||||
|
},
|
||||||
}, AST_Jump);
|
}, AST_Jump);
|
||||||
|
|
||||||
var AST_Return = DEFNODE("Return", null, {
|
var AST_Return = DEFNODE("Return", null, {
|
||||||
@@ -738,6 +931,7 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "LoopControl") throw new Error("should not instantiate AST_LoopControl");
|
||||||
if (this.label != null) {
|
if (this.label != null) {
|
||||||
if (!(this.label instanceof AST_LabelRef)) throw new Error("label must be AST_LabelRef");
|
if (!(this.label instanceof AST_LabelRef)) throw new Error("label must be AST_LabelRef");
|
||||||
}
|
}
|
||||||
@@ -771,8 +965,7 @@ var AST_If = DEFNODE("If", "condition alternative", {
|
|||||||
_validate: function() {
|
_validate: function() {
|
||||||
must_be_expression(this, "condition");
|
must_be_expression(this, "condition");
|
||||||
if (this.alternative != null) {
|
if (this.alternative != null) {
|
||||||
if (!(this.alternative instanceof AST_Statement)) throw new Error("alternative must be AST_Statement");
|
if (!is_statement(this.alternative)) throw new Error("alternative must be AST_Statement");
|
||||||
if (is_function(this.alternative)) throw new error("alternative cannot be AST_Function");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}, AST_StatementWithBody);
|
}, AST_StatementWithBody);
|
||||||
@@ -801,6 +994,9 @@ var AST_Switch = DEFNODE("Switch", "expression", {
|
|||||||
|
|
||||||
var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {
|
var AST_SwitchBranch = DEFNODE("SwitchBranch", null, {
|
||||||
$documentation: "Base class for `switch` branches",
|
$documentation: "Base class for `switch` branches",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "SwitchBranch") throw new Error("should not instantiate AST_SwitchBranch");
|
||||||
|
},
|
||||||
}, AST_Block);
|
}, AST_Block);
|
||||||
|
|
||||||
var AST_Default = DEFNODE("Default", null, {
|
var AST_Default = DEFNODE("Default", null, {
|
||||||
@@ -889,6 +1085,7 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Definitions") throw new Error("should not instantiate AST_Definitions");
|
||||||
if (this.definitions.length < 1) throw new Error("must have at least one definition");
|
if (this.definitions.length < 1) throw new Error("must have at least one definition");
|
||||||
},
|
},
|
||||||
}, AST_Statement);
|
}, AST_Statement);
|
||||||
@@ -949,6 +1146,129 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
|
|||||||
|
|
||||||
/* -----[ OTHER ]----- */
|
/* -----[ OTHER ]----- */
|
||||||
|
|
||||||
|
var AST_ExportDeclaration = DEFNODE("ExportDeclaration", "body", {
|
||||||
|
$documentation: "An `export` statement",
|
||||||
|
$propdoc: {
|
||||||
|
body: "[AST_DefClass|AST_Definitions|AST_LambdaDefinition] the statement to export",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.body.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.body instanceof AST_DefClass
|
||||||
|
|| this.body instanceof AST_Definitions
|
||||||
|
|| this.body instanceof AST_LambdaDefinition)) {
|
||||||
|
throw new Error("body must be AST_DefClass, AST_Definitions or AST_LambdaDefinition");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_ExportDefault = DEFNODE("ExportDefault", "body", {
|
||||||
|
$documentation: "An `export default` statement",
|
||||||
|
$propdoc: {
|
||||||
|
body: "[AST_Node] the default export",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.body.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.body instanceof AST_DefClass || this.body instanceof AST_LambdaDefinition)) {
|
||||||
|
must_be_expression(this, "body");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_ExportForeign = DEFNODE("ExportForeign", "aliases keys path quote", {
|
||||||
|
$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",
|
||||||
|
},
|
||||||
|
_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");
|
||||||
|
});
|
||||||
|
this.keys.forEach(function(name) {
|
||||||
|
if (typeof name != "string") throw new Error("keys must contain 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);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_ExportReferences = DEFNODE("ExportReferences", "properties", {
|
||||||
|
$documentation: "An `export { ... }` statement",
|
||||||
|
$propdoc: {
|
||||||
|
properties: "[AST_SymbolExport*] array of aliases to export",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
node.properties.forEach(function(prop) {
|
||||||
|
prop.walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
this.properties.forEach(function(prop) {
|
||||||
|
if (!(prop instanceof AST_SymbolExport)) throw new Error("properties must contain AST_SymbolExport");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}, AST_Statement);
|
||||||
|
|
||||||
|
var AST_Import = DEFNODE("Import", "all default path properties quote", {
|
||||||
|
$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",
|
||||||
|
properties: "[(AST_SymbolImport*)?] array of aliases, or null if not specified",
|
||||||
|
quote: "[string?] the original quote character",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
if (node.all) node.all.walk(visitor);
|
||||||
|
if (node.default) node.default.walk(visitor);
|
||||||
|
if (node.properties) node.properties.forEach(function(prop) {
|
||||||
|
prop.walk(visitor);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.all != null) {
|
||||||
|
if (!(this.all instanceof AST_SymbolImport)) throw new Error("all must be AST_SymbolImport");
|
||||||
|
if (this.properties != null) throw new Error("cannot import both * and {} in the same statement");
|
||||||
|
}
|
||||||
|
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 (typeof this.path != "string") throw new Error("path must be 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);
|
||||||
|
|
||||||
var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
var AST_DefaultValue = DEFNODE("DefaultValue", "name value", {
|
||||||
$documentation: "A default value declaration",
|
$documentation: "A default value declaration",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
@@ -973,11 +1293,13 @@ function must_be_expressions(node, prop, allow_spread, allow_hole) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var AST_Call = DEFNODE("Call", "expression args pure", {
|
var AST_Call = DEFNODE("Call", "args expression optional pure", {
|
||||||
$documentation: "A function call expression",
|
$documentation: "A function call expression",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
args: "[AST_Node*] array of arguments",
|
||||||
expression: "[AST_Node] expression to invoke as function",
|
expression: "[AST_Node] expression to invoke as function",
|
||||||
args: "[AST_Node*] array of arguments"
|
optional: "[boolean] whether the expression is optional chaining",
|
||||||
|
pure: "[string/S] marker for side-effect-free call expression",
|
||||||
},
|
},
|
||||||
walk: function(visitor) {
|
walk: function(visitor) {
|
||||||
var node = this;
|
var node = this;
|
||||||
@@ -995,7 +1317,10 @@ var AST_Call = DEFNODE("Call", "expression args pure", {
|
|||||||
});
|
});
|
||||||
|
|
||||||
var AST_New = DEFNODE("New", null, {
|
var AST_New = DEFNODE("New", null, {
|
||||||
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
|
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.optional) throw new Error("optional must be false");
|
||||||
|
},
|
||||||
}, AST_Call);
|
}, AST_Call);
|
||||||
|
|
||||||
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
||||||
@@ -1017,11 +1342,12 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
var AST_PropAccess = DEFNODE("PropAccess", "expression optional property", {
|
||||||
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
expression: "[AST_Node] the “container” expression",
|
expression: "[AST_Node] the “container” expression",
|
||||||
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"
|
optional: "[boolean] whether the expression is optional chaining",
|
||||||
|
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",
|
||||||
},
|
},
|
||||||
getProperty: function() {
|
getProperty: function() {
|
||||||
var p = this.property;
|
var p = this.property;
|
||||||
@@ -1036,6 +1362,7 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
|||||||
return p;
|
return p;
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "PropAccess") throw new Error("should not instantiate AST_PropAccess");
|
||||||
must_be_expression(this, "expression");
|
must_be_expression(this, "expression");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1096,6 +1423,7 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Unary") throw new Error("should not instantiate AST_Unary");
|
||||||
if (typeof this.operator != "string") throw new Error("operator must be string");
|
if (typeof this.operator != "string") throw new Error("operator must be string");
|
||||||
must_be_expression(this, "expression");
|
must_be_expression(this, "expression");
|
||||||
},
|
},
|
||||||
@@ -1183,6 +1511,27 @@ var AST_Await = DEFNODE("Await", "expression", {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var AST_Yield = DEFNODE("Yield", "expression nested", {
|
||||||
|
$documentation: "A yield expression",
|
||||||
|
$propdoc: {
|
||||||
|
expression: "[AST_Node?] return value for iterator, or null if undefined",
|
||||||
|
nested: "[boolean] whether to iterate over expression as generator",
|
||||||
|
},
|
||||||
|
walk: function(visitor) {
|
||||||
|
var node = this;
|
||||||
|
visitor.visit(node, function() {
|
||||||
|
if (node.expression) node.expression.walk(visitor);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.expression != null) {
|
||||||
|
must_be_expression(this, "expression");
|
||||||
|
} else if (this.nested) {
|
||||||
|
throw new Error("yield* must contain expression");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
/* -----[ LITERALS ]----- */
|
/* -----[ LITERALS ]----- */
|
||||||
|
|
||||||
var AST_Array = DEFNODE("Array", "elements", {
|
var AST_Array = DEFNODE("Array", "elements", {
|
||||||
@@ -1208,6 +1557,9 @@ var AST_Destructured = DEFNODE("Destructured", "rest", {
|
|||||||
$propdoc: {
|
$propdoc: {
|
||||||
rest: "[(AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)?] rest parameter, or null if absent",
|
rest: "[(AST_Destructured|AST_SymbolDeclaration|AST_SymbolRef)?] rest parameter, or null if absent",
|
||||||
},
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Destructured") throw new Error("should not instantiate AST_Destructured");
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function validate_destructured(node, check, allow_default) {
|
function validate_destructured(node, check, allow_default) {
|
||||||
@@ -1319,6 +1671,7 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
if (this.TYPE == "ObjectProperty") throw new Error("should not instantiate AST_ObjectProperty");
|
||||||
if (typeof this.key != "string") {
|
if (typeof this.key != "string") {
|
||||||
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
if (!(this.key instanceof AST_Node)) throw new Error("key must be string or AST_Node");
|
||||||
must_be_expression(this, "key");
|
must_be_expression(this, "key");
|
||||||
@@ -1334,6 +1687,15 @@ var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, {
|
|||||||
},
|
},
|
||||||
}, AST_ObjectProperty);
|
}, AST_ObjectProperty);
|
||||||
|
|
||||||
|
var AST_ObjectMethod = DEFNODE("ObjectMethod", null, {
|
||||||
|
$documentation: "A key(){} object property",
|
||||||
|
_validate: function() {
|
||||||
|
if (!(this.value instanceof AST_LambdaExpression)) throw new Error("value must be AST_LambdaExpression");
|
||||||
|
if (is_arrow(this.value)) throw new Error("value cannot be AST_Arrow or AST_AsyncArrow");
|
||||||
|
if (this.value.name != null) throw new Error("name of class method's lambda must be null");
|
||||||
|
},
|
||||||
|
}, AST_ObjectKeyVal);
|
||||||
|
|
||||||
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, {
|
||||||
$documentation: "An object setter property",
|
$documentation: "An object setter property",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
@@ -1356,6 +1718,7 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
|
|||||||
thedef: "[SymbolDef/S] the definition of this symbol"
|
thedef: "[SymbolDef/S] the definition of this symbol"
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_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");
|
if (typeof this.name != "string") throw new Error("name must be string");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -1368,6 +1731,16 @@ var AST_SymbolConst = DEFNODE("SymbolConst", null, {
|
|||||||
$documentation: "Symbol defining a constant",
|
$documentation: "Symbol defining a constant",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolImport = DEFNODE("SymbolImport", "key", {
|
||||||
|
$documentation: "Symbol defined by an `import` statement",
|
||||||
|
$propdoc: {
|
||||||
|
key: "[string] the original `export` name",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (typeof this.key != "string") throw new Error("key must be string");
|
||||||
|
},
|
||||||
|
}, AST_SymbolConst);
|
||||||
|
|
||||||
var AST_SymbolLet = DEFNODE("SymbolLet", null, {
|
var AST_SymbolLet = DEFNODE("SymbolLet", null, {
|
||||||
$documentation: "Symbol defining a lexical-scoped variable",
|
$documentation: "Symbol defining a lexical-scoped variable",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
@@ -1388,6 +1761,14 @@ var AST_SymbolLambda = DEFNODE("SymbolLambda", null, {
|
|||||||
$documentation: "Symbol naming a function expression",
|
$documentation: "Symbol naming a function expression",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
|
|
||||||
|
var AST_SymbolDefClass = DEFNODE("SymbolDefClass", null, {
|
||||||
|
$documentation: "Symbol defining a class",
|
||||||
|
}, AST_SymbolLet);
|
||||||
|
|
||||||
|
var AST_SymbolClass = DEFNODE("SymbolClass", null, {
|
||||||
|
$documentation: "Symbol naming a class expression",
|
||||||
|
}, AST_SymbolLet);
|
||||||
|
|
||||||
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, {
|
||||||
$documentation: "Symbol naming the exception in catch",
|
$documentation: "Symbol naming the exception in catch",
|
||||||
}, AST_SymbolDeclaration);
|
}, AST_SymbolDeclaration);
|
||||||
@@ -1407,16 +1788,50 @@ var AST_SymbolRef = DEFNODE("SymbolRef", "fixed in_arg redef", {
|
|||||||
$documentation: "Reference to some symbol (not definition/declaration)",
|
$documentation: "Reference to some symbol (not definition/declaration)",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_SymbolExport = DEFNODE("SymbolExport", "alias", {
|
||||||
|
$documentation: "Reference in an `export` statement",
|
||||||
|
$propdoc: {
|
||||||
|
alias: "[string] the `export` alias",
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (typeof this.alias != "string") throw new Error("alias must be string");
|
||||||
|
},
|
||||||
|
}, AST_SymbolRef);
|
||||||
|
|
||||||
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
var AST_LabelRef = DEFNODE("LabelRef", null, {
|
||||||
$documentation: "Reference to a label symbol",
|
$documentation: "Reference to a label symbol",
|
||||||
}, AST_Symbol);
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_ObjectIdentity = DEFNODE("ObjectIdentity", null, {
|
||||||
|
$documentation: "Base class for `super` & `this`",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "ObjectIdentity") throw new Error("should not instantiate AST_ObjectIdentity");
|
||||||
|
},
|
||||||
|
}, AST_Symbol);
|
||||||
|
|
||||||
|
var AST_Super = DEFNODE("Super", null, {
|
||||||
|
$documentation: "The `super` symbol",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name !== "super") throw new Error('name must be "super"');
|
||||||
|
},
|
||||||
|
}, AST_ObjectIdentity);
|
||||||
|
|
||||||
var AST_This = DEFNODE("This", null, {
|
var AST_This = DEFNODE("This", null, {
|
||||||
$documentation: "The `this` symbol",
|
$documentation: "The `this` symbol",
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
if (this.name !== "this") throw new Error('name must be "this"');
|
if (this.TYPE == "This" && this.name !== "this") throw new Error('name must be "this"');
|
||||||
},
|
},
|
||||||
}, AST_Symbol);
|
}, AST_ObjectIdentity);
|
||||||
|
|
||||||
|
var AST_NewTarget = DEFNODE("NewTarget", null, {
|
||||||
|
$documentation: "The `new.target` symbol",
|
||||||
|
initialize: function() {
|
||||||
|
this.name = "new.target";
|
||||||
|
},
|
||||||
|
_validate: function() {
|
||||||
|
if (this.name !== "new.target") throw new Error('name must be "new.target": ' + this.name);
|
||||||
|
},
|
||||||
|
}, AST_This);
|
||||||
|
|
||||||
var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
||||||
$documentation: "A template literal, i.e. tag`str1${expr1}...strN${exprN}strN+1`",
|
$documentation: "A template literal, i.e. tag`str1${expr1}...strN${exprN}strN+1`",
|
||||||
@@ -1448,15 +1863,22 @@ var AST_Template = DEFNODE("Template", "expressions strings tag", {
|
|||||||
|
|
||||||
var AST_Constant = DEFNODE("Constant", null, {
|
var AST_Constant = DEFNODE("Constant", null, {
|
||||||
$documentation: "Base class for all constants",
|
$documentation: "Base class for all constants",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Constant") throw new Error("should not instantiate AST_Constant");
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var AST_String = DEFNODE("String", "value quote", {
|
var AST_String = DEFNODE("String", "quote value", {
|
||||||
$documentation: "A string literal",
|
$documentation: "A string literal",
|
||||||
$propdoc: {
|
$propdoc: {
|
||||||
|
quote: "[string?] the original quote character",
|
||||||
value: "[string] the contents of this string",
|
value: "[string] the contents of this string",
|
||||||
quote: "[string] the original quote character"
|
|
||||||
},
|
},
|
||||||
_validate: function() {
|
_validate: function() {
|
||||||
|
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 (typeof this.value != "string") throw new Error("value must be string");
|
if (typeof this.value != "string") throw new Error("value must be string");
|
||||||
},
|
},
|
||||||
}, AST_Constant);
|
}, AST_Constant);
|
||||||
@@ -1496,6 +1918,9 @@ var AST_RegExp = DEFNODE("RegExp", "value", {
|
|||||||
|
|
||||||
var AST_Atom = DEFNODE("Atom", null, {
|
var AST_Atom = DEFNODE("Atom", null, {
|
||||||
$documentation: "Base class for atoms",
|
$documentation: "Base class for atoms",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Atom") throw new Error("should not instantiate AST_Atom");
|
||||||
|
},
|
||||||
}, AST_Constant);
|
}, AST_Constant);
|
||||||
|
|
||||||
var AST_Null = DEFNODE("Null", null, {
|
var AST_Null = DEFNODE("Null", null, {
|
||||||
@@ -1525,6 +1950,9 @@ var AST_Infinity = DEFNODE("Infinity", null, {
|
|||||||
|
|
||||||
var AST_Boolean = DEFNODE("Boolean", null, {
|
var AST_Boolean = DEFNODE("Boolean", null, {
|
||||||
$documentation: "Base class for booleans",
|
$documentation: "Base class for booleans",
|
||||||
|
_validate: function() {
|
||||||
|
if (this.TYPE == "Boolean") throw new Error("should not instantiate AST_Boolean");
|
||||||
|
},
|
||||||
}, AST_Atom);
|
}, AST_Atom);
|
||||||
|
|
||||||
var AST_False = DEFNODE("False", null, {
|
var AST_False = DEFNODE("False", null, {
|
||||||
@@ -1563,7 +1991,8 @@ TreeWalker.prototype = {
|
|||||||
this.stack.push(node);
|
this.stack.push(node);
|
||||||
},
|
},
|
||||||
pop: function() {
|
pop: function() {
|
||||||
if (this.stack.pop() instanceof AST_Lambda) {
|
var node = this.stack.pop();
|
||||||
|
if (node instanceof AST_Lambda) {
|
||||||
this.directives = Object.getPrototypeOf(this.directives);
|
this.directives = Object.getPrototypeOf(this.directives);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
2344
lib/compress.js
2344
lib/compress.js
File diff suppressed because it is too large
Load Diff
@@ -47,14 +47,12 @@ function parse_source_map(content) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function set_shorthand(name, options, keys) {
|
function set_shorthand(name, options, keys) {
|
||||||
if (options[name]) {
|
|
||||||
keys.forEach(function(key) {
|
keys.forEach(function(key) {
|
||||||
if (options[key]) {
|
if (options[key]) {
|
||||||
if (typeof options[key] != "object") options[key] = {};
|
if (typeof options[key] != "object") options[key] = {};
|
||||||
if (!(name in options[key])) options[key][name] = options[name];
|
if (!(name in options[key])) options[key][name] = options[name];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function init_cache(cache) {
|
function init_cache(cache) {
|
||||||
@@ -75,6 +73,7 @@ function to_json(cache) {
|
|||||||
function minify(files, options) {
|
function minify(files, options) {
|
||||||
try {
|
try {
|
||||||
options = defaults(options, {
|
options = defaults(options, {
|
||||||
|
annotations: undefined,
|
||||||
compress: {},
|
compress: {},
|
||||||
enclose: false,
|
enclose: false,
|
||||||
ie8: false,
|
ie8: false,
|
||||||
@@ -94,17 +93,14 @@ function minify(files, options) {
|
|||||||
wrap: false,
|
wrap: false,
|
||||||
}, true);
|
}, true);
|
||||||
if (options.validate) AST_Node.enable_validation();
|
if (options.validate) AST_Node.enable_validation();
|
||||||
var timings = options.timings && {
|
var timings = options.timings && { start: Date.now() };
|
||||||
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.rename === undefined) {
|
if (options.ie8) set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
||||||
options.rename = options.compress && options.mangle;
|
if (options.keep_fnames) set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
||||||
}
|
if (options.toplevel) set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
||||||
set_shorthand("ie8", options, [ "compress", "mangle", "output" ]);
|
if (options.v8) set_shorthand("v8", options, [ "mangle", "output" ]);
|
||||||
set_shorthand("keep_fnames", options, [ "compress", "mangle" ]);
|
if (options.webkit) set_shorthand("webkit", options, [ "mangle", "output" ]);
|
||||||
set_shorthand("toplevel", options, [ "compress", "mangle" ]);
|
|
||||||
set_shorthand("v8", options, [ "mangle", "output" ]);
|
|
||||||
set_shorthand("webkit", options, [ "mangle", "output" ]);
|
|
||||||
var quoted_props;
|
var quoted_props;
|
||||||
if (options.mangle) {
|
if (options.mangle) {
|
||||||
options.mangle = defaults(options.mangle, {
|
options.mangle = defaults(options.mangle, {
|
||||||
@@ -208,27 +204,29 @@ function minify(files, options) {
|
|||||||
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
if (options.mangle && options.mangle.properties) mangle_properties(toplevel, options.mangle.properties);
|
||||||
if (timings) timings.output = Date.now();
|
if (timings) timings.output = Date.now();
|
||||||
var result = {};
|
var result = {};
|
||||||
if (options.output.ast) {
|
var output = defaults(options.output, {
|
||||||
result.ast = toplevel;
|
ast: false,
|
||||||
}
|
code: true,
|
||||||
if (!HOP(options.output, "code") || options.output.code) {
|
});
|
||||||
|
if (output.ast) result.ast = toplevel;
|
||||||
|
if (output.code) {
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
options.output.source_map = SourceMap(options.sourceMap);
|
output.source_map = SourceMap(options.sourceMap);
|
||||||
if (options.sourceMap.includeSources) {
|
if (options.sourceMap.includeSources) {
|
||||||
if (files instanceof AST_Toplevel) {
|
if (files instanceof AST_Toplevel) {
|
||||||
throw new Error("original source content unavailable");
|
throw new Error("original source content unavailable");
|
||||||
} else for (var name in files) if (HOP(files, name)) {
|
} else for (var name in files) if (HOP(files, name)) {
|
||||||
options.output.source_map.setSourceContent(name, files[name]);
|
output.source_map.setSourceContent(name, files[name]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete options.output.ast;
|
delete output.ast;
|
||||||
delete options.output.code;
|
delete output.code;
|
||||||
var stream = OutputStream(options.output);
|
var stream = OutputStream(output);
|
||||||
toplevel.print(stream);
|
toplevel.print(stream);
|
||||||
result.code = stream.get();
|
result.code = stream.get();
|
||||||
if (options.sourceMap) {
|
if (options.sourceMap) {
|
||||||
result.map = options.output.source_map.toString();
|
result.map = output.source_map.toString();
|
||||||
var url = options.sourceMap.url;
|
var url = options.sourceMap.url;
|
||||||
if (url) {
|
if (url) {
|
||||||
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
|
result.code = result.code.replace(/\n\/\/# sourceMappingURL=\S+\s*$/, "");
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
700
lib/output.js
700
lib/output.js
File diff suppressed because it is too large
Load Diff
695
lib/parse.js
695
lib/parse.js
File diff suppressed because it is too large
Load Diff
@@ -81,7 +81,9 @@ var builtins = function() {
|
|||||||
|
|
||||||
function reserve_quoted_keys(ast, reserved) {
|
function reserve_quoted_keys(ast, reserved) {
|
||||||
ast.walk(new TreeWalker(function(node) {
|
ast.walk(new TreeWalker(function(node) {
|
||||||
if (node instanceof AST_ObjectProperty) {
|
if (node instanceof AST_ClassProperty) {
|
||||||
|
if (node.start && node.start.quote) add(node.key);
|
||||||
|
} else if (node instanceof AST_ObjectProperty) {
|
||||||
if (node.start && node.start.quote) add(node.key);
|
if (node.start && node.start.quote) add(node.key);
|
||||||
} else if (node instanceof AST_Sub) {
|
} else if (node instanceof AST_Sub) {
|
||||||
addStrings(node.property, add);
|
addStrings(node.property, add);
|
||||||
@@ -163,6 +165,8 @@ function mangle_properties(ast, options) {
|
|||||||
addStrings(node.args[0], add);
|
addStrings(node.args[0], add);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (node instanceof AST_ClassProperty) {
|
||||||
|
if (typeof node.key == "string") add(node.key);
|
||||||
} else if (node instanceof AST_Dot) {
|
} else if (node instanceof AST_Dot) {
|
||||||
add(node.property);
|
add(node.property);
|
||||||
} else if (node instanceof AST_ObjectProperty) {
|
} else if (node instanceof AST_ObjectProperty) {
|
||||||
@@ -193,6 +197,8 @@ function mangle_properties(ast, options) {
|
|||||||
mangleStrings(node.args[0]);
|
mangleStrings(node.args[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
} else if (node instanceof AST_ClassProperty) {
|
||||||
|
if (typeof node.key == "string") node.key = mangle(node.key);
|
||||||
} else if (node instanceof AST_Dot) {
|
} else if (node instanceof AST_Dot) {
|
||||||
node.property = mangle(node.property);
|
node.property = mangle(node.property);
|
||||||
} else if (node instanceof AST_ObjectProperty) {
|
} else if (node instanceof AST_ObjectProperty) {
|
||||||
@@ -222,9 +228,7 @@ function mangle_properties(ast, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mangle(name) {
|
function mangle(name) {
|
||||||
if (!should_mangle(name)) {
|
if (!should_mangle(name)) return name;
|
||||||
return name;
|
|
||||||
}
|
|
||||||
var mangled = cache.get(name);
|
var mangled = cache.get(name);
|
||||||
if (!mangled) {
|
if (!mangled) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
@@ -236,6 +240,7 @@ function mangle_properties(ast, options) {
|
|||||||
if (!mangled) do {
|
if (!mangled) do {
|
||||||
mangled = base54(++cname);
|
mangled = base54(++cname);
|
||||||
} while (!can_mangle(mangled));
|
} while (!can_mangle(mangled));
|
||||||
|
if (/^#/.test(name)) mangled = "#" + mangled;
|
||||||
cache.set(name, mangled);
|
cache.set(name, mangled);
|
||||||
}
|
}
|
||||||
return mangled;
|
return mangled;
|
||||||
|
|||||||
76
lib/scope.js
76
lib/scope.js
@@ -45,6 +45,7 @@
|
|||||||
|
|
||||||
function SymbolDef(id, scope, orig, init) {
|
function SymbolDef(id, scope, orig, init) {
|
||||||
this.eliminated = 0;
|
this.eliminated = 0;
|
||||||
|
this.exported = false;
|
||||||
this.global = false;
|
this.global = false;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.init = init;
|
this.init = init;
|
||||||
@@ -91,11 +92,14 @@ SymbolDef.prototype = {
|
|||||||
},
|
},
|
||||||
unmangleable: function(options) {
|
unmangleable: function(options) {
|
||||||
return this.global && !options.toplevel
|
return this.global && !options.toplevel
|
||||||
|
|| this.exported
|
||||||
|| this.undeclared
|
|| this.undeclared
|
||||||
|| !options.eval && this.scope.pinned()
|
|| !options.eval && this.scope.pinned()
|
||||||
|| options.keep_fnames
|
|| options.keep_fnames
|
||||||
&& (this.orig[0] instanceof AST_SymbolLambda
|
&& (this.orig[0] instanceof AST_SymbolClass
|
||||||
|| this.orig[0] instanceof AST_SymbolDefun);
|
|| this.orig[0] instanceof AST_SymbolDefClass
|
||||||
|
|| this.orig[0] instanceof AST_SymbolDefun
|
||||||
|
|| this.orig[0] instanceof AST_SymbolLambda);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,6 +110,7 @@ function is_lhs(node, parent) {
|
|||||||
if (parent instanceof AST_DefaultValue) return parent.name === node && node;
|
if (parent instanceof AST_DefaultValue) return parent.name === node && node;
|
||||||
if (parent instanceof AST_Destructured) return node;
|
if (parent instanceof AST_Destructured) return node;
|
||||||
if (parent instanceof AST_DestructuredKeyVal) return node;
|
if (parent instanceof AST_DestructuredKeyVal) return node;
|
||||||
|
if (parent instanceof AST_ForEnumeration) return parent.init === node && node;
|
||||||
if (parent instanceof AST_Unary) return unary_side_effects[parent.operator] && parent.expression;
|
if (parent instanceof AST_Unary) return unary_side_effects[parent.operator] && parent.expression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +123,35 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
// pass 1: setup scope chaining and handle definitions
|
// pass 1: setup scope chaining and handle definitions
|
||||||
var self = this;
|
var self = this;
|
||||||
var defun = null;
|
var defun = null;
|
||||||
|
var exported = false;
|
||||||
var next_def_id = 0;
|
var next_def_id = 0;
|
||||||
var scope = self.parent_scope = null;
|
var scope = self.parent_scope = null;
|
||||||
var tw = new TreeWalker(function(node, descend) {
|
var tw = new TreeWalker(function(node, descend) {
|
||||||
if (is_defun(node)) {
|
if (node instanceof AST_DefClass) {
|
||||||
|
var save_exported = exported;
|
||||||
|
exported = tw.parent() instanceof AST_ExportDeclaration;
|
||||||
node.name.walk(tw);
|
node.name.walk(tw);
|
||||||
|
exported = save_exported;
|
||||||
|
walk_scope(function() {
|
||||||
|
if (node.extends) node.extends.walk(tw);
|
||||||
|
node.properties.forEach(function(prop) {
|
||||||
|
prop.walk(tw);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Definitions) {
|
||||||
|
var save_exported = exported;
|
||||||
|
exported = tw.parent() instanceof AST_ExportDeclaration;
|
||||||
|
descend();
|
||||||
|
exported = save_exported;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_LambdaDefinition) {
|
||||||
|
var save_exported = exported;
|
||||||
|
exported = tw.parent() instanceof AST_ExportDeclaration;
|
||||||
|
node.name.walk(tw);
|
||||||
|
exported = save_exported;
|
||||||
walk_scope(function() {
|
walk_scope(function() {
|
||||||
node.argnames.forEach(function(argname) {
|
node.argnames.forEach(function(argname) {
|
||||||
argname.walk(tw);
|
argname.walk(tw);
|
||||||
@@ -169,9 +198,12 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
scope.def_variable(node).defun = defun;
|
scope.def_variable(node).defun = defun;
|
||||||
} else if (node instanceof AST_SymbolConst) {
|
} else if (node instanceof AST_SymbolConst) {
|
||||||
scope.def_variable(node).defun = defun;
|
var def = scope.def_variable(node);
|
||||||
|
def.defun = defun;
|
||||||
|
if (exported) def.exported = true;
|
||||||
} else if (node instanceof AST_SymbolDefun) {
|
} else if (node instanceof AST_SymbolDefun) {
|
||||||
defun.def_function(node, tw.parent());
|
var def = defun.def_function(node, tw.parent());
|
||||||
|
if (exported) def.exported = true;
|
||||||
entangle(defun, scope);
|
entangle(defun, scope);
|
||||||
} else if (node instanceof AST_SymbolFunarg) {
|
} else if (node instanceof AST_SymbolFunarg) {
|
||||||
defun.def_variable(node);
|
defun.def_variable(node);
|
||||||
@@ -180,9 +212,11 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
var def = defun.def_function(node, node.name == "arguments" ? undefined : defun);
|
||||||
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
if (options.ie8) def.defun = defun.parent_scope.resolve();
|
||||||
} else if (node instanceof AST_SymbolLet) {
|
} else if (node instanceof AST_SymbolLet) {
|
||||||
scope.def_variable(node);
|
var def = scope.def_variable(node);
|
||||||
|
if (exported) def.exported = true;
|
||||||
} else if (node instanceof AST_SymbolVar) {
|
} else if (node instanceof AST_SymbolVar) {
|
||||||
defun.def_variable(node, null);
|
var def = defun.def_variable(node, node instanceof AST_SymbolImport ? undefined : null);
|
||||||
|
if (exported) def.exported = true;
|
||||||
entangle(defun, scope);
|
entangle(defun, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,16 +273,18 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (node instanceof AST_SymbolDeclaration) {
|
if (node instanceof AST_SymbolDeclaration) {
|
||||||
|
var def = node.definition();
|
||||||
|
def.preinit = def.references.length;
|
||||||
if (node instanceof AST_SymbolCatch) {
|
if (node instanceof AST_SymbolCatch) {
|
||||||
// ensure mangling works if `catch` reuses a scope variable
|
// ensure mangling works if `catch` reuses a scope variable
|
||||||
var def = node.definition().redefined();
|
var redef = def.redefined();
|
||||||
if (def) for (var s = node.scope; s; s = s.parent_scope) {
|
if (redef) for (var s = node.scope; s; s = s.parent_scope) {
|
||||||
push_uniq(s.enclosed, def);
|
push_uniq(s.enclosed, redef);
|
||||||
if (s === def.scope) break;
|
if (s === redef.scope) break;
|
||||||
}
|
}
|
||||||
} else if (node instanceof AST_SymbolConst) {
|
} else if (node instanceof AST_SymbolConst) {
|
||||||
// ensure compression works if `const` reuses a scope variable
|
// ensure compression works if `const` reuses a scope variable
|
||||||
var redef = node.definition().redefined();
|
var redef = def.redefined();
|
||||||
if (redef) redef.const_redefs = true;
|
if (redef) redef.const_redefs = true;
|
||||||
}
|
}
|
||||||
if (node.name != "arguments") return true;
|
if (node.name != "arguments") return true;
|
||||||
@@ -299,6 +335,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
|
|||||||
self.uses_eval = true;
|
self.uses_eval = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sym.init instanceof AST_LambdaDefinition && sym.scope !== sym.init.name.scope) {
|
||||||
|
var scope = node.scope;
|
||||||
|
do {
|
||||||
|
if (scope === sym.init.name.scope) break;
|
||||||
|
} while (scope = scope.parent_scope);
|
||||||
|
if (!scope) sym.init = undefined;
|
||||||
|
}
|
||||||
node.thedef = sym;
|
node.thedef = sym;
|
||||||
node.reference(options);
|
node.reference(options);
|
||||||
return true;
|
return true;
|
||||||
@@ -399,6 +442,7 @@ AST_Scope.DEFMETHOD("init_vars", function(parent_scope) {
|
|||||||
});
|
});
|
||||||
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
|
AST_Arrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
init_scope_vars(this, parent_scope);
|
init_scope_vars(this, parent_scope);
|
||||||
|
return this;
|
||||||
});
|
});
|
||||||
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
|
AST_AsyncArrow.DEFMETHOD("init_vars", function(parent_scope) {
|
||||||
init_scope_vars(this, parent_scope);
|
init_scope_vars(this, parent_scope);
|
||||||
@@ -418,7 +462,9 @@ AST_Symbol.DEFMETHOD("mark_enclosed", function(options) {
|
|||||||
var def = this.definition();
|
var def = this.definition();
|
||||||
for (var s = this.scope; s; s = s.parent_scope) {
|
for (var s = this.scope; s; s = s.parent_scope) {
|
||||||
push_uniq(s.enclosed, def);
|
push_uniq(s.enclosed, def);
|
||||||
if (options.keep_fnames) {
|
if (!options) {
|
||||||
|
delete s._var_names;
|
||||||
|
} else if (options.keep_fnames) {
|
||||||
s.functions.each(function(d) {
|
s.functions.each(function(d) {
|
||||||
push_uniq(def.scope.enclosed, d);
|
push_uniq(def.scope.enclosed, d);
|
||||||
});
|
});
|
||||||
@@ -439,7 +485,7 @@ AST_BlockScope.DEFMETHOD("find_variable", function(name) {
|
|||||||
|
|
||||||
AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) {
|
AST_BlockScope.DEFMETHOD("def_function", function(symbol, init) {
|
||||||
var def = this.def_variable(symbol, init);
|
var def = this.def_variable(symbol, init);
|
||||||
if (!def.init || is_defun(def.init)) def.init = init;
|
if (!def.init || def.init instanceof AST_LambdaDefinition) def.init = init;
|
||||||
this.functions.set(symbol.name, def);
|
this.functions.set(symbol.name, def);
|
||||||
return def;
|
return def;
|
||||||
});
|
});
|
||||||
@@ -448,7 +494,7 @@ AST_BlockScope.DEFMETHOD("def_variable", function(symbol, init) {
|
|||||||
var def = this.variables.get(symbol.name);
|
var def = this.variables.get(symbol.name);
|
||||||
if (def) {
|
if (def) {
|
||||||
def.orig.push(symbol);
|
def.orig.push(symbol);
|
||||||
if (is_function(def.init)) def.init = init;
|
if (def.init instanceof AST_LambdaExpression) def.init = init;
|
||||||
} else {
|
} else {
|
||||||
def = this.make_def(symbol, init);
|
def = this.make_def(symbol, init);
|
||||||
this.variables.set(symbol.name, def);
|
this.variables.set(symbol.name, def);
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (self.step) self.step = self.step.transform(tw);
|
if (self.step) self.step = self.step.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
});
|
});
|
||||||
DEF(AST_ForIn, function(self, tw) {
|
DEF(AST_ForEnumeration, function(self, tw) {
|
||||||
self.init = self.init.transform(tw);
|
self.init = self.init.transform(tw);
|
||||||
self.object = self.object.transform(tw);
|
self.object = self.object.transform(tw);
|
||||||
self.body = self.body.transform(tw);
|
self.body = self.body.transform(tw);
|
||||||
@@ -147,6 +147,15 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
}
|
}
|
||||||
DEF(AST_Arrow, transform_arrow);
|
DEF(AST_Arrow, transform_arrow);
|
||||||
DEF(AST_AsyncArrow, transform_arrow);
|
DEF(AST_AsyncArrow, transform_arrow);
|
||||||
|
DEF(AST_Class, function(self, tw) {
|
||||||
|
if (self.name) self.name = self.name.transform(tw);
|
||||||
|
if (self.extends) self.extends = self.extends.transform(tw);
|
||||||
|
self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
|
DEF(AST_ClassProperty, function(self, tw) {
|
||||||
|
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
|
||||||
|
if (self.value) self.value = self.value.transform(tw);
|
||||||
|
});
|
||||||
DEF(AST_Call, function(self, tw) {
|
DEF(AST_Call, function(self, tw) {
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
self.args = do_list(self.args, tw);
|
self.args = do_list(self.args, tw);
|
||||||
@@ -157,6 +166,9 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
DEF(AST_Await, function(self, tw) {
|
DEF(AST_Await, function(self, tw) {
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_Yield, function(self, tw) {
|
||||||
|
if (self.expression) self.expression = self.expression.transform(tw);
|
||||||
|
});
|
||||||
DEF(AST_Dot, function(self, tw) {
|
DEF(AST_Dot, function(self, tw) {
|
||||||
self.expression = self.expression.transform(tw);
|
self.expression = self.expression.transform(tw);
|
||||||
});
|
});
|
||||||
@@ -201,6 +213,20 @@ TreeTransformer.prototype = new TreeWalker;
|
|||||||
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
|
if (self.key instanceof AST_Node) self.key = self.key.transform(tw);
|
||||||
self.value = self.value.transform(tw);
|
self.value = self.value.transform(tw);
|
||||||
});
|
});
|
||||||
|
DEF(AST_ExportDeclaration, function(self, tw) {
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
DEF(AST_ExportDefault, function(self, tw) {
|
||||||
|
self.body = self.body.transform(tw);
|
||||||
|
});
|
||||||
|
DEF(AST_ExportReferences, function(self, tw) {
|
||||||
|
self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
|
DEF(AST_Import, function(self, tw) {
|
||||||
|
if (self.all) self.all = self.all.transform(tw);
|
||||||
|
if (self.default) self.default = self.default.transform(tw);
|
||||||
|
if (self.properties) self.properties = do_list(self.properties, tw);
|
||||||
|
});
|
||||||
DEF(AST_Template, function(self, tw) {
|
DEF(AST_Template, function(self, tw) {
|
||||||
if (self.tag) self.tag = self.tag.transform(tw);
|
if (self.tag) self.tag = self.tag.transform(tw);
|
||||||
self.expressions = do_list(self.expressions, tw);
|
self.expressions = do_list(self.expressions, tw);
|
||||||
|
|||||||
@@ -238,7 +238,7 @@ function HOP(obj, prop) {
|
|||||||
// return true if the node at the top of the stack (that means the
|
// return true if the node at the top of the stack (that means the
|
||||||
// innermost node in the current output) is lexically the first in
|
// innermost node in the current output) is lexically the first in
|
||||||
// a statement.
|
// a statement.
|
||||||
function first_in_statement(stack, arrow) {
|
function first_in_statement(stack, arrow, export_default) {
|
||||||
var node = stack.parent(-1);
|
var node = stack.parent(-1);
|
||||||
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
for (var i = 0, p; p = stack.parent(i++); node = p) {
|
||||||
if (is_arrow(p)) {
|
if (is_arrow(p)) {
|
||||||
@@ -249,12 +249,14 @@ function first_in_statement(stack, arrow) {
|
|||||||
if (p.expression === node) continue;
|
if (p.expression === node) continue;
|
||||||
} else if (p instanceof AST_Conditional) {
|
} else if (p instanceof AST_Conditional) {
|
||||||
if (p.condition === node) continue;
|
if (p.condition === node) continue;
|
||||||
|
} else if (p instanceof AST_ExportDefault) {
|
||||||
|
return export_default;
|
||||||
} else if (p instanceof AST_PropAccess) {
|
} else if (p instanceof AST_PropAccess) {
|
||||||
if (p.expression === node) continue;
|
if (p.expression === node) continue;
|
||||||
} else if (p instanceof AST_Sequence) {
|
} else if (p instanceof AST_Sequence) {
|
||||||
if (p.expressions[0] === node) continue;
|
if (p.expressions[0] === node) continue;
|
||||||
} else if (p instanceof AST_Statement) {
|
} else if (p instanceof AST_SimpleStatement) {
|
||||||
return p.body === node;
|
return true;
|
||||||
} else if (p instanceof AST_Template) {
|
} else if (p instanceof AST_Template) {
|
||||||
if (p.tag === node) continue;
|
if (p.tag === node) continue;
|
||||||
} else if (p instanceof AST_UnaryPostfix) {
|
} else if (p instanceof AST_UnaryPostfix) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
"description": "JavaScript parser, mangler/compressor and beautifier toolkit",
|
||||||
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
||||||
"license": "BSD-2-Clause",
|
"license": "BSD-2-Clause",
|
||||||
"version": "3.12.7",
|
"version": "3.13.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.8.0"
|
"node": ">=0.8.0"
|
||||||
},
|
},
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"LICENSE"
|
"LICENSE"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"acorn": "~7.1.0",
|
"acorn": "~8.2.1",
|
||||||
"semver": "~6.3.0"
|
"semver": "~6.3.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -10,33 +10,38 @@ var sandbox = require("./sandbox");
|
|||||||
var semver = require("semver");
|
var semver = require("semver");
|
||||||
var U = require("./node");
|
var U = require("./node");
|
||||||
|
|
||||||
var file = process.argv[2];
|
var batch = 50;
|
||||||
var dir = path.resolve(path.dirname(module.filename), "compress");
|
var dir = path.resolve(path.dirname(module.filename), "compress");
|
||||||
if (file) {
|
if (process.argv.length > 3) {
|
||||||
|
var file = process.argv[2];
|
||||||
|
var start = process.argv[3] | 0;
|
||||||
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
|
var minify_options = require("./ufuzz/options.json").map(JSON.stringify);
|
||||||
log("--- {file}", { file: file });
|
|
||||||
var tests = parse_test(path.resolve(dir, file));
|
var tests = parse_test(path.resolve(dir, file));
|
||||||
process.exit(Object.keys(tests).filter(function(name) {
|
process.exit(Object.keys(tests).slice(start, start + batch).filter(function(name) {
|
||||||
return !test_case(tests[name]);
|
return !test_case(tests[name]);
|
||||||
}).length);
|
}).length);
|
||||||
} else {
|
} else {
|
||||||
var files = fs.readdirSync(dir).filter(function(name) {
|
var files = process.argv.length == 3 ? [ process.argv[2] ] : fs.readdirSync(dir).filter(function(name) {
|
||||||
return /\.js$/i.test(name);
|
return /\.js$/i.test(name);
|
||||||
});
|
});
|
||||||
var failures = 0;
|
var failures = 0;
|
||||||
var failed_files = Object.create(null);
|
var failed_files = Object.create(null);
|
||||||
(function next() {
|
(function next(file, start, length) {
|
||||||
var file = files.shift();
|
if (start < length) {
|
||||||
if (file) {
|
child_process.spawn(process.argv[0], [ process.argv[1], file, start, batch ], {
|
||||||
child_process.spawn(process.argv[0], [ process.argv[1], file ], {
|
|
||||||
stdio: [ "ignore", 1, 2 ]
|
stdio: [ "ignore", 1, 2 ]
|
||||||
}).on("exit", function(code) {
|
}).on("exit", function(code) {
|
||||||
if (code) {
|
if (code) {
|
||||||
failures += code;
|
failures += code;
|
||||||
failed_files[file] = code;
|
failed_files[file] = true;
|
||||||
}
|
}
|
||||||
next();
|
next(file, start + batch, length);
|
||||||
});
|
});
|
||||||
|
} else if (file = files.shift()) {
|
||||||
|
log("--- {file}", { file: file });
|
||||||
|
start = 0;
|
||||||
|
length = Object.keys(parse_test(path.resolve(dir, file))).length;
|
||||||
|
next(file, start, length);
|
||||||
} else if (failures) {
|
} else if (failures) {
|
||||||
console.error();
|
console.error();
|
||||||
console.error("!!! Failed " + failures + " test case(s).");
|
console.error("!!! Failed " + failures + " test case(s).");
|
||||||
@@ -257,6 +262,7 @@ function test_case(test) {
|
|||||||
var input = to_toplevel(test.input, test.mangle);
|
var input = to_toplevel(test.input, test.mangle);
|
||||||
var input_code = make_code(input);
|
var input_code = make_code(input);
|
||||||
var input_formatted = make_code(test.input, {
|
var input_formatted = make_code(test.input, {
|
||||||
|
annotations: true,
|
||||||
beautify: true,
|
beautify: true,
|
||||||
comments: "all",
|
comments: "all",
|
||||||
keep_quoted_props: true,
|
keep_quoted_props: true,
|
||||||
|
|||||||
473
test/compress/annotations.js
Normal file
473
test/compress/annotations.js
Normal file
@@ -0,0 +1,473 @@
|
|||||||
|
issue_2629_1: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a();
|
||||||
|
/*@__PURE__*/ (b());
|
||||||
|
(/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ d());
|
||||||
|
}
|
||||||
|
expect_exact: "c();"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_2: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ (d(1)(2)(3));
|
||||||
|
(/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"e(1)(2)(3);",
|
||||||
|
"f(1)(2)(3);",
|
||||||
|
"g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_3: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
||||||
|
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"h.x(1).y(2).z(3);",
|
||||||
|
"i.x(1).y(2).z(3);",
|
||||||
|
"j.x(1).y(2).z(3);",
|
||||||
|
"k.x(1).y(2).z(3);",
|
||||||
|
"l.x(1).y(2).z(3);",
|
||||||
|
"m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_4: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ x(), y());
|
||||||
|
(w(), /*@__PURE__*/ x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2629_5: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ x() ];
|
||||||
|
[ /*@__PURE__*/ x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2638: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/(g() || h())(x(), y());
|
||||||
|
(/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"x(),y();",
|
||||||
|
"(a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_1: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a();
|
||||||
|
/*@__PURE__*/ (new b());
|
||||||
|
new (/*@__PURE__*/ c)();
|
||||||
|
(/*@__PURE__*/ new d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new c;",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_2: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ new (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ new (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ new (d(1)(2)(3));
|
||||||
|
new (/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ new f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ new g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ new h(1)(2)(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new e(1)(2)(3);",
|
||||||
|
"new f(1)(2)(3);",
|
||||||
|
"new g(1)(2)(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_3: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
||||||
|
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
||||||
|
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
||||||
|
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
||||||
|
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
||||||
|
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
||||||
|
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
||||||
|
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
||||||
|
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
||||||
|
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
||||||
|
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"new h.x(1).y(2).z(3);",
|
||||||
|
"/* */new i.x(1).y(2).z(3);",
|
||||||
|
"new j.x(1).y(2).z(3);",
|
||||||
|
"new k.x(1).y(2).z(3);",
|
||||||
|
"new l.x(1).y(2).z(3);",
|
||||||
|
"new m.x(1).y(2).z(3);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_4: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(/*@__PURE__*/ new x(), y());
|
||||||
|
(w(), /*@__PURE__*/ new x(), y());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_5: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
[ /*@__PURE__*/ new x() ];
|
||||||
|
[ /*@__PURE__*/ new x(), y() ];
|
||||||
|
[ w(), /*@__PURE__*/ new x(), y() ];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
y();
|
||||||
|
w(), y();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2705_6: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
comments: "all",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/new (g() || h())(x(), y());
|
||||||
|
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"x(),y();",
|
||||||
|
"/* */new(a()||b())(c(),d());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_3858: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function(a) {
|
||||||
|
return /*@__PURE__*/ function(b) {
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
};
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = function(a) {
|
||||||
|
return function() {
|
||||||
|
console.log(a);
|
||||||
|
}();
|
||||||
|
};
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_pure_call_1: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function(a) {
|
||||||
|
return /*@__PURE__*/ function(b) {
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
};
|
||||||
|
f("PASS");
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_pure_call_2: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function(a) {
|
||||||
|
return /*@__PURE__*/ function(b) {
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
};
|
||||||
|
var a = f("PASS");
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_pure_call_3: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
passes: 2,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function(a) {
|
||||||
|
return /*@__PURE__*/ function(b) {
|
||||||
|
console.log(b);
|
||||||
|
}(a);
|
||||||
|
};
|
||||||
|
var a = f("PASS");
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
inline_pure_call_4: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = /*@__PURE__*/ function() {
|
||||||
|
return console.log("PASS"), 42;
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = function() {
|
||||||
|
return console.log("PASS"), 42;
|
||||||
|
}();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_and_output_annotations_enabled: {
|
||||||
|
options = {
|
||||||
|
annotations: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
annotations: true,
|
||||||
|
beautify: true,
|
||||||
|
comments: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var top = /*@__PURE__*/ foo();
|
||||||
|
/*@__PURE__*/ a(1)(2)(3);
|
||||||
|
/*@__PURE__*/ (b(1))(2)(3);
|
||||||
|
/*@__PURE__*/ (c(1)(2))(3);
|
||||||
|
/*@__PURE__*/ (d(1)(2)(3));
|
||||||
|
(/*@__PURE__*/ e)(1)(2)(3);
|
||||||
|
(/*@__PURE__*/ f(1))(2)(3);
|
||||||
|
(/*@__PURE__*/ g(1)(2))(3);
|
||||||
|
(/*@__PURE__*/ h(1)(2)(3));
|
||||||
|
/*@__PURE__*/ l(1).p(2);
|
||||||
|
(/*@__PURE__*/ m(1)).p(2);
|
||||||
|
(/*@__PURE__*/ n(1).p)(2);
|
||||||
|
(/*@__PURE__*/ o(1).p(2));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"var top = /*@__PURE__*/foo();",
|
||||||
|
"",
|
||||||
|
"e(1)(2)(3);",
|
||||||
|
"",
|
||||||
|
"f(1)(2)(3);",
|
||||||
|
"",
|
||||||
|
"g(1)(2)(3);",
|
||||||
|
"",
|
||||||
|
"m(1).p(2);",
|
||||||
|
"",
|
||||||
|
"n(1).p(2);",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_annotations_disabled_output_annotations_enabled: {
|
||||||
|
options = {
|
||||||
|
annotations: false,
|
||||||
|
evaluate: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
annotations: true,
|
||||||
|
comments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a(1+2);
|
||||||
|
/*#__PURE__*/ (b(2+3));
|
||||||
|
(/*@__PURE__*/ c)(side_effect);
|
||||||
|
(/*#__PURE__*/ d(effect()));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"/*@__PURE__*/a(3),",
|
||||||
|
"/*#__PURE__*/b(5),",
|
||||||
|
"c(side_effect),",
|
||||||
|
"/*#__PURE__*/d(effect());",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
compress_and_output_annotations_disabled: {
|
||||||
|
options = {
|
||||||
|
annotations: false,
|
||||||
|
evaluate: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
beautify = {
|
||||||
|
annotations: false,
|
||||||
|
comments: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
/*@__PURE__*/ a(1+2);
|
||||||
|
/*@__PURE__*/ (b(2+3));
|
||||||
|
(/*@__PURE__*/ c)(side_effect);
|
||||||
|
(/*@__PURE__*/ d(effect()));
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"a(3),",
|
||||||
|
"b(5),",
|
||||||
|
"c(side_effect),",
|
||||||
|
"d(effect());",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -84,6 +84,7 @@ replace_index_drop_fargs_1: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
properties: true,
|
properties: true,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var arguments = [];
|
var arguments = [];
|
||||||
@@ -119,7 +120,7 @@ replace_index_drop_fargs_1: {
|
|||||||
console.log(b, b, arguments.foo);
|
console.log(b, b, arguments.foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
(function(arguments) {
|
(function(arguments) {
|
||||||
console.log(arguments[1], arguments[1], arguments.foo);
|
console.log("bar"[1], "bar"[1], "bar".foo);
|
||||||
})("bar", 42);
|
})("bar", 42);
|
||||||
(function(argument_0, argument_1) {
|
(function(argument_0, argument_1) {
|
||||||
var arguments;
|
var arguments;
|
||||||
@@ -649,6 +650,7 @@ issue_3420_1: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -671,6 +673,7 @@ issue_3420_2: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var foo = function() {
|
var foo = function() {
|
||||||
@@ -691,6 +694,7 @@ issue_3420_3: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -713,6 +717,7 @@ issue_3420_4: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
!function() {
|
!function() {
|
||||||
@@ -738,6 +743,7 @@ issue_3420_5: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -765,6 +771,7 @@ issue_3420_6: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -783,6 +790,7 @@ issue_3420_7: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -827,6 +835,7 @@ issue_4291_1: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -847,6 +856,7 @@ issue_4291_2: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a = function() {
|
var a = function() {
|
||||||
@@ -857,8 +867,8 @@ issue_4291_2: {
|
|||||||
console.log(a[1], a[0], a.length);
|
console.log(a[1], a[0], a.length);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = function(argument_0) {
|
var a = function() {
|
||||||
if (argument_0)
|
if (arguments[0])
|
||||||
arguments[1] = "PASS";
|
arguments[1] = "PASS";
|
||||||
return arguments;
|
return arguments;
|
||||||
}(42);
|
}(42);
|
||||||
@@ -871,6 +881,7 @@ issue_4397: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(typeof function() {
|
console.log(typeof function() {
|
||||||
@@ -977,3 +988,48 @@ issue_4432: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4696: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
for (arguments in [ 42 ]);
|
||||||
|
for (var a in arguments[0])
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
for (arguments in [ 42 ]);
|
||||||
|
for (var a in arguments[0])
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4809: {
|
||||||
|
options = {
|
||||||
|
arguments: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = 0;
|
||||||
|
(function() {
|
||||||
|
arguments[A] = "PASS";
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = 0;
|
||||||
|
(function() {
|
||||||
|
arguments[A] = "PASS";
|
||||||
|
console.log(arguments[0]);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -355,3 +355,72 @@ constructor_good: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
expect_warnings: []
|
expect_warnings: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe_evaluate_modified_binary: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
(console && a).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
(console && a).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_evaluate_modified_conditional: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
(console ? a : []).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
(console ? a : []).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_evaluate_modified_sequence: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a) {
|
||||||
|
(0, a).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a) {
|
||||||
|
(0, a).push(1);
|
||||||
|
if (a.length)
|
||||||
|
console.log("PASS");
|
||||||
|
})([]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ destructured_funarg: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
await_parenthesis: {
|
await_parentheses: {
|
||||||
input: {
|
input: {
|
||||||
async function f() {
|
async function f() {
|
||||||
await (a => a);
|
await (a => a);
|
||||||
@@ -43,7 +43,7 @@ await_parenthesis: {
|
|||||||
expect_exact: "async function f(){await(a=>a)}"
|
expect_exact: "async function f(){await(a=>a)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_parenthesis_init: {
|
for_parentheses_init: {
|
||||||
input: {
|
input: {
|
||||||
for (a => (a in a); console.log(42););
|
for (a => (a in a); console.log(42););
|
||||||
}
|
}
|
||||||
@@ -52,7 +52,7 @@ for_parenthesis_init: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_parenthesis_condition: {
|
for_parentheses_condition: {
|
||||||
input: {
|
input: {
|
||||||
for (console.log(42); a => (a in a);)
|
for (console.log(42); a => (a in a);)
|
||||||
break;
|
break;
|
||||||
@@ -62,7 +62,7 @@ for_parenthesis_condition: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_parenthesis_step: {
|
for_parentheses_step: {
|
||||||
input: {
|
input: {
|
||||||
for (; console.log(42); a => (a in a));
|
for (; console.log(42); a => (a in a));
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ for_parenthesis_step: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_assign_parenthesis_init: {
|
for_assign_parentheses_init: {
|
||||||
input: {
|
input: {
|
||||||
for (f = a => (a in a); console.log(42););
|
for (f = a => (a in a); console.log(42););
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ for_assign_parenthesis_init: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_assign_parenthesis_condition: {
|
for_assign_parentheses_condition: {
|
||||||
input: {
|
input: {
|
||||||
for (console.log(42); f = a => (a in a);)
|
for (console.log(42); f = a => (a in a);)
|
||||||
break;
|
break;
|
||||||
@@ -90,7 +90,7 @@ for_assign_parenthesis_condition: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_assign_parenthesis_step: {
|
for_assign_parentheses_step: {
|
||||||
input: {
|
input: {
|
||||||
for (; console.log(42); f = a => (a in a));
|
for (; console.log(42); f = a => (a in a));
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ for_assign_parenthesis_step: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_declaration_parenthesis_init: {
|
for_declaration_parentheses_init: {
|
||||||
input: {
|
input: {
|
||||||
for (var f = a => (a in a); console.log(42););
|
for (var f = a => (a in a); console.log(42););
|
||||||
}
|
}
|
||||||
@@ -108,7 +108,7 @@ for_declaration_parenthesis_init: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
for_statement_parenthesis_init: {
|
for_statement_parentheses_init: {
|
||||||
input: {
|
input: {
|
||||||
for (a => {
|
for (a => {
|
||||||
a in a;
|
a in a;
|
||||||
@@ -276,6 +276,7 @@ drop_arguments: {
|
|||||||
options = {
|
options = {
|
||||||
arguments: true,
|
arguments: true,
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
@@ -456,6 +457,7 @@ collapse_property_lambda: {
|
|||||||
|
|
||||||
drop_return: {
|
drop_return: {
|
||||||
options = {
|
options = {
|
||||||
|
arrows: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -474,6 +476,21 @@ drop_return: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop_value: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
((a, b) => a + b)(console.log(42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
((a, b) => {})(console.log(42));
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
reduce_iife_1: {
|
reduce_iife_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -678,3 +695,122 @@ issue_4476: {
|
|||||||
expect_stdout: "foo bar"
|
expect_stdout: "foo bar"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4666: {
|
||||||
|
input: {
|
||||||
|
console.log((a => /[0-9]/.test(a))(42));
|
||||||
|
}
|
||||||
|
expect_exact: "console.log((a=>/[0-9]/.test(a))(42));"
|
||||||
|
expect_stdout: "true"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4685_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(f) {
|
||||||
|
if (f() !== this)
|
||||||
|
console.log("PASS");
|
||||||
|
}(() => this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(f) {
|
||||||
|
if (f() !== this)
|
||||||
|
console.log("PASS");
|
||||||
|
}(() => this);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4685_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(f) {
|
||||||
|
if (f() !== this)
|
||||||
|
console.log("PASS");
|
||||||
|
}(() => {
|
||||||
|
if (console)
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(f) {
|
||||||
|
if (f() !== this)
|
||||||
|
console.log("PASS");
|
||||||
|
}(() => {
|
||||||
|
if (console)
|
||||||
|
return this;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4687_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function() {
|
||||||
|
console.log(function(f) {
|
||||||
|
return f() === this;
|
||||||
|
}(() => this) || "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function() {
|
||||||
|
console.log(function(f) {
|
||||||
|
return f() === this;
|
||||||
|
}(() => this) || "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4687_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function() {
|
||||||
|
console.log(function(f) {
|
||||||
|
return f() === this;
|
||||||
|
}(() => {
|
||||||
|
if (console)
|
||||||
|
return this;
|
||||||
|
}) || "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function() {
|
||||||
|
console.log(function(f) {
|
||||||
|
return f() === this;
|
||||||
|
}(() => {
|
||||||
|
if (console)
|
||||||
|
return this;
|
||||||
|
}) || "PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4772: {
|
||||||
|
input: {
|
||||||
|
var f = a => (a)
|
||||||
|
/**/ console.log(f("PASS"));
|
||||||
|
}
|
||||||
|
expect_exact: 'var f=a=>a;console.log(f("PASS"));'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -475,3 +475,229 @@ issue_4521: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logical_assignments: {
|
||||||
|
input: {
|
||||||
|
var a = 42, b = null, c;
|
||||||
|
a &&= "foo";
|
||||||
|
b ||= "bar";
|
||||||
|
c ??= "baz";
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=42,b=null,c;a&&="foo";b||="bar";c??="baz";console.log(a,b,c);'
|
||||||
|
expect_stdout: "foo bar baz"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
logical_collapse_vars: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL", b = false;
|
||||||
|
a = "PASS";
|
||||||
|
b ??= a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL", b = false;
|
||||||
|
a = "PASS";
|
||||||
|
b ??= a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
logical_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b = 42;
|
||||||
|
b ??= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b = 42;
|
||||||
|
b ??= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
logical_side_effects: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b = 42;
|
||||||
|
b ??= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b = 42;
|
||||||
|
b ??= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4815_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
42..p &&= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
42..p &&= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4815_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
42..p &&= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
42..p &&= a = "FAIL";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4819: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(void 0 === ([].p &&= 42));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void 0 === ([].p &&= 42));
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4827_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = A, b = "PASS", c;
|
||||||
|
c &&= b = a, console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "FAIL";
|
||||||
|
var a = A, b = "PASS", c;
|
||||||
|
c &&= b = a, console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4827_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = "PASS";
|
||||||
|
function f(c) {
|
||||||
|
a++,
|
||||||
|
c &&= b = a;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = "PASS";
|
||||||
|
a++,
|
||||||
|
c &&= b = a;
|
||||||
|
var c;
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4827_3: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b, c;
|
||||||
|
a++;
|
||||||
|
c &&= b = a;
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b, c;
|
||||||
|
a++;
|
||||||
|
c &&= b = a;
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4876: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
var a = null;
|
||||||
|
var b = a &&= 42;
|
||||||
|
b.p;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
var a = null;
|
||||||
|
var b = a &&= 42;
|
||||||
|
b.p;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=15"
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,16 +23,34 @@ async_label: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await_await: {
|
await_await: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
input: {
|
input: {
|
||||||
(async function() {
|
(async function() {
|
||||||
|
await await {
|
||||||
|
then(resolve) {
|
||||||
|
resolve({
|
||||||
|
then() {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
await await 42;
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(async function() {
|
(async function() {
|
||||||
|
await {
|
||||||
|
then(resolve) {
|
||||||
|
resolve({
|
||||||
|
then() {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
await await 42;
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -546,7 +564,7 @@ drop_return: {
|
|||||||
input: {
|
input: {
|
||||||
(async function(a) {
|
(async function(a) {
|
||||||
while (!console);
|
while (!console);
|
||||||
return console.log(a);
|
return !console.log(a);
|
||||||
})(42);
|
})(42);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
@@ -596,14 +614,14 @@ functions: {
|
|||||||
async function b() {
|
async function b() {
|
||||||
return !!b;
|
return !!b;
|
||||||
}
|
}
|
||||||
var c = async function(c) {
|
async function c(c) {
|
||||||
return c;
|
return c;
|
||||||
};
|
|
||||||
if (await c(await b(await a()))) {
|
|
||||||
async function d() {}
|
|
||||||
async function e() {
|
|
||||||
return typeof e;
|
|
||||||
}
|
}
|
||||||
|
if (await c(await b(await a()))) {
|
||||||
|
var d = async function() {};
|
||||||
|
var e = async function y() {
|
||||||
|
return typeof y;
|
||||||
|
};
|
||||||
var f = async function(f) {
|
var f = async function(f) {
|
||||||
return f;
|
return f;
|
||||||
};
|
};
|
||||||
@@ -654,9 +672,9 @@ functions_use_strict: {
|
|||||||
async function b() {
|
async function b() {
|
||||||
return !!b;
|
return !!b;
|
||||||
}
|
}
|
||||||
var c = async function(c) {
|
async function c(c) {
|
||||||
return c;
|
return c;
|
||||||
};
|
}
|
||||||
if (await c(await b(await a()))) {
|
if (await c(await b(await a()))) {
|
||||||
var d = async function() {};
|
var d = async function() {};
|
||||||
var e = async function y() {
|
var e = async function y() {
|
||||||
@@ -673,6 +691,54 @@ functions_use_strict: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
functions_anonymous: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var await = async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
};
|
||||||
|
await(await);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
async function await() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
functions_inner_var: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var await = function a() {
|
||||||
|
var a;
|
||||||
|
console.log(a, a);
|
||||||
|
};
|
||||||
|
await(await);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function await() {
|
||||||
|
var a;
|
||||||
|
console.log(a, a);
|
||||||
|
}
|
||||||
|
await();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined undefined"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4335_1: {
|
issue_4335_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -1218,3 +1284,250 @@ issue_4598: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4618: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
var await = async function f() {
|
||||||
|
console || f();
|
||||||
|
};
|
||||||
|
console.log;
|
||||||
|
return await;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
var await = async function f() {
|
||||||
|
console || f();
|
||||||
|
};
|
||||||
|
console.log;
|
||||||
|
return await;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4717: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
async function f() {
|
||||||
|
var a = function() {
|
||||||
|
await;
|
||||||
|
}();
|
||||||
|
return "FAIL";
|
||||||
|
}
|
||||||
|
return f();
|
||||||
|
})().then(console.log).catch(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return function() {
|
||||||
|
await;
|
||||||
|
}(), "FAIL";
|
||||||
|
})().then(console.log).catch(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4738_1: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4738_2: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
get then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
get then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4738_3: {
|
||||||
|
options = {
|
||||||
|
awaits: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
then: function() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
await {
|
||||||
|
then: function() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4747: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
async function f() {
|
||||||
|
a = "PASS";
|
||||||
|
null.p += "PASS";
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
return a;
|
||||||
|
}("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
(async function() {
|
||||||
|
a = "PASS";
|
||||||
|
null.p += "PASS";
|
||||||
|
})();
|
||||||
|
return a;
|
||||||
|
}("FAIL"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4764_1: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {
|
||||||
|
return {
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function() {
|
||||||
|
return {
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4764_2: {
|
||||||
|
options = {
|
||||||
|
arrows: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async () => ({
|
||||||
|
get then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}))();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async () => ({
|
||||||
|
get then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}))();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4764_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function(o) {
|
||||||
|
return o;
|
||||||
|
})({
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(async function(o) {
|
||||||
|
return o;
|
||||||
|
})({
|
||||||
|
then() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
@@ -60,3 +60,33 @@ issue_4590: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=10"
|
node_version: ">=10"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4801: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
(function(a) {
|
||||||
|
A = 42;
|
||||||
|
a || A;
|
||||||
|
})(!(0 == 42 >> 0o644n));
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
(function(a) {
|
||||||
|
0 != (A = 42) >> 0o644n || A;
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|||||||
1565
test/compress/classes.js
Normal file
1565
test/compress/classes.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -958,8 +958,7 @@ collapse_vars_misc: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f0(o, a, h) {
|
function f0(o, a, h) {
|
||||||
var b = 3 - a;
|
return o.run(3 - a)[7] = h;
|
||||||
return o.run(b)[7] = h;
|
|
||||||
}
|
}
|
||||||
function f1(x) { return 5 - x }
|
function f1(x) { return 5 - x }
|
||||||
function f2(x) { return foo() / (5 - x) }
|
function f2(x) { return foo() / (5 - x) }
|
||||||
@@ -2276,8 +2275,8 @@ var_defs: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var f1 = function(x, y) {
|
var f1 = function(x, y) {
|
||||||
var r = x + y, z = r * r - r, b = 7;
|
var r = x + y;
|
||||||
console.log(z + b);
|
console.log(r * r - r + 7);
|
||||||
};
|
};
|
||||||
f1("1", 0);
|
f1("1", 0);
|
||||||
}
|
}
|
||||||
@@ -2869,7 +2868,7 @@ lvalues_def: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
compound_assignment: {
|
compound_assignment_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
}
|
}
|
||||||
@@ -2888,6 +2887,23 @@ compound_assignment: {
|
|||||||
expect_stdout: "4"
|
expect_stdout: "4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compound_assignment_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
for (a += a + 2; console.log(a););
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a = 1;
|
||||||
|
for (a += a + 2; console.log(a););
|
||||||
|
}
|
||||||
|
expect_stdout: "4"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2187_1: {
|
issue_2187_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -2907,8 +2923,7 @@ issue_2187_1: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
!function(foo) {
|
!function(foo) {
|
||||||
foo();
|
foo();
|
||||||
var a = 2;
|
console.log(2);
|
||||||
console.log(a);
|
|
||||||
}(function() {
|
}(function() {
|
||||||
console.log(a);
|
console.log(a);
|
||||||
});
|
});
|
||||||
@@ -4709,7 +4724,7 @@ cascade_statement: {
|
|||||||
}
|
}
|
||||||
function f3(a, b) {
|
function f3(a, b) {
|
||||||
for (; a < b; a++)
|
for (; a < b; a++)
|
||||||
if ((c = a) && b)
|
if (c = a, a && b)
|
||||||
var c = c = b(a);
|
var c = c = b(a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5879,6 +5894,7 @@ collapse_rhs_this: {
|
|||||||
collapse_rhs_undefined: {
|
collapse_rhs_undefined: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a, b;
|
var a, b;
|
||||||
@@ -6960,8 +6976,7 @@ sequence_in_iife_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "foo", b = 42;
|
var a = "foo", b = 42;
|
||||||
b = a;
|
console.log(a, b = a);
|
||||||
console.log(a, b);
|
|
||||||
}
|
}
|
||||||
expect_stdout: "foo foo"
|
expect_stdout: "foo foo"
|
||||||
}
|
}
|
||||||
@@ -8049,6 +8064,67 @@ mangleable_var: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mangleable_assignment_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return 6;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(function() {
|
||||||
|
var a, b = a = o.p();
|
||||||
|
console.log(a * (b / a + b));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return 6;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(function() {
|
||||||
|
var a;
|
||||||
|
a = o.p();
|
||||||
|
console.log(a * (a / a + a));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
mangleable_assignment_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return 6;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(function(a, b) {
|
||||||
|
b = a = o.p();
|
||||||
|
console.log(a * (b / a + b));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
p: function() {
|
||||||
|
return 6;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(function(a, b) {
|
||||||
|
a = o.p();
|
||||||
|
console.log(a * (a / a + a));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3884_1: {
|
issue_3884_1: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -8484,7 +8560,7 @@ issue_4047_1: {
|
|||||||
expect: {
|
expect: {
|
||||||
var b = 1;
|
var b = 1;
|
||||||
var a;
|
var a;
|
||||||
console.log((a = --b + ((a = 0) !== typeof A), +void ((a >>= 0) && console.log("PASS"))));
|
console.log((a = --b + (0 !== typeof A), +void ((a >>= 0) && console.log("PASS"))));
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"PASS",
|
"PASS",
|
||||||
@@ -8755,3 +8831,392 @@ issue_4586_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4732_1: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function(b) {
|
||||||
|
var b = a++;
|
||||||
|
var c = b ? b && console.log("PASS") : 0;
|
||||||
|
})(a++);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(b) {
|
||||||
|
(b = a++) && (b && console.log("PASS"));
|
||||||
|
})(a++);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4732_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function(b) {
|
||||||
|
var b = a++;
|
||||||
|
var c = b ? b && console.log("PASS") : 0;
|
||||||
|
})(a++);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(b) {
|
||||||
|
(b = a++) && b && console.log("PASS");
|
||||||
|
})(a++);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_in_try: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o, a = 6, b = 7, c;
|
||||||
|
try {
|
||||||
|
c = a * b;
|
||||||
|
o.p(c);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o, a = 6, b = 7, c;
|
||||||
|
try {
|
||||||
|
c = a * b;
|
||||||
|
o.p(c);
|
||||||
|
} catch (e) {
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_non_local: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o, a = 6, b = 7, c;
|
||||||
|
function f() {
|
||||||
|
c = a * b;
|
||||||
|
o.p(c);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o, a = 6, b = 7, c;
|
||||||
|
function f() {
|
||||||
|
c = a * b;
|
||||||
|
o.p(c);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4806: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, o = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === o ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(a = 42, o.f)(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, o = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === o ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(0, o.f)(a = 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4852: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
switch (b = a) {
|
||||||
|
case 42:
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} catch (b) {
|
||||||
|
b.p;
|
||||||
|
}
|
||||||
|
case console.log(b):
|
||||||
|
}
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS";
|
||||||
|
(function(b) {
|
||||||
|
switch (a) {
|
||||||
|
case 42:
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} catch (b) {
|
||||||
|
b.p;
|
||||||
|
}
|
||||||
|
case console.log(a):
|
||||||
|
}
|
||||||
|
})("FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4865: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var NaN;
|
||||||
|
var a = NaN = "PASS";
|
||||||
|
console.log(a, NaN);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var NaN;
|
||||||
|
var a = NaN = "PASS";
|
||||||
|
console.log(a, NaN);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4868: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
console.log(b[0]);
|
||||||
|
})(a = [ "PASS" ], a = [ "FAIL" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
(function(b) {
|
||||||
|
console.log(b[0]);
|
||||||
|
})(a = [ "PASS" ], a = [ "FAIL" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4874: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
a = null;
|
||||||
|
(function(b) {
|
||||||
|
for (var c in b = b && b[console.log("PASS")])
|
||||||
|
console;
|
||||||
|
})(a = 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
null;
|
||||||
|
(function(b) {
|
||||||
|
for (var c in a && a[console.log("PASS")])
|
||||||
|
console;
|
||||||
|
})(a = 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4891: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b;
|
||||||
|
a++;
|
||||||
|
console.log(b = a, b);
|
||||||
|
b--;
|
||||||
|
a.a += 0;
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b;
|
||||||
|
a++;
|
||||||
|
console.log(a, b = a);
|
||||||
|
b--;
|
||||||
|
a.a += 0;
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"1 1",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4895: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b;
|
||||||
|
(function f() {
|
||||||
|
a = 42;
|
||||||
|
})();
|
||||||
|
console.log((b = a) || b, b += 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b;
|
||||||
|
(function f() {
|
||||||
|
a = 42;
|
||||||
|
})();
|
||||||
|
console.log((b = a) || b, b += 0);
|
||||||
|
}
|
||||||
|
expect_stdout: "42 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4908: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
var b;
|
||||||
|
console || a++;
|
||||||
|
var c = d = a, d = [ c && c, d += 42 ];
|
||||||
|
console.log(d[1]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b;
|
||||||
|
console || a++;
|
||||||
|
var c = a, d = [ (d = a) && d, d += 42 ];
|
||||||
|
console.log(d[1]);
|
||||||
|
}
|
||||||
|
expect_stdout: "42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4910: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo", b;
|
||||||
|
var c = b = a;
|
||||||
|
1 && c[a = "bar"];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo", b;
|
||||||
|
var c = b = a;
|
||||||
|
1 && b[a = "bar"];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "bar foo"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4914: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function f() {
|
||||||
|
f.__proto__ = 42;
|
||||||
|
return f.__proto__;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function f() {
|
||||||
|
f.__proto__ = 42;
|
||||||
|
return f.__proto__;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4918: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
({
|
||||||
|
get 42() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}[a = "PASS", 42] += "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
({
|
||||||
|
get 42() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
}[a = "PASS", 42] += "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4920: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
({
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
})[b = a];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "PASS", b;
|
||||||
|
({
|
||||||
|
get PASS() {
|
||||||
|
a = "FAIL";
|
||||||
|
},
|
||||||
|
})[b = a];
|
||||||
|
console.log(b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1861,3 +1861,39 @@ issue_3808_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: " PASS"
|
expect_stdout: " PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_super: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Object.setPrototypeOf({
|
||||||
|
f(a) {
|
||||||
|
a ? this.g("FAIL") : super.g("FAIL");
|
||||||
|
},
|
||||||
|
g(b) {
|
||||||
|
console.log(b);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
g() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}).f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
Object.setPrototypeOf({
|
||||||
|
f(a) {
|
||||||
|
a ? this.g("FAIL") : super.g("FAIL");
|
||||||
|
},
|
||||||
|
g(b) {
|
||||||
|
console.log(b);
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
g() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
}).f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -1434,3 +1434,104 @@ issue_4527: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "aaaa"
|
expect_stdout: "aaaa"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4689: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
for (const a in 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
for (const a in 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4691: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function A() {}
|
||||||
|
A.prototype.f = function() {
|
||||||
|
if (!this)
|
||||||
|
return;
|
||||||
|
const a = "PA";
|
||||||
|
function g(b) {
|
||||||
|
h(a + b);
|
||||||
|
}
|
||||||
|
[ "SS" ].forEach(function(c) {
|
||||||
|
g(c);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
function h(d) {
|
||||||
|
console.log(d);
|
||||||
|
}
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function A() {}
|
||||||
|
A.prototype.f = function() {
|
||||||
|
if (this) {
|
||||||
|
const a = "PA";
|
||||||
|
[ "SS" ].forEach(function(c) {
|
||||||
|
g(c);
|
||||||
|
});
|
||||||
|
function g(b) {
|
||||||
|
h(a + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function h(d) {
|
||||||
|
console.log(d);
|
||||||
|
}
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4848: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
a(function() {
|
||||||
|
console.log(b);
|
||||||
|
});
|
||||||
|
if (!console)
|
||||||
|
return;
|
||||||
|
const b = "PASS";
|
||||||
|
}
|
||||||
|
var g;
|
||||||
|
f(function(h) {
|
||||||
|
g = h;
|
||||||
|
});
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
a(function() {
|
||||||
|
console.log(b);
|
||||||
|
});
|
||||||
|
if (!console)
|
||||||
|
return;
|
||||||
|
const b = "PASS";
|
||||||
|
}
|
||||||
|
var g;
|
||||||
|
f(function(h) {
|
||||||
|
g = h;
|
||||||
|
});
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,16 +53,17 @@ dead_code_2_should_warn: {
|
|||||||
g();
|
g();
|
||||||
x = 10;
|
x = 10;
|
||||||
throw new Error("foo");
|
throw new Error("foo");
|
||||||
|
{
|
||||||
var x;
|
var x;
|
||||||
function g(){};
|
function g(){};
|
||||||
}
|
}
|
||||||
|
}
|
||||||
f();
|
f();
|
||||||
}
|
}
|
||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
expect_warnings: [
|
expect_warnings: [
|
||||||
"WARN: Dropping unreachable code [test/compress/dead-code.js:8,12]",
|
"WARN: Dropping unreachable code [test/compress/dead-code.js:8,12]",
|
||||||
]
|
]
|
||||||
node_version: "<=4"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dead_code_constant_boolean_should_warn_more: {
|
dead_code_constant_boolean_should_warn_more: {
|
||||||
@@ -88,8 +89,10 @@ dead_code_constant_boolean_should_warn_more: {
|
|||||||
bar();
|
bar();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
{
|
||||||
var foo;
|
var foo;
|
||||||
function bar() {}
|
function bar() {}
|
||||||
|
}
|
||||||
// nothing for the while
|
// nothing for the while
|
||||||
// as for the for, it should keep:
|
// as for the for, it should keep:
|
||||||
var x = 10, y;
|
var x = 10, y;
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ inline_side_effects_2: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 42;
|
var a = 42;
|
||||||
[ 0[0] = --a ] = [ console ];
|
[ [].e = --a ] = [ console ];
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
@@ -1477,7 +1477,7 @@ issue_4502_4: {
|
|||||||
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
(function(a, b = console.log("FAIL")) {})(..."" + console.log(42));
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
[ , 0[0] = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
[ , [].e = console.log("FAIL") ] = [ ..."" + console.log(42) ];
|
||||||
}
|
}
|
||||||
expect_stdout: "42"
|
expect_stdout: "42"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
@@ -1661,3 +1661,71 @@ issue_4588_2_evaluate: {
|
|||||||
expect_stdout: "1"
|
expect_stdout: "1"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4817: {
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
inline: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a = console.log(typeof f)) {
|
||||||
|
return 42;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a = console.log(typeof f)) {
|
||||||
|
return 42;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4854: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
inline: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
(function(b = a = "foo") {
|
||||||
|
[] = "foo";
|
||||||
|
})();
|
||||||
|
a;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(void ([] = "foo"));
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4916: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
(function(b = "foo") {
|
||||||
|
b.value = "FAIL";
|
||||||
|
b;
|
||||||
|
log(b.value);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
(function(b = "foo") {
|
||||||
|
b.value = "FAIL";
|
||||||
|
b;
|
||||||
|
log(b.value);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2371,6 +2371,7 @@ function_parameter_ie8: {
|
|||||||
issue_3664: {
|
issue_3664: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
@@ -2381,7 +2382,7 @@ issue_3664: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
console.log(function() {
|
console.log(function() {
|
||||||
var b = ([ b && console.log("FAIL") ].p = 0, 0);
|
var a, b = (a = (a = [ b && console.log("FAIL") ]).p = 0, 0);
|
||||||
return "PASS";
|
return "PASS";
|
||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
@@ -2391,6 +2392,7 @@ issue_3664: {
|
|||||||
issue_3673: {
|
issue_3673: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -2401,8 +2403,6 @@ issue_3673: {
|
|||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a;
|
|
||||||
(a = [ a ]).p = 42;
|
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -3251,3 +3251,222 @@ issue_4558_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4662: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
function f(b, c) {
|
||||||
|
console.log(b, c);
|
||||||
|
}
|
||||||
|
f(++a, a = a, a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function(b, c) {
|
||||||
|
console.log(b, c);
|
||||||
|
})(++a, a = 1);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4806_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a;
|
||||||
|
(a = 42, O.f)();
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(0, O.f)();
|
||||||
|
42;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4806_2: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a;
|
||||||
|
(a = 42, O.f)();
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
(0, O.f)();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4806_3: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var a;
|
||||||
|
(a = 42, O.f)();
|
||||||
|
a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
O = {
|
||||||
|
f: function() {
|
||||||
|
console.log(this === O ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(0, O.f)();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4834: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
new function(a, b) {
|
||||||
|
b;
|
||||||
|
b.p;
|
||||||
|
}(42);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
void b.p;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
var b;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4912_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = A = function() {};
|
||||||
|
A;
|
||||||
|
a.prototype = {
|
||||||
|
f: function() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = A = function() {};
|
||||||
|
A;
|
||||||
|
a.prototype = {
|
||||||
|
f: function() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4912_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function() {
|
||||||
|
var g, f = function() {};
|
||||||
|
f.p = {};
|
||||||
|
(g = f.p.q = function() {}).r = "PASS";
|
||||||
|
return f;
|
||||||
|
}().p.q.r);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function() {
|
||||||
|
var g, f = function() {};
|
||||||
|
f.p = {};
|
||||||
|
(g = f.p.q = function() {}).r = "PASS";
|
||||||
|
return f;
|
||||||
|
}().p.q.r);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4912_3: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(f, g) {
|
||||||
|
f = function() {};
|
||||||
|
f.p = {};
|
||||||
|
g = f.p.q = function() {};
|
||||||
|
g.r = "PASS";
|
||||||
|
return f;
|
||||||
|
}().p.q.r);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(f, g) {
|
||||||
|
f = function() {};
|
||||||
|
f.p = {};
|
||||||
|
g = f.p.q = function() {};
|
||||||
|
g.r = "PASS";
|
||||||
|
return f;
|
||||||
|
}().p.q.r);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -399,18 +399,18 @@ unsafe_object_accessor: {
|
|||||||
function f() {
|
function f() {
|
||||||
var a = {
|
var a = {
|
||||||
get b() {},
|
get b() {},
|
||||||
set b() {}
|
set b(v) {},
|
||||||
};
|
};
|
||||||
return {a:a};
|
return { a: a };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f() {
|
function f() {
|
||||||
var a = {
|
var a = {
|
||||||
get b() {},
|
get b() {},
|
||||||
set b() {}
|
set b(v) {},
|
||||||
};
|
};
|
||||||
return {a:a};
|
return { a: a };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -847,6 +847,8 @@ unsafe_charAt_noop: {
|
|||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
s = "foo";
|
||||||
|
x = 42;
|
||||||
console.log(
|
console.log(
|
||||||
s.charAt(0),
|
s.charAt(0),
|
||||||
"string".charAt(x),
|
"string".charAt(x),
|
||||||
@@ -854,12 +856,15 @@ unsafe_charAt_noop: {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
|
s = "foo";
|
||||||
|
x = 42;
|
||||||
console.log(
|
console.log(
|
||||||
s[0],
|
s[0] || "",
|
||||||
"string"[0 | x],
|
"string"[0 | x] || "",
|
||||||
(typeof x)[0]
|
(typeof x)[0] || ""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "f n"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_1649: {
|
issue_1649: {
|
||||||
@@ -3176,3 +3181,23 @@ issue_4552: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "NaN"
|
expect_stdout: "NaN"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4886: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log("length" in {
|
||||||
|
__proto__: function() {},
|
||||||
|
length: void 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("length" in {
|
||||||
|
__proto__: function() {},
|
||||||
|
length: void 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_stdout: "true"
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,6 +43,28 @@ await: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assignment_1: {
|
||||||
|
input: {
|
||||||
|
var a = 2;
|
||||||
|
a **= 5;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: "var a=2;a**=5;console.log(a);"
|
||||||
|
expect_stdout: "32"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
assignment_2: {
|
||||||
|
input: {
|
||||||
|
var a = 8n;
|
||||||
|
a **= a;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: "var a=8n;a**=a;console.log(a);"
|
||||||
|
expect_stdout: "16777216n"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
evaluate: {
|
evaluate: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -56,3 +78,70 @@ evaluate: {
|
|||||||
expect_stdout: "5"
|
expect_stdout: "5"
|
||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4664: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
new function(a) {
|
||||||
|
console.log(typeof f, a, typeof this);
|
||||||
|
}((A = 0, (NaN ^ 1) * 2 ** 30), 0);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f() {
|
||||||
|
new function(a) {
|
||||||
|
console.log(typeof f, 1073741824, typeof this);
|
||||||
|
}(A = 0);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "function 1073741824 object"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4715: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = 1;
|
||||||
|
console.log((-0) ** A + 0);
|
||||||
|
console.log((-0) ** A - 0);
|
||||||
|
console.log((-0) ** A * 1);
|
||||||
|
console.log((-0) ** A / 1);
|
||||||
|
console.log(Math.pow(-0, A) + 0);
|
||||||
|
console.log(Math.pow(-0, A) - 0);
|
||||||
|
console.log(Math.pow(-0, A) * 1);
|
||||||
|
console.log(Math.pow(-0, A) / 1);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = 1;
|
||||||
|
console.log((-0) ** A + 0);
|
||||||
|
console.log((-0) ** A);
|
||||||
|
console.log((-0) ** A * 1);
|
||||||
|
console.log((-0) ** A);
|
||||||
|
console.log(Math.pow(-0, A) + 0);
|
||||||
|
console.log(+Math.pow(-0, A));
|
||||||
|
console.log(+Math.pow(-0, A));
|
||||||
|
console.log(+Math.pow(-0, A));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"-0",
|
||||||
|
"-0",
|
||||||
|
"-0",
|
||||||
|
"0",
|
||||||
|
"-0",
|
||||||
|
"-0",
|
||||||
|
"-0",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
498
test/compress/exports.js
Normal file
498
test/compress/exports.js
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
refs: {
|
||||||
|
input: {
|
||||||
|
export {};
|
||||||
|
export { a, b as B, c as case, d as default };
|
||||||
|
}
|
||||||
|
expect_exact: "export{};export{a,b as B,c as case,d as default};"
|
||||||
|
}
|
||||||
|
|
||||||
|
var_defs: {
|
||||||
|
input: {
|
||||||
|
export const a = 1;
|
||||||
|
export let b = 2, c = 3;
|
||||||
|
export var { d, e: [] } = f;
|
||||||
|
}
|
||||||
|
expect_exact: "export const a=1;export let b=2,c=3;export var{d,e:[]}=f;"
|
||||||
|
}
|
||||||
|
|
||||||
|
defuns: {
|
||||||
|
input: {
|
||||||
|
export class A {}
|
||||||
|
export function e() {}
|
||||||
|
export function* f(a) {}
|
||||||
|
export async function g(b, c) {}
|
||||||
|
export async function* h({}, ...[]) {}
|
||||||
|
}
|
||||||
|
expect_exact: "export class A{}export function e(){}export function*f(a){}export async function g(b,c){}export async function*h({},...[]){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults: {
|
||||||
|
input: {
|
||||||
|
export default 42;
|
||||||
|
export default async;
|
||||||
|
export default (x, y) => x * x;
|
||||||
|
export default class {};
|
||||||
|
export default function*(a, b) {};
|
||||||
|
export default async function f({ c }, ...[ d ]) {};
|
||||||
|
}
|
||||||
|
expect_exact: "export default 42;export default async;export default(x,y)=>x*x;export default class{}export default function*(a,b){}export default async function f({c},...[d]){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_1: {
|
||||||
|
input: {
|
||||||
|
export default function() {
|
||||||
|
console.log("FAIL");
|
||||||
|
}(console.log("PASS"));
|
||||||
|
}
|
||||||
|
expect_exact: 'export default function(){console.log("FAIL")}console.log("PASS");'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_2: {
|
||||||
|
input: {
|
||||||
|
export default (async function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: 'export default(async function(){console.log("PASS")})();'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_3: {
|
||||||
|
input: {
|
||||||
|
export default (42, "PASS");
|
||||||
|
}
|
||||||
|
expect_exact: 'export default(42,"PASS");'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_4: {
|
||||||
|
input: {
|
||||||
|
export default (function f() {});
|
||||||
|
}
|
||||||
|
expect_exact: "export default(function f(){});"
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_5: {
|
||||||
|
input: {
|
||||||
|
export default (function(a) {
|
||||||
|
console.log(a[0]);
|
||||||
|
}`PASS`);
|
||||||
|
}
|
||||||
|
expect_exact: "export default(function(a){console.log(a[0])})`PASS`;"
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_parentheses_6: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default !function() {
|
||||||
|
while (!console);
|
||||||
|
}() ? "PASS" : "FAIL";
|
||||||
|
}
|
||||||
|
expect_exact: 'export default(function(){while(!console);})()?"FAIL":"PASS";'
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults_regexp: {
|
||||||
|
input: {
|
||||||
|
export default /foo/;
|
||||||
|
}
|
||||||
|
expect_exact: "export default/foo/;"
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign: {
|
||||||
|
input: {
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
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";'
|
||||||
|
}
|
||||||
|
|
||||||
|
same_quotes: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
quote_style: 3,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export * from 'foo';
|
||||||
|
export {} from "bar";
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"export * from 'foo';",
|
||||||
|
"",
|
||||||
|
'export {} from "bar";',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_unused: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default 42;
|
||||||
|
export default (x, y) => x * x;
|
||||||
|
export default class A extends B { get p() { h() } }
|
||||||
|
export default function*(a, b) {}
|
||||||
|
export default async function f({ c }, ...[ d ]) {}
|
||||||
|
export var e;
|
||||||
|
export function g(x, [ y ], ...z) {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export default 42;
|
||||||
|
export default (x, y) => x * x;
|
||||||
|
export default class extends B { get p() { h() } }
|
||||||
|
export default function*(a, b) {}
|
||||||
|
export default async function({}) {}
|
||||||
|
export var e;
|
||||||
|
export function g(x, []) {}
|
||||||
|
function h() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle: {
|
||||||
|
rename = false
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 42;
|
||||||
|
export let b, { foo: c } = a;
|
||||||
|
export function f(d, { [b]: e }) {
|
||||||
|
d(e, f);
|
||||||
|
}
|
||||||
|
export default a;
|
||||||
|
export default async function g(x, ...{ [c]: y }) {
|
||||||
|
(await x)(g, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const t = 42;
|
||||||
|
export let b, { foo: c } = t;
|
||||||
|
export function f(t, { [b]: o }) {
|
||||||
|
t(o, f);
|
||||||
|
}
|
||||||
|
export default t;
|
||||||
|
export default async function e(t, ...{ [c]: o}) {
|
||||||
|
(await t)(e, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle_rename: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 42;
|
||||||
|
export let b, { foo: c } = a;
|
||||||
|
export function f(d, { [b]: e }) {
|
||||||
|
d(e, f);
|
||||||
|
}
|
||||||
|
export default a;
|
||||||
|
export default async function g(x, ...{ [c]: y }) {
|
||||||
|
(await x)(g, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
const t = 42;
|
||||||
|
export let b, { foo: c } = t;
|
||||||
|
export function f(t, { [b]: o }) {
|
||||||
|
t(o, f);
|
||||||
|
}
|
||||||
|
export default t;
|
||||||
|
export default async function e(t, ...{ [c]: o}) {
|
||||||
|
(await t)(e, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_exports_1: {
|
||||||
|
options = {
|
||||||
|
hoist_exports: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export { a };
|
||||||
|
export var b;
|
||||||
|
export function f() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b;
|
||||||
|
function f() {}
|
||||||
|
export { a, b, f };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_exports_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_exports: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
const a = 42;
|
||||||
|
export let bbb, { foo: ccc } = a;
|
||||||
|
export function fff(d, { [bbb]: e }) {
|
||||||
|
d(e, fff);
|
||||||
|
}
|
||||||
|
export default a;
|
||||||
|
export default async function g(x, ...{ [ccc]: y }) {
|
||||||
|
(await x)(g, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
let e, { foo: a } = 42;
|
||||||
|
function f(t, { [e]: o }) {
|
||||||
|
t(o, f);
|
||||||
|
}
|
||||||
|
export default 42;
|
||||||
|
export default async function n(t, ...{ [a]: o }) {
|
||||||
|
(await t)(n, o);
|
||||||
|
};
|
||||||
|
export { e as bbb, a as ccc, f as fff };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_vars: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
export var b = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
export var b = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_return_values: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default function() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
export default function f() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export default function() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
export default function f() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in_use: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export function f() {}
|
||||||
|
f.prototype.p = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export function f() {}
|
||||||
|
f.prototype.p = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
in_use_default: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default function f() {}
|
||||||
|
f.prototype.p = 42;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export default function f() {}
|
||||||
|
f.prototype.p = 42;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use_default: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export default function f() {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use_class: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export class A {}
|
||||||
|
A.prototype.p = "PASS";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export class A {}
|
||||||
|
A.prototype.p = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
single_use_class_default: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export default class A {}
|
||||||
|
A.prototype.p = "PASS";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export default class A {}
|
||||||
|
A.prototype.p = "PASS";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hoist_funs: {
|
||||||
|
options = {
|
||||||
|
hoist_funs: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export function f() {}
|
||||||
|
export default async function* g() {}
|
||||||
|
}
|
||||||
|
expect_exact: "export function f(){}export default async function*g(){}"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4742_join_vars_1: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
export var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
export var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4742_join_vars_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export var a = "foo";
|
||||||
|
var b;
|
||||||
|
b = "bar";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export var a = "foo";
|
||||||
|
var b, b = "bar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4742_unused_1: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 42;
|
||||||
|
export var a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 42;
|
||||||
|
export var a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4742_unused_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
export var a = "foo";
|
||||||
|
var a = "bar";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
export var a = "foo";
|
||||||
|
a = "bar";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4761: {
|
||||||
|
input: {
|
||||||
|
export default "function" == 42;
|
||||||
|
}
|
||||||
|
expect_exact: 'export default"function"==42;'
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4766: {
|
||||||
|
options = {
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "foo";
|
||||||
|
export var a = "bar";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "foo";
|
||||||
|
export var a = "bar";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2053,7 +2053,7 @@ issue_2898: {
|
|||||||
expect_stdout: "2"
|
expect_stdout: "2"
|
||||||
}
|
}
|
||||||
|
|
||||||
deduplicate_parenthesis: {
|
deduplicate_parentheses: {
|
||||||
input: {
|
input: {
|
||||||
({}).a = b;
|
({}).a = b;
|
||||||
(({}).a = b)();
|
(({}).a = b)();
|
||||||
@@ -2492,14 +2492,14 @@ issue_3297_3: {
|
|||||||
input: {
|
input: {
|
||||||
function function1(session) {
|
function function1(session) {
|
||||||
var public = {
|
var public = {
|
||||||
processBulk: processBulk
|
processBulk: processBulk,
|
||||||
};
|
};
|
||||||
return public;
|
return public;
|
||||||
function processBulk(bulk) {
|
function processBulk(bulk) {
|
||||||
var subparam1 = session();
|
var subparam1 = session();
|
||||||
function processOne(param1) {
|
function processOne(param1) {
|
||||||
var param2 = {
|
var param2 = {
|
||||||
subparam1: subparam1
|
subparam1: subparam1,
|
||||||
};
|
};
|
||||||
doProcessOne({
|
doProcessOne({
|
||||||
param1: param1,
|
param1: param1,
|
||||||
@@ -2525,18 +2525,18 @@ issue_3297_3: {
|
|||||||
return {
|
return {
|
||||||
processBulk: function n(o) {
|
processBulk: function n(o) {
|
||||||
var r, t, u = c();
|
var r, t, u = c();
|
||||||
o && 0 < o.length && (r = {
|
o && 0 < o.length && (r = o.shift(),
|
||||||
param1: o.shift(),
|
|
||||||
param2: {
|
|
||||||
subparam1: u
|
|
||||||
}
|
|
||||||
},
|
|
||||||
t = function() {
|
t = function() {
|
||||||
n(o);
|
n(o);
|
||||||
},
|
},
|
||||||
console.log(JSON.stringify(r)),
|
console.log(JSON.stringify({
|
||||||
|
param1: r,
|
||||||
|
param2: {
|
||||||
|
subparam1: u,
|
||||||
|
},
|
||||||
|
})),
|
||||||
t());
|
t());
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
function1(function() {
|
function1(function() {
|
||||||
@@ -2751,17 +2751,17 @@ functions: {
|
|||||||
function b() {
|
function b() {
|
||||||
return !!b;
|
return !!b;
|
||||||
}
|
}
|
||||||
var c = function(c) {
|
function c(c) {
|
||||||
return c;
|
return c;
|
||||||
};
|
}
|
||||||
if (c(b(a()))) {
|
if (c(b(a()))) {
|
||||||
function d() {}
|
function d() {}
|
||||||
function e() {
|
function e() {
|
||||||
return typeof e;
|
return typeof e;
|
||||||
}
|
}
|
||||||
var f = function(f) {
|
function f(f) {
|
||||||
return f;
|
return f;
|
||||||
};
|
}
|
||||||
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
console.log(a(d()), b(e()), c(f(42)), typeof d, e(), typeof f);
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
@@ -2808,9 +2808,9 @@ functions_use_strict: {
|
|||||||
function b() {
|
function b() {
|
||||||
return !!b;
|
return !!b;
|
||||||
}
|
}
|
||||||
var c = function(c) {
|
function c(c) {
|
||||||
return c;
|
return c;
|
||||||
};
|
}
|
||||||
if (c(b(a()))) {
|
if (c(b(a()))) {
|
||||||
var d = function() {};
|
var d = function() {};
|
||||||
var e = function y() {
|
var e = function y() {
|
||||||
@@ -2826,6 +2826,30 @@ functions_use_strict: {
|
|||||||
expect_stdout: "a true 42 function function function"
|
expect_stdout: "a true 42 function function function"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
functions_inner_var: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = function() {
|
||||||
|
var a;
|
||||||
|
console.log(a, a);
|
||||||
|
};
|
||||||
|
a(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function a() {
|
||||||
|
var a;
|
||||||
|
console.log(a, a);
|
||||||
|
}
|
||||||
|
a();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined undefined"
|
||||||
|
}
|
||||||
|
|
||||||
issue_2437: {
|
issue_2437: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
@@ -3322,7 +3346,9 @@ issue_3506_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "FAIL";
|
var a = "FAIL";
|
||||||
a && (a = "PASS");
|
!function(b) {
|
||||||
|
b && (a = "PASS");
|
||||||
|
}(a);
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -5016,9 +5042,12 @@ catch_no_argname: {
|
|||||||
try {
|
try {
|
||||||
throw a;
|
throw a;
|
||||||
} catch {
|
} catch {
|
||||||
console.log(a, a, a);
|
function g() {
|
||||||
|
return a;
|
||||||
}
|
}
|
||||||
console.log(a, a, a);
|
console.log(a, a, g());
|
||||||
|
}
|
||||||
|
console.log(a, a, g());
|
||||||
}
|
}
|
||||||
expect_stdout: [
|
expect_stdout: [
|
||||||
"PASS PASS PASS",
|
"PASS PASS PASS",
|
||||||
@@ -5407,3 +5436,775 @@ issue_4612_4: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4655: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f() {
|
||||||
|
while (console.log("PASS")) {
|
||||||
|
var g = function() {};
|
||||||
|
for (var a in g)
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
for (; console.log("PASS");) {
|
||||||
|
function g() {};
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4659_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
f && f();
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
f && a++;
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4659_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
f && f();
|
||||||
|
})();
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
void (f && a++);
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4659_3: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
function g() {
|
||||||
|
while (!console);
|
||||||
|
}
|
||||||
|
g(f && f());
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
return a++;
|
||||||
|
}
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
while (!console);
|
||||||
|
})(f && a++);
|
||||||
|
(function() {
|
||||||
|
var a = console && a;
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_1: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_1_compress: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_2: {
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
console.log(typeof f);
|
||||||
|
}
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_2_compress: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
console.log(typeof f);
|
||||||
|
}
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_3: {
|
||||||
|
input: {
|
||||||
|
console.log(typeof f);
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f);
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_3_compress: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof f);
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f);
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_4: {
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
block_scope_4_compress: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
typeofs: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
{
|
||||||
|
console.log(typeof f);
|
||||||
|
function f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("function");
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4725_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
return function g() {
|
||||||
|
return g;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(typeof o.f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
return function g() {
|
||||||
|
return g;
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.log(typeof o.f());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4725_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
return function() {
|
||||||
|
while (console.log("PASS"));
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
while (console.log("PASS"));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o.f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target_1: {
|
||||||
|
input: {
|
||||||
|
new function f() {
|
||||||
|
console.log(new.target === f);
|
||||||
|
}();
|
||||||
|
console.log(function() {
|
||||||
|
return new.target;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function f() {
|
||||||
|
console.log(new.target === f);
|
||||||
|
}();
|
||||||
|
console.log(function() {
|
||||||
|
return new.target;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"true",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target_2: {
|
||||||
|
input: {
|
||||||
|
new function(a) {
|
||||||
|
if (!new.target)
|
||||||
|
console.log("FAIL");
|
||||||
|
else if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(a) {
|
||||||
|
if (!new.target)
|
||||||
|
console.log("FAIL");
|
||||||
|
else if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target_collapse_vars: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}(0);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target_delete: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function() {
|
||||||
|
console.log(delete new.target);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function() {
|
||||||
|
console.log(delete new.target);
|
||||||
|
}();
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
new_target_reduce_vars: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
new function(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}(0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
new function(a) {
|
||||||
|
if (a)
|
||||||
|
console.log("PASS");
|
||||||
|
else
|
||||||
|
new new.target(new.target.length);
|
||||||
|
}(0);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4753_1: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
for (var i in [ 1, 2 ])
|
||||||
|
(function() {
|
||||||
|
function f() {}
|
||||||
|
f && console.log(f.p ^= 42);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i in [ 1, 2 ])
|
||||||
|
f = function() {},
|
||||||
|
void (f && console.log(f.p ^= 42));
|
||||||
|
var f;
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4753_2: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
do {
|
||||||
|
(function() {
|
||||||
|
var a = f();
|
||||||
|
function f() {
|
||||||
|
return "PASS";
|
||||||
|
}
|
||||||
|
f;
|
||||||
|
function g() {
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
g();
|
||||||
|
})();
|
||||||
|
} while (0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
do {
|
||||||
|
f = function() {
|
||||||
|
return "PASS";
|
||||||
|
},
|
||||||
|
a = void 0,
|
||||||
|
a = f(),
|
||||||
|
console.log(a);
|
||||||
|
} while (0);
|
||||||
|
var f, a;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4788: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
functions: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
var a = function g() {
|
||||||
|
if (0) {
|
||||||
|
var g = 42;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
g || console.log("PASS");
|
||||||
|
};
|
||||||
|
a(a);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f() {
|
||||||
|
function a() {
|
||||||
|
if (0) {
|
||||||
|
var g = 42;
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
g || console.log("PASS");
|
||||||
|
}
|
||||||
|
a();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4823: {
|
||||||
|
options = {
|
||||||
|
functions: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
var arguments = f();
|
||||||
|
function g() {}
|
||||||
|
var arguments = g;
|
||||||
|
}
|
||||||
|
return f && arguments;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof function() {
|
||||||
|
{
|
||||||
|
function f() {}
|
||||||
|
f();
|
||||||
|
var arguments = function() {};
|
||||||
|
}
|
||||||
|
return f && arguments;
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_unused_self_reference: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
(f.p = f).q = console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_1: {
|
||||||
|
options = {
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
a.p = a;
|
||||||
|
b = a = function() {};
|
||||||
|
b.q = b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_1_toplevel: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
a.p = a;
|
||||||
|
var b = a = function() {};
|
||||||
|
b.q = b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
b.p = a;
|
||||||
|
b = a = function() {};
|
||||||
|
a.q = b;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_2_toplevel: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
b.p = a;
|
||||||
|
var b = a = function() {};
|
||||||
|
a.q = b;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
a.p = b;
|
||||||
|
b = a = function() {};
|
||||||
|
b.q = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_3_toplevel: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
a.p = b;
|
||||||
|
var b = a = function() {};
|
||||||
|
b.q = a;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_4: {
|
||||||
|
options = {
|
||||||
|
passes: 3,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
a = b = function() {};
|
||||||
|
b.p = b;
|
||||||
|
b = a = function() {};
|
||||||
|
a.q = a;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_cross_reference_4_toplevel: {
|
||||||
|
options = {
|
||||||
|
passes: 2,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = b = function() {};
|
||||||
|
b.p = b;
|
||||||
|
var b = a = function() {};
|
||||||
|
a.q = a;
|
||||||
|
}
|
||||||
|
expect: {}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|||||||
@@ -1068,3 +1068,29 @@ issue_4023: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_super: {
|
||||||
|
options = {
|
||||||
|
hoist_props: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f(a) {
|
||||||
|
return a ? console.log("PASS") : super.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.f(42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f(a) {
|
||||||
|
return a ? console.log("PASS") : super.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.f(42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ issue_4487: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function a() {
|
function a() {
|
||||||
var a = console.log(typeof a);
|
var f = console.log(typeof f);
|
||||||
}
|
}
|
||||||
a();
|
a();
|
||||||
}
|
}
|
||||||
@@ -207,3 +207,192 @@ issue_4517: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "2boolean"
|
expect_stdout: "2boolean"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4736: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
function f() {
|
||||||
|
(function g() {
|
||||||
|
var b = (a = 0, 1 << 30);
|
||||||
|
var c = (a = 0, console.log(b));
|
||||||
|
var d = c;
|
||||||
|
})(f);
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
(function() {
|
||||||
|
0,
|
||||||
|
console.log(1073741824);
|
||||||
|
})();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "1073741824"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4839: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = function(a, b) {
|
||||||
|
return b && b;
|
||||||
|
}("foo");
|
||||||
|
for (var k in o)
|
||||||
|
throw "FAIL";
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var k, o = void 0;
|
||||||
|
for (k in o)
|
||||||
|
throw "FAIL";
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4859: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
keep_infinity: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = (a = 2, 1 / 0), c = 3;
|
||||||
|
var d = a + b;
|
||||||
|
console.log(d);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a) {
|
||||||
|
var d = 1 / 0, d = Infinity;
|
||||||
|
console.log(d);
|
||||||
|
return f;
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "Infinity"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4893_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {}
|
||||||
|
var a = null;
|
||||||
|
var b = null;
|
||||||
|
var c = null;
|
||||||
|
b.p += a = 42;
|
||||||
|
f;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try{
|
||||||
|
(function f() {
|
||||||
|
var b;
|
||||||
|
b = null;
|
||||||
|
b.p += 42;
|
||||||
|
f;
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4893_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {
|
||||||
|
function g() {}
|
||||||
|
var a = null;
|
||||||
|
var b = null;
|
||||||
|
var c = null;
|
||||||
|
b.p += a = 42;
|
||||||
|
f;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try{
|
||||||
|
(function() {
|
||||||
|
var b;
|
||||||
|
b = null;
|
||||||
|
b.p += 42;
|
||||||
|
})();
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4898: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
evaluate: true,
|
||||||
|
hoist_vars: true,
|
||||||
|
loops: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
do {
|
||||||
|
var b = [ console.log("PASS") ];
|
||||||
|
var c = b;
|
||||||
|
} while (c.p = 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b;
|
||||||
|
b = [ console.log("PASS") ];
|
||||||
|
b.p = 0;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2653,7 +2653,9 @@ issue_4019: {
|
|||||||
try {
|
try {
|
||||||
console.log("FAIL");
|
console.log("FAIL");
|
||||||
} catch (o) {}
|
} catch (o) {}
|
||||||
}, o = (console.log(o.length), ++o);
|
};
|
||||||
|
console.log(o.length),
|
||||||
|
++o;
|
||||||
}
|
}
|
||||||
expect_stdout: "0"
|
expect_stdout: "0"
|
||||||
}
|
}
|
||||||
@@ -2919,3 +2921,29 @@ issue_4568: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "undefined 1"
|
expect_stdout: "undefined 1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4729: {
|
||||||
|
options = {
|
||||||
|
ie8: true,
|
||||||
|
pure_getters: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
f;
|
||||||
|
} catch (e) {
|
||||||
|
var a = a && a[function f() {}];
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
f;
|
||||||
|
} catch (e) {
|
||||||
|
(function f() {});
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
211
test/compress/imports.js
Normal file
211
test/compress/imports.js
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
nought: {
|
||||||
|
input: {
|
||||||
|
import "foo";
|
||||||
|
}
|
||||||
|
expect_exact: 'import"foo";'
|
||||||
|
}
|
||||||
|
|
||||||
|
default_only: {
|
||||||
|
input: {
|
||||||
|
import foo from "bar";
|
||||||
|
}
|
||||||
|
expect_exact: 'import foo from"bar";'
|
||||||
|
}
|
||||||
|
|
||||||
|
all_only: {
|
||||||
|
input: {
|
||||||
|
import * as foo from "bar";
|
||||||
|
}
|
||||||
|
expect_exact: 'import*as foo from"bar";'
|
||||||
|
}
|
||||||
|
|
||||||
|
keys_only: {
|
||||||
|
input: {
|
||||||
|
import { as as foo, bar, delete as baz } from "moo";
|
||||||
|
}
|
||||||
|
expect_exact: 'import{as as foo,bar,delete as baz}from"moo";'
|
||||||
|
}
|
||||||
|
|
||||||
|
default_all: {
|
||||||
|
input: {
|
||||||
|
import foo, * as bar from "baz";
|
||||||
|
}
|
||||||
|
expect_exact: 'import foo,*as bar from"baz";'
|
||||||
|
}
|
||||||
|
|
||||||
|
default_keys: {
|
||||||
|
input: {
|
||||||
|
import foo, { bar } from "baz";
|
||||||
|
}
|
||||||
|
expect_exact: 'import foo,{bar}from"baz";'
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic: {
|
||||||
|
input: {
|
||||||
|
(async a => await import(a))("foo").then(bar);
|
||||||
|
}
|
||||||
|
expect_exact: '(async a=>await import(a))("foo").then(bar);'
|
||||||
|
}
|
||||||
|
|
||||||
|
dynamic_nought: {
|
||||||
|
input: {
|
||||||
|
import(foo);
|
||||||
|
}
|
||||||
|
expect_exact: "import(foo);"
|
||||||
|
}
|
||||||
|
|
||||||
|
import_meta_1: {
|
||||||
|
input: {
|
||||||
|
console.log(import.meta, import.meta.url);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(import.meta,import.meta.url);"
|
||||||
|
}
|
||||||
|
|
||||||
|
import_meta_2: {
|
||||||
|
input: {
|
||||||
|
import.meta.url.split("/").forEach(function(part, index) {
|
||||||
|
console.log(index, part);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_exact: 'import.meta.url.split("/").forEach(function(part,index){console.log(index,part)});'
|
||||||
|
}
|
||||||
|
|
||||||
|
same_quotes: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
quote_style: 3,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import 'foo';
|
||||||
|
import "bar";
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"import 'foo';",
|
||||||
|
"",
|
||||||
|
'import "bar";',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_unused: {
|
||||||
|
options = {
|
||||||
|
imports: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import a, * as b from "foo";
|
||||||
|
import { c, bar as d } from "baz";
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import "foo";
|
||||||
|
import { c as c } from "baz";
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mangle: {
|
||||||
|
rename = false
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import foo, { bar } from "baz";
|
||||||
|
consoe.log(moo);
|
||||||
|
import * as moo from "moz";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import o, { bar as m } from "baz";
|
||||||
|
consoe.log(r);
|
||||||
|
import * as r from "moz";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rename_mangle: {
|
||||||
|
rename = true
|
||||||
|
mangle = {
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import foo, { bar } from "baz";
|
||||||
|
consoe.log(moo);
|
||||||
|
import * as moo from "moz";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import o, { bar as m } from "baz";
|
||||||
|
consoe.log(r);
|
||||||
|
import * as r from "moz";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
keep_ref: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import foo from "bar";
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import foo from "bar";
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forbid_merge: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
import A from "foo";
|
||||||
|
export default class extends A {}
|
||||||
|
var f = () => () => {};
|
||||||
|
f();
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
import A from "foo";
|
||||||
|
export default class extends A {}
|
||||||
|
var f = () => () => {};
|
||||||
|
f();
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4708_1: {
|
||||||
|
options = {
|
||||||
|
imports: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
import a from "foo";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
import a from "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4708_2: {
|
||||||
|
options = {
|
||||||
|
imports: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log(a);
|
||||||
|
import a from "foo";
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log(a);
|
||||||
|
import a from "foo";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,61 +2,77 @@ keep_name_of_getter: {
|
|||||||
options = {
|
options = {
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: { a = { get foo () {} } }
|
input: {
|
||||||
expect: { a = { get foo () {} } }
|
a = {
|
||||||
|
get foo() {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = {
|
||||||
|
get foo() {},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
keep_name_of_setter: {
|
keep_name_of_setter: {
|
||||||
options = {
|
options = {
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: { a = { set foo () {} } }
|
input: {
|
||||||
expect: { a = { set foo () {} } }
|
a = {
|
||||||
|
set foo(v) {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
a = {
|
||||||
|
set foo(v) {},
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setter_with_operator_keys: {
|
setter_with_operator_keys: {
|
||||||
input: {
|
input: {
|
||||||
var tokenCodes = {
|
var tokenCodes = {
|
||||||
get instanceof(){
|
get instanceof() {
|
||||||
return test0;
|
return test0;
|
||||||
},
|
},
|
||||||
set instanceof(value){
|
set instanceof(value) {
|
||||||
test0 = value;
|
test0 = value;
|
||||||
},
|
},
|
||||||
set typeof(value){
|
set typeof(value) {
|
||||||
test1 = value;
|
test1 = value;
|
||||||
},
|
},
|
||||||
get typeof(){
|
get typeof() {
|
||||||
return test1;
|
return test1;
|
||||||
},
|
},
|
||||||
set else(value){
|
set else(value) {
|
||||||
test2 = value;
|
test2 = value;
|
||||||
},
|
},
|
||||||
get else(){
|
get else() {
|
||||||
return test2;
|
return test2;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var tokenCodes = {
|
var tokenCodes = {
|
||||||
get instanceof(){
|
get instanceof() {
|
||||||
return test0;
|
return test0;
|
||||||
},
|
},
|
||||||
set instanceof(value){
|
set instanceof(value) {
|
||||||
test0 = value;
|
test0 = value;
|
||||||
},
|
},
|
||||||
set typeof(value){
|
set typeof(value) {
|
||||||
test1 = value;
|
test1 = value;
|
||||||
},
|
},
|
||||||
get typeof(){
|
get typeof() {
|
||||||
return test1;
|
return test1;
|
||||||
},
|
},
|
||||||
set else(value){
|
set else(value) {
|
||||||
test2 = value;
|
test2 = value;
|
||||||
},
|
},
|
||||||
get else(){
|
get else() {
|
||||||
return test2;
|
return test2;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ mangle_keep_fnames_false: {
|
|||||||
keep_fnames: true,
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames : false,
|
keep_fnames: false,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -30,7 +30,7 @@ mangle_keep_fnames_true: {
|
|||||||
keep_fnames: true,
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
mangle = {
|
mangle = {
|
||||||
keep_fnames : true,
|
keep_fnames: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
pure_function_calls: {
|
pure_function_calls: {
|
||||||
options = {
|
options = {
|
||||||
|
annotations: true,
|
||||||
booleans: true,
|
booleans: true,
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -60,6 +61,7 @@ pure_function_calls: {
|
|||||||
|
|
||||||
pure_function_calls_toplevel: {
|
pure_function_calls_toplevel: {
|
||||||
options = {
|
options = {
|
||||||
|
annotations: true,
|
||||||
booleans: true,
|
booleans: true,
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -126,6 +128,7 @@ pure_function_calls_toplevel: {
|
|||||||
|
|
||||||
should_warn: {
|
should_warn: {
|
||||||
options = {
|
options = {
|
||||||
|
annotations: true,
|
||||||
booleans: true,
|
booleans: true,
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
|||||||
@@ -426,6 +426,7 @@ wrap_iife_in_return_call: {
|
|||||||
|
|
||||||
pure_annotation_1: {
|
pure_annotation_1: {
|
||||||
options = {
|
options = {
|
||||||
|
annotations: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
@@ -439,6 +440,7 @@ pure_annotation_1: {
|
|||||||
|
|
||||||
pure_annotation_2: {
|
pure_annotation_2: {
|
||||||
options = {
|
options = {
|
||||||
|
annotations: true,
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
inline: true,
|
inline: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -463,15 +465,19 @@ drop_fargs: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
!function(a_1) {
|
!function(a_1) {
|
||||||
a++;
|
a++;
|
||||||
}(a++ + (a && a.var));
|
}(a++ + (a && console.log(a)));
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
++a && a.var, a++;
|
++a && console.log(a),
|
||||||
|
a++;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "3"
|
expect_stdout: [
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
keep_fargs: {
|
keep_fargs: {
|
||||||
@@ -486,13 +492,17 @@ keep_fargs: {
|
|||||||
var a = 1;
|
var a = 1;
|
||||||
!function(a_1) {
|
!function(a_1) {
|
||||||
a++;
|
a++;
|
||||||
}(a++ + (a && a.var));
|
}(a++ + (a && console.log(a)));
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = 1;
|
var a = 1;
|
||||||
++a && a.var, a++;
|
++a && console.log(a),
|
||||||
|
a++;
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "3"
|
expect_stdout: [
|
||||||
|
"2",
|
||||||
|
"3",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1024,7 +1024,7 @@ issue_3856: {
|
|||||||
expect_stdout: "undefined"
|
expect_stdout: "undefined"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3916: {
|
issue_3916_1: {
|
||||||
options = {
|
options = {
|
||||||
join_vars: true,
|
join_vars: true,
|
||||||
}
|
}
|
||||||
@@ -1044,8 +1044,8 @@ issue_3916: {
|
|||||||
var o = {
|
var o = {
|
||||||
p: "PASS",
|
p: "PASS",
|
||||||
__proto__: 42,
|
__proto__: 42,
|
||||||
q: "FAIL",
|
|
||||||
};
|
};
|
||||||
|
o.q = "FAIL";
|
||||||
o.__proto__ = {
|
o.__proto__ = {
|
||||||
p: "FAIL",
|
p: "FAIL",
|
||||||
q: "PASS",
|
q: "PASS",
|
||||||
@@ -1055,3 +1055,131 @@ issue_3916: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "object PASS true PASS"
|
expect_stdout: "object PASS true PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3916_2: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log, o = {};
|
||||||
|
o.p = "FAIL 1";
|
||||||
|
o.__proto__ = {
|
||||||
|
get p() {
|
||||||
|
return "FAIL 2";
|
||||||
|
},
|
||||||
|
set p(u) {
|
||||||
|
log("FAIL 3");
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
log("PASS 1");
|
||||||
|
},
|
||||||
|
get q() {
|
||||||
|
return "PASS 3";
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.p = "PASS 2";
|
||||||
|
o.q = "FAIL 4";
|
||||||
|
log(o.p);
|
||||||
|
log(o.q);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log, o = {
|
||||||
|
p: "FAIL 1",
|
||||||
|
__proto__: {
|
||||||
|
get p() {
|
||||||
|
return "FAIL 2";
|
||||||
|
},
|
||||||
|
set p(u) {
|
||||||
|
log("FAIL 3");
|
||||||
|
},
|
||||||
|
set q(v) {
|
||||||
|
log("PASS 1");
|
||||||
|
},
|
||||||
|
get q() {
|
||||||
|
return "PASS 3";
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o.p = "PASS 2";
|
||||||
|
o.q = "FAIL 4";
|
||||||
|
log(o.p);
|
||||||
|
log(o.q);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS 1",
|
||||||
|
"PASS 2",
|
||||||
|
"PASS 3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
b = "foo";
|
||||||
|
var a = [ , "bar" ];
|
||||||
|
console.log(b);
|
||||||
|
for (var b in a)
|
||||||
|
console.log(b, a[b]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = "foo", a = [ , "bar" ], b;
|
||||||
|
console.log(b);
|
||||||
|
for (b in a)
|
||||||
|
console.log(b, a[b]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"1 bar",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_for_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
i = "foo",
|
||||||
|
a = new Array(i, "bar");
|
||||||
|
for (var i = 2; --i >= 0;) {
|
||||||
|
console.log(a[i]);
|
||||||
|
for (var a in i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var i = "foo", a = new Array(i, "bar"), i = 2; --i >= 0;) {
|
||||||
|
console.log(a[i]);
|
||||||
|
for (var a in i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
assign_sequence_var: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
console.log(a),
|
||||||
|
a++,
|
||||||
|
b = 2;
|
||||||
|
var c = 3;
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
console.log(a),
|
||||||
|
a++;
|
||||||
|
var b = 2, c = 3;
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"0",
|
||||||
|
"1 2 3",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
@@ -438,7 +438,7 @@ issue_2506: {
|
|||||||
function f0(bar) {
|
function f0(bar) {
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function() {
|
||||||
if (false <= NaN & this >> 1 >= 0)
|
if (false <= 0/0 & this >> 1 >= 0)
|
||||||
c++;
|
c++;
|
||||||
})(c++);
|
})(c++);
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ reduce_block_2_toplevel: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
reduce_vars: {
|
reduce_vars_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -381,6 +381,86 @@ reduce_vars: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduce_vars_2: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
for (let a in [ 42 ])
|
||||||
|
f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function() {
|
||||||
|
function f() {
|
||||||
|
console.log(typeof a);
|
||||||
|
}
|
||||||
|
for (let a in [ 42 ])
|
||||||
|
f();
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars_3: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
let i = 1;
|
||||||
|
function f() {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
for (let i = 0, x = 0; i < a.length; i++, x++) {
|
||||||
|
if (x != i) {
|
||||||
|
console.log("FAIL");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a[i]);
|
||||||
|
}
|
||||||
|
console.log(i);
|
||||||
|
})([ 4, 2 ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
(function(a) {
|
||||||
|
let i = 1;
|
||||||
|
function f() {
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
for (let i = 0, x = 0; i < a.length; i++, x++) {
|
||||||
|
if (x != i) {
|
||||||
|
console.log("FAIL");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
console.log(a[i]);
|
||||||
|
}
|
||||||
|
console.log(i);
|
||||||
|
})([ 4, 2 ]);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"4",
|
||||||
|
"2",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
hoist_props: {
|
hoist_props: {
|
||||||
options = {
|
options = {
|
||||||
hoist_props: true,
|
hoist_props: true,
|
||||||
@@ -610,6 +690,28 @@ drop_unused: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_init: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
let a;
|
||||||
|
a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4191: {
|
issue_4191: {
|
||||||
options = {
|
options = {
|
||||||
functions: true,
|
functions: true,
|
||||||
@@ -1319,7 +1421,6 @@ issue_4531_2: {
|
|||||||
toplevel: true,
|
toplevel: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
"use strict";
|
|
||||||
var a = console;
|
var a = console;
|
||||||
console.log(typeof a, function a() {
|
console.log(typeof a, function a() {
|
||||||
let { [console]: a } = 0 && a;
|
let { [console]: a } = 0 && a;
|
||||||
@@ -1328,7 +1429,6 @@ issue_4531_2: {
|
|||||||
}());
|
}());
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
"use strict";
|
|
||||||
var o = console;
|
var o = console;
|
||||||
console.log(typeof o, function o() {
|
console.log(typeof o, function o() {
|
||||||
let { [console]: o } = 0;
|
let { [console]: o } = 0;
|
||||||
@@ -1339,3 +1439,110 @@ issue_4531_2: {
|
|||||||
expect_stdout: "object undefined"
|
expect_stdout: "object undefined"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4689: {
|
||||||
|
options = {
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
for (let a in 42);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = "PASS";
|
||||||
|
console.log(a);
|
||||||
|
for (let a in 42);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4691: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function A() {}
|
||||||
|
A.prototype.f = function() {
|
||||||
|
if (!this)
|
||||||
|
return;
|
||||||
|
let a = "PA";
|
||||||
|
function g(b) {
|
||||||
|
h(a + b);
|
||||||
|
}
|
||||||
|
[ "SS" ].forEach(function(c) {
|
||||||
|
g(c);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
function h(d) {
|
||||||
|
console.log(d);
|
||||||
|
}
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function A() {}
|
||||||
|
A.prototype.f = function() {
|
||||||
|
if (this) {
|
||||||
|
let a = "PA";
|
||||||
|
[ "SS" ].forEach(function(c) {
|
||||||
|
g(c);
|
||||||
|
});
|
||||||
|
function g(b) {
|
||||||
|
h(a + b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function h(d) {
|
||||||
|
console.log(d);
|
||||||
|
}
|
||||||
|
new A().f();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4848: {
|
||||||
|
options = {
|
||||||
|
if_return: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
a(function() {
|
||||||
|
console.log(b);
|
||||||
|
});
|
||||||
|
if (!console)
|
||||||
|
return;
|
||||||
|
let b = "PASS";
|
||||||
|
}
|
||||||
|
var g;
|
||||||
|
f(function(h) {
|
||||||
|
g = h;
|
||||||
|
});
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
function f(a) {
|
||||||
|
a(function() {
|
||||||
|
console.log(b);
|
||||||
|
});
|
||||||
|
if (!console)
|
||||||
|
return;
|
||||||
|
let b = "PASS";
|
||||||
|
}
|
||||||
|
var g;
|
||||||
|
f(function(h) {
|
||||||
|
g = h;
|
||||||
|
});
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -501,14 +501,14 @@ do_switch: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
in_parenthesis_1: {
|
in_parentheses_1: {
|
||||||
input: {
|
input: {
|
||||||
for (("foo" in {});0;);
|
for (("foo" in {});0;);
|
||||||
}
|
}
|
||||||
expect_exact: 'for(("foo"in{});0;);'
|
expect_exact: 'for(("foo"in{});0;);'
|
||||||
}
|
}
|
||||||
|
|
||||||
in_parenthesis_2: {
|
in_parentheses_2: {
|
||||||
input: {
|
input: {
|
||||||
for ((function(){ "foo" in {}; });0;);
|
for ((function(){ "foo" in {}; });0;);
|
||||||
}
|
}
|
||||||
@@ -828,6 +828,44 @@ empty_for_in_prop_init: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for_of: {
|
||||||
|
input: {
|
||||||
|
var a = [ "PASS", 42 ];
|
||||||
|
a.p = "FAIL";
|
||||||
|
for (a of (null, a))
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_exact: 'var a=["PASS",42];a.p="FAIL";for(a of(null,a))console.log(a);'
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=0.12"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_async_of: {
|
||||||
|
input: {
|
||||||
|
var async = [ "PASS", 42 ];
|
||||||
|
async.p = "FAIL";
|
||||||
|
for (async of (null, async))
|
||||||
|
console.log(async);
|
||||||
|
}
|
||||||
|
expect_exact: 'var async=["PASS",42];async.p="FAIL";for(async of(null,async))console.log(async);'
|
||||||
|
expect_stdout: true
|
||||||
|
node_version: ">=0.12 <16"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_of_regexp: {
|
||||||
|
input: {
|
||||||
|
for (var a of /foo/);
|
||||||
|
}
|
||||||
|
expect_exact: "for(var a of/foo/);"
|
||||||
|
}
|
||||||
|
|
||||||
|
for_await_of_regexp: {
|
||||||
|
input: {
|
||||||
|
for await (var a of /foo/);
|
||||||
|
}
|
||||||
|
expect_exact: "for await(var a of/foo/);"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3631_1: {
|
issue_3631_1: {
|
||||||
options = {
|
options = {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
@@ -1052,7 +1090,6 @@ issue_4084: {
|
|||||||
options = {
|
options = {
|
||||||
keep_fargs: false,
|
keep_fargs: false,
|
||||||
loops: true,
|
loops: true,
|
||||||
passes: 2,
|
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -1261,6 +1298,7 @@ issue_4355: {
|
|||||||
dead_code: true,
|
dead_code: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
loops: true,
|
loops: true,
|
||||||
|
passes: 2,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2620,9 +2620,9 @@ issue_4126_1: {
|
|||||||
try {
|
try {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var b = a;
|
var c = a;
|
||||||
} finally {
|
} finally {
|
||||||
var c = b;
|
var c = c;
|
||||||
}
|
}
|
||||||
console.log(c);
|
console.log(c);
|
||||||
}
|
}
|
||||||
@@ -3183,3 +3183,121 @@ issue_4257: {
|
|||||||
"1",
|
"1",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4628: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
for (var a in "foo");
|
||||||
|
console.log(b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
try {
|
||||||
|
console;
|
||||||
|
} finally {
|
||||||
|
var b = a;
|
||||||
|
}
|
||||||
|
for (var a in "foo");
|
||||||
|
console.log(b);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4653: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
merge_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1, b;
|
||||||
|
function f(c, d) {
|
||||||
|
c || console.log(d);
|
||||||
|
}
|
||||||
|
f(a++ + (b = b), b |= console.log(a));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 1;
|
||||||
|
(function(c, d) {
|
||||||
|
c || console.log(d);
|
||||||
|
})(+b + (b = void 0), b |= console.log(2));
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"2",
|
||||||
|
"0",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4759: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var i = 2, a = 1, b, c, d;
|
||||||
|
while (i--) {
|
||||||
|
try {
|
||||||
|
if (1 != b) {
|
||||||
|
d = [];
|
||||||
|
null.p;
|
||||||
|
c = d;
|
||||||
|
} else {
|
||||||
|
b = 0;
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var i = 2, a = 1, b, c, d;
|
||||||
|
while (i--) {
|
||||||
|
try {
|
||||||
|
if (1 != b) {
|
||||||
|
d = [];
|
||||||
|
null.p;
|
||||||
|
c = d;
|
||||||
|
} else {
|
||||||
|
b = 0;
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
b = a;
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4761: {
|
||||||
|
options = {
|
||||||
|
merge_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL", b;
|
||||||
|
try {
|
||||||
|
!a && --a && (b = 0)[console] || console.log(b);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL", b;
|
||||||
|
try {
|
||||||
|
!a && --a && (b = 0)[console] || console.log(b);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ new_with_unary_prefix: {
|
|||||||
expect_exact: 'var bar=(+new Date).toString(32);';
|
expect_exact: 'var bar=(+new Date).toString(32);';
|
||||||
}
|
}
|
||||||
|
|
||||||
dot_parenthesis_1: {
|
dot_parentheses_1: {
|
||||||
input: {
|
input: {
|
||||||
console.log(new (Math.random().constructor) instanceof Number);
|
console.log(new (Math.random().constructor) instanceof Number);
|
||||||
}
|
}
|
||||||
@@ -93,7 +93,7 @@ dot_parenthesis_1: {
|
|||||||
expect_stdout: "true"
|
expect_stdout: "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
dot_parenthesis_2: {
|
dot_parentheses_2: {
|
||||||
input: {
|
input: {
|
||||||
console.log(typeof new function(){Math.random()}.constructor);
|
console.log(typeof new function(){Math.random()}.constructor);
|
||||||
}
|
}
|
||||||
|
|||||||
130
test/compress/nullish.js
Normal file
130
test/compress/nullish.js
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
parentheses: {
|
||||||
|
input: {
|
||||||
|
(console.log("foo") || console.log("bar") ?? console.log("baz")) && console.log("moo");
|
||||||
|
}
|
||||||
|
expect_exact:'((console.log("foo")||console.log("bar"))??console.log("baz"))&&console.log("moo");'
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
evaluate: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
void console.log("foo" ?? "bar") ?? console.log("baz");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo"),
|
||||||
|
console.log("baz");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"baz",
|
||||||
|
]
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_assignment_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
b ?? (a = "FAIL");
|
||||||
|
return a;
|
||||||
|
}("PASS", !console));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a, b) {
|
||||||
|
b ?? (a = "FAIL");
|
||||||
|
return a;
|
||||||
|
}("PASS", !console));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_assignment_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = false;
|
||||||
|
a = "PASS",
|
||||||
|
b ?? (a = "FAIL"),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = false;
|
||||||
|
a = "PASS",
|
||||||
|
b ?? (a = "FAIL"),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_assignment_3: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
join_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = false;
|
||||||
|
a = "PASS",
|
||||||
|
b ?? (a = "FAIL"),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = false, a = "PASS";
|
||||||
|
b ?? (a = "FAIL"),
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
conditional_assignment_4: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(a) {
|
||||||
|
!console ?? (a = "FAIL");
|
||||||
|
return a;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function(a) {
|
||||||
|
!console ?? (a = "FAIL");
|
||||||
|
return a;
|
||||||
|
}("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4679: {
|
||||||
|
options = {
|
||||||
|
comparisons: true,
|
||||||
|
ie8: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
if (void 0 === (undefined ?? a))
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
if (void 0 === (undefined ?? a))
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
@@ -1,3 +1,10 @@
|
|||||||
|
literal_infinity: {
|
||||||
|
input: {
|
||||||
|
console.log(2e308, -1e2345);
|
||||||
|
}
|
||||||
|
expect_exact: "console.log(1/0,-(1/0));"
|
||||||
|
}
|
||||||
|
|
||||||
parentheses_for_prototype_functions: {
|
parentheses_for_prototype_functions: {
|
||||||
beautify = {
|
beautify = {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
@@ -97,6 +104,40 @@ parentheses_for_prototype_functions_galio: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
octal: {
|
||||||
|
beautify = {
|
||||||
|
beautify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function() {
|
||||||
|
console.log(052);
|
||||||
|
console.log(-052);
|
||||||
|
|
||||||
|
console.log(018);
|
||||||
|
console.log(-018);
|
||||||
|
|
||||||
|
console.log(052.toFixed(0));
|
||||||
|
console.log(-052.toFixed(0));
|
||||||
|
|
||||||
|
console.log(018..toFixed(0));
|
||||||
|
console.log(-018..toFixed(0));
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_exact: [
|
||||||
|
"(function() {",
|
||||||
|
" console.log(42);",
|
||||||
|
" console.log(-42);",
|
||||||
|
" console.log(18);",
|
||||||
|
" console.log(-18);",
|
||||||
|
" console.log(42..toFixed(0));",
|
||||||
|
" console.log(-42..toFixed(0));",
|
||||||
|
" console.log(18..toFixed(0));",
|
||||||
|
" console.log(-18..toFixed(0));",
|
||||||
|
"})();",
|
||||||
|
]
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
comparisons: {
|
comparisons: {
|
||||||
options = {
|
options = {
|
||||||
comparisons: true,
|
comparisons: true,
|
||||||
@@ -777,7 +818,7 @@ issue_1710: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
unary_binary_parenthesis: {
|
unary_binary_parentheses: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,6 +280,72 @@ shorthand_keywords: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_super: {
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
return super.p;
|
||||||
|
},
|
||||||
|
p: "FAIL",
|
||||||
|
};
|
||||||
|
Object.setPrototypeOf(o, { p: "PASS" });
|
||||||
|
console.log(o.f());
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});console.log(o.f());'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_super_async: {
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
async f() {
|
||||||
|
return super.p;
|
||||||
|
},
|
||||||
|
p: "FAIL",
|
||||||
|
};
|
||||||
|
Object.setPrototypeOf(o, { p: "PASS" });
|
||||||
|
o.f().then(console.log);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={async f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});o.f().then(console.log);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_super_generator: {
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
*f() {
|
||||||
|
yield super.p;
|
||||||
|
},
|
||||||
|
p: "FAIL",
|
||||||
|
};
|
||||||
|
Object.setPrototypeOf(o, { p: "PASS" });
|
||||||
|
console.log(o.f().next().value);
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={*f(){yield super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});console.log(o.f().next().value);'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
object_super_async_generator: {
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
async *f() {
|
||||||
|
return super.p;
|
||||||
|
},
|
||||||
|
p: "FAIL",
|
||||||
|
};
|
||||||
|
Object.setPrototypeOf(o, { p: "PASS" });
|
||||||
|
o.f().next().then(function(v) {
|
||||||
|
console.log(v.value, v.done);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={async*f(){return super.p},p:"FAIL"};Object.setPrototypeOf(o,{p:"PASS"});o.f().next().then(function(v){console.log(v.value,v.done)});'
|
||||||
|
expect_stdout: "PASS true"
|
||||||
|
node_version: ">=10"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4269_1: {
|
issue_4269_1: {
|
||||||
options = {
|
options = {
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
|
|||||||
213
test/compress/optional-chains.js
Normal file
213
test/compress/optional-chains.js
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
call: {
|
||||||
|
input: {
|
||||||
|
console.log?.(undefined?.(console.log("FAIL")));
|
||||||
|
}
|
||||||
|
expect_exact: 'console.log?.((void 0)?.(console.log("FAIL")));'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot: {
|
||||||
|
input: {
|
||||||
|
console?.log((void 0)?.p);
|
||||||
|
}
|
||||||
|
expect_exact: "console?.log((void 0)?.p);"
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
dot_in: {
|
||||||
|
input: {
|
||||||
|
var o = { in: 42 };
|
||||||
|
console.log(o.in, o?.in);
|
||||||
|
}
|
||||||
|
expect_exact: "var o={in:42};console.log(o.in,o?.in);"
|
||||||
|
expect_stdout: "42 42"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
sub: {
|
||||||
|
input: {
|
||||||
|
console?.["log"](null?.[console.log("FAIL")]);
|
||||||
|
}
|
||||||
|
expect_exact: 'console?.["log"](null?.[console.log("FAIL")]);'
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
ternary_decimal: {
|
||||||
|
input: {
|
||||||
|
null ? .42 : console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_exact: 'null?.42:console.log("PASS");'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
A = 42;
|
||||||
|
a?.[42];
|
||||||
|
console.log(typeof A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
A = 42;
|
||||||
|
a?.[42];
|
||||||
|
console.log(typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: "number"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
collapse_vars_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
A = 42;
|
||||||
|
a?.(42);
|
||||||
|
console.log(typeof A);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
A = 42;
|
||||||
|
a?.(42);
|
||||||
|
console.log(typeof A);
|
||||||
|
}
|
||||||
|
expect_stdout: "number"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log(a?.["FAIL"]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log(a?.FAIL);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
null?.[a = 0];
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
null?.[a = 0];
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
reduce_vars_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
null?.(a = 0);
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
null?.(a = 0);
|
||||||
|
console.log(a ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
a?.[a = "FAIL"];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
a?.[a = "FAIL"];
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function(a, b) {
|
||||||
|
console?.log?.(a?.p, b?.[console.log("FAIL")]);
|
||||||
|
})?.({ p: "PASS" });
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function(a, b) {
|
||||||
|
console?.log?.(a.p, void 0);
|
||||||
|
})({ p: "PASS" });
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS undefined"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
trim_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
optional_chains: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(void console.log("PASS"))?.[console.log("FAIL")];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4906: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
do {
|
||||||
|
var a = a?.[42];
|
||||||
|
} while (console.log("PASS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
do {} while (console.log("PASS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=14"
|
||||||
|
}
|
||||||
@@ -1378,3 +1378,88 @@ issue_3389: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_super: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
({
|
||||||
|
f(a) {
|
||||||
|
return a ? console.log("PASS") : super.log("PASS");
|
||||||
|
},
|
||||||
|
}).f(console);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
({
|
||||||
|
f(a) {
|
||||||
|
return a ? console.log("PASS") : super.log("PASS");
|
||||||
|
},
|
||||||
|
}).f(console);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4831_1: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
f() {
|
||||||
|
return arguments;
|
||||||
|
},
|
||||||
|
}.f("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log([
|
||||||
|
function() {
|
||||||
|
return arguments;
|
||||||
|
},
|
||||||
|
][0]("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4831_2: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = {
|
||||||
|
f() {
|
||||||
|
return arguments;
|
||||||
|
},
|
||||||
|
}.f;
|
||||||
|
console.log(f("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var f = {
|
||||||
|
f() {
|
||||||
|
return arguments;
|
||||||
|
},
|
||||||
|
}.f;
|
||||||
|
console.log(f("PASS")[0]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4888: {
|
||||||
|
options = {
|
||||||
|
properties: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(typeof {
|
||||||
|
__proto__: 42,
|
||||||
|
}.__proto__);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(typeof {
|
||||||
|
__proto__: 42,
|
||||||
|
}.__proto__);
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
}
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ conditional: {
|
|||||||
relational: {
|
relational: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
foo() in new foo();
|
foo() in new foo();
|
||||||
@@ -158,7 +158,7 @@ relational: {
|
|||||||
arithmetic: {
|
arithmetic: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
foo() + foo();
|
foo() + foo();
|
||||||
@@ -183,7 +183,7 @@ arithmetic: {
|
|||||||
boolean_and: {
|
boolean_and: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
foo() && foo();
|
foo() && foo();
|
||||||
@@ -208,7 +208,7 @@ boolean_and: {
|
|||||||
boolean_or: {
|
boolean_or: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
foo() || foo();
|
foo() || foo();
|
||||||
@@ -233,7 +233,7 @@ boolean_or: {
|
|||||||
assign: {
|
assign: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
var a;
|
var a;
|
||||||
@@ -256,7 +256,7 @@ assign: {
|
|||||||
unary: {
|
unary: {
|
||||||
options = {
|
options = {
|
||||||
pure_funcs: [ "foo" ],
|
pure_funcs: [ "foo" ],
|
||||||
side_effects :true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
typeof foo();
|
typeof foo();
|
||||||
@@ -294,248 +294,6 @@ unary: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_2629_1: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ a();
|
|
||||||
/*@__PURE__*/ (b());
|
|
||||||
(/*@__PURE__*/ c)();
|
|
||||||
(/*@__PURE__*/ d());
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"/* */c();",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2629_2: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ a(1)(2)(3);
|
|
||||||
/*@__PURE__*/ (b(1))(2)(3);
|
|
||||||
/*@__PURE__*/ (c(1)(2))(3);
|
|
||||||
/*@__PURE__*/ (d(1)(2)(3));
|
|
||||||
(/*@__PURE__*/ e)(1)(2)(3);
|
|
||||||
(/*@__PURE__*/ f(1))(2)(3);
|
|
||||||
(/*@__PURE__*/ g(1)(2))(3);
|
|
||||||
(/*@__PURE__*/ h(1)(2)(3));
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"/* */e(1)(2)(3);",
|
|
||||||
"/* */f(1)(2)(3);",
|
|
||||||
"/* */g(1)(2)(3);",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2629_3: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ a.x(1).y(2).z(3);
|
|
||||||
/*@__PURE__*/ (b.x)(1).y(2).z(3);
|
|
||||||
/*@__PURE__*/ (c.x(1)).y(2).z(3);
|
|
||||||
/*@__PURE__*/ (d.x(1).y)(2).z(3);
|
|
||||||
/*@__PURE__*/ (e.x(1).y(2)).z(3);
|
|
||||||
/*@__PURE__*/ (f.x(1).y(2).z)(3);
|
|
||||||
/*@__PURE__*/ (g.x(1).y(2).z(3));
|
|
||||||
(/*@__PURE__*/ h).x(1).y(2).z(3);
|
|
||||||
(/*@__PURE__*/ i.x)(1).y(2).z(3);
|
|
||||||
(/*@__PURE__*/ j.x(1)).y(2).z(3);
|
|
||||||
(/*@__PURE__*/ k.x(1).y)(2).z(3);
|
|
||||||
(/*@__PURE__*/ l.x(1).y(2)).z(3);
|
|
||||||
(/*@__PURE__*/ m.x(1).y(2).z)(3);
|
|
||||||
(/*@__PURE__*/ n.x(1).y(2).z(3));
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"/* */h.x(1).y(2).z(3);",
|
|
||||||
"/* */i.x(1).y(2).z(3);",
|
|
||||||
"/* */j.x(1).y(2).z(3);",
|
|
||||||
"/* */k.x(1).y(2).z(3);",
|
|
||||||
"/* */l.x(1).y(2).z(3);",
|
|
||||||
"/* */m.x(1).y(2).z(3);",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2629_4: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(/*@__PURE__*/ x(), y());
|
|
||||||
(w(), /*@__PURE__*/ x(), y());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
y();
|
|
||||||
w(), y();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2629_5: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
[ /*@__PURE__*/ x() ];
|
|
||||||
[ /*@__PURE__*/ x(), y() ];
|
|
||||||
[ w(), /*@__PURE__*/ x(), y() ];
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
y();
|
|
||||||
w(), y();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2638: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/(g() || h())(x(), y());
|
|
||||||
(/*@__PURE__*/ (a() || b()))(c(), d());
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"/* */x(),y();",
|
|
||||||
"/* */(a()||b())(c(),d());",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_1: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ new a();
|
|
||||||
/*@__PURE__*/ (new b());
|
|
||||||
new (/*@__PURE__*/ c)();
|
|
||||||
(/*@__PURE__*/ new d());
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"new/* */c;",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_2: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ new a(1)(2)(3);
|
|
||||||
/*@__PURE__*/ new (b(1))(2)(3);
|
|
||||||
/*@__PURE__*/ new (c(1)(2))(3);
|
|
||||||
/*@__PURE__*/ new (d(1)(2)(3));
|
|
||||||
new (/*@__PURE__*/ e)(1)(2)(3);
|
|
||||||
(/*@__PURE__*/ new f(1))(2)(3);
|
|
||||||
(/*@__PURE__*/ new g(1)(2))(3);
|
|
||||||
(/*@__PURE__*/ new h(1)(2)(3));
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"new/* */e(1)(2)(3);",
|
|
||||||
"/* */new f(1)(2)(3);",
|
|
||||||
"/* */new g(1)(2)(3);",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_3: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/ new a.x(1).y(2).z(3);
|
|
||||||
/*@__PURE__*/ new (b.x)(1).y(2).z(3);
|
|
||||||
/*@__PURE__*/ new (c.x(1)).y(2).z(3);
|
|
||||||
/*@__PURE__*/ new (d.x(1).y)(2).z(3);
|
|
||||||
/*@__PURE__*/ new (e.x(1).y(2)).z(3);
|
|
||||||
/*@__PURE__*/ new (f.x(1).y(2).z)(3);
|
|
||||||
/*@__PURE__*/ new (g.x(1).y(2).z(3));
|
|
||||||
new (/*@__PURE__*/ h).x(1).y(2).z(3);
|
|
||||||
/* */ new (/*@__PURE__*/ i.x)(1).y(2).z(3);
|
|
||||||
(/*@__PURE__*/ new j.x(1)).y(2).z(3);
|
|
||||||
(/*@__PURE__*/ new k.x(1).y)(2).z(3);
|
|
||||||
(/*@__PURE__*/ new l.x(1).y(2)).z(3);
|
|
||||||
(/*@__PURE__*/ new m.x(1).y(2).z)(3);
|
|
||||||
(/*@__PURE__*/ new n.x(1).y(2).z(3));
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"new/* */h.x(1).y(2).z(3);",
|
|
||||||
"/* */new/* */i.x(1).y(2).z(3);",
|
|
||||||
"/* */new j.x(1).y(2).z(3);",
|
|
||||||
"/* */new k.x(1).y(2).z(3);",
|
|
||||||
"/* */new l.x(1).y(2).z(3);",
|
|
||||||
"/* */new m.x(1).y(2).z(3);",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_4: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
(/*@__PURE__*/ new x(), y());
|
|
||||||
(w(), /*@__PURE__*/ new x(), y());
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
y();
|
|
||||||
w(), y();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_5: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
[ /*@__PURE__*/ new x() ];
|
|
||||||
[ /*@__PURE__*/ new x(), y() ];
|
|
||||||
[ w(), /*@__PURE__*/ new x(), y() ];
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
y();
|
|
||||||
w(), y();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_2705_6: {
|
|
||||||
options = {
|
|
||||||
side_effects: true,
|
|
||||||
}
|
|
||||||
beautify = {
|
|
||||||
comments: "all",
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
/*@__PURE__*/new (g() || h())(x(), y());
|
|
||||||
/* */ new (/*@__PURE__*/ (a() || b()))(c(), d());
|
|
||||||
}
|
|
||||||
expect_exact: [
|
|
||||||
"/* */x(),y();",
|
|
||||||
"/* */new(/* */a()||b())(c(),d());",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
issue_3065_1: {
|
issue_3065_1: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -680,130 +438,3 @@ issue_3325_2: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3858: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var f = function(a) {
|
|
||||||
return /*@__PURE__*/ function(b) {
|
|
||||||
console.log(b);
|
|
||||||
}(a);
|
|
||||||
};
|
|
||||||
f("PASS");
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var f = function(a) {
|
|
||||||
return function() {
|
|
||||||
console.log(a);
|
|
||||||
}();
|
|
||||||
};
|
|
||||||
f("PASS");
|
|
||||||
}
|
|
||||||
expect_stdout: "PASS"
|
|
||||||
}
|
|
||||||
|
|
||||||
inline_pure_call_1: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var f = function(a) {
|
|
||||||
return /*@__PURE__*/ function(b) {
|
|
||||||
console.log(b);
|
|
||||||
}(a);
|
|
||||||
};
|
|
||||||
f("PASS");
|
|
||||||
}
|
|
||||||
expect: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline_pure_call_2: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
reduce_vars: true,
|
|
||||||
sequences: true,
|
|
||||||
side_effects: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var f = function(a) {
|
|
||||||
return /*@__PURE__*/ function(b) {
|
|
||||||
console.log(b);
|
|
||||||
}(a);
|
|
||||||
};
|
|
||||||
var a = f("PASS");
|
|
||||||
}
|
|
||||||
expect: {}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline_pure_call_3: {
|
|
||||||
options = {
|
|
||||||
collapse_vars: true,
|
|
||||||
evaluate: true,
|
|
||||||
inline: true,
|
|
||||||
keep_fargs: false,
|
|
||||||
passes: 2,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var f = function(a) {
|
|
||||||
return /*@__PURE__*/ function(b) {
|
|
||||||
console.log(b);
|
|
||||||
}(a);
|
|
||||||
};
|
|
||||||
var a = f("PASS");
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = function() {
|
|
||||||
console.log("PASS");
|
|
||||||
}();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"PASS",
|
|
||||||
"undefined",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
inline_pure_call_4: {
|
|
||||||
options = {
|
|
||||||
evaluate: true,
|
|
||||||
reduce_vars: true,
|
|
||||||
toplevel: true,
|
|
||||||
unused: true,
|
|
||||||
}
|
|
||||||
input: {
|
|
||||||
var a = /*@__PURE__*/ function() {
|
|
||||||
return console.log("PASS"), 42;
|
|
||||||
}();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect: {
|
|
||||||
var a = function() {
|
|
||||||
return console.log("PASS"), 42;
|
|
||||||
}();
|
|
||||||
console.log(a);
|
|
||||||
}
|
|
||||||
expect_stdout: [
|
|
||||||
"PASS",
|
|
||||||
"42",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1220,13 +1220,110 @@ drop_arguments: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lvalues_def: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
var a = b++, b = +function() {}();
|
||||||
|
a && a[a++];
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 1;
|
||||||
|
a = b++, b = +void 0;
|
||||||
|
a && a++;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
side_effects_assign: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
pure_getters: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = typeof void (a && a.in == 1, 0);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "undefined";
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2062: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
collapse_vars: true,
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 1;
|
||||||
|
if ([ a || a++ + a--, a++ + a--, a && a.var ]);
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 1;
|
||||||
|
a || (a++, a--), a++, a--;
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2878: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: true,
|
||||||
|
sequences: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a, b) {
|
||||||
|
function f2() {
|
||||||
|
if (a) c++;
|
||||||
|
}
|
||||||
|
b = f2();
|
||||||
|
a = 1;
|
||||||
|
b && b.b;
|
||||||
|
f2();
|
||||||
|
})();
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var c = 0;
|
||||||
|
(function(a, b) {
|
||||||
|
function f2() {
|
||||||
|
if (a) c++;
|
||||||
|
}
|
||||||
|
b = f2(),
|
||||||
|
a = 1,
|
||||||
|
f2();
|
||||||
|
})(),
|
||||||
|
console.log(c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1"
|
||||||
|
}
|
||||||
|
|
||||||
issue_3427: {
|
issue_3427: {
|
||||||
options = {
|
options = {
|
||||||
assignments: true,
|
evaluate: true,
|
||||||
collapse_vars: true,
|
|
||||||
inline: true,
|
inline: true,
|
||||||
passes: 2,
|
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
sequences: true,
|
sequences: true,
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
toplevel: true,
|
toplevel: true,
|
||||||
@@ -1242,6 +1339,74 @@ issue_3427: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_3490_1: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
dead_code: true,
|
||||||
|
inline: true,
|
||||||
|
pure_getters: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var b = 42, c = "FAIL";
|
||||||
|
if ({
|
||||||
|
3: function() {
|
||||||
|
var a;
|
||||||
|
return (a && a.p) < this;
|
||||||
|
}(),
|
||||||
|
}) c = "PASS";
|
||||||
|
if (b) while ("" == typeof d);
|
||||||
|
console.log(c, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var b = 42, c = "FAIL";
|
||||||
|
if (function() {
|
||||||
|
var a;
|
||||||
|
}(), c = "PASS", b) while ("" == typeof d);
|
||||||
|
console.log(c, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 42"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4135: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
inline: true,
|
||||||
|
merge_vars: true,
|
||||||
|
pure_getters: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
--b;
|
||||||
|
a++;
|
||||||
|
if (!a)
|
||||||
|
var c = function() {
|
||||||
|
var d = 0;
|
||||||
|
function f() {
|
||||||
|
d && d.p;
|
||||||
|
}
|
||||||
|
f();
|
||||||
|
this;
|
||||||
|
}(a++);
|
||||||
|
console.log(a, b, c);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0;
|
||||||
|
0;
|
||||||
|
a++;
|
||||||
|
if (!a)
|
||||||
|
var c = void a++;
|
||||||
|
console.log(a, -1, c);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 -1 undefined"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4440: {
|
issue_4440: {
|
||||||
options = {
|
options = {
|
||||||
pure_getters: "strict",
|
pure_getters: "strict",
|
||||||
@@ -1270,3 +1435,206 @@ issue_4440: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4730_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS") + (a && a[a.p]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4730_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
!console.log("PASS") || a && a[a.p];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4751: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o && o.p;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super_toString: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
f() {
|
||||||
|
return super.toString();
|
||||||
|
},
|
||||||
|
}.f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
f() {
|
||||||
|
return super.toString();
|
||||||
|
},
|
||||||
|
}.f());
|
||||||
|
}
|
||||||
|
expect_stdout: "[object Object]"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
this_toString: {
|
||||||
|
options = {
|
||||||
|
pure_getters: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log({
|
||||||
|
f() {
|
||||||
|
return this.toString();
|
||||||
|
},
|
||||||
|
}.f());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log({
|
||||||
|
f() {
|
||||||
|
return "" + this;
|
||||||
|
},
|
||||||
|
}.f());
|
||||||
|
}
|
||||||
|
expect_stdout: "[object Object]"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4803: {
|
||||||
|
options = {
|
||||||
|
hoist_vars: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get f() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
} || 42;
|
||||||
|
for (var k in o)
|
||||||
|
o[k];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var k, o = {
|
||||||
|
get f() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
} || 42;
|
||||||
|
for (k in o)
|
||||||
|
o[k];
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_property_assignments_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f;
|
||||||
|
((f = function() {
|
||||||
|
console.log("FAIL");
|
||||||
|
}).p = f).q = console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_property_assignments_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {};
|
||||||
|
(function() {
|
||||||
|
var a;
|
||||||
|
(o.p = a = {}).q = "PASS";
|
||||||
|
})();
|
||||||
|
console.log(o.p.q);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {};
|
||||||
|
(function() {
|
||||||
|
(o.p = {}).q = "PASS";
|
||||||
|
})();
|
||||||
|
console.log(o.p.q);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
nested_property_assignments_3: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
pure_getters: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = { p: {} };
|
||||||
|
(function(a) {
|
||||||
|
console && a;
|
||||||
|
if (console) {
|
||||||
|
a = a.p;
|
||||||
|
a.q = a;
|
||||||
|
}
|
||||||
|
})(o);
|
||||||
|
console.log(o.p.q === o.p ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = { p: {} };
|
||||||
|
(function(a) {
|
||||||
|
console;
|
||||||
|
if (console)
|
||||||
|
(a = a.p).q = a;
|
||||||
|
})(o);
|
||||||
|
console.log(o.p.q === o.p ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -2460,6 +2460,7 @@ delay_def: {
|
|||||||
evaluate: true,
|
evaluate: true,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
|
|||||||
@@ -673,26 +673,114 @@ issue_4575: {
|
|||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
A = "PASS";
|
(function(a) {
|
||||||
(function() {
|
var b = a;
|
||||||
var a = 0, b = a;
|
var c = function a(...d) {
|
||||||
var c = function a(...b) {
|
console.log(d.length);
|
||||||
A;
|
|
||||||
var d = A;
|
|
||||||
console.log(d, b.length);
|
|
||||||
}();
|
}();
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
A = "PASS";
|
(function(a) {
|
||||||
(function() {
|
(function a(...d) {
|
||||||
(function(b) {
|
console.log(d.length);
|
||||||
A;
|
})();
|
||||||
var d = A;
|
|
||||||
console.log(d, b.length);
|
|
||||||
})([]);
|
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS 0"
|
expect_stdout: "0"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4621: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(function f(a, ...{
|
||||||
|
[console.log(a)]: b,
|
||||||
|
}) {})("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function f(a, ...{
|
||||||
|
[console.log(a)]: b,
|
||||||
|
}) {})("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4644_1: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(function f(b, ...{
|
||||||
|
[a = "PASS"]: c,
|
||||||
|
}) {
|
||||||
|
return b;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
(function f(b, ...{
|
||||||
|
[a = "PASS"]: c,
|
||||||
|
}) {
|
||||||
|
return b;
|
||||||
|
})();
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4644_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(function(...a) {
|
||||||
|
return a[1];
|
||||||
|
}("FAIL", "PASS"), function(...b) {
|
||||||
|
return b.length;
|
||||||
|
}(), function(c, ...d) {
|
||||||
|
return d[0];
|
||||||
|
}("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("PASS", 0, function(c, ...d) {
|
||||||
|
return d[0];
|
||||||
|
}("FAIL"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS 0 undefined"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4666: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
rests: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var o = ((...c) => a++ + c)(b);
|
||||||
|
for (var k in o)
|
||||||
|
b++;
|
||||||
|
console.log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = 0, b = 0;
|
||||||
|
var o = (c => +a + c)([ b ]);
|
||||||
|
for(var k in o)
|
||||||
|
b++;
|
||||||
|
console.log(1, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "1 2"
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,3 +172,32 @@ issue_4054: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "{ p: [Setter] }"
|
expect_stdout: "{ p: [Setter] }"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4811_1: {
|
||||||
|
input: {
|
||||||
|
for (var PASS in this);
|
||||||
|
console.log(PASS, this, {} < this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var PASS in this);
|
||||||
|
console.log(PASS, this, {} < this);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS [object global] true"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4811_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
(async function() {});
|
||||||
|
for (var PASS in this);
|
||||||
|
console.log(PASS, this, {} < this);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
for (var PASS in this);
|
||||||
|
console.log(PASS, this, {} < this);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS [object global] true"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
@@ -564,6 +564,34 @@ delete_seq_3: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete_seq_4: {
|
delete_seq_4: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: false,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
console.log(delete (f(), undefined));
|
||||||
|
console.log(delete (f(), void 0));
|
||||||
|
console.log(delete (f(), Infinity));
|
||||||
|
console.log(delete (f(), 1 / 0));
|
||||||
|
console.log(delete (f(), NaN));
|
||||||
|
console.log(delete (f(), 0 / 0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
console.log(delete void f()),
|
||||||
|
console.log(delete void f()),
|
||||||
|
console.log((f(), delete (1 / 0))),
|
||||||
|
console.log((f(), delete (1 / 0))),
|
||||||
|
console.log(delete (f(), NaN)),
|
||||||
|
console.log((f(), delete(0 / 0)));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_seq_4_evaluate: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -592,6 +620,35 @@ delete_seq_4: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
delete_seq_5: {
|
delete_seq_5: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
evaluate: false,
|
||||||
|
keep_infinity: true,
|
||||||
|
sequences: true,
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
console.log(delete (f(), undefined));
|
||||||
|
console.log(delete (f(), void 0));
|
||||||
|
console.log(delete (f(), Infinity));
|
||||||
|
console.log(delete (f(), 1 / 0));
|
||||||
|
console.log(delete (f(), NaN));
|
||||||
|
console.log(delete (f(), 0 / 0));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
console.log(delete void f()),
|
||||||
|
console.log(delete void f()),
|
||||||
|
console.log(delete (f(), Infinity)),
|
||||||
|
console.log((f(), delete (1 / 0))),
|
||||||
|
console.log(delete (f(), NaN)),
|
||||||
|
console.log((f(), delete (0 / 0)));
|
||||||
|
}
|
||||||
|
expect_stdout: true
|
||||||
|
}
|
||||||
|
|
||||||
|
delete_seq_5_evaluate: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
evaluate: true,
|
evaluate: true,
|
||||||
@@ -663,12 +720,21 @@ side_effects_cascade_1: {
|
|||||||
if (a < 0) a = 0;
|
if (a < 0) a = 0;
|
||||||
b.a = a;
|
b.a = a;
|
||||||
}
|
}
|
||||||
|
var m = {}, n = {};
|
||||||
|
f(13, m);
|
||||||
|
f("foo", n);
|
||||||
|
console.log(m.a, n.a);
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
function f(a, b) {
|
function f(a, b) {
|
||||||
(a -= 42) < 0 && (a = 0), b.a = a;
|
b.a = a = (a -= 42) < 0 ? 0 : a;
|
||||||
}
|
}
|
||||||
|
var m = {}, n = {};
|
||||||
|
f(13, m),
|
||||||
|
f("foo", n),
|
||||||
|
console.log(m.a, n.a);
|
||||||
}
|
}
|
||||||
|
expect_stdout: "0 NaN"
|
||||||
}
|
}
|
||||||
|
|
||||||
side_effects_cascade_2: {
|
side_effects_cascade_2: {
|
||||||
|
|||||||
@@ -198,6 +198,36 @@ global_fns: {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global_constructors: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
Map;
|
||||||
|
new Map(console.log("foo"));
|
||||||
|
Set;
|
||||||
|
new Set(console.log("bar"));
|
||||||
|
WeakMap;
|
||||||
|
new WeakMap(console.log("baz"));
|
||||||
|
WeakSet;
|
||||||
|
new WeakSet(console.log("moo"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("foo");
|
||||||
|
console.log("bar");
|
||||||
|
console.log("baz");
|
||||||
|
console.log("moo");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"baz",
|
||||||
|
"moo",
|
||||||
|
]
|
||||||
|
node_version: ">=0.12"
|
||||||
|
}
|
||||||
|
|
||||||
unsafe_builtin_1: {
|
unsafe_builtin_1: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -348,8 +378,6 @@ issue_3983_1: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
var a = "PASS";
|
var a = "PASS";
|
||||||
g();
|
|
||||||
function g() {}
|
|
||||||
console.log(a);
|
console.log(a);
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -458,14 +486,14 @@ issue_4325: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
(function() {
|
(function() {
|
||||||
(function() {
|
(function(c) {
|
||||||
try {
|
try {
|
||||||
(void 0).p = 0;
|
c.p = 0;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log("PASS");
|
console.log("PASS");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})();
|
})(void 0);
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
@@ -506,3 +534,114 @@ issue_4366_2: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4668: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
keep_fargs: false,
|
||||||
|
keep_fnames: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b, c;
|
||||||
|
function g() {
|
||||||
|
return a = 0 + a, !d || (a = 0);
|
||||||
|
}
|
||||||
|
c = g();
|
||||||
|
}
|
||||||
|
console.log(f());
|
||||||
|
var d = 0;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f() {
|
||||||
|
(function g() {
|
||||||
|
0;
|
||||||
|
})();
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "undefined"
|
||||||
|
}
|
||||||
|
|
||||||
|
drop_side_effect_free_call: {
|
||||||
|
options = {
|
||||||
|
inline: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
side_effects: true,
|
||||||
|
toplevel: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
return "PA" + a;
|
||||||
|
}
|
||||||
|
f(42);
|
||||||
|
console.log(f("SS"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f(a) {
|
||||||
|
return "PA" + a;
|
||||||
|
}
|
||||||
|
console.log(f("SS"));
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4730_1: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS") + (a && a[a.p]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
console.log("PASS"),
|
||||||
|
a && a[a.p];
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4730_2: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
!console.log("PASS") || a && a[a.p];
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a;
|
||||||
|
!console.log("PASS") || a && a[a.p];
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4751: {
|
||||||
|
options = {
|
||||||
|
pure_getters: "strict",
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o && o.p;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
get p() {
|
||||||
|
console.log("PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
o && o.p;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ collapse_vars_4: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
conditionals_farg: {
|
conditionals_farg_1: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
}
|
}
|
||||||
@@ -107,6 +107,28 @@ conditionals_farg: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conditionals_farg_2: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
pure_getters: "strict",
|
||||||
|
reduce_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var log = console.log;
|
||||||
|
(function(a) {
|
||||||
|
return a.length ? log(...a) : log("FAIL");
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var log = console.log;
|
||||||
|
(function(a) {
|
||||||
|
return a.length ? log(...a) : log("FAIL");
|
||||||
|
})([ "PASS" ]);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
dont_inline: {
|
dont_inline: {
|
||||||
options = {
|
options = {
|
||||||
inline: true,
|
inline: true,
|
||||||
@@ -272,6 +294,31 @@ reduce_vars_2: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reduce_vars_3: {
|
||||||
|
options = {
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return (a => a)(...[ f ]);
|
||||||
|
}
|
||||||
|
console.log(g() === g() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function f() {}
|
||||||
|
function g() {
|
||||||
|
return (a => a)(...[ f ]);
|
||||||
|
}
|
||||||
|
console.log(g() === g() ? "PASS" : "FAIL");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
convert_setter: {
|
convert_setter: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
@@ -667,6 +714,57 @@ unused_var_side_effects: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe_join_1: {
|
||||||
|
options = {
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log([ ..."foo" ].join());
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log([ ..."foo" ].join());
|
||||||
|
}
|
||||||
|
expect_stdout: "f,o,o"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_join_2: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log([ "foo", ..."bar" ].join(""));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log([ "foo", ..."bar" ].join(""));
|
||||||
|
}
|
||||||
|
expect_stdout: "foobar"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe_join_3: {
|
||||||
|
options = {
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
try {
|
||||||
|
[].join(...console);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
try {
|
||||||
|
[].join(...console);
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=6"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4329: {
|
issue_4329: {
|
||||||
options = {
|
options = {
|
||||||
objects: true,
|
objects: true,
|
||||||
@@ -947,3 +1045,114 @@ issue_4614: {
|
|||||||
expect_stdout: true
|
expect_stdout: true
|
||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4849: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
while (function() {
|
||||||
|
while (!console);
|
||||||
|
}(new function(a) {
|
||||||
|
console.log(typeof { ...a });
|
||||||
|
}(function() {})));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
while (function() {
|
||||||
|
while (!console);
|
||||||
|
}(function(a) {
|
||||||
|
console.log(typeof { ...function() {} });
|
||||||
|
}()));
|
||||||
|
}
|
||||||
|
expect_stdout: "object"
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4882_1: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
... {
|
||||||
|
__proto__: {
|
||||||
|
p: "FAIL 1",
|
||||||
|
q: "FAIL 2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(o.p);
|
||||||
|
console.log(o.q);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
p: "PASS",
|
||||||
|
};
|
||||||
|
console.log(o.p);
|
||||||
|
console.log(o.q);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"undefined",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4882_2: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(null == Object.getPrototypeOf({
|
||||||
|
... {
|
||||||
|
__proto__: (console.log(42), null),
|
||||||
|
},
|
||||||
|
}) ? "FAIL" : "PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(null == Object.getPrototypeOf({
|
||||||
|
... {
|
||||||
|
__proto__: (console.log(42), null),
|
||||||
|
},
|
||||||
|
}) ? "FAIL" : "PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"42",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4882_3: {
|
||||||
|
options = {
|
||||||
|
objects: true,
|
||||||
|
spreads: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
__proto__: { p: 42 },
|
||||||
|
... {
|
||||||
|
set __proto__(v) {},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
console.log(o.__proto__ === Object.getPrototypeOf(o) ? "FAIL" : "PASS");
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
__proto__: { p: 42 },
|
||||||
|
["__proto__"]: void 0,
|
||||||
|
};
|
||||||
|
console.log(o.__proto__ === Object.getPrototypeOf(o) ? "FAIL" : "PASS");
|
||||||
|
console.log(o.p);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"42",
|
||||||
|
]
|
||||||
|
node_version: ">=8"
|
||||||
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ tagged_chain: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_parenthesis_arrow: {
|
tag_parentheses_arrow: {
|
||||||
input: {
|
input: {
|
||||||
console.log((s => s.raw[0])`\tPASS`.slice(2));
|
console.log((s => s.raw[0])`\tPASS`.slice(2));
|
||||||
}
|
}
|
||||||
@@ -62,7 +62,24 @@ tag_parenthesis_arrow: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
tag_parenthesis_new: {
|
tag_parentheses_binary: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var f = function() {
|
||||||
|
console.log("PASS");
|
||||||
|
} || console
|
||||||
|
f``;
|
||||||
|
}
|
||||||
|
expect_exact: '(function(){console.log("PASS")}||console)``;'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_parentheses_new: {
|
||||||
input: {
|
input: {
|
||||||
(new function() {
|
(new function() {
|
||||||
return console.log;
|
return console.log;
|
||||||
@@ -73,6 +90,35 @@ tag_parenthesis_new: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tag_parentheses_sequence: {
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
console.log(this === o ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(42, o.f)``;
|
||||||
|
}
|
||||||
|
expect_exact: 'var o={f(){console.log(this===o?"FAIL":"PASS")}};(42,o.f)``;'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
tag_parentheses_unary: {
|
||||||
|
input: {
|
||||||
|
var a;
|
||||||
|
try {
|
||||||
|
(~a)``;
|
||||||
|
(a++)``;
|
||||||
|
} catch (e) {
|
||||||
|
console.log("PASS");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_exact: 'var a;try{(~a)``;(a++)``}catch(e){console.log("PASS")}'
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
malformed_escape: {
|
malformed_escape: {
|
||||||
input: {
|
input: {
|
||||||
(function(s) {
|
(function(s) {
|
||||||
@@ -211,7 +257,7 @@ unsafe_evaluate: {
|
|||||||
node_version: ">=8"
|
node_version: ">=8"
|
||||||
}
|
}
|
||||||
|
|
||||||
side_effects: {
|
side_effects_1: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
}
|
}
|
||||||
@@ -228,6 +274,30 @@ side_effects: {
|
|||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
side_effects_2: {
|
||||||
|
options = {
|
||||||
|
side_effects: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
console.log(this === o ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(42, o.f)``;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var o = {
|
||||||
|
f() {
|
||||||
|
console.log(this === o ? "FAIL" : "PASS");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
(0, o.f)``;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
unsafe_side_effects: {
|
unsafe_side_effects: {
|
||||||
options = {
|
options = {
|
||||||
side_effects: true,
|
side_effects: true,
|
||||||
@@ -283,3 +353,48 @@ issue_4606: {
|
|||||||
expect_stdout: "undefined \r \\ `"
|
expect_stdout: "undefined \r \\ `"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4630: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
templates: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
console.log(`${/PASS/}`);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log("/PASS/");
|
||||||
|
}
|
||||||
|
expect_stdout: "/PASS/"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_4676: {
|
||||||
|
options = {
|
||||||
|
evaluate: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
templates: true,
|
||||||
|
toplevel: true,
|
||||||
|
unsafe: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function f(a) {
|
||||||
|
var b = `foo${a = "PASS"}`;
|
||||||
|
for (var c in f && b)
|
||||||
|
b.p;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
console.log(f("FAIL"));
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
console.log(function f(a) {
|
||||||
|
var b = "fooPASS";
|
||||||
|
for (var c in f, b)
|
||||||
|
b.p;
|
||||||
|
return "PASS";
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ unicode_parse_variables: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unicode_escaped_identifier: {
|
unicode_escaped_identifier_1: {
|
||||||
input: {
|
input: {
|
||||||
var \u0061 = "\ud800\udc00";
|
var \u0061 = "\ud800\udc00";
|
||||||
console.log(a);
|
console.log(a);
|
||||||
@@ -59,6 +59,17 @@ unicode_escaped_identifier: {
|
|||||||
expect_stdout: "\ud800\udc00"
|
expect_stdout: "\ud800\udc00"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unicode_escaped_identifier_2: {
|
||||||
|
input: {
|
||||||
|
var \u{61} = "foo";
|
||||||
|
var \u{10000} = "bar";
|
||||||
|
console.log(a, \u{10000});
|
||||||
|
}
|
||||||
|
expect_exact: 'var a="foo";var \u{10000}="bar";console.log(a,\u{10000});'
|
||||||
|
expect_stdout: "foo bar"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
unicode_identifier_ascii_only: {
|
unicode_identifier_ascii_only: {
|
||||||
beautify = {
|
beautify = {
|
||||||
ascii_only: true,
|
ascii_only: true,
|
||||||
|
|||||||
@@ -354,6 +354,92 @@ forin_let_2: {
|
|||||||
node_version: ">=6"
|
node_version: ">=6"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loop_scope_1: {
|
||||||
|
options = {
|
||||||
|
toplevel: true,
|
||||||
|
varify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var o = { foo: 1, bar: 2 };
|
||||||
|
for (let i in o) {
|
||||||
|
console.log(i);
|
||||||
|
}
|
||||||
|
for (const j in o)
|
||||||
|
setTimeout(() => console.log(j), 0);
|
||||||
|
for (let k in o)
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log(k);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var o = { foo: 1, bar: 2 };
|
||||||
|
for (var i in o)
|
||||||
|
console.log(i);
|
||||||
|
for (const j in o)
|
||||||
|
setTimeout(() => console.log(j), 0);
|
||||||
|
for (let k in o)
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log(k);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
|
loop_scope_2: {
|
||||||
|
options = {
|
||||||
|
reduce_vars: true,
|
||||||
|
toplevel: true,
|
||||||
|
varify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
"use strict";
|
||||||
|
var a = [ "foo", "bar" ];
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
const x = a[i];
|
||||||
|
console.log(x);
|
||||||
|
let y = a[i];
|
||||||
|
setTimeout(() => console.log(y), 0);
|
||||||
|
const z = a[i];
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log(z);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
"use strict";
|
||||||
|
var a = [ "foo", "bar" ];
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
var x = a[i];
|
||||||
|
console.log(x);
|
||||||
|
let y = a[i];
|
||||||
|
setTimeout(() => console.log(y), 0);
|
||||||
|
const z = a[i];
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log(z);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect_stdout: [
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"foo",
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
"bar",
|
||||||
|
]
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|
||||||
issue_4290_1_const: {
|
issue_4290_1_const: {
|
||||||
options = {
|
options = {
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
@@ -409,3 +495,31 @@ drop_forin_let: {
|
|||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
node_version: ">=4"
|
node_version: ">=4"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default_init: {
|
||||||
|
options = {
|
||||||
|
join_vars: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
varify: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
A = "PASS";
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
let a;
|
||||||
|
a = A;
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
A = "PASS";
|
||||||
|
(function() {
|
||||||
|
"use strict";
|
||||||
|
var a = A;
|
||||||
|
console.log(a);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
node_version: ">=4"
|
||||||
|
}
|
||||||
|
|||||||
1085
test/compress/yields.js
Normal file
1085
test/compress/yields.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
|||||||
exports["Compressor"] = Compressor;
|
exports["Compressor"] = Compressor;
|
||||||
exports["defaults"] = defaults;
|
exports["defaults"] = defaults;
|
||||||
|
exports["is_statement"] = is_statement;
|
||||||
exports["JS_Parse_Error"] = JS_Parse_Error;
|
exports["JS_Parse_Error"] = JS_Parse_Error;
|
||||||
exports["List"] = List;
|
exports["List"] = List;
|
||||||
exports["mangle_properties"] = mangle_properties;
|
exports["mangle_properties"] = mangle_properties;
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
++null
|
console.log(4 || (null = 4));
|
||||||
|
|||||||
1
test/input/invalid/assign_5.js
Normal file
1
test/input/invalid/assign_5.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
console.log(5 || ([]?.length ^= 5));
|
||||||
1
test/input/invalid/for-await.js
Normal file
1
test/input/invalid/for-await.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
for await (; console.log(42););
|
||||||
3
test/input/invalid/for-of_1.js
Normal file
3
test/input/invalid/for-of_1.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var a = [ 1 ], b;
|
||||||
|
for (b = 2 of a)
|
||||||
|
console.log(b);
|
||||||
3
test/input/invalid/for-of_2.js
Normal file
3
test/input/invalid/for-of_2.js
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
var a = [ 1 ];
|
||||||
|
for (var b = 2 of a)
|
||||||
|
console.log(b);
|
||||||
@@ -29,7 +29,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments all';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n\n");
|
assert.strictEqual(stdout, "// foo\n/*@preserve*/\n// bar\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -37,7 +37,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments /r/';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n\n");
|
assert.strictEqual(stdout, "/*@preserve*/\n// bar\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -45,7 +45,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
var command = uglifyjscmd + ' test/input/comments/filter.js --comments';
|
||||||
exec(command, function(err, stdout) {
|
exec(command, function(err, stdout) {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
assert.strictEqual(stdout, "/*@preserve*/\n\n");
|
assert.strictEqual(stdout, "/*@preserve*/\n");
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -333,11 +333,13 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/invalid/simple.js";
|
var command = uglifyjscmd + " test/input/invalid/simple.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/simple.js:1,12");
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
assert.strictEqual(lines[1], "function f(a{}");
|
"Parse error at test/input/invalid/simple.js:1,12",
|
||||||
assert.strictEqual(lines[2], " ^");
|
"function f(a{}",
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: punc «{», expected: punc «,»");
|
" ^",
|
||||||
|
"ERROR: Unexpected token: punc «{», expected: punc «,»",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -345,11 +347,13 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/invalid/tab.js";
|
var command = uglifyjscmd + " test/input/invalid/tab.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/tab.js:1,12");
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
assert.strictEqual(lines[1], "\t\tfoo(\txyz, 0abc);");
|
"Parse error at test/input/invalid/tab.js:1,12",
|
||||||
assert.strictEqual(lines[2], "\t\t \t ^");
|
"\t\tfoo(\txyz, 0abc);",
|
||||||
assert.strictEqual(lines[3], "ERROR: Invalid syntax: 0abc");
|
"\t\t \t ^",
|
||||||
|
"ERROR: Invalid syntax: 0abc",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -357,11 +361,13 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/invalid/eof.js";
|
var command = uglifyjscmd + " test/input/invalid/eof.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/eof.js:2,0");
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
assert.strictEqual(lines[1], "foo, bar(");
|
"Parse error at test/input/invalid/eof.js:2,0",
|
||||||
assert.strictEqual(lines[2], " ^");
|
"foo, bar(",
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
|
" ^",
|
||||||
|
"ERROR: Unexpected token: eof",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -369,11 +375,13 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/invalid/loop-no-body.js";
|
var command = uglifyjscmd + " test/input/invalid/loop-no-body.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/loop-no-body.js:2,0");
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
assert.strictEqual(lines[1], "for (var i = 0; i < 1; i++) ");
|
"Parse error at test/input/invalid/loop-no-body.js:2,0",
|
||||||
assert.strictEqual(lines[2], " ^");
|
"for (var i = 0; i < 1; i++) ",
|
||||||
assert.strictEqual(lines[3], "ERROR: Unexpected token: eof");
|
" ^",
|
||||||
|
"ERROR: Unexpected token: eof",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -386,7 +394,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/assign_1.js:1,18",
|
"Parse error at test/input/invalid/assign_1.js:1,18",
|
||||||
"console.log(1 || 5--);",
|
"console.log(1 || 5--);",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid use of -- operator"
|
"ERROR: Invalid use of -- operator",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -400,7 +408,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/assign_2.js:1,32",
|
"Parse error at test/input/invalid/assign_2.js:1,32",
|
||||||
"console.log(2 || (Math.random() /= 2));",
|
"console.log(2 || (Math.random() /= 2));",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid assignment"
|
"ERROR: Invalid assignment",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -414,21 +422,35 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/assign_3.js:1,17",
|
"Parse error at test/input/invalid/assign_3.js:1,17",
|
||||||
"console.log(3 || ++this);",
|
"console.log(3 || ++this);",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid use of ++ operator"
|
"ERROR: Invalid use of ++ operator",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("Should throw syntax error (++null)", function(done) {
|
it("Should throw syntax error (null = 4)", function(done) {
|
||||||
var command = uglifyjscmd + " test/input/invalid/assign_4.js";
|
var command = uglifyjscmd + " test/input/invalid/assign_4.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
assert.strictEqual(stdout, "");
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
"Parse error at test/input/invalid/assign_4.js:1,0",
|
"Parse error at test/input/invalid/assign_4.js:1,23",
|
||||||
"++null",
|
"console.log(4 || (null = 4));",
|
||||||
"^",
|
" ^",
|
||||||
"ERROR: Invalid use of ++ operator"
|
"ERROR: Invalid assignment",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error ([]?.length ^= 5)", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/assign_5.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/assign_5.js:1,29",
|
||||||
|
"console.log(5 || ([]?.length ^= 5));",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid assignment",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -442,7 +464,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_1.js:1,2",
|
"Parse error at test/input/invalid/dot_1.js:1,2",
|
||||||
"a.=",
|
"a.=",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator «=», expected: name"
|
"ERROR: Unexpected token: operator «=», expected: name",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -456,7 +478,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_2.js:1,0",
|
"Parse error at test/input/invalid/dot_2.js:1,0",
|
||||||
"%.a;",
|
"%.a;",
|
||||||
"^",
|
"^",
|
||||||
"ERROR: Unexpected token: operator «%»"
|
"ERROR: Unexpected token: operator «%»",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -470,7 +492,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/dot_3.js:1,2",
|
"Parse error at test/input/invalid/dot_3.js:1,2",
|
||||||
"a./();",
|
"a./();",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator «/», expected: name"
|
"ERROR: Unexpected token: operator «/», expected: name",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -484,7 +506,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/object.js:1,13",
|
"Parse error at test/input/invalid/object.js:1,13",
|
||||||
"console.log({%: 1});",
|
"console.log({%: 1});",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: operator «%»"
|
"ERROR: Unexpected token: operator «%»",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -498,7 +520,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/delete.js:13,11",
|
"Parse error at test/input/invalid/delete.js:13,11",
|
||||||
" delete x;",
|
" delete x;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Calling delete on expression not allowed in strict mode"
|
"ERROR: Calling delete on expression not allowed in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -512,7 +534,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/function_1.js:4,11",
|
"Parse error at test/input/invalid/function_1.js:4,11",
|
||||||
"function g(arguments) {",
|
"function g(arguments) {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected arguments in strict mode"
|
"ERROR: Unexpected arguments in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -526,7 +548,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/function_2.js:4,9",
|
"Parse error at test/input/invalid/function_2.js:4,9",
|
||||||
"function eval() {",
|
"function eval() {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -540,7 +562,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/function_3.js:4,10",
|
"Parse error at test/input/invalid/function_3.js:4,10",
|
||||||
"!function arguments() {",
|
"!function arguments() {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected arguments in strict mode"
|
"ERROR: Unexpected arguments in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -554,7 +576,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/try.js:7,18",
|
"Parse error at test/input/invalid/try.js:7,18",
|
||||||
" try {} catch (eval) {}",
|
" try {} catch (eval) {}",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -568,7 +590,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/var.js:7,8",
|
"Parse error at test/input/invalid/var.js:7,8",
|
||||||
" var eval;",
|
" var eval;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -582,7 +604,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/destructured_var.js:7,10",
|
"Parse error at test/input/invalid/destructured_var.js:7,10",
|
||||||
" var { eval } = 42;",
|
" var { eval } = 42;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected eval in strict mode"
|
"ERROR: Unexpected eval in strict mode",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -596,7 +618,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/else.js:1,7",
|
"Parse error at test/input/invalid/else.js:1,7",
|
||||||
"if (0) else 1;",
|
"if (0) else 1;",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Unexpected token: keyword «else»"
|
"ERROR: Unexpected token: keyword «else»",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -610,7 +632,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/return.js:1,0",
|
"Parse error at test/input/invalid/return.js:1,0",
|
||||||
"return 42;",
|
"return 42;",
|
||||||
"^",
|
"^",
|
||||||
"ERROR: 'return' outside of function"
|
"ERROR: 'return' outside of function",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -624,7 +646,7 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/for-in_1.js:2,5",
|
"Parse error at test/input/invalid/for-in_1.js:2,5",
|
||||||
"for (1, 2, a in b) {",
|
"for (1, 2, a in b) {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Invalid left-hand side in for..in loop"
|
"ERROR: Invalid left-hand side in for..in/of loop",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -638,7 +660,49 @@ describe("bin/uglifyjs", function() {
|
|||||||
"Parse error at test/input/invalid/for-in_2.js:2,5",
|
"Parse error at test/input/invalid/for-in_2.js:2,5",
|
||||||
"for (var a, b in c) {",
|
"for (var a, b in c) {",
|
||||||
" ^",
|
" ^",
|
||||||
"ERROR: Only one variable declaration allowed in for..in loop"
|
"ERROR: Only one variable declaration allowed in for..in/of loop",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-of init)", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/for-of_1.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-of_1.js:2,5",
|
||||||
|
"for (b = 2 of a)",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Invalid left-hand side in for..in/of loop",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-of var)", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/for-of_2.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-of_2.js:2,13",
|
||||||
|
"for (var b = 2 of a)",
|
||||||
|
" ^",
|
||||||
|
"ERROR: No initializers allowed in for..of loop",
|
||||||
|
].join("\n"));
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should throw syntax error (for-await)", function(done) {
|
||||||
|
var command = uglifyjscmd + " test/input/invalid/for-await.js";
|
||||||
|
exec(command, function(err, stdout, stderr) {
|
||||||
|
assert.ok(err);
|
||||||
|
assert.strictEqual(stdout, "");
|
||||||
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
|
"Parse error at test/input/invalid/for-await.js:1,11",
|
||||||
|
"for await (; console.log(42););",
|
||||||
|
" ^",
|
||||||
|
"ERROR: Unexpected token: punc «;»",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
@@ -647,11 +711,13 @@ describe("bin/uglifyjs", function() {
|
|||||||
var command = uglifyjscmd + " test/input/invalid/switch.js";
|
var command = uglifyjscmd + " test/input/invalid/switch.js";
|
||||||
exec(command, function(err, stdout, stderr) {
|
exec(command, function(err, stdout, stderr) {
|
||||||
assert.ok(err);
|
assert.ok(err);
|
||||||
var lines = stderr.split(/\n/);
|
assert.strictEqual(stdout, "");
|
||||||
assert.strictEqual(lines[0], "Parse error at test/input/invalid/switch.js:3,2");
|
assert.strictEqual(stderr.split(/\n/).slice(0, 4).join("\n"), [
|
||||||
assert.strictEqual(lines[1], " default:");
|
"Parse error at test/input/invalid/switch.js:3,2",
|
||||||
assert.strictEqual(lines[2], " ^");
|
" default:",
|
||||||
assert.strictEqual(lines[3], "ERROR: More than one default clause in switch statement");
|
" ^",
|
||||||
|
"ERROR: More than one default clause in switch statement",
|
||||||
|
].join("\n"));
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -259,7 +259,7 @@ describe("comments", function() {
|
|||||||
assert.strictEqual(result.code, code);
|
assert.strictEqual(result.code, code);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should handle comments around parenthesis correctly", function() {
|
it("Should handle comments around parentheses correctly", function() {
|
||||||
var code = [
|
var code = [
|
||||||
"a();",
|
"a();",
|
||||||
"/* foo */",
|
"/* foo */",
|
||||||
@@ -392,12 +392,12 @@ describe("comments", function() {
|
|||||||
describe("comment filters", function() {
|
describe("comment filters", function() {
|
||||||
it("Should be able to filter comments by passing regexp", function() {
|
it("Should be able to filter comments by passing regexp", function() {
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
assert.strictEqual(ast.print_to_string({comments: /^!/}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to filter comments with the 'all' option", function() {
|
it("Should be able to filter comments with the 'all' option", function() {
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
assert.strictEqual(ast.print_to_string({comments: "all"}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to filter commments with the 'some' option", function() {
|
it("Should be able to filter commments with the 'some' option", function() {
|
||||||
@@ -410,13 +410,12 @@ describe("comments", function() {
|
|||||||
var f = function(node, comment) {
|
var f = function(node, comment) {
|
||||||
return comment.value.length === 8;
|
return comment.value.length === 8;
|
||||||
};
|
};
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.");
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "/*TEST 123*/\n//8 chars.\n");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to filter comments by passing regex in string format", function() {
|
it("Should be able to filter comments by passing regex in string format", function() {
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8\n");
|
assert.strictEqual(ast.print_to_string({comments: "/^!/"}), "/*!test1*/\n//!test3\n//!test6\n//!test8");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to get the comment and comment type when using a function", function() {
|
it("Should be able to get the comment and comment type when using a function", function() {
|
||||||
@@ -424,14 +423,12 @@ describe("comments", function() {
|
|||||||
var f = function(node, comment) {
|
var f = function(node, comment) {
|
||||||
return comment.type == "comment1" || comment.type == "comment3";
|
return comment.type == "comment1" || comment.type == "comment3";
|
||||||
};
|
};
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6");
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "//!test3\n//test4\n//test5\n//!test6\n");
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should be able to filter comments by passing a boolean", function() {
|
it("Should be able to filter comments by passing a boolean", function() {
|
||||||
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
var ast = UglifyJS.parse("/*!test1*/\n/*test2*/\n//!test3\n//test4\n<!--test5\n<!--!test6\n-->test7\n-->!test8");
|
||||||
|
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8");
|
||||||
assert.strictEqual(ast.print_to_string({comments: true}), "/*!test1*/\n/*test2*/\n//!test3\n//test4\n//test5\n//!test6\n//test7\n//!test8\n");
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: false}), "");
|
assert.strictEqual(ast.print_to_string({comments: false}), "");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -439,10 +436,8 @@ describe("comments", function() {
|
|||||||
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
|
var ast = UglifyJS.parse("#!Random comment\n//test1\n/*test2*/");
|
||||||
var f = function(node, comment) {
|
var f = function(node, comment) {
|
||||||
assert.strictEqual(comment.type === "comment5", false);
|
assert.strictEqual(comment.type === "comment5", false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
|
assert.strictEqual(ast.print_to_string({comments: f}), "#!Random comment\n//test1\n/*test2*/");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -453,9 +448,8 @@ describe("comments", function() {
|
|||||||
|
|
||||||
it("Should have no problem on multiple calls", function() {
|
it("Should have no problem on multiple calls", function() {
|
||||||
const options = {
|
const options = {
|
||||||
comments: /ok/
|
comments: /ok/,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
assert.strictEqual(UglifyJS.parse("/* ok */ function a(){}").print_to_string(options), "/* ok */function a(){}");
|
||||||
@@ -463,14 +457,14 @@ describe("comments", function() {
|
|||||||
|
|
||||||
it("Should handle shebang and preamble correctly", function() {
|
it("Should handle shebang and preamble correctly", function() {
|
||||||
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
var code = UglifyJS.minify("#!/usr/bin/node\nvar x = 10;", {
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" },
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
assert.strictEqual(code, "#!/usr/bin/node\n/* Build */\nvar x=10;");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should handle preamble without shebang correctly", function() {
|
it("Should handle preamble without shebang correctly", function() {
|
||||||
var code = UglifyJS.minify("var x = 10;", {
|
var code = UglifyJS.minify("var x = 10;", {
|
||||||
output: { preamble: "/* Build */" }
|
output: { preamble: "/* Build */" },
|
||||||
}).code;
|
}).code;
|
||||||
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
assert.strictEqual(code, "/* Build */\nvar x=10;");
|
||||||
});
|
});
|
||||||
|
|||||||
71
test/mocha/exports.js
Normal file
71
test/mocha/exports.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
|
describe("export", function() {
|
||||||
|
it("Should reject invalid `export ...` statement syntax", function() {
|
||||||
|
[
|
||||||
|
"export *;",
|
||||||
|
"export A;",
|
||||||
|
"export 42;",
|
||||||
|
"export var;",
|
||||||
|
"export * as A;",
|
||||||
|
"export A as B;",
|
||||||
|
"export const A;",
|
||||||
|
"export function(){};",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject invalid `export { ... }` statement syntax", function() {
|
||||||
|
[
|
||||||
|
"export { * };",
|
||||||
|
"export { * as A };",
|
||||||
|
"export { 42 as A };",
|
||||||
|
"export { A as B-C };",
|
||||||
|
"export { default as A };",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject invalid `export default ...` statement syntax", function() {
|
||||||
|
[
|
||||||
|
"export default *;",
|
||||||
|
"export default var;",
|
||||||
|
"export default A as B;",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject invalid `export ... from ...` statement syntax", function() {
|
||||||
|
[
|
||||||
|
"export from 'path';",
|
||||||
|
"export * from `path`;",
|
||||||
|
"export A as B from 'path';",
|
||||||
|
"export default from 'path';",
|
||||||
|
"export { A }, B from 'path';",
|
||||||
|
"export * as A, B from 'path';",
|
||||||
|
"export * as A, {} from 'path';",
|
||||||
|
"export { * as A } from 'path';",
|
||||||
|
"export { 42 as A } from 'path';",
|
||||||
|
"export { A-B as C } from 'path';",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
28
test/mocha/imports.js
Normal file
28
test/mocha/imports.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
|
describe("import", function() {
|
||||||
|
it("Should reject invalid `import` statement syntax", function() {
|
||||||
|
[
|
||||||
|
"import *;",
|
||||||
|
"import A;",
|
||||||
|
"import {};",
|
||||||
|
"import `path`;",
|
||||||
|
"import from 'path';",
|
||||||
|
"import * from 'path';",
|
||||||
|
"import A as B from 'path';",
|
||||||
|
"import { A }, B from 'path';",
|
||||||
|
"import * as A, B from 'path';",
|
||||||
|
"import * as A, {} from 'path';",
|
||||||
|
"import { * as A } from 'path';",
|
||||||
|
"import { 42 as A } from 'path';",
|
||||||
|
"import { A-B as C } from 'path';",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -235,8 +235,8 @@ describe("minify", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
var code = result.code;
|
var code = result.code;
|
||||||
assert.strictEqual(code, "var a=/* */function(){foo()}();");
|
assert.strictEqual(code, "var a=function(){foo()}();");
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("JS_Parse_Error", function() {
|
describe("JS_Parse_Error", function() {
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ describe("parentheses", function() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Should compress leading parenthesis with reasonable performance", function() {
|
it("Should compress leading parentheses with reasonable performance", function() {
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
var code = [
|
var code = [
|
||||||
"({}?0:1)&&x();",
|
"({}?0:1)&&x();",
|
||||||
|
|||||||
@@ -183,6 +183,24 @@ describe("test/reduce.js", function() {
|
|||||||
"// }",
|
"// }",
|
||||||
].join("\n"));
|
].join("\n"));
|
||||||
});
|
});
|
||||||
|
it("Should reduce `for (const ... in ...)` without invalid intermediate AST", function() {
|
||||||
|
if (semver.satisfies(process.version, "<4")) return;
|
||||||
|
var code = [
|
||||||
|
"var a = 0;",
|
||||||
|
"",
|
||||||
|
"for (const b in [ 1, 2, 3 ]) {",
|
||||||
|
" a = +a + 1 - .2;",
|
||||||
|
" console.log(a);",
|
||||||
|
"}",
|
||||||
|
].join("\n");
|
||||||
|
var result = reduce_test(code, {
|
||||||
|
compress: {
|
||||||
|
unsafe_math: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.deepEqual(result.warnings, []);
|
||||||
|
});
|
||||||
it("Should reduce infinite loops with reasonable performance", function() {
|
it("Should reduce infinite loops with reasonable performance", function() {
|
||||||
if (semver.satisfies(process.version, "<=0.10")) return;
|
if (semver.satisfies(process.version, "<=0.10")) return;
|
||||||
this.timeout(120000);
|
this.timeout(120000);
|
||||||
@@ -294,6 +312,40 @@ describe("test/reduce.js", function() {
|
|||||||
"// }",
|
"// }",
|
||||||
]).join("\n"));
|
]).join("\n"));
|
||||||
});
|
});
|
||||||
|
it("Should maintain block-scope for const/let", function() {
|
||||||
|
if (semver.satisfies(process.version, "<4")) return;
|
||||||
|
this.timeout(120000);
|
||||||
|
var code = [
|
||||||
|
'"use strict";',
|
||||||
|
"",
|
||||||
|
"L: for (let a = (1 - .8).toString(); ;) {",
|
||||||
|
" if (!console.log(a)) {",
|
||||||
|
" break L;",
|
||||||
|
" }",
|
||||||
|
"}",
|
||||||
|
].join("\n");
|
||||||
|
var result = reduce_test(code, {
|
||||||
|
compress: {
|
||||||
|
unsafe_math: true,
|
||||||
|
},
|
||||||
|
mangle: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"// (beautified)",
|
||||||
|
code,
|
||||||
|
"// output: 0.19999999999999996",
|
||||||
|
"// ",
|
||||||
|
"// minify: 0.2",
|
||||||
|
"// ",
|
||||||
|
"// options: {",
|
||||||
|
'// "compress": {',
|
||||||
|
'// "unsafe_math": true',
|
||||||
|
'// },',
|
||||||
|
'// "mangle": false',
|
||||||
|
"// }",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
it("Should handle corner cases when intermediate case differs only in Error.message", function() {
|
it("Should handle corner cases when intermediate case differs only in Error.message", function() {
|
||||||
if (semver.satisfies(process.version, "<=0.10")) return;
|
if (semver.satisfies(process.version, "<=0.10")) return;
|
||||||
var result = reduce_test(read("test/input/reduce/diff_error.js"), {
|
var result = reduce_test(read("test/input/reduce/diff_error.js"), {
|
||||||
@@ -327,4 +379,39 @@ describe("test/reduce.js", function() {
|
|||||||
if (result.error) throw result.error;
|
if (result.error) throw result.error;
|
||||||
assert.strictEqual(result.code, read("test/input/reduce/destructured_catch.reduced.js"));
|
assert.strictEqual(result.code, read("test/input/reduce/destructured_catch.reduced.js"));
|
||||||
});
|
});
|
||||||
|
it("Should not enumerate `toString` over global context", function() {
|
||||||
|
if (semver.satisfies(process.version, "<8")) return;
|
||||||
|
var code = [
|
||||||
|
"(async function() {});",
|
||||||
|
"for (var k in this);",
|
||||||
|
"console.log(k, 42 + this);",
|
||||||
|
].join("\n");
|
||||||
|
var result = reduce_test(code, {
|
||||||
|
mangle: false,
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.strictEqual(result.code, [
|
||||||
|
"// Can't reproduce test failure",
|
||||||
|
"// minify options: {",
|
||||||
|
'// "mangle": false',
|
||||||
|
"// }",
|
||||||
|
].join("\n"));
|
||||||
|
});
|
||||||
|
it("Should reduce object with method syntax without invalid intermediate AST", function() {
|
||||||
|
if (semver.satisfies(process.version, "<4")) return;
|
||||||
|
var code = [
|
||||||
|
"console.log({",
|
||||||
|
" f() {",
|
||||||
|
" return 1 - .8;",
|
||||||
|
" },",
|
||||||
|
"}.f());",
|
||||||
|
].join("\n");
|
||||||
|
var result = reduce_test(code, {
|
||||||
|
compress: {
|
||||||
|
unsafe_math: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result.error) throw result.error;
|
||||||
|
assert.deepEqual(result.warnings, []);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
82
test/mocha/yields.js
Normal file
82
test/mocha/yields.js
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
var assert = require("assert");
|
||||||
|
var UglifyJS = require("../node");
|
||||||
|
|
||||||
|
describe("generator", function() {
|
||||||
|
it("Should reject `yield` as symbol name within generator functions only", function() {
|
||||||
|
[
|
||||||
|
"function yield() {}",
|
||||||
|
"function(yield) {}",
|
||||||
|
"function() { yield:{} }",
|
||||||
|
"function() { var yield; }",
|
||||||
|
"function() { function yield() {} }",
|
||||||
|
"function() { try {} catch (yield) {} }",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var ast = UglifyJS.parse("(" + code + ")();");
|
||||||
|
assert.strictEqual(ast.TYPE, "Toplevel");
|
||||||
|
assert.strictEqual(ast.body.length, 1);
|
||||||
|
assert.strictEqual(ast.body[0].TYPE, "SimpleStatement");
|
||||||
|
assert.strictEqual(ast.body[0].body.TYPE, "Call");
|
||||||
|
assert.strictEqual(ast.body[0].body.expression.TYPE, "Function");
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse("(" + code.replace(/^function/, "function*") + ")();");
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject `yield` expression outside of generator functions", function() {
|
||||||
|
[
|
||||||
|
"yield 42;",
|
||||||
|
"function f() { yield 42; }",
|
||||||
|
"function* f() { function g() { yield 42; } }",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject `yield` expression directly on computed key of function argument", function() {
|
||||||
|
[
|
||||||
|
"function f({ [yield 42]: a }) {}",
|
||||||
|
"function* f({ [yield 42]: a }) {}",
|
||||||
|
].forEach(function(code) {
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should accept `yield` expression nested within computed key of function argument", function() {
|
||||||
|
[
|
||||||
|
"function f({ [function*() { yield 42; }()]: a }) {}",
|
||||||
|
"function* f({ [function*() { yield 42; }()]: a }) {}",
|
||||||
|
].forEach(function(code) {
|
||||||
|
var ast = UglifyJS.parse(code);
|
||||||
|
assert.strictEqual(ast.TYPE, "Toplevel");
|
||||||
|
assert.strictEqual(ast.body.length, 1);
|
||||||
|
assert.strictEqual(ast.body[0].argnames.length, 1);
|
||||||
|
assert.strictEqual(ast.body[0].argnames[0].TYPE, "DestructuredObject");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("Should reject `yield*` without an expression", function() {
|
||||||
|
[
|
||||||
|
"yield*",
|
||||||
|
"yield*;",
|
||||||
|
"yield*,",
|
||||||
|
"(yield*)",
|
||||||
|
"[ yield* ]",
|
||||||
|
"42[yield*]",
|
||||||
|
"yield* && 42",
|
||||||
|
].forEach(function(code) {
|
||||||
|
code = "function* f() { " + code + " }";
|
||||||
|
assert.throws(function() {
|
||||||
|
UglifyJS.parse(code);
|
||||||
|
}, function(e) {
|
||||||
|
return e instanceof UglifyJS.JS_Parse_Error;
|
||||||
|
}, code);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,23 +5,23 @@ var acorn = require("acorn");
|
|||||||
var ufuzz = require("./ufuzz");
|
var ufuzz = require("./ufuzz");
|
||||||
var UglifyJS = require("..");
|
var UglifyJS = require("..");
|
||||||
|
|
||||||
function try_beautify(code) {
|
function beautify(ast) {
|
||||||
var beautified = UglifyJS.minify(code, {
|
var beautified = UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
beautify: true,
|
beautify: true,
|
||||||
braces: true
|
braces: true,
|
||||||
}
|
},
|
||||||
|
});
|
||||||
|
if (beautified.error) return beautified;
|
||||||
|
return UglifyJS.minify(beautified.code, {
|
||||||
|
compress: false,
|
||||||
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
if (beautified.error) {
|
|
||||||
console.log("// !!! beautify failed !!!");
|
|
||||||
console.log(beautified.error.stack);
|
|
||||||
console.log(code);
|
|
||||||
} else {
|
|
||||||
console.log("// (beautified)");
|
|
||||||
console.log(beautified.code);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate(ast) {
|
function validate(ast) {
|
||||||
@@ -35,16 +35,55 @@ function validate(ast) {
|
|||||||
return UglifyJS.minify(ast, {
|
return UglifyJS.minify(ast, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
|
output: {
|
||||||
|
ast: true,
|
||||||
|
},
|
||||||
|
validate: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function test(original, estree, description) {
|
function patch_import(code) {
|
||||||
var transformed = validate(UglifyJS.AST_Node.from_mozilla_ast(estree));
|
return code.replace(/\bimport\s*\{\s*\}\s*from\s*(['"])/g, "import$1")
|
||||||
if (transformed.error || original !== transformed.code) {
|
.replace(/\b(import\b.*?)\s*,\s*\{\s*\}\s*(from\s*['"])/g, "$1 $2");
|
||||||
|
}
|
||||||
|
|
||||||
|
function equals(input, transformed) {
|
||||||
|
if (input.code === transformed.code) return true;
|
||||||
|
return patch_import(input.code) === patch_import(transformed.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(input, to_moz, description, skip_on_error, beautified) {
|
||||||
|
try {
|
||||||
|
var ast = UglifyJS.AST_Node.from_mozilla_ast(to_moz(input));
|
||||||
|
} catch (e) {
|
||||||
|
if (skip_on_error) return true;
|
||||||
|
console.log("//=============================================================");
|
||||||
|
console.log("//", description, "failed... round", round);
|
||||||
|
console.log(e);
|
||||||
|
console.log("// original code");
|
||||||
|
if (beautified === true) console.log("// (beautified)");
|
||||||
|
console.log(input.code);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var transformed = validate(ast);
|
||||||
|
if (transformed.error || !equals(input, transformed)) {
|
||||||
|
if (!beautified) {
|
||||||
|
beautified = beautify(input.ast);
|
||||||
|
if (!beautified.error) {
|
||||||
|
beautified.raw = beautified.code;
|
||||||
|
if (!test(beautified, to_moz, description, skip_on_error, true)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
console.log("//=============================================================");
|
console.log("//=============================================================");
|
||||||
console.log("// !!!!!! Failed... round", round);
|
console.log("// !!!!!! Failed... round", round);
|
||||||
console.log("// original code");
|
console.log("// original code");
|
||||||
try_beautify(original);
|
if (beautified.error) {
|
||||||
|
console.log("// !!! beautify failed !!!");
|
||||||
|
console.log(beautified.error.stack);
|
||||||
|
} else if (beautified === true) {
|
||||||
|
console.log("// (beautified)");
|
||||||
|
}
|
||||||
|
console.log(input.raw);
|
||||||
console.log();
|
console.log();
|
||||||
console.log();
|
console.log();
|
||||||
console.log("//-------------------------------------------------------------");
|
console.log("//-------------------------------------------------------------");
|
||||||
@@ -52,7 +91,15 @@ function test(original, estree, description) {
|
|||||||
if (transformed.error) {
|
if (transformed.error) {
|
||||||
console.log(transformed.error.stack);
|
console.log(transformed.error.stack);
|
||||||
} else {
|
} else {
|
||||||
try_beautify(transformed.code);
|
beautified = beautify(transformed.ast);
|
||||||
|
if (beautified.error) {
|
||||||
|
console.log("// !!! beautify failed !!!");
|
||||||
|
console.log(beautified.error.stack);
|
||||||
|
console.log(transformed.code);
|
||||||
|
} else {
|
||||||
|
console.log("// (beautified)");
|
||||||
|
console.log(beautified.code);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
console.log("!!!!!! Failed... round", round);
|
console.log("!!!!!! Failed... round", round);
|
||||||
return false;
|
return false;
|
||||||
@@ -67,24 +114,33 @@ for (var round = 1; round <= num_iterations; round++) {
|
|||||||
process.stdout.write(round + " of " + num_iterations + "\r");
|
process.stdout.write(round + " of " + num_iterations + "\r");
|
||||||
var code = ufuzz.createTopLevelCode();
|
var code = ufuzz.createTopLevelCode();
|
||||||
minify_options.forEach(function(options) {
|
minify_options.forEach(function(options) {
|
||||||
var input = options ? UglifyJS.minify(code, JSON.parse(options)).code : code;
|
var ok = true;
|
||||||
var uglified = UglifyJS.minify(input, {
|
var input = UglifyJS.minify(options ? UglifyJS.minify(code, JSON.parse(options)).code : code, {
|
||||||
compress: false,
|
compress: false,
|
||||||
mangle: false,
|
mangle: false,
|
||||||
output: {
|
output: {
|
||||||
ast: true
|
ast: true,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
var ok = test(uglified.code, uglified.ast.to_mozilla_ast(), "AST_Node.to_mozilla_ast()");
|
input.raw = options ? input.code : code;
|
||||||
try {
|
if (input.error) {
|
||||||
ok = test(uglified.code, acorn.parse(input), "acorn.parse()") && ok;
|
ok = false;
|
||||||
} catch (e) {
|
|
||||||
console.log("//=============================================================");
|
console.log("//=============================================================");
|
||||||
console.log("// acorn parser failed... round", round);
|
console.log("// minify() failed... round", round);
|
||||||
console.log(e);
|
console.log(input.error);
|
||||||
console.log("// original code");
|
console.log("// original code");
|
||||||
console.log(input);
|
console.log(code);
|
||||||
}
|
}
|
||||||
|
if (ok) ok = test(input, function(input) {
|
||||||
|
return input.ast.to_mozilla_ast();
|
||||||
|
}, "AST_Node.to_mozilla_ast()");
|
||||||
|
if (ok) ok = test(input, function(input) {
|
||||||
|
return acorn.parse(input.raw, {
|
||||||
|
ecmaVersion: "latest",
|
||||||
|
locations: true,
|
||||||
|
sourceType: "module",
|
||||||
|
});
|
||||||
|
}, "acorn.parse()", !ufuzz.verbose);
|
||||||
if (!ok) process.exit(1);
|
if (!ok) process.exit(1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
104
test/reduce.js
104
test/reduce.js
@@ -131,10 +131,22 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
case "delete":
|
case "delete":
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (parent instanceof U.AST_VarDef && parent.name === node) return;
|
||||||
|
// preserve exports
|
||||||
|
if (parent instanceof U.AST_ExportDeclaration) return;
|
||||||
|
if (parent instanceof U.AST_ExportDefault) return;
|
||||||
|
if (parent instanceof U.AST_ExportForeign) return;
|
||||||
|
if (parent instanceof U.AST_ExportReferences) return;
|
||||||
|
// preserve sole definition of an export statement
|
||||||
|
if (node instanceof U.AST_VarDef
|
||||||
|
&& parent.definitions.length == 1
|
||||||
|
&& tt.parent(1) instanceof U.AST_ExportDeclaration) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// preserve for (var xxx; ...)
|
// preserve for (var xxx; ...)
|
||||||
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node;
|
if (parent instanceof U.AST_For && parent.init === node && node instanceof U.AST_Definitions) return node;
|
||||||
// preserve for (xxx in ...)
|
// preserve for (xxx in/of ...)
|
||||||
if (parent instanceof U.AST_ForIn && parent.init === node) return node;
|
if (parent instanceof U.AST_ForEnumeration && parent.init === node) return node;
|
||||||
|
|
||||||
// node specific permutations with no parent logic
|
// node specific permutations with no parent logic
|
||||||
|
|
||||||
@@ -180,7 +192,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
else if (node instanceof U.AST_Call) {
|
else if (node instanceof U.AST_Call) {
|
||||||
var expr = [
|
var expr = [
|
||||||
node.expression,
|
!(node.expression instanceof U.AST_Super) && node.expression,
|
||||||
node.args[0],
|
node.args[0],
|
||||||
null, // intentional
|
null, // intentional
|
||||||
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
][ ((node.start._permute += step) * steps | 0) % 3 ];
|
||||||
@@ -196,12 +208,10 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
if (node.expression instanceof U.AST_Function) {
|
if (node.expression instanceof U.AST_Function) {
|
||||||
// hoist and return expressions from the IIFE function expression
|
// hoist and return expressions from the IIFE function expression
|
||||||
var body = node.expression.body;
|
|
||||||
node.expression.body = [];
|
|
||||||
var seq = [];
|
var seq = [];
|
||||||
body.forEach(function(node) {
|
node.expression.body.forEach(function(node) {
|
||||||
var expr = expr instanceof U.AST_Exit ? node.value : node.body;
|
var expr = expr instanceof U.AST_Exit ? node.value : node.body;
|
||||||
if (expr instanceof U.AST_Node && !is_statement(expr)) {
|
if (expr instanceof U.AST_Node && !U.is_statement(expr) && can_hoist(expr)) {
|
||||||
// collect expressions from each statements' body
|
// collect expressions from each statements' body
|
||||||
seq.push(expr);
|
seq.push(expr);
|
||||||
}
|
}
|
||||||
@@ -252,7 +262,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return List.skip;
|
return List.skip;
|
||||||
default:
|
default:
|
||||||
if (!has_exit(node)) {
|
if (!has_exit(node) && can_hoist(node)) {
|
||||||
// hoist function declaration body
|
// hoist function declaration body
|
||||||
var body = node.body;
|
var body = node.body;
|
||||||
node.body = [];
|
node.body = [];
|
||||||
@@ -299,17 +309,18 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
node.start._permute += step;
|
node.start._permute += step;
|
||||||
if (expr && (expr !== node.body || !has_loopcontrol(expr, node, parent))) {
|
if (expr && (expr !== node.body || !has_loopcontrol(expr, node, parent))) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return to_statement(expr);
|
return to_statement_init(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_ForIn) {
|
else if (node instanceof U.AST_ForEnumeration) {
|
||||||
var expr;
|
var expr;
|
||||||
switch ((node.start._permute * steps | 0) % 3) {
|
switch ((node.start._permute * steps | 0) % 3) {
|
||||||
case 0:
|
case 0:
|
||||||
if (!(node.init instanceof U.AST_Definitions
|
if (node.init instanceof U.AST_Definitions) {
|
||||||
&& node.init.definitions[0].name instanceof U.AST_Destructured)) {
|
if (node.init instanceof U.AST_Const) break;
|
||||||
expr = node.init;
|
if (node.init.definitions[0].name instanceof U.AST_Destructured) break;
|
||||||
}
|
}
|
||||||
|
expr = node.init;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
expr = node.object;
|
expr = node.object;
|
||||||
@@ -321,7 +332,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
node.start._permute += step;
|
node.start._permute += step;
|
||||||
if (expr) {
|
if (expr) {
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return to_statement(expr);
|
return to_statement_init(expr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_If) {
|
else if (node instanceof U.AST_If) {
|
||||||
@@ -357,7 +368,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
else if (node instanceof U.AST_PropAccess) {
|
else if (node instanceof U.AST_PropAccess) {
|
||||||
var expr = [
|
var expr = [
|
||||||
node.expression,
|
!(node.expression instanceof U.AST_Super) && node.expression,
|
||||||
node.property instanceof U.AST_Node && !(parent instanceof U.AST_Destructured) && node.property,
|
node.property instanceof U.AST_Node && !(parent instanceof U.AST_Destructured) && node.property,
|
||||||
][ node.start._permute++ % 2 ];
|
][ node.start._permute++ % 2 ];
|
||||||
if (expr) {
|
if (expr) {
|
||||||
@@ -369,11 +380,9 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
if (node.body instanceof U.AST_Call && node.body.expression instanceof U.AST_Function) {
|
if (node.body instanceof U.AST_Call && node.body.expression instanceof U.AST_Function) {
|
||||||
// hoist simple statement IIFE function expression body
|
// hoist simple statement IIFE function expression body
|
||||||
node.start._permute++;
|
node.start._permute++;
|
||||||
if (!has_exit(node.body.expression)) {
|
if (!has_exit(node.body.expression) && can_hoist(node.body.expression)) {
|
||||||
var body = node.body.expression.body;
|
|
||||||
node.body.expression.body = [];
|
|
||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return List.splice(body);
|
return List.splice(node.body.expression.body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -467,7 +476,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// replace this node
|
// replace this node
|
||||||
var newNode = is_statement(node) ? new U.AST_EmptyStatement({
|
var newNode = U.is_statement(node) ? new U.AST_EmptyStatement({
|
||||||
start: {},
|
start: {},
|
||||||
}) : U.parse(REPLACEMENTS[node.start._permute % REPLACEMENTS.length | 0], {
|
}) : U.parse(REPLACEMENTS[node.start._permute % REPLACEMENTS.length | 0], {
|
||||||
expression: true,
|
expression: true,
|
||||||
@@ -476,23 +485,27 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options)
|
|||||||
CHANGED = true;
|
CHANGED = true;
|
||||||
return newNode;
|
return newNode;
|
||||||
}, function(node, in_list) {
|
}, function(node, in_list) {
|
||||||
if (node instanceof U.AST_Sequence) {
|
if (node instanceof U.AST_Definitions) {
|
||||||
|
// remove empty var statement
|
||||||
|
if (node.definitions.length == 0) return in_list ? List.skip : new U.AST_EmptyStatement({
|
||||||
|
start: {},
|
||||||
|
});
|
||||||
|
} else if (node instanceof U.AST_ObjectMethod) {
|
||||||
|
if (!/Function$/.test(node.value.TYPE)) return new U.AST_ObjectKeyVal({
|
||||||
|
key: node.key,
|
||||||
|
value: node.value,
|
||||||
|
start: {},
|
||||||
|
});
|
||||||
|
} else if (node instanceof U.AST_Sequence) {
|
||||||
// expand single-element sequence
|
// expand single-element sequence
|
||||||
if (node.expressions.length == 1) return node.expressions[0];
|
if (node.expressions.length == 1) return node.expressions[0];
|
||||||
}
|
} else if (node instanceof U.AST_Try) {
|
||||||
else if (node instanceof U.AST_Try) {
|
|
||||||
// expand orphaned try block
|
// expand orphaned try block
|
||||||
if (!node.bcatch && !node.bfinally) return new U.AST_BlockStatement({
|
if (!node.bcatch && !node.bfinally) return new U.AST_BlockStatement({
|
||||||
body: node.body,
|
body: node.body,
|
||||||
start: {},
|
start: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else if (node instanceof U.AST_Definitions) {
|
|
||||||
// remove empty var statement
|
|
||||||
if (node.definitions.length == 0) return in_list ? List.skip : new U.AST_EmptyStatement({
|
|
||||||
start: {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var diff_error_message;
|
var diff_error_message;
|
||||||
@@ -661,16 +674,22 @@ function has_loopcontrol(body, loop, label) {
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_timed_out(result) {
|
function can_hoist(body) {
|
||||||
return sandbox.is_error(result) && /timed out/.test(result.message);
|
var found = false;
|
||||||
|
body.walk(new U.TreeWalker(function(node) {
|
||||||
|
if (found) return true;
|
||||||
|
if (node instanceof U.AST_NewTarget) return found = true;
|
||||||
|
if (node instanceof U.AST_Scope) {
|
||||||
|
if (node === body) return;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof U.AST_Super) return found = true;
|
||||||
|
}));
|
||||||
|
return !found;
|
||||||
}
|
}
|
||||||
|
|
||||||
function is_statement(node) {
|
function is_timed_out(result) {
|
||||||
return node instanceof U.AST_Statement
|
return sandbox.is_error(result) && /timed out/.test(result.message);
|
||||||
&& !(node instanceof U.AST_Arrow
|
|
||||||
|| node instanceof U.AST_AsyncArrow
|
|
||||||
|| node instanceof U.AST_AsyncFunction
|
|
||||||
|| node instanceof U.AST_Function);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function merge_sequence(array, node) {
|
function merge_sequence(array, node) {
|
||||||
@@ -692,12 +711,19 @@ function to_sequence(expressions) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function to_statement(node) {
|
function to_statement(node) {
|
||||||
return is_statement(node) ? node : new U.AST_SimpleStatement({
|
return U.is_statement(node) ? node : new U.AST_SimpleStatement({
|
||||||
body: node,
|
body: node,
|
||||||
start: {},
|
start: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function to_statement_init(node) {
|
||||||
|
return node instanceof U.AST_Const || node instanceof U.AST_Let ? new U.AST_BlockStatement({
|
||||||
|
body: [ node ],
|
||||||
|
start: {},
|
||||||
|
}) : to_statement(node);;
|
||||||
|
}
|
||||||
|
|
||||||
function wrap_with_console_log(node) {
|
function wrap_with_console_log(node) {
|
||||||
// wrap with console.log()
|
// wrap with console.log()
|
||||||
return new U.AST_Call({
|
return new U.AST_Call({
|
||||||
@@ -720,7 +746,7 @@ function run_code(code, toplevel, result_cache, timeout) {
|
|||||||
if (!value) {
|
if (!value) {
|
||||||
var start = Date.now();
|
var start = Date.now();
|
||||||
result_cache[key] = value = {
|
result_cache[key] = value = {
|
||||||
result: sandbox.run_code(code, toplevel, timeout),
|
result: sandbox.run_code(sandbox.patch_module_statements(code), toplevel, timeout),
|
||||||
elapsed: Date.now() - start,
|
elapsed: Date.now() - start,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
98
test/release/acorn.sh
Executable file
98
test/release/acorn.sh
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/acorn \
|
||||||
|
&& git clone https://github.com/acornjs/acorn.git tmp/acorn \
|
||||||
|
&& cd tmp/acorn \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& git checkout 74b59384320ced82e09da2e8fdbed16810f7379a \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
diff --git a/acorn-loose/rollup.config.js b/acorn-loose/rollup.config.js
|
||||||
|
index d2389b2..c37882b 100644
|
||||||
|
--- a/acorn-loose/rollup.config.js
|
||||||
|
+++ b/acorn-loose/rollup.config.js
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-import buble from "rollup-plugin-buble"
|
||||||
|
-
|
||||||
|
@@ -23 +20,0 @@ export default {
|
||||||
|
- buble({transforms: {dangerousForOf: true}})
|
||||||
|
diff --git a/acorn-walk/rollup.config.js b/acorn-walk/rollup.config.js
|
||||||
|
index 67dd613..8c28807 100644
|
||||||
|
--- a/acorn-walk/rollup.config.js
|
||||||
|
+++ b/acorn-walk/rollup.config.js
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-import buble from "rollup-plugin-buble"
|
||||||
|
-
|
||||||
|
@@ -19 +16,0 @@ export default {
|
||||||
|
- buble({transforms: {dangerousForOf: true}})
|
||||||
|
diff --git a/acorn/rollup.config.bin.js b/acorn/rollup.config.bin.js
|
||||||
|
index 8a082b0..b3eda60 100644
|
||||||
|
--- a/acorn/rollup.config.bin.js
|
||||||
|
+++ b/acorn/rollup.config.bin.js
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-import buble from "rollup-plugin-buble"
|
||||||
|
-
|
||||||
|
@@ -11 +9 @@ export default {
|
||||||
|
- plugins: [buble()]
|
||||||
|
+ plugins: []
|
||||||
|
diff --git a/acorn/rollup.config.js b/acorn/rollup.config.js
|
||||||
|
index c775a0c..cfd4c68 100644
|
||||||
|
--- a/acorn/rollup.config.js
|
||||||
|
+++ b/acorn/rollup.config.js
|
||||||
|
@@ -1,2 +0,0 @@
|
||||||
|
-import buble from "rollup-plugin-buble"
|
||||||
|
-
|
||||||
|
@@ -19 +16,0 @@ export default {
|
||||||
|
- buble({transforms: {dangerousForOf: true}})
|
||||||
|
diff --git a/package.json b/package.json
|
||||||
|
index 382f59e..4612a75 100644
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -24,4 +24 @@
|
||||||
|
- "prepare": "npm run test",
|
||||||
|
- "test": "node test/run.js && node test/lint.js",
|
||||||
|
- "pretest": "npm run build:main && npm run build:loose",
|
||||||
|
- "test:test262": "node bin/run_test262.js",
|
||||||
|
+ "test": "node test/run.js",
|
||||||
|
@@ -32,2 +29 @@
|
||||||
|
- "build:bin": "rollup -c acorn/rollup.config.bin.js",
|
||||||
|
- "lint": "eslint acorn/src/ acorn-walk/src/ acorn-loose/src/"
|
||||||
|
+ "build:bin": "rollup -c acorn/rollup.config.bin.js"
|
||||||
|
@@ -36,6 +31,0 @@
|
||||||
|
- "eslint": "^4.10.0",
|
||||||
|
- "eslint-config-standard": "^10.2.1",
|
||||||
|
- "eslint-plugin-import": "^2.2.0",
|
||||||
|
- "eslint-plugin-node": "^5.2.1",
|
||||||
|
- "eslint-plugin-promise": "^3.5.0",
|
||||||
|
- "eslint-plugin-standard": "^3.0.1",
|
||||||
|
@@ -43,4 +32,0 @@
|
||||||
|
- "rollup-plugin-buble": "^0.19.0",
|
||||||
|
- "test262": "git+https://github.com/tc39/test262.git#a6c819ad0f049f23f1a37af6b89dbb79fe3b9216",
|
||||||
|
- "test262-parser-runner": "^0.5.0",
|
||||||
|
- "test262-stream": "^1.2.1",
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "acorn/src" \
|
||||||
|
&& minify_in_situ "acorn-loose/src" \
|
||||||
|
&& minify_in_situ "acorn-walk/src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm install \
|
||||||
|
&& rm -rf acorn/dist acorn-loose/dist acorn-walk/dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "acorn/dist" \
|
||||||
|
&& minify_in_situ "acorn-loose/dist" \
|
||||||
|
&& minify_in_situ "acorn-walk/dist" \
|
||||||
|
&& npm test
|
||||||
182
test/release/bootstrap.sh
Executable file
182
test/release/bootstrap.sh
Executable file
@@ -0,0 +1,182 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/bootstrap \
|
||||||
|
&& git clone --depth 1 --branch v5.0.0-beta2 https://github.com/twbs/bootstrap.git tmp/bootstrap \
|
||||||
|
&& cd tmp/bootstrap \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& patch -p1 <<EOF
|
||||||
|
--- a/.babelrc.js
|
||||||
|
+++ /dev/null
|
||||||
|
@@ -1,12 +0,0 @@
|
||||||
|
-module.exports = {
|
||||||
|
- presets: [
|
||||||
|
- [
|
||||||
|
- '@babel/preset-env',
|
||||||
|
- {
|
||||||
|
- loose: true,
|
||||||
|
- bugfixes: true,
|
||||||
|
- modules: false
|
||||||
|
- }
|
||||||
|
- ]
|
||||||
|
- ]
|
||||||
|
-};
|
||||||
|
--- a/.gitattributes
|
||||||
|
+++ b/.gitattributes
|
||||||
|
@@ -5,0 +6 @@
|
||||||
|
+*.png binary
|
||||||
|
--- a/build/build-plugins.js
|
||||||
|
+++ b/build/build-plugins.js
|
||||||
|
@@ -14 +13,0 @@ const rollup = require('rollup')
|
||||||
|
-const { babel } = require('@rollup/plugin-babel')
|
||||||
|
@@ -19,6 +17,0 @@ const plugins = [
|
||||||
|
- babel({
|
||||||
|
- // Only transpile our source code
|
||||||
|
- exclude: 'node_modules/**',
|
||||||
|
- // Include the helpers in each file, at most one copy of each
|
||||||
|
- babelHelpers: 'bundled'
|
||||||
|
- })
|
||||||
|
--- a/build/rollup.config.js
|
||||||
|
+++ b/build/rollup.config.js
|
||||||
|
@@ -4 +3,0 @@ const path = require('path')
|
||||||
|
-const { babel } = require('@rollup/plugin-babel')
|
||||||
|
@@ -15,6 +13,0 @@ const plugins = [
|
||||||
|
- babel({
|
||||||
|
- // Only transpile our source code
|
||||||
|
- exclude: 'node_modules/**',
|
||||||
|
- // Include the helpers in the bundle, at most one copy of each
|
||||||
|
- babelHelpers: 'bundled'
|
||||||
|
- })
|
||||||
|
--- a/js/tests/integration/rollup.bundle.js
|
||||||
|
+++ b/js/tests/integration/rollup.bundle.js
|
||||||
|
@@ -3 +2,0 @@
|
||||||
|
-const { babel } = require('@rollup/plugin-babel')
|
||||||
|
@@ -18,4 +16,0 @@ module.exports = {
|
||||||
|
- babel({
|
||||||
|
- exclude: 'node_modules/**',
|
||||||
|
- babelHelpers: 'bundled'
|
||||||
|
- })
|
||||||
|
--- a/js/tests/karma.conf.js
|
||||||
|
+++ b/js/tests/karma.conf.js
|
||||||
|
@@ -7,2 +6,0 @@ const ip = require('ip')
|
||||||
|
-const { babel } = require('@rollup/plugin-babel')
|
||||||
|
-const istanbul = require('rollup-plugin-istanbul')
|
||||||
|
@@ -84,13 +81,0 @@ const conf = {
|
||||||
|
- istanbul({
|
||||||
|
- exclude: [
|
||||||
|
- 'node_modules/**',
|
||||||
|
- 'js/tests/unit/**/*.spec.js',
|
||||||
|
- 'js/tests/helpers/**/*.js'
|
||||||
|
- ]
|
||||||
|
- }),
|
||||||
|
- babel({
|
||||||
|
- // Only transpile our source code
|
||||||
|
- exclude: 'node_modules/**',
|
||||||
|
- // Inline the required helpers in each file
|
||||||
|
- babelHelpers: 'inline'
|
||||||
|
- }),
|
||||||
|
@@ -142 +126,0 @@ if (BROWSERSTACK) {
|
||||||
|
- 'karma-coverage-istanbul-reporter'
|
||||||
|
@@ -144 +127,0 @@ if (BROWSERSTACK) {
|
||||||
|
- reporters.push('coverage-istanbul')
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -23 +23 @@
|
||||||
|
- "start": "npm-run-all --parallel watch docs-serve",
|
||||||
|
+ "start": "npm-run-all --parallel watch",
|
||||||
|
@@ -28,3 +27,0 @@
|
||||||
|
- "css-lint": "npm-run-all --continue-on-error --parallel css-lint-*",
|
||||||
|
- "css-lint-stylelint": "stylelint \"**/*.{css,scss}\" --cache --cache-location .cache/.stylelintcache --rd",
|
||||||
|
- "css-lint-vars": "fusv scss/ site/assets/scss/",
|
||||||
|
@@ -44 +40,0 @@
|
||||||
|
- "js-lint": "eslint --cache --cache-location .cache/.eslintcache --report-unused-disable-directives .",
|
||||||
|
@@ -46,3 +42,3 @@
|
||||||
|
- "js-minify-standalone": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
|
||||||
|
- "js-minify-standalone-esm": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
|
||||||
|
- "js-minify-bundle": "terser --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
|
||||||
|
+ "js-minify-standalone": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.js.map,includeSources,url=bootstrap.min.js.map\" --output dist/js/bootstrap.min.js dist/js/bootstrap.js",
|
||||||
|
+ "js-minify-standalone-esm": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.esm.js.map,includeSources,url=bootstrap.esm.min.js.map\" --output dist/js/bootstrap.esm.min.js dist/js/bootstrap.esm.js",
|
||||||
|
+ "js-minify-bundle": "../../bin/uglifyjs --compress passes=2 --mangle --comments \"/^!/\" --source-map \"content=dist/js/bootstrap.bundle.js.map,includeSources,url=bootstrap.bundle.min.js.map\" --output dist/js/bootstrap.bundle.min.js dist/js/bootstrap.bundle.js",
|
||||||
|
@@ -56,25 +52 @@
|
||||||
|
- "lint": "npm-run-all --parallel js-lint css-lint lockfile-lint",
|
||||||
|
- "docs": "npm-run-all docs-build docs-lint",
|
||||||
|
- "docs-build": "hugo --cleanDestinationDir",
|
||||||
|
- "docs-compile": "npm run docs-build",
|
||||||
|
- "docs-linkinator": "linkinator _gh_pages --recurse --silent --skip \"^(?!http://localhost)\"",
|
||||||
|
- "docs-vnu": "node build/vnu-jar.js",
|
||||||
|
- "docs-lint": "npm-run-all --parallel docs-vnu docs-linkinator",
|
||||||
|
- "docs-serve": "hugo server --port 9001 --disableFastRender",
|
||||||
|
- "docs-serve-only": "npx sirv-cli _gh_pages --port 9001",
|
||||||
|
- "lockfile-lint": "lockfile-lint --allowed-hosts npm --allowed-schemes https: --empty-hostname false --type npm --path package-lock.json",
|
||||||
|
- "update-deps": "ncu -u -x karma-browserstack-launcher,terser && npm update && echo Manually update site/assets/js/vendor",
|
||||||
|
- "release": "npm-run-all dist release-sri docs-build release-zip*",
|
||||||
|
- "release-sri": "node build/generate-sri.js",
|
||||||
|
- "release-version": "node build/change-version.js",
|
||||||
|
- "release-zip": "cross-env-shell \"rm -rf bootstrap-\$npm_package_version-dist && cp -r dist/ bootstrap-\$npm_package_version-dist && zip -r9 bootstrap-\$npm_package_version-dist.zip bootstrap-\$npm_package_version-dist && rm -rf bootstrap-\$npm_package_version-dist\"",
|
||||||
|
- "release-zip-examples": "node build/zip-examples.js",
|
||||||
|
- "dist": "npm-run-all --parallel css js",
|
||||||
|
- "test": "npm-run-all lint dist js-test docs-build docs-lint",
|
||||||
|
- "netlify": "cross-env-shell HUGO_BASEURL=\$DEPLOY_PRIME_URL npm-run-all dist release-sri docs-build",
|
||||||
|
- "watch": "npm-run-all --parallel watch-*",
|
||||||
|
- "watch-css-main": "nodemon --watch scss/ --ext scss --exec \"npm-run-all css-lint css-compile css-prefix\"",
|
||||||
|
- "watch-css-dist": "nodemon --watch dist/css/ --ext css --ignore \"dist/css/*.rtl.*\" --exec \"npm run css-rtl\"",
|
||||||
|
- "watch-css-docs": "nodemon --watch site/assets/scss/ --ext scss --exec \"npm run css-lint\"",
|
||||||
|
- "watch-js-main": "nodemon --watch js/src/ --ext js --exec \"npm-run-all js-lint js-compile\"",
|
||||||
|
- "watch-js-docs": "nodemon --watch site/assets/js/ --ext js --exec \"npm run js-lint\""
|
||||||
|
+ "dist": "npm run css && npm run js"
|
||||||
|
@@ -103,3 +74,0 @@
|
||||||
|
- "@babel/cli": "^7.12.13",
|
||||||
|
- "@babel/core": "^7.12.13",
|
||||||
|
- "@babel/preset-env": "^7.12.13",
|
||||||
|
@@ -107 +75,0 @@
|
||||||
|
- "@rollup/plugin-babel": "^5.2.3",
|
||||||
|
@@ -115,4 +82,0 @@
|
||||||
|
- "eslint": "^7.19.0",
|
||||||
|
- "eslint-config-xo": "^0.34.0",
|
||||||
|
- "eslint-plugin-import": "^2.22.1",
|
||||||
|
- "eslint-plugin-unicorn": "^27.0.0",
|
||||||
|
@@ -122 +85,0 @@
|
||||||
|
- "hugo-bin": "^0.68.0",
|
||||||
|
@@ -128 +90,0 @@
|
||||||
|
- "karma-coverage-istanbul-reporter": "^3.0.3",
|
||||||
|
@@ -134,2 +95,0 @@
|
||||||
|
- "linkinator": "^2.13.4",
|
||||||
|
- "lockfile-lint": "^4.3.7",
|
||||||
|
@@ -141 +100,0 @@
|
||||||
|
- "rollup-plugin-istanbul": "^3.0.0",
|
||||||
|
@@ -144,5 +103 @@
|
||||||
|
- "shelljs": "^0.8.4",
|
||||||
|
- "stylelint": "^13.9.0",
|
||||||
|
- "stylelint-config-twbs-bootstrap": "^2.1.0",
|
||||||
|
- "terser": "5.1.0",
|
||||||
|
- "vnu-jar": "21.2.5"
|
||||||
|
+ "shelljs": "^0.8.4"
|
||||||
|
@@ -155,3 +109,0 @@
|
||||||
|
- "hugo-bin": {
|
||||||
|
- "buildTags": "extended"
|
||||||
|
- },
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& minify_in_situ "node_modules/@popperjs/core" \
|
||||||
|
&& rm -rf dist/js/* \
|
||||||
|
&& minify_in_situ "build" \
|
||||||
|
&& minify_in_situ "js" \
|
||||||
|
&& minify_in_situ "site" \
|
||||||
|
&& npm run dist \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& npm run js-test
|
||||||
45
test/release/buble.sh
Executable file
45
test/release/buble.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/buble \
|
||||||
|
&& git clone https://github.com/bublejs/buble.git tmp/buble \
|
||||||
|
&& cd tmp/buble \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& git checkout dcc5ab02c9af6ddaad94e587c4911677340ec100 \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -29 +28,0 @@
|
||||||
|
- "prepublish": "npm test",
|
||||||
|
@@ -67,3 +66 @@
|
||||||
|
- "source-map-support": "^0.5.16",
|
||||||
|
- "test262": "git+https://github.com/tc39/test262.git#4f1155c566a222238fd86f179c6635ecb4c289bb",
|
||||||
|
- "test262-stream": "^1.3.0"
|
||||||
|
+ "source-map-support": "^0.5.16"
|
||||||
|
--- a/src/program/BlockStatement.js
|
||||||
|
+++ b/src/program/BlockStatement.js
|
||||||
|
@@ -309 +309 @@ export default class BlockStatement extends Node {
|
||||||
|
- let cont = false; // TODO implement proper continue...
|
||||||
|
+ let cont = !declarations; // TODO implement proper continue...
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& rm -rf dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& node_modules/.bin/mocha
|
||||||
45
test/release/butternut.sh
Executable file
45
test/release/butternut.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/butternut \
|
||||||
|
&& git clone https://github.com/Rich-Harris/butternut.git tmp/butternut \
|
||||||
|
&& cd tmp/butternut \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -25 +24,0 @@
|
||||||
|
- "prepublish": "npm run test:min",
|
||||||
|
--- a/rollup.config.js
|
||||||
|
+++ b/rollup.config.js
|
||||||
|
@@ -1 +0,0 @@
|
||||||
|
-import buble from 'rollup-plugin-buble';
|
||||||
|
@@ -28,6 +26,0 @@ const config = {
|
||||||
|
- buble({
|
||||||
|
- include: ['src/**', 'node_modules/acorn/**'],
|
||||||
|
- transforms: {
|
||||||
|
- dangerousForOf: true
|
||||||
|
- }
|
||||||
|
- }),
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm install \
|
||||||
|
&& rm -rf dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& node_modules/.bin/mocha test/test.js
|
||||||
54
test/release/install.sh
Executable file
54
test/release/install.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
echo "::group::GitHub Environment Variables"
|
||||||
|
echo "CI: $CI"
|
||||||
|
echo "GITHUB_WORKFLOW: $GITHUB_WORKFLOW"
|
||||||
|
echo "GITHUB_RUN_ID: $GITHUB_RUN_ID"
|
||||||
|
echo "GITHUB_RUN_NUMBER: $GITHUB_RUN_NUMBER"
|
||||||
|
echo "GITHUB_ACTION: $GITHUB_ACTION"
|
||||||
|
echo "GITHUB_ACTIONS: $GITHUB_ACTIONS"
|
||||||
|
echo "GITHUB_ACTOR: $GITHUB_ACTOR"
|
||||||
|
echo "GITHUB_REPOSITORY: $GITHUB_REPOSITORY"
|
||||||
|
echo "GITHUB_EVENT_NAME: $GITHUB_EVENT_NAME"
|
||||||
|
echo "GITHUB_EVENT_PATH: $GITHUB_EVENT_PATH"
|
||||||
|
echo "GITHUB_WORKSPACE: $GITHUB_WORKSPACE"
|
||||||
|
echo "GITHUB_SHA: $GITHUB_SHA"
|
||||||
|
echo "GITHUB_REF: $GITHUB_REF"
|
||||||
|
echo "GITHUB_HEAD_REF: $GITHUB_HEAD_REF"
|
||||||
|
echo "GITHUB_BASE_REF: $GITHUB_BASE_REF"
|
||||||
|
echo "GITHUB_SERVER_URL: $GITHUB_SERVER_URL"
|
||||||
|
echo "GITHUB_API_URL: $GITHUB_API_URL"
|
||||||
|
echo "GITHUB_GRAPHQL_URL: $GITHUB_GRAPHQL_URL"
|
||||||
|
echo "::endgroup::"
|
||||||
|
|
||||||
|
if command -v timeout &> /dev/null; then NATIVE=1; fi
|
||||||
|
timeout() {
|
||||||
|
T=$1
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
expect <<EOF
|
||||||
|
set timeout $T
|
||||||
|
spawn -noecho sh -c "$@"
|
||||||
|
expect timeout { exit 124 } eof
|
||||||
|
catch wait ret
|
||||||
|
exit [lindex \$ret 3]
|
||||||
|
EOF
|
||||||
|
return $?
|
||||||
|
}
|
||||||
|
if [ $NATIVE ]; then unset -f timeout; fi
|
||||||
|
|
||||||
|
git clone --branch v1.6.0 --depth 1 https://github.com/jasongin/nvs.git ~/.nvs
|
||||||
|
while ! timeout 60 bash -c ". ~/.nvs/nvs.sh add $NODE && nvs use $NODE"; do
|
||||||
|
cd ~/.nvs
|
||||||
|
while !(git clean -xdf); do echo "'git clean' failed - retrying..."; done
|
||||||
|
cd -
|
||||||
|
done
|
||||||
|
. ~/.nvs/nvs.sh --version
|
||||||
|
nvs use $NODE
|
||||||
|
node --version
|
||||||
|
npm config set audit false
|
||||||
|
npm config set optional false
|
||||||
|
npm config set save false
|
||||||
|
npm config set strict-ssl false
|
||||||
|
npm config set update-notifier false
|
||||||
|
npm --version
|
||||||
|
while !(npm install); do echo "'npm install' failed - retrying..."; done
|
||||||
198
test/release/mathjs.sh
Executable file
198
test/release/mathjs.sh
Executable file
@@ -0,0 +1,198 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS="--annotations $@"
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
for i in `find $DIRS -type f -name '*.mjs'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/mathjs \
|
||||||
|
&& git clone --depth 1 --branch v9.2.0 https://github.com/josdejong/mathjs.git tmp/mathjs \
|
||||||
|
&& cd tmp/mathjs \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/gulpfile.cjs
|
||||||
|
+++ b/gulpfile.cjs
|
||||||
|
@@ -74 +74 @@ const webpackConfig = {
|
||||||
|
- mode: 'production',
|
||||||
|
+ mode: 'development',
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -132,2 +131,0 @@
|
||||||
|
- "prepublishOnly": "npm run test:all && npm run lint",
|
||||||
|
- "prepare": "npm run build",
|
||||||
|
--- a/src/utils/string.js
|
||||||
|
+++ b/src/utils/string.js
|
||||||
|
@@ -15,0 +16,7 @@ export function endsWith (text, search) {
|
||||||
|
+export function HACK (value) {
|
||||||
|
+ if (typeof value == "object") {
|
||||||
|
+ (value = Object.create(value)).valueOf = function() { return this }
|
||||||
|
+ }
|
||||||
|
+ return value
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
@@ -68 +75 @@ export function format (value, options) {
|
||||||
|
- return value.toString()
|
||||||
|
+ return HACK(value).toString()
|
||||||
|
--- a/test/node-tests/cli/cli.test.js
|
||||||
|
+++ b/test/node-tests/cli/cli.test.js
|
||||||
|
@@ -36 +35,0 @@ describe('command line interface', function () {
|
||||||
|
- const path2 = path.join(__dirname, 'script2')
|
||||||
|
@@ -38,2 +37,2 @@ describe('command line interface', function () {
|
||||||
|
- run('"' + path1 + '" "' + path2 + '"', function (e, result) {
|
||||||
|
- assert.strictEqual(result, '2\n8\n')
|
||||||
|
+ run('"' + path1 + '"', function (e, result) {
|
||||||
|
+ assert.strictEqual(result, '2\n')
|
||||||
|
--- a/test/unit-tests/expression/node/Node.test.js
|
||||||
|
+++ b/test/unit-tests/expression/node/Node.test.js
|
||||||
|
@@ -157 +157 @@ describe('Node', function () {
|
||||||
|
- assert.throws(function () {
|
||||||
|
+ if (0) assert.throws(function () {
|
||||||
|
--- a/test/unit-tests/expression/parse.test.js
|
||||||
|
+++ b/test/unit-tests/expression/parse.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../src/utils/string.js'
|
||||||
|
@@ -333 +334 @@ describe('parse', function () {
|
||||||
|
- assert.strictEqual(fmath.parse('1/3').compile().evaluate().toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(fmath.parse('1/3').compile().evaluate()).toString(), '0.(3)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/abs.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/abs.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -35,3 +36,3 @@ describe('abs', function () {
|
||||||
|
- assert.strictEqual(abs(a).toString(), '0.(3)')
|
||||||
|
- assert.strictEqual(a.toString(), '-0.(3)')
|
||||||
|
- assert.strictEqual(abs(fraction('1/3')).toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(abs(a)).toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '-0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(abs(fraction('1/3'))).toString(), '0.(3)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/addScalar.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/addScalar.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -71 +72 @@ describe('addScalar', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||||
|
@@ -73 +74 @@ describe('addScalar', function () {
|
||||||
|
- assert.strictEqual(add(math.fraction(1), math.fraction(1, 3)).toString(), '1.(3)')
|
||||||
|
+ assert.strictEqual(HACK(add(math.fraction(1), math.fraction(1, 3))).toString(), '1.(3)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/ceil.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/ceil.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -88 +89 @@ describe('ceil', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
@@ -105 +106 @@ describe('ceil', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
@@ -107 +108 @@ describe('ceil', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/fix.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/fix.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -107 +108 @@ describe('fix', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
@@ -124 +125 @@ describe('fix', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
@@ -127 +128 @@ describe('fix', function () {
|
||||||
|
- assert.strictEqual(b.toString(), '-0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(b).toString(), '-0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/floor.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/floor.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -96 +97 @@ describe('floor', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/gcd.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/gcd.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -62 +63 @@ describe('gcd', function () {
|
||||||
|
- assert.strictEqual(gcd(a, math.fraction(3, 7)).toString(), '0.017(857142)')
|
||||||
|
+ assert.strictEqual(HACK(gcd(a, math.fraction(3, 7))).toString(), '0.017(857142)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/multiply.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/multiply.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -129 +130 @@ describe('multiply', function () {
|
||||||
|
- assert.strictEqual(multiply(math.fraction(2), math.fraction(1, 3)).toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(multiply(math.fraction(2), math.fraction(1, 3))).toString(), '0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/round.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/round.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -82 +83 @@ describe('round', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/subtract.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/subtract.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -76,2 +77,2 @@ describe('subtract', function () {
|
||||||
|
- assert.strictEqual(subtract(a, math.fraction(1, 6)).toString(), '0.1(6)')
|
||||||
|
- assert.strictEqual(a.toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(subtract(a, math.fraction(1, 6))).toString(), '0.1(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||||
|
@@ -80 +81 @@ describe('subtract', function () {
|
||||||
|
- assert.strictEqual(subtract(math.fraction(1), math.fraction(1, 3)).toString(), '0.(6)')
|
||||||
|
+ assert.strictEqual(HACK(subtract(math.fraction(1), math.fraction(1, 3))).toString(), '0.(6)')
|
||||||
|
--- a/test/unit-tests/function/arithmetic/unaryMinus.test.js
|
||||||
|
+++ b/test/unit-tests/function/arithmetic/unaryMinus.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -31 +32 @@ describe('unaryMinus', function () {
|
||||||
|
- assert.deepStrictEqual(math.unaryMinus(bignumber(0)).toString(), '0')
|
||||||
|
+ assert.deepStrictEqual(HACK(math.unaryMinus(bignumber(0))).toString(), '0')
|
||||||
|
--- a/test/unit-tests/function/relational/compare.test.js
|
||||||
|
+++ b/test/unit-tests/function/relational/compare.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -76,2 +77,2 @@ describe('compare', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(3)')
|
||||||
|
- assert.strictEqual(b.toString(), '0.1(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(b).toString(), '0.1(6)')
|
||||||
|
--- a/test/unit-tests/function/relational/compareNatural.test.js
|
||||||
|
+++ b/test/unit-tests/function/relational/compareNatural.test.js
|
||||||
|
@@ -0,0 +1 @@
|
||||||
|
+import { HACK } from '../../../../src/utils/string.js'
|
||||||
|
@@ -57,2 +58,2 @@ describe('compareNatural', function () {
|
||||||
|
- assert.strictEqual(a.toString(), '0.(3)')
|
||||||
|
- assert.strictEqual(b.toString(), '0.1(6)')
|
||||||
|
+ assert.strictEqual(HACK(a).toString(), '0.(3)')
|
||||||
|
+ assert.strictEqual(HACK(b).toString(), '0.1(6)')
|
||||||
|
--- a/test/unit-tests/type/matrix/Matrix.test.js
|
||||||
|
+++ b/test/unit-tests/type/matrix/Matrix.test.js
|
||||||
|
@@ -44 +44 @@ describe('matrix', function () {
|
||||||
|
- assert.throws(function () { m.toString() }, /Cannot invoke toString on a Matrix interface/)
|
||||||
|
+ if (0) assert.throws(function () { m.toString() }, /Cannot invoke toString on a Matrix interface/)
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "bin" \
|
||||||
|
&& minify_in_situ "src" \
|
||||||
|
&& minify_in_situ "test" \
|
||||||
|
&& minify_in_situ "tools" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& rm -rf lib \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "lib" \
|
||||||
|
&& npm run test:all
|
||||||
84
test/release/rollup-es.sh
Executable file
84
test/release/rollup-es.sh
Executable file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/rollup \
|
||||||
|
&& git clone https://github.com/rollup/rollup.git tmp/rollup \
|
||||||
|
&& cd tmp/rollup \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& git checkout 3d80c06f895eab41e648ee99786fa68c72458b80 \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -23 +22,0 @@
|
||||||
|
- "prepublishOnly": "npm run lint && npm run test:only && npm run test:leak",
|
||||||
|
--- a/rollup.config.js
|
||||||
|
+++ b/rollup.config.js
|
||||||
|
@@ -1,5 +1,4 @@
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
-import buble from 'rollup-plugin-buble';
|
||||||
|
import resolve from 'rollup-plugin-node-resolve';
|
||||||
|
import commonjs from 'rollup-plugin-commonjs';
|
||||||
|
import json from 'rollup-plugin-json';
|
||||||
|
@@ -25,12 +24,6 @@ export default [
|
||||||
|
input: 'src/node-entry.js',
|
||||||
|
plugins: [
|
||||||
|
json(),
|
||||||
|
- buble({
|
||||||
|
- include: ['src/**', 'node_modules/acorn/**'],
|
||||||
|
- target: {
|
||||||
|
- node: '4'
|
||||||
|
- }
|
||||||
|
- }),
|
||||||
|
resolve(),
|
||||||
|
commonjs()
|
||||||
|
],
|
||||||
|
@@ -48,12 +41,6 @@ export default [
|
||||||
|
input: 'src/browser-entry.js',
|
||||||
|
plugins: [
|
||||||
|
json(),
|
||||||
|
- buble({
|
||||||
|
- include: ['src/**', 'node_modules/acorn/**'],
|
||||||
|
- target: {
|
||||||
|
- node: '4'
|
||||||
|
- }
|
||||||
|
- }),
|
||||||
|
resolve(),
|
||||||
|
commonjs(),
|
||||||
|
{
|
||||||
|
@@ -80,7 +67,6 @@ export default [
|
||||||
|
plugins: [
|
||||||
|
string({ include: '**/*.md' }),
|
||||||
|
json(),
|
||||||
|
- buble({ target: { node: 4 } }),
|
||||||
|
commonjs({
|
||||||
|
include: 'node_modules/**'
|
||||||
|
}),
|
||||||
|
--- a/test/mocha.opts
|
||||||
|
+++ b/test/mocha.opts
|
||||||
|
@@ -1,2 +1 @@
|
||||||
|
---require buble/register
|
||||||
|
test/test.js
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "bin" \
|
||||||
|
&& minify_in_situ "browser" \
|
||||||
|
&& minify_in_situ "src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& rm -rf dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& node_modules/.bin/mocha
|
||||||
56
test/release/rollup-ts.sh
Executable file
56
test/release/rollup-ts.sh
Executable file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> esbuild' $DIRS
|
||||||
|
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
|
||||||
|
do
|
||||||
|
echo "$i"
|
||||||
|
CODE=`cat "$i"`
|
||||||
|
node_modules/.bin/esbuild --loader=ts --target=esnext > "$i" <<EOF
|
||||||
|
$CODE
|
||||||
|
EOF
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/rollup \
|
||||||
|
&& git clone --depth 1 --branch v2.39.1 https://github.com/rollup/rollup.git tmp/rollup \
|
||||||
|
&& cd tmp/rollup \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -27,4 +26,0 @@
|
||||||
|
- "postinstall": "husky install",
|
||||||
|
- "postpublish": "pinst --enable",
|
||||||
|
- "prepare": "npm run build",
|
||||||
|
- "prepublishOnly": "pinst --disable && npm ci && npm run lint:nofix && npm run security && npm run build:bootstrap && npm run test:all",
|
||||||
|
--- a/test/cli/index.js
|
||||||
|
+++ b/test/cli/index.js
|
||||||
|
@@ -13,0 +14,3 @@ sander.rimrafSync(__dirname, 'node_modules');
|
||||||
|
+sander.rimrafSync(__dirname, 'samples', 'watch', 'bundle-error');
|
||||||
|
+sander.rimrafSync(__dirname, 'samples', 'watch', 'watch-config-error');
|
||||||
|
+sander.rimrafSync(__dirname, 'samples', 'watch', 'watch-config-initial-error');
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
npm install esbuild-wasm@0.8.56 \
|
||||||
|
&& minify_in_situ "cli" \
|
||||||
|
&& minify_in_situ "src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& rm -rf dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& node_modules/.bin/mocha test/test.js \
|
||||||
|
&& node_modules/.bin/mocha test/browser/index.js
|
||||||
94
test/release/sucrase.sh
Executable file
94
test/release/sucrase.sh
Executable file
@@ -0,0 +1,94 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js=$PWD/bin/uglifyjs
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> esbuild' $DIRS
|
||||||
|
for i in `find $DIRS -type f -name '*.ts' | grep -v '\.d\.ts'`
|
||||||
|
do
|
||||||
|
echo "$i"
|
||||||
|
CODE=`cat "$i"`
|
||||||
|
node_modules/.bin/esbuild --loader=ts --target=esnext > "$i" <<EOF
|
||||||
|
$CODE
|
||||||
|
EOF
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
for i in `find $DIRS -type f -name '*.mjs'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/sucrase \
|
||||||
|
&& git clone https://github.com/alangpierce/sucrase.git tmp/sucrase \
|
||||||
|
&& cd tmp/sucrase \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& git checkout 38b66f3009feb76750a799deea211adcc83574f1 \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -25 +24,0 @@
|
||||||
|
- "prepublishOnly": "yarn clean && yarn build",
|
||||||
|
@@ -65 +63,0 @@
|
||||||
|
- "test262-harness": "^6.5.0",
|
||||||
|
--- a/script/build.ts
|
||||||
|
+++ b/script/build.ts
|
||||||
|
@@ -16 +15,0 @@ async function main(): Promise<void> {
|
||||||
|
- () => buildBenchmark(),
|
||||||
|
@@ -18,5 +16,0 @@ async function main(): Promise<void> {
|
||||||
|
- () => buildIntegration("./integrations/gulp-plugin"),
|
||||||
|
- () => buildIntegration("./integrations/jest-plugin"),
|
||||||
|
- () => buildIntegration("./integrations/webpack-loader"),
|
||||||
|
- () => buildIntegration("./integrations/webpack-object-rest-spread-plugin"),
|
||||||
|
- () => buildWebsite(),
|
||||||
|
@@ -66,3 +59,0 @@ async function buildSucrase(): Promise<void> {
|
||||||
|
- // Also add in .d.ts files from tsc, which only need to be compiled once.
|
||||||
|
- await run(\`\${TSC} --project ./src --outDir ./dist-types\`);
|
||||||
|
- await mergeDirectoryContents("./dist-types/src", "./dist");
|
||||||
|
@@ -70 +61 @@ async function buildSucrase(): Promise<void> {
|
||||||
|
- await run("yarn link");
|
||||||
|
+ await run("npm link");
|
||||||
|
--- a/src/identifyShadowedGlobals.ts
|
||||||
|
+++ b/src/identifyShadowedGlobals.ts
|
||||||
|
@@ -23,0 +24 @@ export default function identifyShadowedGlobals(
|
||||||
|
+export { identifyShadowedGlobals as HACK };
|
||||||
|
--- a/src/parser/tokenizer/state.ts
|
||||||
|
+++ b/src/parser/tokenizer/state.ts
|
||||||
|
@@ -100,0 +101 @@ export default class State {
|
||||||
|
+export { State as HACK };
|
||||||
|
--- a/src/transformers/JSXTransformer.ts
|
||||||
|
+++ b/src/transformers/JSXTransformer.ts
|
||||||
|
@@ -253,0 +254 @@ export default class JSXTransformer extends Transformer {
|
||||||
|
+export { JSXTransformer as HACK };
|
||||||
|
--- a/src/util/getClassInfo.ts
|
||||||
|
+++ b/src/util/getClassInfo.ts
|
||||||
|
@@ -164,0 +165 @@ export default function getClassInfo(
|
||||||
|
+export { getClassInfo as HACK };
|
||||||
|
--- a/src/util/getDeclarationInfo.ts
|
||||||
|
+++ b/src/util/getDeclarationInfo.ts
|
||||||
|
@@ -40,0 +41 @@ export default function getDeclarationInfo(tokens: TokenProcessor): DeclarationI
|
||||||
|
+export { getDeclarationInfo as HACK };
|
||||||
|
--- a/src/util/getJSXPragmaInfo.ts
|
||||||
|
+++ b/src/util/getJSXPragmaInfo.ts
|
||||||
|
@@ -14,0 +15 @@ export default function getJSXPragmaInfo(options: Options): JSXPragmaInfo {
|
||||||
|
+export { getJSXPragmaInfo as HACK };
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
npm install esbuild-wasm@0.8.56 \
|
||||||
|
&& minify_in_situ "src" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm install \
|
||||||
|
&& npm run clean \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& minify_in_situ "dist-self-build" \
|
||||||
|
&& npm run test-only
|
||||||
58
test/release/web-tooling-benchmark.sh
Executable file
58
test/release/web-tooling-benchmark.sh
Executable file
@@ -0,0 +1,58 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
alias uglify-js="node --max-old-space-size=8192 $PWD/bin/uglifyjs"
|
||||||
|
UGLIFY_OPTIONS=$@
|
||||||
|
|
||||||
|
minify_in_situ() {
|
||||||
|
ARGS="$UGLIFY_OPTIONS --validate --in-situ"
|
||||||
|
DIRS="$1"
|
||||||
|
echo '> uglify-js' $DIRS $UGLIFY_OPTIONS
|
||||||
|
for i in `find $DIRS -type f -name '*.js'`
|
||||||
|
do
|
||||||
|
ARGS="$ARGS $i"
|
||||||
|
done
|
||||||
|
uglify-js $ARGS
|
||||||
|
}
|
||||||
|
|
||||||
|
rm -rf tmp/web-tooling-benchmark \
|
||||||
|
&& git clone --depth 1 --branch v0.5.3 https://github.com/v8/web-tooling-benchmark.git tmp/web-tooling-benchmark \
|
||||||
|
&& cd tmp/web-tooling-benchmark \
|
||||||
|
&& rm -rf .git/hooks \
|
||||||
|
&& patch -l -p1 <<EOF
|
||||||
|
--- a/package.json
|
||||||
|
+++ b/package.json
|
||||||
|
@@ -12 +11,0 @@
|
||||||
|
- "postinstall": "npm run build:terser-bundled && npm run build:uglify-js-bundled && npm run build",
|
||||||
|
--- a/src/bootstrap.js
|
||||||
|
+++ b/src/bootstrap.js
|
||||||
|
@@ -6 +6 @@ const gmean = require("compute-gmean");
|
||||||
|
-const package = require("../package.json");
|
||||||
|
+const package_json = require("../package.json");
|
||||||
|
@@ -65 +65 @@ function initialize() {
|
||||||
|
- document.title = \`Web Tooling Benchmark v\${package.version}\`;
|
||||||
|
+ document.title = \`Web Tooling Benchmark v\${package_json.version}\`;
|
||||||
|
@@ -68 +68 @@ function initialize() {
|
||||||
|
- versionDiv.innerHTML = \`v\${package.version}\`;
|
||||||
|
+ versionDiv.innerHTML = \`v\${package_json.version}\`;
|
||||||
|
--- a/src/cli-flags-helper.js
|
||||||
|
+++ b/src/cli-flags-helper.js
|
||||||
|
@@ -7 +6,0 @@ const targetList = new Set([
|
||||||
|
- "chai",
|
||||||
|
--- a/src/cli.js
|
||||||
|
+++ b/src/cli.js
|
||||||
|
@@ -18,0 +19 @@ suite.on("error", event => {
|
||||||
|
+ global.process.exitCode = 42;
|
||||||
|
EOF
|
||||||
|
ERR=$?; if [ "$ERR" != "0" ]; then echo "Error: $ERR"; exit $ERR; fi
|
||||||
|
minify_in_situ "src" \
|
||||||
|
&& minify_in_situ "third_party" \
|
||||||
|
&& rm -rf node_modules \
|
||||||
|
&& npm ci \
|
||||||
|
&& rm -rf build/* \
|
||||||
|
&& npm run build:terser-bundled \
|
||||||
|
&& npm run build:uglify-js-bundled \
|
||||||
|
&& minify_in_situ "build" \
|
||||||
|
&& rm -rf dist \
|
||||||
|
&& npm run build \
|
||||||
|
&& minify_in_situ "dist" \
|
||||||
|
&& node dist/cli.js
|
||||||
@@ -25,7 +25,13 @@ exports.run_code = semver.satisfies(process.version, "0.8") ? function(code, top
|
|||||||
} while (prev !== stdout);
|
} while (prev !== stdout);
|
||||||
return stdout;
|
return stdout;
|
||||||
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
|
} : semver.satisfies(process.version, "<0.12") ? run_code_vm : function(code, toplevel, timeout) {
|
||||||
if (/\basync([ \t]+[^\s()[\]{},.&|!~=*%/+-]+|[ \t]*\([\s\S]*?\))[ \t]*=>|\b(async[ \t]+function|setInterval|setTimeout)\b/.test(code)) {
|
if ([
|
||||||
|
/\basync[ \t]*\([\s\S]*?\)[ \t]*=>/,
|
||||||
|
/\b(async[ \t]+function|setImmediate|setInterval|setTimeout)\b/,
|
||||||
|
/\basync([ \t]+|[ \t]*\*[ \t]*)[^\s()[\]{},.&|!~=*%/+-]+(\s*\(|[ \t]*=>)/,
|
||||||
|
].some(function(pattern) {
|
||||||
|
return pattern.test(code);
|
||||||
|
})) {
|
||||||
return run_code_exec(code, toplevel, timeout);
|
return run_code_exec(code, toplevel, timeout);
|
||||||
} else {
|
} else {
|
||||||
return run_code_vm(code, toplevel, timeout);
|
return run_code_vm(code, toplevel, timeout);
|
||||||
@@ -43,6 +49,30 @@ exports.same_stdout = semver.satisfies(process.version, "0.12") ? function(expec
|
|||||||
} : function(expected, actual) {
|
} : function(expected, actual) {
|
||||||
return typeof expected == typeof actual && strip_func_ids(expected) == strip_func_ids(actual);
|
return typeof expected == typeof actual && strip_func_ids(expected) == strip_func_ids(actual);
|
||||||
};
|
};
|
||||||
|
exports.patch_module_statements = function(code) {
|
||||||
|
var count = 0, imports = [];
|
||||||
|
code = code.replace(/\bexport(?:\s*\{[^}]*}\s*?(?:$|\n|;)|\s+default\b(?:\s*(\(|\{|class\s*\{|class\s+(?=extends\b)|(?:async\s+)?function\s*(?:\*\s*)?\())?|\b)/g, function(match, header) {
|
||||||
|
if (!header) return "";
|
||||||
|
if (header.length == 1) return "0, " + header;
|
||||||
|
return header.slice(0, -1) + " _" + ++count + header.slice(-1);
|
||||||
|
}).replace(/\bimport\.meta\b/g, function() {
|
||||||
|
return '({ url: "https://example.com/path/index.html" })';
|
||||||
|
}).replace(/\bimport\b(?:\s*([^('"]+)\bfrom\b)?\s*(['"]).*?\2(?:$|\n|;)/g, function(match, symbols) {
|
||||||
|
if (symbols) {
|
||||||
|
if (!/^[{*]/.test(symbols)) symbols = "default:" + symbols;
|
||||||
|
symbols = symbols.replace(/[{}]/g, "").trim().replace(/\s*,\s*/g, ",");
|
||||||
|
symbols = symbols.replace(/\*/, '"*"').replace(/\bas\s+(?!$|,|as\s)/g, ":");
|
||||||
|
imports.push([
|
||||||
|
"const {",
|
||||||
|
symbols,
|
||||||
|
"} = new Proxy(Object.create(null), { get(_, value) { return { value }; } });",
|
||||||
|
].join(""));
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
});
|
||||||
|
imports.push("");
|
||||||
|
return imports.join("\n") + code;
|
||||||
|
};
|
||||||
|
|
||||||
function is_error(result) {
|
function is_error(result) {
|
||||||
return result && typeof result.name == "string" && typeof result.message == "string";
|
return result && typeof result.name == "string" && typeof result.message == "string";
|
||||||
@@ -147,12 +177,14 @@ function setup(global, builtins, setup_log, setup_tty) {
|
|||||||
[
|
[
|
||||||
// for Node.js v0.12
|
// for Node.js v0.12
|
||||||
"Buffer",
|
"Buffer",
|
||||||
|
"clearImmediate",
|
||||||
"clearInterval",
|
"clearInterval",
|
||||||
"clearTimeout",
|
"clearTimeout",
|
||||||
// for Node.js v0.12
|
// for Node.js v0.12
|
||||||
"DTRACE_NET_STREAM_END",
|
"DTRACE_NET_STREAM_END",
|
||||||
// for Node.js v8
|
// for Node.js v8
|
||||||
"process",
|
"process",
|
||||||
|
"setImmediate",
|
||||||
"setInterval",
|
"setInterval",
|
||||||
"setTimeout",
|
"setTimeout",
|
||||||
].forEach(function(name) {
|
].forEach(function(name) {
|
||||||
@@ -170,9 +202,13 @@ function setup(global, builtins, setup_log, setup_tty) {
|
|||||||
});
|
});
|
||||||
Object.defineProperties(global, props);
|
Object.defineProperties(global, props);
|
||||||
// for Node.js v8+
|
// for Node.js v8+
|
||||||
global.toString = function() {
|
if (global.toString !== Object.prototype.toString) {
|
||||||
|
global.__proto__ = Object.defineProperty(Object.create(global.__proto__), "toString", {
|
||||||
|
value: function() {
|
||||||
return "[object global]";
|
return "[object global]";
|
||||||
};
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function self() {
|
function self() {
|
||||||
return this;
|
return this;
|
||||||
@@ -186,7 +222,7 @@ function setup(global, builtins, setup_log, setup_tty) {
|
|||||||
if (arg === global) return "[object global]";
|
if (arg === global) return "[object global]";
|
||||||
if (/Error$/.test(arg.name)) return arg.toString();
|
if (/Error$/.test(arg.name)) return arg.toString();
|
||||||
if (typeof arg.then == "function") return "[object Promise]";
|
if (typeof arg.then == "function") return "[object Promise]";
|
||||||
arg.constructor.toString();
|
if (arg.constructor) arg.constructor.toString();
|
||||||
var index = cache.original.indexOf(arg);
|
var index = cache.original.indexOf(arg);
|
||||||
if (index >= 0) return cache.replaced[index];
|
if (index >= 0) return cache.replaced[index];
|
||||||
if (--cache.level < 0) return "[object Object]";
|
if (--cache.level < 0) return "[object Object]";
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,5 @@
|
|||||||
exports["Dictionary"] = Dictionary;
|
exports["Dictionary"] = Dictionary;
|
||||||
|
exports["is_statement"] = is_statement;
|
||||||
exports["List"] = List;
|
exports["List"] = List;
|
||||||
exports["minify"] = minify;
|
exports["minify"] = minify;
|
||||||
exports["parse"] = parse;
|
exports["parse"] = parse;
|
||||||
|
|||||||
@@ -56,6 +56,9 @@ if (+process.env["UGLIFY_BUG_REPORT"]) exports.minify = function(files, options)
|
|||||||
|
|
||||||
function describe_ast() {
|
function describe_ast() {
|
||||||
var out = OutputStream({ beautify: true });
|
var out = OutputStream({ beautify: true });
|
||||||
|
doitem(AST_Node);
|
||||||
|
return out.get() + "\n";
|
||||||
|
|
||||||
function doitem(ctor) {
|
function doitem(ctor) {
|
||||||
out.print("AST_" + ctor.TYPE);
|
out.print("AST_" + ctor.TYPE);
|
||||||
var props = ctor.SELF_PROPS.filter(function(prop) {
|
var props = ctor.SELF_PROPS.filter(function(prop) {
|
||||||
@@ -86,9 +89,7 @@ function describe_ast() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
doitem(AST_Node);
|
|
||||||
return out + "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function infer_options(options) {
|
function infer_options(options) {
|
||||||
|
|||||||
Reference in New Issue
Block a user